diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-06-21 14:16:09 +0400 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-06-21 14:16:09 +0400 |
commit | 3d5c81535a01c28d88bcab4a0bebf585a24f43a7 (patch) | |
tree | 90d4f67e5a3c4df7af16ed25f713b907944eb808 /core/src/main/java/org/bouncycastle | |
parent | a75c64a4ed05deb6d63362078bf73c53d6ffd4ef (diff) |
Add the client-version check part of PR
https://github.com/bcgit/bc-java/pull/67/, after review.
Diffstat (limited to 'core/src/main/java/org/bouncycastle')
-rw-r--r-- | core/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java index df54e1d9..1fe4fa52 100644 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java +++ b/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java @@ -8,6 +8,7 @@ import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; +import org.bouncycastle.util.Arrays; public class TlsRSAUtils { @@ -73,16 +74,17 @@ public class TlsRSAUtils * Generate 48 random bytes we can use as a Pre-Master-Secret, if the * PKCS1 padding check should fail. */ - byte[] M = new byte[48]; - context.getSecureRandom().nextBytes(M); + byte[] fallback = new byte[48]; + context.getSecureRandom().nextBytes(fallback); + byte[] M = Arrays.clone(fallback); try { - PKCS1Encoding encoding = new PKCS1Encoding(new RSABlindedEngine(), M); - encoding.init(false, new ParametersWithRandom(rsaServerPrivateKey, context.getSecureRandom())); + PKCS1Encoding encoding = new PKCS1Encoding(new RSABlindedEngine(), fallback); + encoding.init(false, + new ParametersWithRandom(rsaServerPrivateKey, context.getSecureRandom())); - M = encoding.processBlock(encryptedPreMasterSecret, 0, - encryptedPreMasterSecret.length); + M = encoding.processBlock(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.length); } catch (Exception e) { @@ -110,13 +112,28 @@ public class TlsRSAUtils * * So there is nothing to do here. */ - } else { + } + else + { /* - * Note that explicitly constructing the pre_master_secret with the - * ClientHello.client_version produces an invalid master_secret if the client - * has sent the wrong version in the original pre_master_secret. + * OK, we need to compare the version number in the decrypted Pre-Master-Secret with the + * clientVersion received during the handshake. If they don't match, we replace the + * decrypted Pre-Master-Secret with a random one. */ - TlsUtils.writeVersion(clientVersion, M, 0); + int correct = (clientVersion.getMajorVersion() ^ (M[0] & 0xff)) + | (clientVersion.getMinorVersion() ^ (M[1] & 0xff)); + correct |= correct >> 1; + correct |= correct >> 2; + correct |= correct >> 4; + int mask = ~((correct & 1) - 1); + + /* + * mask will be all bits set to 0xff if the version number differed. + */ + for (int i = 0; i < 48; i++) + { + M[i] = (byte)((M[i] & (~mask)) | (fallback[i] & mask)); + } } return M; } |