use of org.terasology.identity.PublicIdentityCertificate in project Terasology by MovingBlocks.
the class ClientHandshakeHandler method processNewIdentity.
private void processNewIdentity(NetData.ProvisionIdentity provisionIdentity, ChannelHandlerContext ctx) {
logger.info("Received identity from server");
if (!requestedCertificate) {
logger.error("Received identity without requesting it: cancelling authentication");
joinStatus.setErrorMessage(AUTHENTICATION_FAILURE);
ctx.getChannel().close();
return;
}
try {
byte[] decryptedCert = null;
try {
SecretKeySpec key = HandshakeCommon.generateSymmetricKey(masterSecret, clientRandom, serverRandom);
Cipher cipher = Cipher.getInstance(IdentityConstants.SYMMETRIC_ENCRYPTION_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
decryptedCert = cipher.doFinal(provisionIdentity.getEncryptedCertificates().toByteArray());
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
logger.error("Unexpected error decrypting received certificate, ending connection attempt", e);
joinStatus.setErrorMessage(AUTHENTICATION_FAILURE);
ctx.getChannel().close();
return;
}
NetData.CertificateSet certificateSet = NetData.CertificateSet.parseFrom(decryptedCert);
NetData.Certificate publicCertData = certificateSet.getPublicCertificate();
PublicIdentityCertificate publicCert = NetMessageUtil.convert(publicCertData);
if (!publicCert.verifySignedBy(serverCertificate)) {
logger.error("Received invalid certificate, not signed by server: cancelling authentication");
joinStatus.setErrorMessage(AUTHENTICATION_FAILURE);
ctx.getChannel().close();
return;
}
BigInteger exponent = new BigInteger(certificateSet.getPrivateExponent().toByteArray());
PrivateIdentityCertificate privateCert = new PrivateIdentityCertificate(publicCert.getModulus(), exponent);
// Store identity for later use
identity = new ClientIdentity(publicCert, privateCert);
config.getSecurity().addIdentity(serverCertificate, identity);
config.save();
// Try to upload the new identity to the identity storage service (if user is logged in)
StorageServiceWorker storageServiceWorker = CoreRegistry.get(StorageServiceWorker.class);
if (storageServiceWorker != null && storageServiceWorker.getStatus() == StorageServiceWorkerStatus.LOGGED_IN) {
storageServiceWorker.putIdentity(serverCertificate, identity);
}
// And we're authenticated.
ctx.getPipeline().remove(this);
channelAuthenticated(ctx);
} catch (InvalidProtocolBufferException e) {
logger.error("Received invalid certificate data: cancelling authentication", e);
joinStatus.setErrorMessage(AUTHENTICATION_FAILURE);
ctx.getChannel().close();
}
}
use of org.terasology.identity.PublicIdentityCertificate in project Terasology by MovingBlocks.
the class ClientHandshakeHandler method sendCertificate.
private void sendCertificate(NetData.HandshakeHello helloMessage, ChannelHandlerContext ctx) {
logger.info("Sending client certificate");
PublicIdentityCertificate pubClientCert = identity.getPlayerPublicCertificate();
clientHello = NetData.HandshakeHello.newBuilder().setRandom(ByteString.copyFrom(clientRandom)).setCertificate(NetMessageUtil.convert(pubClientCert)).setTimestamp(System.currentTimeMillis()).build();
byte[] dataToSign = Bytes.concat(helloMessage.toByteArray(), clientHello.toByteArray());
byte[] signature = identity.getPlayerPrivateCertificate().sign(dataToSign);
ctx.getChannel().write(NetData.NetMessage.newBuilder().setHandshakeHello(clientHello).setHandshakeVerification(NetData.HandshakeVerification.newBuilder().setSignature(ByteString.copyFrom(signature))).build());
}
use of org.terasology.identity.PublicIdentityCertificate in project Terasology by MovingBlocks.
the class ServerHandshakeHandler method channelConnected.
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
logger.info("Sending Server Hello");
PublicIdentityCertificate serverPublicCert = config.getSecurity().getServerPublicCertificate();
new SecureRandom().nextBytes(serverRandom);
serverHello = NetData.HandshakeHello.newBuilder().setRandom(ByteString.copyFrom(serverRandom)).setCertificate(NetMessageUtil.convert(serverPublicCert)).setTimestamp(System.currentTimeMillis()).build();
e.getChannel().write(NetData.NetMessage.newBuilder().setHandshakeHello(serverHello).build());
}
Aggregations