Search in sources :

Example 1 with MessageEncryptionHandler

use of org.lanternpowered.server.network.pipeline.MessageEncryptionHandler in project LanternServer by LanternPowered.

the class HandlerEncryptionResponse method handle.

@Override
public void handle(NetworkContext context, MessageLoginInEncryptionResponse message) {
    final NetworkSession session = context.getSession();
    final PrivateKey privateKey = session.getServer().getKeyPair().getPrivate();
    // Create rsaCipher
    Cipher rsaCipher;
    try {
        rsaCipher = Cipher.getInstance("RSA");
    } catch (GeneralSecurityException e) {
        Lantern.getLogger().error("Could not initialize RSA cipher", e);
        session.disconnect(t("Unable to initialize RSA cipher."));
        return;
    }
    // Decrypt shared secret
    SecretKey sharedSecret;
    try {
        rsaCipher.init(Cipher.DECRYPT_MODE, privateKey);
        sharedSecret = new SecretKeySpec(rsaCipher.doFinal(message.getSharedSecret()), "AES");
    } catch (Exception e) {
        Lantern.getLogger().warn("Could not decrypt shared secret", e);
        session.disconnect(t("Unable to decrypt shared secret."));
        return;
    }
    // Decrypt verify token
    byte[] verifyToken;
    try {
        rsaCipher.init(Cipher.DECRYPT_MODE, privateKey);
        verifyToken = rsaCipher.doFinal(message.getVerifyToken());
    } catch (Exception e) {
        Lantern.getLogger().warn("Could not decrypt verify token", e);
        session.disconnect(t("Unable to decrypt verify token."));
        return;
    }
    LoginAuthData authData = context.getChannel().attr(HandlerLoginStart.AUTH_DATA).getAndSet(null);
    // Check verify token
    if (!Arrays.equals(verifyToken, authData.getVerifyToken())) {
        session.disconnect(t("Invalid verify token."));
        return;
    }
    // Initialize stream encryption
    session.getChannel().pipeline().replace(NetworkSession.ENCRYPTION, NetworkSession.ENCRYPTION, new MessageEncryptionHandler(sharedSecret));
    // Create hash for auth
    String hash;
    try {
        MessageDigest digest = MessageDigest.getInstance("SHA-1");
        digest.update(authData.getSessionId().getBytes());
        digest.update(sharedSecret.getEncoded());
        digest.update(session.getServer().getKeyPair().getPublic().getEncoded());
        // BigInteger takes care of sign and leading zeroes
        hash = new BigInteger(digest.digest()).toString(16);
    } catch (NoSuchAlgorithmException e) {
        Lantern.getLogger().error("Unable to generate SHA-1 digest", e);
        session.disconnect(t("Failed to hash login data."));
        return;
    }
    String preventProxiesIp = null;
    if (Lantern.getGame().getGlobalConfig().shouldPreventProxyConnections()) {
        final InetAddress address = context.getSession().getAddress().getAddress();
        if (!isLocalAddress(address)) {
            // Ignore local addresses, they will always fail
            try {
                preventProxiesIp = URLEncoder.encode(address.getHostAddress(), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                Lantern.getLogger().error("Failed to encode the ip address to prevent proxies.", e);
                session.disconnect(t("Something funky happened."));
                return;
            }
        }
    }
    final String preventProxiesIp1 = preventProxiesIp;
    Lantern.getScheduler().submitAsyncTask(() -> performAuth(session, authData.getUsername(), hash, preventProxiesIp1));
}
Also used : NetworkSession(org.lanternpowered.server.network.NetworkSession) PrivateKey(java.security.PrivateKey) GeneralSecurityException(java.security.GeneralSecurityException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) MessageEncryptionHandler(org.lanternpowered.server.network.pipeline.MessageEncryptionHandler) SocketException(java.net.SocketException) GeneralSecurityException(java.security.GeneralSecurityException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) SecretKey(javax.crypto.SecretKey) SecretKeySpec(javax.crypto.spec.SecretKeySpec) BigInteger(java.math.BigInteger) Cipher(javax.crypto.Cipher) MessageDigest(java.security.MessageDigest) InetAddress(java.net.InetAddress)

Aggregations

UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 BigInteger (java.math.BigInteger)1 InetAddress (java.net.InetAddress)1 SocketException (java.net.SocketException)1 GeneralSecurityException (java.security.GeneralSecurityException)1 MessageDigest (java.security.MessageDigest)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 PrivateKey (java.security.PrivateKey)1 Cipher (javax.crypto.Cipher)1 SecretKey (javax.crypto.SecretKey)1 SecretKeySpec (javax.crypto.spec.SecretKeySpec)1 NetworkSession (org.lanternpowered.server.network.NetworkSession)1 MessageEncryptionHandler (org.lanternpowered.server.network.pipeline.MessageEncryptionHandler)1