
org.echocat.marquardt.common.domain.certificate.Certificate Maven / Gradle / Ivy
/*
* echocat Marquardt Java SDK, Copyright (c) 2015 echocat
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.echocat.marquardt.common.domain.certificate;
import com.google.common.collect.Sets;
import com.google.common.primitives.Longs;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.echocat.marquardt.common.domain.ClientId;
import org.echocat.marquardt.common.domain.PublicKeyWithMechanism;
import org.echocat.marquardt.common.domain.Signable;
import org.echocat.marquardt.common.serialization.RolesSerializer;
import javax.annotation.Nonnull;
import javax.annotation.WillNotClose;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Certificate produced by the authority when clients signup or signin.
*
* Clients use this certificate to get user authorization (roles) to enable features for a user.
* Clients use this certificate to communicate with services (with header X-Certificate) to access protected resources.
*
* Services use this certificate for authentication of protected resources.
* Services use this certificate for authorization of service methods (roles).
*
* @param Class of wrapped payload, for example additional user information to use on clents and services.
*/
public class Certificate implements Signable {
public static final Byte VERSION = 1;
private final PublicKey _issuerPublicKey;
private final PublicKey _clientPublicKey;
@SuppressWarnings("UseOfObsoleteDateTimeApi")
private final Date _expiresAt;
private final Set extends Role> _roles;
private final T _payload;
private final String _clientId;
private byte[] _signedCertificateBytes;
/**
* Factory method to create Certificate (used by the authority)
*
* @param issuerPublicKey Authority's public key. Must be trusted by clients and services.
* @param clientPublicKey Client's public key. Enables login of the same user on different clients.
* @param roles Roles of the user to enable authorization in clients and services.
* @param payload Wrapped payload, for example additional user information to use on clients and services
* @param Class of wrapped payload, for example additional user information to use on clients and services.
* @return A certificate.
*/
public static Certificate create(final PublicKey issuerPublicKey, final PublicKey clientPublicKey, String clientId, final Set extends Role> roles, final T payload) {
return new Certificate<>(issuerPublicKey, clientPublicKey, clientId, roles, payload);
}
private Certificate(final PublicKey issuerPublicKey, final PublicKey clientPublicKey, String clientId, final Set extends Role> roles, final T payload) {
_issuerPublicKey = issuerPublicKey;
_clientPublicKey = clientPublicKey;
_clientId = clientId;
_expiresAt = new Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(15));
_roles = roles;
_payload = payload;
}
/**
* Used by the CertificateFactory only. To serialize certificate from bytes.
*
* @param issuerPublicKey Authority's public key. Must be trusted by clients and services.
* @param clientPublicKey Client's public key. Enabled login of the same user on different clients.
* @param expiresAt Timestamp of expiration. Should be a relative short timeframe compared to the session of the authority.
* @param roles Roles of the user to enable authorization in clients and services.
* @param payload Wrapped payload, for example additional user information to use on clients and services
*/
Certificate(final PublicKey issuerPublicKey, final PublicKey clientPublicKey, String clientId, @SuppressWarnings("UseOfObsoleteDateTimeApi") final Date expiresAt, final Set extends Role> roles, final T payload) {
_issuerPublicKey = issuerPublicKey;
_clientPublicKey = clientPublicKey;
_clientId = clientId;
_expiresAt = expiresAt;
_roles = Sets.newHashSet(roles);
_payload = payload;
}
/**
* @return Authority's public key. Must be trusted by clients and services.
*/
public PublicKey getIssuerPublicKey() {
return _issuerPublicKey;
}
/**
* @return Client's public key. Enabled login of the same user on different clients.
*/
public PublicKey getClientPublicKey() {
return _clientPublicKey;
}
/**
* @return Wrapped payload, for example additional user information to use on clents and services.
*/
public T getPayload() {
return _payload;
}
/**
* @return Timestamp of expiration. Should be a relative short timeframe compared to the session of the authority.
*/
@SuppressWarnings("UseOfObsoleteDateTimeApi")
public Date getExpiresAt() {
return _expiresAt;
}
public String getClientId() {
return _clientId;
}
/**
* @return Roles of the user to enable authorization in clients and services.
*/
public Set extends Role> getRoles() {
return _roles;
}
@Override
public void writeTo(@Nonnull @WillNotClose final OutputStream out) throws IOException {
if (isSignedCertificate()) {
out.write(_signedCertificateBytes);
} else {
serializeTo(out);
}
}
@Override
public byte[] getContent() throws IOException {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
writeTo(out);
return out.toByteArray();
} finally {
IOUtils.closeQuietly(out);
}
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("_issuerPublicKey", _issuerPublicKey)
.append("_clientPublicKey", _clientPublicKey)
.append("_expiresAt", _expiresAt)
.append("_roles", _roles)
.append("_payload", _payload)
.toString();
}
/**
* If the certificate was received from an authority, we can use the already signed bytes when
* sending the certificate another service.
*/
public void setSignedCertificateBytes(final byte[] signedCertificateBytes) {
_signedCertificateBytes = Arrays.copyOf(signedCertificateBytes, signedCertificateBytes.length);
}
private void serializeTo(@Nonnull @WillNotClose final OutputStream out) throws IOException {
out.write(VERSION);
new PublicKeyWithMechanism(_issuerPublicKey).writeTo(out);
new PublicKeyWithMechanism(_clientPublicKey).writeTo(out);
new ClientId(_clientId).writeTo(out);
out.write(Longs.toByteArray(_expiresAt.getTime()));
out.write(Longs.toByteArray(RolesSerializer.from(_roles)));
_payload.writeTo(out);
}
private boolean isSignedCertificate() {
return _signedCertificateBytes != null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy