From 0544ad7e2c9eaf2f2ee5d4220747765af483091c Mon Sep 17 00:00:00 2001 From: Major- Date: Sat, 9 Nov 2013 13:37:03 +0000 Subject: [PATCH] Enable RSA. --- data/rsa.xml | 4 ++ src/org/apollo/game/GameService.java | 9 +++ src/org/apollo/io/RsaKeyParser.java | 66 +++++++++++++++++++ src/org/apollo/net/NetworkConstants.java | 14 +++- .../apollo/net/codec/login/LoginDecoder.java | 16 +++-- 5 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 data/rsa.xml create mode 100644 src/org/apollo/io/RsaKeyParser.java diff --git a/data/rsa.xml b/data/rsa.xml new file mode 100644 index 00000000..abe68a05 --- /dev/null +++ b/data/rsa.xml @@ -0,0 +1,4 @@ + + 143690958001225849100503496893758066948984921380482659564113596152800934352119496873386875214251264258425208995167316497331786595942754290983849878549630226741961610780416197036711585670124061149988186026407785250364328460839202438651793652051153157765358767514800252431284681765433239888090564804146588087023 + 124425314960550024206991065332877157931472210939505789558012215720454903710618146200843877022273818555405810618059191162604008259757866640421952188957253368398733319663236323097864278319463888334484786055755767881706264786840339899269810859874287402892848784247637729987603089254067178011764721326471352835473 + \ No newline at end of file diff --git a/src/org/apollo/game/GameService.java b/src/org/apollo/game/GameService.java index 23540626..1da9d1e3 100644 --- a/src/org/apollo/game/GameService.java +++ b/src/org/apollo/game/GameService.java @@ -15,6 +15,7 @@ import org.apollo.game.model.World; import org.apollo.game.model.World.RegistrationStatus; import org.apollo.game.sync.ClientSynchronizer; import org.apollo.io.EventHandlerChainParser; +import org.apollo.io.RsaKeyParser; import org.apollo.login.LoginService; import org.apollo.net.session.GameSession; import org.apollo.util.NamedThreadFactory; @@ -117,6 +118,14 @@ public final class GameService extends Service { } finally { is.close(); } + + is = new FileInputStream("data/rsa.xml"); + try { + RsaKeyParser parser = new RsaKeyParser(is); + parser.parse(); + } finally { + is.close(); + } } /** diff --git a/src/org/apollo/io/RsaKeyParser.java b/src/org/apollo/io/RsaKeyParser.java new file mode 100644 index 00000000..d23e36ee --- /dev/null +++ b/src/org/apollo/io/RsaKeyParser.java @@ -0,0 +1,66 @@ +package org.apollo.io; + +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; + +import org.apollo.net.NetworkConstants; +import org.apollo.util.xml.XmlNode; +import org.apollo.util.xml.XmlParser; +import org.xml.sax.SAXException; + +/** + * A class that parses the {@code rsa.xml} file. + * + * @author Major + */ +public class RsaKeyParser { + + /** + * The source {@link InputStream}. + */ + private final InputStream is; + + /** + * The {@link XmlParser} instance. + */ + private final XmlParser parser; + + /** + * Creates the RSA specification parser. + * + * @param is The source {@link InputStream}. + * @throws SAXException If a SAX error occurs. + */ + public RsaKeyParser(InputStream is) throws SAXException { + parser = new XmlParser(); + this.is = is; + } + + /** + * Parses the {@code rsa.xml} file. + * + * @throws SAXException If a SAX error occurs. + * @throws IOException + */ + public void parse() throws SAXException, IOException { + XmlNode rootNode = parser.parse(is); + if (!rootNode.getName().equals("rsa")) { + throw new IOException("root node name is not 'rsa'"); + } + + XmlNode modulusNode = rootNode.getChild("modulus"); + if (modulusNode == null) { + throw new IOException("no node named 'modulus' beneath root node"); + } + + XmlNode exponentNode = rootNode.getChild("private-exponent"); + if (exponentNode == null) { + throw new IOException("no node named 'private-exponent' beneath root node"); + } + + NetworkConstants.RSA_MODULUS = new BigInteger(modulusNode.getValue()); + NetworkConstants.RSA_EXPONENT = new BigInteger(exponentNode.getValue()); + } + +} \ No newline at end of file diff --git a/src/org/apollo/net/NetworkConstants.java b/src/org/apollo/net/NetworkConstants.java index 6f32e758..9c111feb 100644 --- a/src/org/apollo/net/NetworkConstants.java +++ b/src/org/apollo/net/NetworkConstants.java @@ -1,5 +1,7 @@ package org.apollo.net; +import java.math.BigInteger; + /** * Holds various network-related constants such as port numbers. * @@ -22,6 +24,16 @@ public final class NetworkConstants { */ public static final int JAGGRAB_PORT = 43595; + /** + * The exponent used when decrypting the RSA block. + */ + public static BigInteger RSA_EXPONENT; + + /** + * The modulus used when decrypting the RSA block. + */ + public static BigInteger RSA_MODULUS; + /** * The service port. */ @@ -39,4 +51,4 @@ public final class NetworkConstants { } -} +} \ No newline at end of file diff --git a/src/org/apollo/net/codec/login/LoginDecoder.java b/src/org/apollo/net/codec/login/LoginDecoder.java index fd4068d2..79c1d844 100644 --- a/src/org/apollo/net/codec/login/LoginDecoder.java +++ b/src/org/apollo/net/codec/login/LoginDecoder.java @@ -1,10 +1,12 @@ package org.apollo.net.codec.login; +import java.math.BigInteger; import java.security.SecureRandom; import net.burtleburtle.bob.rand.IsaacRandom; import org.apollo.fs.FileSystemConstants; +import org.apollo.net.NetworkConstants; import org.apollo.security.IsaacRandomPair; import org.apollo.security.PlayerCredentials; import org.apollo.util.ChannelBufferUtil; @@ -64,7 +66,7 @@ public final class LoginDecoder extends StatefulFrameDecoder case LOGIN_PAYLOAD: return decodePayload(ctx, channel, buffer); default: - throw new Exception("Invalid login decoder state"); + throw new IllegalArgumentException("Invalid login decoder state"); } } @@ -156,6 +158,11 @@ public final class LoginDecoder extends StatefulFrameDecoder ChannelBuffer securePayload = payload.readBytes(securePayloadLength); + BigInteger bigInteger = new BigInteger(securePayload.array()); + bigInteger = bigInteger.modPow(NetworkConstants.RSA_EXPONENT, NetworkConstants.RSA_MODULUS); + + securePayload = ChannelBuffers.wrappedBuffer(bigInteger.toByteArray()); + int secureId = securePayload.readUnsignedByte(); if (secureId != 10) { throw new Exception("Invalid secure payload id"); @@ -173,7 +180,7 @@ public final class LoginDecoder extends StatefulFrameDecoder String password = ChannelBufferUtil.readString(securePayload); if (username.length() > 12 || password.length() > 20) { - throw new Exception("Username or password too long"); + throw new Exception("Username or password too long."); } int[] seed = new int[4]; @@ -196,11 +203,10 @@ public final class LoginDecoder extends StatefulFrameDecoder if (buffer.readable()) { return new Object[] { req, buffer.readBytes(buffer.readableBytes()) }; - } else { - return req; } + return req; } return null; } -} +} \ No newline at end of file