Search in sources :

Example 1 with ClientIdentity

use of org.terasology.engine.identity.ClientIdentity in project Terasology by MovingBlocks.

the class IdentityIOHelper method importIdentities.

public void importIdentities() {
    FilePickerPopup filePicker = nuiManager.pushScreen(FilePickerPopup.ASSET_URI, FilePickerPopup.class);
    filePicker.setTitle(importPopupTitle);
    filePicker.setOkHandler(path -> {
        Map<PublicIdentityCertificate, ClientIdentity> newIdentities;
        try (BufferedReader reader = Files.newBufferedReader(path)) {
            newIdentities = GSON.fromJson(reader, MAP_TYPE);
        } catch (IOException | JsonIOException | JsonSyntaxException ex) {
            nuiManager.pushScreen(MessagePopup.ASSET_URI, MessagePopup.class).setMessage(translationSystem.translate("${engine:menu#identity-import-failed}"), ex.toString());
            return;
        }
        checkNextConflict(newIdentities.entrySet().iterator(), () -> {
            newIdentities.forEach(securityConfig::addIdentity);
            nuiManager.pushScreen(MessagePopup.ASSET_URI, MessagePopup.class).setMessage(importPopupTitle, newIdentities.isEmpty() ? translationSystem.translate("${engine:menu#identity-import-no-new}") : String.format(translationSystem.translate("${engine:menu#identity-import-ok}"), newIdentities.size()));
        });
    });
}
Also used : JsonSyntaxException(com.google.gson.JsonSyntaxException) ClientIdentity(org.terasology.engine.identity.ClientIdentity) JsonIOException(com.google.gson.JsonIOException) BufferedReader(java.io.BufferedReader) MessagePopup(org.terasology.engine.rendering.nui.layers.mainMenu.MessagePopup) FilePickerPopup(org.terasology.engine.rendering.nui.layers.mainMenu.FilePickerPopup) IOException(java.io.IOException) JsonIOException(com.google.gson.JsonIOException) PublicIdentityCertificate(org.terasology.engine.identity.PublicIdentityCertificate)

Example 2 with ClientIdentity

use of org.terasology.engine.identity.ClientIdentity in project Terasology by MovingBlocks.

the class IdentityIOHelper method checkNextConflict.

private void checkNextConflict(Iterator<Map.Entry<PublicIdentityCertificate, ClientIdentity>> newIdentities, Runnable onCompletion) {
    Runnable next = () -> checkNextConflict(newIdentities, onCompletion);
    if (newIdentities.hasNext()) {
        Map.Entry<PublicIdentityCertificate, ClientIdentity> entry = newIdentities.next();
        PublicIdentityCertificate server = entry.getKey();
        ClientIdentity newClient = entry.getValue();
        ClientIdentity oldClient = securityConfig.getIdentity(server);
        if (oldClient != null) {
            Runnable skip = () -> {
                newIdentities.remove();
                next.run();
            };
            if (newClient.getPlayerPublicCertificate().equals(oldClient.getPlayerPublicCertificate())) {
                skip.run();
            } else {
                ThreeButtonPopup popup = nuiManager.pushScreen(ThreeButtonPopup.ASSET_URI, ThreeButtonPopup.class);
                popup.setMessage(importPopupTitle, String.format(translationSystem.translate("${engine:menu#identity-import-conflict}"), server.getId(), oldClient.getPlayerPublicCertificate().getId(), newClient.getPlayerPublicCertificate().getId()));
                popup.setLeftButton(translationSystem.translate("${engine:menu#identity-import-overwrite}"), next);
                popup.setCenterButton(translationSystem.translate("${engine:menu#identity-import-skip}"), skip);
                popup.setRightButton(translationSystem.translate("${engine:menu#identity-import-cancel}"), () -> nuiManager.pushScreen(MessagePopup.ASSET_URI, MessagePopup.class).setMessage(importPopupTitle, translationSystem.translate("${engine:menu#identity-import-cancelled}")));
            }
        } else {
            next.run();
        }
    } else {
        onCompletion.run();
    }
}
Also used : ClientIdentity(org.terasology.engine.identity.ClientIdentity) Map(java.util.Map) ThreeButtonPopup(org.terasology.engine.rendering.nui.layers.mainMenu.ThreeButtonPopup) PublicIdentityCertificate(org.terasology.engine.identity.PublicIdentityCertificate)

Example 3 with ClientIdentity

use of org.terasology.engine.identity.ClientIdentity in project Terasology by MovingBlocks.

the class StorageServiceWorker method solveNextConflict.

/**
 * @param solution the strategy to resolve the conflict returned by the latest call to {@link
 *         #getNextConflict()}. If there are no more conflicts and some of the solved conflicts must keep the local
 *         version, the uploads are performed asynchronously.
 */
public void solveNextConflict(IdentityConflictSolution solution) {
    IdentityBundle entry = conflictingRemoteIdentities.removeFirst();
    PublicIdentityCertificate server = entry.getServer();
    ClientIdentity remote = entry.getClient();
    ClientIdentity local = securityConfig.getIdentity(server);
    switch(solution) {
        case // save for upload (remote will be overwritten)
        KEEP_LOCAL:
            conflictSolutionsToUpload.put(server, local);
            break;
        case // store the remote identity locally, overwriting the local version
        KEEP_REMOTE:
            securityConfig.addIdentity(server, remote);
            break;
        case IGNORE:
    }
    // if there are no more conflicts, perform the uploads and reset
    if (!hasConflictingIdentities()) {
        putIdentities(conflictSolutionsToUpload);
        resetConflicts();
    }
}
Also used : ClientIdentity(org.terasology.engine.identity.ClientIdentity) PublicIdentityCertificate(org.terasology.engine.identity.PublicIdentityCertificate)

Example 4 with ClientIdentity

use of org.terasology.engine.identity.ClientIdentity in project Terasology by MovingBlocks.

the class ClientHandshakeHandler method processNewIdentity.

/**
 * Generates a new secret key for a user and then decrypts the certificate into a byte array. Storing the certificate to the user ID.
 * @param provisionIdentity
 * @param ctx Channel Handler Context.
 */
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.channel().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.channel().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.channel().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.pipeline().remove(this);
        channelAuthenticated(ctx);
    } catch (InvalidProtocolBufferException e) {
        logger.error("Received invalid certificate data: cancelling authentication", e);
        joinStatus.setErrorMessage(AUTHENTICATION_FAILURE);
        ctx.channel().close();
    }
}
Also used : NetData(org.terasology.protobuf.NetData) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BadPaddingException(javax.crypto.BadPaddingException) InvalidKeyException(java.security.InvalidKeyException) ClientIdentity(org.terasology.engine.identity.ClientIdentity) SecretKeySpec(javax.crypto.spec.SecretKeySpec) BigInteger(java.math.BigInteger) Cipher(javax.crypto.Cipher) StorageServiceWorker(org.terasology.engine.identity.storageServiceClient.StorageServiceWorker) PrivateIdentityCertificate(org.terasology.engine.identity.PrivateIdentityCertificate) PublicIdentityCertificate(org.terasology.engine.identity.PublicIdentityCertificate)

Aggregations

ClientIdentity (org.terasology.engine.identity.ClientIdentity)4 PublicIdentityCertificate (org.terasology.engine.identity.PublicIdentityCertificate)4 JsonIOException (com.google.gson.JsonIOException)1 JsonSyntaxException (com.google.gson.JsonSyntaxException)1 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)1 BufferedReader (java.io.BufferedReader)1 IOException (java.io.IOException)1 BigInteger (java.math.BigInteger)1 InvalidKeyException (java.security.InvalidKeyException)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 Map (java.util.Map)1 BadPaddingException (javax.crypto.BadPaddingException)1 Cipher (javax.crypto.Cipher)1 IllegalBlockSizeException (javax.crypto.IllegalBlockSizeException)1 NoSuchPaddingException (javax.crypto.NoSuchPaddingException)1 SecretKeySpec (javax.crypto.spec.SecretKeySpec)1 PrivateIdentityCertificate (org.terasology.engine.identity.PrivateIdentityCertificate)1 StorageServiceWorker (org.terasology.engine.identity.storageServiceClient.StorageServiceWorker)1 FilePickerPopup (org.terasology.engine.rendering.nui.layers.mainMenu.FilePickerPopup)1 MessagePopup (org.terasology.engine.rendering.nui.layers.mainMenu.MessagePopup)1