From 3f6165d46f132ffcc9b30c27bfea5bcf88dd6b4c Mon Sep 17 00:00:00 2001 From: David Hook Date: Tue, 21 May 2013 10:20:46 +1000 Subject: removed a couple of JDK15isms, changed to regular format, removed ^M --- .../crypto/agreement/DHStandardGroups.java | 409 +++++++++---------- .../crypto/tls/AbstractTlsCipherFactory.java | 7 +- .../bouncycastle/crypto/tls/AbstractTlsClient.java | 109 ++++-- .../crypto/tls/AbstractTlsContext.java | 43 +- .../crypto/tls/AbstractTlsKeyExchange.java | 83 ++-- .../bouncycastle/crypto/tls/AbstractTlsPeer.java | 10 +- .../bouncycastle/crypto/tls/AbstractTlsServer.java | 149 ++++--- .../bouncycastle/crypto/tls/AbstractTlsSigner.java | 7 +- .../bouncycastle/crypto/tls/AlertDescription.java | 3 +- .../crypto/tls/AlwaysValidVerifyer.java | 9 +- .../crypto/tls/BulkCipherAlgorithm.java | 5 +- .../org/bouncycastle/crypto/tls/ByteQueue.java | 16 +- .../org/bouncycastle/crypto/tls/Certificate.java | 67 ++-- .../crypto/tls/CertificateRequest.java | 75 ++-- .../crypto/tls/CertificateVerifyer.java | 2 +- .../org/bouncycastle/crypto/tls/CipherSuite.java | 3 +- .../org/bouncycastle/crypto/tls/CipherType.java | 5 +- .../crypto/tls/ClientAuthenticationType.java | 3 +- .../crypto/tls/ClientCertificateType.java | 3 +- .../org/bouncycastle/crypto/tls/CombinedHash.java | 47 ++- .../org/bouncycastle/crypto/tls/ConnectionEnd.java | 5 +- .../crypto/tls/DTLSClientProtocol.java | 231 +++++++---- .../org/bouncycastle/crypto/tls/DTLSEpoch.java | 27 +- .../crypto/tls/DTLSHandshakeRetransmit.java | 6 +- .../org/bouncycastle/crypto/tls/DTLSProtocol.java | 29 +- .../bouncycastle/crypto/tls/DTLSReassembler.java | 67 ++-- .../bouncycastle/crypto/tls/DTLSRecordLayer.java | 243 ++++++++---- .../crypto/tls/DTLSReliableHandshake.java | 216 ++++++---- .../bouncycastle/crypto/tls/DTLSReplayWindow.java | 28 +- .../crypto/tls/DTLSServerProtocol.java | 225 +++++++---- .../org/bouncycastle/crypto/tls/DTLSTransport.java | 57 ++- .../bouncycastle/crypto/tls/DatagramTransport.java | 18 +- .../crypto/tls/DefaultTlsAgreementCredentials.java | 39 +- .../crypto/tls/DefaultTlsCipherFactory.java | 59 ++- .../bouncycastle/crypto/tls/DefaultTlsClient.java | 77 ++-- .../tls/DefaultTlsEncryptionCredentials.java | 40 +- .../bouncycastle/crypto/tls/DefaultTlsServer.java | 64 ++- .../crypto/tls/DefaultTlsSignerCredentials.java | 48 ++- .../org/bouncycastle/crypto/tls/DeferredHash.java | 69 ++-- .../bouncycastle/crypto/tls/DigestAlgorithm.java | 7 +- .../org/bouncycastle/crypto/tls/ECBasisType.java | 3 +- .../crypto/tls/EncryptionAlgorithm.java | 5 +- .../org/bouncycastle/crypto/tls/ExporterLabel.java | 3 +- .../org/bouncycastle/crypto/tls/HandshakeType.java | 6 +- .../org/bouncycastle/crypto/tls/HashAlgorithm.java | 3 +- .../crypto/tls/KeyExchangeAlgorithm.java | 4 +- .../crypto/tls/LegacyTlsAuthentication.java | 8 +- .../bouncycastle/crypto/tls/LegacyTlsClient.java | 12 +- .../org/bouncycastle/crypto/tls/MACAlgorithm.java | 5 +- .../org/bouncycastle/crypto/tls/NamedCurve.java | 11 +- .../bouncycastle/crypto/tls/NewSessionTicket.java | 20 +- .../org/bouncycastle/crypto/tls/PRFAlgorithm.java | 5 +- .../org/bouncycastle/crypto/tls/PSKTlsClient.java | 34 +- .../bouncycastle/crypto/tls/ProtocolVersion.java | 64 ++- .../org/bouncycastle/crypto/tls/RecordStream.java | 149 ++++--- .../org/bouncycastle/crypto/tls/SRPTlsClient.java | 53 ++- .../crypto/tls/SRTPProtectionProfile.java | 3 +- .../java/org/bouncycastle/crypto/tls/SSL3Mac.java | 9 +- .../crypto/tls/SecurityParameters.java | 24 +- .../crypto/tls/ServerOnlyTlsAuthentication.java | 7 +- .../crypto/tls/SignatureAlgorithm.java | 5 +- .../crypto/tls/SignatureAndHashAlgorithm.java | 56 +-- .../crypto/tls/SupplementalDataEntry.java | 12 +- .../crypto/tls/SupplementalDataType.java | 3 +- .../org/bouncycastle/crypto/tls/TlsAEADCipher.java | 61 ++- .../crypto/tls/TlsAgreementCredentials.java | 7 +- .../bouncycastle/crypto/tls/TlsAuthentication.java | 10 +- .../bouncycastle/crypto/tls/TlsBlockCipher.java | 116 ++++-- .../org/bouncycastle/crypto/tls/TlsCipher.java | 6 +- .../bouncycastle/crypto/tls/TlsCipherFactory.java | 3 +- .../org/bouncycastle/crypto/tls/TlsClient.java | 47 ++- .../bouncycastle/crypto/tls/TlsClientContext.java | 4 +- .../crypto/tls/TlsClientContextImpl.java | 11 +- .../bouncycastle/crypto/tls/TlsClientProtocol.java | 223 +++++++---- .../org/bouncycastle/crypto/tls/TlsContext.java | 16 +- .../bouncycastle/crypto/tls/TlsDHEKeyExchange.java | 35 +- .../bouncycastle/crypto/tls/TlsDHKeyExchange.java | 113 ++++-- .../org/bouncycastle/crypto/tls/TlsDHUtils.java | 37 +- .../org/bouncycastle/crypto/tls/TlsDSASigner.java | 20 +- .../org/bouncycastle/crypto/tls/TlsDSSSigner.java | 10 +- .../org/bouncycastle/crypto/tls/TlsECCUtils.java | 284 +++++++++----- .../crypto/tls/TlsECDHEKeyExchange.java | 92 +++-- .../crypto/tls/TlsECDHKeyExchange.java | 121 ++++-- .../bouncycastle/crypto/tls/TlsECDSASigner.java | 10 +- .../crypto/tls/TlsEncryptionCredentials.java | 7 +- .../org/bouncycastle/crypto/tls/TlsFatalAlert.java | 3 +- .../bouncycastle/crypto/tls/TlsHandshakeHash.java | 4 +- .../bouncycastle/crypto/tls/TlsInputStream.java | 12 +- .../bouncycastle/crypto/tls/TlsKeyExchange.java | 42 +- .../java/org/bouncycastle/crypto/tls/TlsMac.java | 82 ++-- .../org/bouncycastle/crypto/tls/TlsNullCipher.java | 50 ++- .../crypto/tls/TlsNullCompression.java | 3 +- .../bouncycastle/crypto/tls/TlsOutputStream.java | 15 +- .../bouncycastle/crypto/tls/TlsPSKIdentity.java | 8 +- .../bouncycastle/crypto/tls/TlsPSKKeyExchange.java | 95 +++-- .../java/org/bouncycastle/crypto/tls/TlsPeer.java | 25 +- .../org/bouncycastle/crypto/tls/TlsProtocol.java | 434 +++++++++++++-------- .../crypto/tls/TlsProtocolHandler.java | 10 +- .../bouncycastle/crypto/tls/TlsRSAKeyExchange.java | 106 +++-- .../org/bouncycastle/crypto/tls/TlsRSASigner.java | 33 +- .../org/bouncycastle/crypto/tls/TlsRSAUtils.java | 21 +- .../crypto/tls/TlsRuntimeException.java | 3 +- .../bouncycastle/crypto/tls/TlsSRPKeyExchange.java | 92 +++-- .../org/bouncycastle/crypto/tls/TlsSRTPUtils.java | 35 +- .../org/bouncycastle/crypto/tls/TlsServer.java | 67 ++-- .../bouncycastle/crypto/tls/TlsServerContext.java | 4 +- .../crypto/tls/TlsServerContextImpl.java | 11 +- .../bouncycastle/crypto/tls/TlsServerProtocol.java | 313 ++++++++++----- .../org/bouncycastle/crypto/tls/TlsSigner.java | 6 +- .../crypto/tls/TlsSignerCredentials.java | 6 +- .../bouncycastle/crypto/tls/TlsStreamCipher.java | 35 +- .../java/org/bouncycastle/crypto/tls/TlsUtils.java | 160 +++++--- .../org/bouncycastle/crypto/tls/UDPTransport.java | 32 +- .../org/bouncycastle/crypto/tls/UseSRTPData.java | 28 +- .../bouncycastle/crypto/tls/UserMappingType.java | 3 +- .../org/bouncycastle/crypto/tls/test/AllTests.java | 14 +- .../bouncycastle/crypto/tls/test/BasicTlsTest.java | 355 +++++++++-------- .../crypto/tls/test/DTLSClientTest.java | 114 +++--- .../crypto/tls/test/DTLSProtocolTest.java | 187 +++++---- .../crypto/tls/test/HTTPSServerThread.java | 17 +- .../bouncycastle/crypto/tls/test/KeyStores.java | 132 +++---- .../crypto/tls/test/LoggingDatagramTransport.java | 159 ++++---- .../crypto/tls/test/MockDTLSClient.java | 160 ++++---- .../crypto/tls/test/MockDTLSServer.java | 148 +++---- .../crypto/tls/test/MockDatagramAssociation.java | 201 +++++----- .../crypto/tls/test/TestTlsClient.java | 23 ++ .../crypto/tls/test/TlsClientTest.java | 193 ++++----- .../crypto/tls/test/TlsProtocolTest.java | 389 +++++++++--------- .../bouncycastle/crypto/tls/test/TlsTestUtils.java | 304 ++++++++------- .../tls/test/UnreliableDatagramTransport.java | 161 ++++---- 130 files changed, 5442 insertions(+), 3200 deletions(-) create mode 100644 src/test/java/org/bouncycastle/crypto/tls/test/TestTlsClient.java diff --git a/src/main/java/org/bouncycastle/crypto/agreement/DHStandardGroups.java b/src/main/java/org/bouncycastle/crypto/agreement/DHStandardGroups.java index a85f10a5..638bcb13 100644 --- a/src/main/java/org/bouncycastle/crypto/agreement/DHStandardGroups.java +++ b/src/main/java/org/bouncycastle/crypto/agreement/DHStandardGroups.java @@ -1,203 +1,206 @@ -package org.bouncycastle.crypto.agreement; - -import java.math.BigInteger; - -import org.bouncycastle.crypto.params.DHParameters; -import org.bouncycastle.util.encoders.Hex; - -/** - * Standard Diffie-Hellman groups from various IETF specifications. - */ -public class DHStandardGroups { - - private static DHParameters fromPG(String hexP, String hexG) { - BigInteger p = new BigInteger(1, Hex.decode(hexP)); - BigInteger g = new BigInteger(1, Hex.decode(hexG)); - return new DHParameters(p, g); - } - - private static DHParameters fromPGQ(String hexP, String hexG, String hexQ) { - BigInteger p = new BigInteger(1, Hex.decode(hexP)); - BigInteger g = new BigInteger(1, Hex.decode(hexG)); - BigInteger q = new BigInteger(1, Hex.decode(hexQ)); - return new DHParameters(p, g, q); - } - - /* - * RFC 2409 - */ - private static final String rfc2409_768_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" - + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" - + "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"; - private static final String rfc2409_768_g = "02"; - public static final DHParameters rfc2409_768 = fromPG(rfc2409_768_p, rfc2409_768_g); - - private static final String rfc2409_1024_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" - + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" - + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" - + "FFFFFFFFFFFFFFFF"; - private static final String rfc2409_1024_g = "02"; - public static final DHParameters rfc2409_1024 = fromPG(rfc2409_1024_p, rfc2409_1024_g); - - /* - * RFC 3526 - */ - private static final String rfc3526_1536_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" - + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" - + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" - + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" - + "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"; - private static final String rfc3526_1536_g = "02"; - public static final DHParameters rfc3526_1536 = fromPG(rfc3526_1536_p, rfc3526_1536_g); - - private static final String rfc3526_2048_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" - + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" - + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" - + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" - + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" - + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AACAA68FFFFFFFFFFFFFFFF"; - private static final String rfc3526_2048_g = "02"; - public static final DHParameters rfc3526_2048 = fromPG(rfc3526_2048_p, rfc3526_2048_g); - - private static final String rfc3526_3072_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" - + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" - + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" - + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" - + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" - + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" - + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" - + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" - + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; - private static final String rfc3526_3072_g = "02"; - public static final DHParameters rfc3526_3072 = fromPG(rfc3526_3072_p, rfc3526_3072_g); - - private static final String rfc3526_4096_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" - + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" - + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" - + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" - + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" - + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" - + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" - + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" - + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" - + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" - + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" - + "FFFFFFFFFFFFFFFF"; - private static final String rfc3526_4096_g = "02"; - public static final DHParameters rfc3526_4096 = fromPG(rfc3526_4096_p, rfc3526_4096_g); - - private static final String rfc3526_6144_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" - + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" - + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" - + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" - + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" - + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" - + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" - + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" - + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" - + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" - + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" - + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" - + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" - + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" - + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" - + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" - + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" - + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" - + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" - + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" - + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" - + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" - + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" - + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" - + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" - + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" - + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + "6DCC4024FFFFFFFFFFFFFFFF"; - private static final String rfc3526_6144_g = "02"; - public static final DHParameters rfc3526_6144 = fromPG(rfc3526_6144_p, rfc3526_6144_g); - - private static final String rfc3526_8192_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" - + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" - + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" - + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" - + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" - + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" - + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" - + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" - + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" - + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" - + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" - + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" + "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" - + "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" + "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" - + "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" + "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" - + "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" - + "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" + "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" - + "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" + "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" - + "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" + "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" - + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" + "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" - + "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" + "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" - + "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" + "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" - + "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"; - private static final String rfc3526_8192_g = "02"; - public static final DHParameters rfc3526_8192 = fromPG(rfc3526_8192_p, rfc3526_8192_g); - - /* - * RFC 4306 - */ - public static final DHParameters rfc4306_768 = rfc2409_768; - public static final DHParameters rfc4306_1024 = rfc2409_1024; - - /* - * RFC 5114 - */ - private static final String rfc5114_1024_160_p = "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" - + "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" + "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" - + "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" + "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" - + "DF1FB2BC2E4A4371"; - private static final String rfc5114_1024_160_g = "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" - + "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" + "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" - + "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" + "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" - + "855E6EEB22B3B2E5"; - private static final String rfc5114_1024_160_q = "F518AA8781A8DF278ABA4E7D64B7CB9D49462353"; - public static final DHParameters rfc5114_1024_160 = fromPGQ(rfc5114_1024_160_p, rfc5114_1024_160_g, - rfc5114_1024_160_q); - - private static final String rfc5114_2048_224_p = "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" - + "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" + "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" - + "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" + "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" - + "B3BF8A317091883681286130BC8985DB1602E714415D9330" + "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" - + "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" + "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" - + "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" + "CF9DE5384E71B81C0AC4DFFE0C10E64F"; - private static final String rfc5114_2048_224_g = "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF" - + "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA" + "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7" - + "C17669101999024AF4D027275AC1348BB8A762D0521BC98A" + "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE" - + "F180EB34118E98D119529A45D6F834566E3025E316A330EF" + "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB" - + "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381" + "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269" - + "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179" + "81BC087F2A7065B384B890D3191F2BFA"; - private static final String rfc5114_2048_224_q = "801C0D34C58D93FE997177101F80535A4738CEBCBF389A99B36371EB"; - public static final DHParameters rfc5114_2048_224 = fromPGQ(rfc5114_2048_224_p, rfc5114_2048_224_g, - rfc5114_2048_224_q); - - private static final String rfc5114_2048_256_p = "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F2" - + "5D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA30" + "16C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD" - + "5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B" + "6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C" - + "4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0E" + "F13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D9" - + "67E144E5140564251CCACB83E6B486F6B3CA3F7971506026" + "C0B857F689962856DED4010ABD0BE621C3A3960A54E710C3" - + "75F26375D7014103A4B54330C198AF126116D2276E11715F" + "693877FAD7EF09CADB094AE91E1A1597"; - private static final String rfc5114_2048_256_g = "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF2054" - + "07F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555" + "BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18" - + "A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B" + "777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC83" - + "1D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55" + "A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14" - + "C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915" + "B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6" - + "184B523D1DB246C32F63078490F00EF8D647D148D4795451" + "5E2327CFEF98C582664B4C0F6CC41659"; - private static final String rfc5114_2048_256_q = "8CF83642A709A097B447997640129DA299B1A47D1EB3750B" - + "A308B0FE64F5FBD3"; - public static final DHParameters rfc5114_2048_256 = fromPGQ(rfc5114_2048_256_p, rfc5114_2048_256_g, - rfc5114_2048_256_q); - - /* - * RFC 5996 - */ - public static final DHParameters rfc5996_768 = rfc4306_768; - public static final DHParameters rfc5996_1024 = rfc4306_1024; -} +package org.bouncycastle.crypto.agreement; + +import java.math.BigInteger; + +import org.bouncycastle.crypto.params.DHParameters; +import org.bouncycastle.util.encoders.Hex; + +/** + * Standard Diffie-Hellman groups from various IETF specifications. + */ +public class DHStandardGroups +{ + + private static DHParameters fromPG(String hexP, String hexG) + { + BigInteger p = new BigInteger(1, Hex.decode(hexP)); + BigInteger g = new BigInteger(1, Hex.decode(hexG)); + return new DHParameters(p, g); + } + + private static DHParameters fromPGQ(String hexP, String hexG, String hexQ) + { + BigInteger p = new BigInteger(1, Hex.decode(hexP)); + BigInteger g = new BigInteger(1, Hex.decode(hexG)); + BigInteger q = new BigInteger(1, Hex.decode(hexQ)); + return new DHParameters(p, g, q); + } + + /* + * RFC 2409 + */ + private static final String rfc2409_768_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"; + private static final String rfc2409_768_g = "02"; + public static final DHParameters rfc2409_768 = fromPG(rfc2409_768_p, rfc2409_768_g); + + private static final String rfc2409_1024_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" + + "FFFFFFFFFFFFFFFF"; + private static final String rfc2409_1024_g = "02"; + public static final DHParameters rfc2409_1024 = fromPG(rfc2409_1024_p, rfc2409_1024_g); + + /* + * RFC 3526 + */ + private static final String rfc3526_1536_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"; + private static final String rfc3526_1536_g = "02"; + public static final DHParameters rfc3526_1536 = fromPG(rfc3526_1536_p, rfc3526_1536_g); + + private static final String rfc3526_2048_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AACAA68FFFFFFFFFFFFFFFF"; + private static final String rfc3526_2048_g = "02"; + public static final DHParameters rfc3526_2048 = fromPG(rfc3526_2048_p, rfc3526_2048_g); + + private static final String rfc3526_3072_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; + private static final String rfc3526_3072_g = "02"; + public static final DHParameters rfc3526_3072 = fromPG(rfc3526_3072_p, rfc3526_3072_g); + + private static final String rfc3526_4096_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" + + "FFFFFFFFFFFFFFFF"; + private static final String rfc3526_4096_g = "02"; + public static final DHParameters rfc3526_4096 = fromPG(rfc3526_4096_p, rfc3526_4096_g); + + private static final String rfc3526_6144_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" + + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" + + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" + + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" + + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" + + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" + + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" + + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + "6DCC4024FFFFFFFFFFFFFFFF"; + private static final String rfc3526_6144_g = "02"; + public static final DHParameters rfc3526_6144 = fromPG(rfc3526_6144_p, rfc3526_6144_g); + + private static final String rfc3526_8192_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" + "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" + + "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" + "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" + + "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" + "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" + + "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" + + "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" + "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" + + "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" + "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" + + "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" + "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" + + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" + "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" + + "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" + "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" + + "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" + "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" + + "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"; + private static final String rfc3526_8192_g = "02"; + public static final DHParameters rfc3526_8192 = fromPG(rfc3526_8192_p, rfc3526_8192_g); + + /* + * RFC 4306 + */ + public static final DHParameters rfc4306_768 = rfc2409_768; + public static final DHParameters rfc4306_1024 = rfc2409_1024; + + /* + * RFC 5114 + */ + private static final String rfc5114_1024_160_p = "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" + + "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" + "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" + + "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" + "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" + + "DF1FB2BC2E4A4371"; + private static final String rfc5114_1024_160_g = "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" + + "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" + "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" + + "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" + "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" + + "855E6EEB22B3B2E5"; + private static final String rfc5114_1024_160_q = "F518AA8781A8DF278ABA4E7D64B7CB9D49462353"; + public static final DHParameters rfc5114_1024_160 = fromPGQ(rfc5114_1024_160_p, rfc5114_1024_160_g, + rfc5114_1024_160_q); + + private static final String rfc5114_2048_224_p = "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" + + "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" + "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" + + "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" + "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" + + "B3BF8A317091883681286130BC8985DB1602E714415D9330" + "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" + + "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" + "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" + + "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" + "CF9DE5384E71B81C0AC4DFFE0C10E64F"; + private static final String rfc5114_2048_224_g = "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF" + + "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA" + "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7" + + "C17669101999024AF4D027275AC1348BB8A762D0521BC98A" + "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE" + + "F180EB34118E98D119529A45D6F834566E3025E316A330EF" + "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB" + + "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381" + "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269" + + "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179" + "81BC087F2A7065B384B890D3191F2BFA"; + private static final String rfc5114_2048_224_q = "801C0D34C58D93FE997177101F80535A4738CEBCBF389A99B36371EB"; + public static final DHParameters rfc5114_2048_224 = fromPGQ(rfc5114_2048_224_p, rfc5114_2048_224_g, + rfc5114_2048_224_q); + + private static final String rfc5114_2048_256_p = "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F2" + + "5D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA30" + "16C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD" + + "5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B" + "6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C" + + "4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0E" + "F13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D9" + + "67E144E5140564251CCACB83E6B486F6B3CA3F7971506026" + "C0B857F689962856DED4010ABD0BE621C3A3960A54E710C3" + + "75F26375D7014103A4B54330C198AF126116D2276E11715F" + "693877FAD7EF09CADB094AE91E1A1597"; + private static final String rfc5114_2048_256_g = "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF2054" + + "07F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555" + "BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18" + + "A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B" + "777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC83" + + "1D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55" + "A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14" + + "C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915" + "B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6" + + "184B523D1DB246C32F63078490F00EF8D647D148D4795451" + "5E2327CFEF98C582664B4C0F6CC41659"; + private static final String rfc5114_2048_256_q = "8CF83642A709A097B447997640129DA299B1A47D1EB3750B" + + "A308B0FE64F5FBD3"; + public static final DHParameters rfc5114_2048_256 = fromPGQ(rfc5114_2048_256_p, rfc5114_2048_256_g, + rfc5114_2048_256_q); + + /* + * RFC 5996 + */ + public static final DHParameters rfc5996_768 = rfc4306_768; + public static final DHParameters rfc5996_1024 = rfc4306_1024; +} diff --git a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsCipherFactory.java b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsCipherFactory.java index 82f2ea78..289c5dca 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsCipherFactory.java +++ b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsCipherFactory.java @@ -2,10 +2,13 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -public class AbstractTlsCipherFactory implements TlsCipherFactory { +public class AbstractTlsCipherFactory + implements TlsCipherFactory +{ public TlsCipher createCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) - throws IOException { + throws IOException + { throw new TlsFatalAlert(AlertDescription.internal_error); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsClient.java b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsClient.java index e64148c9..9eda0669 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsClient.java +++ b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsClient.java @@ -4,7 +4,10 @@ import java.io.IOException; import java.util.Hashtable; import java.util.Vector; -public abstract class AbstractTlsClient extends AbstractTlsPeer implements TlsClient { +public abstract class AbstractTlsClient + extends AbstractTlsPeer + implements TlsClient +{ protected TlsCipherFactory cipherFactory; @@ -15,15 +18,18 @@ public abstract class AbstractTlsClient extends AbstractTlsPeer implements TlsCl protected int selectedCipherSuite; protected short selectedCompressionMethod; - public AbstractTlsClient() { + public AbstractTlsClient() + { this(new DefaultTlsCipherFactory()); } - public AbstractTlsClient(TlsCipherFactory cipherFactory) { + public AbstractTlsClient(TlsCipherFactory cipherFactory) + { this.cipherFactory = cipherFactory; } - public void init(TlsClientContext context) { + public void init(TlsClientContext context) + { this.context = context; } @@ -34,7 +40,8 @@ public abstract class AbstractTlsClient extends AbstractTlsPeer implements TlsCl * single value will guarantee interoperability with all old servers, but this is a complex * topic beyond the scope of this document." */ - public ProtocolVersion getClientHelloRecordLayerVersion() { + public ProtocolVersion getClientHelloRecordLayerVersion() + { // "{03,00}" // return ProtocolVersion.SSLv3; @@ -45,11 +52,14 @@ public abstract class AbstractTlsClient extends AbstractTlsPeer implements TlsCl return getClientVersion(); } - public ProtocolVersion getClientVersion() { + public ProtocolVersion getClientVersion() + { return ProtocolVersion.TLSv11; } - public Hashtable getClientExtensions() throws IOException { + public Hashtable getClientExtensions() + throws IOException + { Hashtable clientExtensions = null; @@ -59,19 +69,22 @@ public abstract class AbstractTlsClient extends AbstractTlsPeer implements TlsCl * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior to 1.2. * Clients MUST NOT offer it if they are offering prior versions. */ - if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(clientVersion)) { + if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(clientVersion)) + { // TODO Provide a way for the user to specify the acceptable hash/signature algorithms. - short[] hashAlgorithms = new short[] { HashAlgorithm.sha512, HashAlgorithm.sha384, HashAlgorithm.sha256, - HashAlgorithm.sha224, HashAlgorithm.sha1 }; + short[] hashAlgorithms = new short[]{HashAlgorithm.sha512, HashAlgorithm.sha384, HashAlgorithm.sha256, + HashAlgorithm.sha224, HashAlgorithm.sha1}; // TODO Sort out ECDSA signatures and add them as the preferred option here - short[] signatureAlgorithms = new short[] { SignatureAlgorithm.rsa }; + short[] signatureAlgorithms = new short[]{SignatureAlgorithm.rsa}; this.supportedSignatureAlgorithms = new Vector(); - for (int i = 0; i < hashAlgorithms.length; ++i) { - for (int j = 0; j < signatureAlgorithms.length; ++j) { + for (int i = 0; i < hashAlgorithms.length; ++i) + { + for (int j = 0; j < signatureAlgorithms.length; ++j) + { this.supportedSignatureAlgorithms.addElement(new SignatureAndHashAlgorithm(hashAlgorithms[i], signatureAlgorithms[j])); } @@ -83,7 +96,8 @@ public abstract class AbstractTlsClient extends AbstractTlsPeer implements TlsCl this.supportedSignatureAlgorithms.addElement(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.dsa)); - if (clientExtensions == null) { + if (clientExtensions == null) + { clientExtensions = new Hashtable(); } @@ -93,34 +107,45 @@ public abstract class AbstractTlsClient extends AbstractTlsPeer implements TlsCl return clientExtensions; } - public ProtocolVersion getMinimumVersion() { + public ProtocolVersion getMinimumVersion() + { return ProtocolVersion.TLSv10; } - public void notifyServerVersion(ProtocolVersion serverVersion) throws IOException { - if (!getMinimumVersion().isEqualOrEarlierVersionOf(serverVersion)) { + public void notifyServerVersion(ProtocolVersion serverVersion) + throws IOException + { + if (!getMinimumVersion().isEqualOrEarlierVersionOf(serverVersion)) + { throw new TlsFatalAlert(AlertDescription.protocol_version); } } - public short[] getCompressionMethods() { - return new short[] { CompressionMethod._null }; + public short[] getCompressionMethods() + { + return new short[]{CompressionMethod._null}; } - public void notifySessionID(byte[] sessionID) { + public void notifySessionID(byte[] sessionID) + { // Currently ignored } - public void notifySelectedCipherSuite(int selectedCipherSuite) { + public void notifySelectedCipherSuite(int selectedCipherSuite) + { this.selectedCipherSuite = selectedCipherSuite; } - public void notifySelectedCompressionMethod(short selectedCompressionMethod) { + public void notifySelectedCompressionMethod(short selectedCompressionMethod) + { this.selectedCompressionMethod = selectedCompressionMethod; } - public void notifySecureRenegotiation(boolean secureRenegotiation) throws IOException { - if (!secureRenegotiation) { + public void notifySecureRenegotiation(boolean secureRenegotiation) + throws IOException + { + if (!secureRenegotiation) + { /* * RFC 5746 3.4. In this case, some clients may want to terminate the handshake instead * of continuing; see Section 4.1 for discussion. @@ -129,33 +154,45 @@ public abstract class AbstractTlsClient extends AbstractTlsPeer implements TlsCl } } - public void processServerExtensions(Hashtable serverExtensions) throws IOException { + public void processServerExtensions(Hashtable serverExtensions) + throws IOException + { /* * TlsProtocol implementation validates that any server extensions received correspond to * client extensions sent. By default, we don't send any, and this method is not called. */ - if (serverExtensions != null) { + if (serverExtensions != null) + { /* * RFC 5246 7.4.1.4.1. Servers MUST NOT send this extension. */ - if (serverExtensions.containsKey(TlsUtils.EXT_signature_algorithms)) { + if (serverExtensions.containsKey(TlsUtils.EXT_signature_algorithms)) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } } - public void processServerSupplementalData(Vector serverSupplementalData) throws IOException { - if (serverSupplementalData != null) { + public void processServerSupplementalData(Vector serverSupplementalData) + throws IOException + { + if (serverSupplementalData != null) + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } - public Vector getClientSupplementalData() throws IOException { + public Vector getClientSupplementalData() + throws IOException + { return null; } - public TlsCompression getCompression() throws IOException { - switch (selectedCompressionMethod) { + public TlsCompression getCompression() + throws IOException + { + switch (selectedCompressionMethod) + { case CompressionMethod._null: return new TlsNullCompression(); @@ -169,9 +206,13 @@ public abstract class AbstractTlsClient extends AbstractTlsPeer implements TlsCl } } - public void notifyNewSessionTicket(NewSessionTicket newSessionTicket) throws IOException { + public void notifyNewSessionTicket(NewSessionTicket newSessionTicket) + throws IOException + { } - public void notifyHandshakeComplete() throws IOException { + public void notifyHandshakeComplete() + throws IOException + { } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java index 0b5b8feb..83310330 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java +++ b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java @@ -2,7 +2,9 @@ package org.bouncycastle.crypto.tls; import java.security.SecureRandom; -abstract class AbstractTlsContext implements TlsContext { +abstract class AbstractTlsContext + implements TlsContext +{ private SecureRandom secureRandom; private SecurityParameters securityParameters; @@ -11,50 +13,61 @@ abstract class AbstractTlsContext implements TlsContext { private ProtocolVersion serverVersion = null; private Object userObject = null; - AbstractTlsContext(SecureRandom secureRandom, SecurityParameters securityParameters) { + AbstractTlsContext(SecureRandom secureRandom, SecurityParameters securityParameters) + { this.secureRandom = secureRandom; this.securityParameters = securityParameters; } - public SecureRandom getSecureRandom() { + public SecureRandom getSecureRandom() + { return secureRandom; } - public SecurityParameters getSecurityParameters() { + public SecurityParameters getSecurityParameters() + { return securityParameters; } - public ProtocolVersion getClientVersion() { + public ProtocolVersion getClientVersion() + { return clientVersion; } - public void setClientVersion(ProtocolVersion clientVersion) { + public void setClientVersion(ProtocolVersion clientVersion) + { this.clientVersion = clientVersion; } - public ProtocolVersion getServerVersion() { + public ProtocolVersion getServerVersion() + { return serverVersion; } - public void setServerVersion(ProtocolVersion serverVersion) { + public void setServerVersion(ProtocolVersion serverVersion) + { this.serverVersion = serverVersion; } - public Object getUserObject() { + public Object getUserObject() + { return userObject; } - public void setUserObject(Object userObject) { + public void setUserObject(Object userObject) + { this.userObject = userObject; } - public byte[] exportKeyingMaterial(String asciiLabel, byte[] context_value, int length) { + public byte[] exportKeyingMaterial(String asciiLabel, byte[] context_value, int length) + { SecurityParameters sp = getSecurityParameters(); byte[] cr = sp.getClientRandom(), sr = sp.getServerRandom(); int seedLength = cr.length + sr.length; - if (context_value != null) { + if (context_value != null) + { seedLength += (2 + context_value.length); } @@ -65,14 +78,16 @@ abstract class AbstractTlsContext implements TlsContext { seedPos += cr.length; System.arraycopy(sr, 0, seed, seedPos, sr.length); seedPos += sr.length; - if (context_value != null) { + if (context_value != null) + { TlsUtils.writeUint16(context_value.length, seed, seedPos); seedPos += 2; System.arraycopy(context_value, 0, seed, seedPos, context_value.length); seedPos += context_value.length; } - if (seedPos != seedLength) { + if (seedPos != seedLength) + { throw new IllegalStateException("error in calculation of seed for export"); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsKeyExchange.java b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsKeyExchange.java index bd1945e3..10c5d550 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsKeyExchange.java +++ b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsKeyExchange.java @@ -4,24 +4,29 @@ import java.io.IOException; import java.io.InputStream; import java.util.Vector; -public abstract class AbstractTlsKeyExchange implements TlsKeyExchange { +public abstract class AbstractTlsKeyExchange + implements TlsKeyExchange +{ protected int keyExchange; protected Vector supportedSignatureAlgorithms; protected TlsContext context; - protected AbstractTlsKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms) { + protected AbstractTlsKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms) + { this.keyExchange = keyExchange; this.supportedSignatureAlgorithms = supportedSignatureAlgorithms; } - public void init(TlsContext context) { + public void init(TlsContext context) + { this.context = context; ProtocolVersion clientVersion = context.getClientVersion(); - if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(clientVersion)) { + if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(clientVersion)) + { /* * RFC 5264 7.4.1.4.1. If the client does not send the signature_algorithms extension, @@ -36,18 +41,22 @@ public abstract class AbstractTlsKeyExchange implements TlsKeyExchange { * - If the negotiated key exchange algorithm is one of (ECDH_ECDSA, ECDHE_ECDSA), * behave as if the client had sent value {sha1,ecdsa}. */ - if (this.supportedSignatureAlgorithms == null) { - switch (keyExchange) { + if (this.supportedSignatureAlgorithms == null) + { + switch (keyExchange) + { case KeyExchangeAlgorithm.DH_DSS: case KeyExchangeAlgorithm.DHE_DSS: - case KeyExchangeAlgorithm.SRP_DSS: { + case KeyExchangeAlgorithm.SRP_DSS: + { this.supportedSignatureAlgorithms = TlsUtils.getDefaultDSSSignatureAlgorithms(); break; } case KeyExchangeAlgorithm.ECDH_ECDSA: - case KeyExchangeAlgorithm.ECDHE_ECDSA: { + case KeyExchangeAlgorithm.ECDHE_ECDSA: + { this.supportedSignatureAlgorithms = TlsUtils.getDefaultECDSASignatureAlgorithms(); break; } @@ -58,7 +67,8 @@ public abstract class AbstractTlsKeyExchange implements TlsKeyExchange { case KeyExchangeAlgorithm.ECDHE_RSA: case KeyExchangeAlgorithm.RSA: case KeyExchangeAlgorithm.RSA_PSK: - case KeyExchangeAlgorithm.SRP_RSA: { + case KeyExchangeAlgorithm.SRP_RSA: + { this.supportedSignatureAlgorithms = TlsUtils.getDefaultRSASignatureAlgorithms(); break; } @@ -68,19 +78,26 @@ public abstract class AbstractTlsKeyExchange implements TlsKeyExchange { } } - } else if (this.supportedSignatureAlgorithms != null) { + } + else if (this.supportedSignatureAlgorithms != null) + { throw new IllegalStateException("supported_signature_algorithms not allowed for " + clientVersion); } } - public void processServerCertificate(Certificate serverCertificate) throws IOException { + public void processServerCertificate(Certificate serverCertificate) + throws IOException + { - if (supportedSignatureAlgorithms == null) { + if (supportedSignatureAlgorithms == null) + { /* * TODO RFC 2264 7.4.2. Unless otherwise specified, the signing algorithm for the * certificate must be the same as the algorithm for the certificate key. */ - } else { + } + else + { /* * TODO RFC 5264 7.4.2. If the client provided a "signature_algorithms" extension, then * all certificates provided by the server MUST be signed by a hash/signature algorithm @@ -89,40 +106,58 @@ public abstract class AbstractTlsKeyExchange implements TlsKeyExchange { } } - public void processServerCredentials(TlsCredentials serverCredentials) throws IOException { + public void processServerCredentials(TlsCredentials serverCredentials) + throws IOException + { processServerCertificate(serverCredentials.getCertificate()); } - public boolean requiresServerKeyExchange() { + public boolean requiresServerKeyExchange() + { return false; } - public byte[] generateServerKeyExchange() throws IOException { - if (requiresServerKeyExchange()) { + public byte[] generateServerKeyExchange() + throws IOException + { + if (requiresServerKeyExchange()) + { throw new TlsFatalAlert(AlertDescription.internal_error); } return null; } - public void skipServerKeyExchange() throws IOException { - if (requiresServerKeyExchange()) { + public void skipServerKeyExchange() + throws IOException + { + if (requiresServerKeyExchange()) + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } - public void processServerKeyExchange(InputStream input) throws IOException { - if (!requiresServerKeyExchange()) { + public void processServerKeyExchange(InputStream input) + throws IOException + { + if (!requiresServerKeyExchange()) + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } - public void skipClientCredentials() throws IOException { + public void skipClientCredentials() + throws IOException + { } - public void processClientCertificate(Certificate clientCertificate) throws IOException { + public void processClientCertificate(Certificate clientCertificate) + throws IOException + { } - public void processClientKeyExchange(InputStream input) throws IOException { + public void processClientKeyExchange(InputStream input) + throws IOException + { // Key exchange implementation MUST support client key exchange throw new TlsFatalAlert(AlertDescription.internal_error); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsPeer.java b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsPeer.java index 3a53c58c..74efae31 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsPeer.java +++ b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsPeer.java @@ -1,10 +1,14 @@ package org.bouncycastle.crypto.tls; -public abstract class AbstractTlsPeer implements TlsPeer { +public abstract class AbstractTlsPeer + implements TlsPeer +{ - public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { + public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) + { } - public void notifyAlertReceived(short alertLevel, short alertDescription) { + public void notifyAlertReceived(short alertLevel, short alertDescription) + { } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsServer.java b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsServer.java index b97528da..35ab9fbf 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsServer.java +++ b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsServer.java @@ -4,7 +4,10 @@ import java.io.IOException; import java.util.Hashtable; import java.util.Vector; -public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsServer { +public abstract class AbstractTlsServer + extends AbstractTlsPeer + implements TlsServer +{ protected TlsCipherFactory cipherFactory; @@ -25,33 +28,40 @@ public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsSe protected short selectedCompressionMethod; protected Hashtable serverExtensions; - public AbstractTlsServer() { + public AbstractTlsServer() + { this(new DefaultTlsCipherFactory()); } - public AbstractTlsServer(TlsCipherFactory cipherFactory) { + public AbstractTlsServer(TlsCipherFactory cipherFactory) + { this.cipherFactory = cipherFactory; } protected abstract int[] getCipherSuites(); - protected short[] getCompressionMethods() { - return new short[] { CompressionMethod._null }; + protected short[] getCompressionMethods() + { + return new short[]{CompressionMethod._null}; } - protected ProtocolVersion getMaximumVersion() { + protected ProtocolVersion getMaximumVersion() + { return ProtocolVersion.TLSv11; } - protected ProtocolVersion getMinimumVersion() { + protected ProtocolVersion getMinimumVersion() + { return ProtocolVersion.TLSv10; } - protected boolean supportsClientECCCapabilities(int[] namedCurves, short[] ecPointFormats) { + protected boolean supportsClientECCCapabilities(int[] namedCurves, short[] ecPointFormats) + { // NOTE: BC supports all the current set of point formats so we don't check them here - if (namedCurves == null) { + if (namedCurves == null) + { /* * RFC 4492 4. A client that proposes ECC cipher suites may choose not to include these * extensions. In this case, the server is free to choose any one of the elliptic curves @@ -60,9 +70,11 @@ public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsSe return TlsECCUtils.hasAnySupportedNamedCurves(); } - for (int i = 0; i < namedCurves.length; ++i) { + for (int i = 0; i < namedCurves.length; ++i) + { int namedCurve = namedCurves[i]; - if (!NamedCurve.refersToASpecificNamedCurve(namedCurve) || TlsECCUtils.isSupportedNamedCurve(namedCurve)) { + if (!NamedCurve.refersToASpecificNamedCurve(namedCurve) || TlsECCUtils.isSupportedNamedCurve(namedCurve)) + { return true; } } @@ -70,25 +82,35 @@ public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsSe return false; } - public void init(TlsServerContext context) { + public void init(TlsServerContext context) + { this.context = context; } - public void notifyClientVersion(ProtocolVersion clientVersion) throws IOException { + public void notifyClientVersion(ProtocolVersion clientVersion) + throws IOException + { this.clientVersion = clientVersion; } - public void notifyOfferedCipherSuites(int[] offeredCipherSuites) throws IOException { + public void notifyOfferedCipherSuites(int[] offeredCipherSuites) + throws IOException + { this.offeredCipherSuites = offeredCipherSuites; this.eccCipherSuitesOffered = TlsECCUtils.containsECCCipherSuites(this.offeredCipherSuites); } - public void notifyOfferedCompressionMethods(short[] offeredCompressionMethods) throws IOException { + public void notifyOfferedCompressionMethods(short[] offeredCompressionMethods) + throws IOException + { this.offeredCompressionMethods = offeredCompressionMethods; } - public void notifySecureRenegotiation(boolean secureRenegotiation) throws IOException { - if (!secureRenegotiation) { + public void notifySecureRenegotiation(boolean secureRenegotiation) + throws IOException + { + if (!secureRenegotiation) + { /* * RFC 5746 3.6. In this case, some servers may want to terminate the handshake instead * of continuing; see Section 4.3 for discussion. @@ -97,19 +119,24 @@ public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsSe } } - public void processClientExtensions(Hashtable clientExtensions) throws IOException { + public void processClientExtensions(Hashtable clientExtensions) + throws IOException + { this.clientExtensions = clientExtensions; - if (clientExtensions != null) { + if (clientExtensions != null) + { this.supportedSignatureAlgorithms = TlsUtils.getSignatureAlgorithmsExtension(clientExtensions); - if (this.supportedSignatureAlgorithms != null) { + if (this.supportedSignatureAlgorithms != null) + { /* * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior * to 1.2. Clients MUST NOT offer it if they are offering prior versions. */ - if (!TlsUtils.isSignatureAlgorithmsExtensionAllowed(clientVersion)) { + if (!TlsUtils.isSignatureAlgorithmsExtensionAllowed(clientVersion)) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } @@ -122,25 +149,33 @@ public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsSe * RFC 4429 4. The client MUST NOT include these extensions in the ClientHello message if it * does not propose any ECC cipher suites. */ - if (!this.eccCipherSuitesOffered && (this.namedCurves != null || this.clientECPointFormats != null)) { + if (!this.eccCipherSuitesOffered && (this.namedCurves != null || this.clientECPointFormats != null)) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } - public ProtocolVersion getServerVersion() throws IOException { - if (getMinimumVersion().isEqualOrEarlierVersionOf(clientVersion)) { + public ProtocolVersion getServerVersion() + throws IOException + { + if (getMinimumVersion().isEqualOrEarlierVersionOf(clientVersion)) + { ProtocolVersion maximumVersion = getMaximumVersion(); - if (clientVersion.isEqualOrEarlierVersionOf(maximumVersion)) { + if (clientVersion.isEqualOrEarlierVersionOf(maximumVersion)) + { return serverVersion = clientVersion; } - if (clientVersion.isLaterVersionOf(maximumVersion)) { + if (clientVersion.isLaterVersionOf(maximumVersion)) + { return serverVersion = maximumVersion; } } throw new TlsFatalAlert(AlertDescription.protocol_version); } - public int getSelectedCipherSuite() throws IOException { + public int getSelectedCipherSuite() + throws IOException + { /* * TODO RFC 5246 7.4.3. In order to negotiate correctly, the server MUST check any candidate @@ -159,20 +194,26 @@ public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsSe boolean eccCipherSuitesEnabled = supportsClientECCCapabilities(this.namedCurves, this.clientECPointFormats); int[] cipherSuites = getCipherSuites(); - for (int i = 0; i < cipherSuites.length; ++i) { + for (int i = 0; i < cipherSuites.length; ++i) + { int cipherSuite = cipherSuites[i]; if (TlsProtocol.arrayContains(this.offeredCipherSuites, cipherSuite) - && (eccCipherSuitesEnabled || !TlsECCUtils.isECCCipherSuite(cipherSuite))) { + && (eccCipherSuitesEnabled || !TlsECCUtils.isECCCipherSuite(cipherSuite))) + { return this.selectedCipherSuite = cipherSuite; } } throw new TlsFatalAlert(AlertDescription.handshake_failure); } - public short getSelectedCompressionMethod() throws IOException { + public short getSelectedCompressionMethod() + throws IOException + { short[] compressionMethods = getCompressionMethods(); - for (int i = 0; i < compressionMethods.length; ++i) { - if (TlsProtocol.arrayContains(offeredCompressionMethods, compressionMethods[i])) { + for (int i = 0; i < compressionMethods.length; ++i) + { + if (TlsProtocol.arrayContains(offeredCompressionMethods, compressionMethods[i])) + { return this.selectedCompressionMethod = compressionMethods[i]; } } @@ -180,16 +221,19 @@ public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsSe } // Hashtable is (Integer -> byte[]) - public Hashtable getServerExtensions() throws IOException { + public Hashtable getServerExtensions() + throws IOException + { - if (this.clientECPointFormats != null && TlsECCUtils.isECCCipherSuite(this.selectedCipherSuite)) { + if (this.clientECPointFormats != null && TlsECCUtils.isECCCipherSuite(this.selectedCipherSuite)) + { /* * RFC 4492 5.2. A server that selects an ECC cipher suite in response to a ClientHello * message including a Supported Point Formats Extension appends this extension (along * with others) to its ServerHello message, enumerating the point formats it can parse. */ - this.serverECPointFormats = new short[] { ECPointFormat.ansiX962_compressed_char2, - ECPointFormat.ansiX962_compressed_prime, ECPointFormat.uncompressed }; + this.serverECPointFormats = new short[]{ECPointFormat.ansiX962_compressed_char2, + ECPointFormat.ansiX962_compressed_prime, ECPointFormat.uncompressed}; this.serverExtensions = new Hashtable(); TlsECCUtils.addSupportedPointFormatsExtension(serverExtensions, serverECPointFormats); @@ -199,26 +243,37 @@ public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsSe return null; } - public Vector getServerSupplementalData() throws IOException { + public Vector getServerSupplementalData() + throws IOException + { return null; } - public CertificateRequest getCertificateRequest() { + public CertificateRequest getCertificateRequest() + { return null; } - public void processClientSupplementalData(Vector clientSupplementalData) throws IOException { - if (clientSupplementalData != null) { + public void processClientSupplementalData(Vector clientSupplementalData) + throws IOException + { + if (clientSupplementalData != null) + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } - public void notifyClientCertificate(Certificate clientCertificate) throws IOException { + public void notifyClientCertificate(Certificate clientCertificate) + throws IOException + { throw new TlsFatalAlert(AlertDescription.internal_error); } - public TlsCompression getCompression() throws IOException { - switch (selectedCompressionMethod) { + public TlsCompression getCompression() + throws IOException + { + switch (selectedCompressionMethod) + { case CompressionMethod._null: return new TlsNullCompression(); @@ -231,7 +286,9 @@ public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsSe } } - public NewSessionTicket getNewSessionTicket() throws IOException { + public NewSessionTicket getNewSessionTicket() + throws IOException + { /* * RFC 5077 3.3. If the server determines that it does not want to include a ticket after it * has included the SessionTicket extension in the ServerHello, then it sends a zero-length @@ -240,6 +297,8 @@ public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsSe return new NewSessionTicket(0L, TlsUtils.EMPTY_BYTES); } - public void notifyHandshakeComplete() throws IOException { + public void notifyHandshakeComplete() + throws IOException + { } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsSigner.java b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsSigner.java index 9884a6f8..3d19037a 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsSigner.java +++ b/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsSigner.java @@ -1,10 +1,13 @@ package org.bouncycastle.crypto.tls; -public abstract class AbstractTlsSigner implements TlsSigner { +public abstract class AbstractTlsSigner + implements TlsSigner +{ protected TlsContext context; - public void init(TlsContext context) { + public void init(TlsContext context) + { this.context = context; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/AlertDescription.java b/src/main/java/org/bouncycastle/crypto/tls/AlertDescription.java index 31e93e04..5e3269bd 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/AlertDescription.java +++ b/src/main/java/org/bouncycastle/crypto/tls/AlertDescription.java @@ -3,7 +3,8 @@ package org.bouncycastle.crypto.tls; /** * RFC 5246 7.2. */ -public class AlertDescription { +public class AlertDescription +{ /** * This message notifies the recipient that the sender will not send any more messages on this diff --git a/src/main/java/org/bouncycastle/crypto/tls/AlwaysValidVerifyer.java b/src/main/java/org/bouncycastle/crypto/tls/AlwaysValidVerifyer.java index 4afb410e..bf4cd13b 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/AlwaysValidVerifyer.java +++ b/src/main/java/org/bouncycastle/crypto/tls/AlwaysValidVerifyer.java @@ -2,18 +2,19 @@ package org.bouncycastle.crypto.tls; /** * A certificate verifyer, that will always return true. - * + *

*

  * DO NOT USE THIS FILE UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING.
  * 
- * + * * @deprecated Perform certificate verification in TlsAuthentication implementation */ -public class AlwaysValidVerifyer implements CertificateVerifyer +public class AlwaysValidVerifyer + implements CertificateVerifyer { /** * Return true. - * + * * @see org.bouncycastle.crypto.tls.CertificateVerifyer#isValid(org.bouncycastle.asn1.x509.Certificate[]) */ public boolean isValid(org.bouncycastle.asn1.x509.Certificate[] certs) diff --git a/src/main/java/org/bouncycastle/crypto/tls/BulkCipherAlgorithm.java b/src/main/java/org/bouncycastle/crypto/tls/BulkCipherAlgorithm.java index 50d33c36..6595534b 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/BulkCipherAlgorithm.java +++ b/src/main/java/org/bouncycastle/crypto/tls/BulkCipherAlgorithm.java @@ -2,11 +2,12 @@ package org.bouncycastle.crypto.tls; /** * RFC 2246 - * + *

* Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ -public class BulkCipherAlgorithm { +public class BulkCipherAlgorithm +{ public static final int _null = 0; public static final int rc4 = 1; diff --git a/src/main/java/org/bouncycastle/crypto/tls/ByteQueue.java b/src/main/java/org/bouncycastle/crypto/tls/ByteQueue.java index f017897c..8b9d4ab1 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/ByteQueue.java +++ b/src/main/java/org/bouncycastle/crypto/tls/ByteQueue.java @@ -44,11 +44,11 @@ public class ByteQueue /** * Read data from the buffer. - * - * @param buf The buffer where the read data will be copied to. + * + * @param buf The buffer where the read data will be copied to. * @param offset How many bytes to skip at the beginning of buf. - * @param len How many bytes to read at all. - * @param skip How many bytes from our data to skip. + * @param len How many bytes to read at all. + * @param skip How many bytes from our data to skip. */ public void read(byte[] buf, int offset, int len, int skip) { @@ -67,10 +67,10 @@ public class ByteQueue /** * Add some data to our buffer. - * - * @param data A byte-array to read data from. + * + * @param data A byte-array to read data from. * @param offset How many bytes to skip at the beginning of the array. - * @param len How many bytes to read from the array. + * @param len How many bytes to read from the array. */ public void addData(byte[] data, int offset, int len) { @@ -87,7 +87,7 @@ public class ByteQueue /** * Remove some bytes from our data from the beginning. - * + * * @param i How many bytes to remove. */ public void removeData(int i) diff --git a/src/main/java/org/bouncycastle/crypto/tls/Certificate.java b/src/main/java/org/bouncycastle/crypto/tls/Certificate.java index c16d8b13..cdb8ff6e 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/Certificate.java +++ b/src/main/java/org/bouncycastle/crypto/tls/Certificate.java @@ -12,26 +12,29 @@ import org.bouncycastle.asn1.ASN1Primitive; /** * Parsing and encoding of a Certificate struct from RFC 4346. - * + *

*

  * opaque ASN.1Cert<2^24-1>;
- * 
+ *
  * struct {
  *     ASN.1Cert certificate_list<0..2^24-1>;
  * } Certificate;
  * 
- * + * * @see org.bouncycastle.asn1.x509.Certificate */ -public class Certificate { +public class Certificate +{ public static final Certificate EMPTY_CHAIN = new Certificate( new org.bouncycastle.asn1.x509.Certificate[0]); protected org.bouncycastle.asn1.x509.Certificate[] certificateList; - public Certificate(org.bouncycastle.asn1.x509.Certificate[] certificateList) { - if (certificateList == null) { + public Certificate(org.bouncycastle.asn1.x509.Certificate[] certificateList) + { + if (certificateList == null) + { throw new IllegalArgumentException("'certificateList' cannot be null"); } @@ -41,7 +44,8 @@ public class Certificate { /** * @deprecated use {@link #getCertificateList()} instead */ - public org.bouncycastle.asn1.x509.Certificate[] getCerts() { + public org.bouncycastle.asn1.x509.Certificate[] getCerts() + { return certificateList.clone(); } @@ -49,15 +53,18 @@ public class Certificate { * @return an array of {@link org.bouncycastle.asn1.x509.Certificate} representing a certificate * chain. */ - public org.bouncycastle.asn1.x509.Certificate[] getCertificateList() { + public org.bouncycastle.asn1.x509.Certificate[] getCertificateList() + { return certificateList.clone(); } - public org.bouncycastle.asn1.x509.Certificate getCertificateAt(int index) { + public org.bouncycastle.asn1.x509.Certificate getCertificateAt(int index) + { return certificateList[index]; } - public int getLength() { + public int getLength() + { return certificateList.length; } @@ -65,21 +72,24 @@ public class Certificate { * @return true if this certificate chain contains no certificates, or * false otherwise. */ - public boolean isEmpty() { + public boolean isEmpty() + { return certificateList.length == 0; } /** * Encode this {@link Certificate} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. + * + * @param output the {@link OutputStream} to encode to. * @throws IOException */ - public void encode(OutputStream output) throws IOException { + public void encode(OutputStream output) + throws IOException + { Vector encCerts = new Vector(this.certificateList.length); int totalLength = 0; - for (int i = 0; i < this.certificateList.length; ++i) { + for (int i = 0; i < this.certificateList.length; ++i) + { byte[] encCert = certificateList[i].getEncoded(ASN1Encoding.DER); encCerts.addElement(encCert); totalLength += encCert.length + 3; @@ -87,28 +97,32 @@ public class Certificate { TlsUtils.writeUint24(totalLength, output); - for (int i = 0; i < encCerts.size(); ++i) { - byte[] encCert = (byte[]) encCerts.elementAt(i); + for (int i = 0; i < encCerts.size(); ++i) + { + byte[] encCert = (byte[])encCerts.elementAt(i); TlsUtils.writeOpaque24(encCert, output); } } /** * Parse a {@link Certificate} from an {@link InputStream}. - * - * @param input - * the {@link InputStream} to parse from. + * + * @param input the {@link InputStream} to parse from. * @return a {@link Certificate} object. * @throws IOException */ - public static Certificate parse(InputStream input) throws IOException { + public static Certificate parse(InputStream input) + throws IOException + { org.bouncycastle.asn1.x509.Certificate[] certs; int left = TlsUtils.readUint24(input); - if (left == 0) { + if (left == 0) + { return EMPTY_CHAIN; } Vector tmp = new Vector(); - while (left > 0) { + while (left > 0) + { int size = TlsUtils.readUint24(input); left -= 3 + size; @@ -121,8 +135,9 @@ public class Certificate { tmp.addElement(org.bouncycastle.asn1.x509.Certificate.getInstance(asn1)); } certs = new org.bouncycastle.asn1.x509.Certificate[tmp.size()]; - for (int i = 0; i < tmp.size(); i++) { - certs[i] = (org.bouncycastle.asn1.x509.Certificate) tmp.elementAt(i); + for (int i = 0; i < tmp.size(); i++) + { + certs[i] = (org.bouncycastle.asn1.x509.Certificate)tmp.elementAt(i); } return new Certificate(certs); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/CertificateRequest.java b/src/main/java/org/bouncycastle/crypto/tls/CertificateRequest.java index 9d661d2d..7b6f9a01 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/CertificateRequest.java +++ b/src/main/java/org/bouncycastle/crypto/tls/CertificateRequest.java @@ -12,18 +12,19 @@ import org.bouncycastle.asn1.x500.X500Name; /** * Parsing and encoding of a CertificateRequest struct from RFC 4346. - * + *

*

  * struct {
  *     ClientCertificateType certificate_types<1..2^8-1>;
  *     DistinguishedName certificate_authorities<3..2^16-1>;
  * } CertificateRequest;
  * 
- * + * * @see ClientCertificateType * @see X500Name */ -public class CertificateRequest { +public class CertificateRequest +{ private short[] certificateTypes; private Vector certificateAuthorities; @@ -33,56 +34,64 @@ public class CertificateRequest { */ /** - * @param certificateTypes - * see {@link ClientCertificateType} for valid constants. - * @param certificateAuthorities - * a {@link Vector} of {@link X500Name}. + * @param certificateTypes see {@link ClientCertificateType} for valid constants. + * @param certificateAuthorities a {@link Vector} of {@link X500Name}. */ - public CertificateRequest(short[] certificateTypes, Vector certificateAuthorities) { + public CertificateRequest(short[] certificateTypes, Vector certificateAuthorities) + { this.certificateTypes = certificateTypes; this.certificateAuthorities = certificateAuthorities; } /** * @return an array of certificate types - * * @see {@link ClientCertificateType} */ - public short[] getCertificateTypes() { + public short[] getCertificateTypes() + { return certificateTypes; } /** * @return a {@link Vector} of {@link X500Name} */ - public Vector getCertificateAuthorities() { + public Vector getCertificateAuthorities() + { return certificateAuthorities; } /** * Encode this {@link CertificateRequest} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. + * + * @param output the {@link OutputStream} to encode to. * @throws IOException */ - public void encode(OutputStream output) throws IOException { + public void encode(OutputStream output) + throws IOException + { - if (certificateTypes == null || certificateTypes.length == 0) { - TlsUtils.writeUint8((short) 0, output); - } else { - TlsUtils.writeUint8((short) certificateTypes.length, output); + if (certificateTypes == null || certificateTypes.length == 0) + { + TlsUtils.writeUint8((short)0, output); + } + else + { + TlsUtils.writeUint8((short)certificateTypes.length, output); TlsUtils.writeUint8Array(certificateTypes, output); } - if (certificateAuthorities == null || certificateAuthorities.isEmpty()) { + if (certificateAuthorities == null || certificateAuthorities.isEmpty()) + { TlsUtils.writeUint16(0, output); - } else { + } + else + { Vector encDNs = new Vector(certificateAuthorities.size()); int totalLength = 0; - for (int i = 0; i < certificateAuthorities.size(); ++i) { - X500Name authorityDN = (X500Name) certificateAuthorities.get(i); + for (int i = 0; i < certificateAuthorities.size(); ++i) + { + X500Name authorityDN = (X500Name)certificateAuthorities.get(i); byte[] encDN = authorityDN.getEncoded(ASN1Encoding.DER); encDNs.addElement(encDN); totalLength += encDN.length; @@ -90,8 +99,9 @@ public class CertificateRequest { TlsUtils.writeUint16(totalLength, output); - for (int i = 0; i < encDNs.size(); ++i) { - byte[] encDN = (byte[]) encDNs.elementAt(i); + for (int i = 0; i < encDNs.size(); ++i) + { + byte[] encDN = (byte[])encDNs.elementAt(i); output.write(encDN); } } @@ -99,16 +109,18 @@ public class CertificateRequest { /** * Parse a {@link CertificateRequest} from an {@link InputStream}. - * - * @param input - * the {@link InputStream} to parse from. + * + * @param input the {@link InputStream} to parse from. * @return a {@link CertificateRequest} object. * @throws IOException */ - public static CertificateRequest parse(InputStream input) throws IOException { + public static CertificateRequest parse(InputStream input) + throws IOException + { int numTypes = TlsUtils.readUint8(input); short[] certificateTypes = new short[numTypes]; - for (int i = 0; i < numTypes; ++i) { + for (int i = 0; i < numTypes; ++i) + { certificateTypes[i] = TlsUtils.readUint8(input); } @@ -117,7 +129,8 @@ public class CertificateRequest { Vector authorityDNs = new Vector(); ByteArrayInputStream bis = new ByteArrayInputStream(authorities); - while (bis.available() > 0) { + while (bis.available() > 0) + { byte[] dnBytes = TlsUtils.readOpaque16(bis); authorityDNs.addElement(X500Name.getInstance(ASN1Primitive.fromByteArray(dnBytes))); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/CertificateVerifyer.java b/src/main/java/org/bouncycastle/crypto/tls/CertificateVerifyer.java index 95877a3e..2e3715c1 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/CertificateVerifyer.java +++ b/src/main/java/org/bouncycastle/crypto/tls/CertificateVerifyer.java @@ -3,7 +3,7 @@ package org.bouncycastle.crypto.tls; /** * This should be implemented by any class which can find out, if a given certificate * chain is being accepted by an client. - * + * * @deprecated Perform certificate verification in TlsAuthentication implementation */ public interface CertificateVerifyer diff --git a/src/main/java/org/bouncycastle/crypto/tls/CipherSuite.java b/src/main/java/org/bouncycastle/crypto/tls/CipherSuite.java index 7d34f015..24dcfd33 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/CipherSuite.java +++ b/src/main/java/org/bouncycastle/crypto/tls/CipherSuite.java @@ -3,7 +3,8 @@ package org.bouncycastle.crypto.tls; /** * RFC 2246 A.5 */ -public class CipherSuite { +public class CipherSuite +{ public static final int TLS_NULL_WITH_NULL_NULL = 0x0000; public static final int TLS_RSA_WITH_NULL_MD5 = 0x0001; diff --git a/src/main/java/org/bouncycastle/crypto/tls/CipherType.java b/src/main/java/org/bouncycastle/crypto/tls/CipherType.java index 7232b85d..7c7ceaff 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/CipherType.java +++ b/src/main/java/org/bouncycastle/crypto/tls/CipherType.java @@ -2,11 +2,12 @@ package org.bouncycastle.crypto.tls; /** * RFC 2246 - * + *

* Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ -public class CipherType { +public class CipherType +{ public static final int stream = 0; public static final int block = 1; diff --git a/src/main/java/org/bouncycastle/crypto/tls/ClientAuthenticationType.java b/src/main/java/org/bouncycastle/crypto/tls/ClientAuthenticationType.java index f689dde6..00c4fae8 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/ClientAuthenticationType.java +++ b/src/main/java/org/bouncycastle/crypto/tls/ClientAuthenticationType.java @@ -1,6 +1,7 @@ package org.bouncycastle.crypto.tls; -public class ClientAuthenticationType { +public class ClientAuthenticationType +{ /* * RFC 5077 4 diff --git a/src/main/java/org/bouncycastle/crypto/tls/ClientCertificateType.java b/src/main/java/org/bouncycastle/crypto/tls/ClientCertificateType.java index 6f1c871e..baa33c27 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/ClientCertificateType.java +++ b/src/main/java/org/bouncycastle/crypto/tls/ClientCertificateType.java @@ -1,6 +1,7 @@ package org.bouncycastle.crypto.tls; -public class ClientCertificateType { +public class ClientCertificateType +{ /* * RFC 4346 7.4.4 diff --git a/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java b/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java index 8dcbda93..b9330267 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java +++ b/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java @@ -5,70 +5,83 @@ import org.bouncycastle.crypto.Digest; /** * A combined hash, which implements md5(m) || sha1(m). */ -class CombinedHash implements TlsHandshakeHash { +class CombinedHash + implements TlsHandshakeHash +{ protected TlsContext context; protected Digest md5; protected Digest sha1; - CombinedHash() { + CombinedHash() + { this.md5 = TlsUtils.createHash(HashAlgorithm.md5); this.sha1 = TlsUtils.createHash(HashAlgorithm.sha1); } - CombinedHash(CombinedHash t) { + CombinedHash(CombinedHash t) + { this.context = t.context; this.md5 = TlsUtils.cloneHash(HashAlgorithm.md5, t.md5); this.sha1 = TlsUtils.cloneHash(HashAlgorithm.sha1, t.sha1); } - public void init(TlsContext context) { + public void init(TlsContext context) + { this.context = context; } - public TlsHandshakeHash commit() { + public TlsHandshakeHash commit() + { return this; } - public TlsHandshakeHash fork() { + public TlsHandshakeHash fork() + { return new CombinedHash(this); } /** * @see org.bouncycastle.crypto.Digest#getAlgorithmName() */ - public String getAlgorithmName() { + public String getAlgorithmName() + { return md5.getAlgorithmName() + " and " + sha1.getAlgorithmName(); } /** * @see org.bouncycastle.crypto.Digest#getDigestSize() */ - public int getDigestSize() { + public int getDigestSize() + { return md5.getDigestSize() + sha1.getDigestSize(); } /** * @see org.bouncycastle.crypto.Digest#update(byte) */ - public void update(byte in) { + public void update(byte in) + { md5.update(in); sha1.update(in); } /** - * @see org.bouncycastle.crypto.Digest#update(byte[],int,int) + * @see org.bouncycastle.crypto.Digest#update(byte[], int, int) */ - public void update(byte[] in, int inOff, int len) { + public void update(byte[] in, int inOff, int len) + { md5.update(in, inOff, len); sha1.update(in, inOff, len); } /** - * @see org.bouncycastle.crypto.Digest#doFinal(byte[],int) + * @see org.bouncycastle.crypto.Digest#doFinal(byte[], int) */ - public int doFinal(byte[] out, int outOff) { - if (context != null && context.getServerVersion().isSSL()) { + public int doFinal(byte[] out, int outOff) + { + if (context != null && context.getServerVersion().isSSL()) + { ssl3Complete(md5, SSL3Mac.IPAD, SSL3Mac.OPAD, 48); ssl3Complete(sha1, SSL3Mac.IPAD, SSL3Mac.OPAD, 40); } @@ -81,12 +94,14 @@ class CombinedHash implements TlsHandshakeHash { /** * @see org.bouncycastle.crypto.Digest#reset() */ - public void reset() { + public void reset() + { md5.reset(); sha1.reset(); } - protected void ssl3Complete(Digest d, byte[] ipad, byte[] opad, int padLength) { + protected void ssl3Complete(Digest d, byte[] ipad, byte[] opad, int padLength) + { byte[] secret = context.getSecurityParameters().masterSecret; d.update(secret, 0, secret.length); diff --git a/src/main/java/org/bouncycastle/crypto/tls/ConnectionEnd.java b/src/main/java/org/bouncycastle/crypto/tls/ConnectionEnd.java index dedfb068..991297d7 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/ConnectionEnd.java +++ b/src/main/java/org/bouncycastle/crypto/tls/ConnectionEnd.java @@ -2,11 +2,12 @@ package org.bouncycastle.crypto.tls; /** * RFC 2246 - * + *

* Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ -public class ConnectionEnd { +public class ConnectionEnd +{ public static final int server = 0; public static final int client = 1; diff --git a/src/main/java/org/bouncycastle/crypto/tls/DTLSClientProtocol.java b/src/main/java/org/bouncycastle/crypto/tls/DTLSClientProtocol.java index 20226963..6344f21b 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DTLSClientProtocol.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DTLSClientProtocol.java @@ -10,18 +10,27 @@ import java.util.Vector; import org.bouncycastle.util.Arrays; -public class DTLSClientProtocol extends DTLSProtocol { +public class DTLSClientProtocol + extends DTLSProtocol +{ - public DTLSClientProtocol(SecureRandom secureRandom) { + public DTLSClientProtocol(SecureRandom secureRandom) + { super(secureRandom); } - public DTLSTransport connect(TlsClient client, DatagramTransport transport) throws IOException { + public DTLSTransport connect(TlsClient client, DatagramTransport transport) + throws IOException + { if (client == null) + { throw new IllegalArgumentException("'client' cannot be null"); + } if (transport == null) + { throw new IllegalArgumentException("'transport' cannot be null"); + } SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = ConnectionEnd.client; @@ -34,21 +43,30 @@ public class DTLSClientProtocol extends DTLSProtocol { DTLSRecordLayer recordLayer = new DTLSRecordLayer(transport, state.clientContext, client, ContentType.handshake); - try { + try + { return clientHandshake(state, recordLayer); - } catch (TlsFatalAlert fatalAlert) { + } + catch (TlsFatalAlert fatalAlert) + { recordLayer.fail(fatalAlert.getAlertDescription()); throw fatalAlert; - } catch (IOException e) { + } + catch (IOException e) + { recordLayer.fail(AlertDescription.internal_error); throw e; - } catch (RuntimeException e) { + } + catch (RuntimeException e) + { recordLayer.fail(AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error); } } - protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLayer recordLayer) throws IOException { + protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLayer recordLayer) + throws IOException + { SecurityParameters securityParameters = state.clientContext.getSecurityParameters(); DTLSReliableHandshake handshake = new DTLSReliableHandshake(state.clientContext, recordLayer); @@ -63,7 +81,8 @@ public class DTLSClientProtocol extends DTLSProtocol { ProtocolVersion server_version = recordLayer.getDiscoveredPeerVersion(); ProtocolVersion client_version = state.clientContext.getClientVersion(); - if (!server_version.isEqualOrEarlierVersionOf(client_version)) { + if (!server_version.isEqualOrEarlierVersionOf(client_version)) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } @@ -71,7 +90,8 @@ public class DTLSClientProtocol extends DTLSProtocol { state.client.notifyServerVersion(server_version); } - while (serverMessage.getType() == HandshakeType.hello_verify_request) { + while (serverMessage.getType() == HandshakeType.hello_verify_request) + { byte[] cookie = parseHelloVerifyRequest(state.clientContext, serverMessage.getBody()); byte[] patched = patchClientHelloWithCookie(clientHelloBody, cookie); @@ -81,10 +101,13 @@ public class DTLSClientProtocol extends DTLSProtocol { serverMessage = handshake.receiveMessage(); } - if (serverMessage.getType() == HandshakeType.server_hello) { + if (serverMessage.getType() == HandshakeType.server_hello) + { processServerHello(state, serverMessage.getBody()); serverMessage = handshake.receiveMessage(); - } else { + } + else + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } @@ -99,54 +122,72 @@ public class DTLSClientProtocol extends DTLSProtocol { handshake.notifyHelloComplete(); - if (serverMessage.getType() == HandshakeType.supplemental_data) { + if (serverMessage.getType() == HandshakeType.supplemental_data) + { processServerSupplementalData(state, serverMessage.getBody()); serverMessage = handshake.receiveMessage(); - } else { + } + else + { state.client.processServerSupplementalData(null); } state.keyExchange = state.client.getKeyExchange(); state.keyExchange.init(state.clientContext); - if (serverMessage.getType() == HandshakeType.certificate) { + if (serverMessage.getType() == HandshakeType.certificate) + { processServerCertificate(state, serverMessage.getBody()); serverMessage = handshake.receiveMessage(); - } else { + } + else + { // Okay, Certificate is optional state.keyExchange.skipServerCredentials(); } - if (serverMessage.getType() == HandshakeType.server_key_exchange) { + if (serverMessage.getType() == HandshakeType.server_key_exchange) + { processServerKeyExchange(state, serverMessage.getBody()); serverMessage = handshake.receiveMessage(); - } else { + } + else + { // Okay, ServerKeyExchange is optional state.keyExchange.skipServerKeyExchange(); } - if (serverMessage.getType() == HandshakeType.certificate_request) { + if (serverMessage.getType() == HandshakeType.certificate_request) + { processCertificateRequest(state, serverMessage.getBody()); serverMessage = handshake.receiveMessage(); - } else { + } + else + { // Okay, CertificateRequest is optional } - if (serverMessage.getType() == HandshakeType.server_hello_done) { - if (serverMessage.getBody().length != 0) { + if (serverMessage.getType() == HandshakeType.server_hello_done) + { + if (serverMessage.getBody().length != 0) + { throw new TlsFatalAlert(AlertDescription.decode_error); } - } else { + } + else + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } Vector clientSupplementalData = state.client.getClientSupplementalData(); - if (clientSupplementalData != null) { + if (clientSupplementalData != null) + { byte[] supplementalDataBody = generateSupplementalData(clientSupplementalData); handshake.sendMessage(HandshakeType.supplemental_data, supplementalDataBody); } - if (state.certificateRequest != null) { + if (state.certificateRequest != null) + { state.clientCredentials = state.authentication.getClientCredentials(state.certificateRequest); /* @@ -156,10 +197,12 @@ public class DTLSClientProtocol extends DTLSProtocol { * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ Certificate clientCertificate = null; - if (state.clientCredentials != null) { + if (state.clientCredentials != null) + { clientCertificate = state.clientCredentials.getCertificate(); } - if (clientCertificate == null) { + if (clientCertificate == null) + { clientCertificate = Certificate.EMPTY_CHAIN; } @@ -167,9 +210,12 @@ public class DTLSClientProtocol extends DTLSProtocol { handshake.sendMessage(HandshakeType.certificate, certificateBody); } - if (state.clientCredentials != null) { + if (state.clientCredentials != null) + { state.keyExchange.processClientCredentials(state.clientCredentials); - } else { + } + else + { state.keyExchange.skipClientCredentials(); } @@ -178,12 +224,13 @@ public class DTLSClientProtocol extends DTLSProtocol { TlsProtocol.establishMasterSecret(state.clientContext, state.keyExchange); - if (state.clientCredentials instanceof TlsSignerCredentials) { + if (state.clientCredentials instanceof TlsSignerCredentials) + { /* * TODO RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm prepended * from TLS 1.2 */ - TlsSignerCredentials signerCredentials = (TlsSignerCredentials) state.clientCredentials; + TlsSignerCredentials signerCredentials = (TlsSignerCredentials)state.clientCredentials; byte[] md5andsha1 = handshake.getCurrentHash(); byte[] signature = signerCredentials.generateCertificateSignature(md5andsha1); byte[] certificateVerifyBody = generateCertificateVerify(state, signature); @@ -197,11 +244,15 @@ public class DTLSClientProtocol extends DTLSProtocol { handshake.getCurrentHash()); handshake.sendMessage(HandshakeType.finished, clientVerifyData); - if (state.expectSessionTicket) { + if (state.expectSessionTicket) + { serverMessage = handshake.receiveMessage(); - if (serverMessage.getType() == HandshakeType.session_ticket) { + if (serverMessage.getType() == HandshakeType.session_ticket) + { processNewSessionTicket(state, serverMessage.getBody()); - } else { + } + else + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } @@ -211,9 +262,12 @@ public class DTLSClientProtocol extends DTLSProtocol { handshake.getCurrentHash()); serverMessage = handshake.receiveMessage(); - if (serverMessage.getType() == HandshakeType.finished) { + if (serverMessage.getType() == HandshakeType.finished) + { processFinished(serverMessage.getBody(), expectedServerVerifyData); - } else { + } + else + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } @@ -224,19 +278,24 @@ public class DTLSClientProtocol extends DTLSProtocol { return new DTLSTransport(recordLayer); } - protected byte[] generateCertificateVerify(ClientHandshakeState state, byte[] signature) throws IOException { + protected byte[] generateCertificateVerify(ClientHandshakeState state, byte[] signature) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeOpaque16(signature, buf); return buf.toByteArray(); } - protected byte[] generateClientHello(ClientHandshakeState state, TlsClient client) throws IOException { + protected byte[] generateClientHello(ClientHandshakeState state, TlsClient client) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); ProtocolVersion client_version = client.getClientVersion(); - if (!client_version.isDTLS()) { + if (!client_version.isDTLS()) + { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -270,7 +329,8 @@ public class DTLSClientProtocol extends DTLSProtocol { || state.clientExtensions.get(TlsProtocol.EXT_RenegotiationInfo) == null; int count = state.offeredCipherSuites.length; - if (noRenegExt) { + if (noRenegExt) + { // Note: 1 extra slot for TLS_EMPTY_RENEGOTIATION_INFO_SCSV ++count; } @@ -278,7 +338,8 @@ public class DTLSClientProtocol extends DTLSProtocol { TlsUtils.writeUint16(2 * count, buf); TlsUtils.writeUint16Array(state.offeredCipherSuites, buf); - if (noRenegExt) { + if (noRenegExt) + { TlsUtils.writeUint16(CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV, buf); } } @@ -286,29 +347,35 @@ public class DTLSClientProtocol extends DTLSProtocol { // TODO Add support for compression // Compression methods // state.offeredCompressionMethods = client.getCompressionMethods(); - state.offeredCompressionMethods = new short[] { CompressionMethod._null }; + state.offeredCompressionMethods = new short[]{CompressionMethod._null}; - TlsUtils.writeUint8((short) state.offeredCompressionMethods.length, buf); + TlsUtils.writeUint8((short)state.offeredCompressionMethods.length, buf); TlsUtils.writeUint8Array(state.offeredCompressionMethods, buf); // Extensions - if (state.clientExtensions != null) { + if (state.clientExtensions != null) + { TlsProtocol.writeExtensions(buf, state.clientExtensions); } return buf.toByteArray(); } - protected byte[] generateClientKeyExchange(ClientHandshakeState state) throws IOException { + protected byte[] generateClientKeyExchange(ClientHandshakeState state) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); state.keyExchange.generateClientKeyExchange(buf); return buf.toByteArray(); } - protected void processCertificateRequest(ClientHandshakeState state, byte[] body) throws IOException { + protected void processCertificateRequest(ClientHandshakeState state, byte[] body) + throws IOException + { - if (state.authentication == null) { + if (state.authentication == null) + { /* * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server to * request client identification. @@ -325,7 +392,9 @@ public class DTLSClientProtocol extends DTLSProtocol { state.keyExchange.validateCertificateRequest(state.certificateRequest); } - protected void processNewSessionTicket(ClientHandshakeState state, byte[] body) throws IOException { + protected void processNewSessionTicket(ClientHandshakeState state, byte[] body) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(body); @@ -336,7 +405,9 @@ public class DTLSClientProtocol extends DTLSProtocol { state.client.notifyNewSessionTicket(newSessionTicket); } - protected void processServerCertificate(ClientHandshakeState state, byte[] body) throws IOException { + protected void processServerCertificate(ClientHandshakeState state, byte[] body) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(body); @@ -349,7 +420,9 @@ public class DTLSClientProtocol extends DTLSProtocol { state.authentication.notifyServerCertificate(serverCertificate); } - protected void processServerHello(ClientHandshakeState state, byte[] body) throws IOException { + protected void processServerHello(ClientHandshakeState state, byte[] body) + throws IOException + { SecurityParameters securityParameters = state.clientContext.getSecurityParameters(); @@ -357,14 +430,16 @@ public class DTLSClientProtocol extends DTLSProtocol { // TODO Read RFCs for guidance on the expected record layer version number ProtocolVersion server_version = TlsUtils.readVersion(buf); - if (!server_version.equals(state.clientContext.getServerVersion())) { + if (!server_version.equals(state.clientContext.getServerVersion())) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } securityParameters.serverRandom = TlsUtils.readFully(32, buf); byte[] sessionID = TlsUtils.readOpaque8(buf); - if (sessionID.length > 32) { + if (sessionID.length > 32) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } state.client.notifySessionID(sessionID); @@ -372,7 +447,8 @@ public class DTLSClientProtocol extends DTLSProtocol { state.selectedCipherSuite = TlsUtils.readUint16(buf); if (!TlsProtocol.arrayContains(state.offeredCipherSuites, state.selectedCipherSuite) || state.selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL - || state.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { + || state.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } @@ -381,7 +457,8 @@ public class DTLSClientProtocol extends DTLSProtocol { state.client.notifySelectedCipherSuite(state.selectedCipherSuite); state.selectedCompressionMethod = TlsUtils.readUint8(buf); - if (!TlsProtocol.arrayContains(state.offeredCompressionMethods, state.selectedCompressionMethod)) { + if (!TlsProtocol.arrayContains(state.offeredCompressionMethods, state.selectedCompressionMethod)) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } state.client.notifySelectedCompressionMethod(state.selectedCompressionMethod); @@ -409,10 +486,12 @@ public class DTLSClientProtocol extends DTLSProtocol { * extended client hello message. However, see RFC 5746 exception below. We always include * the SCSV, so an Extended Server Hello is always allowed. */ - if (serverExtensions != null) { + if (serverExtensions != null) + { Enumeration e = serverExtensions.keys(); - while (e.hasMoreElements()) { - Integer extType = (Integer) e.nextElement(); + while (e.hasMoreElements()) + { + Integer extType = (Integer)e.nextElement(); /* * RFC 5746 Note that sending a "renegotiation_info" extension in response to a @@ -423,7 +502,8 @@ public class DTLSClientProtocol extends DTLSProtocol { * MUST continue to comply with Section 7.4.1.4 for all other extensions. */ if (!extType.equals(TlsProtocol.EXT_RenegotiationInfo) - && (state.clientExtensions == null || state.clientExtensions.get(extType) == null)) { + && (state.clientExtensions == null || state.clientExtensions.get(extType) == null)) + { /* * RFC 3546 2.3 Note that for all extension types (including those defined in * future), the extension type MUST NOT appear in the extended server hello @@ -444,8 +524,9 @@ public class DTLSClientProtocol extends DTLSProtocol { * When a ServerHello is received, the client MUST check if it includes the * "renegotiation_info" extension: */ - byte[] renegExtValue = (byte[]) serverExtensions.get(TlsProtocol.EXT_RenegotiationInfo); - if (renegExtValue != null) { + byte[] renegExtValue = (byte[])serverExtensions.get(TlsProtocol.EXT_RenegotiationInfo); + if (renegExtValue != null) + { /* * If the extension is present, set the secure_renegotiation flag to TRUE. The * client MUST then verify that the length of the "renegotiated_connection" @@ -455,7 +536,8 @@ public class DTLSClientProtocol extends DTLSProtocol { state.secure_renegotiation = true; if (!Arrays.constantTimeAreEqual(renegExtValue, - TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) { + TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) + { throw new TlsFatalAlert(AlertDescription.handshake_failure); } } @@ -466,12 +548,15 @@ public class DTLSClientProtocol extends DTLSProtocol { state.client.notifySecureRenegotiation(state.secure_renegotiation); - if (state.clientExtensions != null) { + if (state.clientExtensions != null) + { state.client.processServerExtensions(serverExtensions); } } - protected void processServerKeyExchange(ClientHandshakeState state, byte[] body) throws IOException { + protected void processServerKeyExchange(ClientHandshakeState state, byte[] body) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(body); @@ -480,19 +565,24 @@ public class DTLSClientProtocol extends DTLSProtocol { TlsProtocol.assertEmpty(buf); } - protected void processServerSupplementalData(ClientHandshakeState state, byte[] body) throws IOException { + protected void processServerSupplementalData(ClientHandshakeState state, byte[] body) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(body); Vector serverSupplementalData = TlsProtocol.readSupplementalDataMessage(buf); state.client.processServerSupplementalData(serverSupplementalData); } - protected static byte[] parseHelloVerifyRequest(TlsContext context, byte[] body) throws IOException { + protected static byte[] parseHelloVerifyRequest(TlsContext context, byte[] body) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(body); ProtocolVersion server_version = TlsUtils.readVersion(buf); - if (!server_version.equals(context.getServerVersion())) { + if (!server_version.equals(context.getServerVersion())) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } @@ -505,7 +595,9 @@ public class DTLSClientProtocol extends DTLSProtocol { return cookie; } - protected static byte[] patchClientHelloWithCookie(byte[] clientHelloBody, byte[] cookie) throws IOException { + protected static byte[] patchClientHelloWithCookie(byte[] clientHelloBody, byte[] cookie) + throws IOException + { int sessionIDPos = 34; int sessionIDLength = TlsUtils.readUint8(clientHelloBody, sessionIDPos); @@ -515,7 +607,7 @@ public class DTLSClientProtocol extends DTLSProtocol { byte[] patched = new byte[clientHelloBody.length + cookie.length]; System.arraycopy(clientHelloBody, 0, patched, 0, cookieLengthPos); - TlsUtils.writeUint8((short) cookie.length, patched, cookieLengthPos); + TlsUtils.writeUint8((short)cookie.length, patched, cookieLengthPos); System.arraycopy(cookie, 0, patched, cookiePos, cookie.length); System.arraycopy(clientHelloBody, cookiePos, patched, cookiePos + cookie.length, clientHelloBody.length - cookiePos); @@ -523,7 +615,8 @@ public class DTLSClientProtocol extends DTLSProtocol { return patched; } - protected static class ClientHandshakeState { + protected static class ClientHandshakeState + { TlsClient client = null; TlsClientContextImpl clientContext = null; int[] offeredCipherSuites = null; diff --git a/src/main/java/org/bouncycastle/crypto/tls/DTLSEpoch.java b/src/main/java/org/bouncycastle/crypto/tls/DTLSEpoch.java index 49a7f536..cbef79f6 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DTLSEpoch.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DTLSEpoch.java @@ -1,6 +1,7 @@ package org.bouncycastle.crypto.tls; -class DTLSEpoch { +class DTLSEpoch +{ private final DTLSReplayWindow replayWindow = new DTLSReplayWindow(); @@ -9,11 +10,14 @@ class DTLSEpoch { private long sequence_number = 0; - DTLSEpoch(int epoch, TlsCipher cipher) { - if (epoch < 0) { + DTLSEpoch(int epoch, TlsCipher cipher) + { + if (epoch < 0) + { throw new IllegalArgumentException("'epoch' must be >= 0"); } - if (cipher == null) { + if (cipher == null) + { throw new IllegalArgumentException("'cipher' cannot be null"); } @@ -21,24 +25,29 @@ class DTLSEpoch { this.cipher = cipher; } - long allocateSequenceNumber() { + long allocateSequenceNumber() + { // TODO Check for overflow return sequence_number++; } - TlsCipher getCipher() { + TlsCipher getCipher() + { return cipher; } - int getEpoch() { + int getEpoch() + { return epoch; } - DTLSReplayWindow getReplayWindow() { + DTLSReplayWindow getReplayWindow() + { return replayWindow; } - long getSequence_number() { + long getSequence_number() + { return sequence_number; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DTLSHandshakeRetransmit.java b/src/main/java/org/bouncycastle/crypto/tls/DTLSHandshakeRetransmit.java index 6f7bb478..ecff5bac 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DTLSHandshakeRetransmit.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DTLSHandshakeRetransmit.java @@ -2,6 +2,8 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -interface DTLSHandshakeRetransmit { - void receivedHandshakeRecord(int epoch, byte[] buf, int off, int len) throws IOException; +interface DTLSHandshakeRetransmit +{ + void receivedHandshakeRecord(int epoch, byte[] buf, int off, int len) + throws IOException; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DTLSProtocol.java b/src/main/java/org/bouncycastle/crypto/tls/DTLSProtocol.java index 55826dc9..02892237 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DTLSProtocol.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DTLSProtocol.java @@ -8,19 +8,25 @@ import java.util.Vector; import org.bouncycastle.util.Arrays; -public abstract class DTLSProtocol { +public abstract class DTLSProtocol +{ protected final SecureRandom secureRandom; - protected DTLSProtocol(SecureRandom secureRandom) { + protected DTLSProtocol(SecureRandom secureRandom) + { if (secureRandom == null) + { throw new IllegalArgumentException("'secureRandom' cannot be null"); + } this.secureRandom = secureRandom; } - protected void processFinished(byte[] body, byte[] expected_verify_data) throws IOException { + protected void processFinished(byte[] body, byte[] expected_verify_data) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(body); @@ -28,19 +34,24 @@ public abstract class DTLSProtocol { TlsProtocol.assertEmpty(buf); - if (!Arrays.constantTimeAreEqual(expected_verify_data, verify_data)) { + if (!Arrays.constantTimeAreEqual(expected_verify_data, verify_data)) + { throw new TlsFatalAlert(AlertDescription.handshake_failure); } } - protected static byte[] generateCertificate(Certificate certificate) throws IOException { + protected static byte[] generateCertificate(Certificate certificate) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); certificate.encode(buf); return buf.toByteArray(); } - protected static byte[] generateSupplementalData(Vector supplementalData) throws IOException { + protected static byte[] generateSupplementalData(Vector supplementalData) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsProtocol.writeSupplementalData(buf, supplementalData); @@ -48,9 +59,11 @@ public abstract class DTLSProtocol { } protected static void validateSelectedCipherSuite(int selectedCipherSuite, short alertDescription) - throws IOException { + throws IOException + { - switch (selectedCipherSuite) { + switch (selectedCipherSuite) + { case CipherSuite.TLS_RSA_EXPORT_WITH_RC4_40_MD5: case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: diff --git a/src/main/java/org/bouncycastle/crypto/tls/DTLSReassembler.java b/src/main/java/org/bouncycastle/crypto/tls/DTLSReassembler.java index 7a419f97..99111b2c 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DTLSReassembler.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DTLSReassembler.java @@ -2,14 +2,16 @@ package org.bouncycastle.crypto.tls; import java.util.Vector; -class DTLSReassembler { +class DTLSReassembler +{ private final short msg_type; private final byte[] body; private Vector missing = new Vector(); - DTLSReassembler(short msg_type, int length) { + DTLSReassembler(short msg_type, int length) + { this.msg_type = msg_type; this.body = new byte[length]; this.missing.addElement(new Range(0, length)); @@ -26,30 +28,39 @@ class DTLSReassembler { } void contributeFragment(short msg_type, int length, byte[] buf, int off, int fragment_offset, - int fragment_length) { + int fragment_length) + { int fragment_end = fragment_offset + fragment_length; - if (this.msg_type != msg_type || this.body.length != length || fragment_end > length) { + if (this.msg_type != msg_type || this.body.length != length || fragment_end > length) + { return; } - if (fragment_length == 0) { + if (fragment_length == 0) + { // NOTE: Empty messages still require an empty fragment to complete it - if (fragment_offset == 0 && !missing.isEmpty()) { + if (fragment_offset == 0 && !missing.isEmpty()) + { Range firstRange = (Range)missing.firstElement(); - if (firstRange.getEnd() == 0) { + if (firstRange.getEnd() == 0) + { missing.removeElementAt(0); } } return; } - for (int i = 0; i < missing.size(); ++i) { - Range range = (Range) missing.get(i); + for (int i = 0; i < missing.size(); ++i) + { + Range range = (Range)missing.get(i); if (range.getStart() >= fragment_end) + { break; - if (range.getEnd() > fragment_offset) { + } + if (range.getEnd() > fragment_offset) + { int copyStart = Math.max(range.getStart(), fragment_offset); int copyEnd = Math.min(range.getEnd(), fragment_end); @@ -58,19 +69,25 @@ class DTLSReassembler { System.arraycopy(buf, off + copyStart - fragment_offset, body, copyStart, copyLength); - if (copyStart == range.getStart()) { - if (copyEnd == range.getEnd()) { + if (copyStart == range.getStart()) + { + if (copyEnd == range.getEnd()) + { missing.removeElementAt(i--); } - else { + else + { range.setStart(copyEnd); } } - else { - if (copyEnd == range.getEnd()) { + else + { + if (copyEnd == range.getEnd()) + { range.setEnd(copyStart); } - else { + else + { missing.insertElementAt(new Range(copyEnd, range.getEnd()), ++i); range.setEnd(copyStart); } @@ -85,28 +102,34 @@ class DTLSReassembler { this.missing.addElement(new Range(0, body.length)); } - private static class Range { + private static class Range + { private int start, end; - Range(int start, int end) { + Range(int start, int end) + { this.start = start; this.end = end; } - public int getStart() { + public int getStart() + { return start; } - public void setStart(int start) { + public void setStart(int start) + { this.start = start; } - public int getEnd() { + public int getEnd() + { return end; } - public void setEnd(int end) { + public void setEnd(int end) + { this.end = end; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DTLSRecordLayer.java b/src/main/java/org/bouncycastle/crypto/tls/DTLSRecordLayer.java index b0c4bdc8..37ec889c 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DTLSRecordLayer.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DTLSRecordLayer.java @@ -2,7 +2,9 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -class DTLSRecordLayer implements DatagramTransport { +class DTLSRecordLayer + implements DatagramTransport +{ private static final int RECORD_HEADER_LENGTH = 13; private static final int MAX_FRAGMENT_LENGTH = 1 << 14; @@ -26,7 +28,8 @@ class DTLSRecordLayer implements DatagramTransport { private DTLSEpoch retransmitEpoch = null; private long retransmitExpiry = 0; - DTLSRecordLayer(DatagramTransport transport, TlsContext context, TlsPeer peer, short contentType) { + DTLSRecordLayer(DatagramTransport transport, TlsContext context, TlsPeer peer, short contentType) + { this.transport = transport; this.context = context; this.peer = peer; @@ -39,12 +42,15 @@ class DTLSRecordLayer implements DatagramTransport { this.writeEpoch = currentEpoch; } - ProtocolVersion getDiscoveredPeerVersion() { + ProtocolVersion getDiscoveredPeerVersion() + { return discoveredPeerVersion; } - void initPendingEpoch(TlsCipher pendingCipher) { - if (pendingEpoch != null) { + void initPendingEpoch(TlsCipher pendingCipher) + { + if (pendingEpoch != null) + { throw new IllegalStateException(); } @@ -58,13 +64,16 @@ class DTLSRecordLayer implements DatagramTransport { this.pendingEpoch = new DTLSEpoch(writeEpoch.getEpoch() + 1, pendingCipher); } - void handshakeSuccessful(DTLSHandshakeRetransmit retransmit) { - if (readEpoch == currentEpoch || writeEpoch == currentEpoch) { + void handshakeSuccessful(DTLSHandshakeRetransmit retransmit) + { + if (readEpoch == currentEpoch || writeEpoch == currentEpoch) + { // TODO throw new IllegalStateException(); } - if (retransmit != null) { + if (retransmit != null) + { this.retransmit = retransmit; this.retransmitEpoch = currentEpoch; this.retransmitExpiry = System.currentTimeMillis() + RETRANSMIT_TIMEOUT; @@ -75,57 +84,75 @@ class DTLSRecordLayer implements DatagramTransport { this.pendingEpoch = null; } - void resetWriteEpoch() { - if (retransmitEpoch != null) { + void resetWriteEpoch() + { + if (retransmitEpoch != null) + { this.writeEpoch = retransmitEpoch; - } else { + } + else + { this.writeEpoch = currentEpoch; } } - public int getReceiveLimit() throws IOException { + public int getReceiveLimit() + throws IOException + { return Math.min(MAX_FRAGMENT_LENGTH, readEpoch.getCipher().getPlaintextLimit(transport.getReceiveLimit() - RECORD_HEADER_LENGTH)); } - public int getSendLimit() throws IOException { + public int getSendLimit() + throws IOException + { return Math.min(MAX_FRAGMENT_LENGTH, writeEpoch.getCipher().getPlaintextLimit(transport.getSendLimit() - RECORD_HEADER_LENGTH)); } - public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { + public int receive(byte[] buf, int off, int len, int waitMillis) + throws IOException + { byte[] record = null; - for (;;) { + for (; ; ) + { int receiveLimit = Math.min(len, getReceiveLimit()) + RECORD_HEADER_LENGTH; - if (record == null || record.length < receiveLimit) { + if (record == null || record.length < receiveLimit) + { record = new byte[receiveLimit]; } - try { - if (retransmit != null && System.currentTimeMillis() > retransmitExpiry) { + try + { + if (retransmit != null && System.currentTimeMillis() > retransmitExpiry) + { retransmit = null; retransmitEpoch = null; } int received = receiveRecord(record, 0, receiveLimit, waitMillis); - if (received < 0) { + if (received < 0) + { return received; } - if (received < RECORD_HEADER_LENGTH) { + if (received < RECORD_HEADER_LENGTH) + { continue; } int length = TlsUtils.readUint16(record, 11); - if (received != (length + RECORD_HEADER_LENGTH)) { + if (received != (length + RECORD_HEADER_LENGTH)) + { continue; } short type = TlsUtils.readUint8(record, 0); // TODO Support user-specified custom protocols? - switch (type) { + switch (type) + { case ContentType.alert: case ContentType.application_data: case ContentType.change_cipher_spec: @@ -139,23 +166,32 @@ class DTLSRecordLayer implements DatagramTransport { int epoch = TlsUtils.readUint16(record, 3); DTLSEpoch recordEpoch = null; - if (epoch == readEpoch.getEpoch()) { + if (epoch == readEpoch.getEpoch()) + { recordEpoch = readEpoch; - } else if (type == ContentType.handshake && retransmitEpoch != null - && epoch == retransmitEpoch.getEpoch()) { + } + else if (type == ContentType.handshake && retransmitEpoch != null + && epoch == retransmitEpoch.getEpoch()) + { recordEpoch = retransmitEpoch; } if (recordEpoch == null) + { continue; + } long seq = TlsUtils.readUint48(record, 5); if (recordEpoch.getReplayWindow().shouldDiscard(seq)) + { continue; + } ProtocolVersion version = TlsUtils.readVersion(record, 1); if (discoveredPeerVersion != null && !discoveredPeerVersion.equals(version)) + { continue; + } byte[] plaintext = recordEpoch.getCipher().decodeCiphertext( getMacSequenceNumber(recordEpoch.getEpoch(), seq), type, record, RECORD_HEADER_LENGTH, @@ -163,58 +199,74 @@ class DTLSRecordLayer implements DatagramTransport { recordEpoch.getReplayWindow().reportAuthenticated(seq); - if (discoveredPeerVersion == null) { + if (discoveredPeerVersion == null) + { discoveredPeerVersion = version; } - switch (type) { - case ContentType.alert: { + switch (type) + { + case ContentType.alert: + { - if (plaintext.length == 2) { + if (plaintext.length == 2) + { short alertLevel = plaintext[0]; short alertDescription = plaintext[1]; peer.notifyAlertReceived(alertLevel, alertDescription); - if (alertLevel == AlertLevel.fatal) { + if (alertLevel == AlertLevel.fatal) + { fail(alertDescription); throw new TlsFatalAlert(alertDescription); } // TODO Can close_notify be a fatal alert? - if (alertDescription == AlertDescription.close_notify) { + if (alertDescription == AlertDescription.close_notify) + { closeTransport(); } - } else { + } + else + { // TODO What exception? } continue; } - case ContentType.application_data: { - if (inHandshake) { + case ContentType.application_data: + { + if (inHandshake) + { // TODO Consider buffering application data for new epoch that arrives // out-of-order with the Finished message continue; } break; } - case ContentType.change_cipher_spec: { + case ContentType.change_cipher_spec: + { // Implicitly receive change_cipher_spec and change to pending cipher state - if (plaintext.length != 1 || plaintext[0] != 1) { + if (plaintext.length != 1 || plaintext[0] != 1) + { continue; } - if (pendingEpoch != null) { + if (pendingEpoch != null) + { readEpoch = pendingEpoch; } continue; } - case ContentType.handshake: { - if (!inHandshake) { - if (retransmit != null) { + case ContentType.handshake: + { + if (!inHandshake) + { + if (retransmit != null) + { retransmit.receivedHandshakeRecord(epoch, plaintext, 0, plaintext.length); } @@ -228,40 +280,50 @@ class DTLSRecordLayer implements DatagramTransport { * NOTE: If we receive any non-handshake data in the new epoch implies the peer has * received our final flight. */ - if (!inHandshake && retransmit != null) { + if (!inHandshake && retransmit != null) + { this.retransmit = null; this.retransmitEpoch = null; } System.arraycopy(plaintext, 0, buf, off, plaintext.length); return plaintext.length; - } catch (IOException e) { + } + catch (IOException e) + { // NOTE: Assume this is a timeout for the moment throw e; } } } - public void send(byte[] buf, int off, int len) throws IOException { + public void send(byte[] buf, int off, int len) + throws IOException + { short contentType = ContentType.application_data; - if (this.inHandshake || this.writeEpoch == this.retransmitEpoch) { + if (this.inHandshake || this.writeEpoch == this.retransmitEpoch) + { contentType = ContentType.handshake; short handshakeType = TlsUtils.readUint8(buf, off); - if (handshakeType == HandshakeType.finished) { - + if (handshakeType == HandshakeType.finished) + { + DTLSEpoch nextEpoch = null; - if (this.inHandshake) { + if (this.inHandshake) + { nextEpoch = pendingEpoch; } - else if (this.writeEpoch == this.retransmitEpoch) { + else if (this.writeEpoch == this.retransmitEpoch) + { nextEpoch = currentEpoch; } - if (nextEpoch == null) { + if (nextEpoch == null) + { // TODO throw new IllegalStateException(); } @@ -269,7 +331,7 @@ class DTLSRecordLayer implements DatagramTransport { // Implicitly send change_cipher_spec and change to pending cipher state // TODO Send change_cipher_spec and finished records in single datagram? - byte[] data = new byte[] { 1 }; + byte[] data = new byte[]{1}; sendRecord(ContentType.change_cipher_spec, data, 0, data.length); writeEpoch = nextEpoch; @@ -279,20 +341,29 @@ class DTLSRecordLayer implements DatagramTransport { sendRecord(contentType, buf, off, len); } - public void close() throws IOException { - if (!closed) { - if (inHandshake) { + public void close() + throws IOException + { + if (!closed) + { + if (inHandshake) + { warn(AlertDescription.user_canceled, "User canceled handshake"); } closeTransport(); } } - void fail(short alertDescription) { - if (!closed) { - try { + void fail(short alertDescription) + { + if (!closed) + { + try + { raiseAlert(AlertLevel.fatal, alertDescription, null, null); - } catch (Exception e) { + } + catch (Exception e) + { // Ignore } @@ -302,12 +373,16 @@ class DTLSRecordLayer implements DatagramTransport { } } - void warn(short alertDescription, String message) throws IOException { + void warn(short alertDescription, String message) + throws IOException + { raiseAlert(AlertLevel.warning, alertDescription, message, null); } - private void closeTransport() { - if (!closed) { + private void closeTransport() + { + if (!closed) + { /* * RFC 5246 7.2.1. Unless some other fatal alert has been transmitted, each party is * required to send a close_notify alert before closing the write side of the @@ -315,12 +390,16 @@ class DTLSRecordLayer implements DatagramTransport { * close down the connection immediately, discarding any pending writes. */ - try { - if (!failed) { + try + { + if (!failed) + { warn(AlertDescription.close_notify, null); } transport.close(); - } catch (Exception e) { + } + catch (Exception e) + { // Ignore } @@ -329,21 +408,26 @@ class DTLSRecordLayer implements DatagramTransport { } private void raiseAlert(short alertLevel, short alertDescription, String message, Exception cause) - throws IOException { + throws IOException + { peer.notifyAlertRaised(alertLevel, alertDescription, message, cause); byte[] error = new byte[2]; - error[0] = (byte) alertLevel; - error[1] = (byte) alertDescription; + error[0] = (byte)alertLevel; + error[1] = (byte)alertDescription; sendRecord(ContentType.alert, error, 0, 2); } - private int receiveRecord(byte[] buf, int off, int len, int waitMillis) throws IOException { - if (recordQueue.size() > 0) { + private int receiveRecord(byte[] buf, int off, int len, int waitMillis) + throws IOException + { + if (recordQueue.size() > 0) + { int length = 0; - if (recordQueue.size() >= RECORD_HEADER_LENGTH) { + if (recordQueue.size() >= RECORD_HEADER_LENGTH) + { byte[] lengthBytes = new byte[2]; recordQueue.read(lengthBytes, 0, 2, 11); length = TlsUtils.readUint16(lengthBytes, 0); @@ -356,10 +440,12 @@ class DTLSRecordLayer implements DatagramTransport { } int received = transport.receive(buf, off, len, waitMillis); - if (received >= RECORD_HEADER_LENGTH) { + if (received >= RECORD_HEADER_LENGTH) + { int fragmentLength = TlsUtils.readUint16(buf, off + 11); int recordLength = RECORD_HEADER_LENGTH + fragmentLength; - if (received > recordLength) { + if (received > recordLength) + { recordQueue.addData(buf, off + recordLength, received - recordLength); received = recordLength; } @@ -368,13 +454,16 @@ class DTLSRecordLayer implements DatagramTransport { return received; } - private void sendRecord(short contentType, byte[] buf, int off, int len) throws IOException { + private void sendRecord(short contentType, byte[] buf, int off, int len) + throws IOException + { /* * RFC 5264 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, * or ChangeCipherSpec content types. */ - if (len < 1 && contentType != ContentType.application_data) { + if (len < 1 && contentType != ContentType.application_data) + { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -384,7 +473,8 @@ class DTLSRecordLayer implements DatagramTransport { byte[] ciphertext = writeEpoch.getCipher().encodePlaintext( getMacSequenceNumber(recordEpoch, recordSequenceNumber), contentType, buf, off, len); - if (ciphertext.length > MAX_FRAGMENT_LENGTH) { + if (ciphertext.length > MAX_FRAGMENT_LENGTH) + { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -400,7 +490,8 @@ class DTLSRecordLayer implements DatagramTransport { transport.send(record, 0, record.length); } - private static long getMacSequenceNumber(int epoch, long sequence_number) { - return ((long) epoch << 48) | sequence_number; + private static long getMacSequenceNumber(int epoch, long sequence_number) + { + return ((long)epoch << 48) | sequence_number; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java b/src/main/java/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java index 622324b5..91b701aa 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java @@ -6,7 +6,8 @@ import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; -class DTLSReliableHandshake { +class DTLSReliableHandshake +{ private final static int MAX_RECEIVE_AHEAD = 10; @@ -21,25 +22,31 @@ class DTLSReliableHandshake { private int message_seq = 0, next_receive_seq = 0; - DTLSReliableHandshake(TlsContext context, DTLSRecordLayer transport) { + DTLSReliableHandshake(TlsContext context, DTLSRecordLayer transport) + { this.recordLayer = transport; this.hash.init(context); } - void notifyHelloComplete() { + void notifyHelloComplete() + { this.hash = this.hash.commit(); } - byte[] getCurrentHash() { + byte[] getCurrentHash() + { TlsHandshakeHash copyOfHash = hash.fork(); byte[] result = new byte[copyOfHash.getDigestSize()]; copyOfHash.doFinal(result, 0); return result; } - void sendMessage(short msg_type, byte[] body) throws IOException { + void sendMessage(short msg_type, byte[] body) + throws IOException + { - if (!sending) { + if (!sending) + { checkInboundFlight(); sending = true; outboundFlight.clear(); @@ -53,19 +60,24 @@ class DTLSReliableHandshake { updateHandshakeMessagesDigest(message); } - Message receiveMessage() throws IOException { + Message receiveMessage() + throws IOException + { - if (sending) { + if (sending) + { sending = false; prepareInboundFlight(); } // Check if we already have the next message waiting { - DTLSReassembler next = (DTLSReassembler) currentInboundFlight.get(Integer.valueOf(next_receive_seq)); - if (next != null) { + DTLSReassembler next = (DTLSReassembler)currentInboundFlight.get(Integer.valueOf(next_receive_seq)); + if (next != null) + { byte[] body = next.getBodyIfComplete(); - if (body != null) { + if (body != null) + { previousInboundFlight = null; return updateHandshakeMessagesDigest(new Message(next_receive_seq++, next.getType(), body)); } @@ -77,53 +89,66 @@ class DTLSReliableHandshake { // TODO Check the conditions under which we should reset this int readTimeoutMillis = 1000; - for (;;) { + for (; ; ) + { int receiveLimit = recordLayer.getReceiveLimit(); - if (buf == null || buf.length < receiveLimit) { + if (buf == null || buf.length < receiveLimit) + { buf = new byte[receiveLimit]; } // TODO Handle records containing multiple handshake messages - try { - for (;;) { + try + { + for (; ; ) + { int received = recordLayer.receive(buf, 0, receiveLimit, readTimeoutMillis); - if (received < 0) { + if (received < 0) + { break; } - if (received < 12) { + if (received < 12) + { continue; } int fragment_length = TlsUtils.readUint24(buf, 9); - if (received != (fragment_length + 12)) { + if (received != (fragment_length + 12)) + { continue; } int seq = TlsUtils.readUint16(buf, 4); - if (seq > (next_receive_seq + MAX_RECEIVE_AHEAD)) { + if (seq > (next_receive_seq + MAX_RECEIVE_AHEAD)) + { continue; } short msg_type = TlsUtils.readUint8(buf, 0); int length = TlsUtils.readUint24(buf, 1); int fragment_offset = TlsUtils.readUint24(buf, 6); - if (fragment_offset + fragment_length > length) { + if (fragment_offset + fragment_length > length) + { continue; } - if (seq < next_receive_seq) { + if (seq < next_receive_seq) + { /* * NOTE: If we receive the previous flight of incoming messages in full * again, retransmit our last flight */ - if (previousInboundFlight != null) { - DTLSReassembler reassembler = (DTLSReassembler) previousInboundFlight.get(Integer + if (previousInboundFlight != null) + { + DTLSReassembler reassembler = (DTLSReassembler)previousInboundFlight.get(Integer .valueOf(seq)); - if (reassembler != null) { + if (reassembler != null) + { reassembler.contributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); - if (checkAll(previousInboundFlight)) { + if (checkAll(previousInboundFlight)) + { resendOutboundFlight(); @@ -137,19 +162,24 @@ class DTLSReliableHandshake { } } } - } else { + } + else + { - DTLSReassembler reassembler = (DTLSReassembler) currentInboundFlight.get(Integer.valueOf(seq)); - if (reassembler == null) { + DTLSReassembler reassembler = (DTLSReassembler)currentInboundFlight.get(Integer.valueOf(seq)); + if (reassembler == null) + { reassembler = new DTLSReassembler(msg_type, length); currentInboundFlight.put(Integer.valueOf(seq), reassembler); } reassembler.contributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); - if (seq == next_receive_seq) { + if (seq == next_receive_seq) + { byte[] body = reassembler.getBodyIfComplete(); - if (body != null) { + if (body != null) + { previousInboundFlight = null; return updateHandshakeMessagesDigest(new Message(next_receive_seq++, reassembler.getType(), body)); @@ -157,7 +187,9 @@ class DTLSReliableHandshake { } } } - } catch (IOException e) { + } + catch (IOException e) + { // NOTE: Assume this is a timeout for the moment } @@ -171,32 +203,42 @@ class DTLSReliableHandshake { } } - void finish() { + void finish() + { DTLSHandshakeRetransmit retransmit = null; - if (!sending) { + if (!sending) + { checkInboundFlight(); - } else if (currentInboundFlight != null) { + } + else if (currentInboundFlight != null) + { /* * RFC 6347 4.2.4. In addition, for at least twice the default MSL defined for [TCP], * when in the FINISHED state, the node that transmits the last flight (the server in an * ordinary handshake or the client in a resumed handshake) MUST respond to a retransmit * of the peer's last flight with a retransmit of the last flight. */ - retransmit = new DTLSHandshakeRetransmit() { - public void receivedHandshakeRecord(int epoch, byte[] buf, int off, int len) throws IOException { + retransmit = new DTLSHandshakeRetransmit() + { + public void receivedHandshakeRecord(int epoch, byte[] buf, int off, int len) + throws IOException + { /* * TODO Need to handle the case where the previous inbound flight contains * messages from two epochs. */ - if (len < 12) { + if (len < 12) + { return; } int fragment_length = TlsUtils.readUint24(buf, off + 9); - if (len != (fragment_length + 12)) { + if (len != (fragment_length + 12)) + { return; } int seq = TlsUtils.readUint16(buf, off + 4); - if (seq >= next_receive_seq) { + if (seq >= next_receive_seq) + { return; } @@ -205,19 +247,24 @@ class DTLSReliableHandshake { // TODO This is a hack that only works until we try to support renegotiation int expectedEpoch = msg_type == HandshakeType.finished ? 1 : 0; if (epoch != expectedEpoch) + { return; + } int length = TlsUtils.readUint24(buf, off + 1); int fragment_offset = TlsUtils.readUint24(buf, off + 6); - if (fragment_offset + fragment_length > length) { + if (fragment_offset + fragment_length > length) + { return; } - DTLSReassembler reassembler = (DTLSReassembler) currentInboundFlight.get(Integer.valueOf(seq)); - if (reassembler != null) { + DTLSReassembler reassembler = (DTLSReassembler)currentInboundFlight.get(Integer.valueOf(seq)); + if (reassembler != null) + { reassembler.contributeFragment(msg_type, length, buf, off + 12, fragment_offset, fragment_length); - if (checkAll(currentInboundFlight)) { + if (checkAll(currentInboundFlight)) + { resendOutboundFlight(); resetAll(currentInboundFlight); } @@ -229,38 +276,49 @@ class DTLSReliableHandshake { recordLayer.handshakeSuccessful(retransmit); } - void resetHandshakeMessagesDigest() { + void resetHandshakeMessagesDigest() + { hash.reset(); } /** * Check that there are no "extra" messages left in the current inbound flight */ - private void checkInboundFlight() { + private void checkInboundFlight() + { Enumeration e = currentInboundFlight.keys(); - while (e.hasMoreElements()) { - Integer key = (Integer) e.nextElement(); - if (key.intValue() >= next_receive_seq) { + while (e.hasMoreElements()) + { + Integer key = (Integer)e.nextElement(); + if (key.intValue() >= next_receive_seq) + { // TODO Should this be considered an error? } } } - private void prepareInboundFlight() { + private void prepareInboundFlight() + { resetAll(currentInboundFlight); previousInboundFlight = currentInboundFlight; currentInboundFlight = new Hashtable(); } - private void resendOutboundFlight() throws IOException { + private void resendOutboundFlight() + throws IOException + { recordLayer.resetWriteEpoch(); - for (int i = 0; i < outboundFlight.size(); ++i) { - writeMessage((Message) outboundFlight.elementAt(i)); + for (int i = 0; i < outboundFlight.size(); ++i) + { + writeMessage((Message)outboundFlight.elementAt(i)); } } - private Message updateHandshakeMessagesDigest(Message message) throws IOException { - if (message.getType() != HandshakeType.hello_request) { + private Message updateHandshakeMessagesDigest(Message message) + throws IOException + { + if (message.getType() != HandshakeType.hello_request) + { byte[] body = message.getBody(); byte[] buf = new byte[12]; TlsUtils.writeUint8(message.getType(), buf, 0); @@ -274,13 +332,16 @@ class DTLSReliableHandshake { return message; } - private void writeMessage(Message message) throws IOException { + private void writeMessage(Message message) + throws IOException + { int sendLimit = recordLayer.getSendLimit(); int fragmentLimit = sendLimit - 12; // TODO Support a higher minimum fragment size? - if (fragmentLimit < 1) { + if (fragmentLimit < 1) + { // TODO Should we be throwing an exception here? throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -289,14 +350,18 @@ class DTLSReliableHandshake { // NOTE: Must still send a fragment if body is empty int fragment_offset = 0; - do { + do + { int fragment_length = Math.min(length - fragment_offset, fragmentLimit); writeHandshakeFragment(message, fragment_offset, fragment_length); fragment_offset += fragment_length; - } while (fragment_offset < length); + } + while (fragment_offset < length); } - private void writeHandshakeFragment(Message message, int fragment_offset, int fragment_length) throws IOException { + private void writeHandshakeFragment(Message message, int fragment_offset, int fragment_length) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8(message.getType(), buf); @@ -311,43 +376,54 @@ class DTLSReliableHandshake { recordLayer.send(fragment, 0, fragment.length); } - private static boolean checkAll(Hashtable inboundFlight) { + private static boolean checkAll(Hashtable inboundFlight) + { Enumeration e = inboundFlight.elements(); - while (e.hasMoreElements()) { - if (((DTLSReassembler) e.nextElement()).getBodyIfComplete() == null) + while (e.hasMoreElements()) + { + if (((DTLSReassembler)e.nextElement()).getBodyIfComplete() == null) + { return false; + } } return true; } - private static void resetAll(Hashtable inboundFlight) { + private static void resetAll(Hashtable inboundFlight) + { Enumeration e = inboundFlight.elements(); - while (e.hasMoreElements()) { - ((DTLSReassembler) e.nextElement()).reset(); + while (e.hasMoreElements()) + { + ((DTLSReassembler)e.nextElement()).reset(); } } - static class Message { + static class Message + { private final int message_seq; private final short msg_type; private final byte[] body; - private Message(int message_seq, short msg_type, byte[] body) { + private Message(int message_seq, short msg_type, byte[] body) + { this.message_seq = message_seq; this.msg_type = msg_type; this.body = body; } - public int getSeq() { + public int getSeq() + { return message_seq; } - public short getType() { + public short getType() + { return msg_type; } - public byte[] getBody() { + public byte[] getBody() + { return body; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DTLSReplayWindow.java b/src/main/java/org/bouncycastle/crypto/tls/DTLSReplayWindow.java index b8809487..98e050ce 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DTLSReplayWindow.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DTLSReplayWindow.java @@ -2,10 +2,11 @@ package org.bouncycastle.crypto.tls; /** * RFC 4347 4.1.2.5 Anti-replay - * + *

* Support fast rejection of duplicate records by maintaining a sliding receive window */ -class DTLSReplayWindow { +class DTLSReplayWindow +{ private static final long VALID_SEQ_MASK = 0x0000FFFFFFFFFFFFL; @@ -16,22 +17,28 @@ class DTLSReplayWindow { /** * Check whether a received record with the given sequence number should be rejected as a duplicate. - * - * @param seq the 48-bit DTLSPlainText.sequence_number field of a received record. + * + * @param seq the 48-bit DTLSPlainText.sequence_number field of a received record. * @return true if the record should be discarded without further processing. */ boolean shouldDiscard(long seq) { if ((seq & VALID_SEQ_MASK) != seq) + { return true; + } if (seq <= latestConfirmedSeq) { long diff = latestConfirmedSeq - seq; if (diff >= WINDOW_SIZE) + { return true; + } if ((bitmap & (1L << diff)) != 0) + { return true; + } } return false; @@ -39,28 +46,33 @@ class DTLSReplayWindow { /** * Report that a received record with the given sequence number passed authentication checks. - * + * * @param seq the 48-bit DTLSPlainText.sequence_number field of an authenticated record. */ void reportAuthenticated(long seq) { if ((seq & VALID_SEQ_MASK) != seq) + { throw new IllegalArgumentException("'seq' out of range"); + } if (seq <= latestConfirmedSeq) { long diff = latestConfirmedSeq - seq; - if (diff < WINDOW_SIZE) { + if (diff < WINDOW_SIZE) + { bitmap |= (1L << diff); } } else { long diff = seq - latestConfirmedSeq; - if (diff >= WINDOW_SIZE) { + if (diff >= WINDOW_SIZE) + { bitmap = 1; } - else { + else + { bitmap <<= diff; bitmap |= 1; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DTLSServerProtocol.java b/src/main/java/org/bouncycastle/crypto/tls/DTLSServerProtocol.java index 4ff11a1e..6fde9304 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DTLSServerProtocol.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DTLSServerProtocol.java @@ -12,28 +12,39 @@ import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.util.Arrays; -public class DTLSServerProtocol extends DTLSProtocol { +public class DTLSServerProtocol + extends DTLSProtocol +{ protected boolean verifyRequests = true; - public DTLSServerProtocol(SecureRandom secureRandom) { + public DTLSServerProtocol(SecureRandom secureRandom) + { super(secureRandom); } - public boolean getVerifyRequests() { + public boolean getVerifyRequests() + { return verifyRequests; } - public void setVerifyRequests(boolean verifyRequests) { + public void setVerifyRequests(boolean verifyRequests) + { this.verifyRequests = verifyRequests; } - public DTLSTransport accept(TlsServer server, DatagramTransport transport) throws IOException { + public DTLSTransport accept(TlsServer server, DatagramTransport transport) + throws IOException + { if (server == null) + { throw new IllegalArgumentException("'server' cannot be null"); + } if (transport == null) + { throw new IllegalArgumentException("'transport' cannot be null"); + } SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = ConnectionEnd.server; @@ -48,21 +59,30 @@ public class DTLSServerProtocol extends DTLSProtocol { // TODO Need to handle sending of HelloVerifyRequest without entering a full connection - try { + try + { return serverHandshake(state, recordLayer); - } catch (TlsFatalAlert fatalAlert) { + } + catch (TlsFatalAlert fatalAlert) + { recordLayer.fail(fatalAlert.getAlertDescription()); throw fatalAlert; - } catch (IOException e) { + } + catch (IOException e) + { recordLayer.fail(AlertDescription.internal_error); throw e; - } catch (RuntimeException e) { + } + catch (RuntimeException e) + { recordLayer.fail(AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error); } } - public DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLayer recordLayer) throws IOException { + public DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLayer recordLayer) + throws IOException + { SecurityParameters securityParameters = state.serverContext.getSecurityParameters(); DTLSReliableHandshake handshake = new DTLSReliableHandshake(state.serverContext, recordLayer); @@ -76,9 +96,12 @@ public class DTLSServerProtocol extends DTLSProtocol { state.serverContext.setClientVersion(client_version); } - if (clientMessage.getType() == HandshakeType.client_hello) { + if (clientMessage.getType() == HandshakeType.client_hello) + { processClientHello(state, clientMessage.getBody()); - } else { + } + else + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } @@ -100,7 +123,8 @@ public class DTLSServerProtocol extends DTLSProtocol { } Vector serverSupplementalData = state.server.getServerSupplementalData(); - if (serverSupplementalData != null) { + if (serverSupplementalData != null) + { byte[] supplementalDataBody = generateSupplementalData(serverSupplementalData); handshake.sendMessage(HandshakeType.supplemental_data, supplementalDataBody); } @@ -109,9 +133,12 @@ public class DTLSServerProtocol extends DTLSProtocol { state.keyExchange.init(state.serverContext); state.serverCredentials = state.server.getCredentials(); - if (state.serverCredentials == null) { + if (state.serverCredentials == null) + { state.keyExchange.skipServerCredentials(); - } else { + } + else + { state.keyExchange.processServerCredentials(state.serverCredentials); byte[] certificateBody = generateCertificate(state.serverCredentials.getCertificate()); @@ -119,13 +146,16 @@ public class DTLSServerProtocol extends DTLSProtocol { } byte[] serverKeyExchange = state.keyExchange.generateServerKeyExchange(); - if (serverKeyExchange != null) { + if (serverKeyExchange != null) + { handshake.sendMessage(HandshakeType.server_key_exchange, serverKeyExchange); } - if (state.serverCredentials != null) { + if (state.serverCredentials != null) + { state.certificateRequest = state.server.getCertificateRequest(); - if (state.certificateRequest != null) { + if (state.certificateRequest != null) + { state.keyExchange.validateCertificateRequest(state.certificateRequest); byte[] certificateRequestBody = generateCertificateRequest(state, state.certificateRequest); @@ -137,23 +167,33 @@ public class DTLSServerProtocol extends DTLSProtocol { clientMessage = handshake.receiveMessage(); - if (clientMessage.getType() == HandshakeType.supplemental_data) { + if (clientMessage.getType() == HandshakeType.supplemental_data) + { processClientSupplementalData(state, clientMessage.getBody()); clientMessage = handshake.receiveMessage(); - } else { + } + else + { state.server.processClientSupplementalData(null); } - if (state.certificateRequest == null) { + if (state.certificateRequest == null) + { state.keyExchange.skipClientCredentials(); - } else { - if (clientMessage.getType() == HandshakeType.certificate) { + } + else + { + if (clientMessage.getType() == HandshakeType.certificate) + { processClientCertificate(state, clientMessage.getBody()); clientMessage = handshake.receiveMessage(); - } else { + } + else + { ProtocolVersion equivalentTLSVersion = state.serverContext.getServerVersion().getEquivalentTLSVersion(); - if (ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(equivalentTLSVersion)) { + if (ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(equivalentTLSVersion)) + { /* * RFC 5246 If no suitable certificate is available, the client MUST send a * certificate message containing no certificates. @@ -167,9 +207,12 @@ public class DTLSServerProtocol extends DTLSProtocol { } } - if (clientMessage.getType() == HandshakeType.client_key_exchange) { + if (clientMessage.getType() == HandshakeType.client_key_exchange) + { processClientKeyExchange(state, clientMessage.getBody()); - } else { + } + else + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } @@ -180,13 +223,17 @@ public class DTLSServerProtocol extends DTLSProtocol { * capability (i.e., all certificates except those containing fixed Diffie-Hellman * parameters). */ - if (expectCertificateVerifyMessage(state)) { + if (expectCertificateVerifyMessage(state)) + { byte[] certificateVerifyHash = handshake.getCurrentHash(); clientMessage = handshake.receiveMessage(); - if (clientMessage.getType() == HandshakeType.certificate_verify) { + if (clientMessage.getType() == HandshakeType.certificate_verify) + { processCertificateVerify(state, clientMessage.getBody(), certificateVerifyHash); - } else { + } + else + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } @@ -195,15 +242,19 @@ public class DTLSServerProtocol extends DTLSProtocol { byte[] clientFinishedHash = handshake.getCurrentHash(); clientMessage = handshake.receiveMessage(); - if (clientMessage.getType() == HandshakeType.finished) { + if (clientMessage.getType() == HandshakeType.finished) + { byte[] expectedClientVerifyData = TlsUtils.calculateVerifyData(state.serverContext, "client finished", clientFinishedHash); processFinished(clientMessage.getBody(), expectedClientVerifyData); - } else { + } + else + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } - if (state.expectSessionTicket) { + if (state.expectSessionTicket) + { NewSessionTicket newSessionTicket = state.server.getNewSessionTicket(); byte[] newSessionTicketBody = generateNewSessionTicket(state, newSessionTicket); handshake.sendMessage(HandshakeType.session_ticket, newSessionTicketBody); @@ -222,7 +273,8 @@ public class DTLSServerProtocol extends DTLSProtocol { } protected byte[] generateCertificateRequest(ServerHandshakeState state, CertificateRequest certificateRequest) - throws IOException { + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); certificateRequest.encode(buf); @@ -230,19 +282,23 @@ public class DTLSServerProtocol extends DTLSProtocol { } protected byte[] generateNewSessionTicket(ServerHandshakeState state, NewSessionTicket newSessionTicket) - throws IOException { + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); newSessionTicket.encode(buf); return buf.toByteArray(); } - protected byte[] generateServerHello(ServerHandshakeState state) throws IOException { + protected byte[] generateServerHello(ServerHandshakeState state) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); ProtocolVersion server_version = state.server.getServerVersion(); - if (!server_version.isEqualOrEarlierVersionOf(state.serverContext.getClientVersion())) { + if (!server_version.isEqualOrEarlierVersionOf(state.serverContext.getClientVersion())) + { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -265,14 +321,16 @@ public class DTLSServerProtocol extends DTLSProtocol { state.selectedCipherSuite = state.server.getSelectedCipherSuite(); if (!TlsProtocol.arrayContains(state.offeredCipherSuites, state.selectedCipherSuite) || state.selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL - || state.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { + || state.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) + { throw new TlsFatalAlert(AlertDescription.internal_error); } validateSelectedCipherSuite(state.selectedCipherSuite, AlertDescription.internal_error); state.selectedCompressionMethod = state.server.getSelectedCompressionMethod(); - if (!TlsProtocol.arrayContains(state.offeredCompressionMethods, state.selectedCompressionMethod)) { + if (!TlsProtocol.arrayContains(state.offeredCompressionMethods, state.selectedCompressionMethod)) + { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -284,12 +342,14 @@ public class DTLSServerProtocol extends DTLSProtocol { /* * RFC 5746 3.6. Server Behavior: Initial Handshake */ - if (state.secure_renegotiation) { + if (state.secure_renegotiation) + { boolean noRenegExt = state.serverExtensions == null || !state.serverExtensions.containsKey(TlsProtocol.EXT_RenegotiationInfo); - if (noRenegExt) { + if (noRenegExt) + { /* * Note that sending a "renegotiation_info" extension in response to a ClientHello * containing only the SCSV is an explicit exception to the prohibition in RFC 5246, @@ -297,7 +357,8 @@ public class DTLSServerProtocol extends DTLSProtocol { * because the client is signaling its willingness to receive the extension via the * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. */ - if (state.serverExtensions == null) { + if (state.serverExtensions == null) + { state.serverExtensions = new Hashtable(); } @@ -310,7 +371,8 @@ public class DTLSServerProtocol extends DTLSProtocol { } } - if (state.serverExtensions != null) { + if (state.serverExtensions != null) + { state.expectSessionTicket = state.serverExtensions.containsKey(TlsProtocol.EXT_SessionTicket); TlsProtocol.writeExtensions(buf, state.serverExtensions); } @@ -319,21 +381,27 @@ public class DTLSServerProtocol extends DTLSProtocol { } protected void notifyClientCertificate(ServerHandshakeState state, Certificate clientCertificate) - throws IOException { + throws IOException + { - if (state.certificateRequest == null) { + if (state.certificateRequest == null) + { throw new IllegalStateException(); } - if (state.clientCertificate != null) { + if (state.clientCertificate != null) + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } state.clientCertificate = clientCertificate; - if (clientCertificate.isEmpty()) { + if (clientCertificate.isEmpty()) + { state.keyExchange.skipClientCredentials(); - } else { + } + else + { /* * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request @@ -358,7 +426,9 @@ public class DTLSServerProtocol extends DTLSProtocol { state.server.notifyClientCertificate(clientCertificate); } - protected void processClientCertificate(ServerHandshakeState state, byte[] body) throws IOException { + protected void processClientCertificate(ServerHandshakeState state, byte[] body) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(body); @@ -370,7 +440,8 @@ public class DTLSServerProtocol extends DTLSProtocol { } protected void processCertificateVerify(ServerHandshakeState state, byte[] body, byte[] certificateVerifyHash) - throws IOException { + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(body); @@ -379,7 +450,8 @@ public class DTLSServerProtocol extends DTLSProtocol { TlsProtocol.assertEmpty(buf); // Verify the CertificateVerify message contains a correct signature. - try { + try + { TlsSigner tlsSigner = TlsUtils.createTlsSigner(state.clientCertificateType); tlsSigner.init(state.serverContext); @@ -388,18 +460,23 @@ public class DTLSServerProtocol extends DTLSProtocol { AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(keyInfo); tlsSigner.verifyRawSignature(clientCertificateSignature, publicKey, certificateVerifyHash); - } catch (Exception e) { + } + catch (Exception e) + { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } - protected void processClientHello(ServerHandshakeState state, byte[] body) throws IOException { + protected void processClientHello(ServerHandshakeState state, byte[] body) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(body); // TODO Read RFCs for guidance on the expected record layer version number ProtocolVersion client_version = TlsUtils.readVersion(buf); - if (!client_version.isDTLS()) { + if (!client_version.isDTLS()) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } @@ -409,7 +486,8 @@ public class DTLSServerProtocol extends DTLSProtocol { byte[] client_random = TlsUtils.readFully(32, buf); byte[] sessionID = TlsUtils.readOpaque8(buf); - if (sessionID.length > 32) { + if (sessionID.length > 32) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } @@ -417,7 +495,8 @@ public class DTLSServerProtocol extends DTLSProtocol { byte[] cookie = TlsUtils.readOpaque8(buf); int cipher_suites_length = TlsUtils.readUint16(buf); - if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0) { + if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0) + { throw new TlsFatalAlert(AlertDescription.decode_error); } @@ -428,7 +507,8 @@ public class DTLSServerProtocol extends DTLSProtocol { state.offeredCipherSuites = TlsUtils.readUint16Array(cipher_suites_length / 2, buf); int compression_methods_length = TlsUtils.readUint8(buf); - if (compression_methods_length < 1) { + if (compression_methods_length < 1) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } @@ -465,7 +545,8 @@ public class DTLSServerProtocol extends DTLSProtocol { * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag * to TRUE. */ - if (TlsProtocol.arrayContains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) { + if (TlsProtocol.arrayContains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) + { state.secure_renegotiation = true; } @@ -473,9 +554,11 @@ public class DTLSServerProtocol extends DTLSProtocol { * The server MUST check if the "renegotiation_info" extension is included in the * ClientHello. */ - if (state.clientExtensions != null) { - byte[] renegExtValue = (byte[]) state.clientExtensions.get(TlsProtocol.EXT_RenegotiationInfo); - if (renegExtValue != null) { + if (state.clientExtensions != null) + { + byte[] renegExtValue = (byte[])state.clientExtensions.get(TlsProtocol.EXT_RenegotiationInfo); + if (renegExtValue != null) + { /* * If the extension is present, set secure_renegotiation flag to TRUE. The * server MUST then verify that the length of the "renegotiated_connection" @@ -484,7 +567,8 @@ public class DTLSServerProtocol extends DTLSProtocol { state.secure_renegotiation = true; if (!Arrays.constantTimeAreEqual(renegExtValue, - TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) { + TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) + { throw new TlsFatalAlert(AlertDescription.handshake_failure); } } @@ -493,12 +577,15 @@ public class DTLSServerProtocol extends DTLSProtocol { state.server.notifySecureRenegotiation(state.secure_renegotiation); - if (state.clientExtensions != null) { + if (state.clientExtensions != null) + { state.server.processClientExtensions(state.clientExtensions); } } - protected void processClientKeyExchange(ServerHandshakeState state, byte[] body) throws IOException { + protected void processClientKeyExchange(ServerHandshakeState state, byte[] body) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(body); @@ -509,18 +596,22 @@ public class DTLSServerProtocol extends DTLSProtocol { TlsProtocol.establishMasterSecret(state.serverContext, state.keyExchange); } - protected void processClientSupplementalData(ServerHandshakeState state, byte[] body) throws IOException { + protected void processClientSupplementalData(ServerHandshakeState state, byte[] body) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(body); Vector clientSupplementalData = TlsProtocol.readSupplementalDataMessage(buf); state.server.processClientSupplementalData(clientSupplementalData); } - protected boolean expectCertificateVerifyMessage(ServerHandshakeState state) { + protected boolean expectCertificateVerifyMessage(ServerHandshakeState state) + { return state.clientCertificateType >= 0 && TlsUtils.hasSigningCapability(state.clientCertificateType); } - protected static class ServerHandshakeState { + protected static class ServerHandshakeState + { TlsServer server = null; TlsServerContextImpl serverContext = null; int[] offeredCipherSuites; diff --git a/src/main/java/org/bouncycastle/crypto/tls/DTLSTransport.java b/src/main/java/org/bouncycastle/crypto/tls/DTLSTransport.java index f62c5c99..1c053796 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DTLSTransport.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DTLSTransport.java @@ -2,53 +2,80 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -public class DTLSTransport implements DatagramTransport { +public class DTLSTransport + implements DatagramTransport +{ private final DTLSRecordLayer recordLayer; - DTLSTransport(DTLSRecordLayer recordLayer) { + DTLSTransport(DTLSRecordLayer recordLayer) + { this.recordLayer = recordLayer; } - public int getReceiveLimit() throws IOException { + public int getReceiveLimit() + throws IOException + { return recordLayer.getReceiveLimit(); } - public int getSendLimit() throws IOException { + public int getSendLimit() + throws IOException + { return recordLayer.getSendLimit(); } - public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { - try { + public int receive(byte[] buf, int off, int len, int waitMillis) + throws IOException + { + try + { return recordLayer.receive(buf, off, len, waitMillis); - } catch (TlsFatalAlert fatalAlert) { + } + catch (TlsFatalAlert fatalAlert) + { recordLayer.fail(fatalAlert.getAlertDescription()); throw fatalAlert; - } catch (IOException e) { + } + catch (IOException e) + { recordLayer.fail(AlertDescription.internal_error); throw e; - } catch (RuntimeException e) { + } + catch (RuntimeException e) + { recordLayer.fail(AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error); } } - public void send(byte[] buf, int off, int len) throws IOException { - try { + public void send(byte[] buf, int off, int len) + throws IOException + { + try + { recordLayer.send(buf, off, len); - } catch (TlsFatalAlert fatalAlert) { + } + catch (TlsFatalAlert fatalAlert) + { recordLayer.fail(fatalAlert.getAlertDescription()); throw fatalAlert; - } catch (IOException e) { + } + catch (IOException e) + { recordLayer.fail(AlertDescription.internal_error); throw e; - } catch (RuntimeException e) { + } + catch (RuntimeException e) + { recordLayer.fail(AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error); } } - public void close() throws IOException { + public void close() + throws IOException + { recordLayer.close(); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DatagramTransport.java b/src/main/java/org/bouncycastle/crypto/tls/DatagramTransport.java index 2c202be0..84c4ee4a 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DatagramTransport.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DatagramTransport.java @@ -2,15 +2,21 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -public interface DatagramTransport { +public interface DatagramTransport +{ - int getReceiveLimit() throws IOException; + int getReceiveLimit() + throws IOException; - int getSendLimit() throws IOException; + int getSendLimit() + throws IOException; - int receive(byte[] buf, int off, int len, int waitMillis) throws IOException; + int receive(byte[] buf, int off, int len, int waitMillis) + throws IOException; - void send(byte[] buf, int off, int len) throws IOException; + void send(byte[] buf, int off, int len) + throws IOException; - void close() throws IOException; + void close() + throws IOException; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsAgreementCredentials.java b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsAgreementCredentials.java index 27b2960e..98efc4f0 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsAgreementCredentials.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsAgreementCredentials.java @@ -10,7 +10,9 @@ import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.util.BigIntegers; -public class DefaultTlsAgreementCredentials implements TlsAgreementCredentials { +public class DefaultTlsAgreementCredentials + implements TlsAgreementCredentials +{ protected Certificate certificate; protected AsymmetricKeyParameter privateKey; @@ -18,27 +20,37 @@ public class DefaultTlsAgreementCredentials implements TlsAgreementCredentials { protected BasicAgreement basicAgreement; protected boolean truncateAgreement; - public DefaultTlsAgreementCredentials(Certificate certificate, AsymmetricKeyParameter privateKey) { - if (certificate == null) { + public DefaultTlsAgreementCredentials(Certificate certificate, AsymmetricKeyParameter privateKey) + { + if (certificate == null) + { throw new IllegalArgumentException("'certificate' cannot be null"); } - if (certificate.isEmpty()) { + if (certificate.isEmpty()) + { throw new IllegalArgumentException("'certificate' cannot be empty"); } - if (privateKey == null) { + if (privateKey == null) + { throw new IllegalArgumentException("'privateKey' cannot be null"); } - if (!privateKey.isPrivate()) { + if (!privateKey.isPrivate()) + { throw new IllegalArgumentException("'privateKey' must be private"); } - if (privateKey instanceof DHPrivateKeyParameters) { + if (privateKey instanceof DHPrivateKeyParameters) + { basicAgreement = new DHBasicAgreement(); truncateAgreement = true; - } else if (privateKey instanceof ECPrivateKeyParameters) { + } + else if (privateKey instanceof ECPrivateKeyParameters) + { basicAgreement = new ECDHBasicAgreement(); truncateAgreement = false; - } else { + } + else + { throw new IllegalArgumentException("'privateKey' type not supported: " + privateKey.getClass().getName()); } @@ -47,15 +59,18 @@ public class DefaultTlsAgreementCredentials implements TlsAgreementCredentials { this.privateKey = privateKey; } - public Certificate getCertificate() { + public Certificate getCertificate() + { return certificate; } - public byte[] generateAgreement(AsymmetricKeyParameter peerPublicKey) { + public byte[] generateAgreement(AsymmetricKeyParameter peerPublicKey) + { basicAgreement.init(privateKey); BigInteger agreementValue = basicAgreement.calculateAgreement(peerPublicKey); - if (truncateAgreement) { + if (truncateAgreement) + { return BigIntegers.asUnsignedByteArray(agreementValue); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsCipherFactory.java b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsCipherFactory.java index f4b525f9..18551a98 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsCipherFactory.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsCipherFactory.java @@ -19,11 +19,16 @@ import org.bouncycastle.crypto.modes.AEADBlockCipher; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; -public class DefaultTlsCipherFactory extends AbstractTlsCipherFactory { +public class DefaultTlsCipherFactory + extends AbstractTlsCipherFactory +{ - public TlsCipher createCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) throws IOException { + public TlsCipher createCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) + throws IOException + { - switch (encryptionAlgorithm) { + switch (encryptionAlgorithm) + { case EncryptionAlgorithm._3DES_EDE_CBC: return createDESedeCipher(context, macAlgorithm); case EncryptionAlgorithm.AES_128_CBC: @@ -52,75 +57,93 @@ public class DefaultTlsCipherFactory extends AbstractTlsCipherFactory { } protected TlsBlockCipher createAESCipher(TlsContext context, int cipherKeySize, int macAlgorithm) - throws IOException { + throws IOException + { return new TlsBlockCipher(context, createAESBlockCipher(), createAESBlockCipher(), createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), cipherKeySize); } protected TlsAEADCipher createCipher_AES_GCM(TlsContext context, int cipherKeySize, int macSize) - throws IOException { + throws IOException + { return new TlsAEADCipher(context, createAEADBlockCipher_AES_GCM(), createAEADBlockCipher_AES_GCM(), cipherKeySize, macSize); } protected TlsBlockCipher createCamelliaCipher(TlsContext context, int cipherKeySize, - int macAlgorithm) throws IOException { + int macAlgorithm) + throws IOException + { return new TlsBlockCipher(context, createCamelliaBlockCipher(), createCamelliaBlockCipher(), createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), cipherKeySize); } protected TlsNullCipher createNullCipher(TlsContext context, int macAlgorithm) - throws IOException { + throws IOException + { return new TlsNullCipher(context, createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm)); } protected TlsStreamCipher createRC4Cipher(TlsContext context, int cipherKeySize, - int macAlgorithm) throws IOException { + int macAlgorithm) + throws IOException + { return new TlsStreamCipher(context, createRC4StreamCipher(), createRC4StreamCipher(), createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), cipherKeySize); } protected TlsBlockCipher createDESedeCipher(TlsContext context, int macAlgorithm) - throws IOException { + throws IOException + { return new TlsBlockCipher(context, createDESedeBlockCipher(), createDESedeBlockCipher(), createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), 24); } protected TlsBlockCipher createSEEDCipher(TlsContext context, int macAlgorithm) - throws IOException { + throws IOException + { return new TlsBlockCipher(context, createSEEDBlockCipher(), createSEEDBlockCipher(), createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), 16); } - protected StreamCipher createRC4StreamCipher() { + protected StreamCipher createRC4StreamCipher() + { return new RC4Engine(); } - protected BlockCipher createAESBlockCipher() { + protected BlockCipher createAESBlockCipher() + { return new CBCBlockCipher(new AESFastEngine()); } - protected AEADBlockCipher createAEADBlockCipher_AES_GCM() { + protected AEADBlockCipher createAEADBlockCipher_AES_GCM() + { // TODO Consider allowing custom configuration of multiplier return new GCMBlockCipher(new AESFastEngine()); } - protected BlockCipher createCamelliaBlockCipher() { + protected BlockCipher createCamelliaBlockCipher() + { return new CBCBlockCipher(new CamelliaEngine()); } - protected BlockCipher createDESedeBlockCipher() { + protected BlockCipher createDESedeBlockCipher() + { return new CBCBlockCipher(new DESedeEngine()); } - protected BlockCipher createSEEDBlockCipher() { + protected BlockCipher createSEEDBlockCipher() + { return new CBCBlockCipher(new SEEDEngine()); } - protected Digest createHMACDigest(int macAlgorithm) throws IOException { - switch (macAlgorithm) { + protected Digest createHMACDigest(int macAlgorithm) + throws IOException + { + switch (macAlgorithm) + { case MACAlgorithm._null: return null; case MACAlgorithm.hmac_md5: diff --git a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsClient.java b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsClient.java index 681de337..920af5dd 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsClient.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsClient.java @@ -3,32 +3,40 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; import java.util.Hashtable; -public abstract class DefaultTlsClient extends AbstractTlsClient { +public abstract class DefaultTlsClient + extends AbstractTlsClient +{ protected int[] namedCurves; protected short[] clientECPointFormats, serverECPointFormats; - public DefaultTlsClient() { + public DefaultTlsClient() + { super(); } - public DefaultTlsClient(TlsCipherFactory cipherFactory) { + public DefaultTlsClient(TlsCipherFactory cipherFactory) + { super(cipherFactory); } - public int[] getCipherSuites() { - return new int[] { CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + public int[] getCipherSuites() + { + return new int[]{CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, - CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA, }; + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,}; } - public Hashtable getClientExtensions() throws IOException { + public Hashtable getClientExtensions() + throws IOException + { Hashtable clientExtensions = super.getClientExtensions(); - if (TlsECCUtils.containsECCCipherSuites(getCipherSuites())) { + if (TlsECCUtils.containsECCCipherSuites(getCipherSuites())) + { /* * RFC 4492 5.1. A client that proposes ECC cipher suites in its ClientHello message * appends these extensions (along with any others), enumerating the curves it supports @@ -39,13 +47,14 @@ public abstract class DefaultTlsClient extends AbstractTlsClient { * TODO Could just add all the curves since we support them all, but users may not want * to use unnecessarily large fields. Need configuration options. */ - this.namedCurves = new int[] { NamedCurve.secp256r1, NamedCurve.sect233r1, NamedCurve.secp224r1, + this.namedCurves = new int[]{NamedCurve.secp256r1, NamedCurve.sect233r1, NamedCurve.secp224r1, NamedCurve.sect193r1, NamedCurve.secp192r1, NamedCurve.arbitrary_explicit_char2_curves, - NamedCurve.arbitrary_explicit_prime_curves }; - this.clientECPointFormats = new short[] { ECPointFormat.ansiX962_compressed_char2, - ECPointFormat.ansiX962_compressed_prime, ECPointFormat.uncompressed }; + NamedCurve.arbitrary_explicit_prime_curves}; + this.clientECPointFormats = new short[]{ECPointFormat.ansiX962_compressed_char2, + ECPointFormat.ansiX962_compressed_prime, ECPointFormat.uncompressed}; - if (clientExtensions == null) { + if (clientExtensions == null) + { clientExtensions = new Hashtable(); } @@ -56,26 +65,34 @@ public abstract class DefaultTlsClient extends AbstractTlsClient { return clientExtensions; } - public void processServerExtensions(Hashtable serverExtensions) throws IOException { + public void processServerExtensions(Hashtable serverExtensions) + throws IOException + { super.processServerExtensions(serverExtensions); - if (serverExtensions != null) { + if (serverExtensions != null) + { int[] namedCurves = TlsECCUtils.getSupportedEllipticCurvesExtension(serverExtensions); - if (namedCurves != null) { + if (namedCurves != null) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } this.serverECPointFormats = TlsECCUtils.getSupportedPointFormatsExtension(serverExtensions); - if (this.serverECPointFormats != null && !TlsECCUtils.isECCCipherSuite(this.selectedCipherSuite)) { + if (this.serverECPointFormats != null && !TlsECCUtils.isECCCipherSuite(this.selectedCipherSuite)) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } } - public TlsKeyExchange getKeyExchange() throws IOException { + public TlsKeyExchange getKeyExchange() + throws IOException + { - switch (selectedCipherSuite) { + switch (selectedCipherSuite) + { case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: @@ -195,9 +212,12 @@ public abstract class DefaultTlsClient extends AbstractTlsClient { } } - public TlsCipher getCipher() throws IOException { + public TlsCipher getCipher() + throws IOException + { - switch (selectedCipherSuite) { + switch (selectedCipherSuite) + { case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: @@ -331,25 +351,30 @@ public abstract class DefaultTlsClient extends AbstractTlsClient { } } - protected TlsKeyExchange createDHKeyExchange(int keyExchange) { + protected TlsKeyExchange createDHKeyExchange(int keyExchange) + { return new TlsDHKeyExchange(keyExchange, supportedSignatureAlgorithms, null); } - protected TlsKeyExchange createDHEKeyExchange(int keyExchange) { + protected TlsKeyExchange createDHEKeyExchange(int keyExchange) + { return new TlsDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, null); } - protected TlsKeyExchange createECDHKeyExchange(int keyExchange) { + protected TlsKeyExchange createECDHKeyExchange(int keyExchange) + { return new TlsECDHKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats); } - protected TlsKeyExchange createECDHEKeyExchange(int keyExchange) { + protected TlsKeyExchange createECDHEKeyExchange(int keyExchange) + { return new TlsECDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats); } - protected TlsKeyExchange createRSAKeyExchange() { + protected TlsKeyExchange createRSAKeyExchange() + { return new TlsRSAKeyExchange(supportedSignatureAlgorithms); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsEncryptionCredentials.java b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsEncryptionCredentials.java index a9e95ea0..c21a555d 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsEncryptionCredentials.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsEncryptionCredentials.java @@ -9,28 +9,38 @@ import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; -public class DefaultTlsEncryptionCredentials implements TlsEncryptionCredentials { +public class DefaultTlsEncryptionCredentials + implements TlsEncryptionCredentials +{ protected TlsContext context; protected Certificate certificate; protected AsymmetricKeyParameter privateKey; public DefaultTlsEncryptionCredentials(TlsContext context, Certificate certificate, - AsymmetricKeyParameter privateKey) { - if (certificate == null) { + AsymmetricKeyParameter privateKey) + { + if (certificate == null) + { throw new IllegalArgumentException("'certificate' cannot be null"); } - if (certificate.isEmpty()) { + if (certificate.isEmpty()) + { throw new IllegalArgumentException("'certificate' cannot be empty"); } - if (privateKey == null) { + if (privateKey == null) + { throw new IllegalArgumentException("'privateKey' cannot be null"); } - if (!privateKey.isPrivate()) { + if (!privateKey.isPrivate()) + { throw new IllegalArgumentException("'privateKey' must be private"); } - if (privateKey instanceof RSAKeyParameters) { - } else { + if (privateKey instanceof RSAKeyParameters) + { + } + else + { throw new IllegalArgumentException("'privateKey' type not supported: " + privateKey.getClass().getName()); } @@ -40,19 +50,25 @@ public class DefaultTlsEncryptionCredentials implements TlsEncryptionCredentials this.privateKey = privateKey; } - public Certificate getCertificate() { + public Certificate getCertificate() + { return certificate; } - public byte[] decryptPreMasterSecret(byte[] encryptedPreMasterSecret) throws IOException { + public byte[] decryptPreMasterSecret(byte[] encryptedPreMasterSecret) + throws IOException + { PKCS1Encoding encoding = new PKCS1Encoding(new RSABlindedEngine()); encoding.init(false, new ParametersWithRandom(this.privateKey, context.getSecureRandom())); - try { + try + { return encoding.processBlock(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.length); - } catch (InvalidCipherTextException e) { + } + catch (InvalidCipherTextException e) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsServer.java b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsServer.java index 546e05f2..4eb17533 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsServer.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsServer.java @@ -5,39 +5,52 @@ import java.io.IOException; import org.bouncycastle.crypto.agreement.DHStandardGroups; import org.bouncycastle.crypto.params.DHParameters; -public abstract class DefaultTlsServer extends AbstractTlsServer { +public abstract class DefaultTlsServer + extends AbstractTlsServer +{ - public DefaultTlsServer() { + public DefaultTlsServer() + { super(); } - public DefaultTlsServer(TlsCipherFactory cipherFactory) { + public DefaultTlsServer(TlsCipherFactory cipherFactory) + { super(cipherFactory); } - protected TlsEncryptionCredentials getRSAEncryptionCredentials() throws IOException { + protected TlsEncryptionCredentials getRSAEncryptionCredentials() + throws IOException + { throw new TlsFatalAlert(AlertDescription.internal_error); } - protected TlsSignerCredentials getRSASignerCredentials() throws IOException { + protected TlsSignerCredentials getRSASignerCredentials() + throws IOException + { throw new TlsFatalAlert(AlertDescription.internal_error); } - protected DHParameters getDHParameters() { + protected DHParameters getDHParameters() + { return DHStandardGroups.rfc5114_1024_160; } - protected int[] getCipherSuites() { - return new int[] { CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + protected int[] getCipherSuites() + { + return new int[]{CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, - CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA, }; + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,}; } - public TlsCredentials getCredentials() throws IOException { + public TlsCredentials getCredentials() + throws IOException + { - switch (selectedCipherSuite) { + switch (selectedCipherSuite) + { case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: @@ -82,9 +95,12 @@ public abstract class DefaultTlsServer extends AbstractTlsServer { } } - public TlsKeyExchange getKeyExchange() throws IOException { + public TlsKeyExchange getKeyExchange() + throws IOException + { - switch (selectedCipherSuite) { + switch (selectedCipherSuite) + { case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: @@ -202,9 +218,12 @@ public abstract class DefaultTlsServer extends AbstractTlsServer { } } - public TlsCipher getCipher() throws IOException { + public TlsCipher getCipher() + throws IOException + { - switch (selectedCipherSuite) { + switch (selectedCipherSuite) + { case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: @@ -336,25 +355,30 @@ public abstract class DefaultTlsServer extends AbstractTlsServer { } } - protected TlsKeyExchange createDHKeyExchange(int keyExchange) { + protected TlsKeyExchange createDHKeyExchange(int keyExchange) + { return new TlsDHKeyExchange(keyExchange, supportedSignatureAlgorithms, getDHParameters()); } - protected TlsKeyExchange createDHEKeyExchange(int keyExchange) { + protected TlsKeyExchange createDHEKeyExchange(int keyExchange) + { return new TlsDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, getDHParameters()); } - protected TlsKeyExchange createECDHKeyExchange(int keyExchange) { + protected TlsKeyExchange createECDHKeyExchange(int keyExchange) + { return new TlsECDHKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats); } - protected TlsKeyExchange createECDHEKeyExchange(int keyExchange) { + protected TlsKeyExchange createECDHEKeyExchange(int keyExchange) + { return new TlsECDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats); } - protected TlsKeyExchange createRSAKeyExchange() { + protected TlsKeyExchange createRSAKeyExchange() + { return new TlsRSAKeyExchange(supportedSignatureAlgorithms); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsSignerCredentials.java b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsSignerCredentials.java index 89f029c7..3254eb0a 100755 --- a/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsSignerCredentials.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsSignerCredentials.java @@ -8,35 +8,49 @@ import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; -public class DefaultTlsSignerCredentials implements TlsSignerCredentials { +public class DefaultTlsSignerCredentials + implements TlsSignerCredentials +{ protected TlsContext context; protected Certificate certificate; protected AsymmetricKeyParameter privateKey; protected TlsSigner signer; - public DefaultTlsSignerCredentials(TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey) { + public DefaultTlsSignerCredentials(TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey) + { - if (certificate == null) { + if (certificate == null) + { throw new IllegalArgumentException("'certificate' cannot be null"); } - if (certificate.isEmpty()) { + if (certificate.isEmpty()) + { throw new IllegalArgumentException("'certificate' cannot be empty"); } - if (privateKey == null) { + if (privateKey == null) + { throw new IllegalArgumentException("'privateKey' cannot be null"); } - if (!privateKey.isPrivate()) { + if (!privateKey.isPrivate()) + { throw new IllegalArgumentException("'privateKey' must be private"); } - if (privateKey instanceof RSAKeyParameters) { + if (privateKey instanceof RSAKeyParameters) + { this.signer = new TlsRSASigner(); - } else if (privateKey instanceof DSAPrivateKeyParameters) { + } + else if (privateKey instanceof DSAPrivateKeyParameters) + { this.signer = new TlsDSSSigner(); - } else if (privateKey instanceof ECPrivateKeyParameters) { + } + else if (privateKey instanceof ECPrivateKeyParameters) + { this.signer = new TlsECDSASigner(); - } else { + } + else + { throw new IllegalArgumentException("'privateKey' type not supported: " + privateKey.getClass().getName()); } @@ -47,14 +61,20 @@ public class DefaultTlsSignerCredentials implements TlsSignerCredentials { this.privateKey = privateKey; } - public Certificate getCertificate() { + public Certificate getCertificate() + { return certificate; } - public byte[] generateCertificateSignature(byte[] md5andsha1) throws IOException { - try { + public byte[] generateCertificateSignature(byte[] md5andsha1) + throws IOException + { + try + { return signer.generateRawSignature(privateKey, md5andsha1); - } catch (CryptoException e) { + } + catch (CryptoException e) + { throw new TlsFatalAlert(AlertDescription.internal_error); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DeferredHash.java b/src/main/java/org/bouncycastle/crypto/tls/DeferredHash.java index 363fc22a..0682ceb7 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DeferredHash.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DeferredHash.java @@ -7,7 +7,9 @@ import org.bouncycastle.crypto.Digest; /** * Buffers input until the hash algorithm is determined. */ -class DeferredHash implements TlsHandshakeHash { +class DeferredHash + implements TlsHandshakeHash +{ protected TlsContext context; @@ -15,21 +17,25 @@ class DeferredHash implements TlsHandshakeHash { private int prfAlgorithm = -1; private Digest hash = null; - DeferredHash() { + DeferredHash() + { this.buf = new ByteArrayOutputStream(); this.hash = null; } - private DeferredHash(Digest hash) { + private DeferredHash(Digest hash) + { this.buf = null; this.hash = hash; } - public void init(TlsContext context) { + public void init(TlsContext context) + { this.context = context; } - public TlsHandshakeHash commit() { + public TlsHandshakeHash commit() + { int prfAlgorithm = context.getSecurityParameters().getPrfAlgorithm(); @@ -38,8 +44,9 @@ class DeferredHash implements TlsHandshakeHash { byte[] data = buf.toByteArray(); prfHash.update(data, 0, data.length); - if (prfHash instanceof TlsHandshakeHash) { - TlsHandshakeHash tlsPRFHash = (TlsHandshakeHash) prfHash; + if (prfHash instanceof TlsHandshakeHash) + { + TlsHandshakeHash tlsPRFHash = (TlsHandshakeHash)prfHash; tlsPRFHash.init(context); return tlsPRFHash.commit(); } @@ -51,52 +58,70 @@ class DeferredHash implements TlsHandshakeHash { return this; } - public TlsHandshakeHash fork() { + public TlsHandshakeHash fork() + { checkHash(); return new DeferredHash(TlsUtils.clonePRFHash(prfAlgorithm, hash)); } - public String getAlgorithmName() { + public String getAlgorithmName() + { checkHash(); return hash.getAlgorithmName(); } - public int getDigestSize() { + public int getDigestSize() + { checkHash(); return hash.getDigestSize(); } - public void update(byte input) { - if (hash == null) { + public void update(byte input) + { + if (hash == null) + { buf.write(input); - } else { + } + else + { hash.update(input); } } - public void update(byte[] input, int inOff, int len) { - if (hash == null) { + public void update(byte[] input, int inOff, int len) + { + if (hash == null) + { buf.write(input, inOff, len); - } else { + } + else + { hash.update(input, inOff, len); } } - public int doFinal(byte[] output, int outOff) { + public int doFinal(byte[] output, int outOff) + { checkHash(); return hash.doFinal(output, outOff); } - public void reset() { - if (hash == null) { + public void reset() + { + if (hash == null) + { buf.reset(); - } else { + } + else + { hash.reset(); } } - protected void checkHash() { - if (hash == null) { + protected void checkHash() + { + if (hash == null) + { throw new IllegalStateException("No hash algorithm has been set"); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/DigestAlgorithm.java b/src/main/java/org/bouncycastle/crypto/tls/DigestAlgorithm.java index 24953914..41d54009 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/DigestAlgorithm.java +++ b/src/main/java/org/bouncycastle/crypto/tls/DigestAlgorithm.java @@ -2,13 +2,14 @@ package org.bouncycastle.crypto.tls; /** * RFC 2246 - * + *

* Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). - * + * * @deprecated use MACAlgorithm constants instead */ -public class DigestAlgorithm { +public class DigestAlgorithm +{ public static final int NULL = 0; public static final int MD5 = 1; public static final int SHA = 2; diff --git a/src/main/java/org/bouncycastle/crypto/tls/ECBasisType.java b/src/main/java/org/bouncycastle/crypto/tls/ECBasisType.java index 24c304c8..b73c75b9 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/ECBasisType.java +++ b/src/main/java/org/bouncycastle/crypto/tls/ECBasisType.java @@ -3,7 +3,8 @@ package org.bouncycastle.crypto.tls; /** * RFC 4492 5.4. (Errata ID: 2389) */ -public class ECBasisType { +public class ECBasisType +{ public static final short ec_basis_trinomial = 1; public static final short ec_basis_pentanomial = 2; diff --git a/src/main/java/org/bouncycastle/crypto/tls/EncryptionAlgorithm.java b/src/main/java/org/bouncycastle/crypto/tls/EncryptionAlgorithm.java index 6cc8a094..069237c0 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/EncryptionAlgorithm.java +++ b/src/main/java/org/bouncycastle/crypto/tls/EncryptionAlgorithm.java @@ -2,11 +2,12 @@ package org.bouncycastle.crypto.tls; /** * RFC 2246 - * + *

* Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ -public class EncryptionAlgorithm { +public class EncryptionAlgorithm +{ public static final int NULL = 0; public static final int RC4_40 = 1; diff --git a/src/main/java/org/bouncycastle/crypto/tls/ExporterLabel.java b/src/main/java/org/bouncycastle/crypto/tls/ExporterLabel.java index d287956e..08d2f221 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/ExporterLabel.java +++ b/src/main/java/org/bouncycastle/crypto/tls/ExporterLabel.java @@ -3,7 +3,8 @@ package org.bouncycastle.crypto.tls; /** * RFC 5705 */ -public class ExporterLabel { +public class ExporterLabel +{ /* * RFC 5246 */ diff --git a/src/main/java/org/bouncycastle/crypto/tls/HandshakeType.java b/src/main/java/org/bouncycastle/crypto/tls/HandshakeType.java index 94dcfb23..53b4520c 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/HandshakeType.java +++ b/src/main/java/org/bouncycastle/crypto/tls/HandshakeType.java @@ -2,9 +2,9 @@ package org.bouncycastle.crypto.tls; public class HandshakeType { - /* - * RFC 2246 7.4 - */ + /* + * RFC 2246 7.4 + */ public static final short hello_request = 0; public static final short client_hello = 1; public static final short server_hello = 2; diff --git a/src/main/java/org/bouncycastle/crypto/tls/HashAlgorithm.java b/src/main/java/org/bouncycastle/crypto/tls/HashAlgorithm.java index aacb4e42..fdd8c84b 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/HashAlgorithm.java +++ b/src/main/java/org/bouncycastle/crypto/tls/HashAlgorithm.java @@ -3,7 +3,8 @@ package org.bouncycastle.crypto.tls; /** * RFC 5246 7.4.1.4.1 */ -public class HashAlgorithm { +public class HashAlgorithm +{ public static final short none = 0; public static final short md5 = 1; diff --git a/src/main/java/org/bouncycastle/crypto/tls/KeyExchangeAlgorithm.java b/src/main/java/org/bouncycastle/crypto/tls/KeyExchangeAlgorithm.java index 082f1252..c049bb70 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/KeyExchangeAlgorithm.java +++ b/src/main/java/org/bouncycastle/crypto/tls/KeyExchangeAlgorithm.java @@ -2,7 +2,7 @@ package org.bouncycastle.crypto.tls; /** * RFC 2246 - * + *

* Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ @@ -21,7 +21,7 @@ public class KeyExchangeAlgorithm public static final int DH_RSA_EXPORT = 10; public static final int DH_anon = 11; public static final int DH_anon_EXPORT = 12; - + /* * RFC 4279 */ diff --git a/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsAuthentication.java b/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsAuthentication.java index 51da5d1d..9bcf2deb 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsAuthentication.java +++ b/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsAuthentication.java @@ -4,10 +4,11 @@ import java.io.IOException; /** * A temporary class to wrap old CertificateVerifyer stuff for new TlsAuthentication - * + * * @deprecated */ -public class LegacyTlsAuthentication extends ServerOnlyTlsAuthentication +public class LegacyTlsAuthentication + extends ServerOnlyTlsAuthentication { protected CertificateVerifyer verifyer; @@ -16,7 +17,8 @@ public class LegacyTlsAuthentication extends ServerOnlyTlsAuthentication this.verifyer = verifyer; } - public void notifyServerCertificate(Certificate serverCertificate) throws IOException + public void notifyServerCertificate(Certificate serverCertificate) + throws IOException { if (!this.verifyer.isValid(serverCertificate.getCertificateList())) { diff --git a/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsClient.java b/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsClient.java index 2af98b84..33217ac4 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsClient.java +++ b/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsClient.java @@ -4,12 +4,15 @@ import java.io.IOException; /** * A temporary class to use LegacyTlsAuthentication - * + * * @deprecated */ -public class LegacyTlsClient extends DefaultTlsClient +public class LegacyTlsClient + extends DefaultTlsClient { - /** @deprecated */ + /** + * @deprecated + */ protected CertificateVerifyer verifyer; /** @@ -22,7 +25,8 @@ public class LegacyTlsClient extends DefaultTlsClient this.verifyer = verifyer; } - public TlsAuthentication getAuthentication() throws IOException + public TlsAuthentication getAuthentication() + throws IOException { return new LegacyTlsAuthentication(verifyer); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/MACAlgorithm.java b/src/main/java/org/bouncycastle/crypto/tls/MACAlgorithm.java index 03321c59..fe6ebd41 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/MACAlgorithm.java +++ b/src/main/java/org/bouncycastle/crypto/tls/MACAlgorithm.java @@ -2,11 +2,12 @@ package org.bouncycastle.crypto.tls; /** * RFC 2246 - * + *

* Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ -public class MACAlgorithm { +public class MACAlgorithm +{ public static final int _null = 0; public static final int md5 = 1; diff --git a/src/main/java/org/bouncycastle/crypto/tls/NamedCurve.java b/src/main/java/org/bouncycastle/crypto/tls/NamedCurve.java index 10480cd4..9a20f22f 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/NamedCurve.java +++ b/src/main/java/org/bouncycastle/crypto/tls/NamedCurve.java @@ -2,14 +2,15 @@ package org.bouncycastle.crypto.tls; /** * RFC 4492 5.1.1 - * + *

* The named curves defined here are those specified in SEC 2 [13]. Note that many of these curves * are also recommended in ANSI X9.62 [7] and FIPS 186-2 [11]. Values 0xFE00 through 0xFEFF are * reserved for private use. Values 0xFF01 and 0xFF02 indicate that the client supports arbitrary * prime and characteristic-2 curves, respectively (the curve parameters must be encoded explicitly * in ECParameters). */ -public class NamedCurve { +public class NamedCurve +{ public static final int sect163k1 = 1; public static final int sect163r1 = 2; public static final int sect163r2 = 3; @@ -43,8 +44,10 @@ public class NamedCurve { public static final int arbitrary_explicit_prime_curves = 0xFF01; public static final int arbitrary_explicit_char2_curves = 0xFF02; - public static boolean refersToASpecificNamedCurve(int namedCurve) { - switch (namedCurve) { + public static boolean refersToASpecificNamedCurve(int namedCurve) + { + switch (namedCurve) + { case arbitrary_explicit_prime_curves: case arbitrary_explicit_char2_curves: return false; diff --git a/src/main/java/org/bouncycastle/crypto/tls/NewSessionTicket.java b/src/main/java/org/bouncycastle/crypto/tls/NewSessionTicket.java index 24b75ba7..c80968ff 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/NewSessionTicket.java +++ b/src/main/java/org/bouncycastle/crypto/tls/NewSessionTicket.java @@ -4,30 +4,38 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -public class NewSessionTicket { +public class NewSessionTicket +{ protected long ticketLifetimeHint; protected byte[] ticket; - public NewSessionTicket(long ticketLifetimeHint, byte[] ticket) { + public NewSessionTicket(long ticketLifetimeHint, byte[] ticket) + { this.ticketLifetimeHint = ticketLifetimeHint; this.ticket = ticket; } - public long getTicketLifetimeHint() { + public long getTicketLifetimeHint() + { return ticketLifetimeHint; } - public byte[] getTicket() { + public byte[] getTicket() + { return ticket; } - public void encode(OutputStream output) throws IOException { + public void encode(OutputStream output) + throws IOException + { TlsUtils.writeUint32(ticketLifetimeHint, output); TlsUtils.writeOpaque16(ticket, output); } - public static NewSessionTicket parse(InputStream input) throws IOException { + public static NewSessionTicket parse(InputStream input) + throws IOException + { long ticketLifetimeHint = TlsUtils.readUint32(input); byte[] ticket = TlsUtils.readOpaque16(input); return new NewSessionTicket(ticketLifetimeHint, ticket); diff --git a/src/main/java/org/bouncycastle/crypto/tls/PRFAlgorithm.java b/src/main/java/org/bouncycastle/crypto/tls/PRFAlgorithm.java index 530643ec..b1728b47 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/PRFAlgorithm.java +++ b/src/main/java/org/bouncycastle/crypto/tls/PRFAlgorithm.java @@ -2,11 +2,12 @@ package org.bouncycastle.crypto.tls; /** * RFC 5246 - * + *

* Note that the values here are implementation-specific and arbitrary. It is recommended not to * depend on the particular values (e.g. serialization). */ -public class PRFAlgorithm { +public class PRFAlgorithm +{ /* * Placeholder to refer to the legacy TLS algorithm diff --git a/src/main/java/org/bouncycastle/crypto/tls/PSKTlsClient.java b/src/main/java/org/bouncycastle/crypto/tls/PSKTlsClient.java index c644e6cf..df4a65a2 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/PSKTlsClient.java +++ b/src/main/java/org/bouncycastle/crypto/tls/PSKTlsClient.java @@ -2,31 +2,39 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -public abstract class PSKTlsClient extends AbstractTlsClient { +public abstract class PSKTlsClient + extends AbstractTlsClient +{ protected TlsPSKIdentity pskIdentity; - public PSKTlsClient(TlsPSKIdentity pskIdentity) { + public PSKTlsClient(TlsPSKIdentity pskIdentity) + { super(); this.pskIdentity = pskIdentity; } - public PSKTlsClient(TlsCipherFactory cipherFactory, TlsPSKIdentity pskIdentity) { + public PSKTlsClient(TlsCipherFactory cipherFactory, TlsPSKIdentity pskIdentity) + { super(cipherFactory); this.pskIdentity = pskIdentity; } - public int[] getCipherSuites() { - return new int[] { CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA, CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA, + public int[] getCipherSuites() + { + return new int[]{CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA, CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA, CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA, CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA, CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA, CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA, CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA, - CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_PSK_WITH_RC4_128_SHA, }; + CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_PSK_WITH_RC4_128_SHA,}; } - public TlsKeyExchange getKeyExchange() throws IOException { + public TlsKeyExchange getKeyExchange() + throws IOException + { - switch (selectedCipherSuite) { + switch (selectedCipherSuite) + { case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: @@ -58,9 +66,12 @@ public abstract class PSKTlsClient extends AbstractTlsClient { } } - public TlsCipher getCipher() throws IOException { + public TlsCipher getCipher() + throws IOException + { - switch (selectedCipherSuite) { + switch (selectedCipherSuite) + { case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: @@ -96,7 +107,8 @@ public abstract class PSKTlsClient extends AbstractTlsClient { } } - protected TlsKeyExchange createPSKKeyExchange(int keyExchange) { + protected TlsKeyExchange createPSKKeyExchange(int keyExchange) + { return new TlsPSKKeyExchange(keyExchange, supportedSignatureAlgorithms, pskIdentity); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/ProtocolVersion.java b/src/main/java/org/bouncycastle/crypto/tls/ProtocolVersion.java index 87bb891c..aade297a 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/ProtocolVersion.java +++ b/src/main/java/org/bouncycastle/crypto/tls/ProtocolVersion.java @@ -2,7 +2,8 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -public final class ProtocolVersion { +public final class ProtocolVersion +{ public static final ProtocolVersion SSLv3 = new ProtocolVersion(0x0300, "SSL 3.0"); public static final ProtocolVersion TLSv10 = new ProtocolVersion(0x0301, "TLS 1.0"); @@ -14,69 +15,88 @@ public final class ProtocolVersion { private int version; private String name; - private ProtocolVersion(int v, String name) { + private ProtocolVersion(int v, String name) + { this.version = v & 0xffff; this.name = name; } - public int getFullVersion() { + public int getFullVersion() + { return version; } - public int getMajorVersion() { + public int getMajorVersion() + { return version >> 8; } - public int getMinorVersion() { + public int getMinorVersion() + { return version & 0xff; } - public boolean isDTLS() { + public boolean isDTLS() + { return getMajorVersion() == 0xFE; } - public boolean isSSL() { + public boolean isSSL() + { return this == SSLv3; } - public ProtocolVersion getEquivalentTLSVersion() { - if (!isDTLS()) { + public ProtocolVersion getEquivalentTLSVersion() + { + if (!isDTLS()) + { return this; } - if (this == DTLSv10) { + if (this == DTLSv10) + { return TLSv11; } return TLSv12; } - public boolean isEqualOrEarlierVersionOf(ProtocolVersion version) { - if (getMajorVersion() != version.getMajorVersion()) { + public boolean isEqualOrEarlierVersionOf(ProtocolVersion version) + { + if (getMajorVersion() != version.getMajorVersion()) + { return false; } int diffMinorVersion = version.getMinorVersion() - getMinorVersion(); return isDTLS() ? diffMinorVersion <= 0 : diffMinorVersion >= 0; } - public boolean isLaterVersionOf(ProtocolVersion version) { - if (getMajorVersion() != version.getMajorVersion()) { + public boolean isLaterVersionOf(ProtocolVersion version) + { + if (getMajorVersion() != version.getMajorVersion()) + { return false; } int diffMinorVersion = version.getMinorVersion() - getMinorVersion(); return isDTLS() ? diffMinorVersion > 0 : diffMinorVersion < 0; } - public boolean equals(Object obj) { + public boolean equals(Object obj) + { return this == obj; } - public int hashCode() { + public int hashCode() + { return version; } - public static ProtocolVersion get(int major, int minor) throws IOException { - switch (major) { + public static ProtocolVersion get(int major, int minor) + throws IOException + { + switch (major) + { case 0x03: - switch (minor) { + switch (minor) + { case 0x00: return SSLv3; case 0x01: @@ -87,7 +107,8 @@ public final class ProtocolVersion { return TLSv12; } case 0xFE: - switch (minor) { + switch (minor) + { case 0xFF: return DTLSv10; case 0xFD: @@ -98,7 +119,8 @@ public final class ProtocolVersion { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } - public String toString() { + public String toString() + { return name; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/RecordStream.java b/src/main/java/org/bouncycastle/crypto/tls/RecordStream.java index 5760e87a..7ff8551a 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/RecordStream.java +++ b/src/main/java/org/bouncycastle/crypto/tls/RecordStream.java @@ -10,7 +10,8 @@ import org.bouncycastle.crypto.Digest; /** * An implementation of the TLS 1.0/1.1/1.2 record layer, allowing downgrade to SSLv3. */ -class RecordStream { +class RecordStream +{ private static int PLAINTEXT_LIMIT = (1 << 14); private static int COMPRESSED_LIMIT = PLAINTEXT_LIMIT + 1024; @@ -30,7 +31,8 @@ class RecordStream { private ProtocolVersion readVersion = null, writeVersion = null; private boolean restrictReadVersion = true; - RecordStream(TlsProtocol handler, InputStream input, OutputStream output) { + RecordStream(TlsProtocol handler, InputStream input, OutputStream output) + { this.handler = handler; this.input = input; this.output = output; @@ -40,21 +42,25 @@ class RecordStream { this.writeCipher = this.readCipher; } - void init(TlsContext context) { + void init(TlsContext context) + { this.context = context; this.hash = new DeferredHash(); this.hash.init(context); } - ProtocolVersion getReadVersion() { + ProtocolVersion getReadVersion() + { return readVersion; } - void setReadVersion(ProtocolVersion readVersion) { + void setReadVersion(ProtocolVersion readVersion) + { this.readVersion = readVersion; } - void setWriteVersion(ProtocolVersion writeVersion) { + void setWriteVersion(ProtocolVersion writeVersion) + { this.writeVersion = writeVersion; } @@ -65,21 +71,27 @@ class RecordStream { * compliant with this specification MUST accept any value {03,XX} as the record layer version * number for ClientHello." */ - void setRestrictReadVersion(boolean enabled) { + void setRestrictReadVersion(boolean enabled) + { this.restrictReadVersion = enabled; } - void notifyHelloComplete() { + void notifyHelloComplete() + { this.hash = this.hash.commit(); } - void setPendingConnectionState(TlsCompression tlsCompression, TlsCipher tlsCipher) { + void setPendingConnectionState(TlsCompression tlsCompression, TlsCipher tlsCipher) + { this.pendingCompression = tlsCompression; this.pendingCipher = tlsCipher; } - void sentWriteCipherSpec() throws IOException { - if (pendingCompression == null || pendingCipher == null) { + void sentWriteCipherSpec() + throws IOException + { + if (pendingCompression == null || pendingCipher == null) + { throw new TlsFatalAlert(AlertDescription.handshake_failure); } this.writeCompression = this.pendingCompression; @@ -87,8 +99,11 @@ class RecordStream { this.writeSeqNo = 0; } - void receivedReadCipherSpec() throws IOException { - if (pendingCompression == null || pendingCipher == null) { + void receivedReadCipherSpec() + throws IOException + { + if (pendingCompression == null || pendingCipher == null) + { throw new TlsFatalAlert(AlertDescription.handshake_failure); } this.readCompression = this.pendingCompression; @@ -96,16 +111,21 @@ class RecordStream { this.readSeqNo = 0; } - void finaliseHandshake() throws IOException { + void finaliseHandshake() + throws IOException + { if (readCompression != pendingCompression || writeCompression != pendingCompression - || readCipher != pendingCipher || writeCipher != pendingCipher) { + || readCipher != pendingCipher || writeCipher != pendingCipher) + { throw new TlsFatalAlert(AlertDescription.handshake_failure); } pendingCompression = null; pendingCipher = null; } - public void readRecord() throws IOException { + public void readRecord() + throws IOException + { short type = TlsUtils.readUint8(input); @@ -116,16 +136,23 @@ class RecordStream { */ checkType(type, AlertDescription.unexpected_message); - if (!restrictReadVersion) { + if (!restrictReadVersion) + { int version = TlsUtils.readVersionRaw(input); - if ((version & 0xffffff00) != 0x0300) { + if ((version & 0xffffff00) != 0x0300) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } - } else { + } + else + { ProtocolVersion version = TlsUtils.readVersion(input); - if (readVersion == null) { + if (readVersion == null) + { readVersion = version; - } else if (!version.equals(readVersion)) { + } + else if (!version.equals(readVersion)) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } @@ -135,7 +162,9 @@ class RecordStream { handler.processRecord(type, plaintext, 0, plaintext.length); } - protected byte[] decodeAndVerify(short type, InputStream input, int len) throws IOException { + protected byte[] decodeAndVerify(short type, InputStream input, int len) + throws IOException + { checkLength(len, CIPHERTEXT_LIMIT, AlertDescription.record_overflow); @@ -149,7 +178,8 @@ class RecordStream { * ensuring that messages cannot cause internal buffer overflows. */ OutputStream cOut = readCompression.decompress(buffer); - if (cOut != buffer) { + if (cOut != buffer) + { cOut.write(decoded, 0, decoded.length); cOut.flush(); decoded = getBufferContents(); @@ -166,7 +196,8 @@ class RecordStream { } protected void writeRecord(short type, byte[] plaintext, int plaintextOffset, int plaintextLength) - throws IOException { + throws IOException + { /* * RFC 5264 6. Implementations MUST NOT send record types not defined in this document @@ -183,20 +214,25 @@ class RecordStream { * RFC 5264 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, * or ChangeCipherSpec content types. */ - if (plaintextLength < 1 && type != ContentType.application_data) { + if (plaintextLength < 1 && type != ContentType.application_data) + { throw new TlsFatalAlert(AlertDescription.internal_error); } - if (type == ContentType.handshake) { + if (type == ContentType.handshake) + { updateHandshakeData(plaintext, plaintextOffset, plaintextLength); } OutputStream cOut = writeCompression.compress(buffer); byte[] ciphertext; - if (cOut == buffer) { + if (cOut == buffer) + { ciphertext = writeCipher.encodePlaintext(writeSeqNo++, type, plaintext, plaintextOffset, plaintextLength); - } else { + } + else + { cOut.write(plaintext, plaintextOffset, plaintextLength); cOut.flush(); byte[] compressed = getBufferContents(); @@ -224,18 +260,22 @@ class RecordStream { output.flush(); } - void updateHandshakeData(byte[] message, int offset, int len) { + void updateHandshakeData(byte[] message, int offset, int len) + { hash.update(message, offset, len); } /** * 'sender' only relevant to SSLv3 */ - byte[] getCurrentHash(byte[] sender) { + byte[] getCurrentHash(byte[] sender) + { TlsHandshakeHash d = hash.fork(); - if (context.getServerVersion().isSSL()) { - if (sender != null) { + if (context.getServerVersion().isSSL()) + { + if (sender != null) + { d.update(sender, 0, sender.length); } } @@ -243,42 +283,58 @@ class RecordStream { return doFinal(d); } - protected void close() throws IOException { + protected void close() + throws IOException + { IOException e = null; - try { + try + { input.close(); - } catch (IOException ex) { + } + catch (IOException ex) + { e = ex; } - try { + try + { output.close(); - } catch (IOException ex) { + } + catch (IOException ex) + { e = ex; } - if (e != null) { + if (e != null) + { throw e; } } - protected void flush() throws IOException { + protected void flush() + throws IOException + { output.flush(); } - private byte[] getBufferContents() { + private byte[] getBufferContents() + { byte[] contents = buffer.toByteArray(); buffer.reset(); return contents; } - private static byte[] doFinal(Digest d) { + private static byte[] doFinal(Digest d) + { byte[] bs = new byte[d.getDigestSize()]; d.doFinal(bs, 0); return bs; } - private static void checkType(short type, short alertDescription) throws IOException { + private static void checkType(short type, short alertDescription) + throws IOException + { - switch (type) { + switch (type) + { case ContentType.change_cipher_spec: case ContentType.alert: case ContentType.handshake: @@ -289,8 +345,11 @@ class RecordStream { } } - private static void checkLength(int length, int limit, short alertDescription) throws IOException { - if (length > limit) { + private static void checkLength(int length, int limit, short alertDescription) + throws IOException + { + if (length > limit) + { throw new TlsFatalAlert(alertDescription); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/SRPTlsClient.java b/src/main/java/org/bouncycastle/crypto/tls/SRPTlsClient.java index e27a47d7..17ba2269 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/SRPTlsClient.java +++ b/src/main/java/org/bouncycastle/crypto/tls/SRPTlsClient.java @@ -7,35 +7,43 @@ import java.util.Hashtable; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; -public abstract class SRPTlsClient extends AbstractTlsClient { +public abstract class SRPTlsClient + extends AbstractTlsClient +{ public static final Integer EXT_SRP = Integers.valueOf(ExtensionType.srp); protected byte[] identity; protected byte[] password; - public SRPTlsClient(byte[] identity, byte[] password) { + public SRPTlsClient(byte[] identity, byte[] password) + { super(); this.identity = Arrays.clone(identity); this.password = Arrays.clone(password); } - public SRPTlsClient(TlsCipherFactory cipherFactory, byte[] identity, byte[] password) { + public SRPTlsClient(TlsCipherFactory cipherFactory, byte[] identity, byte[] password) + { super(cipherFactory); this.identity = Arrays.clone(identity); this.password = Arrays.clone(password); } - public int[] getCipherSuites() { - return new int[] { CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + public int[] getCipherSuites() + { + return new int[]{CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA, - CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, }; + CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,}; } - public Hashtable getClientExtensions() throws IOException { + public Hashtable getClientExtensions() + throws IOException + { Hashtable clientExtensions = super.getClientExtensions(); - if (clientExtensions == null) { + if (clientExtensions == null) + { clientExtensions = new Hashtable(); } @@ -46,19 +54,26 @@ public abstract class SRPTlsClient extends AbstractTlsClient { return clientExtensions; } - public void processServerExtensions(Hashtable serverExtensions) throws IOException { + public void processServerExtensions(Hashtable serverExtensions) + throws IOException + { // No explicit guidance in RFC 5054 here; we allow an optional empty extension from server - if (serverExtensions != null) { - byte[] extValue = (byte[]) serverExtensions.get(EXT_SRP); - if (extValue != null && extValue.length > 0) { + if (serverExtensions != null) + { + byte[] extValue = (byte[])serverExtensions.get(EXT_SRP); + if (extValue != null && extValue.length > 0) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } } - public TlsKeyExchange getKeyExchange() throws IOException { + public TlsKeyExchange getKeyExchange() + throws IOException + { - switch (selectedCipherSuite) { + switch (selectedCipherSuite) + { case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: @@ -84,9 +99,12 @@ public abstract class SRPTlsClient extends AbstractTlsClient { } } - public TlsCipher getCipher() throws IOException { + public TlsCipher getCipher() + throws IOException + { - switch (selectedCipherSuite) { + switch (selectedCipherSuite) + { case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: @@ -112,7 +130,8 @@ public abstract class SRPTlsClient extends AbstractTlsClient { } } - protected TlsKeyExchange createSRPKeyExchange(int keyExchange) { + protected TlsKeyExchange createSRPKeyExchange(int keyExchange) + { return new TlsSRPKeyExchange(keyExchange, supportedSignatureAlgorithms, identity, password); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/SRTPProtectionProfile.java b/src/main/java/org/bouncycastle/crypto/tls/SRTPProtectionProfile.java index 754f8e34..638608c0 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/SRTPProtectionProfile.java +++ b/src/main/java/org/bouncycastle/crypto/tls/SRTPProtectionProfile.java @@ -1,6 +1,7 @@ package org.bouncycastle.crypto.tls; -public class SRTPProtectionProfile { +public class SRTPProtectionProfile +{ /* * RFC 5764 4.1.2. */ diff --git a/src/main/java/org/bouncycastle/crypto/tls/SSL3Mac.java b/src/main/java/org/bouncycastle/crypto/tls/SSL3Mac.java index c4599852..0d2e2f19 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/SSL3Mac.java +++ b/src/main/java/org/bouncycastle/crypto/tls/SSL3Mac.java @@ -8,12 +8,13 @@ import org.bouncycastle.util.Arrays; /** * HMAC implementation based on original internet draft for HMAC (RFC 2104) - * + *

* The difference is that padding is concatenated versus XORed with the key - * + *

* H(K + opad, H(K + ipad, text)) */ -public class SSL3Mac implements Mac +public class SSL3Mac + implements Mac { private final static byte IPAD_BYTE = (byte)0x36; private final static byte OPAD_BYTE = (byte)0x5C; @@ -29,7 +30,7 @@ public class SSL3Mac implements Mac /** * Base constructor for one of the standard digest algorithms that the byteLength of * the algorithm is know for. Behaviour is undefined for digests other than MD5 or SHA1. - * + * * @param digest the digest. */ public SSL3Mac(Digest digest) diff --git a/src/main/java/org/bouncycastle/crypto/tls/SecurityParameters.java b/src/main/java/org/bouncycastle/crypto/tls/SecurityParameters.java index 84d47f05..0d8713ab 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/SecurityParameters.java +++ b/src/main/java/org/bouncycastle/crypto/tls/SecurityParameters.java @@ -1,6 +1,7 @@ package org.bouncycastle.crypto.tls; -public class SecurityParameters { +public class SecurityParameters +{ int entity = -1; int prfAlgorithm = -1; @@ -13,37 +14,44 @@ public class SecurityParameters { /** * @return {@link ConnectionEnd} */ - public int getEntity() { + public int getEntity() + { return entity; } /** * @return {@link PRFAlgorithm} */ - public int getPrfAlgorithm() { + public int getPrfAlgorithm() + { return prfAlgorithm; } /** * @return {@link CompressionMethod} */ - public short getCompressionAlgorithm() { + public short getCompressionAlgorithm() + { return compressionAlgorithm; } - public int getVerifyDataLength() { + public int getVerifyDataLength() + { return verifyDataLength; } - public byte[] getMasterSecret() { + public byte[] getMasterSecret() + { return masterSecret; } - public byte[] getClientRandom() { + public byte[] getClientRandom() + { return clientRandom; } - public byte[] getServerRandom() { + public byte[] getServerRandom() + { return serverRandom; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/ServerOnlyTlsAuthentication.java b/src/main/java/org/bouncycastle/crypto/tls/ServerOnlyTlsAuthentication.java index 62f74d60..73b858e5 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/ServerOnlyTlsAuthentication.java +++ b/src/main/java/org/bouncycastle/crypto/tls/ServerOnlyTlsAuthentication.java @@ -1,7 +1,10 @@ package org.bouncycastle.crypto.tls; -public abstract class ServerOnlyTlsAuthentication implements TlsAuthentication { - public final TlsCredentials getClientCredentials(CertificateRequest certificateRequest) { +public abstract class ServerOnlyTlsAuthentication + implements TlsAuthentication +{ + public final TlsCredentials getClientCredentials(CertificateRequest certificateRequest) + { return null; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/SignatureAlgorithm.java b/src/main/java/org/bouncycastle/crypto/tls/SignatureAlgorithm.java index 0a13649a..19659808 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/SignatureAlgorithm.java +++ b/src/main/java/org/bouncycastle/crypto/tls/SignatureAlgorithm.java @@ -1,9 +1,10 @@ package org.bouncycastle.crypto.tls; /** - * RFC 5246 7.4.1.4.1 (in RFC 2246, there were no specific values assigned) + * RFC 5246 7.4.1.4.1 (in RFC 2246, there were no specific values assigned) */ -public class SignatureAlgorithm { +public class SignatureAlgorithm +{ public static final short anonymous = 0; public static final short rsa = 1; diff --git a/src/main/java/org/bouncycastle/crypto/tls/SignatureAndHashAlgorithm.java b/src/main/java/org/bouncycastle/crypto/tls/SignatureAndHashAlgorithm.java index 12929f01..a0ce1207 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/SignatureAndHashAlgorithm.java +++ b/src/main/java/org/bouncycastle/crypto/tls/SignatureAndHashAlgorithm.java @@ -7,26 +7,29 @@ import java.io.OutputStream; /** * RFC 5246 7.4.1.4.1 */ -public class SignatureAndHashAlgorithm { +public class SignatureAndHashAlgorithm +{ private short hash; private short signature; /** - * @param hash - * {@link HashAlgorithm} - * @param signature - * {@link SignatureAlgorithm} + * @param hash {@link HashAlgorithm} + * @param signature {@link SignatureAlgorithm} */ - public SignatureAndHashAlgorithm(short hash, short signature) { + public SignatureAndHashAlgorithm(short hash, short signature) + { - if (!TlsUtils.isValidUint8(hash)) { + if (!TlsUtils.isValidUint8(hash)) + { throw new IllegalArgumentException("'hash' should be a uint8"); } - if (!TlsUtils.isValidUint8(signature)) { + if (!TlsUtils.isValidUint8(signature)) + { throw new IllegalArgumentException("'signature' should be a uint8"); } - if (signature == SignatureAlgorithm.anonymous) { + if (signature == SignatureAlgorithm.anonymous) + { throw new IllegalArgumentException("'signature' MUST NOT be \"anonymous\""); } @@ -37,50 +40,57 @@ public class SignatureAndHashAlgorithm { /** * @return {@link HashAlgorithm} */ - public short getHash() { + public short getHash() + { return hash; } /** * @return {@link SignatureAlgorithm} */ - public short getSignature() { + public short getSignature() + { return signature; } - public boolean equals(Object obj) { - if (!(obj instanceof SignatureAndHashAlgorithm)) { + public boolean equals(Object obj) + { + if (!(obj instanceof SignatureAndHashAlgorithm)) + { return false; } - SignatureAndHashAlgorithm other = (SignatureAndHashAlgorithm) obj; + SignatureAndHashAlgorithm other = (SignatureAndHashAlgorithm)obj; return other.getHash() == getHash() && other.getSignature() == getSignature(); } - public int hashCode() { + public int hashCode() + { return (getHash() << 8) | getSignature(); } /** * Encode this {@link SignatureAndHashAlgorithm} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. + * + * @param output the {@link OutputStream} to encode to. * @throws IOException */ - public void encode(OutputStream output) throws IOException { + public void encode(OutputStream output) + throws IOException + { TlsUtils.writeUint8(hash, output); TlsUtils.writeUint8(signature, output); } /** * Parse a {@link SignatureAndHashAlgorithm} from an {@link InputStream}. - * - * @param input - * the {@link InputStream} to parse from. + * + * @param input the {@link InputStream} to parse from. * @return a {@link SignatureAndHashAlgorithm} object. * @throws IOException */ - public static SignatureAndHashAlgorithm parse(InputStream input) throws IOException { + public static SignatureAndHashAlgorithm parse(InputStream input) + throws IOException + { short hash = TlsUtils.readUint8(input); short signature = TlsUtils.readUint8(input); return new SignatureAndHashAlgorithm(hash, signature); diff --git a/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataEntry.java b/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataEntry.java index 79c39749..b8d054b1 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataEntry.java +++ b/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataEntry.java @@ -1,20 +1,24 @@ package org.bouncycastle.crypto.tls; -public class SupplementalDataEntry { +public class SupplementalDataEntry +{ private int supp_data_type; private byte[] data; - public SupplementalDataEntry(int supp_data_type, byte[] data) { + public SupplementalDataEntry(int supp_data_type, byte[] data) + { this.supp_data_type = supp_data_type; this.data = data; } - public int getDataType() { + public int getDataType() + { return supp_data_type; } - public byte[] getData() { + public byte[] getData() + { return data; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataType.java b/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataType.java index 0101c7e1..dc8fcb0b 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataType.java +++ b/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataType.java @@ -3,7 +3,8 @@ package org.bouncycastle.crypto.tls; /** * RFC 4680 */ -public class SupplementalDataType { +public class SupplementalDataType +{ /* * RFC 4681 */ diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsAEADCipher.java b/src/main/java/org/bouncycastle/crypto/tls/TlsAEADCipher.java index 074ffb6b..823140f8 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsAEADCipher.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsAEADCipher.java @@ -1,13 +1,15 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -import java.util.Arrays; import org.bouncycastle.crypto.modes.AEADBlockCipher; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.util.Arrays; -public class TlsAEADCipher implements TlsCipher { +public class TlsAEADCipher + implements TlsCipher +{ protected TlsContext context; protected int macSize; @@ -19,9 +21,12 @@ public class TlsAEADCipher implements TlsCipher { protected byte[] encryptImplicitNonce, decryptImplicitNonce; public TlsAEADCipher(TlsContext context, AEADBlockCipher clientWriteCipher, AEADBlockCipher serverWriteCipher, - int cipherKeySize, int macSize) throws IOException { + int cipherKeySize, int macSize) + throws IOException + { - if (!ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(context.getServerVersion().getEquivalentTLSVersion())) { + if (!ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(context.getServerVersion().getEquivalentTLSVersion())) + { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -49,19 +54,23 @@ public class TlsAEADCipher implements TlsCipher { byte[] server_write_IV = Arrays.copyOfRange(key_block, offset, offset + fixed_iv_length); offset += fixed_iv_length; - if (offset != key_block_size) { + if (offset != key_block_size) + { throw new TlsFatalAlert(AlertDescription.internal_error); } KeyParameter encryptKey, decryptKey; - if (context.isServer()) { + if (context.isServer()) + { this.encryptCipher = serverWriteCipher; this.decryptCipher = clientWriteCipher; this.encryptImplicitNonce = server_write_IV; this.decryptImplicitNonce = client_write_IV; encryptKey = server_write_key; decryptKey = client_write_key; - } else { + } + else + { this.encryptCipher = clientWriteCipher; this.decryptCipher = serverWriteCipher; this.encryptImplicitNonce = client_write_IV; @@ -76,12 +85,15 @@ public class TlsAEADCipher implements TlsCipher { this.decryptCipher.init(false, new AEADParameters(decryptKey, 8 * macSize, dummyNonce)); } - public int getPlaintextLimit(int ciphertextLimit) { + public int getPlaintextLimit(int ciphertextLimit) + { // TODO We ought to be able to ask the decryptCipher (independently of it's current state!) return ciphertextLimit - macSize - nonce_explicit_length; } - public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) throws IOException { + public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) + throws IOException + { byte[] nonce = new byte[this.encryptImplicitNonce.length + nonce_explicit_length]; System.arraycopy(encryptImplicitNonce, 0, nonce, 0, encryptImplicitNonce.length); @@ -105,13 +117,17 @@ public class TlsAEADCipher implements TlsCipher { new AEADParameters(null, 8 * macSize, nonce, getAdditionalData(seqNo, type, plaintextLength))); outputPos += encryptCipher.processBytes(plaintext, plaintextOffset, plaintextLength, output, outputPos); - try { + try + { outputPos += encryptCipher.doFinal(output, outputPos); - } catch (Exception e) { + } + catch (Exception e) + { throw new TlsFatalAlert(AlertDescription.internal_error); } - if (outputPos != output.length) { + if (outputPos != output.length) + { // NOTE: Existing AEAD cipher implementations all give exact output lengths throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -119,9 +135,12 @@ public class TlsAEADCipher implements TlsCipher { return output; } - public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) throws IOException { + public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) + throws IOException + { - if (getPlaintextLimit(len) < 0) { + if (getPlaintextLimit(len) < 0) + { throw new TlsFatalAlert(AlertDescription.decode_error); } @@ -141,13 +160,17 @@ public class TlsAEADCipher implements TlsCipher { outputPos += decryptCipher.processBytes(ciphertext, ciphertextOffset, ciphertextLength, output, outputPos); - try { + try + { outputPos += decryptCipher.doFinal(output, outputPos); - } catch (Exception e) { + } + catch (Exception e) + { throw new TlsFatalAlert(AlertDescription.bad_record_mac); } - if (outputPos != output.length) { + if (outputPos != output.length) + { // NOTE: Existing AEAD cipher implementations all give exact output lengths throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -155,7 +178,9 @@ public class TlsAEADCipher implements TlsCipher { return output; } - protected byte[] getAdditionalData(long seqNo, short type, int len) throws IOException { + protected byte[] getAdditionalData(long seqNo, short type, int len) + throws IOException + { /* * additional_data = seq_num + TLSCompressed.type + TLSCompressed.version + * TLSCompressed.length diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsAgreementCredentials.java b/src/main/java/org/bouncycastle/crypto/tls/TlsAgreementCredentials.java index 1f283d18..d8fe239c 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsAgreementCredentials.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsAgreementCredentials.java @@ -4,7 +4,10 @@ import java.io.IOException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -public interface TlsAgreementCredentials extends TlsCredentials { +public interface TlsAgreementCredentials + extends TlsCredentials +{ - byte[] generateAgreement(AsymmetricKeyParameter peerPublicKey) throws IOException; + byte[] generateAgreement(AsymmetricKeyParameter peerPublicKey) + throws IOException; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsAuthentication.java b/src/main/java/org/bouncycastle/crypto/tls/TlsAuthentication.java index e2800096..62c2616e 100755 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsAuthentication.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsAuthentication.java @@ -7,18 +7,20 @@ public interface TlsAuthentication /** * Called by the protocol handler to report the server certificate * Note: this method is responsible for certificate verification and validation - * + * * @param serverCertificate the server certificate received * @throws IOException */ - void notifyServerCertificate(Certificate serverCertificate) throws IOException; + void notifyServerCertificate(Certificate serverCertificate) + throws IOException; /** * Return client credentials in response to server's certificate request - * + * * @param certificateRequest details of the certificate request * @return a TlsCredentials object or null for no client authentication * @throws IOException */ - TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException; + TlsCredentials getClientCredentials(CertificateRequest certificateRequest) + throws IOException; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsBlockCipher.java b/src/main/java/org/bouncycastle/crypto/tls/TlsBlockCipher.java index aba63156..1531a163 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsBlockCipher.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsBlockCipher.java @@ -13,7 +13,9 @@ import org.bouncycastle.util.Arrays; /** * A generic TLS 1.0-1.1 / SSLv3 block cipher. This can be used for AES or 3DES for example. */ -public class TlsBlockCipher implements TlsCipher { +public class TlsBlockCipher + implements TlsCipher +{ protected TlsContext context; protected byte[] randomData; @@ -25,16 +27,20 @@ public class TlsBlockCipher implements TlsCipher { protected TlsMac writeMac; protected TlsMac readMac; - public TlsMac getWriteMac() { + public TlsMac getWriteMac() + { return writeMac; } - public TlsMac getReadMac() { + public TlsMac getReadMac() + { return readMac; } public TlsBlockCipher(TlsContext context, BlockCipher clientWriteCipher, BlockCipher serverWriteCipher, - Digest clientWriteDigest, Digest serverWriteDigest, int cipherKeySize) throws IOException { + Digest clientWriteDigest, Digest serverWriteDigest, int cipherKeySize) + throws IOException + { this.context = context; @@ -48,7 +54,8 @@ public class TlsBlockCipher implements TlsCipher { + serverWriteDigest.getDigestSize(); // From TLS 1.1 onwards, block ciphers don't need client_write_IV - if (!useExplicitIV) { + if (!useExplicitIV) + { key_block_size += clientWriteCipher.getBlockSize() + serverWriteCipher.getBlockSize(); } @@ -69,29 +76,36 @@ public class TlsBlockCipher implements TlsCipher { offset += cipherKeySize; byte[] client_write_IV, server_write_IV; - if (useExplicitIV) { + if (useExplicitIV) + { client_write_IV = new byte[clientWriteCipher.getBlockSize()]; server_write_IV = new byte[serverWriteCipher.getBlockSize()]; - } else { + } + else + { client_write_IV = Arrays.copyOfRange(key_block, offset, offset + clientWriteCipher.getBlockSize()); offset += clientWriteCipher.getBlockSize(); server_write_IV = Arrays.copyOfRange(key_block, offset, offset + serverWriteCipher.getBlockSize()); offset += serverWriteCipher.getBlockSize(); } - if (offset != key_block_size) { + if (offset != key_block_size) + { throw new TlsFatalAlert(AlertDescription.internal_error); } CipherParameters encryptParams, decryptParams; - if (context.isServer()) { + if (context.isServer()) + { this.writeMac = serverWriteMac; this.readMac = clientWriteMac; this.encryptCipher = serverWriteCipher; this.decryptCipher = clientWriteCipher; encryptParams = new ParametersWithIV(server_write_key, server_write_IV); decryptParams = new ParametersWithIV(client_write_key, client_write_IV); - } else { + } + else + { this.writeMac = clientWriteMac; this.readMac = serverWriteMac; this.encryptCipher = clientWriteCipher; @@ -104,19 +118,22 @@ public class TlsBlockCipher implements TlsCipher { this.decryptCipher.init(false, decryptParams); } - public int getPlaintextLimit(int ciphertextLimit) { + public int getPlaintextLimit(int ciphertextLimit) + { int blockSize = encryptCipher.getBlockSize(); int macSize = writeMac.getSize(); int result = ciphertextLimit - (ciphertextLimit % blockSize) - macSize - 1; - if (useExplicitIV) { + if (useExplicitIV) + { result -= blockSize; } return result; } - public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) { + public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) + { int blockSize = encryptCipher.getBlockSize(); int macSize = writeMac.getSize(); @@ -125,7 +142,8 @@ public class TlsBlockCipher implements TlsCipher { int padding_length = blockSize - 1 - ((len + macSize) % blockSize); // TODO[DTLS] Consider supporting in DTLS (without exceeding send limit though) - if (!version.isDTLS() && !version.isSSL()) { + if (!version.isDTLS() && !version.isSSL()) + { // Add a random number of extra blocks worth of padding int maxExtraPadBlocks = (255 - padding_length) / blockSize; int actualExtraPadBlocks = chooseExtraPadBlocks(context.getSecureRandom(), maxExtraPadBlocks); @@ -133,14 +151,16 @@ public class TlsBlockCipher implements TlsCipher { } int totalSize = len + macSize + padding_length + 1; - if (useExplicitIV) { + if (useExplicitIV) + { totalSize += blockSize; } byte[] outbuf = new byte[totalSize]; int outOff = 0; - if (useExplicitIV) { + if (useExplicitIV) + { byte[] explicitIV = new byte[blockSize]; context.getSecureRandom().nextBytes(explicitIV); @@ -156,40 +176,49 @@ public class TlsBlockCipher implements TlsCipher { System.arraycopy(mac, 0, outbuf, outOff + len, mac.length); int padOffset = outOff + len + mac.length; - for (int i = 0; i <= padding_length; i++) { - outbuf[i + padOffset] = (byte) padding_length; + for (int i = 0; i <= padding_length; i++) + { + outbuf[i + padOffset] = (byte)padding_length; } - for (int i = outOff; i < totalSize; i += blockSize) { + for (int i = outOff; i < totalSize; i += blockSize) + { encryptCipher.processBlock(outbuf, i, outbuf, i); } return outbuf; } - public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) throws IOException { + public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) + throws IOException + { int blockSize = decryptCipher.getBlockSize(); int macSize = readMac.getSize(); int minLen = Math.max(blockSize, macSize + 1); - if (useExplicitIV) { + if (useExplicitIV) + { minLen += blockSize; } - if (len < minLen) { + if (len < minLen) + { throw new TlsFatalAlert(AlertDescription.decode_error); } - if (len % blockSize != 0) { + if (len % blockSize != 0) + { throw new TlsFatalAlert(AlertDescription.decryption_failed); } - if (useExplicitIV) { + if (useExplicitIV) + { decryptCipher.init(false, new ParametersWithIV(null, ciphertext, offset, blockSize)); offset += blockSize; len -= blockSize; } - for (int i = 0; i < len; i += blockSize) { + for (int i = 0; i < len; i += blockSize) + { decryptCipher.processBlock(ciphertext, offset + i, ciphertext, offset + i); } @@ -204,14 +233,16 @@ public class TlsBlockCipher implements TlsCipher { boolean badMac = !Arrays.constantTimeAreEqual(calculatedMac, decryptedMac); - if (badMac || totalPad == 0) { + if (badMac || totalPad == 0) + { throw new TlsFatalAlert(AlertDescription.bad_record_mac); } return Arrays.copyOfRange(ciphertext, offset, offset + macInputLen); } - protected int checkPaddingConstantTime(byte[] buf, int off, int len, int blockSize, int macSize) { + protected int checkPaddingConstantTime(byte[] buf, int off, int len, int blockSize, int macSize) + { int end = off + len; byte lastByte = buf[end - 1]; int padlen = lastByte & 0xff; @@ -220,17 +251,23 @@ public class TlsBlockCipher implements TlsCipher { int dummyIndex = 0; byte padDiff = 0; - if ((context.getServerVersion().isSSL() && totalPad > blockSize) || (macSize + totalPad > len)) { + if ((context.getServerVersion().isSSL() && totalPad > blockSize) || (macSize + totalPad > len)) + { totalPad = 0; - } else { + } + else + { int padPos = end - totalPad; - do { + do + { padDiff |= (buf[padPos++] ^ lastByte); - } while (padPos < end); + } + while (padPos < end); dummyIndex = totalPad; - if (padDiff != 0) { + if (padDiff != 0) + { totalPad = 0; } } @@ -238,7 +275,8 @@ public class TlsBlockCipher implements TlsCipher { // Run some extra dummy checks so the number of checks is always constant { byte[] dummyPad = randomData; - while (dummyIndex < 256) { + while (dummyIndex < 256) + { padDiff |= (dummyPad[dummyIndex++] ^ lastByte); } // Ensure the above loop is not eliminated @@ -248,7 +286,8 @@ public class TlsBlockCipher implements TlsCipher { return totalPad; } - protected int chooseExtraPadBlocks(SecureRandom r, int max) { + protected int chooseExtraPadBlocks(SecureRandom r, int max) + { // return r.nextInt(max + 1); int x = r.nextInt(); @@ -256,13 +295,16 @@ public class TlsBlockCipher implements TlsCipher { return Math.min(n, max); } - protected int lowestBitSet(int x) { - if (x == 0) { + protected int lowestBitSet(int x) + { + if (x == 0) + { return 32; } int n = 0; - while ((x & 1) == 0) { + while ((x & 1) == 0) + { ++n; x >>= 1; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsCipher.java b/src/main/java/org/bouncycastle/crypto/tls/TlsCipher.java index ebb99888..c7dcec96 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsCipher.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsCipher.java @@ -6,7 +6,9 @@ public interface TlsCipher { int getPlaintextLimit(int ciphertextLimit); - byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) throws IOException; + byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) + throws IOException; - byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) throws IOException; + byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) + throws IOException; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsCipherFactory.java b/src/main/java/org/bouncycastle/crypto/tls/TlsCipherFactory.java index 88f1d0bb..d401d814 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsCipherFactory.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsCipherFactory.java @@ -2,7 +2,8 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -public interface TlsCipherFactory { +public interface TlsCipherFactory +{ /** * See enumeration classes EncryptionAlgorithm, MACAlgorithm for appropriate argument values diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsClient.java b/src/main/java/org/bouncycastle/crypto/tls/TlsClient.java index 3e09592a..fddfe882 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsClient.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsClient.java @@ -4,7 +4,9 @@ import java.io.IOException; import java.util.Hashtable; import java.util.Vector; -public interface TlsClient extends TlsPeer { +public interface TlsClient + extends TlsPeer +{ void init(TlsClientContext context); @@ -17,9 +19,11 @@ public interface TlsClient extends TlsPeer { short[] getCompressionMethods(); // Hashtable is (Integer -> byte[]) - Hashtable getClientExtensions() throws IOException; + Hashtable getClientExtensions() + throws IOException; - void notifyServerVersion(ProtocolVersion selectedVersion) throws IOException; + void notifyServerVersion(ProtocolVersion selectedVersion) + throws IOException; void notifySessionID(byte[] sessionID); @@ -27,37 +31,46 @@ public interface TlsClient extends TlsPeer { void notifySelectedCompressionMethod(short selectedCompressionMethod); - void notifySecureRenegotiation(boolean secureNegotiation) throws IOException; + void notifySecureRenegotiation(boolean secureNegotiation) + throws IOException; // Hashtable is (Integer -> byte[]) - void processServerExtensions(Hashtable serverExtensions) throws IOException; + void processServerExtensions(Hashtable serverExtensions) + throws IOException; // Vector is (SupplementalDataEntry) - void processServerSupplementalData(Vector serverSupplementalData) throws IOException; + void processServerSupplementalData(Vector serverSupplementalData) + throws IOException; - TlsKeyExchange getKeyExchange() throws IOException; + TlsKeyExchange getKeyExchange() + throws IOException; - TlsAuthentication getAuthentication() throws IOException; + TlsAuthentication getAuthentication() + throws IOException; // Vector is (SupplementalDataEntry) - Vector getClientSupplementalData() throws IOException; + Vector getClientSupplementalData() + throws IOException; - TlsCompression getCompression() throws IOException; + TlsCompression getCompression() + throws IOException; - TlsCipher getCipher() throws IOException; + TlsCipher getCipher() + throws IOException; /** * RFC 5077 3.3. NewSessionTicket Handshake Message - *

+ *

* This method will be called (only) when a NewSessionTicket handshake message is received. The * ticket is opaque to the client and clients MUST NOT examine the ticket under the assumption * that it complies with e.g. RFC 5077 4. Recommended Ticket Construction. - * - * @param newSessionTicket - * The ticket. + * + * @param newSessionTicket The ticket. * @throws IOException */ - void notifyNewSessionTicket(NewSessionTicket newSessionTicket) throws IOException; + void notifyNewSessionTicket(NewSessionTicket newSessionTicket) + throws IOException; - void notifyHandshakeComplete() throws IOException; + void notifyHandshakeComplete() + throws IOException; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsClientContext.java b/src/main/java/org/bouncycastle/crypto/tls/TlsClientContext.java index d51b106c..db9f15b7 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsClientContext.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsClientContext.java @@ -1,4 +1,6 @@ package org.bouncycastle.crypto.tls; -public interface TlsClientContext extends TlsContext { +public interface TlsClientContext + extends TlsContext +{ } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsClientContextImpl.java b/src/main/java/org/bouncycastle/crypto/tls/TlsClientContextImpl.java index 011fb3ca..d91f7f8e 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsClientContextImpl.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsClientContextImpl.java @@ -2,13 +2,18 @@ package org.bouncycastle.crypto.tls; import java.security.SecureRandom; -class TlsClientContextImpl extends AbstractTlsContext implements TlsClientContext { +class TlsClientContextImpl + extends AbstractTlsContext + implements TlsClientContext +{ - TlsClientContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) { + TlsClientContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) + { super(secureRandom, securityParameters); } - public boolean isServer() { + public boolean isServer() + { return false; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsClientProtocol.java b/src/main/java/org/bouncycastle/crypto/tls/TlsClientProtocol.java index 6b48566e..60dc3317 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsClientProtocol.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsClientProtocol.java @@ -13,7 +13,9 @@ import java.util.Vector; import org.bouncycastle.crypto.prng.ThreadedSeedGenerator; import org.bouncycastle.util.Arrays; -public class TlsClientProtocol extends TlsProtocol { +public class TlsClientProtocol + extends TlsProtocol +{ protected TlsClient tlsClient = null; protected TlsClientContextImpl tlsClientContext = null; @@ -29,7 +31,8 @@ public class TlsClientProtocol extends TlsProtocol { protected TlsAuthentication authentication = null; protected CertificateRequest certificateRequest = null; - private static SecureRandom createSecureRandom() { + private static SecureRandom createSecureRandom() + { /* * We use our threaded seed generator to generate a good random seed. If the user has a * better random seed, he should use the constructor with a SecureRandom. @@ -45,26 +48,31 @@ public class TlsClientProtocol extends TlsProtocol { return random; } - public TlsClientProtocol(InputStream input, OutputStream output) { + public TlsClientProtocol(InputStream input, OutputStream output) + { this(input, output, createSecureRandom()); } - public TlsClientProtocol(InputStream input, OutputStream output, SecureRandom secureRandom) { + public TlsClientProtocol(InputStream input, OutputStream output, SecureRandom secureRandom) + { super(input, output, secureRandom); } /** * Initiates a TLS handshake in the role of client - * + * * @param tlsClient - * @throws IOException - * If handshake was not successful. + * @throws IOException If handshake was not successful. */ - public void connect(TlsClient tlsClient) throws IOException { - if (tlsClient == null) { + public void connect(TlsClient tlsClient) + throws IOException + { + if (tlsClient == null) + { throw new IllegalArgumentException("'tlsClient' cannot be null"); } - if (this.tlsClient != null) { + if (this.tlsClient != null) + { throw new IllegalStateException("connect can only be called once"); } @@ -86,19 +94,26 @@ public class TlsClientProtocol extends TlsProtocol { this.tlsClient.notifyHandshakeComplete(); } - protected AbstractTlsContext getContext() { + protected AbstractTlsContext getContext() + { return tlsClientContext; } - protected TlsPeer getPeer() { + protected TlsPeer getPeer() + { return tlsClient; } - protected void handleChangeCipherSpecMessage() throws IOException { + protected void handleChangeCipherSpecMessage() + throws IOException + { - switch (this.connection_state) { - case CS_CLIENT_FINISHED: { - if (this.expectSessionTicket) { + switch (this.connection_state) + { + case CS_CLIENT_FINISHED: + { + if (this.expectSessionTicket) + { /* * RFC 5077 3.3. This message MUST be sent if the server included a SessionTicket * extension in the ServerHello. @@ -115,17 +130,24 @@ public class TlsClientProtocol extends TlsProtocol { } } - protected void handleHandshakeMessage(short type, byte[] data) throws IOException { + protected void handleHandshakeMessage(short type, byte[] data) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(data); - switch (type) { - case HandshakeType.certificate: { - switch (this.connection_state) { - case CS_SERVER_HELLO: { + switch (type) + { + case HandshakeType.certificate: + { + switch (this.connection_state) + { + case CS_SERVER_HELLO: + { handleSupplementalData(null); // NB: Fall through to next case label } - case CS_SERVER_SUPPLEMENTAL_DATA: { + case CS_SERVER_SUPPLEMENTAL_DATA: + { // Parse the Certificate message and send to cipher suite Certificate serverCertificate = Certificate.parse(buf); @@ -147,7 +169,8 @@ public class TlsClientProtocol extends TlsProtocol { break; } case HandshakeType.finished: - switch (this.connection_state) { + switch (this.connection_state) + { case CS_SERVER_CHANGE_CIPHER_SPEC: processFinishedMessage(buf); this.connection_state = CS_SERVER_FINISHED; @@ -157,7 +180,8 @@ public class TlsClientProtocol extends TlsProtocol { } break; case HandshakeType.server_hello: - switch (this.connection_state) { + switch (this.connection_state) + { case CS_CLIENT_HELLO: receiveServerHelloMessage(buf); this.connection_state = CS_SERVER_HELLO; @@ -179,8 +203,10 @@ public class TlsClientProtocol extends TlsProtocol { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } break; - case HandshakeType.supplemental_data: { - switch (this.connection_state) { + case HandshakeType.supplemental_data: + { + switch (this.connection_state) + { case CS_SERVER_HELLO: handleSupplementalData(readSupplementalDataMessage(buf)); break; @@ -190,12 +216,15 @@ public class TlsClientProtocol extends TlsProtocol { break; } case HandshakeType.server_hello_done: - switch (this.connection_state) { - case CS_SERVER_HELLO: { + switch (this.connection_state) + { + case CS_SERVER_HELLO: + { handleSupplementalData(null); // NB: Fall through to next case label } - case CS_SERVER_SUPPLEMENTAL_DATA: { + case CS_SERVER_SUPPLEMENTAL_DATA: + { // There was no server certificate message; check it's OK this.keyExchange.skipServerCredentials(); @@ -218,18 +247,23 @@ public class TlsClientProtocol extends TlsProtocol { this.connection_state = CS_SERVER_HELLO_DONE; Vector clientSupplementalData = tlsClient.getClientSupplementalData(); - if (clientSupplementalData != null) { + if (clientSupplementalData != null) + { sendSupplementalDataMessage(clientSupplementalData); } this.connection_state = CS_CLIENT_SUPPLEMENTAL_DATA; TlsCredentials clientCreds = null; - if (certificateRequest == null) { + if (certificateRequest == null) + { this.keyExchange.skipClientCredentials(); - } else { + } + else + { clientCreds = this.authentication.getClientCredentials(certificateRequest); - if (clientCreds == null) { + if (clientCreds == null) + { this.keyExchange.skipClientCredentials(); /* @@ -239,7 +273,9 @@ public class TlsClientProtocol extends TlsProtocol { * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ sendCertificateMessage(Certificate.EMPTY_CHAIN); - } else { + } + else + { this.keyExchange.processClientCredentials(clientCreds); sendCertificateMessage(clientCreds.getCertificate()); @@ -263,12 +299,13 @@ public class TlsClientProtocol extends TlsProtocol { this.connection_state = CS_CLIENT_KEY_EXCHANGE; - if (clientCreds != null && clientCreds instanceof TlsSignerCredentials) { + if (clientCreds != null && clientCreds instanceof TlsSignerCredentials) + { /* * TODO RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm * prepended from TLS 1.2 */ - TlsSignerCredentials signerCreds = (TlsSignerCredentials) clientCreds; + TlsSignerCredentials signerCreds = (TlsSignerCredentials)clientCreds; byte[] md5andsha1 = recordStream.getCurrentHash(null); byte[] clientCertificateSignature = signerCreds.generateCertificateSignature(md5andsha1); sendCertificateVerifyMessage(clientCertificateSignature); @@ -286,13 +323,17 @@ public class TlsClientProtocol extends TlsProtocol { this.failWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } break; - case HandshakeType.server_key_exchange: { - switch (this.connection_state) { - case CS_SERVER_HELLO: { + case HandshakeType.server_key_exchange: + { + switch (this.connection_state) + { + case CS_SERVER_HELLO: + { handleSupplementalData(null); // NB: Fall through to next case label } - case CS_SERVER_SUPPLEMENTAL_DATA: { + case CS_SERVER_SUPPLEMENTAL_DATA: + { // There was no server certificate message; check it's OK this.keyExchange.skipServerCredentials(); @@ -314,8 +355,10 @@ public class TlsClientProtocol extends TlsProtocol { this.connection_state = CS_SERVER_KEY_EXCHANGE; break; } - case HandshakeType.certificate_request: { - switch (this.connection_state) { + case HandshakeType.certificate_request: + { + switch (this.connection_state) + { case CS_SERVER_CERTIFICATE: // There was no server key exchange message; check it's OK @@ -323,8 +366,10 @@ public class TlsClientProtocol extends TlsProtocol { // NB: Fall through to next case label - case CS_SERVER_KEY_EXCHANGE: { - if (this.authentication == null) { + case CS_SERVER_KEY_EXCHANGE: + { + if (this.authentication == null) + { /* * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server * to request client identification. @@ -347,10 +392,13 @@ public class TlsClientProtocol extends TlsProtocol { this.connection_state = CS_CERTIFICATE_REQUEST; break; } - case HandshakeType.session_ticket: { - switch (this.connection_state) { + case HandshakeType.session_ticket: + { + switch (this.connection_state) + { case CS_CLIENT_FINISHED: - if (!this.expectSessionTicket) { + if (!this.expectSessionTicket) + { /* * RFC 5077 3.3. This message MUST NOT be sent if the server did not include a * SessionTicket extension in the ServerHello. @@ -374,7 +422,8 @@ public class TlsClientProtocol extends TlsProtocol { * if it does not wish to renegotiate a session, or the client may, if it wishes, * respond with a no_renegotiation alert. */ - if (this.connection_state == CS_SERVER_FINISHED) { + if (this.connection_state == CS_SERVER_FINISHED) + { String message = "Renegotiation not supported"; raiseWarning(AlertDescription.no_renegotiation, message); } @@ -390,7 +439,9 @@ public class TlsClientProtocol extends TlsProtocol { } } - protected void handleSupplementalData(Vector serverSupplementalData) throws IOException { + protected void handleSupplementalData(Vector serverSupplementalData) + throws IOException + { this.tlsClient.processServerSupplementalData(serverSupplementalData); this.connection_state = CS_SERVER_SUPPLEMENTAL_DATA; @@ -399,7 +450,9 @@ public class TlsClientProtocol extends TlsProtocol { this.keyExchange.init(getContext()); } - protected void receiveNewSessionTicketMessage(ByteArrayInputStream buf) throws IOException { + protected void receiveNewSessionTicketMessage(ByteArrayInputStream buf) + throws IOException + { NewSessionTicket newSessionTicket = NewSessionTicket.parse(buf); @@ -408,20 +461,25 @@ public class TlsClientProtocol extends TlsProtocol { tlsClient.notifyNewSessionTicket(newSessionTicket); } - protected void receiveServerHelloMessage(ByteArrayInputStream buf) throws IOException { + protected void receiveServerHelloMessage(ByteArrayInputStream buf) + throws IOException + { ProtocolVersion server_version = TlsUtils.readVersion(buf); - if (server_version.isDTLS()) { + if (server_version.isDTLS()) + { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } // Check that this matches what the server is sending in the record layer - if (!server_version.equals(recordStream.getReadVersion())) { + if (!server_version.equals(recordStream.getReadVersion())) + { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } ProtocolVersion client_version = getContext().getClientVersion(); - if (!server_version.isEqualOrEarlierVersionOf(client_version)) { + if (!server_version.isEqualOrEarlierVersionOf(client_version)) + { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } @@ -435,7 +493,8 @@ public class TlsClientProtocol extends TlsProtocol { securityParameters.serverRandom = TlsUtils.readFully(32, buf); byte[] sessionID = TlsUtils.readOpaque8(buf); - if (sessionID.length > 32) { + if (sessionID.length > 32) + { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } @@ -448,7 +507,8 @@ public class TlsClientProtocol extends TlsProtocol { this.selectedCipherSuite = TlsUtils.readUint16(buf); if (!arrayContains(offeredCipherSuites, this.selectedCipherSuite) || this.selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL - || this.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { + || this.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) + { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } @@ -459,7 +519,8 @@ public class TlsClientProtocol extends TlsProtocol { * offered ones. */ short selectedCompressionMethod = TlsUtils.readUint8(buf); - if (!arrayContains(offeredCompressionMethods, selectedCompressionMethod)) { + if (!arrayContains(offeredCompressionMethods, selectedCompressionMethod)) + { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } @@ -490,10 +551,12 @@ public class TlsClientProtocol extends TlsProtocol { * However, see RFC 5746 exception below. We always include the SCSV, so an Extended Server * Hello is always allowed. */ - if (serverExtensions != null) { + if (serverExtensions != null) + { Enumeration e = serverExtensions.keys(); - while (e.hasMoreElements()) { - Integer extType = (Integer) e.nextElement(); + while (e.hasMoreElements()) + { + Integer extType = (Integer)e.nextElement(); /* * RFC 5746 3.6. Note that sending a "renegotiation_info" extension in response to a @@ -503,7 +566,8 @@ public class TlsClientProtocol extends TlsProtocol { * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. */ if (!extType.equals(EXT_RenegotiationInfo) - && (clientExtensions == null || clientExtensions.get(extType) == null)) { + && (clientExtensions == null || clientExtensions.get(extType) == null)) + { /* * RFC 5246 7.4.1.4 An extension type MUST NOT appear in the ServerHello unless * the same extension type appeared in the corresponding ClientHello. If a @@ -523,8 +587,9 @@ public class TlsClientProtocol extends TlsProtocol { * When a ServerHello is received, the client MUST check if it includes the * "renegotiation_info" extension: */ - byte[] renegExtValue = (byte[]) serverExtensions.get(EXT_RenegotiationInfo); - if (renegExtValue != null) { + byte[] renegExtValue = (byte[])serverExtensions.get(EXT_RenegotiationInfo); + if (renegExtValue != null) + { /* * If the extension is present, set the secure_renegotiation flag to TRUE. The * client MUST then verify that the length of the "renegotiated_connection" @@ -533,7 +598,8 @@ public class TlsClientProtocol extends TlsProtocol { */ this.secure_renegotiation = true; - if (!Arrays.constantTimeAreEqual(renegExtValue, createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) { + if (!Arrays.constantTimeAreEqual(renegExtValue, createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) + { this.failWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } } @@ -544,12 +610,15 @@ public class TlsClientProtocol extends TlsProtocol { tlsClient.notifySecureRenegotiation(this.secure_renegotiation); - if (clientExtensions != null) { + if (clientExtensions != null) + { tlsClient.processServerExtensions(serverExtensions); } } - protected void sendCertificateVerifyMessage(byte[] data) throws IOException { + protected void sendCertificateVerifyMessage(byte[] data) + throws IOException + { /* * Send signature of handshake messages so far to prove we are the owner of the cert See RFC * 2246 sections 4.7, 7.4.3 and 7.4.8 @@ -563,7 +632,9 @@ public class TlsClientProtocol extends TlsProtocol { safeWriteRecord(ContentType.handshake, message, 0, message.length); } - protected void sendClientHelloMessage() throws IOException { + protected void sendClientHelloMessage() + throws IOException + { recordStream.setWriteVersion(this.tlsClient.getClientHelloRecordLayerVersion()); @@ -574,7 +645,8 @@ public class TlsClientProtocol extends TlsProtocol { TlsUtils.writeUint24(0, buf); ProtocolVersion client_version = this.tlsClient.getClientVersion(); - if (client_version.isDTLS()) { + if (client_version.isDTLS()) + { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } @@ -604,7 +676,8 @@ public class TlsClientProtocol extends TlsProtocol { boolean noRenegExt = clientExtensions == null || clientExtensions.get(EXT_RenegotiationInfo) == null; int count = offeredCipherSuites.length; - if (noRenegExt) { + if (noRenegExt) + { // Note: 1 extra slot for TLS_EMPTY_RENEGOTIATION_INFO_SCSV ++count; } @@ -612,7 +685,8 @@ public class TlsClientProtocol extends TlsProtocol { TlsUtils.writeUint16(2 * count, buf); TlsUtils.writeUint16Array(offeredCipherSuites, buf); - if (noRenegExt) { + if (noRenegExt) + { TlsUtils.writeUint16(CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV, buf); } } @@ -620,11 +694,12 @@ public class TlsClientProtocol extends TlsProtocol { // Compression methods this.offeredCompressionMethods = this.tlsClient.getCompressionMethods(); - TlsUtils.writeUint8((short) offeredCompressionMethods.length, buf); + TlsUtils.writeUint8((short)offeredCompressionMethods.length, buf); TlsUtils.writeUint8Array(offeredCompressionMethods, buf); // Extensions - if (clientExtensions != null) { + if (clientExtensions != null) + { writeExtensions(buf, clientExtensions); } @@ -636,7 +711,9 @@ public class TlsClientProtocol extends TlsProtocol { safeWriteRecord(ContentType.handshake, message, 0, message.length); } - protected void sendClientKeyExchangeMessage() throws IOException { + protected void sendClientKeyExchangeMessage() + throws IOException + { ByteArrayOutputStream bos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.client_key_exchange, bos); diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsContext.java b/src/main/java/org/bouncycastle/crypto/tls/TlsContext.java index 97660098..e8c940c7 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsContext.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsContext.java @@ -2,7 +2,8 @@ package org.bouncycastle.crypto.tls; import java.security.SecureRandom; -public interface TlsContext { +public interface TlsContext +{ SecureRandom getSecureRandom(); @@ -20,14 +21,11 @@ public interface TlsContext { /** * Export keying material according to RFC 5705: "Keying Material Exporters for TLS". - * - * @param asciiLabel - * indicates which application will use the exported keys. - * @param context_value - * allows the application using the exporter to mix its own data with the TLS PRF for - * the exporter output. - * @param length - * the number of bytes to generate + * + * @param asciiLabel indicates which application will use the exported keys. + * @param context_value allows the application using the exporter to mix its own data with the TLS PRF for + * the exporter output. + * @param length the number of bytes to generate * @return a pseudorandom bit string of 'length' bytes generated from the master_secret. */ byte[] exportKeyingMaterial(String asciiLabel, byte[] context_value, int length); diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsDHEKeyExchange.java b/src/main/java/org/bouncycastle/crypto/tls/TlsDHEKeyExchange.java index 825b5375..8c4795fe 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsDHEKeyExchange.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsDHEKeyExchange.java @@ -15,28 +15,37 @@ import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; -public class TlsDHEKeyExchange extends TlsDHKeyExchange { +public class TlsDHEKeyExchange + extends TlsDHKeyExchange +{ protected TlsSignerCredentials serverCredentials = null; - public TlsDHEKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, DHParameters dhParameters) { + public TlsDHEKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, DHParameters dhParameters) + { super(keyExchange, supportedSignatureAlgorithms, dhParameters); } - public void processServerCredentials(TlsCredentials serverCredentials) throws IOException { + public void processServerCredentials(TlsCredentials serverCredentials) + throws IOException + { - if (!(serverCredentials instanceof TlsSignerCredentials)) { + if (!(serverCredentials instanceof TlsSignerCredentials)) + { throw new TlsFatalAlert(AlertDescription.internal_error); } processServerCertificate(serverCredentials.getCertificate()); - this.serverCredentials = (TlsSignerCredentials) serverCredentials; + this.serverCredentials = (TlsSignerCredentials)serverCredentials; } - public byte[] generateServerKeyExchange() throws IOException { + public byte[] generateServerKeyExchange() + throws IOException + { - if (this.dhParameters == null) { + if (this.dhParameters == null) + { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -46,7 +55,7 @@ public class TlsDHEKeyExchange extends TlsDHKeyExchange { kpg.init(new DHKeyGenerationParameters(context.getSecureRandom(), this.dhParameters)); AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); - BigInteger Ys = ((DHPublicKeyParameters) kp.getPublic()).getY(); + BigInteger Ys = ((DHPublicKeyParameters)kp.getPublic()).getY(); TlsDHUtils.writeDHParameter(dhParameters.getP(), buf); TlsDHUtils.writeDHParameter(dhParameters.getG(), buf); @@ -72,7 +81,9 @@ public class TlsDHEKeyExchange extends TlsDHKeyExchange { return buf.toByteArray(); } - public void processServerKeyExchange(InputStream input) throws IOException { + public void processServerKeyExchange(InputStream input) + throws IOException + { SecurityParameters securityParameters = context.getSecurityParameters(); @@ -84,14 +95,16 @@ public class TlsDHEKeyExchange extends TlsDHKeyExchange { BigInteger Ys = TlsDHUtils.readDHParameter(sigIn); byte[] sigBytes = TlsUtils.readOpaque16(input); - if (!signer.verifySignature(sigBytes)) { + if (!signer.verifySignature(sigBytes)) + { throw new TlsFatalAlert(AlertDescription.decrypt_error); } this.dhAgreeServerPublicKey = validateDHPublicKey(new DHPublicKeyParameters(Ys, new DHParameters(p, g))); } - protected Signer initVerifyer(TlsSigner tlsSigner, SecurityParameters securityParameters) { + protected Signer initVerifyer(TlsSigner tlsSigner, SecurityParameters securityParameters) + { Signer signer = tlsSigner.createVerifyer(this.serverPublicKey); signer.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); signer.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsDHKeyExchange.java b/src/main/java/org/bouncycastle/crypto/tls/TlsDHKeyExchange.java index 810f1b52..0f59909f 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsDHKeyExchange.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsDHKeyExchange.java @@ -17,7 +17,9 @@ import org.bouncycastle.crypto.util.PublicKeyFactory; /** * TLS 1.0/1.1 DH key exchange. */ -public class TlsDHKeyExchange extends AbstractTlsKeyExchange { +public class TlsDHKeyExchange + extends AbstractTlsKeyExchange +{ protected static final BigInteger ONE = BigInteger.valueOf(1); protected static final BigInteger TWO = BigInteger.valueOf(2); @@ -32,11 +34,13 @@ public class TlsDHKeyExchange extends AbstractTlsKeyExchange { protected DHPublicKeyParameters dhAgreeClientPublicKey; - public TlsDHKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, DHParameters dhParameters) { + public TlsDHKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, DHParameters dhParameters) + { super(keyExchange, supportedSignatureAlgorithms); - switch (keyExchange) { + switch (keyExchange) + { case KeyExchangeAlgorithm.DH_RSA: case KeyExchangeAlgorithm.DH_DSS: this.tlsSigner = null; @@ -54,43 +58,60 @@ public class TlsDHKeyExchange extends AbstractTlsKeyExchange { this.dhParameters = dhParameters; } - public void init(TlsContext context) { + public void init(TlsContext context) + { super.init(context); - if (this.tlsSigner != null) { + if (this.tlsSigner != null) + { this.tlsSigner.init(context); } } - public void skipServerCredentials() throws IOException { + public void skipServerCredentials() + throws IOException + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } - public void processServerCertificate(Certificate serverCertificate) throws IOException { + public void processServerCertificate(Certificate serverCertificate) + throws IOException + { - if (serverCertificate.isEmpty()) { + if (serverCertificate.isEmpty()) + { throw new TlsFatalAlert(AlertDescription.bad_certificate); } org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - try { + try + { this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); - } catch (RuntimeException e) { + } + catch (RuntimeException e) + { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } - if (tlsSigner == null) { - try { - this.dhAgreeServerPublicKey = validateDHPublicKey((DHPublicKeyParameters) this.serverPublicKey); - } catch (ClassCastException e) { + if (tlsSigner == null) + { + try + { + this.dhAgreeServerPublicKey = validateDHPublicKey((DHPublicKeyParameters)this.serverPublicKey); + } + catch (ClassCastException e) + { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyAgreement); - } else { - if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) { + } + else + { + if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) + { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } @@ -100,8 +121,10 @@ public class TlsDHKeyExchange extends AbstractTlsKeyExchange { super.processServerCertificate(serverCertificate); } - public boolean requiresServerKeyExchange() { - switch (keyExchange) { + public boolean requiresServerKeyExchange() + { + switch (keyExchange) + { case KeyExchangeAlgorithm.DHE_DSS: case KeyExchangeAlgorithm.DHE_RSA: case KeyExchangeAlgorithm.DH_anon: @@ -111,10 +134,14 @@ public class TlsDHKeyExchange extends AbstractTlsKeyExchange { } } - public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { + public void validateCertificateRequest(CertificateRequest certificateRequest) + throws IOException + { short[] types = certificateRequest.getCertificateTypes(); - for (int i = 0; i < types.length; ++i) { - switch (types[i]) { + for (int i = 0; i < types.length; ++i) + { + switch (types[i]) + { case ClientCertificateType.rsa_sign: case ClientCertificateType.dss_sign: case ClientCertificateType.rsa_fixed_dh: @@ -127,51 +154,69 @@ public class TlsDHKeyExchange extends AbstractTlsKeyExchange { } } - public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { - if (clientCredentials instanceof TlsAgreementCredentials) { + public void processClientCredentials(TlsCredentials clientCredentials) + throws IOException + { + if (clientCredentials instanceof TlsAgreementCredentials) + { // TODO Validate client cert has matching parameters (see 'areCompatibleParameters')? - this.agreementCredentials = (TlsAgreementCredentials) clientCredentials; - } else if (clientCredentials instanceof TlsSignerCredentials) { + this.agreementCredentials = (TlsAgreementCredentials)clientCredentials; + } + else if (clientCredentials instanceof TlsSignerCredentials) + { // OK - } else { + } + else + { throw new TlsFatalAlert(AlertDescription.internal_error); } } - public void generateClientKeyExchange(OutputStream output) throws IOException { + public void generateClientKeyExchange(OutputStream output) + throws IOException + { /* * RFC 2246 7.4.7.2 If the client certificate already contains a suitable Diffie-Hellman * key, then Yc is implicit and does not need to be sent again. In this case, the Client Key * Exchange message will be sent, but will be empty. */ - if (agreementCredentials == null) { + if (agreementCredentials == null) + { this.dhAgreeClientPrivateKey = TlsDHUtils.generateEphemeralClientKeyExchange(context.getSecureRandom(), dhAgreeServerPublicKey.getParameters(), output); } } - public byte[] generatePremasterSecret() throws IOException { - if (agreementCredentials != null) { + public byte[] generatePremasterSecret() + throws IOException + { + if (agreementCredentials != null) + { return agreementCredentials.generateAgreement(dhAgreeServerPublicKey); } return calculateDHBasicAgreement(dhAgreeServerPublicKey, dhAgreeClientPrivateKey); } - protected boolean areCompatibleParameters(DHParameters a, DHParameters b) { + protected boolean areCompatibleParameters(DHParameters a, DHParameters b) + { return a.getP().equals(b.getP()) && a.getG().equals(b.getG()); } - protected byte[] calculateDHBasicAgreement(DHPublicKeyParameters publicKey, DHPrivateKeyParameters privateKey) { + protected byte[] calculateDHBasicAgreement(DHPublicKeyParameters publicKey, DHPrivateKeyParameters privateKey) + { return TlsDHUtils.calculateDHBasicAgreement(publicKey, privateKey); } - protected AsymmetricCipherKeyPair generateDHKeyPair(DHParameters dhParams) { + protected AsymmetricCipherKeyPair generateDHKeyPair(DHParameters dhParams) + { return TlsDHUtils.generateDHKeyPair(context.getSecureRandom(), dhParams); } - protected DHPublicKeyParameters validateDHPublicKey(DHPublicKeyParameters key) throws IOException { + protected DHPublicKeyParameters validateDHPublicKey(DHPublicKeyParameters key) + throws IOException + { return TlsDHUtils.validateDHPublicKey(key); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsDHUtils.java b/src/main/java/org/bouncycastle/crypto/tls/TlsDHUtils.java index ccb4542c..bc9954e0 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsDHUtils.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsDHUtils.java @@ -15,13 +15,15 @@ import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.util.BigIntegers; -public class TlsDHUtils { +public class TlsDHUtils +{ static final BigInteger ONE = BigInteger.valueOf(1); static final BigInteger TWO = BigInteger.valueOf(2); public static byte[] calculateDHBasicAgreement(DHPublicKeyParameters publicKey, - DHPrivateKeyParameters privateKey) { + DHPrivateKeyParameters privateKey) + { DHBasicAgreement basicAgreement = new DHBasicAgreement(); basicAgreement.init(privateKey); @@ -35,20 +37,23 @@ public class TlsDHUtils { } public static AsymmetricCipherKeyPair generateDHKeyPair(SecureRandom random, - DHParameters dhParams) { + DHParameters dhParams) + { DHBasicKeyPairGenerator dhGen = new DHBasicKeyPairGenerator(); dhGen.init(new DHKeyGenerationParameters(random, dhParams)); return dhGen.generateKeyPair(); } public static DHPrivateKeyParameters generateEphemeralClientKeyExchange(SecureRandom random, - DHParameters dhParams, OutputStream output) throws IOException { + DHParameters dhParams, OutputStream output) + throws IOException + { AsymmetricCipherKeyPair dhAgreeClientKeyPair = generateDHKeyPair(random, dhParams); - DHPrivateKeyParameters dhAgreeClientPrivateKey = (DHPrivateKeyParameters) dhAgreeClientKeyPair + DHPrivateKeyParameters dhAgreeClientPrivateKey = (DHPrivateKeyParameters)dhAgreeClientKeyPair .getPrivate(); - BigInteger Yc = ((DHPublicKeyParameters) dhAgreeClientKeyPair.getPublic()).getY(); + BigInteger Yc = ((DHPublicKeyParameters)dhAgreeClientKeyPair.getPublic()).getY(); byte[] keData = BigIntegers.asUnsignedByteArray(Yc); TlsUtils.writeOpaque16(keData, output); @@ -56,19 +61,23 @@ public class TlsDHUtils { } public static DHPublicKeyParameters validateDHPublicKey(DHPublicKeyParameters key) - throws IOException { + throws IOException + { BigInteger Y = key.getY(); DHParameters params = key.getParameters(); BigInteger p = params.getP(); BigInteger g = params.getG(); - if (!p.isProbablePrime(2)) { + if (!p.isProbablePrime(2)) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } - if (g.compareTo(TWO) < 0 || g.compareTo(p.subtract(TWO)) > 0) { + if (g.compareTo(TWO) < 0 || g.compareTo(p.subtract(TWO)) > 0) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } - if (Y.compareTo(TWO) < 0 || Y.compareTo(p.subtract(ONE)) > 0) { + if (Y.compareTo(TWO) < 0 || Y.compareTo(p.subtract(ONE)) > 0) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } @@ -77,11 +86,15 @@ public class TlsDHUtils { return key; } - public static BigInteger readDHParameter(InputStream input) throws IOException { + public static BigInteger readDHParameter(InputStream input) + throws IOException + { return new BigInteger(1, TlsUtils.readOpaque16(input)); } - public static void writeDHParameter(BigInteger x, OutputStream output) throws IOException { + public static void writeDHParameter(BigInteger x, OutputStream output) + throws IOException + { TlsUtils.writeOpaque16(BigIntegers.asUnsignedByteArray(x), output); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsDSASigner.java b/src/main/java/org/bouncycastle/crypto/tls/TlsDSASigner.java index ea5a8572..b0e89572 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsDSASigner.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsDSASigner.java @@ -11,9 +11,13 @@ import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.DSADigestSigner; -public abstract class TlsDSASigner extends AbstractTlsSigner { +public abstract class TlsDSASigner + extends AbstractTlsSigner +{ - public byte[] generateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) throws CryptoException { + public byte[] generateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) + throws CryptoException + { // Note: Only use the SHA1 part of the hash Signer signer = makeSigner(new NullDigest(), true, @@ -23,7 +27,8 @@ public abstract class TlsDSASigner extends AbstractTlsSigner { } public boolean verifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1) - throws CryptoException { + throws CryptoException + { // Note: Only use the SHA1 part of the hash Signer signer = makeSigner(new NullDigest(), false, publicKey); @@ -31,15 +36,18 @@ public abstract class TlsDSASigner extends AbstractTlsSigner { return signer.verifySignature(sigBytes); } - public Signer createSigner(AsymmetricKeyParameter privateKey) { + public Signer createSigner(AsymmetricKeyParameter privateKey) + { return makeSigner(new SHA1Digest(), true, new ParametersWithRandom(privateKey, this.context.getSecureRandom())); } - public Signer createVerifyer(AsymmetricKeyParameter publicKey) { + public Signer createVerifyer(AsymmetricKeyParameter publicKey) + { return makeSigner(new SHA1Digest(), false, publicKey); } - protected Signer makeSigner(Digest d, boolean forSigning, CipherParameters cp) { + protected Signer makeSigner(Digest d, boolean forSigning, CipherParameters cp) + { Signer s = new DSADigestSigner(createDSAImpl(), d); s.init(forSigning, cp); return s; diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsDSSSigner.java b/src/main/java/org/bouncycastle/crypto/tls/TlsDSSSigner.java index e4b9012b..e0eeca98 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsDSSSigner.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsDSSSigner.java @@ -5,13 +5,17 @@ import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.signers.DSASigner; -public class TlsDSSSigner extends TlsDSASigner { +public class TlsDSSSigner + extends TlsDSASigner +{ - public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) { + public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) + { return publicKey instanceof DSAPublicKeyParameters; } - protected DSA createDSAImpl() { + protected DSA createDSAImpl() + { return new DSASigner(); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java b/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java index 25b273bd..9cf17f41 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java @@ -23,54 +23,69 @@ import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.Integers; -public class TlsECCUtils { +public class TlsECCUtils +{ public static final Integer EXT_elliptic_curves = Integers.valueOf(ExtensionType.elliptic_curves); public static final Integer EXT_ec_point_formats = Integers.valueOf(ExtensionType.ec_point_formats); - private static final String[] curveNames = new String[] { "sect163k1", "sect163r1", "sect163r2", "sect193r1", + private static final String[] curveNames = new String[]{"sect163k1", "sect163r1", "sect163r2", "sect193r1", "sect193r2", "sect233k1", "sect233r1", "sect239k1", "sect283k1", "sect283r1", "sect409k1", "sect409r1", "sect571k1", "sect571r1", "secp160k1", "secp160r1", "secp160r2", "secp192k1", "secp192r1", "secp224k1", - "secp224r1", "secp256k1", "secp256r1", "secp384r1", "secp521r1", }; + "secp224r1", "secp256k1", "secp256r1", "secp384r1", "secp521r1",}; - public static void addSupportedEllipticCurvesExtension(Hashtable extensions, int[] namedCurves) throws IOException { + public static void addSupportedEllipticCurvesExtension(Hashtable extensions, int[] namedCurves) + throws IOException + { extensions.put(EXT_elliptic_curves, createSupportedEllipticCurvesExtension(namedCurves)); } public static void addSupportedPointFormatsExtension(Hashtable extensions, short[] ecPointFormats) - throws IOException { + throws IOException + { extensions.put(EXT_ec_point_formats, createSupportedPointFormatsExtension(ecPointFormats)); } - public static int[] getSupportedEllipticCurvesExtension(Hashtable extensions) throws IOException { + public static int[] getSupportedEllipticCurvesExtension(Hashtable extensions) + throws IOException + { - if (extensions == null) { + if (extensions == null) + { return null; } - byte[] extensionValue = (byte[]) extensions.get(EXT_elliptic_curves); - if (extensionValue == null) { + byte[] extensionValue = (byte[])extensions.get(EXT_elliptic_curves); + if (extensionValue == null) + { return null; } return readSupportedEllipticCurvesExtension(extensionValue); } - public static short[] getSupportedPointFormatsExtension(Hashtable extensions) throws IOException { + public static short[] getSupportedPointFormatsExtension(Hashtable extensions) + throws IOException + { - if (extensions == null) { + if (extensions == null) + { return null; } - byte[] extensionValue = (byte[]) extensions.get(EXT_ec_point_formats); - if (extensionValue == null) { + byte[] extensionValue = (byte[])extensions.get(EXT_ec_point_formats); + if (extensionValue == null) + { return null; } return readSupportedPointFormatsExtension(extensionValue); } - public static byte[] createSupportedEllipticCurvesExtension(int[] namedCurves) throws IOException { + public static byte[] createSupportedEllipticCurvesExtension(int[] namedCurves) + throws IOException + { - if (namedCurves == null || namedCurves.length < 1) { + if (namedCurves == null || namedCurves.length < 1) + { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -80,11 +95,16 @@ public class TlsECCUtils { return buf.toByteArray(); } - public static byte[] createSupportedPointFormatsExtension(short[] ecPointFormats) throws IOException { + public static byte[] createSupportedPointFormatsExtension(short[] ecPointFormats) + throws IOException + { - if (ecPointFormats == null) { - ecPointFormats = new short[] { ECPointFormat.uncompressed }; - } else if (!TlsProtocol.arrayContains(ecPointFormats, ECPointFormat.uncompressed)) { + if (ecPointFormats == null) + { + ecPointFormats = new short[]{ECPointFormat.uncompressed}; + } + else if (!TlsProtocol.arrayContains(ecPointFormats, ECPointFormat.uncompressed)) + { /* * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST * contain the value 0 (uncompressed) as one of the items in the list of point formats. @@ -99,21 +119,25 @@ public class TlsECCUtils { } ByteArrayOutputStream buf = new ByteArrayOutputStream(); - TlsUtils.writeUint8((short) ecPointFormats.length, buf); + TlsUtils.writeUint8((short)ecPointFormats.length, buf); TlsUtils.writeUint8Array(ecPointFormats, buf); return buf.toByteArray(); } - public static int[] readSupportedEllipticCurvesExtension(byte[] extensionValue) throws IOException { + public static int[] readSupportedEllipticCurvesExtension(byte[] extensionValue) + throws IOException + { - if (extensionValue == null) { + if (extensionValue == null) + { throw new IllegalArgumentException("'extensionValue' cannot be null"); } ByteArrayInputStream buf = new ByteArrayInputStream(extensionValue); int length = TlsUtils.readUint16(buf); - if (length < 2 || (length & 1) != 0) { + if (length < 2 || (length & 1) != 0) + { throw new TlsFatalAlert(AlertDescription.decode_error); } @@ -124,16 +148,20 @@ public class TlsECCUtils { return namedCurves; } - public static short[] readSupportedPointFormatsExtension(byte[] extensionValue) throws IOException { + public static short[] readSupportedPointFormatsExtension(byte[] extensionValue) + throws IOException + { - if (extensionValue == null) { + if (extensionValue == null) + { throw new IllegalArgumentException("'extensionValue' cannot be null"); } ByteArrayInputStream buf = new ByteArrayInputStream(extensionValue); short length = TlsUtils.readUint8(buf); - if (length < 1) { + if (length < 1) + { throw new TlsFatalAlert(AlertDescription.decode_error); } @@ -141,7 +169,8 @@ public class TlsECCUtils { TlsProtocol.assertEmpty(buf); - if (!TlsProtocol.arrayContains(ecPointFormats, ECPointFormat.uncompressed)) { + if (!TlsProtocol.arrayContains(ecPointFormats, ECPointFormat.uncompressed)) + { /* * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST * contain the value 0 (uncompressed) as one of the items in the list of point formats. @@ -152,20 +181,24 @@ public class TlsECCUtils { return ecPointFormats; } - public static String getNameOfNamedCurve(int namedCurve) { + public static String getNameOfNamedCurve(int namedCurve) + { return isSupportedNamedCurve(namedCurve) ? curveNames[namedCurve - 1] : null; } - public static ECDomainParameters getParametersForNamedCurve(int namedCurve) { + public static ECDomainParameters getParametersForNamedCurve(int namedCurve) + { String curveName = getNameOfNamedCurve(namedCurve); - if (curveName == null) { + if (curveName == null) + { return null; } // Lazily created the first time a particular curve is accessed X9ECParameters ecP = SECNamedCurves.getByName(curveName); - if (ecP == null) { + if (ecP == null) + { return null; } @@ -173,21 +206,27 @@ public class TlsECCUtils { return new ECDomainParameters(ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); } - public static boolean hasAnySupportedNamedCurves() { + public static boolean hasAnySupportedNamedCurves() + { return curveNames.length > 0; } - public static boolean containsECCCipherSuites(int[] cipherSuites) { - for (int i = 0; i < cipherSuites.length; ++i) { - if (isECCCipherSuite(cipherSuites[i])) { + public static boolean containsECCCipherSuites(int[] cipherSuites) + { + for (int i = 0; i < cipherSuites.length; ++i) + { + if (isECCCipherSuite(cipherSuites[i])) + { return true; } } return false; } - public static boolean isECCCipherSuite(int cipherSuite) { - switch (cipherSuite) { + public static boolean isECCCipherSuite(int cipherSuite) + { + switch (cipherSuite) + { case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: @@ -235,38 +274,49 @@ public class TlsECCUtils { } } - public static boolean areOnSameCurve(ECDomainParameters a, ECDomainParameters b) { + public static boolean areOnSameCurve(ECDomainParameters a, ECDomainParameters b) + { // TODO Move to ECDomainParameters.equals() or other utility method? return a.getCurve().equals(b.getCurve()) && a.getG().equals(b.getG()) && a.getN().equals(b.getN()) && a.getH().equals(b.getH()); } - public static boolean isSupportedNamedCurve(int namedCurve) { + public static boolean isSupportedNamedCurve(int namedCurve) + { return (namedCurve > 0 && namedCurve <= curveNames.length); } - public static boolean isCompressionPreferred(short[] ecPointFormats, short compressionFormat) { - if (ecPointFormats == null) { + public static boolean isCompressionPreferred(short[] ecPointFormats, short compressionFormat) + { + if (ecPointFormats == null) + { return false; } - for (int i = 0; i < ecPointFormats.length; ++i) { + for (int i = 0; i < ecPointFormats.length; ++i) + { short ecPointFormat = ecPointFormats[i]; - if (ecPointFormat == ECPointFormat.uncompressed) { + if (ecPointFormat == ECPointFormat.uncompressed) + { return false; } - if (ecPointFormat == compressionFormat) { + if (ecPointFormat == compressionFormat) + { return true; } } return false; } - public static byte[] serializeECFieldElement(int fieldSize, BigInteger x) throws IOException { + public static byte[] serializeECFieldElement(int fieldSize, BigInteger x) + throws IOException + { int requiredLength = (fieldSize + 7) / 8; return BigIntegers.asUnsignedByteArray(requiredLength, x); } - public static byte[] serializeECPoint(short[] ecPointFormats, ECPoint point) throws IOException { + public static byte[] serializeECPoint(short[] ecPointFormats, ECPoint point) + throws IOException + { ECCurve curve = point.getCurve(); @@ -277,29 +327,38 @@ public class TlsECCUtils { * used. */ boolean compressed = false; - if (curve instanceof ECCurve.F2m) { + if (curve instanceof ECCurve.F2m) + { compressed = isCompressionPreferred(ecPointFormats, ECPointFormat.ansiX962_compressed_char2); - } else if (curve instanceof ECCurve.Fp) { + } + else if (curve instanceof ECCurve.Fp) + { compressed = isCompressionPreferred(ecPointFormats, ECPointFormat.ansiX962_compressed_prime); } return point.getEncoded(compressed); } public static byte[] serializeECPublicKey(short[] ecPointFormats, ECPublicKeyParameters keyParameters) - throws IOException { + throws IOException + { return serializeECPoint(ecPointFormats, keyParameters.getQ()); } - public static BigInteger deserializeECFieldElement(int fieldSize, byte[] encoding) throws IOException { + public static BigInteger deserializeECFieldElement(int fieldSize, byte[] encoding) + throws IOException + { int requiredLength = (fieldSize + 7) / 8; - if (encoding.length != requiredLength) { + if (encoding.length != requiredLength) + { throw new TlsFatalAlert(AlertDescription.decode_error); } return new BigInteger(1, encoding); } - public static ECPoint deserializeECPoint(short[] ecPointFormats, ECCurve curve, byte[] encoding) throws IOException { + public static ECPoint deserializeECPoint(short[] ecPointFormats, ECCurve curve, byte[] encoding) + throws IOException + { /* * NOTE: Here we implicitly decode compressed or uncompressed encodings. DefaultTlsClient by * default is set up to advertise that we can parse any encoding so this works fine, but @@ -309,17 +368,23 @@ public class TlsECCUtils { } public static ECPublicKeyParameters deserializeECPublicKey(short[] ecPointFormats, ECDomainParameters curve_params, - byte[] encoding) throws IOException { + byte[] encoding) + throws IOException + { - try { + try + { ECPoint Y = deserializeECPoint(ecPointFormats, curve_params.getCurve(), encoding); return new ECPublicKeyParameters(Y, curve_params); - } catch (RuntimeException e) { + } + catch (RuntimeException e) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } - public static byte[] calculateECDHBasicAgreement(ECPublicKeyParameters publicKey, ECPrivateKeyParameters privateKey) { + public static byte[] calculateECDHBasicAgreement(ECPublicKeyParameters publicKey, ECPrivateKeyParameters privateKey) + { ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement(); basicAgreement.init(privateKey); @@ -333,7 +398,8 @@ public class TlsECCUtils { return BigIntegers.asUnsignedByteArray(basicAgreement.getFieldSize(), agreementValue); } - public static AsymmetricCipherKeyPair generateECKeyPair(SecureRandom random, ECDomainParameters ecParams) { + public static AsymmetricCipherKeyPair generateECKeyPair(SecureRandom random, ECDomainParameters ecParams) + { ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); ECKeyGenerationParameters keyGenerationParameters = new ECKeyGenerationParameters(ecParams, random); @@ -341,39 +407,53 @@ public class TlsECCUtils { return keyPairGenerator.generateKeyPair(); } - public static ECPublicKeyParameters validateECPublicKey(ECPublicKeyParameters key) throws IOException { + public static ECPublicKeyParameters validateECPublicKey(ECPublicKeyParameters key) + throws IOException + { // TODO Check RFC 4492 for validation return key; } - public static int readECExponent(int fieldSize, InputStream input) throws IOException { + public static int readECExponent(int fieldSize, InputStream input) + throws IOException + { BigInteger K = readECParameter(input); - if (K.bitLength() < 32) { + if (K.bitLength() < 32) + { int k = K.intValue(); - if (k > 0 && k < fieldSize) { + if (k > 0 && k < fieldSize) + { return k; } } throw new TlsFatalAlert(AlertDescription.illegal_parameter); } - public static BigInteger readECFieldElement(int fieldSize, InputStream input) throws IOException { + public static BigInteger readECFieldElement(int fieldSize, InputStream input) + throws IOException + { return deserializeECFieldElement(fieldSize, TlsUtils.readOpaque8(input)); } - public static BigInteger readECParameter(InputStream input) throws IOException { + public static BigInteger readECParameter(InputStream input) + throws IOException + { // TODO Are leading zeroes okay here? return new BigInteger(1, TlsUtils.readOpaque8(input)); } public static ECDomainParameters readECParameters(int[] namedCurves, short[] ecPointFormats, InputStream input) - throws IOException { + throws IOException + { - try { + try + { short curveType = TlsUtils.readUint8(input); - switch (curveType) { - case ECCurveType.explicit_prime: { + switch (curveType) + { + case ECCurveType.explicit_prime: + { BigInteger prime_p = readECParameter(input); BigInteger a = readECFieldElement(prime_p.bitLength(), input); BigInteger b = readECFieldElement(prime_p.bitLength(), input); @@ -383,19 +463,23 @@ public class TlsECCUtils { BigInteger cofactor = readECParameter(input); return new ECDomainParameters(curve, base, order, cofactor); } - case ECCurveType.explicit_char2: { + case ECCurveType.explicit_char2: + { int m = TlsUtils.readUint16(input); short basis = TlsUtils.readUint8(input); ECCurve curve; - switch (basis) { - case ECBasisType.ec_basis_trinomial: { + switch (basis) + { + case ECBasisType.ec_basis_trinomial: + { int k = readECExponent(m, input); BigInteger a = readECFieldElement(m, input); BigInteger b = readECFieldElement(m, input); curve = new ECCurve.F2m(m, k, a, b); break; } - case ECBasisType.ec_basis_pentanomial: { + case ECBasisType.ec_basis_pentanomial: + { int k1 = readECExponent(m, input); int k2 = readECExponent(m, input); int k3 = readECExponent(m, input); @@ -412,9 +496,11 @@ public class TlsECCUtils { BigInteger cofactor = readECParameter(input); return new ECDomainParameters(curve, base, order, cofactor); } - case ECCurveType.named_curve: { + case ECCurveType.named_curve: + { int namedCurve = TlsUtils.readUint16(input); - if (!NamedCurve.refersToASpecificNamedCurve(namedCurve)) { + if (!NamedCurve.refersToASpecificNamedCurve(namedCurve)) + { /* * RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a * specific curve. Values of NamedCurve that indicate support for a class of @@ -423,7 +509,8 @@ public class TlsECCUtils { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } - if (!TlsProtocol.arrayContains(namedCurves, namedCurve)) { + if (!TlsProtocol.arrayContains(namedCurves, namedCurve)) + { /* * RFC 4492 4. [...] servers MUST NOT negotiate the use of an ECC cipher suite * unless they can complete the handshake while respecting the choice of curves @@ -437,53 +524,71 @@ public class TlsECCUtils { default: throw new TlsFatalAlert(AlertDescription.illegal_parameter); } - } catch (RuntimeException e) { + } + catch (RuntimeException e) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } - public static void writeECExponent(int k, OutputStream output) throws IOException { + public static void writeECExponent(int k, OutputStream output) + throws IOException + { BigInteger K = BigInteger.valueOf(k); writeECParameter(K, output); } - public static void writeECFieldElement(int fieldSize, BigInteger x, OutputStream output) throws IOException { + public static void writeECFieldElement(int fieldSize, BigInteger x, OutputStream output) + throws IOException + { TlsUtils.writeOpaque8(serializeECFieldElement(fieldSize, x), output); } - public static void writeECParameter(BigInteger x, OutputStream output) throws IOException { + public static void writeECParameter(BigInteger x, OutputStream output) + throws IOException + { TlsUtils.writeOpaque8(BigIntegers.asUnsignedByteArray(x), output); } public static void writeExplicitECParameters(short[] ecPointFormats, ECDomainParameters ecParameters, - OutputStream output) throws IOException { + OutputStream output) + throws IOException + { ECCurve curve = ecParameters.getCurve(); - if (curve instanceof ECCurve.Fp) { + if (curve instanceof ECCurve.Fp) + { TlsUtils.writeUint8(ECCurveType.explicit_prime, output); - ECCurve.Fp fp = (ECCurve.Fp) curve; + ECCurve.Fp fp = (ECCurve.Fp)curve; writeECParameter(fp.getQ(), output); - } else if (curve instanceof ECCurve.F2m) { + } + else if (curve instanceof ECCurve.F2m) + { TlsUtils.writeUint8(ECCurveType.explicit_char2, output); - ECCurve.F2m f2m = (ECCurve.F2m) curve; + ECCurve.F2m f2m = (ECCurve.F2m)curve; TlsUtils.writeUint16(f2m.getM(), output); - if (f2m.isTrinomial()) { + if (f2m.isTrinomial()) + { TlsUtils.writeUint8(ECBasisType.ec_basis_trinomial, output); writeECExponent(f2m.getK1(), output); - } else { + } + else + { TlsUtils.writeUint8(ECBasisType.ec_basis_pentanomial, output); writeECExponent(f2m.getK1(), output); writeECExponent(f2m.getK2(), output); writeECExponent(f2m.getK3(), output); } - } else { + } + else + { throw new IllegalArgumentException("'ecParameters' not a known curve type"); } @@ -494,9 +599,12 @@ public class TlsECCUtils { writeECParameter(ecParameters.getH(), output); } - public static void writeNamedECParameters(int namedCurve, OutputStream output) throws IOException { + public static void writeNamedECParameters(int namedCurve, OutputStream output) + throws IOException + { - if (!NamedCurve.refersToASpecificNamedCurve(namedCurve)) { + if (!NamedCurve.refersToASpecificNamedCurve(namedCurve)) + { /* * RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a specific * curve. Values of NamedCurve that indicate support for a class of explicitly defined diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsECDHEKeyExchange.java b/src/main/java/org/bouncycastle/crypto/tls/TlsECDHEKeyExchange.java index 152e371f..094443eb 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsECDHEKeyExchange.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsECDHEKeyExchange.java @@ -16,38 +16,51 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters; /** * ECDHE key exchange (see RFC 4492) */ -public class TlsECDHEKeyExchange extends TlsECDHKeyExchange { +public class TlsECDHEKeyExchange + extends TlsECDHKeyExchange +{ protected TlsSignerCredentials serverCredentials = null; public TlsECDHEKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, int[] namedCurves, - short[] clientECPointFormats, short[] serverECPointFormats) { + short[] clientECPointFormats, short[] serverECPointFormats) + { super(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats); } - public void processServerCredentials(TlsCredentials serverCredentials) throws IOException { + public void processServerCredentials(TlsCredentials serverCredentials) + throws IOException + { - if (!(serverCredentials instanceof TlsSignerCredentials)) { + if (!(serverCredentials instanceof TlsSignerCredentials)) + { throw new TlsFatalAlert(AlertDescription.internal_error); } processServerCertificate(serverCredentials.getCertificate()); - this.serverCredentials = (TlsSignerCredentials) serverCredentials; + this.serverCredentials = (TlsSignerCredentials)serverCredentials; } - public byte[] generateServerKeyExchange() throws IOException { + public byte[] generateServerKeyExchange() + throws IOException + { /* * First we try to find a supported named curve from the client's list. */ int namedCurve = -1; - if (namedCurves == null) { + if (namedCurves == null) + { namedCurve = NamedCurve.secp256r1; - } else { - for (int i = 0; i < namedCurves.length; ++i) { + } + else + { + for (int i = 0; i < namedCurves.length; ++i) + { int entry = namedCurves[i]; - if (TlsECCUtils.isSupportedNamedCurve(entry)) { + if (TlsECCUtils.isSupportedNamedCurve(entry)) + { namedCurve = entry; break; } @@ -55,20 +68,27 @@ public class TlsECDHEKeyExchange extends TlsECDHKeyExchange { } ECDomainParameters curve_params = null; - if (namedCurve >= 0) { + if (namedCurve >= 0) + { curve_params = TlsECCUtils.getParametersForNamedCurve(namedCurve); - } else { + } + else + { /* * If no named curves are suitable, check if the client supports explicit curves. */ - if (TlsProtocol.arrayContains(namedCurves, NamedCurve.arbitrary_explicit_prime_curves)) { + if (TlsProtocol.arrayContains(namedCurves, NamedCurve.arbitrary_explicit_prime_curves)) + { curve_params = TlsECCUtils.getParametersForNamedCurve(NamedCurve.secp256r1); - } else if (TlsProtocol.arrayContains(namedCurves, NamedCurve.arbitrary_explicit_char2_curves)) { + } + else if (TlsProtocol.arrayContains(namedCurves, NamedCurve.arbitrary_explicit_char2_curves)) + { curve_params = TlsECCUtils.getParametersForNamedCurve(NamedCurve.sect233r1); } } - if (curve_params == null) { + if (curve_params == null) + { /* * NOTE: We shouldn't have negotiated ECDHE key exchange since we apparently can't find * a suitable curve. @@ -77,16 +97,19 @@ public class TlsECDHEKeyExchange extends TlsECDHKeyExchange { } AsymmetricCipherKeyPair kp = TlsECCUtils.generateECKeyPair(context.getSecureRandom(), curve_params); - this.ecAgreeServerPrivateKey = (ECPrivateKeyParameters) kp.getPrivate(); + this.ecAgreeServerPrivateKey = (ECPrivateKeyParameters)kp.getPrivate(); byte[] publicBytes = TlsECCUtils.serializeECPublicKey(clientECPointFormats, - (ECPublicKeyParameters) kp.getPublic()); + (ECPublicKeyParameters)kp.getPublic()); ByteArrayOutputStream buf = new ByteArrayOutputStream(); - if (namedCurve < 0) { + if (namedCurve < 0) + { TlsECCUtils.writeExplicitECParameters(clientECPointFormats, curve_params, buf); - } else { + } + else + { TlsECCUtils.writeNamedECParameters(namedCurve, buf); } @@ -113,7 +136,9 @@ public class TlsECDHEKeyExchange extends TlsECDHKeyExchange { return buf.toByteArray(); } - public void processServerKeyExchange(InputStream input) throws IOException { + public void processServerKeyExchange(InputStream input) + throws IOException + { SecurityParameters securityParameters = context.getSecurityParameters(); @@ -125,7 +150,8 @@ public class TlsECDHEKeyExchange extends TlsECDHKeyExchange { byte[] point = TlsUtils.readOpaque8(sigIn); byte[] sigByte = TlsUtils.readOpaque16(input); - if (!signer.verifySignature(sigByte)) { + if (!signer.verifySignature(sigByte)) + { throw new TlsFatalAlert(AlertDescription.decrypt_error); } @@ -133,7 +159,9 @@ public class TlsECDHEKeyExchange extends TlsECDHKeyExchange { clientECPointFormats, curve_params, point)); } - public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { + public void validateCertificateRequest(CertificateRequest certificateRequest) + throws IOException + { /* * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because @@ -141,8 +169,10 @@ public class TlsECDHEKeyExchange extends TlsECDHKeyExchange { * these algorithms. */ short[] types = certificateRequest.getCertificateTypes(); - for (int i = 0; i < types.length; ++i) { - switch (types[i]) { + for (int i = 0; i < types.length; ++i) + { + switch (types[i]) + { case ClientCertificateType.rsa_sign: case ClientCertificateType.dss_sign: case ClientCertificateType.ecdsa_sign: @@ -153,15 +183,21 @@ public class TlsECDHEKeyExchange extends TlsECDHKeyExchange { } } - public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { - if (clientCredentials instanceof TlsSignerCredentials) { + public void processClientCredentials(TlsCredentials clientCredentials) + throws IOException + { + if (clientCredentials instanceof TlsSignerCredentials) + { // OK - } else { + } + else + { throw new TlsFatalAlert(AlertDescription.internal_error); } } - protected Signer initVerifyer(TlsSigner tlsSigner, SecurityParameters securityParameters) { + protected Signer initVerifyer(TlsSigner tlsSigner, SecurityParameters securityParameters) + { Signer signer = tlsSigner.createVerifyer(this.serverPublicKey); signer.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); signer.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsECDHKeyExchange.java b/src/main/java/org/bouncycastle/crypto/tls/TlsECDHKeyExchange.java index 74231dbc..e157533f 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsECDHKeyExchange.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsECDHKeyExchange.java @@ -17,7 +17,9 @@ import org.bouncycastle.crypto.util.PublicKeyFactory; /** * ECDH key exchange (see RFC 4492) */ -public class TlsECDHKeyExchange extends AbstractTlsKeyExchange { +public class TlsECDHKeyExchange + extends AbstractTlsKeyExchange +{ protected TlsSigner tlsSigner; protected int[] namedCurves; @@ -32,11 +34,13 @@ public class TlsECDHKeyExchange extends AbstractTlsKeyExchange { protected ECPublicKeyParameters ecAgreeClientPublicKey; public TlsECDHKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, int[] namedCurves, - short[] clientECPointFormats, short[] serverECPointFormats) { + short[] clientECPointFormats, short[] serverECPointFormats) + { super(keyExchange, supportedSignatureAlgorithms); - switch (keyExchange) { + switch (keyExchange) + { case KeyExchangeAlgorithm.ECDHE_RSA: this.tlsSigner = new TlsRSASigner(); break; @@ -57,44 +61,61 @@ public class TlsECDHKeyExchange extends AbstractTlsKeyExchange { this.serverECPointFormats = serverECPointFormats; } - public void init(TlsContext context) { + public void init(TlsContext context) + { super.init(context); - if (this.tlsSigner != null) { + if (this.tlsSigner != null) + { this.tlsSigner.init(context); } } - public void skipServerCredentials() throws IOException { + public void skipServerCredentials() + throws IOException + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } - public void processServerCertificate(Certificate serverCertificate) throws IOException { + public void processServerCertificate(Certificate serverCertificate) + throws IOException + { - if (serverCertificate.isEmpty()) { + if (serverCertificate.isEmpty()) + { throw new TlsFatalAlert(AlertDescription.bad_certificate); } org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - try { + try + { this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); - } catch (RuntimeException e) { + } + catch (RuntimeException e) + { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } - if (tlsSigner == null) { - try { + if (tlsSigner == null) + { + try + { this.ecAgreeServerPublicKey = TlsECCUtils - .validateECPublicKey((ECPublicKeyParameters) this.serverPublicKey); - } catch (ClassCastException e) { + .validateECPublicKey((ECPublicKeyParameters)this.serverPublicKey); + } + catch (ClassCastException e) + { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyAgreement); - } else { - if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) { + } + else + { + if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) + { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } @@ -104,8 +125,10 @@ public class TlsECDHKeyExchange extends AbstractTlsKeyExchange { super.processServerCertificate(serverCertificate); } - public boolean requiresServerKeyExchange() { - switch (keyExchange) { + public boolean requiresServerKeyExchange() + { + switch (keyExchange) + { case KeyExchangeAlgorithm.ECDHE_ECDSA: case KeyExchangeAlgorithm.ECDHE_RSA: case KeyExchangeAlgorithm.ECDH_anon: @@ -115,7 +138,9 @@ public class TlsECDHKeyExchange extends AbstractTlsKeyExchange { } } - public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { + public void validateCertificateRequest(CertificateRequest certificateRequest) + throws IOException + { /* * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because @@ -123,8 +148,10 @@ public class TlsECDHKeyExchange extends AbstractTlsKeyExchange { * these algorithms. */ short[] types = certificateRequest.getCertificateTypes(); - for (int i = 0; i < types.length; ++i) { - switch (types[i]) { + for (int i = 0; i < types.length; ++i) + { + switch (types[i]) + { case ClientCertificateType.rsa_sign: case ClientCertificateType.dss_sign: case ClientCertificateType.ecdsa_sign: @@ -137,42 +164,57 @@ public class TlsECDHKeyExchange extends AbstractTlsKeyExchange { } } - public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { - if (clientCredentials instanceof TlsAgreementCredentials) { + public void processClientCredentials(TlsCredentials clientCredentials) + throws IOException + { + if (clientCredentials instanceof TlsAgreementCredentials) + { // TODO Validate client cert has matching parameters (see 'TlsECCUtils.areOnSameCurve')? - this.agreementCredentials = (TlsAgreementCredentials) clientCredentials; - } else if (clientCredentials instanceof TlsSignerCredentials) { + this.agreementCredentials = (TlsAgreementCredentials)clientCredentials; + } + else if (clientCredentials instanceof TlsSignerCredentials) + { // OK - } else { + } + else + { throw new TlsFatalAlert(AlertDescription.internal_error); } } - public void generateClientKeyExchange(OutputStream output) throws IOException { - if (agreementCredentials != null) { + public void generateClientKeyExchange(OutputStream output) + throws IOException + { + if (agreementCredentials != null) + { return; } AsymmetricCipherKeyPair ecAgreeClientKeyPair = TlsECCUtils.generateECKeyPair(context.getSecureRandom(), ecAgreeServerPublicKey.getParameters()); - this.ecAgreeClientPrivateKey = (ECPrivateKeyParameters) ecAgreeClientKeyPair.getPrivate(); + this.ecAgreeClientPrivateKey = (ECPrivateKeyParameters)ecAgreeClientKeyPair.getPrivate(); byte[] point = TlsECCUtils.serializeECPublicKey(serverECPointFormats, - (ECPublicKeyParameters) ecAgreeClientKeyPair.getPublic()); + (ECPublicKeyParameters)ecAgreeClientKeyPair.getPublic()); TlsUtils.writeOpaque8(point, output); } - public void processClientCertificate(Certificate clientCertificate) throws IOException { + public void processClientCertificate(Certificate clientCertificate) + throws IOException + { // TODO Extract the public key // TODO If the certificate is 'fixed', take the public key as ecAgreeClientPublicKey } - public void processClientKeyExchange(InputStream input) throws IOException { + public void processClientKeyExchange(InputStream input) + throws IOException + { - if (ecAgreeClientPublicKey != null) { + if (ecAgreeClientPublicKey != null) + { // For ecdsa_fixed_ecdh and rsa_fixed_ecdh, the key arrived in the client certificate return; } @@ -185,16 +227,21 @@ public class TlsECDHKeyExchange extends AbstractTlsKeyExchange { serverECPointFormats, curve_params, point)); } - public byte[] generatePremasterSecret() throws IOException { - if (agreementCredentials != null) { + public byte[] generatePremasterSecret() + throws IOException + { + if (agreementCredentials != null) + { return agreementCredentials.generateAgreement(ecAgreeServerPublicKey); } - if (ecAgreeServerPrivateKey != null) { + if (ecAgreeServerPrivateKey != null) + { return TlsECCUtils.calculateECDHBasicAgreement(ecAgreeClientPublicKey, ecAgreeServerPrivateKey); } - if (ecAgreeClientPrivateKey != null) { + if (ecAgreeClientPrivateKey != null) + { return TlsECCUtils.calculateECDHBasicAgreement(ecAgreeServerPublicKey, ecAgreeClientPrivateKey); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsECDSASigner.java b/src/main/java/org/bouncycastle/crypto/tls/TlsECDSASigner.java index 5f23c787..6809815c 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsECDSASigner.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsECDSASigner.java @@ -5,13 +5,17 @@ import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.signers.ECDSASigner; -public class TlsECDSASigner extends TlsDSASigner { +public class TlsECDSASigner + extends TlsDSASigner +{ - public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) { + public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) + { return publicKey instanceof ECPublicKeyParameters; } - protected DSA createDSAImpl() { + protected DSA createDSAImpl() + { return new ECDSASigner(); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsEncryptionCredentials.java b/src/main/java/org/bouncycastle/crypto/tls/TlsEncryptionCredentials.java index 5cc7c5b2..7e5d6d81 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsEncryptionCredentials.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsEncryptionCredentials.java @@ -2,7 +2,10 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -public interface TlsEncryptionCredentials extends TlsCredentials { +public interface TlsEncryptionCredentials + extends TlsCredentials +{ - byte[] decryptPreMasterSecret(byte[] encryptedPreMasterSecret) throws IOException; + byte[] decryptPreMasterSecret(byte[] encryptedPreMasterSecret) + throws IOException; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsFatalAlert.java b/src/main/java/org/bouncycastle/crypto/tls/TlsFatalAlert.java index 3380deee..61cec318 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsFatalAlert.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsFatalAlert.java @@ -2,7 +2,8 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -public class TlsFatalAlert extends IOException +public class TlsFatalAlert + extends IOException { private static final long serialVersionUID = 3584313123679111168L; diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsHandshakeHash.java b/src/main/java/org/bouncycastle/crypto/tls/TlsHandshakeHash.java index fe2373ab..4b5ccac7 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsHandshakeHash.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsHandshakeHash.java @@ -2,7 +2,9 @@ package org.bouncycastle.crypto.tls; import org.bouncycastle.crypto.Digest; -interface TlsHandshakeHash extends Digest { +interface TlsHandshakeHash + extends Digest +{ void init(TlsContext context); diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsInputStream.java b/src/main/java/org/bouncycastle/crypto/tls/TlsInputStream.java index 47281d9b..9509dc4f 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsInputStream.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsInputStream.java @@ -6,7 +6,8 @@ import java.io.InputStream; /** * An InputStream for an TLS 1.0 connection. */ -class TlsInputStream extends InputStream +class TlsInputStream + extends InputStream { private byte[] buf = new byte[1]; private TlsProtocol handler = null; @@ -16,12 +17,14 @@ class TlsInputStream extends InputStream this.handler = handler; } - public int read(byte[] buf, int offset, int len) throws IOException + public int read(byte[] buf, int offset, int len) + throws IOException { return this.handler.readApplicationData(buf, offset, len); } - public int read() throws IOException + public int read() + throws IOException { if (this.read(buf) < 0) { @@ -30,7 +33,8 @@ class TlsInputStream extends InputStream return buf[0] & 0xff; } - public void close() throws IOException + public void close() + throws IOException { handler.close(); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsKeyExchange.java b/src/main/java/org/bouncycastle/crypto/tls/TlsKeyExchange.java index 182ac5d9..46562ab6 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsKeyExchange.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsKeyExchange.java @@ -7,35 +7,49 @@ import java.io.OutputStream; /** * A generic interface for key exchange implementations in TLS 1.0/1.1. */ -public interface TlsKeyExchange { +public interface TlsKeyExchange +{ void init(TlsContext context); - void skipServerCredentials() throws IOException; + void skipServerCredentials() + throws IOException; - void processServerCredentials(TlsCredentials serverCredentials) throws IOException; + void processServerCredentials(TlsCredentials serverCredentials) + throws IOException; - void processServerCertificate(Certificate serverCertificate) throws IOException; + void processServerCertificate(Certificate serverCertificate) + throws IOException; boolean requiresServerKeyExchange(); - byte[] generateServerKeyExchange() throws IOException; + byte[] generateServerKeyExchange() + throws IOException; - void skipServerKeyExchange() throws IOException; + void skipServerKeyExchange() + throws IOException; - void processServerKeyExchange(InputStream input) throws IOException; + void processServerKeyExchange(InputStream input) + throws IOException; - void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException; + void validateCertificateRequest(CertificateRequest certificateRequest) + throws IOException; - void skipClientCredentials() throws IOException; + void skipClientCredentials() + throws IOException; - void processClientCredentials(TlsCredentials clientCredentials) throws IOException; + void processClientCredentials(TlsCredentials clientCredentials) + throws IOException; - void processClientCertificate(Certificate clientCertificate) throws IOException; + void processClientCertificate(Certificate clientCertificate) + throws IOException; - void generateClientKeyExchange(OutputStream output) throws IOException; + void generateClientKeyExchange(OutputStream output) + throws IOException; - void processClientKeyExchange(InputStream input) throws IOException; + void processClientKeyExchange(InputStream input) + throws IOException; - byte[] generatePremasterSecret() throws IOException; + byte[] generatePremasterSecret() + throws IOException; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsMac.java b/src/main/java/org/bouncycastle/crypto/tls/TlsMac.java index 3de0be1f..adfaff4d 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsMac.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsMac.java @@ -13,7 +13,8 @@ import org.bouncycastle.util.Arrays; /** * A generic TLS MAC implementation, acting as an HMAC based on some underlying Digest. */ -public class TlsMac { +public class TlsMac +{ protected TlsContext context; protected byte[] secret; @@ -23,19 +24,15 @@ public class TlsMac { /** * Generate a new instance of an TlsMac. - * - * @param context - * the TLS client context - * @param digest - * The digest to use. - * @param key - * A byte-array where the key for this mac is located. - * @param keyOff - * The number of bytes to skip, before the key starts in the buffer. - * @param len - * The length of the key. + * + * @param context the TLS client context + * @param digest The digest to use. + * @param key A byte-array where the key for this mac is located. + * @param keyOff The number of bytes to skip, before the key starts in the buffer. + * @param len The length of the key. */ - public TlsMac(TlsContext context, Digest digest, byte[] key, int keyOff, int keyLen) { + public TlsMac(TlsContext context, Digest digest, byte[] key, int keyOff, int keyLen) + { this.context = context; KeyParameter keyParameter = new KeyParameter(key, keyOff, keyLen); @@ -43,26 +40,33 @@ public class TlsMac { this.secret = Arrays.clone(keyParameter.getKey()); // TODO This should check the actual algorithm, not rely on the engine type - if (digest instanceof LongDigest) { + if (digest instanceof LongDigest) + { this.digestBlockSize = 128; this.digestOverhead = 16; - } else { + } + else + { this.digestBlockSize = 64; this.digestOverhead = 8; } - if (context.getServerVersion().isSSL()) { + if (context.getServerVersion().isSSL()) + { this.mac = new SSL3Mac(digest); // TODO This should check the actual algorithm, not assume based on the digest size - if (digest.getDigestSize() == 20) { + if (digest.getDigestSize() == 20) + { /* * NOTE: When SHA-1 is used with the SSL 3.0 MAC, the secret + input pad is not * digest block-aligned. */ this.digestOverhead = 4; } - } else { + } + else + { this.mac = new HMac(digest); // NOTE: The input pad for HMAC is always a full digest block @@ -74,46 +78,49 @@ public class TlsMac { /** * @return the MAC write secret */ - public byte[] getMACSecret() { + public byte[] getMACSecret() + { return this.secret; } /** * @return The Keysize of the mac. */ - public int getSize() { + public int getSize() + { return mac.getMacSize(); } /** * Calculate the MAC for some given data. - * - * @param type - * The message type of the message. - * @param message - * A byte-buffer containing the message. - * @param offset - * The number of bytes to skip, before the message starts. - * @param length - * The length of the message. + * + * @param type The message type of the message. + * @param message A byte-buffer containing the message. + * @param offset The number of bytes to skip, before the message starts. + * @param length The length of the message. * @return A new byte-buffer containing the MAC value. */ - public byte[] calculateMac(long seqNo, short type, byte[] message, int offset, int length) { + public byte[] calculateMac(long seqNo, short type, byte[] message, int offset, int length) + { ProtocolVersion serverVersion = context.getServerVersion(); boolean isSSL = serverVersion.isSSL(); ByteArrayOutputStream bosMac = new ByteArrayOutputStream(isSSL ? 11 : 13); - try { + try + { TlsUtils.writeUint64(seqNo, bosMac); TlsUtils.writeUint8(type, bosMac); - if (!isSSL) { + if (!isSSL) + { TlsUtils.writeVersion(serverVersion, bosMac); } TlsUtils.writeUint16(length, bosMac); - } catch (IOException e) { + } + catch (IOException e) + { // This should never happen throw new IllegalStateException("Internal error during mac calculation"); } @@ -128,7 +135,8 @@ public class TlsMac { } public byte[] calculateMacConstantTime(long seqNo, short type, byte[] message, int offset, int length, - int fullLength, byte[] dummyData) { + int fullLength, byte[] dummyData) + { /* * Actual MAC only calculated on 'length' bytes... @@ -144,7 +152,8 @@ public class TlsMac { // How many extra full blocks do we need to calculate? int extra = getDigestBlockCount(headerLength + fullLength) - getDigestBlockCount(headerLength + length); - while (--extra >= 0) { + while (--extra >= 0) + { mac.update(dummyData, 0, digestBlockSize); } @@ -155,7 +164,8 @@ public class TlsMac { return result; } - private int getDigestBlockCount(int inputLength) { + private int getDigestBlockCount(int inputLength) + { // NOTE: This calculation assumes a minimum of 1 pad byte return (inputLength + digestOverhead) / digestBlockSize; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java b/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java index 5a109929..c50bde8f 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java @@ -8,22 +8,27 @@ import org.bouncycastle.util.Arrays; /** * A NULL CipherSuite with optional MAC */ -public class TlsNullCipher implements TlsCipher { +public class TlsNullCipher + implements TlsCipher +{ protected TlsContext context; protected TlsMac writeMac; protected TlsMac readMac; - public TlsNullCipher(TlsContext context) { + public TlsNullCipher(TlsContext context) + { this.context = context; this.writeMac = null; this.readMac = null; } public TlsNullCipher(TlsContext context, Digest clientWriteDigest, Digest serverWriteDigest) - throws IOException { + throws IOException + { - if ((clientWriteDigest == null) != (serverWriteDigest == null)) { + if ((clientWriteDigest == null) != (serverWriteDigest == null)) + { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -31,7 +36,8 @@ public class TlsNullCipher implements TlsCipher { TlsMac clientWriteMac = null, serverWriteMac = null; - if (clientWriteDigest != null) { + if (clientWriteDigest != null) + { int key_block_size = clientWriteDigest.getDigestSize() + serverWriteDigest.getDigestSize(); @@ -47,32 +53,40 @@ public class TlsNullCipher implements TlsCipher { serverWriteDigest.getDigestSize()); offset += serverWriteDigest.getDigestSize(); - if (offset != key_block_size) { + if (offset != key_block_size) + { throw new TlsFatalAlert(AlertDescription.internal_error); } } - if (context.isServer()) { + if (context.isServer()) + { writeMac = serverWriteMac; readMac = clientWriteMac; - } else { + } + else + { writeMac = clientWriteMac; readMac = serverWriteMac; } } - public int getPlaintextLimit(int ciphertextLimit) { + public int getPlaintextLimit(int ciphertextLimit) + { int result = ciphertextLimit; - if (writeMac != null) { + if (writeMac != null) + { result -= writeMac.getSize(); } return result; } public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) - throws IOException { + throws IOException + { - if (writeMac == null) { + if (writeMac == null) + { return Arrays.copyOfRange(plaintext, offset, offset + len); } @@ -84,14 +98,17 @@ public class TlsNullCipher implements TlsCipher { } public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) - throws IOException { + throws IOException + { - if (readMac == null) { + if (readMac == null) + { return Arrays.copyOfRange(ciphertext, offset, offset + len); } int macSize = readMac.getSize(); - if (len < macSize) { + if (len < macSize) + { throw new TlsFatalAlert(AlertDescription.decode_error); } @@ -100,7 +117,8 @@ public class TlsNullCipher implements TlsCipher { byte[] receivedMac = Arrays.copyOfRange(ciphertext, offset + macInputLen, offset + len); byte[] computedMac = readMac.calculateMac(seqNo, type, ciphertext, offset, macInputLen); - if (!Arrays.constantTimeAreEqual(receivedMac, computedMac)) { + if (!Arrays.constantTimeAreEqual(receivedMac, computedMac)) + { throw new TlsFatalAlert(AlertDescription.bad_record_mac); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsNullCompression.java b/src/main/java/org/bouncycastle/crypto/tls/TlsNullCompression.java index 93810442..13a85abf 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsNullCompression.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsNullCompression.java @@ -2,7 +2,8 @@ package org.bouncycastle.crypto.tls; import java.io.OutputStream; -public class TlsNullCompression implements TlsCompression +public class TlsNullCompression + implements TlsCompression { public OutputStream compress(OutputStream output) { diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsOutputStream.java b/src/main/java/org/bouncycastle/crypto/tls/TlsOutputStream.java index 475a592f..d9532414 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsOutputStream.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsOutputStream.java @@ -6,7 +6,8 @@ import java.io.OutputStream; /** * An OutputStream for an TLS connection. */ -class TlsOutputStream extends OutputStream +class TlsOutputStream + extends OutputStream { private byte[] buf = new byte[1]; private TlsProtocol handler; @@ -16,23 +17,27 @@ class TlsOutputStream extends OutputStream this.handler = handler; } - public void write(byte buf[], int offset, int len) throws IOException + public void write(byte buf[], int offset, int len) + throws IOException { this.handler.writeData(buf, offset, len); } - public void write(int arg0) throws IOException + public void write(int arg0) + throws IOException { buf[0] = (byte)arg0; this.write(buf, 0, 1); } - public void close() throws IOException + public void close() + throws IOException { handler.close(); } - public void flush() throws IOException + public void flush() + throws IOException { handler.flush(); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsPSKIdentity.java b/src/main/java/org/bouncycastle/crypto/tls/TlsPSKIdentity.java index 4d5f73b1..2f6eea26 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsPSKIdentity.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsPSKIdentity.java @@ -2,11 +2,11 @@ package org.bouncycastle.crypto.tls; public interface TlsPSKIdentity { - void skipIdentityHint(); + void skipIdentityHint(); - void notifyIdentityHint(byte[] psk_identity_hint); + void notifyIdentityHint(byte[] psk_identity_hint); - byte[] getPSKIdentity(); + byte[] getPSKIdentity(); - byte[] getPSK(); + byte[] getPSK(); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsPSKKeyExchange.java b/src/main/java/org/bouncycastle/crypto/tls/TlsPSKKeyExchange.java index 8f40f40d..87cb8d78 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsPSKKeyExchange.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsPSKKeyExchange.java @@ -19,7 +19,9 @@ import org.bouncycastle.crypto.util.PublicKeyFactory; /** * TLS 1.0 PSK key exchange (RFC 4279). */ -public class TlsPSKKeyExchange extends AbstractTlsKeyExchange { +public class TlsPSKKeyExchange + extends AbstractTlsKeyExchange +{ protected TlsPSKIdentity pskIdentity; @@ -32,10 +34,12 @@ public class TlsPSKKeyExchange extends AbstractTlsKeyExchange { protected RSAKeyParameters rsaServerPublicKey = null; protected byte[] premasterSecret; - public TlsPSKKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, TlsPSKIdentity pskIdentity) { + public TlsPSKKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, TlsPSKIdentity pskIdentity) + { super(keyExchange, supportedSignatureAlgorithms); - switch (keyExchange) { + switch (keyExchange) + { case KeyExchangeAlgorithm.PSK: case KeyExchangeAlgorithm.RSA_PSK: case KeyExchangeAlgorithm.DHE_PSK: @@ -47,51 +51,66 @@ public class TlsPSKKeyExchange extends AbstractTlsKeyExchange { this.pskIdentity = pskIdentity; } - public void skipServerCredentials() throws IOException { - if (keyExchange == KeyExchangeAlgorithm.RSA_PSK) { + public void skipServerCredentials() + throws IOException + { + if (keyExchange == KeyExchangeAlgorithm.RSA_PSK) + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } - public void processServerCertificate(Certificate serverCertificate) throws IOException { + public void processServerCertificate(Certificate serverCertificate) + throws IOException + { - if (keyExchange != KeyExchangeAlgorithm.RSA_PSK) { + if (keyExchange != KeyExchangeAlgorithm.RSA_PSK) + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } - if (serverCertificate.isEmpty()) { + if (serverCertificate.isEmpty()) + { throw new TlsFatalAlert(AlertDescription.bad_certificate); } org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - try { + try + { this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); - } catch (RuntimeException e) { + } + catch (RuntimeException e) + { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } // Sanity check the PublicKeyFactory - if (this.serverPublicKey.isPrivate()) { + if (this.serverPublicKey.isPrivate()) + { throw new TlsFatalAlert(AlertDescription.internal_error); } - this.rsaServerPublicKey = validateRSAPublicKey((RSAKeyParameters) this.serverPublicKey); + this.rsaServerPublicKey = validateRSAPublicKey((RSAKeyParameters)this.serverPublicKey); TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyEncipherment); super.processServerCertificate(serverCertificate); } - public boolean requiresServerKeyExchange() { + public boolean requiresServerKeyExchange() + { return keyExchange == KeyExchangeAlgorithm.DHE_PSK; } - public void processServerKeyExchange(InputStream input) throws IOException { + public void processServerKeyExchange(InputStream input) + throws IOException + { this.psk_identity_hint = TlsUtils.readOpaque16(input); - if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) { + if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) + { byte[] pBytes = TlsUtils.readOpaque16(input); byte[] gBytes = TlsUtils.readOpaque16(input); byte[] YsBytes = TlsUtils.readOpaque16(input); @@ -105,19 +124,28 @@ public class TlsPSKKeyExchange extends AbstractTlsKeyExchange { } } - public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { + public void validateCertificateRequest(CertificateRequest certificateRequest) + throws IOException + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } - public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { + public void processClientCredentials(TlsCredentials clientCredentials) + throws IOException + { throw new TlsFatalAlert(AlertDescription.internal_error); } - public void generateClientKeyExchange(OutputStream output) throws IOException { + public void generateClientKeyExchange(OutputStream output) + throws IOException + { - if (psk_identity_hint == null) { + if (psk_identity_hint == null) + { pskIdentity.skipIdentityHint(); - } else { + } + else + { pskIdentity.notifyIdentityHint(psk_identity_hint); } @@ -125,16 +153,21 @@ public class TlsPSKKeyExchange extends AbstractTlsKeyExchange { TlsUtils.writeOpaque16(psk_identity, output); - if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK) { + if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK) + { this.premasterSecret = TlsRSAUtils.generateEncryptedPreMasterSecret(context, this.rsaServerPublicKey, output); - } else if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) { + } + else if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) + { this.dhAgreeClientPrivateKey = TlsDHUtils.generateEphemeralClientKeyExchange(context.getSecureRandom(), dhAgreeServerPublicKey.getParameters(), output); } } - public byte[] generatePremasterSecret() throws IOException { + public byte[] generatePremasterSecret() + throws IOException + { byte[] psk = pskIdentity.getPSK(); byte[] other_secret = generateOtherSecret(psk.length); @@ -145,24 +178,30 @@ public class TlsPSKKeyExchange extends AbstractTlsKeyExchange { return buf.toByteArray(); } - protected byte[] generateOtherSecret(int pskLength) { + protected byte[] generateOtherSecret(int pskLength) + { - if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) { + if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) + { return TlsDHUtils.calculateDHBasicAgreement(dhAgreeServerPublicKey, dhAgreeClientPrivateKey); } - if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK) { + if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK) + { return this.premasterSecret; } return new byte[pskLength]; } - protected RSAKeyParameters validateRSAPublicKey(RSAKeyParameters key) throws IOException { + protected RSAKeyParameters validateRSAPublicKey(RSAKeyParameters key) + throws IOException + { // TODO What is the minimum bit length required? // key.getModulus().bitLength(); - if (!key.getExponent().isProbablePrime(2)) { + if (!key.getExponent().isProbablePrime(2)) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsPeer.java b/src/main/java/org/bouncycastle/crypto/tls/TlsPeer.java index 482a4a0f..d21581fb 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsPeer.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsPeer.java @@ -1,28 +1,23 @@ package org.bouncycastle.crypto.tls; -public interface TlsPeer { +public interface TlsPeer +{ /** * This method will be called when an alert is raised by the protocol. - * - * @param alertLevel - * {@link AlertLevel} - * @param alertDescription - * {@link AlertDescription} - * @param message - * A human-readable message explaining what caused this alert. May be null. - * @param cause - * The exception that caused this alert to be raised. May be null. + * + * @param alertLevel {@link AlertLevel} + * @param alertDescription {@link AlertDescription} + * @param message A human-readable message explaining what caused this alert. May be null. + * @param cause The exception that caused this alert to be raised. May be null. */ void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause); /** * This method will be called when an alert is received from the remote peer. - * - * @param alertLevel - * {@link AlertLevel} - * @param alertDescription - * {@link AlertDescription} + * + * @param alertLevel {@link AlertLevel} + * @param alertDescription {@link AlertDescription} */ void notifyAlertReceived(short alertLevel, short alertDescription); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsProtocol.java b/src/main/java/org/bouncycastle/crypto/tls/TlsProtocol.java index 0c40fb72..58e633af 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsProtocol.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsProtocol.java @@ -16,7 +16,8 @@ import org.bouncycastle.util.Integers; /** * An implementation of all high level protocols in TLS 1.0/1.1. */ -public abstract class TlsProtocol { +public abstract class TlsProtocol +{ protected static final Integer EXT_RenegotiationInfo = Integers.valueOf(ExtensionType.renegotiation_info); protected static final Integer EXT_SessionTicket = Integers.valueOf(ExtensionType.session_ticket); @@ -73,7 +74,8 @@ public abstract class TlsProtocol { protected boolean secure_renegotiation = false; protected boolean expectSessionTicket = false; - public TlsProtocol(InputStream input, OutputStream output, SecureRandom secureRandom) { + public TlsProtocol(InputStream input, OutputStream output, SecureRandom secureRandom) + { this.recordStream = new RecordStream(this, input, output); this.secureRandom = secureRandom; } @@ -82,22 +84,29 @@ public abstract class TlsProtocol { protected abstract TlsPeer getPeer(); - protected abstract void handleChangeCipherSpecMessage() throws IOException; + protected abstract void handleChangeCipherSpecMessage() + throws IOException; - protected abstract void handleHandshakeMessage(short type, byte[] buf) throws IOException; + protected abstract void handleHandshakeMessage(short type, byte[] buf) + throws IOException; - protected void handleWarningMessage(short description) throws IOException { + protected void handleWarningMessage(short description) + throws IOException + { } - protected void completeHandshake() throws IOException { + protected void completeHandshake() + throws IOException + { this.expected_verify_data = null; /* * We will now read data, until we have completed the handshake. */ - while (this.connection_state != CS_SERVER_FINISHED) { + while (this.connection_state != CS_SERVER_FINISHED) + { safeReadRecord(); } @@ -109,7 +118,8 @@ public abstract class TlsProtocol { /* * If this was an initial handshake, we are now ready to send and receive application data. */ - if (!appDataReady) { + if (!appDataReady) + { this.appDataReady = true; this.tlsInputStream = new TlsInputStream(this); @@ -117,11 +127,14 @@ public abstract class TlsProtocol { } } - protected void processRecord(short protocol, byte[] buf, int offset, int len) throws IOException { + protected void processRecord(short protocol, byte[] buf, int offset, int len) + throws IOException + { /* * Have a look at the protocol type, and add it to the correct queue. */ - switch (protocol) { + switch (protocol) + { case ContentType.change_cipher_spec: changeCipherSpecQueue.addData(buf, offset, len); processChangeCipherSpec(); @@ -135,7 +148,8 @@ public abstract class TlsProtocol { processHandshake(); break; case ContentType.application_data: - if (!appDataReady) { + if (!appDataReady) + { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } applicationDataQueue.addData(buf, offset, len); @@ -150,14 +164,18 @@ public abstract class TlsProtocol { } } - private void processHandshake() throws IOException { + private void processHandshake() + throws IOException + { boolean read; - do { + do + { read = false; /* * We need the first 4 bytes, they contain type and length of the message. */ - if (handshakeQueue.size() >= 4) { + if (handshakeQueue.size() >= 4) + { byte[] beginning = new byte[4]; handshakeQueue.read(beginning, 0, 4, 0); ByteArrayInputStream bis = new ByteArrayInputStream(beginning); @@ -167,7 +185,8 @@ public abstract class TlsProtocol { /* * Check if we have enough bytes in the buffer to read the full message. */ - if (handshakeQueue.size() >= (len + 4)) { + if (handshakeQueue.size() >= (len + 4)) + { /* * Read the message. */ @@ -180,12 +199,15 @@ public abstract class TlsProtocol { * starting at client hello up to, but not including, this finished message. * [..] Note: [Also,] Hello Request messages are omitted from handshake hashes. */ - switch (type) { + switch (type) + { case HandshakeType.hello_request: break; - case HandshakeType.finished: { + case HandshakeType.finished: + { - if (this.expected_verify_data == null) { + if (this.expected_verify_data == null) + { this.expected_verify_data = createVerifyData(!getContext().isServer()); } @@ -204,10 +226,12 @@ public abstract class TlsProtocol { read = true; } } - } while (read); + } + while (read); } - private void processApplicationData() { + private void processApplicationData() + { /* * There is nothing we need to do here. * @@ -215,8 +239,11 @@ public abstract class TlsProtocol { */ } - private void processAlert() throws IOException { - while (alertQueue.size() >= 2) { + private void processAlert() + throws IOException + { + while (alertQueue.size() >= 2) + { /* * An alert is always 2 bytes. Read the alert. */ @@ -228,27 +255,34 @@ public abstract class TlsProtocol { getPeer().notifyAlertReceived(level, description); - if (level == AlertLevel.fatal) { + if (level == AlertLevel.fatal) + { this.failedWithError = true; this.closed = true; /* * Now try to close the stream, ignore errors. */ - try { + try + { recordStream.close(); - } catch (Exception e) { + } + catch (Exception e) + { } throw new IOException(TLS_ERROR_MESSAGE); - } else { + } + else + { /* * RFC 5246 7.2.1. The other party MUST respond with a close_notify alert of its own * and close down the connection immediately, discarding any pending writes. */ // TODO Can close_notify be a fatal alert? - if (description == AlertDescription.close_notify) { + if (description == AlertDescription.close_notify) + { handleClose(false); } @@ -262,20 +296,23 @@ public abstract class TlsProtocol { /** * This method is called, when a change cipher spec message is received. - * - * @throws IOException - * If the message has an invalid content or the handshake is not in the correct - * state. + * + * @throws IOException If the message has an invalid content or the handshake is not in the correct + * state. */ - private void processChangeCipherSpec() throws IOException { - while (changeCipherSpecQueue.size() > 0) { + private void processChangeCipherSpec() + throws IOException + { + while (changeCipherSpecQueue.size() > 0) + { /* * A change cipher spec message is only one byte with the value 1. */ byte[] b = new byte[1]; changeCipherSpecQueue.read(b, 0, 1, 0); changeCipherSpecQueue.removeData(1); - if (b[0] != 1) { + if (b[0] != 1) + { /* * This should never happen. */ @@ -291,29 +328,31 @@ public abstract class TlsProtocol { /** * Read data from the network. The method will return immediately, if there is still some data * left in the buffer, or block until some application data has been read from the network. - * - * @param buf - * The buffer where the data will be copied to. - * @param offset - * The position where the data will be placed in the buffer. - * @param len - * The maximum number of bytes to read. + * + * @param buf The buffer where the data will be copied to. + * @param offset The position where the data will be placed in the buffer. + * @param len The maximum number of bytes to read. * @return The number of bytes read. - * @throws IOException - * If something goes wrong during reading data. + * @throws IOException If something goes wrong during reading data. */ - protected int readApplicationData(byte[] buf, int offset, int len) throws IOException { + protected int readApplicationData(byte[] buf, int offset, int len) + throws IOException + { - if (len < 1) { + if (len < 1) + { return 0; } - while (applicationDataQueue.size() == 0) { + while (applicationDataQueue.size() == 0) + { /* * We need to read some data. */ - if (this.closed) { - if (this.failedWithError) { + if (this.closed) + { + if (this.failedWithError) + { /* * Something went terribly wrong, we should throw an IOException */ @@ -334,42 +373,66 @@ public abstract class TlsProtocol { return len; } - protected void safeReadRecord() throws IOException { - try { + protected void safeReadRecord() + throws IOException + { + try + { recordStream.readRecord(); - } catch (TlsFatalAlert e) { - if (!this.closed) { + } + catch (TlsFatalAlert e) + { + if (!this.closed) + { this.failWithError(AlertLevel.fatal, e.getAlertDescription()); } throw e; - } catch (IOException e) { - if (!this.closed) { + } + catch (IOException e) + { + if (!this.closed) + { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; - } catch (RuntimeException e) { - if (!this.closed) { + } + catch (RuntimeException e) + { + if (!this.closed) + { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; } } - protected void safeWriteRecord(short type, byte[] buf, int offset, int len) throws IOException { - try { + protected void safeWriteRecord(short type, byte[] buf, int offset, int len) + throws IOException + { + try + { recordStream.writeRecord(type, buf, offset, len); - } catch (TlsFatalAlert e) { - if (!this.closed) { + } + catch (TlsFatalAlert e) + { + if (!this.closed) + { this.failWithError(AlertLevel.fatal, e.getAlertDescription()); } throw e; - } catch (IOException e) { - if (!closed) { + } + catch (IOException e) + { + if (!closed) + { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; - } catch (RuntimeException e) { - if (!closed) { + } + catch (RuntimeException e) + { + if (!closed) + { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; @@ -380,31 +443,33 @@ public abstract class TlsProtocol { * Send some application data to the remote system. *

* The method will handle fragmentation internally. - * - * @param buf - * The buffer with the data. - * @param offset - * The position in the buffer where the data is placed. - * @param len - * The length of the data. - * @throws IOException - * If something goes wrong during sending. + * + * @param buf The buffer with the data. + * @param offset The position in the buffer where the data is placed. + * @param len The length of the data. + * @throws IOException If something goes wrong during sending. */ - protected void writeData(byte[] buf, int offset, int len) throws IOException { - if (this.closed) { - if (this.failedWithError) { + protected void writeData(byte[] buf, int offset, int len) + throws IOException + { + if (this.closed) + { + if (this.failedWithError) + { throw new IOException(TLS_ERROR_MESSAGE); } throw new IOException("Sorry, connection has been closed, you cannot write more data"); } - while (len > 0) { + while (len > 0) + { /* * RFC 5246 6.2.1. Zero-length fragments of Application data MAY be sent as they are * potentially useful as a traffic analysis countermeasure. */ - if (this.writeExtraEmptyRecords) { + if (this.writeExtraEmptyRecords) + { /* * Protect against known IV attack! * @@ -428,14 +493,16 @@ public abstract class TlsProtocol { /** * @return An OutputStream which can be used to send data. */ - public OutputStream getOutputStream() { + public OutputStream getOutputStream() + { return this.tlsOutputStream; } /** * @return An InputStream which can be used to read data. */ - public InputStream getInputStream() { + public InputStream getInputStream() + { return this.tlsInputStream; } @@ -443,25 +510,26 @@ public abstract class TlsProtocol { * Terminate this connection with an alert. *

* Can be used for normal closure too. - * - * @param alertLevel - * The level of the alert, an be AlertLevel.fatal or AL_warning. - * @param alertDescription - * The exact alert message. - * @throws IOException - * If alert was fatal. + * + * @param alertLevel The level of the alert, an be AlertLevel.fatal or AL_warning. + * @param alertDescription The exact alert message. + * @throws IOException If alert was fatal. */ - protected void failWithError(short alertLevel, short alertDescription) throws IOException { + protected void failWithError(short alertLevel, short alertDescription) + throws IOException + { /* * Check if the connection is still open. */ - if (!closed) { + if (!closed) + { /* * Prepare the message */ this.closed = true; - if (alertLevel == AlertLevel.fatal) { + if (alertLevel == AlertLevel.fatal) + { /* * This is a fatal message. */ @@ -469,15 +537,20 @@ public abstract class TlsProtocol { } raiseAlert(alertLevel, alertDescription, null, null); recordStream.close(); - if (alertLevel == AlertLevel.fatal) { + if (alertLevel == AlertLevel.fatal) + { throw new IOException(TLS_ERROR_MESSAGE); } - } else { + } + else + { throw new IOException(TLS_ERROR_MESSAGE); } } - protected void processFinishedMessage(ByteArrayInputStream buf) throws IOException { + protected void processFinishedMessage(ByteArrayInputStream buf) + throws IOException + { byte[] verify_data = TlsUtils.readFully(expected_verify_data.length, buf); @@ -486,7 +559,8 @@ public abstract class TlsProtocol { /* * Compare both checksums. */ - if (!Arrays.constantTimeAreEqual(expected_verify_data, verify_data)) { + if (!Arrays.constantTimeAreEqual(expected_verify_data, verify_data)) + { /* * Wrong checksum in the finished message. */ @@ -495,32 +569,41 @@ public abstract class TlsProtocol { } protected void raiseAlert(short alertLevel, short alertDescription, String message, Exception cause) - throws IOException { + throws IOException + { getPeer().notifyAlertRaised(alertLevel, alertDescription, message, cause); byte[] error = new byte[2]; - error[0] = (byte) alertLevel; - error[1] = (byte) alertDescription; + error[0] = (byte)alertLevel; + error[1] = (byte)alertDescription; safeWriteRecord(ContentType.alert, error, 0, 2); } - protected void raiseWarning(short alertDescription, String message) throws IOException { + protected void raiseWarning(short alertDescription, String message) + throws IOException + { raiseAlert(AlertLevel.warning, alertDescription, message, null); } - protected void sendCertificateMessage(Certificate certificate) throws IOException { + protected void sendCertificateMessage(Certificate certificate) + throws IOException + { - if (certificate == null) { + if (certificate == null) + { certificate = Certificate.EMPTY_CHAIN; } - if (certificate.getLength() == 0) { + if (certificate.getLength() == 0) + { TlsContext context = getContext(); - if (!context.isServer()) { + if (!context.isServer()) + { ProtocolVersion serverVersion = getContext().getServerVersion(); - if (serverVersion.isSSL()) { + if (serverVersion.isSSL()) + { String message = serverVersion.toString() + " client didn't provide credentials"; raiseWarning(AlertDescription.no_certificate, message); return; @@ -543,13 +626,17 @@ public abstract class TlsProtocol { safeWriteRecord(ContentType.handshake, message, 0, message.length); } - protected void sendChangeCipherSpecMessage() throws IOException { - byte[] message = new byte[] { 1 }; + protected void sendChangeCipherSpecMessage() + throws IOException + { + byte[] message = new byte[]{1}; safeWriteRecord(ContentType.change_cipher_spec, message, 0, message.length); recordStream.sentWriteCipherSpec(); } - protected void sendFinishedMessage() throws IOException { + protected void sendFinishedMessage() + throws IOException + { byte[] verify_data = createVerifyData(getContext().isServer()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -561,7 +648,9 @@ public abstract class TlsProtocol { safeWriteRecord(ContentType.handshake, message, 0, message.length); } - protected void sendSupplementalDataMessage(Vector supplementalData) throws IOException { + protected void sendSupplementalDataMessage(Vector supplementalData) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.supplemental_data, buf); @@ -579,10 +668,12 @@ public abstract class TlsProtocol { safeWriteRecord(ContentType.handshake, message, 0, message.length); } - protected byte[] createVerifyData(boolean isServer) { + protected byte[] createVerifyData(boolean isServer) + { TlsContext context = getContext(); - if (isServer) { + if (isServer) + { return TlsUtils.calculateVerifyData(context, "server finished", recordStream.getCurrentHash(TlsUtils.SSL_SERVER)); } @@ -593,39 +684,52 @@ public abstract class TlsProtocol { /** * Closes this connection. - * - * @throws IOException - * If something goes wrong during closing. + * + * @throws IOException If something goes wrong during closing. */ - public void close() throws IOException { + public void close() + throws IOException + { handleClose(true); } - protected void handleClose(boolean user_canceled) throws IOException { - if (!closed) { - if (user_canceled && !appDataReady) { + protected void handleClose(boolean user_canceled) + throws IOException + { + if (!closed) + { + if (user_canceled && !appDataReady) + { raiseWarning(AlertDescription.user_canceled, "User canceled handshake"); } this.failWithError(AlertLevel.warning, AlertDescription.close_notify); } } - protected void flush() throws IOException { + protected void flush() + throws IOException + { recordStream.flush(); } - protected static boolean arrayContains(short[] a, short n) { - for (int i = 0; i < a.length; ++i) { - if (a[i] == n) { + protected static boolean arrayContains(short[] a, short n) + { + for (int i = 0; i < a.length; ++i) + { + if (a[i] == n) + { return true; } } return false; } - protected static boolean arrayContains(int[] a, int n) { - for (int i = 0; i < a.length; ++i) { - if (a[i] == n) { + protected static boolean arrayContains(int[] a, int n) + { + for (int i = 0; i < a.length; ++i) + { + if (a[i] == n) + { return true; } } @@ -634,53 +738,66 @@ public abstract class TlsProtocol { /** * Make sure the InputStream 'buf' now empty. Fail otherwise. - * - * @param buf - * The InputStream to check. - * @throws IOException - * If 'buf' is not empty. + * + * @param buf The InputStream to check. + * @throws IOException If 'buf' is not empty. */ - protected static void assertEmpty(ByteArrayInputStream buf) throws IOException { - if (buf.available() > 0) { + protected static void assertEmpty(ByteArrayInputStream buf) + throws IOException + { + if (buf.available() > 0) + { throw new TlsFatalAlert(AlertDescription.decode_error); } } - protected static byte[] createRandomBlock(SecureRandom random) { + protected static byte[] createRandomBlock(SecureRandom random) + { byte[] result = new byte[32]; random.nextBytes(result); TlsUtils.writeGMTUnixTime(result, 0); return result; } - protected static byte[] createRenegotiationInfo(byte[] renegotiated_connection) throws IOException { + protected static byte[] createRenegotiationInfo(byte[] renegotiated_connection) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeOpaque8(renegotiated_connection, buf); return buf.toByteArray(); } - protected static void establishMasterSecret(TlsContext context, TlsKeyExchange keyExchange) throws IOException { + protected static void establishMasterSecret(TlsContext context, TlsKeyExchange keyExchange) + throws IOException + { byte[] pre_master_secret = keyExchange.generatePremasterSecret(); - try { + try + { context.getSecurityParameters().masterSecret = TlsUtils.calculateMasterSecret(context, pre_master_secret); - } finally { + } + finally + { // TODO Is there a way to ensure the data is really overwritten? /* * RFC 2246 8.1. The pre_master_secret should be deleted from memory once the * master_secret has been computed. */ - if (pre_master_secret != null) { - Arrays.fill(pre_master_secret, (byte) 0); + if (pre_master_secret != null) + { + Arrays.fill(pre_master_secret, (byte)0); } } } - protected static Hashtable readExtensions(ByteArrayInputStream input) throws IOException { + protected static Hashtable readExtensions(ByteArrayInputStream input) + throws IOException + { - if (input.available() < 1) { + if (input.available() < 1) + { return null; } @@ -693,14 +810,16 @@ public abstract class TlsProtocol { // Integer -> byte[] Hashtable extensions = new Hashtable(); - while (buf.available() > 0) { + while (buf.available() > 0) + { Integer extType = Integers.valueOf(TlsUtils.readUint16(buf)); byte[] extValue = TlsUtils.readOpaque16(buf); /* * RFC 3546 2.3 There MUST NOT be more than one extension of the same type. */ - if (null != extensions.put(extType, extValue)) { + if (null != extensions.put(extType, extValue)) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } @@ -708,7 +827,9 @@ public abstract class TlsProtocol { return extensions; } - protected static Vector readSupplementalDataMessage(ByteArrayInputStream input) throws IOException { + protected static Vector readSupplementalDataMessage(ByteArrayInputStream input) + throws IOException + { byte[] supp_data = TlsUtils.readOpaque24(input); @@ -718,7 +839,8 @@ public abstract class TlsProtocol { Vector supplementalData = new Vector(); - while (buf.available() > 0) { + while (buf.available() > 0) + { int supp_data_type = TlsUtils.readUint16(buf); byte[] data = TlsUtils.readOpaque16(buf); @@ -728,14 +850,17 @@ public abstract class TlsProtocol { return supplementalData; } - protected static void writeExtensions(OutputStream output, Hashtable extensions) throws IOException { + protected static void writeExtensions(OutputStream output, Hashtable extensions) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); Enumeration keys = extensions.keys(); - while (keys.hasMoreElements()) { - Integer extType = (Integer) keys.nextElement(); - byte[] extValue = (byte[]) extensions.get(extType); + while (keys.hasMoreElements()) + { + Integer extType = (Integer)keys.nextElement(); + byte[] extValue = (byte[])extensions.get(extType); TlsUtils.writeUint16(extType.intValue(), buf); TlsUtils.writeOpaque16(extValue, buf); @@ -746,12 +871,15 @@ public abstract class TlsProtocol { TlsUtils.writeOpaque16(extBytes, output); } - protected static void writeSupplementalData(OutputStream output, Vector supplementalData) throws IOException { + protected static void writeSupplementalData(OutputStream output, Vector supplementalData) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); - for (int i = 0; i < supplementalData.size(); ++i) { - SupplementalDataEntry entry = (SupplementalDataEntry) supplementalData.elementAt(i); + for (int i = 0; i < supplementalData.size(); ++i) + { + SupplementalDataEntry entry = (SupplementalDataEntry)supplementalData.elementAt(i); TlsUtils.writeUint16(entry.getDataType(), buf); TlsUtils.writeOpaque16(entry.getData(), buf); @@ -762,9 +890,11 @@ public abstract class TlsProtocol { TlsUtils.writeOpaque24(supp_data, output); } - protected static int getPRFAlgorithm(int ciphersuite) { + protected static int getPRFAlgorithm(int ciphersuite) + { - switch (ciphersuite) { + switch (ciphersuite) + { case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsProtocolHandler.java b/src/main/java/org/bouncycastle/crypto/tls/TlsProtocolHandler.java index ba811590..c4f20e6e 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsProtocolHandler.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsProtocolHandler.java @@ -7,13 +7,17 @@ import java.security.SecureRandom; /** * @deprecated use TlsClientProtocol instead */ -public class TlsProtocolHandler extends TlsClientProtocol { +public class TlsProtocolHandler + extends TlsClientProtocol +{ - public TlsProtocolHandler(InputStream is, OutputStream os) { + public TlsProtocolHandler(InputStream is, OutputStream os) + { super(is, os); } - public TlsProtocolHandler(InputStream is, OutputStream os, SecureRandom sr) { + public TlsProtocolHandler(InputStream is, OutputStream os, SecureRandom sr) + { super(is, os, sr); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsRSAKeyExchange.java b/src/main/java/org/bouncycastle/crypto/tls/TlsRSAKeyExchange.java index d0d4608d..77df98b1 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsRSAKeyExchange.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsRSAKeyExchange.java @@ -15,7 +15,9 @@ import org.bouncycastle.util.io.Streams; /** * TLS 1.0/1.1 and SSLv3 RSA key exchange. */ -public class TlsRSAKeyExchange extends AbstractTlsKeyExchange { +public class TlsRSAKeyExchange + extends AbstractTlsKeyExchange +{ protected AsymmetricKeyParameter serverPublicKey = null; protected RSAKeyParameters rsaServerPublicKey = null; @@ -24,56 +26,73 @@ public class TlsRSAKeyExchange extends AbstractTlsKeyExchange { protected byte[] premasterSecret; - public TlsRSAKeyExchange(Vector supportedSignatureAlgorithms) { + public TlsRSAKeyExchange(Vector supportedSignatureAlgorithms) + { super(KeyExchangeAlgorithm.RSA, supportedSignatureAlgorithms); } - public void skipServerCredentials() throws IOException { + public void skipServerCredentials() + throws IOException + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } - public void processServerCredentials(TlsCredentials serverCredentials) throws IOException { + public void processServerCredentials(TlsCredentials serverCredentials) + throws IOException + { - if (!(serverCredentials instanceof TlsEncryptionCredentials)) { + if (!(serverCredentials instanceof TlsEncryptionCredentials)) + { throw new TlsFatalAlert(AlertDescription.internal_error); } processServerCertificate(serverCredentials.getCertificate()); - this.serverCredentials = (TlsEncryptionCredentials) serverCredentials; + this.serverCredentials = (TlsEncryptionCredentials)serverCredentials; } - public void processServerCertificate(Certificate serverCertificate) throws IOException { + public void processServerCertificate(Certificate serverCertificate) + throws IOException + { - if (serverCertificate.isEmpty()) { + if (serverCertificate.isEmpty()) + { throw new TlsFatalAlert(AlertDescription.bad_certificate); } org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - try { + try + { this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); - } catch (RuntimeException e) { + } + catch (RuntimeException e) + { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } // Sanity check the PublicKeyFactory - if (this.serverPublicKey.isPrivate()) { + if (this.serverPublicKey.isPrivate()) + { throw new TlsFatalAlert(AlertDescription.internal_error); } - this.rsaServerPublicKey = validateRSAPublicKey((RSAKeyParameters) this.serverPublicKey); + this.rsaServerPublicKey = validateRSAPublicKey((RSAKeyParameters)this.serverPublicKey); TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyEncipherment); super.processServerCertificate(serverCertificate); } - public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { + public void validateCertificateRequest(CertificateRequest certificateRequest) + throws IOException + { short[] types = certificateRequest.getCertificateTypes(); - for (int i = 0; i < types.length; ++i) { - switch (types[i]) { + for (int i = 0; i < types.length; ++i) + { + switch (types[i]) + { case ClientCertificateType.rsa_sign: case ClientCertificateType.dss_sign: case ClientCertificateType.ecdsa_sign: @@ -84,23 +103,33 @@ public class TlsRSAKeyExchange extends AbstractTlsKeyExchange { } } - public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { - if (!(clientCredentials instanceof TlsSignerCredentials)) { + public void processClientCredentials(TlsCredentials clientCredentials) + throws IOException + { + if (!(clientCredentials instanceof TlsSignerCredentials)) + { throw new TlsFatalAlert(AlertDescription.internal_error); } } - public void generateClientKeyExchange(OutputStream output) throws IOException { + public void generateClientKeyExchange(OutputStream output) + throws IOException + { this.premasterSecret = TlsRSAUtils.generateEncryptedPreMasterSecret(context, this.rsaServerPublicKey, output); } - public void processClientKeyExchange(InputStream input) throws IOException { + public void processClientKeyExchange(InputStream input) + throws IOException + { byte[] encryptedPreMasterSecret; - if (context.getServerVersion().isSSL()) { + if (context.getServerVersion().isSSL()) + { // TODO Do any SSLv3 clients actually include the length? encryptedPreMasterSecret = Streams.readAll(input); - } else { + } + else + { encryptedPreMasterSecret = TlsUtils.readOpaque16(input); } @@ -121,9 +150,12 @@ public class TlsRSAKeyExchange extends AbstractTlsKeyExchange { this.context.getSecureRandom().nextBytes(R); byte[] M = TlsUtils.EMPTY_BYTES; - try { + try + { M = serverCredentials.decryptPreMasterSecret(encryptedPreMasterSecret); - } catch (Exception e) { + } + catch (Exception e) + { /* * In any case, a TLS server MUST NOT generate an alert if processing an * RSA-encrypted premaster secret message fails, or the version number is not as @@ -132,21 +164,27 @@ public class TlsRSAKeyExchange extends AbstractTlsKeyExchange { */ } - if (M.length != 48) { + if (M.length != 48) + { TlsUtils.writeVersion(clientVersion, R, 0); this.premasterSecret = R; - } else { + } + else + { /* * If ClientHello.client_version is TLS 1.1 or higher, server implementations MUST * check the version number [..]. */ - if (versionNumberCheckDisabled && clientVersion.isEqualOrEarlierVersionOf(ProtocolVersion.TLSv10)) { + if (versionNumberCheckDisabled && clientVersion.isEqualOrEarlierVersionOf(ProtocolVersion.TLSv10)) + { /* * If the version number is TLS 1.0 or earlier, server implementations SHOULD * check the version number, but MAY have a configuration option to disable the * check. */ - } else { + } + else + { /* * Note that explicitly constructing the pre_master_secret with the * ClientHello.client_version produces an invalid master_secret if the client @@ -159,8 +197,11 @@ public class TlsRSAKeyExchange extends AbstractTlsKeyExchange { } } - public byte[] generatePremasterSecret() throws IOException { - if (this.premasterSecret == null) { + public byte[] generatePremasterSecret() + throws IOException + { + if (this.premasterSecret == null) + { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -198,11 +239,14 @@ public class TlsRSAKeyExchange extends AbstractTlsKeyExchange { // exponent)); // } - protected RSAKeyParameters validateRSAPublicKey(RSAKeyParameters key) throws IOException { + protected RSAKeyParameters validateRSAPublicKey(RSAKeyParameters key) + throws IOException + { // TODO What is the minimum bit length required? // key.getModulus().bitLength(); - if (!key.getExponent().isProbablePrime(2)) { + if (!key.getExponent().isProbablePrime(2)) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsRSASigner.java b/src/main/java/org/bouncycastle/crypto/tls/TlsRSASigner.java index 7e90e2d4..d9f7975a 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsRSASigner.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsRSASigner.java @@ -14,9 +14,13 @@ import org.bouncycastle.crypto.signers.GenericSigner; import org.bouncycastle.crypto.signers.RSADigestSigner; import org.bouncycastle.util.Arrays; -public class TlsRSASigner extends AbstractTlsSigner { +public class TlsRSASigner + extends AbstractTlsSigner +{ - public byte[] generateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) throws CryptoException { + public byte[] generateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) + throws CryptoException + { AsymmetricBlockCipher engine = createRSAImpl(); engine.init(true, new ParametersWithRandom(privateKey, this.context.getSecureRandom())); @@ -24,7 +28,8 @@ public class TlsRSASigner extends AbstractTlsSigner { } public boolean verifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1) - throws CryptoException { + throws CryptoException + { AsymmetricBlockCipher engine = createRSAImpl(); engine.init(false, publicKey); @@ -32,28 +37,35 @@ public class TlsRSASigner extends AbstractTlsSigner { return Arrays.constantTimeAreEqual(signed, md5AndSha1); } - public Signer createSigner(AsymmetricKeyParameter privateKey) { + public Signer createSigner(AsymmetricKeyParameter privateKey) + { return makeSigner(new CombinedHash(), true, new ParametersWithRandom(privateKey, this.context.getSecureRandom())); } - public Signer createVerifyer(AsymmetricKeyParameter publicKey) { + public Signer createVerifyer(AsymmetricKeyParameter publicKey) + { return makeSigner(new CombinedHash(), false, publicKey); } - public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) { + public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) + { return publicKey instanceof RSAKeyParameters && !publicKey.isPrivate(); } - protected Signer makeSigner(Digest d, boolean forSigning, CipherParameters cp) { + protected Signer makeSigner(Digest d, boolean forSigning, CipherParameters cp) + { Signer s; - if (ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(context.getServerVersion().getEquivalentTLSVersion())) { + if (ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(context.getServerVersion().getEquivalentTLSVersion())) + { /* * RFC 5246 4.7. In RSA signing, the opaque vector contains the signature generated * using the RSASSA-PKCS1-v1_5 signature scheme defined in [PKCS1]. */ s = new RSADigestSigner(d); - } else { + } + else + { /* * RFC 5246 4.7. Note that earlier versions of TLS used a different RSA signature scheme * that did not include a DigestInfo encoding. @@ -64,7 +76,8 @@ public class TlsRSASigner extends AbstractTlsSigner { return s; } - protected AsymmetricBlockCipher createRSAImpl() { + protected AsymmetricBlockCipher createRSAImpl() + { /* * RFC 5264 7.4.7.1. Implementation note: It is now known that remote timing-based attacks * on TLS are possible, at least when the client and server are on the same LAN. diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java b/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java index 4efe9376..23bdc03f 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java @@ -9,9 +9,12 @@ import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.params.RSAKeyParameters; -public class TlsRSAUtils { +public class TlsRSAUtils +{ public static byte[] generateEncryptedPreMasterSecret(TlsContext context, RSAKeyParameters rsaServerPublicKey, - OutputStream output) throws IOException { + OutputStream output) + throws IOException + { /* * Choose a PremasterSecret and send it encrypted to the server */ @@ -22,16 +25,22 @@ public class TlsRSAUtils { PKCS1Encoding encoding = new PKCS1Encoding(new RSABlindedEngine()); encoding.init(true, new ParametersWithRandom(rsaServerPublicKey, context.getSecureRandom())); - try { + try + { byte[] encryptedPreMasterSecret = encoding.processBlock(premasterSecret, 0, premasterSecret.length); - if (context.getServerVersion().isSSL()) { + if (context.getServerVersion().isSSL()) + { // TODO Do any SSLv3 servers actually expect the length? output.write(encryptedPreMasterSecret); - } else { + } + else + { TlsUtils.writeOpaque16(encryptedPreMasterSecret, output); } - } catch (InvalidCipherTextException e) { + } + catch (InvalidCipherTextException e) + { /* * This should never happen, only during decryption. */ diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsRuntimeException.java b/src/main/java/org/bouncycastle/crypto/tls/TlsRuntimeException.java index b5160357..3340e490 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsRuntimeException.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsRuntimeException.java @@ -1,6 +1,7 @@ package org.bouncycastle.crypto.tls; -public class TlsRuntimeException extends RuntimeException +public class TlsRuntimeException + extends RuntimeException { private static final long serialVersionUID = 1928023487348344086L; diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsSRPKeyExchange.java b/src/main/java/org/bouncycastle/crypto/tls/TlsSRPKeyExchange.java index 946239a3..51fcc999 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsSRPKeyExchange.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsSRPKeyExchange.java @@ -21,7 +21,9 @@ import org.bouncycastle.util.BigIntegers; /** * TLS 1.1 SRP key exchange (RFC 5054). */ -public class TlsSRPKeyExchange extends AbstractTlsKeyExchange { +public class TlsSRPKeyExchange + extends AbstractTlsKeyExchange +{ protected TlsSigner tlsSigner; protected byte[] identity; @@ -33,11 +35,13 @@ public class TlsSRPKeyExchange extends AbstractTlsKeyExchange { protected BigInteger B = null; protected SRP6Client srpClient = new SRP6Client(); - public TlsSRPKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, byte[] identity, byte[] password) { + public TlsSRPKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, byte[] identity, byte[] password) + { super(keyExchange, supportedSignatureAlgorithms); - switch (keyExchange) { + switch (keyExchange) + { case KeyExchangeAlgorithm.SRP: this.tlsSigner = null; break; @@ -56,39 +60,52 @@ public class TlsSRPKeyExchange extends AbstractTlsKeyExchange { this.password = password; } - public void init(TlsContext context) { + public void init(TlsContext context) + { super.init(context); - if (this.tlsSigner != null) { + if (this.tlsSigner != null) + { this.tlsSigner.init(context); } } - public void skipServerCredentials() throws IOException { - if (tlsSigner != null) { + public void skipServerCredentials() + throws IOException + { + if (tlsSigner != null) + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } - public void processServerCertificate(Certificate serverCertificate) throws IOException { + public void processServerCertificate(Certificate serverCertificate) + throws IOException + { - if (tlsSigner == null) { + if (tlsSigner == null) + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } - if (serverCertificate.isEmpty()) { + if (serverCertificate.isEmpty()) + { throw new TlsFatalAlert(AlertDescription.bad_certificate); } org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - try { + try + { this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); - } catch (RuntimeException e) { + } + catch (RuntimeException e) + { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } - if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) { + if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) + { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } @@ -97,18 +114,22 @@ public class TlsSRPKeyExchange extends AbstractTlsKeyExchange { super.processServerCertificate(serverCertificate); } - public boolean requiresServerKeyExchange() { + public boolean requiresServerKeyExchange() + { return true; } - public void processServerKeyExchange(InputStream input) throws IOException { + public void processServerKeyExchange(InputStream input) + throws IOException + { SecurityParameters securityParameters = context.getSecurityParameters(); InputStream sigIn = input; Signer signer = null; - if (tlsSigner != null) { + if (tlsSigner != null) + { signer = initVerifyer(tlsSigner, securityParameters); sigIn = new SignerInputStream(input, signer); } @@ -118,10 +139,12 @@ public class TlsSRPKeyExchange extends AbstractTlsKeyExchange { byte[] sBytes = TlsUtils.readOpaque8(sigIn); byte[] BBytes = TlsUtils.readOpaque16(sigIn); - if (signer != null) { + if (signer != null) + { byte[] sigByte = TlsUtils.readOpaque16(input); - if (!signer.verifySignature(sigByte)) { + if (!signer.verifySignature(sigByte)) + { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } @@ -138,39 +161,54 @@ public class TlsSRPKeyExchange extends AbstractTlsKeyExchange { * RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter" alert if * B % N = 0. */ - try { + try + { this.B = SRP6Util.validatePublicValue(N, new BigInteger(1, BBytes)); - } catch (CryptoException e) { + } + catch (CryptoException e) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } this.srpClient.init(N, g, new SHA1Digest(), context.getSecureRandom()); } - public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException { + public void validateCertificateRequest(CertificateRequest certificateRequest) + throws IOException + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } - public void processClientCredentials(TlsCredentials clientCredentials) throws IOException { + public void processClientCredentials(TlsCredentials clientCredentials) + throws IOException + { throw new TlsFatalAlert(AlertDescription.internal_error); } - public void generateClientKeyExchange(OutputStream output) throws IOException { + public void generateClientKeyExchange(OutputStream output) + throws IOException + { byte[] keData = BigIntegers.asUnsignedByteArray(srpClient.generateClientCredentials(s, this.identity, this.password)); TlsUtils.writeOpaque16(keData, output); } - public byte[] generatePremasterSecret() throws IOException { - try { + public byte[] generatePremasterSecret() + throws IOException + { + try + { // TODO Check if this needs to be a fixed size return BigIntegers.asUnsignedByteArray(srpClient.calculateSecret(B)); - } catch (CryptoException e) { + } + catch (CryptoException e) + { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } - protected Signer initVerifyer(TlsSigner tlsSigner, SecurityParameters securityParameters) { + protected Signer initVerifyer(TlsSigner tlsSigner, SecurityParameters securityParameters) + { Signer signer = tlsSigner.createVerifyer(this.serverPublicKey); signer.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); signer.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsSRTPUtils.java b/src/main/java/org/bouncycastle/crypto/tls/TlsSRTPUtils.java index 8bd873c3..45575dac 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsSRTPUtils.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsSRTPUtils.java @@ -10,31 +10,40 @@ import org.bouncycastle.util.Integers; /** * RFC 5764 DTLS Extension to Establish Keys for SRTP. */ -public class TlsSRTPUtils { +public class TlsSRTPUtils +{ public static final Integer EXT_use_srtp = Integers.valueOf(ExtensionType.use_srtp); public static void addUseSRTPExtension(Hashtable extensions, UseSRTPData useSRTPData) - throws IOException { + throws IOException + { extensions.put(EXT_use_srtp, createUseSRTPExtension(useSRTPData)); } - public static UseSRTPData getUseSRTPExtension(Hashtable extensions) throws IOException { + public static UseSRTPData getUseSRTPExtension(Hashtable extensions) + throws IOException + { - if (extensions == null) { + if (extensions == null) + { return null; } - byte[] extensionValue = (byte[]) extensions.get(EXT_use_srtp); - if (extensionValue == null) { + byte[] extensionValue = (byte[])extensions.get(EXT_use_srtp); + if (extensionValue == null) + { return null; } return readUseSRTPExtension(extensionValue); } - public static byte[] createUseSRTPExtension(UseSRTPData useSRTPData) throws IOException { + public static byte[] createUseSRTPExtension(UseSRTPData useSRTPData) + throws IOException + { - if (useSRTPData == null) { + if (useSRTPData == null) + { throw new IllegalArgumentException("'useSRTPData' cannot be null"); } @@ -51,9 +60,12 @@ public class TlsSRTPUtils { return buf.toByteArray(); } - public static UseSRTPData readUseSRTPExtension(byte[] extensionValue) throws IOException { + public static UseSRTPData readUseSRTPExtension(byte[] extensionValue) + throws IOException + { - if (extensionValue == null) { + if (extensionValue == null) + { throw new IllegalArgumentException("'extensionValue' cannot be null"); } @@ -61,7 +73,8 @@ public class TlsSRTPUtils { // SRTPProtectionProfiles int length = TlsUtils.readUint16(buf); - if (length < 2 || (length & 1) != 0) { + if (length < 2 || (length & 1) != 0) + { throw new TlsFatalAlert(AlertDescription.decode_error); } int[] protectionProfiles = TlsUtils.readUint16Array(length / 2, buf); diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsServer.java b/src/main/java/org/bouncycastle/crypto/tls/TlsServer.java index 96a98ff9..888c70a8 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsServer.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsServer.java @@ -4,67 +4,86 @@ import java.io.IOException; import java.util.Hashtable; import java.util.Vector; -public interface TlsServer extends TlsPeer { +public interface TlsServer + extends TlsPeer +{ void init(TlsServerContext context); - void notifyClientVersion(ProtocolVersion clientVersion) throws IOException; + void notifyClientVersion(ProtocolVersion clientVersion) + throws IOException; - void notifyOfferedCipherSuites(int[] offeredCipherSuites) throws IOException; + void notifyOfferedCipherSuites(int[] offeredCipherSuites) + throws IOException; - void notifyOfferedCompressionMethods(short[] offeredCompressionMethods) throws IOException; + void notifyOfferedCompressionMethods(short[] offeredCompressionMethods) + throws IOException; - void notifySecureRenegotiation(boolean secureNegotiation) throws IOException; + void notifySecureRenegotiation(boolean secureNegotiation) + throws IOException; // Hashtable is (Integer -> byte[]) - void processClientExtensions(Hashtable clientExtensions) throws IOException; + void processClientExtensions(Hashtable clientExtensions) + throws IOException; - ProtocolVersion getServerVersion() throws IOException; + ProtocolVersion getServerVersion() + throws IOException; - int getSelectedCipherSuite() throws IOException; + int getSelectedCipherSuite() + throws IOException; - short getSelectedCompressionMethod() throws IOException; + short getSelectedCompressionMethod() + throws IOException; // Hashtable is (Integer -> byte[]) - Hashtable getServerExtensions() throws IOException; + Hashtable getServerExtensions() + throws IOException; // Vector is (SupplementalDataEntry) - Vector getServerSupplementalData() throws IOException; + Vector getServerSupplementalData() + throws IOException; - TlsCredentials getCredentials() throws IOException; + TlsCredentials getCredentials() + throws IOException; - TlsKeyExchange getKeyExchange() throws IOException; + TlsKeyExchange getKeyExchange() + throws IOException; CertificateRequest getCertificateRequest(); // Vector is (SupplementalDataEntry) - void processClientSupplementalData(Vector clientSupplementalData) throws IOException; + void processClientSupplementalData(Vector clientSupplementalData) + throws IOException; /** * Called by the protocol handler to report the client certificate, only if a Certificate * {@link #getCertificateRequest()} returned non-null. Note: this method is responsible for * certificate verification and validation. - * - * @param clientCertificate - * the effective client certificate (may be an empty chain). + * + * @param clientCertificate the effective client certificate (may be an empty chain). * @throws IOException */ - void notifyClientCertificate(Certificate clientCertificate) throws IOException; + void notifyClientCertificate(Certificate clientCertificate) + throws IOException; - TlsCompression getCompression() throws IOException; + TlsCompression getCompression() + throws IOException; - TlsCipher getCipher() throws IOException; + TlsCipher getCipher() + throws IOException; /** * RFC 5077 3.3. NewSessionTicket Handshake Message. - *

+ *

* This method will be called (only) if a NewSessionTicket extension was sent by the server. See * RFC 5077 4. Recommended Ticket Construction for recommended format and protection. - * + * * @return The ticket. * @throws IOException */ - NewSessionTicket getNewSessionTicket() throws IOException; + NewSessionTicket getNewSessionTicket() + throws IOException; - void notifyHandshakeComplete() throws IOException; + void notifyHandshakeComplete() + throws IOException; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsServerContext.java b/src/main/java/org/bouncycastle/crypto/tls/TlsServerContext.java index af3c2b96..f4f50897 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsServerContext.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsServerContext.java @@ -1,4 +1,6 @@ package org.bouncycastle.crypto.tls; -public interface TlsServerContext extends TlsContext { +public interface TlsServerContext + extends TlsContext +{ } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsServerContextImpl.java b/src/main/java/org/bouncycastle/crypto/tls/TlsServerContextImpl.java index bb442956..91705362 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsServerContextImpl.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsServerContextImpl.java @@ -2,13 +2,18 @@ package org.bouncycastle.crypto.tls; import java.security.SecureRandom; -class TlsServerContextImpl extends AbstractTlsContext implements TlsServerContext { +class TlsServerContextImpl + extends AbstractTlsContext + implements TlsServerContext +{ - TlsServerContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) { + TlsServerContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) + { super(secureRandom, securityParameters); } - public boolean isServer() { + public boolean isServer() + { return true; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsServerProtocol.java b/src/main/java/org/bouncycastle/crypto/tls/TlsServerProtocol.java index b26e5b33..4c0cec03 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsServerProtocol.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsServerProtocol.java @@ -14,7 +14,9 @@ import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.util.Arrays; -public class TlsServerProtocol extends TlsProtocol { +public class TlsServerProtocol + extends TlsProtocol +{ protected TlsServer tlsServer = null; protected TlsServerContextImpl tlsServerContext = null; @@ -35,23 +37,27 @@ public class TlsServerProtocol extends TlsProtocol { protected Certificate clientCertificate = null; protected byte[] certificateVerifyHash = null; - public TlsServerProtocol(InputStream input, OutputStream output, SecureRandom secureRandom) { + public TlsServerProtocol(InputStream input, OutputStream output, SecureRandom secureRandom) + { super(input, output, secureRandom); } /** * Receives a TLS handshake in the role of server - * + * * @param tlsServer - * @throws IOException - * If handshake was not successful. + * @throws IOException If handshake was not successful. */ - public void accept(TlsServer tlsServer) throws IOException { + public void accept(TlsServer tlsServer) + throws IOException + { - if (tlsServer == null) { + if (tlsServer == null) + { throw new IllegalArgumentException("'tlsServer' cannot be null"); } - if (this.tlsServer != null) { + if (this.tlsServer != null) + { throw new IllegalStateException("accept can only be called once"); } @@ -72,41 +78,56 @@ public class TlsServerProtocol extends TlsProtocol { this.tlsServer.notifyHandshakeComplete(); } - protected AbstractTlsContext getContext() { + protected AbstractTlsContext getContext() + { return tlsServerContext; } - protected TlsPeer getPeer() { + protected TlsPeer getPeer() + { return tlsServer; } - protected void handleChangeCipherSpecMessage() throws IOException { + protected void handleChangeCipherSpecMessage() + throws IOException + { - switch (this.connection_state) { - case CS_CLIENT_KEY_EXCHANGE: { - if (this.certificateVerifyHash != null) { + switch (this.connection_state) + { + case CS_CLIENT_KEY_EXCHANGE: + { + if (this.certificateVerifyHash != null) + { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } // NB: Fall through to next case label } - case CS_CERTIFICATE_VERIFY: { + case CS_CERTIFICATE_VERIFY: + { this.connection_state = CS_CLIENT_CHANGE_CIPHER_SPEC; break; } - default: { + default: + { this.failWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } } } - protected void handleHandshakeMessage(short type, byte[] data) throws IOException { + protected void handleHandshakeMessage(short type, byte[] data) + throws IOException + { ByteArrayInputStream buf = new ByteArrayInputStream(data); - switch (type) { - case HandshakeType.client_hello: { - switch (this.connection_state) { - case CS_START: { + switch (type) + { + case HandshakeType.client_hello: + { + switch (this.connection_state) + { + case CS_START: + { receiveClientHelloMessage(buf); this.connection_state = CS_CLIENT_HELLO; @@ -129,7 +150,8 @@ public class TlsServerProtocol extends TlsProtocol { } Vector serverSupplementalData = tlsServer.getServerSupplementalData(); - if (serverSupplementalData != null) { + if (serverSupplementalData != null) + { sendSupplementalDataMessage(serverSupplementalData); } this.connection_state = CS_SERVER_SUPPLEMENTAL_DATA; @@ -138,23 +160,29 @@ public class TlsServerProtocol extends TlsProtocol { this.keyExchange.init(getContext()); this.serverCredentials = tlsServer.getCredentials(); - if (this.serverCredentials == null) { + if (this.serverCredentials == null) + { this.keyExchange.skipServerCredentials(); - } else { + } + else + { this.keyExchange.processServerCredentials(this.serverCredentials); sendCertificateMessage(this.serverCredentials.getCertificate()); } this.connection_state = CS_SERVER_CERTIFICATE; byte[] serverKeyExchange = this.keyExchange.generateServerKeyExchange(); - if (serverKeyExchange != null) { + if (serverKeyExchange != null) + { sendServerKeyExchangeMessage(serverKeyExchange); } this.connection_state = CS_SERVER_KEY_EXCHANGE; - if (this.serverCredentials != null) { + if (this.serverCredentials != null) + { this.certificateRequest = tlsServer.getCertificateRequest(); - if (this.certificateRequest != null) { + if (this.certificateRequest != null) + { this.keyExchange.validateCertificateRequest(certificateRequest); sendCertificateRequestMessage(certificateRequest); } @@ -166,59 +194,78 @@ public class TlsServerProtocol extends TlsProtocol { break; } - default: { + default: + { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } break; } - case HandshakeType.supplemental_data: { - switch (this.connection_state) { - case CS_SERVER_HELLO_DONE: { + case HandshakeType.supplemental_data: + { + switch (this.connection_state) + { + case CS_SERVER_HELLO_DONE: + { tlsServer.processClientSupplementalData(readSupplementalDataMessage(buf)); this.connection_state = CS_CLIENT_SUPPLEMENTAL_DATA; break; } - default: { + default: + { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } break; } - case HandshakeType.certificate: { - switch (this.connection_state) { - case CS_SERVER_HELLO_DONE: { + case HandshakeType.certificate: + { + switch (this.connection_state) + { + case CS_SERVER_HELLO_DONE: + { tlsServer.processClientSupplementalData(null); // NB: Fall through to next case label } - case CS_CLIENT_SUPPLEMENTAL_DATA: { - if (this.certificateRequest == null) { + case CS_CLIENT_SUPPLEMENTAL_DATA: + { + if (this.certificateRequest == null) + { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } receiveCertificateMessage(buf); this.connection_state = CS_CLIENT_CERTIFICATE; break; } - default: { + default: + { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } break; } - case HandshakeType.client_key_exchange: { - switch (this.connection_state) { - case CS_SERVER_HELLO_DONE: { + case HandshakeType.client_key_exchange: + { + switch (this.connection_state) + { + case CS_SERVER_HELLO_DONE: + { tlsServer.processClientSupplementalData(null); // NB: Fall through to next case label } - case CS_CLIENT_SUPPLEMENTAL_DATA: { - if (this.certificateRequest == null) { + case CS_CLIENT_SUPPLEMENTAL_DATA: + { + if (this.certificateRequest == null) + { this.keyExchange.skipClientCredentials(); - } else { + } + else + { ProtocolVersion equivalentTLSVersion = getContext().getServerVersion().getEquivalentTLSVersion(); - if (ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(equivalentTLSVersion)) { + if (ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(equivalentTLSVersion)) + { /* * RFC 5246 If no suitable certificate is available, the client MUST send a * certificate message containing no certificates. @@ -226,55 +273,70 @@ public class TlsServerProtocol extends TlsProtocol { * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); - } else if (equivalentTLSVersion.isSSL()) { - if (clientCertificate == null) { + } + else if (equivalentTLSVersion.isSSL()) + { + if (clientCertificate == null) + { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } - } else { + } + else + { notifyClientCertificate(Certificate.EMPTY_CHAIN); } } // NB: Fall through to next case label } - case CS_CLIENT_CERTIFICATE: { + case CS_CLIENT_CERTIFICATE: + { receiveClientKeyExchangeMessage(buf); this.connection_state = CS_CLIENT_KEY_EXCHANGE; break; } - default: { + default: + { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } break; } - case HandshakeType.certificate_verify: { - switch (this.connection_state) { - case CS_CLIENT_KEY_EXCHANGE: { + case HandshakeType.certificate_verify: + { + switch (this.connection_state) + { + case CS_CLIENT_KEY_EXCHANGE: + { /* * RFC 5246 7.4.8 This message is only sent following a client certificate that has * signing capability (i.e., all certificates except those containing fixed * Diffie-Hellman parameters). */ - if (this.certificateVerifyHash == null) { + if (this.certificateVerifyHash == null) + { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } receiveCertificateVerifyMessage(buf); this.connection_state = CS_CERTIFICATE_VERIFY; break; } - default: { + default: + { this.failWithError(AlertLevel.fatal, AlertDescription.unexpected_message); } } break; } - case HandshakeType.finished: { - switch (this.connection_state) { + case HandshakeType.finished: + { + switch (this.connection_state) + { case CS_CLIENT_CHANGE_CIPHER_SPEC: processFinishedMessage(buf); this.connection_state = CS_CLIENT_FINISHED; - if (expectSessionTicket) { + if (expectSessionTicket) + { sendNewSessionTicketMessage(tlsServer.getNewSessionTicket()); } this.connection_state = CS_SERVER_SESSION_TICKET; @@ -304,39 +366,52 @@ public class TlsServerProtocol extends TlsProtocol { } } - protected void handleWarningMessage(short description) throws IOException { - switch (description) { - case AlertDescription.no_certificate: { + protected void handleWarningMessage(short description) + throws IOException + { + switch (description) + { + case AlertDescription.no_certificate: + { /* * SSL 3.0 If the server has sent a certificate request Message, the client must send * either the certificate message or a no_certificate alert. */ - if (getContext().getServerVersion().isSSL() && certificateRequest != null) { + if (getContext().getServerVersion().isSSL() && certificateRequest != null) + { notifyClientCertificate(Certificate.EMPTY_CHAIN); } break; } - default: { + default: + { super.handleWarningMessage(description); } } } - protected void notifyClientCertificate(Certificate clientCertificate) throws IOException { + protected void notifyClientCertificate(Certificate clientCertificate) + throws IOException + { - if (certificateRequest == null) { + if (certificateRequest == null) + { throw new IllegalStateException(); } - if (this.clientCertificate != null) { + if (this.clientCertificate != null) + { throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.clientCertificate = clientCertificate; - if (clientCertificate.isEmpty()) { + if (clientCertificate.isEmpty()) + { this.keyExchange.skipClientCredentials(); - } else { + } + else + { /* * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request @@ -361,7 +436,9 @@ public class TlsServerProtocol extends TlsProtocol { this.tlsServer.notifyClientCertificate(clientCertificate); } - protected void receiveCertificateMessage(ByteArrayInputStream buf) throws IOException { + protected void receiveCertificateMessage(ByteArrayInputStream buf) + throws IOException + { Certificate clientCertificate = Certificate.parse(buf); @@ -370,14 +447,17 @@ public class TlsServerProtocol extends TlsProtocol { notifyClientCertificate(clientCertificate); } - protected void receiveCertificateVerifyMessage(ByteArrayInputStream buf) throws IOException { + protected void receiveCertificateVerifyMessage(ByteArrayInputStream buf) + throws IOException + { byte[] clientCertificateSignature = TlsUtils.readOpaque16(buf); assertEmpty(buf); // Verify the CertificateVerify message contains a correct signature. - try { + try + { TlsSigner tlsSigner = TlsUtils.createTlsSigner(this.clientCertificateType); tlsSigner.init(getContext()); @@ -386,15 +466,20 @@ public class TlsServerProtocol extends TlsProtocol { AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(keyInfo); tlsSigner.verifyRawSignature(clientCertificateSignature, publicKey, this.certificateVerifyHash); - } catch (Exception e) { + } + catch (Exception e) + { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } - protected void receiveClientHelloMessage(ByteArrayInputStream buf) throws IOException { + protected void receiveClientHelloMessage(ByteArrayInputStream buf) + throws IOException + { ProtocolVersion client_version = TlsUtils.readVersion(buf); - if (client_version.isDTLS()) { + if (client_version.isDTLS()) + { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } @@ -404,12 +489,14 @@ public class TlsServerProtocol extends TlsProtocol { byte[] client_random = TlsUtils.readFully(32, buf); byte[] sessionID = TlsUtils.readOpaque8(buf); - if (sessionID.length > 32) { + if (sessionID.length > 32) + { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } int cipher_suites_length = TlsUtils.readUint16(buf); - if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0) { + if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0) + { this.failWithError(AlertLevel.fatal, AlertDescription.decode_error); } @@ -420,7 +507,8 @@ public class TlsServerProtocol extends TlsProtocol { this.offeredCipherSuites = TlsUtils.readUint16Array(cipher_suites_length / 2, buf); int compression_methods_length = TlsUtils.readUint8(buf); - if (compression_methods_length < 1) { + if (compression_methods_length < 1) + { this.failWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } @@ -457,7 +545,8 @@ public class TlsServerProtocol extends TlsProtocol { * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag * to TRUE. */ - if (arrayContains(offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) { + if (arrayContains(offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) + { this.secure_renegotiation = true; } @@ -465,9 +554,11 @@ public class TlsServerProtocol extends TlsProtocol { * The server MUST check if the "renegotiation_info" extension is included in the * ClientHello. */ - if (clientExtensions != null) { - byte[] renegExtValue = (byte[]) clientExtensions.get(EXT_RenegotiationInfo); - if (renegExtValue != null) { + if (clientExtensions != null) + { + byte[] renegExtValue = (byte[])clientExtensions.get(EXT_RenegotiationInfo); + if (renegExtValue != null) + { /* * If the extension is present, set secure_renegotiation flag to TRUE. The * server MUST then verify that the length of the "renegotiated_connection" @@ -475,7 +566,8 @@ public class TlsServerProtocol extends TlsProtocol { */ this.secure_renegotiation = true; - if (!Arrays.constantTimeAreEqual(renegExtValue, createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) { + if (!Arrays.constantTimeAreEqual(renegExtValue, createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) + { this.failWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } } @@ -484,12 +576,15 @@ public class TlsServerProtocol extends TlsProtocol { tlsServer.notifySecureRenegotiation(this.secure_renegotiation); - if (clientExtensions != null) { + if (clientExtensions != null) + { tlsServer.processClientExtensions(clientExtensions); } } - protected void receiveClientKeyExchangeMessage(ByteArrayInputStream buf) throws IOException { + protected void receiveClientKeyExchangeMessage(ByteArrayInputStream buf) + throws IOException + { this.keyExchange.processClientKeyExchange(buf); @@ -502,12 +597,15 @@ public class TlsServerProtocol extends TlsProtocol { */ recordStream.setPendingConnectionState(tlsServer.getCompression(), tlsServer.getCipher()); - if (expectCertificateVerifyMessage()) { + if (expectCertificateVerifyMessage()) + { this.certificateVerifyHash = recordStream.getCurrentHash(null); } } - protected void sendCertificateRequestMessage(CertificateRequest certificateRequest) throws IOException { + protected void sendCertificateRequestMessage(CertificateRequest certificateRequest) + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.certificate_request, buf); @@ -524,9 +622,12 @@ public class TlsServerProtocol extends TlsProtocol { safeWriteRecord(ContentType.handshake, message, 0, message.length); } - protected void sendNewSessionTicketMessage(NewSessionTicket newSessionTicket) throws IOException { + protected void sendNewSessionTicketMessage(NewSessionTicket newSessionTicket) + throws IOException + { - if (newSessionTicket == null) { + if (newSessionTicket == null) + { throw new TlsFatalAlert(AlertDescription.internal_error); } @@ -545,7 +646,9 @@ public class TlsServerProtocol extends TlsProtocol { safeWriteRecord(ContentType.handshake, message, 0, message.length); } - protected void sendServerHelloMessage() throws IOException { + protected void sendServerHelloMessage() + throws IOException + { ByteArrayOutputStream buf = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.server_hello, buf); @@ -554,7 +657,8 @@ public class TlsServerProtocol extends TlsProtocol { TlsUtils.writeUint24(0, buf); ProtocolVersion server_version = tlsServer.getServerVersion(); - if (!server_version.isEqualOrEarlierVersionOf(getContext().getClientVersion())) { + if (!server_version.isEqualOrEarlierVersionOf(getContext().getClientVersion())) + { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } @@ -576,12 +680,14 @@ public class TlsServerProtocol extends TlsProtocol { this.selectedCipherSuite = tlsServer.getSelectedCipherSuite(); if (!arrayContains(this.offeredCipherSuites, this.selectedCipherSuite) || this.selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL - || this.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { + || this.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) + { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } this.selectedCompressionMethod = tlsServer.getSelectedCompressionMethod(); - if (!arrayContains(this.offeredCompressionMethods, this.selectedCompressionMethod)) { + if (!arrayContains(this.offeredCompressionMethods, this.selectedCompressionMethod)) + { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } @@ -593,12 +699,14 @@ public class TlsServerProtocol extends TlsProtocol { /* * RFC 5746 3.6. Server Behavior: Initial Handshake */ - if (this.secure_renegotiation) { + if (this.secure_renegotiation) + { boolean noRenegExt = this.serverExtensions == null || !this.serverExtensions.containsKey(EXT_RenegotiationInfo); - if (noRenegExt) { + if (noRenegExt) + { /* * Note that sending a "renegotiation_info" extension in response to a ClientHello * containing only the SCSV is an explicit exception to the prohibition in RFC 5246, @@ -606,7 +714,8 @@ public class TlsServerProtocol extends TlsProtocol { * because the client is signaling its willingness to receive the extension via the * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. */ - if (this.serverExtensions == null) { + if (this.serverExtensions == null) + { this.serverExtensions = new Hashtable(); } @@ -618,7 +727,8 @@ public class TlsServerProtocol extends TlsProtocol { } } - if (this.serverExtensions != null) { + if (this.serverExtensions != null) + { this.expectSessionTicket = serverExtensions.containsKey(EXT_SessionTicket); writeExtensions(buf, this.serverExtensions); } @@ -631,7 +741,9 @@ public class TlsServerProtocol extends TlsProtocol { safeWriteRecord(ContentType.handshake, message, 0, message.length); } - protected void sendServerHelloDoneMessage() throws IOException { + protected void sendServerHelloDoneMessage() + throws IOException + { byte[] message = new byte[4]; TlsUtils.writeUint8(HandshakeType.server_hello_done, message, 0); @@ -640,7 +752,9 @@ public class TlsServerProtocol extends TlsProtocol { safeWriteRecord(ContentType.handshake, message, 0, message.length); } - protected void sendServerKeyExchangeMessage(byte[] serverKeyExchange) throws IOException { + protected void sendServerKeyExchangeMessage(byte[] serverKeyExchange) + throws IOException + { ByteArrayOutputStream bos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HandshakeType.server_key_exchange, bos); @@ -651,7 +765,8 @@ public class TlsServerProtocol extends TlsProtocol { safeWriteRecord(ContentType.handshake, message, 0, message.length); } - protected boolean expectCertificateVerifyMessage() { + protected boolean expectCertificateVerifyMessage() + { return this.clientCertificateType >= 0 && TlsUtils.hasSigningCapability(this.clientCertificateType); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsSigner.java b/src/main/java/org/bouncycastle/crypto/tls/TlsSigner.java index f3ec0489..2b615076 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsSigner.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsSigner.java @@ -4,11 +4,13 @@ import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -public interface TlsSigner { +public interface TlsSigner +{ void init(TlsContext context); - byte[] generateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) throws CryptoException; + byte[] generateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) + throws CryptoException; boolean verifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1) throws CryptoException; diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsSignerCredentials.java b/src/main/java/org/bouncycastle/crypto/tls/TlsSignerCredentials.java index f0e5ac93..7067fa21 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsSignerCredentials.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsSignerCredentials.java @@ -2,7 +2,9 @@ package org.bouncycastle.crypto.tls; import java.io.IOException; -public interface TlsSignerCredentials extends TlsCredentials +public interface TlsSignerCredentials + extends TlsCredentials { - byte[] generateCertificateSignature(byte[] md5andsha1) throws IOException; + byte[] generateCertificateSignature(byte[] md5andsha1) + throws IOException; } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsStreamCipher.java b/src/main/java/org/bouncycastle/crypto/tls/TlsStreamCipher.java index a6c838ff..dae49b6f 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsStreamCipher.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsStreamCipher.java @@ -8,7 +8,9 @@ import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.util.Arrays; -public class TlsStreamCipher implements TlsCipher { +public class TlsStreamCipher + implements TlsCipher +{ protected TlsContext context; protected StreamCipher encryptCipher; @@ -18,8 +20,10 @@ public class TlsStreamCipher implements TlsCipher { protected TlsMac readMac; public TlsStreamCipher(TlsContext context, StreamCipher clientWriteCipher, - StreamCipher serverWriteCipher, Digest clientWriteDigest, Digest serverWriteDigest, - int cipherKeySize) throws IOException { + StreamCipher serverWriteCipher, Digest clientWriteDigest, Digest serverWriteDigest, + int cipherKeySize) + throws IOException + { boolean isServer = context.isServer(); @@ -49,19 +53,23 @@ public class TlsStreamCipher implements TlsCipher { KeyParameter serverWriteKey = new KeyParameter(key_block, offset, cipherKeySize); offset += cipherKeySize; - if (offset != key_block_size) { + if (offset != key_block_size) + { throw new TlsFatalAlert(AlertDescription.internal_error); } CipherParameters encryptParams, decryptParams; - if (isServer) { + if (isServer) + { this.writeMac = serverWriteMac; this.readMac = clientWriteMac; this.encryptCipher = serverWriteCipher; this.decryptCipher = clientWriteCipher; encryptParams = serverWriteKey; decryptParams = clientWriteKey; - } else { + } + else + { this.writeMac = clientWriteMac; this.readMac = serverWriteMac; this.encryptCipher = clientWriteCipher; @@ -74,11 +82,13 @@ public class TlsStreamCipher implements TlsCipher { this.decryptCipher.init(false, decryptParams); } - public int getPlaintextLimit(int ciphertextLimit) { + public int getPlaintextLimit(int ciphertextLimit) + { return ciphertextLimit - writeMac.getSize(); } - public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) { + public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) + { byte[] mac = writeMac.calculateMac(seqNo, type, plaintext, offset, len); byte[] outbuf = new byte[len + mac.length]; @@ -90,9 +100,11 @@ public class TlsStreamCipher implements TlsCipher { } public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) - throws IOException { + throws IOException + { int macSize = readMac.getSize(); - if (len < macSize) { + if (len < macSize) + { throw new TlsFatalAlert(AlertDescription.decode_error); } @@ -104,7 +116,8 @@ public class TlsStreamCipher implements TlsCipher { byte[] receivedMac = Arrays.copyOfRange(deciphered, macInputLen, len); byte[] computedMac = readMac.calculateMac(seqNo, type, deciphered, 0, macInputLen); - if (!Arrays.constantTimeAreEqual(receivedMac, computedMac)) { + if (!Arrays.constantTimeAreEqual(receivedMac, computedMac)) + { throw new TlsFatalAlert(AlertDescription.bad_record_mac); } diff --git a/src/main/java/org/bouncycastle/crypto/tls/TlsUtils.java b/src/main/java/org/bouncycastle/crypto/tls/TlsUtils.java index e5219768..5f850f76 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/TlsUtils.java +++ b/src/main/java/org/bouncycastle/crypto/tls/TlsUtils.java @@ -74,7 +74,8 @@ public class TlsUtils return true; } - public static void writeUint8(short i, OutputStream output) throws IOException + public static void writeUint8(short i, OutputStream output) + throws IOException { output.write(i); } @@ -84,7 +85,8 @@ public class TlsUtils buf[offset] = (byte)i; } - public static void writeUint16(int i, OutputStream output) throws IOException + public static void writeUint16(int i, OutputStream output) + throws IOException { output.write(i >> 8); output.write(i); @@ -96,7 +98,8 @@ public class TlsUtils buf[offset + 1] = (byte)i; } - public static void writeUint24(int i, OutputStream output) throws IOException + public static void writeUint24(int i, OutputStream output) + throws IOException { output.write(i >> 16); output.write(i >> 8); @@ -110,7 +113,8 @@ public class TlsUtils buf[offset + 2] = (byte)(i); } - public static void writeUint32(long i, OutputStream output) throws IOException + public static void writeUint32(long i, OutputStream output) + throws IOException { output.write((int)(i >> 24)); output.write((int)(i >> 16)); @@ -136,7 +140,8 @@ public class TlsUtils buf[offset + 5] = (byte)(i); } - public static void writeUint64(long i, OutputStream output) throws IOException + public static void writeUint64(long i, OutputStream output) + throws IOException { output.write((int)(i >> 56)); output.write((int)(i >> 48)); @@ -160,25 +165,29 @@ public class TlsUtils buf[offset + 7] = (byte)(i); } - public static void writeOpaque8(byte[] buf, OutputStream output) throws IOException + public static void writeOpaque8(byte[] buf, OutputStream output) + throws IOException { writeUint8((short)buf.length, output); output.write(buf); } - public static void writeOpaque16(byte[] buf, OutputStream output) throws IOException + public static void writeOpaque16(byte[] buf, OutputStream output) + throws IOException { writeUint16(buf.length, output); output.write(buf); } - public static void writeOpaque24(byte[] buf, OutputStream output) throws IOException + public static void writeOpaque24(byte[] buf, OutputStream output) + throws IOException { writeUint24(buf.length, output); output.write(buf); } - public static void writeUint8Array(short[] uints, OutputStream output) throws IOException + public static void writeUint8Array(short[] uints, OutputStream output) + throws IOException { for (int i = 0; i < uints.length; ++i) { @@ -186,7 +195,8 @@ public class TlsUtils } } - public static void writeUint16Array(int[] uints, OutputStream output) throws IOException + public static void writeUint16Array(int[] uints, OutputStream output) + throws IOException { for (int i = 0; i < uints.length; ++i) { @@ -194,7 +204,8 @@ public class TlsUtils } } - public static short readUint8(InputStream input) throws IOException + public static short readUint8(InputStream input) + throws IOException { int i = input.read(); if (i < 0) @@ -209,7 +220,8 @@ public class TlsUtils return (short)buf[offset]; } - public static int readUint16(InputStream input) throws IOException + public static int readUint16(InputStream input) + throws IOException { int i1 = input.read(); int i2 = input.read(); @@ -227,7 +239,8 @@ public class TlsUtils return n; } - public static int readUint24(InputStream input) throws IOException + public static int readUint24(InputStream input) + throws IOException { int i1 = input.read(); int i2 = input.read(); @@ -247,7 +260,8 @@ public class TlsUtils return n; } - public static long readUint32(InputStream input) throws IOException + public static long readUint32(InputStream input) + throws IOException { int i1 = input.read(); int i2 = input.read(); @@ -260,7 +274,8 @@ public class TlsUtils return (((long)i1) << 24) | (((long)i2) << 16) | (((long)i3) << 8) | ((long)i4); } - public static long readUint48(InputStream input) throws IOException + public static long readUint48(InputStream input) + throws IOException { int i1 = input.read(); int i2 = input.read(); @@ -272,7 +287,7 @@ public class TlsUtils { throw new EOFException(); } - return (((long)i1) << 40) | (((long)i2) << 32) | (((long)i3) << 24) | (((long)i4) << 16) | (((long)i5) << 8) | ((long)i6); + return (((long)i1) << 40) | (((long)i2) << 32) | (((long)i3) << 24) | (((long)i4) << 16) | (((long)i5) << 8) | ((long)i6); } public static long readUint48(byte[] buf, int offset) @@ -282,9 +297,11 @@ public class TlsUtils return ((long)(hi & 0xffffffffL) << 24) | (long)(lo & 0xffffffffL); } - public static byte[] readFully(int length, InputStream input) throws IOException + public static byte[] readFully(int length, InputStream input) + throws IOException { - if (length < 1) { + if (length < 1) + { return EMPTY_BYTES; } byte[] buf = new byte[length]; @@ -295,7 +312,8 @@ public class TlsUtils return buf; } - public static void readFully(byte[] buf, InputStream input) throws IOException + public static void readFully(byte[] buf, InputStream input) + throws IOException { int length = buf.length; if (length > 0 && length != Streams.readFully(input, buf)) @@ -304,25 +322,29 @@ public class TlsUtils } } - public static byte[] readOpaque8(InputStream input) throws IOException + public static byte[] readOpaque8(InputStream input) + throws IOException { short length = readUint8(input); return readFully(length, input); } - public static byte[] readOpaque16(InputStream input) throws IOException + public static byte[] readOpaque16(InputStream input) + throws IOException { int length = readUint16(input); return readFully(length, input); } - public static byte[] readOpaque24(InputStream input) throws IOException + public static byte[] readOpaque24(InputStream input) + throws IOException { int length = readUint24(input); return readFully(length, input); } - public static short[] readUint8Array(int count, InputStream input) throws IOException + public static short[] readUint8Array(int count, InputStream input) + throws IOException { short[] uints = new short[count]; for (int i = 0; i < count; ++i) @@ -332,7 +354,8 @@ public class TlsUtils return uints; } - public static int[] readUint16Array(int count, InputStream input) throws IOException + public static int[] readUint16Array(int count, InputStream input) + throws IOException { int[] uints = new int[count]; for (int i = 0; i < count; ++i) @@ -342,12 +365,14 @@ public class TlsUtils return uints; } - public static ProtocolVersion readVersion(byte[] buf, int offset) throws IOException + public static ProtocolVersion readVersion(byte[] buf, int offset) + throws IOException { return ProtocolVersion.get(buf[offset] & 0xFF, buf[offset + 1] & 0xFF); } - public static ProtocolVersion readVersion(InputStream input) throws IOException + public static ProtocolVersion readVersion(InputStream input) + throws IOException { int i1 = input.read(); int i2 = input.read(); @@ -358,7 +383,8 @@ public class TlsUtils return ProtocolVersion.get(i1, i2); } - public static int readVersionRaw(InputStream input) throws IOException + public static int readVersionRaw(InputStream input) + throws IOException { int i1 = input.read(); int i2 = input.read(); @@ -378,13 +404,15 @@ public class TlsUtils buf[offset + 3] = (byte)t; } - public static void writeVersion(ProtocolVersion version, OutputStream output) throws IOException + public static void writeVersion(ProtocolVersion version, OutputStream output) + throws IOException { output.write(version.getMajorVersion()); output.write(version.getMinorVersion()); } - public static void writeVersion(ProtocolVersion version, byte[] buf, int offset) throws IOException + public static void writeVersion(ProtocolVersion version, byte[] buf, int offset) + throws IOException { buf[offset] = (byte)version.getMajorVersion(); buf[offset + 1] = (byte)version.getMinorVersion(); @@ -412,8 +440,8 @@ public class TlsUtils /** * Add a 'signature_algorithms' extension to existing extensions. - * - * @param extensions A {@link Hashtable} to add the extension to. + * + * @param extensions A {@link Hashtable} to add the extension to. * @param supportedSignatureAlgorithms {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. * @throws IOException */ @@ -425,18 +453,22 @@ public class TlsUtils /** * Get a 'signature_algorithms' extension from extensions. - * + * * @param extensions A {@link Hashtable} to get the extension from, if it is present. * @return A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}, or null. * @throws IOException */ - public static Vector getSignatureAlgorithmsExtension(Hashtable extensions) throws IOException { + public static Vector getSignatureAlgorithmsExtension(Hashtable extensions) + throws IOException + { - if (extensions == null) { + if (extensions == null) + { return null; } - byte[] extensionValue = (byte[]) extensions.get(EXT_signature_algorithms); - if (extensionValue == null) { + byte[] extensionValue = (byte[])extensions.get(EXT_signature_algorithms); + if (extensionValue == null) + { return null; } return readSignatureAlgorithmsExtension(extensionValue); @@ -444,14 +476,17 @@ public class TlsUtils /** * Create a 'signature_algorithms' extension value. - * + * * @param supportedSignatureAlgorithms A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. * @return A byte array suitable for use as an extension value. * @throws IOException */ - public static byte[] createSignatureAlgorithmsExtension(Vector supportedSignatureAlgorithms) throws IOException { + public static byte[] createSignatureAlgorithmsExtension(Vector supportedSignatureAlgorithms) + throws IOException + { - if (supportedSignatureAlgorithms == null || supportedSignatureAlgorithms.size() < 1 || supportedSignatureAlgorithms.size() >= (1 << 15)) { + if (supportedSignatureAlgorithms == null || supportedSignatureAlgorithms.size() < 1 || supportedSignatureAlgorithms.size() >= (1 << 15)) + { throw new IllegalArgumentException( "'supportedSignatureAlgorithms' must have length from 1 to (2^15 - 1)"); } @@ -460,7 +495,8 @@ public class TlsUtils // supported_signature_algorithms TlsUtils.writeUint16(2 * supportedSignatureAlgorithms.size(), buf); - for (int i = 0; i < supportedSignatureAlgorithms.size(); ++i) { + for (int i = 0; i < supportedSignatureAlgorithms.size(); ++i) + { SignatureAndHashAlgorithm entry = (SignatureAndHashAlgorithm)supportedSignatureAlgorithms.elementAt(i); entry.encode(buf); } @@ -470,14 +506,17 @@ public class TlsUtils /** * Read a 'signature_algorithms' extension value. - * + * * @param extensionValue The extension value. * @return A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. * @throws IOException */ - public static Vector readSignatureAlgorithmsExtension(byte[] extensionValue) throws IOException { + public static Vector readSignatureAlgorithmsExtension(byte[] extensionValue) + throws IOException + { - if (extensionValue == null) { + if (extensionValue == null) + { throw new IllegalArgumentException("'extensionValue' cannot be null"); } @@ -485,12 +524,14 @@ public class TlsUtils // supported_signature_algorithms int length = TlsUtils.readUint16(buf); - if (length < 2 || (length & 1) != 0) { + if (length < 2 || (length & 1) != 0) + { throw new TlsFatalAlert(AlertDescription.decode_error); } int count = length / 2; Vector result = new Vector(count); - for (int i = 0; i < count; ++i) { + for (int i = 0; i < count; ++i) + { SignatureAndHashAlgorithm entry = SignatureAndHashAlgorithm.parse(buf); result.addElement(entry); } @@ -580,7 +621,8 @@ public class TlsUtils } } - static void validateKeyUsage(org.bouncycastle.asn1.x509.Certificate c, int keyUsageBits) throws IOException + static void validateKeyUsage(org.bouncycastle.asn1.x509.Certificate c, int keyUsageBits) + throws IOException { Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) @@ -687,10 +729,10 @@ public class TlsUtils static byte[] calculateVerifyData(TlsContext context, String asciiLabel, byte[] handshakeHash) { - if (context.getServerVersion().isSSL()) - { - return handshakeHash; - } + if (context.getServerVersion().isSSL()) + { + return handshakeHash; + } SecurityParameters securityParameters = context.getSecurityParameters(); byte[] master_secret = securityParameters.getMasterSecret(); @@ -763,7 +805,8 @@ public class TlsUtils } } - public static final short getHashAlgorithmForPRFAlgorithm(int prfAlgorithm) { + public static final short getHashAlgorithmForPRFAlgorithm(int prfAlgorithm) + { switch (prfAlgorithm) { case PRFAlgorithm.tls_prf_legacy: @@ -777,8 +820,10 @@ public class TlsUtils } } - public static ASN1ObjectIdentifier getOIDForHashAlgorithm(int hashAlgorithm) { - switch (hashAlgorithm) { + public static ASN1ObjectIdentifier getOIDForHashAlgorithm(int hashAlgorithm) + { + switch (hashAlgorithm) + { case HashAlgorithm.md5: return PKCSObjectIdentifiers.md5; case HashAlgorithm.sha1: @@ -880,7 +925,8 @@ public class TlsUtils } } - public static TlsSigner createTlsSigner(short clientCertificateType) { + public static TlsSigner createTlsSigner(short clientCertificateType) + { switch (clientCertificateType) { case ClientCertificateType.dss_sign: @@ -894,8 +940,8 @@ public class TlsUtils } } - static final byte[] SSL_CLIENT = { 0x43, 0x4C, 0x4E, 0x54 }; - static final byte[] SSL_SERVER = { 0x53, 0x52, 0x56, 0x52 }; + static final byte[] SSL_CLIENT = {0x43, 0x4C, 0x4E, 0x54}; + static final byte[] SSL_SERVER = {0x53, 0x52, 0x56, 0x52}; // SSL3 magic mix constants ("A", "BB", "CCC", ...) static final byte[][] SSL3_CONST = genConst(); @@ -912,7 +958,7 @@ public class TlsUtils } return arr; } - + private static Vector vectorOfOne(Object obj) { Vector v = new Vector(1); diff --git a/src/main/java/org/bouncycastle/crypto/tls/UDPTransport.java b/src/main/java/org/bouncycastle/crypto/tls/UDPTransport.java index 98de5db8..82c98aaa 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/UDPTransport.java +++ b/src/main/java/org/bouncycastle/crypto/tls/UDPTransport.java @@ -4,7 +4,9 @@ import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; -public class UDPTransport implements DatagramTransport { +public class UDPTransport + implements DatagramTransport +{ private final static int MIN_IP_OVERHEAD = 20; private final static int MAX_IP_OVERHEAD = MIN_IP_OVERHEAD + 64; @@ -13,9 +15,12 @@ public class UDPTransport implements DatagramTransport { private final DatagramSocket socket; private final int receiveLimit, sendLimit; - public UDPTransport(DatagramSocket socket, int mtu) throws IOException { + public UDPTransport(DatagramSocket socket, int mtu) + throws IOException + { - if (!socket.isBound() || !socket.isConnected()) { + if (!socket.isBound() || !socket.isConnected()) + { throw new IllegalArgumentException("'socket' must be bound and connected"); } @@ -27,24 +32,31 @@ public class UDPTransport implements DatagramTransport { this.sendLimit = mtu - MAX_IP_OVERHEAD - UDP_OVERHEAD; } - public int getReceiveLimit() { + public int getReceiveLimit() + { return receiveLimit; } - public int getSendLimit() { + public int getSendLimit() + { // TODO[DTLS] Implement Path-MTU discovery? return sendLimit; } - public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { + public int receive(byte[] buf, int off, int len, int waitMillis) + throws IOException + { socket.setSoTimeout(waitMillis); DatagramPacket packet = new DatagramPacket(buf, off, len); socket.receive(packet); return packet.getLength(); } - public void send(byte[] buf, int off, int len) throws IOException { - if (len > getSendLimit()) { + public void send(byte[] buf, int off, int len) + throws IOException + { + if (len > getSendLimit()) + { /* * RFC 4347 4.1.1. "If the application attempts to send a record larger than the MTU, * the DTLS implementation SHOULD generate an error, thus avoiding sending a packet @@ -57,7 +69,9 @@ public class UDPTransport implements DatagramTransport { socket.send(packet); } - public void close() throws IOException { + public void close() + throws IOException + { socket.close(); } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/UseSRTPData.java b/src/main/java/org/bouncycastle/crypto/tls/UseSRTPData.java index 3e9f0cbe..8828211c 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/UseSRTPData.java +++ b/src/main/java/org/bouncycastle/crypto/tls/UseSRTPData.java @@ -3,28 +3,32 @@ package org.bouncycastle.crypto.tls; /** * RFC 5764 4.1.1 */ -public class UseSRTPData { +public class UseSRTPData +{ private int[] protectionProfiles; private byte[] mki; /** - * @param protectionProfiles - * see {@link SRTPProtectionProfile} for valid constants. - * @param mki - * valid lengths from 0 to 255. + * @param protectionProfiles see {@link SRTPProtectionProfile} for valid constants. + * @param mki valid lengths from 0 to 255. */ - public UseSRTPData(int[] protectionProfiles, byte[] mki) { + public UseSRTPData(int[] protectionProfiles, byte[] mki) + { if (protectionProfiles == null || protectionProfiles.length < 1 - || protectionProfiles.length >= (1 << 15)) { + || protectionProfiles.length >= (1 << 15)) + { throw new IllegalArgumentException( "'protectionProfiles' must have length from 1 to (2^15 - 1)"); } - if (mki == null) { + if (mki == null) + { mki = TlsUtils.EMPTY_BYTES; - } else if (mki.length > 255) { + } + else if (mki.length > 255) + { throw new IllegalArgumentException("'mki' cannot be longer than 255 bytes"); } @@ -35,14 +39,16 @@ public class UseSRTPData { /** * @return see {@link SRTPProtectionProfile} for valid constants. */ - public int[] getProtectionProfiles() { + public int[] getProtectionProfiles() + { return protectionProfiles; } /** * @return valid lengths from 0 to 255. */ - public byte[] getMki() { + public byte[] getMki() + { return mki; } } diff --git a/src/main/java/org/bouncycastle/crypto/tls/UserMappingType.java b/src/main/java/org/bouncycastle/crypto/tls/UserMappingType.java index ad8a3d81..9b83684f 100644 --- a/src/main/java/org/bouncycastle/crypto/tls/UserMappingType.java +++ b/src/main/java/org/bouncycastle/crypto/tls/UserMappingType.java @@ -3,7 +3,8 @@ package org.bouncycastle.crypto.tls; /** * RFC 4681 */ -public class UserMappingType { +public class UserMappingType +{ /* * RFC 4681 */ diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/AllTests.java b/src/test/java/org/bouncycastle/crypto/tls/test/AllTests.java index 2cc170bc..ef5b29bc 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/AllTests.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/AllTests.java @@ -3,21 +3,21 @@ package org.bouncycastle.crypto.tls.test; import junit.framework.Test; import junit.framework.TestSuite; -public class AllTests +public class AllTests { - public static void main (String[] args) + public static void main(String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } - - public static Test suite() + + public static Test suite() throws Exception - { + { TestSuite suite = new TestSuite("TLS tests"); - + suite.addTest(BasicTlsTest.suite()); - + return suite; } } diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/BasicTlsTest.java b/src/test/java/org/bouncycastle/crypto/tls/test/BasicTlsTest.java index cf0676dd..aa583e75 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/BasicTlsTest.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/BasicTlsTest.java @@ -1,162 +1,193 @@ -package org.bouncycastle.crypto.tls.test; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.net.Socket; - -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.bouncycastle.crypto.tls.AlertDescription; -import org.bouncycastle.crypto.tls.AlertLevel; -import org.bouncycastle.crypto.tls.AlwaysValidVerifyer; -import org.bouncycastle.crypto.tls.Certificate; -import org.bouncycastle.crypto.tls.CipherSuite; -import org.bouncycastle.crypto.tls.DefaultTlsClient; -import org.bouncycastle.crypto.tls.LegacyTlsClient; -import org.bouncycastle.crypto.tls.TlsAuthentication; -import org.bouncycastle.crypto.tls.TlsClient; -import org.bouncycastle.crypto.tls.TlsClientProtocol; -import org.bouncycastle.crypto.tls.TlsFatalAlert; -import org.bouncycastle.crypto.tls.TlsKeyExchange; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.encoders.Hex; - -public class BasicTlsTest extends TestCase { - private static final int PORT_NO = 8003; - - // private static final String CLIENT = "client"; - // private static final char[] CLIENT_PASSWORD = "clientPassword".toCharArray(); - // private static final char[] SERVER_PASSWORD = "serverPassword".toCharArray(); - // private static final char[] TRUST_STORE_PASSWORD = "trustPassword".toCharArray(); - - public void testConnection() throws Exception { - Thread server = new HTTPSServerThread(); - - server.start(); - - Thread.yield(); - - AlwaysValidVerifyer verifyer = new AlwaysValidVerifyer(); - Socket s = null; - - for (int i = 0; s == null && i != 3; i++) { - Thread.sleep(1000); - - try { - s = new Socket("localhost", PORT_NO); - } catch (IOException e) { - // ignore - } - } - - if (s == null) { - throw new IOException("unable to connect"); - } - - // long time = System.currentTimeMillis(); - TlsClientProtocol protocol = new TlsClientProtocol(s.getInputStream(), s.getOutputStream()); - protocol.connect(new LegacyTlsClient(verifyer)); - InputStream is = protocol.getInputStream(); - OutputStream os = protocol.getOutputStream(); - - os.write("GET / HTTP/1.1\r\n\r\n".getBytes()); - - // time = System.currentTimeMillis(); - byte[] buf = new byte[4096]; - int read = 0; - int total = 0; - - while ((read = is.read(buf, total, buf.length - total)) > 0) { - total += read; - } - - is.close(); - - byte[] expected = Hex.decode("485454502f312e3120323030204f4b0d0a436f6e74656e742d547970653a20746578742f68" - + "746d6c0d0a0d0a3c68746d6c3e0d0a3c626f64793e0d0a48656c6c6f20576f726c64210d0a3c2f626f64793e0d0a3c2f" - + "68746d6c3e0d0a"); - assertEquals(total, expected.length); - - byte[] tmp = new byte[expected.length]; - System.arraycopy(buf, 0, tmp, 0, total); - assertTrue(Arrays.areEqual(expected, tmp)); - } - - public void testRSAConnectionClient() throws Exception { - MyTlsClient client = new MyTlsClient(null); - - checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA, TlsTestUtils.rsaCertData); - checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, TlsTestUtils.rsaCertData); - checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, TlsTestUtils.rsaCertData); - checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_RC4_128_SHA, TlsTestUtils.rsaCertData); - - try { - checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA, TlsTestUtils.dudRsaCertData); - - fail("dud certificate not caught"); - } catch (TlsFatalAlert e) { - assertEquals(AlertDescription.certificate_unknown, e.getAlertDescription()); - } - - try { - checkConnectionClient(client, CipherSuite.TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, TlsTestUtils.rsaCertData); - - fail("wrong certificate not caught"); - } catch (TlsFatalAlert e) { - assertEquals(AlertDescription.internal_error, e.getAlertDescription()); - } - } - - private void checkConnectionClient(TlsClient client, int cipherSuite, byte[] encCert) throws Exception { - client.notifySelectedCipherSuite(cipherSuite); - - TlsKeyExchange keyExchange = client.getKeyExchange(); - - keyExchange - .processServerCertificate(new Certificate( - new org.bouncycastle.asn1.x509.Certificate[] { org.bouncycastle.asn1.x509.Certificate - .getInstance(encCert) })); - } - - public static TestSuite suite() { - return new TestSuite(BasicTlsTest.class); - } - - public static void main(String[] args) throws Exception { - junit.textui.TestRunner.run(suite()); - } - - static class MyTlsClient extends DefaultTlsClient { - - public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("TLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription - + ")"); - if (message != null) { - out.println(message); - } - if (cause != null) { - cause.printStackTrace(out); - } - } - - public void notifyAlertReceived(short alertLevel, short alertDescription) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("TLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." - + alertDescription + ")"); - } - - private final TlsAuthentication authentication; - - MyTlsClient(TlsAuthentication authentication) { - this.authentication = authentication; - } - - public TlsAuthentication getAuthentication() throws IOException { - return authentication; - } - } -} +package org.bouncycastle.crypto.tls.test; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.Socket; + +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.bouncycastle.crypto.tls.AlertDescription; +import org.bouncycastle.crypto.tls.AlertLevel; +import org.bouncycastle.crypto.tls.AlwaysValidVerifyer; +import org.bouncycastle.crypto.tls.Certificate; +import org.bouncycastle.crypto.tls.CipherSuite; +import org.bouncycastle.crypto.tls.DefaultTlsClient; +import org.bouncycastle.crypto.tls.LegacyTlsClient; +import org.bouncycastle.crypto.tls.TlsAuthentication; +import org.bouncycastle.crypto.tls.TlsClient; +import org.bouncycastle.crypto.tls.TlsClientProtocol; +import org.bouncycastle.crypto.tls.TlsFatalAlert; +import org.bouncycastle.crypto.tls.TlsKeyExchange; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; + +public class BasicTlsTest + extends TestCase +{ + private static final int PORT_NO = 8003; + + // private static final String CLIENT = "client"; + // private static final char[] CLIENT_PASSWORD = "clientPassword".toCharArray(); + // private static final char[] SERVER_PASSWORD = "serverPassword".toCharArray(); + // private static final char[] TRUST_STORE_PASSWORD = "trustPassword".toCharArray(); + + public void testConnection() + throws Exception + { + Thread server = new HTTPSServerThread(); + + server.start(); + + Thread.yield(); + + AlwaysValidVerifyer verifyer = new AlwaysValidVerifyer(); + Socket s = null; + + for (int i = 0; s == null && i != 3; i++) + { + Thread.sleep(1000); + + try + { + s = new Socket("localhost", PORT_NO); + } + catch (IOException e) + { + // ignore + } + } + + if (s == null) + { + throw new IOException("unable to connect"); + } + + // long time = System.currentTimeMillis(); + TlsClientProtocol protocol = new TlsClientProtocol(s.getInputStream(), s.getOutputStream()); + protocol.connect(new LegacyTlsClient(verifyer)); + InputStream is = protocol.getInputStream(); + OutputStream os = protocol.getOutputStream(); + + os.write("GET / HTTP/1.1\r\n\r\n".getBytes()); + + // time = System.currentTimeMillis(); + byte[] buf = new byte[4096]; + int read = 0; + int total = 0; + + while ((read = is.read(buf, total, buf.length - total)) > 0) + { + total += read; + } + + is.close(); + + byte[] expected = Hex.decode("485454502f312e3120323030204f4b0d0a436f6e74656e742d547970653a20746578742f68" + + "746d6c0d0a0d0a3c68746d6c3e0d0a3c626f64793e0d0a48656c6c6f20576f726c64210d0a3c2f626f64793e0d0a3c2f" + + "68746d6c3e0d0a"); + assertEquals(total, expected.length); + + byte[] tmp = new byte[expected.length]; + System.arraycopy(buf, 0, tmp, 0, total); + assertTrue(Arrays.areEqual(expected, tmp)); + } + + public void testRSAConnectionClient() + throws Exception + { + MyTlsClient client = new MyTlsClient(null); + + checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA, TlsTestUtils.rsaCertData); + checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, TlsTestUtils.rsaCertData); + checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, TlsTestUtils.rsaCertData); + checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_RC4_128_SHA, TlsTestUtils.rsaCertData); + + try + { + checkConnectionClient(client, CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA, TlsTestUtils.dudRsaCertData); + + fail("dud certificate not caught"); + } + catch (TlsFatalAlert e) + { + assertEquals(AlertDescription.certificate_unknown, e.getAlertDescription()); + } + + try + { + checkConnectionClient(client, CipherSuite.TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, TlsTestUtils.rsaCertData); + + fail("wrong certificate not caught"); + } + catch (TlsFatalAlert e) + { + assertEquals(AlertDescription.internal_error, e.getAlertDescription()); + } + } + + private void checkConnectionClient(TlsClient client, int cipherSuite, byte[] encCert) + throws Exception + { + client.notifySelectedCipherSuite(cipherSuite); + + TlsKeyExchange keyExchange = client.getKeyExchange(); + + keyExchange + .processServerCertificate(new Certificate( + new org.bouncycastle.asn1.x509.Certificate[]{org.bouncycastle.asn1.x509.Certificate + .getInstance(encCert)})); + } + + public static TestSuite suite() + { + return new TestSuite(BasicTlsTest.class); + } + + public static void main(String[] args) + throws Exception + { + junit.textui.TestRunner.run(suite()); + } + + static class MyTlsClient + extends DefaultTlsClient + { + + public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + + ")"); + if (message != null) + { + out.println(message); + } + if (cause != null) + { + cause.printStackTrace(out); + } + } + + public void notifyAlertReceived(short alertLevel, short alertDescription) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." + + alertDescription + ")"); + } + + private final TlsAuthentication authentication; + + MyTlsClient(TlsAuthentication authentication) + { + this.authentication = authentication; + } + + public TlsAuthentication getAuthentication() + throws IOException + { + return authentication; + } + } +} diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/DTLSClientTest.java b/src/test/java/org/bouncycastle/crypto/tls/test/DTLSClientTest.java index 4eab60c7..41573b01 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/DTLSClientTest.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/DTLSClientTest.java @@ -1,55 +1,59 @@ -package org.bouncycastle.crypto.tls.test; - -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.security.SecureRandom; - -import org.bouncycastle.crypto.tls.DTLSClientProtocol; -import org.bouncycastle.crypto.tls.DTLSTransport; -import org.bouncycastle.crypto.tls.DatagramTransport; -import org.bouncycastle.crypto.tls.UDPTransport; - -/** - * A simple test designed to conduct a DTLS handshake with an external DTLS server. - * - * Please refer to GnuTLSSetup.txt or OpenSSLSetup.txt, and x509-*.pem files in this package for - * help configuring an external DTLS server. - */ -public class DTLSClientTest { - - public static void main(String[] args) throws Exception { - - SecureRandom secureRandom = new SecureRandom(); - - DatagramSocket socket = new DatagramSocket(); - socket.connect(InetAddress.getLocalHost(), 5556); - - int mtu = 1500; - DatagramTransport transport = new UDPTransport(socket, mtu); - - transport = new UnreliableDatagramTransport(transport, secureRandom, 0, 0); - - transport = new LoggingDatagramTransport(transport, System.out); - - DTLSClientProtocol protocol = new DTLSClientProtocol(secureRandom); - - MockDTLSClient client = new MockDTLSClient(); - DTLSTransport dtlsClient = protocol.connect(client, transport); - - System.out.println("Receive limit: " + dtlsClient.getReceiveLimit()); - System.out.println("Send limit: " + dtlsClient.getSendLimit()); - - // Send and hopefully receive a packet back - - byte[] request = "Hello World!\n".getBytes("UTF-8"); - dtlsClient.send(request, 0, request.length); - - byte[] response = new byte[dtlsClient.getReceiveLimit()]; - int received = dtlsClient.receive(response, 0, response.length, 30000); - if (received >= 0) { - System.out.println(new String(response, 0, received, "UTF-8")); - } - - dtlsClient.close(); - } -} +package org.bouncycastle.crypto.tls.test; + +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.security.SecureRandom; + +import org.bouncycastle.crypto.tls.DTLSClientProtocol; +import org.bouncycastle.crypto.tls.DTLSTransport; +import org.bouncycastle.crypto.tls.DatagramTransport; +import org.bouncycastle.crypto.tls.UDPTransport; + +/** + * A simple test designed to conduct a DTLS handshake with an external DTLS server. + *

+ * Please refer to GnuTLSSetup.txt or OpenSSLSetup.txt, and x509-*.pem files in this package for + * help configuring an external DTLS server. + */ +public class DTLSClientTest +{ + + public static void main(String[] args) + throws Exception + { + + SecureRandom secureRandom = new SecureRandom(); + + DatagramSocket socket = new DatagramSocket(); + socket.connect(InetAddress.getLocalHost(), 5556); + + int mtu = 1500; + DatagramTransport transport = new UDPTransport(socket, mtu); + + transport = new UnreliableDatagramTransport(transport, secureRandom, 0, 0); + + transport = new LoggingDatagramTransport(transport, System.out); + + DTLSClientProtocol protocol = new DTLSClientProtocol(secureRandom); + + MockDTLSClient client = new MockDTLSClient(); + DTLSTransport dtlsClient = protocol.connect(client, transport); + + System.out.println("Receive limit: " + dtlsClient.getReceiveLimit()); + System.out.println("Send limit: " + dtlsClient.getSendLimit()); + + // Send and hopefully receive a packet back + + byte[] request = "Hello World!\n".getBytes("UTF-8"); + dtlsClient.send(request, 0, request.length); + + byte[] response = new byte[dtlsClient.getReceiveLimit()]; + int received = dtlsClient.receive(response, 0, response.length, 30000); + if (received >= 0) + { + System.out.println(new String(response, 0, received, "UTF-8")); + } + + dtlsClient.close(); + } +} diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/DTLSProtocolTest.java b/src/test/java/org/bouncycastle/crypto/tls/test/DTLSProtocolTest.java index 339ea3bc..60f879fb 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/DTLSProtocolTest.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/DTLSProtocolTest.java @@ -1,84 +1,103 @@ -package org.bouncycastle.crypto.tls.test; - -import java.security.SecureRandom; - -import junit.framework.TestCase; - -import org.bouncycastle.crypto.tls.DTLSClientProtocol; -import org.bouncycastle.crypto.tls.DTLSServerProtocol; -import org.bouncycastle.crypto.tls.DTLSTransport; -import org.bouncycastle.crypto.tls.DatagramTransport; -import org.bouncycastle.util.Arrays; - -public class DTLSProtocolTest extends TestCase { - - public void testClientServer() throws Exception { - - SecureRandom secureRandom = new SecureRandom(); - - DTLSClientProtocol clientProtocol = new DTLSClientProtocol(secureRandom); - DTLSServerProtocol serverProtocol = new DTLSServerProtocol(secureRandom); - - MockDatagramAssociation network = new MockDatagramAssociation(1500); - - ServerThread serverThread = new ServerThread(serverProtocol, network.getServer()); - serverThread.start(); - - DatagramTransport clientTransport = network.getClient(); - - clientTransport = new UnreliableDatagramTransport(clientTransport, secureRandom, 0, 0); - - clientTransport = new LoggingDatagramTransport(clientTransport, System.out); - - MockDTLSClient client = new MockDTLSClient(); - DTLSTransport dtlsClient = clientProtocol.connect(client, clientTransport); - - for (int i = 1; i <= 10; ++i) { - byte[] data = new byte[i]; - Arrays.fill(data, (byte)i); - dtlsClient.send(data, 0, data.length); - } - - byte[] buf = new byte[dtlsClient.getReceiveLimit()]; - while (dtlsClient.receive(buf, 0, buf.length, 1000) >= 0); - - dtlsClient.close(); - - serverThread.shutdown(); - } - - static class ServerThread extends Thread { - private final DTLSServerProtocol serverProtocol; - private final DatagramTransport serverTransport; - private volatile boolean isShutdown = false; - - ServerThread(DTLSServerProtocol serverProtocol, DatagramTransport serverTransport) { - this.serverProtocol = serverProtocol; - this.serverTransport = serverTransport; - } - - public void run() { - try { - MockDTLSServer server = new MockDTLSServer(); - DTLSTransport dtlsServer = serverProtocol.accept(server, serverTransport); - byte[] buf = new byte[dtlsServer.getReceiveLimit()]; - while (!isShutdown) { - int length = dtlsServer.receive(buf, 0, buf.length, 1000); - if (length >= 0) { - dtlsServer.send(buf, 0, length); - } - } - dtlsServer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - void shutdown() throws InterruptedException { - if (!isShutdown) { - isShutdown = true; - this.join(); - } - } - } -} +package org.bouncycastle.crypto.tls.test; + +import java.security.SecureRandom; + +import junit.framework.TestCase; +import org.bouncycastle.crypto.tls.DTLSClientProtocol; +import org.bouncycastle.crypto.tls.DTLSServerProtocol; +import org.bouncycastle.crypto.tls.DTLSTransport; +import org.bouncycastle.crypto.tls.DatagramTransport; +import org.bouncycastle.util.Arrays; + +public class DTLSProtocolTest + extends TestCase +{ + + public void testClientServer() + throws Exception + { + + SecureRandom secureRandom = new SecureRandom(); + + DTLSClientProtocol clientProtocol = new DTLSClientProtocol(secureRandom); + DTLSServerProtocol serverProtocol = new DTLSServerProtocol(secureRandom); + + MockDatagramAssociation network = new MockDatagramAssociation(1500); + + ServerThread serverThread = new ServerThread(serverProtocol, network.getServer()); + serverThread.start(); + + DatagramTransport clientTransport = network.getClient(); + + clientTransport = new UnreliableDatagramTransport(clientTransport, secureRandom, 0, 0); + + clientTransport = new LoggingDatagramTransport(clientTransport, System.out); + + MockDTLSClient client = new MockDTLSClient(); + DTLSTransport dtlsClient = clientProtocol.connect(client, clientTransport); + + for (int i = 1; i <= 10; ++i) + { + byte[] data = new byte[i]; + Arrays.fill(data, (byte)i); + dtlsClient.send(data, 0, data.length); + } + + byte[] buf = new byte[dtlsClient.getReceiveLimit()]; + while (dtlsClient.receive(buf, 0, buf.length, 1000) >= 0) + { + ; + } + + dtlsClient.close(); + + serverThread.shutdown(); + } + + static class ServerThread + extends Thread + { + private final DTLSServerProtocol serverProtocol; + private final DatagramTransport serverTransport; + private volatile boolean isShutdown = false; + + ServerThread(DTLSServerProtocol serverProtocol, DatagramTransport serverTransport) + { + this.serverProtocol = serverProtocol; + this.serverTransport = serverTransport; + } + + public void run() + { + try + { + MockDTLSServer server = new MockDTLSServer(); + DTLSTransport dtlsServer = serverProtocol.accept(server, serverTransport); + byte[] buf = new byte[dtlsServer.getReceiveLimit()]; + while (!isShutdown) + { + int length = dtlsServer.receive(buf, 0, buf.length, 1000); + if (length >= 0) + { + dtlsServer.send(buf, 0, length); + } + } + dtlsServer.close(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + void shutdown() + throws InterruptedException + { + if (!isShutdown) + { + isShutdown = true; + this.join(); + } + } + } +} diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/HTTPSServerThread.java b/src/test/java/org/bouncycastle/crypto/tls/test/HTTPSServerThread.java index 3ed21a51..d55bc737 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/HTTPSServerThread.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/HTTPSServerThread.java @@ -1,12 +1,5 @@ package org.bouncycastle.crypto.tls.test; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLServerSocket; -import javax.net.ssl.SSLServerSocketFactory; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.TrustManagerFactory; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -15,6 +8,14 @@ import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.security.KeyStore; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLServerSocketFactory; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.TrustManagerFactory; + public class HTTPSServerThread extends Thread { @@ -70,7 +71,7 @@ public class HTTPSServerThread // set up a trust manager so we can recognize the server TrustManagerFactory trustFact = TrustManagerFactory.getInstance("SunX509"); - KeyStore trustStore = KeyStore.getInstance("JKS"); + KeyStore trustStore = KeyStore.getInstance("JKS"); trustStore.load(new ByteArrayInputStream(KeyStores.trustStore), TRUST_STORE_PASSWORD); diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/KeyStores.java b/src/test/java/org/bouncycastle/crypto/tls/test/KeyStores.java index 64ecab2c..bf71f965 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/KeyStores.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/KeyStores.java @@ -5,7 +5,7 @@ import org.bouncycastle.util.encoders.Base64; public class KeyStores { static final byte[] trustStore = Base64.decode( - "/u3+7QAAAAIAAAABAAAAAgAGc2VydmVyAAABD34zDJEABVguNTA5AAABrzCC" + "/u3+7QAAAAIAAAABAAAAAgAGc2VydmVyAAABD34zDJEABVguNTA5AAABrzCC" + "AaswggEUAgEBMA0GCSqGSIb3DQEBBQUAMB4xHDAaBgNVBAMTE1Rlc3QgQ0Eg" + "Q2VydGlmaWNhdGUwHhcNMDYxMjEzMjM0MzI5WhcNMDYxMjIwMjM0MzI5WjAe" + "MRwwGgYDVQQDExNUZXN0IENBIENlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEB" @@ -17,8 +17,8 @@ public class KeyStores + "cRlUOPsQtTl6KbUnxmKxa04UzDuNXzSx2oyGx5GCWx9u62hpO6vSpK69L9gH" + "OUtM5dQXcoK4i3olScKaU8qaYb0mBAy8fnx5pen8B0bIg+pz47l5VxQ5NO8="); - static final byte[] server = Base64.decode( - "/u3+7QAAAAIAAAABAAAAAQAGc2VydmVyAAABD34zDJIAAAK8MIICuDAOBgor" + static final byte[] server = Base64.decode( + "/u3+7QAAAAIAAAABAAAAAQAGc2VydmVyAAABD34zDJIAAAK8MIICuDAOBgor" + "BgEEASoCEQEBBQAEggKk9OXWj3aBr6rV9Grcsm2YL+/2ShVsxbJVGMSWll1f" + "U8z/mjhv5K/skgleTIMoyE5FzDDxJIGEmSMCkcHsnseXzxyhLpKBaz3N1Tk7" + "KVPzXfrNh0FJwzw3lPWyC2ayT+ObQfAtzuI9SUWNLBzzpWeolUJ8gkXnLshX" @@ -47,67 +47,67 @@ public class KeyStores + "ScKaU8qaYb0mBAy87VQaPfaiQqqxSgqifbSowlg+0fg="); static final byte[] client = Base64.decode( - "MIACAQMwgAYJKoZIhvcNAQcBoIAkgASCA+gwgDCABgkqhkiG9w0BBwGggCSA" - + "BIIDDzCCAwswggMHBgsqhkiG9w0BDAoBAqCCArIwggKuMCgGCiqGSIb3DQEM" - + "AQMwGgQUyeN8U+ViAJCk1WGo8wTnRVOaE1oCAgQABIICgH3yMWB+dfMBNa07" - + "hn3smUSBTF+LUauM+kx+12nZt0QazBYg09yM+aVcTznettlDwE/PTpKZnrFT" - + "22DSQf5GwABwiL6KW+xyM8wV5vZx1xtqrQoNf2oNHnF0lB7ddSYM8jHqennb" - + "bzcVOdrrCqewqAfUU/CDugpwwI8c8Iy9ECri6vBMbfeIIZQTug+1952TCCiA" - + "E1bEDFGqgAoDsqYi6uNtpjmL/DPX/qmkbHAXUKxOtjTtxacfat2HgN97Gb7z" - + "+ZBNI5aaCSRoYwl+K9biWGID3EqsNmg0+2ELmFhE4mQZ78i7vNLTG7e5mj6v" - + "Qt+QuqN+daCbVqVTKxsFpODRRweobUTRxwEun6p0p3w3SUhR6p7ug1Jttgyu" - + "vfZug3PIk2j9fb26wAs2ZreVYut8hXpp/09ulCUudtlsYb/FD+H11v/JyopG" - + "2vYy0hL/gkMr41sGoVdyvzXeZUa7A1wYask+g7torad9sT8CPb3zXBd0kU2r" - + "lbSJIXQ8wTpheeUKe47YF9JVCF8WRc1dokD7fgfn6197pwyZpDEVrVyz1pUq" - + "jyum3ctONU4BSkAUVr9pTyeRFUeOE7SLuVu+c67PzNWXEc/HMVD4Hgs/idVc" - + "mrONk3xe385wFJK1iPe1kfRX5OXk9UWr2/yjgrahbkonWhJHnIlvs+b5rRKN" - + "qauwUZ+agMJV98Eyc2Lz0Lp/pNDRNjmGXeJLzAaAy46STov8sxwAgj3bQ7xu" - + "uEzdhJPDynAY5sWd3WnBY2ZhpawnToEKnD4u+eiH2MjUL2q/R2IPSmoyg9i2" - + "Ictgh4/ylrhm+lJDzcDrLDhC0m/t9EdhytH4erk/uCPcmAK/jpzFn6ltxcsx" - + "QjAbBgkqhkiG9w0BCRQxDh4MAGMAbABpAGUAbgB0MCMGCSqGSIb3DQEJFTEW" - + "BBS2wDxw7yH2OhKIgkDoQrTlavLvxQAAAAAAADCABgkqhkiG9w0BBwaggDCA" - + "AgEAMIAGCSqGSIb3DQEHATAoBgoqhkiG9w0BDAEGMBoEFORdyeTIG2oXDQBl" - + "I3aFNozDAkC2AgIEAKCABIIHICsc3D8rxLiDlegyXFfIejto66RW4u6b+d0C" - + "uAAz0G+dIvhQ9g3s++vUsX7x+icO/vjpgdo09aqtIg7T3suzfcHtU8CGSgtQ" - + "Tvml25LDC3IK3qI6cRqO+sCdvg18aS04IDKvDPYH4ca5btwPBIID6CStk/jY" - + "QFpnSI6VNz9IERi/nwuvuBYk+A0Z7+nQdhF+QkW1rzN+uz0dkNJt6ZbG5lEK" - + "GayV+FDTQcREMihYa716RN9sq3cm0jXXdttj998oS/QrpZDEcPqd4AM6EIL+" - + "PTA1tEQYxXa8msAPp+tLvXOtiD6v/4FO77EA7E5oR36a9en+M1QQasFU3VBf" - + "V9os92QlbtVUTkspJV9gXL6s4CGNptc7lUH+nIw65j9MOoyOU9w1qjPRlN/Z" - + "MTuhFooglE6TPd29Udwufqp+hHkW/7z5tBKkhGlZEClzD3IWhcF9NVraE/IV" - + "S5qVmx2Up7SeLZAXJ+AAznq5IXwE1dOUTkwYLcIrH1FuVA5rtOkB8Xt1LJq0" - + "ERkjJ5MfpxTxbKXp5PejzD98v54+s4INekcrI0jzz4pLsann7ex0r6CPsQsH" - + "+F3rBVaT3oHSKqoIm2Nw57oDjLLp5lP2qcCqps3y2dcVzu5NIzCSkVlxUaBK" - + "IT3xv0gvVJI7wnP0QM35MCywKkToJX5ajQKrDc4iCAAzmxaQzdBycxJPYByq" - + "VHvH7BJldJlMw5NHbTHlNoYKndMdAsHp7sUqERkDEGl80R86TlB4nJaDrfsx" - + "vL+KluiCY9AD7o+MEYZ9VYoNDUzVGH4pTr4wnv1UFoRWix5IZuDnnYkyijKD" - + "VtU5+mc0YtsPQIpKCBJOYt05bgpX5aPQ3s2lviYw3bvP0TrclYs/rx4wKVgW" - + "2GYLzPh0OVMBduCbzW1E58ieBsgRyQ7+2MTl9Nj+nznjCAfLSvrVEcwxVUQA" - + "ofcEbiECEJss2JNQq8erwgo8dP3atwQ1KeqMc8acICcOrI2rNxwVOLzPuCsl" - + "l8gwZOoxLZXuKMQbQu4as1HNS309dfWIWppvc3K4nDWg51HUCPbsIo3wm3rR" - + "igc/W3bf4Ppg0pLAS5c1s0Xau43u9GmIjGiDqYaasfcXnCKy2LNuUpbhoOC1" - + "o/wMC9gT45aJQ5vsVGe5XvfhLV7Y815EdI756s9PIEOnG8HbAtCAjOIVpQfP" - + "eF8+cnZyGGdsbmu7lYzg3whCpZ/L2RrTI86nEn5eePs4m2hDV0Oi9r6e2CIf" - + "nGUa0TB9jf1OMhOSBD+h4jx7b6uT+XLmG8qUxvkoItMDZLrJ0f8czO5MyOZa" - + "nEJoG42Fy2p7zD/qO72OUQISNmt8C1rQFsg9dBDib4DMu69vBsVrIV028sal" - + "+tq1UH3vFMbEYyVfPH3WDgxyHwUQK2qrz3WBdD/BMyuAV4DPI3SPTweROh8n" - + "yWJN1ppY9qybmTyHFCs6TRjPB9cVcdKSc0qYxgzblJiXXb3s9ANOb89aA3Ah" - + "anWnAhcEggLZN2yFCtrRuvJXvDQhj8qmye9UkjB2fEpWXV7H0natE3hSoB+C" - + "2krt3eBV0xJ1tLEco7T4zsbQQJRmeu/essOsfwpRfE5ZPoIeThf+UmWTsfsw" - + "r4fxeePMTy6iCnkF5/ro8k5WKnOsaV+HWy/ulwW2r/DMT3aDBWfHX5Hk8DpU" - + "+PlQhbyGTSTIJ/OFmbcWjMPt469o7+KrrF9IBrzJ42KzMw6xtKwtVb0232AM" - + "pIwnLzCHIiNO2qDBZAIDdF68+GU3RsEkHfR6d5myZVxnH4mhSCFFtHxgqTOz" - + "Ouo/uvgu72miZ0OFAy1zcMtfGMS3Md54MJkhSZq4ZgUo/EyJCeEDLGn8pMF1" - + "jX1WsUj96qMRyc+p2KnKs6ZL95BVa76SdIFz6ts6uoIem3drTXYJHNbw29OW" - + "Y0am+FmXTWFZFnin8Qu5Xct5l7FYIGA9VLOHL9Vtp+SXomcFEZpjMaxvtf4R" - + "xoAI2Bc9Ka+MNiz35O0JXhI9/t5uOdiN6ZOJlfpEWOK7ou5lDkZuDcrHvLvQ" - + "PocP2Yemd36xEgjFssR/tFITlhRBXHDeHwpvmXM4iiwD1wOGMqybXx/1g1m1" - + "0UBbKqDsgSLQC7c0TaRFJjj71T74PBMiapiQgijv9WINfmTgxNUukbK3Kqp/" - + "G3BmThoIDCB8WD1kxXBpaG62dSsih7yhPQJVEV3Y0tdkdChOk+Y3Wf8crV/Q" - + "P08pQH7H9yCi04S5fSJtIDtYARWhr1yl8EQMnu2X8J6r/DWcDmXUK4Bv1vqe" - + "tcnT5EAYFPeOMz21nonM3kJgUMNsxCQjKaEMEcUu8ZRnGUAFdG4lULPJn5NQ" - + "LTvWg8Y3GrHRLjpnd9k+8gWWzRIbBiwCwEbClMZffRd6kcA5ZoOhVngdyvvj" - + "BhkgadB5jC+ZRzExHxoEhzPJx3mxIVTqLuw7QxHz9OTcysvY/cGKCvmgzgk/" - + "TjTJsqcEAAAAAAAAAAAAAAAAAAAAAAAAMD0wITAJBgUrDgMCGgUABBQWfGA6" - + "lI+TXQiuXaa1V+LlHodhXAQUAwMIAAUvBYY+a7sXNlQeVEPAGkMCAgQAAAA="); + "MIACAQMwgAYJKoZIhvcNAQcBoIAkgASCA+gwgDCABgkqhkiG9w0BBwGggCSA" + + "BIIDDzCCAwswggMHBgsqhkiG9w0BDAoBAqCCArIwggKuMCgGCiqGSIb3DQEM" + + "AQMwGgQUyeN8U+ViAJCk1WGo8wTnRVOaE1oCAgQABIICgH3yMWB+dfMBNa07" + + "hn3smUSBTF+LUauM+kx+12nZt0QazBYg09yM+aVcTznettlDwE/PTpKZnrFT" + + "22DSQf5GwABwiL6KW+xyM8wV5vZx1xtqrQoNf2oNHnF0lB7ddSYM8jHqennb" + + "bzcVOdrrCqewqAfUU/CDugpwwI8c8Iy9ECri6vBMbfeIIZQTug+1952TCCiA" + + "E1bEDFGqgAoDsqYi6uNtpjmL/DPX/qmkbHAXUKxOtjTtxacfat2HgN97Gb7z" + + "+ZBNI5aaCSRoYwl+K9biWGID3EqsNmg0+2ELmFhE4mQZ78i7vNLTG7e5mj6v" + + "Qt+QuqN+daCbVqVTKxsFpODRRweobUTRxwEun6p0p3w3SUhR6p7ug1Jttgyu" + + "vfZug3PIk2j9fb26wAs2ZreVYut8hXpp/09ulCUudtlsYb/FD+H11v/JyopG" + + "2vYy0hL/gkMr41sGoVdyvzXeZUa7A1wYask+g7torad9sT8CPb3zXBd0kU2r" + + "lbSJIXQ8wTpheeUKe47YF9JVCF8WRc1dokD7fgfn6197pwyZpDEVrVyz1pUq" + + "jyum3ctONU4BSkAUVr9pTyeRFUeOE7SLuVu+c67PzNWXEc/HMVD4Hgs/idVc" + + "mrONk3xe385wFJK1iPe1kfRX5OXk9UWr2/yjgrahbkonWhJHnIlvs+b5rRKN" + + "qauwUZ+agMJV98Eyc2Lz0Lp/pNDRNjmGXeJLzAaAy46STov8sxwAgj3bQ7xu" + + "uEzdhJPDynAY5sWd3WnBY2ZhpawnToEKnD4u+eiH2MjUL2q/R2IPSmoyg9i2" + + "Ictgh4/ylrhm+lJDzcDrLDhC0m/t9EdhytH4erk/uCPcmAK/jpzFn6ltxcsx" + + "QjAbBgkqhkiG9w0BCRQxDh4MAGMAbABpAGUAbgB0MCMGCSqGSIb3DQEJFTEW" + + "BBS2wDxw7yH2OhKIgkDoQrTlavLvxQAAAAAAADCABgkqhkiG9w0BBwaggDCA" + + "AgEAMIAGCSqGSIb3DQEHATAoBgoqhkiG9w0BDAEGMBoEFORdyeTIG2oXDQBl" + + "I3aFNozDAkC2AgIEAKCABIIHICsc3D8rxLiDlegyXFfIejto66RW4u6b+d0C" + + "uAAz0G+dIvhQ9g3s++vUsX7x+icO/vjpgdo09aqtIg7T3suzfcHtU8CGSgtQ" + + "Tvml25LDC3IK3qI6cRqO+sCdvg18aS04IDKvDPYH4ca5btwPBIID6CStk/jY" + + "QFpnSI6VNz9IERi/nwuvuBYk+A0Z7+nQdhF+QkW1rzN+uz0dkNJt6ZbG5lEK" + + "GayV+FDTQcREMihYa716RN9sq3cm0jXXdttj998oS/QrpZDEcPqd4AM6EIL+" + + "PTA1tEQYxXa8msAPp+tLvXOtiD6v/4FO77EA7E5oR36a9en+M1QQasFU3VBf" + + "V9os92QlbtVUTkspJV9gXL6s4CGNptc7lUH+nIw65j9MOoyOU9w1qjPRlN/Z" + + "MTuhFooglE6TPd29Udwufqp+hHkW/7z5tBKkhGlZEClzD3IWhcF9NVraE/IV" + + "S5qVmx2Up7SeLZAXJ+AAznq5IXwE1dOUTkwYLcIrH1FuVA5rtOkB8Xt1LJq0" + + "ERkjJ5MfpxTxbKXp5PejzD98v54+s4INekcrI0jzz4pLsann7ex0r6CPsQsH" + + "+F3rBVaT3oHSKqoIm2Nw57oDjLLp5lP2qcCqps3y2dcVzu5NIzCSkVlxUaBK" + + "IT3xv0gvVJI7wnP0QM35MCywKkToJX5ajQKrDc4iCAAzmxaQzdBycxJPYByq" + + "VHvH7BJldJlMw5NHbTHlNoYKndMdAsHp7sUqERkDEGl80R86TlB4nJaDrfsx" + + "vL+KluiCY9AD7o+MEYZ9VYoNDUzVGH4pTr4wnv1UFoRWix5IZuDnnYkyijKD" + + "VtU5+mc0YtsPQIpKCBJOYt05bgpX5aPQ3s2lviYw3bvP0TrclYs/rx4wKVgW" + + "2GYLzPh0OVMBduCbzW1E58ieBsgRyQ7+2MTl9Nj+nznjCAfLSvrVEcwxVUQA" + + "ofcEbiECEJss2JNQq8erwgo8dP3atwQ1KeqMc8acICcOrI2rNxwVOLzPuCsl" + + "l8gwZOoxLZXuKMQbQu4as1HNS309dfWIWppvc3K4nDWg51HUCPbsIo3wm3rR" + + "igc/W3bf4Ppg0pLAS5c1s0Xau43u9GmIjGiDqYaasfcXnCKy2LNuUpbhoOC1" + + "o/wMC9gT45aJQ5vsVGe5XvfhLV7Y815EdI756s9PIEOnG8HbAtCAjOIVpQfP" + + "eF8+cnZyGGdsbmu7lYzg3whCpZ/L2RrTI86nEn5eePs4m2hDV0Oi9r6e2CIf" + + "nGUa0TB9jf1OMhOSBD+h4jx7b6uT+XLmG8qUxvkoItMDZLrJ0f8czO5MyOZa" + + "nEJoG42Fy2p7zD/qO72OUQISNmt8C1rQFsg9dBDib4DMu69vBsVrIV028sal" + + "+tq1UH3vFMbEYyVfPH3WDgxyHwUQK2qrz3WBdD/BMyuAV4DPI3SPTweROh8n" + + "yWJN1ppY9qybmTyHFCs6TRjPB9cVcdKSc0qYxgzblJiXXb3s9ANOb89aA3Ah" + + "anWnAhcEggLZN2yFCtrRuvJXvDQhj8qmye9UkjB2fEpWXV7H0natE3hSoB+C" + + "2krt3eBV0xJ1tLEco7T4zsbQQJRmeu/essOsfwpRfE5ZPoIeThf+UmWTsfsw" + + "r4fxeePMTy6iCnkF5/ro8k5WKnOsaV+HWy/ulwW2r/DMT3aDBWfHX5Hk8DpU" + + "+PlQhbyGTSTIJ/OFmbcWjMPt469o7+KrrF9IBrzJ42KzMw6xtKwtVb0232AM" + + "pIwnLzCHIiNO2qDBZAIDdF68+GU3RsEkHfR6d5myZVxnH4mhSCFFtHxgqTOz" + + "Ouo/uvgu72miZ0OFAy1zcMtfGMS3Md54MJkhSZq4ZgUo/EyJCeEDLGn8pMF1" + + "jX1WsUj96qMRyc+p2KnKs6ZL95BVa76SdIFz6ts6uoIem3drTXYJHNbw29OW" + + "Y0am+FmXTWFZFnin8Qu5Xct5l7FYIGA9VLOHL9Vtp+SXomcFEZpjMaxvtf4R" + + "xoAI2Bc9Ka+MNiz35O0JXhI9/t5uOdiN6ZOJlfpEWOK7ou5lDkZuDcrHvLvQ" + + "PocP2Yemd36xEgjFssR/tFITlhRBXHDeHwpvmXM4iiwD1wOGMqybXx/1g1m1" + + "0UBbKqDsgSLQC7c0TaRFJjj71T74PBMiapiQgijv9WINfmTgxNUukbK3Kqp/" + + "G3BmThoIDCB8WD1kxXBpaG62dSsih7yhPQJVEV3Y0tdkdChOk+Y3Wf8crV/Q" + + "P08pQH7H9yCi04S5fSJtIDtYARWhr1yl8EQMnu2X8J6r/DWcDmXUK4Bv1vqe" + + "tcnT5EAYFPeOMz21nonM3kJgUMNsxCQjKaEMEcUu8ZRnGUAFdG4lULPJn5NQ" + + "LTvWg8Y3GrHRLjpnd9k+8gWWzRIbBiwCwEbClMZffRd6kcA5ZoOhVngdyvvj" + + "BhkgadB5jC+ZRzExHxoEhzPJx3mxIVTqLuw7QxHz9OTcysvY/cGKCvmgzgk/" + + "TjTJsqcEAAAAAAAAAAAAAAAAAAAAAAAAMD0wITAJBgUrDgMCGgUABBQWfGA6" + + "lI+TXQiuXaa1V+LlHodhXAQUAwMIAAUvBYY+a7sXNlQeVEPAGkMCAgQAAAA="); } diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/LoggingDatagramTransport.java b/src/test/java/org/bouncycastle/crypto/tls/test/LoggingDatagramTransport.java index a0cf192b..41816193 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/LoggingDatagramTransport.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/LoggingDatagramTransport.java @@ -1,68 +1,91 @@ -package org.bouncycastle.crypto.tls.test; - -import java.io.IOException; -import java.io.PrintStream; - -import org.bouncycastle.crypto.tls.DatagramTransport; - -public class LoggingDatagramTransport implements DatagramTransport { - - private static final String HEX_CHARS = "0123456789ABCDEF"; - - private final DatagramTransport transport; - private final PrintStream output; - private final long launchTimestamp; - - public LoggingDatagramTransport(DatagramTransport transport, PrintStream output) { - this.transport = transport; - this.output = output; - this.launchTimestamp = System.currentTimeMillis(); - } - - public int getReceiveLimit() throws IOException { - return transport.getReceiveLimit(); - } - - public int getSendLimit() throws IOException { - return transport.getSendLimit(); - } - - public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { - int length = transport.receive(buf, off, len, waitMillis); - if (length >= 0) { - dumpDatagram("Received", buf, off, length); - } - return length; - } - - public void send(byte[] buf, int off, int len) throws IOException { - dumpDatagram("Sending", buf, off, len); - transport.send(buf, off, len); - } - - public void close() throws IOException { - } - - private void dumpDatagram(String verb, byte[] buf, int off, int len) throws IOException { - long timestamp = System.currentTimeMillis() - launchTimestamp; - StringBuffer sb = new StringBuffer("(+" + timestamp + "ms) " + verb + " " + len + " byte datagram:"); - for (int pos = 0; pos < len; ++pos) { - if (pos % 16 == 0) { - sb.append(System.lineSeparator()); - sb.append(" "); - } else if (pos % 16 == 8) { - sb.append('-'); - } else { - sb.append(' '); - } - int val = buf[off + pos] & 0xFF; - sb.append(HEX_CHARS.charAt(val >> 4)); - sb.append(HEX_CHARS.charAt(val & 0xF)); - } - dump(sb.toString()); - } - - private synchronized void dump(String s) { - output.println(s); - } -} +package org.bouncycastle.crypto.tls.test; + +import java.io.IOException; +import java.io.PrintStream; + +import org.bouncycastle.crypto.tls.DatagramTransport; + +public class LoggingDatagramTransport + implements DatagramTransport +{ + + private static final String HEX_CHARS = "0123456789ABCDEF"; + + private final DatagramTransport transport; + private final PrintStream output; + private final long launchTimestamp; + + public LoggingDatagramTransport(DatagramTransport transport, PrintStream output) + { + this.transport = transport; + this.output = output; + this.launchTimestamp = System.currentTimeMillis(); + } + + public int getReceiveLimit() + throws IOException + { + return transport.getReceiveLimit(); + } + + public int getSendLimit() + throws IOException + { + return transport.getSendLimit(); + } + + public int receive(byte[] buf, int off, int len, int waitMillis) + throws IOException + { + int length = transport.receive(buf, off, len, waitMillis); + if (length >= 0) + { + dumpDatagram("Received", buf, off, length); + } + return length; + } + + public void send(byte[] buf, int off, int len) + throws IOException + { + dumpDatagram("Sending", buf, off, len); + transport.send(buf, off, len); + } + + public void close() + throws IOException + { + } + + private void dumpDatagram(String verb, byte[] buf, int off, int len) + throws IOException + { + long timestamp = System.currentTimeMillis() - launchTimestamp; + StringBuffer sb = new StringBuffer("(+" + timestamp + "ms) " + verb + " " + len + " byte datagram:"); + for (int pos = 0; pos < len; ++pos) + { + if (pos % 16 == 0) + { + sb.append(System.getProperty("line.separator")); + sb.append(" "); + } + else if (pos % 16 == 8) + { + sb.append('-'); + } + else + { + sb.append(' '); + } + int val = buf[off + pos] & 0xFF; + sb.append(HEX_CHARS.charAt(val >> 4)); + sb.append(HEX_CHARS.charAt(val & 0xF)); + } + dump(sb.toString()); + } + + private synchronized void dump(String s) + { + output.println(s); + } +} diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/MockDTLSClient.java b/src/test/java/org/bouncycastle/crypto/tls/test/MockDTLSClient.java index b8b34e5e..46ae7e68 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/MockDTLSClient.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/MockDTLSClient.java @@ -1,71 +1,89 @@ -package org.bouncycastle.crypto.tls.test; - -import java.io.IOException; -import java.io.PrintStream; - -import org.bouncycastle.asn1.x509.Certificate; -import org.bouncycastle.crypto.tls.AlertLevel; -import org.bouncycastle.crypto.tls.CertificateRequest; -import org.bouncycastle.crypto.tls.ClientCertificateType; -import org.bouncycastle.crypto.tls.DefaultTlsClient; -import org.bouncycastle.crypto.tls.ProtocolVersion; -import org.bouncycastle.crypto.tls.TlsAuthentication; -import org.bouncycastle.crypto.tls.TlsCredentials; - -public class MockDTLSClient extends DefaultTlsClient { - - public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("DTLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription - + ")"); - if (message != null) { - out.println(message); - } - if (cause != null) { - cause.printStackTrace(out); - } - } - - public void notifyAlertReceived(short alertLevel, short alertDescription) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("DTLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription - + ")"); - } - - public ProtocolVersion getClientVersion() { - return ProtocolVersion.DTLSv10; - } - - public ProtocolVersion getMinimumVersion() { - return ProtocolVersion.DTLSv10; - } - - public TlsAuthentication getAuthentication() throws IOException { - return new TlsAuthentication() { - public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) - throws IOException { - Certificate[] chain = serverCertificate.getCertificateList(); - System.out.println("Received server certificate chain of length " + chain.length); - for (Certificate entry : chain) { - // TODO Create fingerprint based on certificate signature algorithm digest - System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" - + entry.getSubject() + ")"); - } - } - - public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException { - short[] certificateTypes = certificateRequest.getCertificateTypes(); - if (certificateTypes != null) { - for (int i = 0; i < certificateTypes.length; ++i) { - if (certificateTypes[i] == ClientCertificateType.rsa_sign) { - // TODO Create a distinct client certificate for use here - return TlsTestUtils.loadSignerCredentials(context, new String[] { "x509-server.pem", - "x509-ca.pem" }, "x509-server-key.pem"); - } - } - } - return null; - } - }; - } -} +package org.bouncycastle.crypto.tls.test; + +import java.io.IOException; +import java.io.PrintStream; + +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.crypto.tls.AlertLevel; +import org.bouncycastle.crypto.tls.CertificateRequest; +import org.bouncycastle.crypto.tls.ClientCertificateType; +import org.bouncycastle.crypto.tls.DefaultTlsClient; +import org.bouncycastle.crypto.tls.ProtocolVersion; +import org.bouncycastle.crypto.tls.TlsAuthentication; +import org.bouncycastle.crypto.tls.TlsCredentials; + +public class MockDTLSClient + extends DefaultTlsClient +{ + + public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("DTLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + + ")"); + if (message != null) + { + out.println(message); + } + if (cause != null) + { + cause.printStackTrace(out); + } + } + + public void notifyAlertReceived(short alertLevel, short alertDescription) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("DTLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + + ")"); + } + + public ProtocolVersion getClientVersion() + { + return ProtocolVersion.DTLSv10; + } + + public ProtocolVersion getMinimumVersion() + { + return ProtocolVersion.DTLSv10; + } + + public TlsAuthentication getAuthentication() + throws IOException + { + return new TlsAuthentication() + { + public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) + throws IOException + { + Certificate[] chain = serverCertificate.getCertificateList(); + System.out.println("Received server certificate chain of length " + chain.length); + for (Certificate entry : chain) + { + // TODO Create fingerprint based on certificate signature algorithm digest + System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" + + entry.getSubject() + ")"); + } + } + + public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) + throws IOException + { + short[] certificateTypes = certificateRequest.getCertificateTypes(); + if (certificateTypes != null) + { + for (int i = 0; i < certificateTypes.length; ++i) + { + if (certificateTypes[i] == ClientCertificateType.rsa_sign) + { + // TODO Create a distinct client certificate for use here + return TlsTestUtils.loadSignerCredentials(context, new String[]{"x509-server.pem", + "x509-ca.pem"}, "x509-server-key.pem"); + } + } + } + return null; + } + }; + } +} diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/MockDTLSServer.java b/src/test/java/org/bouncycastle/crypto/tls/test/MockDTLSServer.java index ca182036..89368411 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/MockDTLSServer.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/MockDTLSServer.java @@ -1,66 +1,82 @@ -package org.bouncycastle.crypto.tls.test; - -import java.io.IOException; -import java.io.PrintStream; - -import org.bouncycastle.asn1.x509.Certificate; -import org.bouncycastle.crypto.tls.AlertLevel; -import org.bouncycastle.crypto.tls.CertificateRequest; -import org.bouncycastle.crypto.tls.ClientCertificateType; -import org.bouncycastle.crypto.tls.DefaultTlsServer; -import org.bouncycastle.crypto.tls.ProtocolVersion; -import org.bouncycastle.crypto.tls.TlsEncryptionCredentials; -import org.bouncycastle.crypto.tls.TlsSignerCredentials; - -public class MockDTLSServer extends DefaultTlsServer { - - public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("DTLS server raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription - + ")"); - if (message != null) { - out.println(message); - } - if (cause != null) { - cause.printStackTrace(out); - } - } - - public void notifyAlertReceived(short alertLevel, short alertDescription) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("DTLS server received alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription - + ")"); - } - - public CertificateRequest getCertificateRequest() { - return new CertificateRequest(new short[] { ClientCertificateType.rsa_sign }, null); - } - - public void notifyClientCertificate(org.bouncycastle.crypto.tls.Certificate clientCertificate) throws IOException { - Certificate[] chain = clientCertificate.getCertificateList(); - System.out.println("Received client certificate chain of length " + chain.length); - for (Certificate entry : chain) { - // TODO Create fingerprint based on certificate signature algorithm digest - System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" + entry.getSubject() - + ")"); - } - } - - protected ProtocolVersion getMaximumVersion() { - return ProtocolVersion.DTLSv10; - } - - protected ProtocolVersion getMinimumVersion() { - return ProtocolVersion.DTLSv10; - } - - protected TlsEncryptionCredentials getRSAEncryptionCredentials() throws IOException { - return TlsTestUtils.loadEncryptionCredentials(context, new String[] { "x509-server.pem", "x509-ca.pem" }, - "x509-server-key.pem"); - } - - protected TlsSignerCredentials getRSASignerCredentials() throws IOException { - return TlsTestUtils.loadSignerCredentials(context, new String[] { "x509-server.pem", "x509-ca.pem" }, - "x509-server-key.pem"); - } -} +package org.bouncycastle.crypto.tls.test; + +import java.io.IOException; +import java.io.PrintStream; + +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.crypto.tls.AlertLevel; +import org.bouncycastle.crypto.tls.CertificateRequest; +import org.bouncycastle.crypto.tls.ClientCertificateType; +import org.bouncycastle.crypto.tls.DefaultTlsServer; +import org.bouncycastle.crypto.tls.ProtocolVersion; +import org.bouncycastle.crypto.tls.TlsEncryptionCredentials; +import org.bouncycastle.crypto.tls.TlsSignerCredentials; + +public class MockDTLSServer + extends DefaultTlsServer +{ + + public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("DTLS server raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + + ")"); + if (message != null) + { + out.println(message); + } + if (cause != null) + { + cause.printStackTrace(out); + } + } + + public void notifyAlertReceived(short alertLevel, short alertDescription) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("DTLS server received alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + + ")"); + } + + public CertificateRequest getCertificateRequest() + { + return new CertificateRequest(new short[]{ClientCertificateType.rsa_sign}, null); + } + + public void notifyClientCertificate(org.bouncycastle.crypto.tls.Certificate clientCertificate) + throws IOException + { + Certificate[] chain = clientCertificate.getCertificateList(); + System.out.println("Received client certificate chain of length " + chain.length); + for (Certificate entry : chain) + { + // TODO Create fingerprint based on certificate signature algorithm digest + System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" + entry.getSubject() + + ")"); + } + } + + protected ProtocolVersion getMaximumVersion() + { + return ProtocolVersion.DTLSv10; + } + + protected ProtocolVersion getMinimumVersion() + { + return ProtocolVersion.DTLSv10; + } + + protected TlsEncryptionCredentials getRSAEncryptionCredentials() + throws IOException + { + return TlsTestUtils.loadEncryptionCredentials(context, new String[]{"x509-server.pem", "x509-ca.pem"}, + "x509-server-key.pem"); + } + + protected TlsSignerCredentials getRSASignerCredentials() + throws IOException + { + return TlsTestUtils.loadSignerCredentials(context, new String[]{"x509-server.pem", "x509-ca.pem"}, + "x509-server-key.pem"); + } +} diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/MockDatagramAssociation.java b/src/test/java/org/bouncycastle/crypto/tls/test/MockDatagramAssociation.java index dd74a72f..31444989 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/MockDatagramAssociation.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/MockDatagramAssociation.java @@ -1,88 +1,113 @@ -package org.bouncycastle.crypto.tls.test; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.util.Vector; - -import org.bouncycastle.crypto.tls.DatagramTransport; - -public class MockDatagramAssociation { - - private int mtu; - private MockDatagramTransport client, server; - - public MockDatagramAssociation(int mtu) { - - this.mtu = mtu; - - Vector clientQueue = new Vector(); - Vector serverQueue = new Vector(); - - this.client = new MockDatagramTransport(clientQueue, serverQueue); - this.server = new MockDatagramTransport(serverQueue, clientQueue); - } - - public DatagramTransport getClient() { - return client; - } - - public DatagramTransport getServer() { - return server; - } - - private class MockDatagramTransport implements DatagramTransport { - - private Vector receiveQueue, sendQueue; - - MockDatagramTransport(Vector receiveQueue, Vector sendQueue) { - this.receiveQueue = receiveQueue; - this.sendQueue = sendQueue; - } - - public int getReceiveLimit() throws IOException { - return mtu; - } - - public int getSendLimit() throws IOException { - return mtu; - } - - public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { - synchronized (receiveQueue) { - if (receiveQueue.isEmpty()) { - try { - receiveQueue.wait(waitMillis); - } catch (InterruptedException e) { - // TODO Keep waiting until full wait expired? - } - if (receiveQueue.isEmpty()) { - return -1; - } - } - DatagramPacket packet = (DatagramPacket) receiveQueue.remove(0); - int copyLength = Math.min(len, packet.getLength()); - System.arraycopy(packet.getData(), packet.getOffset(), buf, off, copyLength); - return copyLength; - } - } - - public void send(byte[] buf, int off, int len) throws IOException { - if (len > mtu) { - // TODO Simulate rejection? - } - - byte[] copy = new byte[len]; - System.arraycopy(buf, off, copy, 0, len); - DatagramPacket packet = new DatagramPacket(copy, len); - - synchronized (sendQueue) { - sendQueue.addElement(packet); - sendQueue.notify(); - } - } - - public void close() throws IOException { - // TODO? - } - } -} +package org.bouncycastle.crypto.tls.test; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.util.Vector; + +import org.bouncycastle.crypto.tls.DatagramTransport; + +public class MockDatagramAssociation +{ + + private int mtu; + private MockDatagramTransport client, server; + + public MockDatagramAssociation(int mtu) + { + + this.mtu = mtu; + + Vector clientQueue = new Vector(); + Vector serverQueue = new Vector(); + + this.client = new MockDatagramTransport(clientQueue, serverQueue); + this.server = new MockDatagramTransport(serverQueue, clientQueue); + } + + public DatagramTransport getClient() + { + return client; + } + + public DatagramTransport getServer() + { + return server; + } + + private class MockDatagramTransport + implements DatagramTransport + { + + private Vector receiveQueue, sendQueue; + + MockDatagramTransport(Vector receiveQueue, Vector sendQueue) + { + this.receiveQueue = receiveQueue; + this.sendQueue = sendQueue; + } + + public int getReceiveLimit() + throws IOException + { + return mtu; + } + + public int getSendLimit() + throws IOException + { + return mtu; + } + + public int receive(byte[] buf, int off, int len, int waitMillis) + throws IOException + { + synchronized (receiveQueue) + { + if (receiveQueue.isEmpty()) + { + try + { + receiveQueue.wait(waitMillis); + } + catch (InterruptedException e) + { + // TODO Keep waiting until full wait expired? + } + if (receiveQueue.isEmpty()) + { + return -1; + } + } + DatagramPacket packet = (DatagramPacket)receiveQueue.remove(0); + int copyLength = Math.min(len, packet.getLength()); + System.arraycopy(packet.getData(), packet.getOffset(), buf, off, copyLength); + return copyLength; + } + } + + public void send(byte[] buf, int off, int len) + throws IOException + { + if (len > mtu) + { + // TODO Simulate rejection? + } + + byte[] copy = new byte[len]; + System.arraycopy(buf, off, copy, 0, len); + DatagramPacket packet = new DatagramPacket(copy, len); + + synchronized (sendQueue) + { + sendQueue.addElement(packet); + sendQueue.notify(); + } + } + + public void close() + throws IOException + { + // TODO? + } + } +} diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/TestTlsClient.java b/src/test/java/org/bouncycastle/crypto/tls/test/TestTlsClient.java new file mode 100644 index 00000000..fdca978e --- /dev/null +++ b/src/test/java/org/bouncycastle/crypto/tls/test/TestTlsClient.java @@ -0,0 +1,23 @@ +package org.bouncycastle.crypto.tls.test; + +import java.io.IOException; + +import org.bouncycastle.crypto.tls.DefaultTlsClient; +import org.bouncycastle.crypto.tls.TlsAuthentication; + +public class TestTlsClient + extends DefaultTlsClient +{ + private final TlsAuthentication authentication; + + TestTlsClient(TlsAuthentication authentication) + { + this.authentication = authentication; + } + + public TlsAuthentication getAuthentication() + throws IOException + { + return authentication; + } +} diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/TlsClientTest.java b/src/test/java/org/bouncycastle/crypto/tls/test/TlsClientTest.java index 5c7ecab9..c7bb8332 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/TlsClientTest.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/TlsClientTest.java @@ -1,89 +1,104 @@ -package org.bouncycastle.crypto.tls.test; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.net.InetAddress; -import java.net.Socket; -import java.security.SecureRandom; - -import org.bouncycastle.asn1.x509.Certificate; -import org.bouncycastle.crypto.tls.AlertLevel; -import org.bouncycastle.crypto.tls.CipherSuite; -import org.bouncycastle.crypto.tls.DefaultTlsClient; -import org.bouncycastle.crypto.tls.ServerOnlyTlsAuthentication; -import org.bouncycastle.crypto.tls.TlsAuthentication; -import org.bouncycastle.crypto.tls.TlsClientProtocol; -import org.bouncycastle.util.io.Streams; - -/** - * A simple test designed to conduct a TLS handshake with an external TLS server. - * - * Please refer to GnuTLSSetup.txt or OpenSSLSetup.txt, and x509-*.pem files in this package for - * help configuring an external TLS server. - */ -public class TlsClientTest { - - public static void main(String[] args) throws Exception { - - Socket socket = new Socket(InetAddress.getLocalHost(), 5556); - - SecureRandom secureRandom = new SecureRandom(); - TlsClientProtocol protocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), - secureRandom); - - MyTlsClient client = new MyTlsClient(); - protocol.connect(client); - - OutputStream output = protocol.getOutputStream(); - output.write("GET / HTTP/1.1\r\n\r\n".getBytes("UTF-8")); - - InputStream input = protocol.getInputStream(); - byte[] result = Streams.readAll(input); - - System.out.println(new String(result, "UTF-8")); - - protocol.close(); - socket.close(); - } - - static class MyTlsClient extends DefaultTlsClient { - - public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("TLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription - + ")"); - if (message != null) { - out.println(message); - } - if (cause != null) { - cause.printStackTrace(out); - } - } - - public void notifyAlertReceived(short alertLevel, short alertDescription) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("TLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." - + alertDescription + ")"); - } - - public int[] getCipherSuites() { - return new int[] { CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, - CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA, }; - } - - public TlsAuthentication getAuthentication() throws IOException { - return new ServerOnlyTlsAuthentication() { - public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) - throws IOException { - Certificate[] chain = serverCertificate.getCertificateList(); - System.out.println("Received server certificate chain with " + chain.length + " entries"); - for (Certificate entry : chain) { - System.out.println(" " + entry.getSubject()); - } - } - }; - } - } -} +package org.bouncycastle.crypto.tls.test; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.InetAddress; +import java.net.Socket; +import java.security.SecureRandom; + +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.crypto.tls.AlertLevel; +import org.bouncycastle.crypto.tls.CipherSuite; +import org.bouncycastle.crypto.tls.DefaultTlsClient; +import org.bouncycastle.crypto.tls.ServerOnlyTlsAuthentication; +import org.bouncycastle.crypto.tls.TlsAuthentication; +import org.bouncycastle.crypto.tls.TlsClientProtocol; +import org.bouncycastle.util.io.Streams; + +/** + * A simple test designed to conduct a TLS handshake with an external TLS server. + *

+ * Please refer to GnuTLSSetup.txt or OpenSSLSetup.txt, and x509-*.pem files in this package for + * help configuring an external TLS server. + */ +public class TlsClientTest +{ + + public static void main(String[] args) + throws Exception + { + + Socket socket = new Socket(InetAddress.getLocalHost(), 5556); + + SecureRandom secureRandom = new SecureRandom(); + TlsClientProtocol protocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), + secureRandom); + + MyTlsClient client = new MyTlsClient(); + protocol.connect(client); + + OutputStream output = protocol.getOutputStream(); + output.write("GET / HTTP/1.1\r\n\r\n".getBytes("UTF-8")); + + InputStream input = protocol.getInputStream(); + byte[] result = Streams.readAll(input); + + System.out.println(new String(result, "UTF-8")); + + protocol.close(); + socket.close(); + } + + static class MyTlsClient + extends DefaultTlsClient + { + + public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + + ")"); + if (message != null) + { + out.println(message); + } + if (cause != null) + { + cause.printStackTrace(out); + } + } + + public void notifyAlertReceived(short alertLevel, short alertDescription) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." + + alertDescription + ")"); + } + + public int[] getCipherSuites() + { + return new int[]{CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,}; + } + + public TlsAuthentication getAuthentication() + throws IOException + { + return new ServerOnlyTlsAuthentication() + { + public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) + throws IOException + { + Certificate[] chain = serverCertificate.getCertificateList(); + System.out.println("Received server certificate chain with " + chain.length + " entries"); + for (Certificate entry : chain) + { + System.out.println(" " + entry.getSubject()); + } + } + }; + } + } +} diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/TlsProtocolTest.java b/src/test/java/org/bouncycastle/crypto/tls/test/TlsProtocolTest.java index 403b5682..916b0200 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/TlsProtocolTest.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/TlsProtocolTest.java @@ -1,178 +1,211 @@ -package org.bouncycastle.crypto.tls.test; - -import java.io.IOException; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.io.PrintStream; -import java.security.SecureRandom; - -import junit.framework.TestCase; - -import org.bouncycastle.asn1.x509.Certificate; -import org.bouncycastle.crypto.digests.SHA256Digest; -import org.bouncycastle.crypto.tls.AlertDescription; -import org.bouncycastle.crypto.tls.AlertLevel; -import org.bouncycastle.crypto.tls.CertificateRequest; -import org.bouncycastle.crypto.tls.CipherSuite; -import org.bouncycastle.crypto.tls.ClientCertificateType; -import org.bouncycastle.crypto.tls.DefaultTlsClient; -import org.bouncycastle.crypto.tls.DefaultTlsServer; -import org.bouncycastle.crypto.tls.ServerOnlyTlsAuthentication; -import org.bouncycastle.crypto.tls.TlsAuthentication; -import org.bouncycastle.crypto.tls.TlsClientProtocol; -import org.bouncycastle.crypto.tls.TlsCredentials; -import org.bouncycastle.crypto.tls.TlsEncryptionCredentials; -import org.bouncycastle.crypto.tls.TlsFatalAlert; -import org.bouncycastle.crypto.tls.TlsServerProtocol; -import org.bouncycastle.crypto.tls.TlsSignerCredentials; -import org.bouncycastle.util.encoders.Hex; - -public class TlsProtocolTest extends TestCase { - - public void testClientServer() throws Exception { - - SecureRandom secureRandom = new SecureRandom(); - - PipedInputStream clientRead = new PipedInputStream(); - PipedInputStream serverRead = new PipedInputStream(); - PipedOutputStream clientWrite = new PipedOutputStream(serverRead); - PipedOutputStream serverWrite = new PipedOutputStream(clientRead); - - TlsClientProtocol clientProtocol = new TlsClientProtocol(clientRead, clientWrite, secureRandom); - TlsServerProtocol serverProtocol = new TlsServerProtocol(serverRead, serverWrite, secureRandom); - - ServerThread serverThread = new ServerThread(serverProtocol); - serverThread.start(); - - MyTlsClient client = new MyTlsClient(); - clientProtocol.connect(client); - - // byte[] data = new byte[64]; - // secureRandom.nextBytes(data); - // - // OutputStream output = clientProtocol.getOutputStream(); - // output.write(data); - // output.close(); - // - // byte[] echo = Streams.readAll(clientProtocol.getInputStream()); - serverThread.join(); - - // assertTrue(Arrays.areEqual(data, echo)); - } - - static class ServerThread extends Thread { - private final TlsServerProtocol serverProtocol; - - ServerThread(TlsServerProtocol serverProtocol) { - this.serverProtocol = serverProtocol; - } - - public void run() { - try { - MyTlsServer server = new MyTlsServer(); - serverProtocol.accept(server); - // Streams.pipeAll(serverProtocol.getInputStream(), - // serverProtocol.getOutputStream()); - serverProtocol.close(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - static class MyTlsClient extends DefaultTlsClient { - - public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("TLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription - + ")"); - if (message != null) { - out.println(message); - } - if (cause != null) { - cause.printStackTrace(out); - } - } - - public void notifyAlertReceived(short alertLevel, short alertDescription) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("TLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." - + alertDescription + ")"); - } - - public TlsAuthentication getAuthentication() throws IOException { - return new TlsAuthentication() { - public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) - throws IOException { - Certificate[] chain = serverCertificate.getCertificateList(); - System.out.println("Received server certificate chain of length " + chain.length); - for (Certificate entry : chain) { - // TODO Create fingerprint based on certificate signature algorithm digest - System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" - + entry.getSubject() + ")"); - } - } - - public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException { - short[] certificateTypes = certificateRequest.getCertificateTypes(); - if (certificateTypes != null) { - for (int i = 0; i < certificateTypes.length; ++i) { - if (certificateTypes[i] == ClientCertificateType.rsa_sign) { - // TODO Create a distinct client certificate for use here - return TlsTestUtils.loadSignerCredentials(context, new String[] { "x509-server.pem", - "x509-ca.pem" }, "x509-server-key.pem"); - } - } - } - return null; - } - }; - } - } - - static class MyTlsServer extends DefaultTlsServer { - - public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("TLS server raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription - + ")"); - if (message != null) { - out.println(message); - } - if (cause != null) { - cause.printStackTrace(out); - } - } - - public void notifyAlertReceived(short alertLevel, short alertDescription) { - PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; - out.println("TLS server received alert (AlertLevel." + alertLevel + ", AlertDescription." - + alertDescription + ")"); - } - - public CertificateRequest getCertificateRequest() { - return new CertificateRequest(new short[] { ClientCertificateType.rsa_sign }, null); - } - - public void notifyClientCertificate(org.bouncycastle.crypto.tls.Certificate clientCertificate) - throws IOException { - Certificate[] chain = clientCertificate.getCertificateList(); - System.out.println("Received client certificate chain of length " + chain.length); - for (Certificate entry : chain) { - // TODO Create fingerprint based on certificate signature algorithm digest - System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" - + entry.getSubject() + ")"); - } - } - - protected TlsEncryptionCredentials getRSAEncryptionCredentials() throws IOException { - return TlsTestUtils.loadEncryptionCredentials(context, new String[] { "x509-server.pem", "x509-ca.pem" }, - "x509-server-key.pem"); - } - - protected TlsSignerCredentials getRSASignerCredentials() throws IOException { - return TlsTestUtils.loadSignerCredentials(context, new String[] { "x509-server.pem", "x509-ca.pem" }, - "x509-server-key.pem"); - } - } -} +package org.bouncycastle.crypto.tls.test; + +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.security.SecureRandom; + +import junit.framework.TestCase; +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.crypto.tls.AlertLevel; +import org.bouncycastle.crypto.tls.CertificateRequest; +import org.bouncycastle.crypto.tls.ClientCertificateType; +import org.bouncycastle.crypto.tls.DefaultTlsClient; +import org.bouncycastle.crypto.tls.DefaultTlsServer; +import org.bouncycastle.crypto.tls.TlsAuthentication; +import org.bouncycastle.crypto.tls.TlsClientProtocol; +import org.bouncycastle.crypto.tls.TlsCredentials; +import org.bouncycastle.crypto.tls.TlsEncryptionCredentials; +import org.bouncycastle.crypto.tls.TlsServerProtocol; +import org.bouncycastle.crypto.tls.TlsSignerCredentials; + +public class TlsProtocolTest + extends TestCase +{ + + public void testClientServer() + throws Exception + { + + SecureRandom secureRandom = new SecureRandom(); + + PipedInputStream clientRead = new PipedInputStream(); + PipedInputStream serverRead = new PipedInputStream(); + PipedOutputStream clientWrite = new PipedOutputStream(serverRead); + PipedOutputStream serverWrite = new PipedOutputStream(clientRead); + + TlsClientProtocol clientProtocol = new TlsClientProtocol(clientRead, clientWrite, secureRandom); + TlsServerProtocol serverProtocol = new TlsServerProtocol(serverRead, serverWrite, secureRandom); + + ServerThread serverThread = new ServerThread(serverProtocol); + serverThread.start(); + + MyTlsClient client = new MyTlsClient(); + clientProtocol.connect(client); + + // byte[] data = new byte[64]; + // secureRandom.nextBytes(data); + // + // OutputStream output = clientProtocol.getOutputStream(); + // output.write(data); + // output.close(); + // + // byte[] echo = Streams.readAll(clientProtocol.getInputStream()); + serverThread.join(); + + // assertTrue(Arrays.areEqual(data, echo)); + } + + static class ServerThread + extends Thread + { + private final TlsServerProtocol serverProtocol; + + ServerThread(TlsServerProtocol serverProtocol) + { + this.serverProtocol = serverProtocol; + } + + public void run() + { + try + { + MyTlsServer server = new MyTlsServer(); + serverProtocol.accept(server); + // Streams.pipeAll(serverProtocol.getInputStream(), + // serverProtocol.getOutputStream()); + serverProtocol.close(); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + } + + static class MyTlsClient + extends DefaultTlsClient + { + + public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + + ")"); + if (message != null) + { + out.println(message); + } + if (cause != null) + { + cause.printStackTrace(out); + } + } + + public void notifyAlertReceived(short alertLevel, short alertDescription) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS client received alert (AlertLevel." + alertLevel + ", AlertDescription." + + alertDescription + ")"); + } + + public TlsAuthentication getAuthentication() + throws IOException + { + return new TlsAuthentication() + { + public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) + throws IOException + { + Certificate[] chain = serverCertificate.getCertificateList(); + System.out.println("Received server certificate chain of length " + chain.length); + for (Certificate entry : chain) + { + // TODO Create fingerprint based on certificate signature algorithm digest + System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" + + entry.getSubject() + ")"); + } + } + + public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) + throws IOException + { + short[] certificateTypes = certificateRequest.getCertificateTypes(); + if (certificateTypes != null) + { + for (int i = 0; i < certificateTypes.length; ++i) + { + if (certificateTypes[i] == ClientCertificateType.rsa_sign) + { + // TODO Create a distinct client certificate for use here + return TlsTestUtils.loadSignerCredentials(context, new String[]{"x509-server.pem", + "x509-ca.pem"}, "x509-server-key.pem"); + } + } + } + return null; + } + }; + } + } + + static class MyTlsServer + extends DefaultTlsServer + { + + public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS server raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + + ")"); + if (message != null) + { + out.println(message); + } + if (cause != null) + { + cause.printStackTrace(out); + } + } + + public void notifyAlertReceived(short alertLevel, short alertDescription) + { + PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out; + out.println("TLS server received alert (AlertLevel." + alertLevel + ", AlertDescription." + + alertDescription + ")"); + } + + public CertificateRequest getCertificateRequest() + { + return new CertificateRequest(new short[]{ClientCertificateType.rsa_sign}, null); + } + + public void notifyClientCertificate(org.bouncycastle.crypto.tls.Certificate clientCertificate) + throws IOException + { + Certificate[] chain = clientCertificate.getCertificateList(); + System.out.println("Received client certificate chain of length " + chain.length); + for (Certificate entry : chain) + { + // TODO Create fingerprint based on certificate signature algorithm digest + System.out.println(" fingerprint:SHA-256 " + TlsTestUtils.fingerprint(entry) + " (" + + entry.getSubject() + ")"); + } + } + + protected TlsEncryptionCredentials getRSAEncryptionCredentials() + throws IOException + { + return TlsTestUtils.loadEncryptionCredentials(context, new String[]{"x509-server.pem", "x509-ca.pem"}, + "x509-server-key.pem"); + } + + protected TlsSignerCredentials getRSASignerCredentials() + throws IOException + { + return TlsTestUtils.loadSignerCredentials(context, new String[]{"x509-server.pem", "x509-ca.pem"}, + "x509-server-key.pem"); + } + } +} diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestUtils.java b/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestUtils.java index 95805375..32a414b3 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestUtils.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/TlsTestUtils.java @@ -1,141 +1,163 @@ -package org.bouncycastle.crypto.tls.test; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import org.bouncycastle.asn1.pkcs.RSAPrivateKey; -import org.bouncycastle.crypto.digests.SHA256Digest; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; -import org.bouncycastle.crypto.tls.Certificate; -import org.bouncycastle.crypto.tls.DefaultTlsAgreementCredentials; -import org.bouncycastle.crypto.tls.DefaultTlsEncryptionCredentials; -import org.bouncycastle.crypto.tls.DefaultTlsSignerCredentials; -import org.bouncycastle.crypto.tls.TlsAgreementCredentials; -import org.bouncycastle.crypto.tls.TlsContext; -import org.bouncycastle.crypto.tls.TlsEncryptionCredentials; -import org.bouncycastle.crypto.tls.TlsSignerCredentials; -import org.bouncycastle.crypto.util.PrivateKeyFactory; -import org.bouncycastle.util.encoders.Base64; -import org.bouncycastle.util.encoders.Hex; -import org.bouncycastle.util.io.pem.PemObject; -import org.bouncycastle.util.io.pem.PemReader; - -public class TlsTestUtils { - static final byte[] rsaCertData = Base64 - .decode("MIICUzCCAf2gAwIBAgIBATANBgkqhkiG9w0BAQQFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb2" - + "4gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkq" - + "hkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTEzMDIyNTA2MDIwNVoXDTEzMDIyNT" - + "A2MDM0NVowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIw" - + "EAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG" - + "9AYm91bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb4Shy" - + "pL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERo0QwQjAOBgNVHQ8BAf8EBAMCBSAwEgYDVR" - + "0lAQH/BAgwBgYEVR0lADAcBgNVHREBAf8EEjAQgQ50ZXN0QHRlc3QudGVzdDANBgkqhkiG9w0BAQQFAANBAHU55Ncz" - + "eglREcTg54YLUlGWu2WOYWhit/iM1eeq8Kivro7q98eW52jTuMI3CI5ulqd0hYzshQKQaZ5GDzErMyM="); - - static final byte[] dudRsaCertData = Base64 - .decode("MIICUzCCAf2gAwIBAgIBATANBgkqhkiG9w0BAQQFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb2" - + "4gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkq" - + "hkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTEzMDIyNTA1NDcyOFoXDTEzMDIyNT" - + "A1NDkwOFowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIw" - + "EAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG" - + "9AYm91bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb4Shy" - + "pL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERo0QwQjAOBgNVHQ8BAf8EBAMCAAEwEgYDVR" - + "0lAQH/BAgwBgYEVR0lADAcBgNVHREBAf8EEjAQgQ50ZXN0QHRlc3QudGVzdDANBgkqhkiG9w0BAQQFAANBAJg55PBS" - + "weg6obRUKF4FF6fCrWFi6oCYSQ99LWcAeupc5BofW5MstFMhCOaEucuGVqunwT5G7/DweazzCIrSzB0="); - - static String fingerprint(org.bouncycastle.asn1.x509.Certificate c) throws IOException { - byte[] der = c.getEncoded(); - byte[] sha1 = sha256DigestOf(der); - byte[] hexBytes = Hex.encode(sha1); - String hex = new String(hexBytes, "ASCII").toUpperCase(); - - StringBuffer fp = new StringBuffer(); - int i = 0; - fp.append(hex.substring(i, i + 2)); - while ((i += 2) < hex.length()) { - fp.append(':'); - fp.append(hex.substring(i, i + 2)); - } - return fp.toString(); - } - - static byte[] sha256DigestOf(byte[] input) { - SHA256Digest d = new SHA256Digest(); - d.update(input, 0, input.length); - byte[] result = new byte[d.getDigestSize()]; - d.doFinal(result, 0); - return result; - } - - static TlsAgreementCredentials loadAgreementCredentials(TlsContext context, - String[] certResources, String keyResource) throws IOException { - - Certificate certificate = loadCertificateChain(certResources); - AsymmetricKeyParameter privateKey = loadPrivateKeyResource(keyResource); - - return new DefaultTlsAgreementCredentials(certificate, privateKey); - } - - static TlsEncryptionCredentials loadEncryptionCredentials(TlsContext context, - String[] certResources, String keyResource) throws IOException { - - Certificate certificate = loadCertificateChain(certResources); - AsymmetricKeyParameter privateKey = loadPrivateKeyResource(keyResource); - - return new DefaultTlsEncryptionCredentials(context, certificate, privateKey); - } - - static TlsSignerCredentials loadSignerCredentials(TlsContext context, String[] certResources, - String keyResource) throws IOException { - - Certificate certificate = loadCertificateChain(certResources); - AsymmetricKeyParameter privateKey = loadPrivateKeyResource(keyResource); - - return new DefaultTlsSignerCredentials(context, certificate, privateKey); - } - - static Certificate loadCertificateChain(String[] resources) throws IOException { - - org.bouncycastle.asn1.x509.Certificate[] chain = new org.bouncycastle.asn1.x509.Certificate[resources.length]; - for (int i = 0; i < resources.length; ++i) { - chain[i] = loadCertificateResource(resources[i]); - } - return new Certificate(chain); - } - - static org.bouncycastle.asn1.x509.Certificate loadCertificateResource(String resource) - throws IOException { - - PemObject pem = loadPemResource(resource); - if (pem.getType().endsWith("CERTIFICATE")) { - return org.bouncycastle.asn1.x509.Certificate.getInstance(pem.getContent()); - } - throw new IllegalArgumentException("'resource' doesn't specify a valid certificate"); - } - - static AsymmetricKeyParameter loadPrivateKeyResource(String resource) throws IOException { - - PemObject pem = loadPemResource(resource); - if (pem.getType().endsWith("RSA PRIVATE KEY")) { - RSAPrivateKey rsa = RSAPrivateKey.getInstance(pem.getContent()); - return new RSAPrivateCrtKeyParameters(rsa.getModulus(), rsa.getPublicExponent(), - rsa.getPrivateExponent(), rsa.getPrime1(), rsa.getPrime2(), rsa.getExponent1(), - rsa.getExponent2(), rsa.getCoefficient()); - } - if (pem.getType().endsWith("PRIVATE KEY")) { - return PrivateKeyFactory.createKey(pem.getContent()); - } - throw new IllegalArgumentException("'resource' doesn't specify a valid private key"); - } - - static PemObject loadPemResource(String resource) throws IOException { - - InputStream s = TlsTestUtils.class.getResourceAsStream(resource); - PemReader p = new PemReader(new InputStreamReader(s)); - PemObject o = p.readPemObject(); - p.close(); - return o; - } -} +package org.bouncycastle.crypto.tls.test; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.bouncycastle.asn1.pkcs.RSAPrivateKey; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; +import org.bouncycastle.crypto.tls.Certificate; +import org.bouncycastle.crypto.tls.DefaultTlsAgreementCredentials; +import org.bouncycastle.crypto.tls.DefaultTlsEncryptionCredentials; +import org.bouncycastle.crypto.tls.DefaultTlsSignerCredentials; +import org.bouncycastle.crypto.tls.TlsAgreementCredentials; +import org.bouncycastle.crypto.tls.TlsContext; +import org.bouncycastle.crypto.tls.TlsEncryptionCredentials; +import org.bouncycastle.crypto.tls.TlsSignerCredentials; +import org.bouncycastle.crypto.util.PrivateKeyFactory; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.io.pem.PemObject; +import org.bouncycastle.util.io.pem.PemReader; + +public class TlsTestUtils +{ + static final byte[] rsaCertData = Base64 + .decode("MIICUzCCAf2gAwIBAgIBATANBgkqhkiG9w0BAQQFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb2" + + "4gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkq" + + "hkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTEzMDIyNTA2MDIwNVoXDTEzMDIyNT" + + "A2MDM0NVowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIw" + + "EAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG" + + "9AYm91bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb4Shy" + + "pL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERo0QwQjAOBgNVHQ8BAf8EBAMCBSAwEgYDVR" + + "0lAQH/BAgwBgYEVR0lADAcBgNVHREBAf8EEjAQgQ50ZXN0QHRlc3QudGVzdDANBgkqhkiG9w0BAQQFAANBAHU55Ncz" + + "eglREcTg54YLUlGWu2WOYWhit/iM1eeq8Kivro7q98eW52jTuMI3CI5ulqd0hYzshQKQaZ5GDzErMyM="); + + static final byte[] dudRsaCertData = Base64 + .decode("MIICUzCCAf2gAwIBAgIBATANBgkqhkiG9w0BAQQFADCBjzELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb2" + + "4gb2YgdGhlIEJvdW5jeSBDYXN0bGUxEjAQBgNVBAcMCU1lbGJvdXJuZTERMA8GA1UECAwIVmljdG9yaWExLzAtBgkq" + + "hkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTEzMDIyNTA1NDcyOFoXDTEzMDIyNT" + + "A1NDkwOFowgY8xCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIw" + + "EAYDVQQHDAlNZWxib3VybmUxETAPBgNVBAgMCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWVkYmFjay1jcnlwdG" + + "9AYm91bmN5Y2FzdGxlLm9yZzBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr5YtqKmKXmEGb4Shy" + + "pL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERo0QwQjAOBgNVHQ8BAf8EBAMCAAEwEgYDVR" + + "0lAQH/BAgwBgYEVR0lADAcBgNVHREBAf8EEjAQgQ50ZXN0QHRlc3QudGVzdDANBgkqhkiG9w0BAQQFAANBAJg55PBS" + + "weg6obRUKF4FF6fCrWFi6oCYSQ99LWcAeupc5BofW5MstFMhCOaEucuGVqunwT5G7/DweazzCIrSzB0="); + + static String fingerprint(org.bouncycastle.asn1.x509.Certificate c) + throws IOException + { + byte[] der = c.getEncoded(); + byte[] sha1 = sha256DigestOf(der); + byte[] hexBytes = Hex.encode(sha1); + String hex = new String(hexBytes, "ASCII").toUpperCase(); + + StringBuffer fp = new StringBuffer(); + int i = 0; + fp.append(hex.substring(i, i + 2)); + while ((i += 2) < hex.length()) + { + fp.append(':'); + fp.append(hex.substring(i, i + 2)); + } + return fp.toString(); + } + + static byte[] sha256DigestOf(byte[] input) + { + SHA256Digest d = new SHA256Digest(); + d.update(input, 0, input.length); + byte[] result = new byte[d.getDigestSize()]; + d.doFinal(result, 0); + return result; + } + + static TlsAgreementCredentials loadAgreementCredentials(TlsContext context, + String[] certResources, String keyResource) + throws IOException + { + + Certificate certificate = loadCertificateChain(certResources); + AsymmetricKeyParameter privateKey = loadPrivateKeyResource(keyResource); + + return new DefaultTlsAgreementCredentials(certificate, privateKey); + } + + static TlsEncryptionCredentials loadEncryptionCredentials(TlsContext context, + String[] certResources, String keyResource) + throws IOException + { + + Certificate certificate = loadCertificateChain(certResources); + AsymmetricKeyParameter privateKey = loadPrivateKeyResource(keyResource); + + return new DefaultTlsEncryptionCredentials(context, certificate, privateKey); + } + + static TlsSignerCredentials loadSignerCredentials(TlsContext context, String[] certResources, + String keyResource) + throws IOException + { + + Certificate certificate = loadCertificateChain(certResources); + AsymmetricKeyParameter privateKey = loadPrivateKeyResource(keyResource); + + return new DefaultTlsSignerCredentials(context, certificate, privateKey); + } + + static Certificate loadCertificateChain(String[] resources) + throws IOException + { + + org.bouncycastle.asn1.x509.Certificate[] chain = new org.bouncycastle.asn1.x509.Certificate[resources.length]; + for (int i = 0; i < resources.length; ++i) + { + chain[i] = loadCertificateResource(resources[i]); + } + return new Certificate(chain); + } + + static org.bouncycastle.asn1.x509.Certificate loadCertificateResource(String resource) + throws IOException + { + + PemObject pem = loadPemResource(resource); + if (pem.getType().endsWith("CERTIFICATE")) + { + return org.bouncycastle.asn1.x509.Certificate.getInstance(pem.getContent()); + } + throw new IllegalArgumentException("'resource' doesn't specify a valid certificate"); + } + + static AsymmetricKeyParameter loadPrivateKeyResource(String resource) + throws IOException + { + + PemObject pem = loadPemResource(resource); + if (pem.getType().endsWith("RSA PRIVATE KEY")) + { + RSAPrivateKey rsa = RSAPrivateKey.getInstance(pem.getContent()); + return new RSAPrivateCrtKeyParameters(rsa.getModulus(), rsa.getPublicExponent(), + rsa.getPrivateExponent(), rsa.getPrime1(), rsa.getPrime2(), rsa.getExponent1(), + rsa.getExponent2(), rsa.getCoefficient()); + } + if (pem.getType().endsWith("PRIVATE KEY")) + { + return PrivateKeyFactory.createKey(pem.getContent()); + } + throw new IllegalArgumentException("'resource' doesn't specify a valid private key"); + } + + static PemObject loadPemResource(String resource) + throws IOException + { + + InputStream s = TlsTestUtils.class.getResourceAsStream(resource); + PemReader p = new PemReader(new InputStreamReader(s)); + PemObject o = p.readPemObject(); + p.close(); + return o; + } +} diff --git a/src/test/java/org/bouncycastle/crypto/tls/test/UnreliableDatagramTransport.java b/src/test/java/org/bouncycastle/crypto/tls/test/UnreliableDatagramTransport.java index 68a116ae..fcc2aa23 100644 --- a/src/test/java/org/bouncycastle/crypto/tls/test/UnreliableDatagramTransport.java +++ b/src/test/java/org/bouncycastle/crypto/tls/test/UnreliableDatagramTransport.java @@ -1,68 +1,93 @@ -package org.bouncycastle.crypto.tls.test; - -import java.io.IOException; -import java.util.Random; - -import org.bouncycastle.crypto.tls.DatagramTransport; - -public class UnreliableDatagramTransport implements DatagramTransport { - - private final DatagramTransport transport; - private final Random random; - private final int percentPacketLossReceiving, percentPacketLossSending; - - public UnreliableDatagramTransport(DatagramTransport transport, Random random, - int percentPacketLossReceiving, int percentPacketLossSending) { - if (percentPacketLossReceiving < 0 || percentPacketLossReceiving > 100) - throw new IllegalArgumentException("'percentPacketLossReceiving' out of range"); - if (percentPacketLossSending < 0 || percentPacketLossSending > 100) - throw new IllegalArgumentException("'percentPacketLossSending' out of range"); - - this.transport = transport; - this.random = random; - this.percentPacketLossReceiving = percentPacketLossReceiving; - this.percentPacketLossSending = percentPacketLossSending; - } - - public int getReceiveLimit() throws IOException { - return transport.getReceiveLimit(); - } - - public int getSendLimit() throws IOException { - return transport.getSendLimit(); - } - - public int receive(byte[] buf, int off, int len, int waitMillis) throws IOException { - long endMillis = System.currentTimeMillis() + waitMillis; - for (;;) - { - int length = transport.receive(buf, off, len, waitMillis); - if (length < 0 || !lostPacket(percentPacketLossReceiving)) - return length; - - System.out.println("PACKET LOSS (" + length + " byte packet not received)"); - - long now = System.currentTimeMillis(); - if (now >= endMillis) - return -1; - - waitMillis = (int)(endMillis - now); - } - } - - public void send(byte[] buf, int off, int len) throws IOException { - if (lostPacket(percentPacketLossSending)) { - System.out.println("PACKET LOSS (" + len + " byte packet not sent)"); - } else { - transport.send(buf, off, len); - } - } - - public void close() throws IOException { - transport.close(); - } - - private boolean lostPacket(int percentPacketLoss) { - return random.nextInt(100) < percentPacketLoss; - } -} +package org.bouncycastle.crypto.tls.test; + +import java.io.IOException; +import java.util.Random; + +import org.bouncycastle.crypto.tls.DatagramTransport; + +public class UnreliableDatagramTransport + implements DatagramTransport +{ + + private final DatagramTransport transport; + private final Random random; + private final int percentPacketLossReceiving, percentPacketLossSending; + + public UnreliableDatagramTransport(DatagramTransport transport, Random random, + int percentPacketLossReceiving, int percentPacketLossSending) + { + if (percentPacketLossReceiving < 0 || percentPacketLossReceiving > 100) + { + throw new IllegalArgumentException("'percentPacketLossReceiving' out of range"); + } + if (percentPacketLossSending < 0 || percentPacketLossSending > 100) + { + throw new IllegalArgumentException("'percentPacketLossSending' out of range"); + } + + this.transport = transport; + this.random = random; + this.percentPacketLossReceiving = percentPacketLossReceiving; + this.percentPacketLossSending = percentPacketLossSending; + } + + public int getReceiveLimit() + throws IOException + { + return transport.getReceiveLimit(); + } + + public int getSendLimit() + throws IOException + { + return transport.getSendLimit(); + } + + public int receive(byte[] buf, int off, int len, int waitMillis) + throws IOException + { + long endMillis = System.currentTimeMillis() + waitMillis; + for (; ; ) + { + int length = transport.receive(buf, off, len, waitMillis); + if (length < 0 || !lostPacket(percentPacketLossReceiving)) + { + return length; + } + + System.out.println("PACKET LOSS (" + length + " byte packet not received)"); + + long now = System.currentTimeMillis(); + if (now >= endMillis) + { + return -1; + } + + waitMillis = (int)(endMillis - now); + } + } + + public void send(byte[] buf, int off, int len) + throws IOException + { + if (lostPacket(percentPacketLossSending)) + { + System.out.println("PACKET LOSS (" + len + " byte packet not sent)"); + } + else + { + transport.send(buf, off, len); + } + } + + public void close() + throws IOException + { + transport.close(); + } + + private boolean lostPacket(int percentPacketLoss) + { + return random.nextInt(100) < percentPacketLoss; + } +} -- cgit v1.2.3