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));
}
Aggregations