diff options
Diffstat (limited to 'core/src/main/java/org/bouncycastle/crypto/tls')
151 files changed, 0 insertions, 19891 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsAgreementCredentials.java b/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsAgreementCredentials.java deleted file mode 100644 index ef7f4fba..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsAgreementCredentials.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public abstract class AbstractTlsAgreementCredentials - extends AbstractTlsCredentials - implements TlsAgreementCredentials -{ -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsCipherFactory.java b/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsCipherFactory.java deleted file mode 100644 index 71a2cab0..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsCipherFactory.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public class AbstractTlsCipherFactory - implements TlsCipherFactory -{ - public TlsCipher createCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) - throws IOException - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsClient.java b/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsClient.java deleted file mode 100644 index 7d4fd033..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsClient.java +++ /dev/null @@ -1,235 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.util.Hashtable; -import java.util.Vector; - -public abstract class AbstractTlsClient - extends AbstractTlsPeer - implements TlsClient -{ - protected TlsCipherFactory cipherFactory; - - protected TlsClientContext context; - - protected Vector supportedSignatureAlgorithms; - protected int[] namedCurves; - protected short[] clientECPointFormats, serverECPointFormats; - - protected int selectedCipherSuite; - protected short selectedCompressionMethod; - - public AbstractTlsClient() - { - this(new DefaultTlsCipherFactory()); - } - - public AbstractTlsClient(TlsCipherFactory cipherFactory) - { - this.cipherFactory = cipherFactory; - } - - public void init(TlsClientContext context) - { - this.context = context; - } - - public TlsSession getSessionToResume() - { - return null; - } - - /** - * RFC 5246 E.1. "TLS clients that wish to negotiate with older servers MAY send any value - * {03,XX} as the record layer version number. Typical values would be {03,00}, the lowest - * version number supported by the client, and the value of ClientHello.client_version. No - * single value will guarantee interoperability with all old servers, but this is a complex - * topic beyond the scope of this document." - */ - public ProtocolVersion getClientHelloRecordLayerVersion() - { - // "{03,00}" - // return ProtocolVersion.SSLv3; - - // "the lowest version number supported by the client" - // return getMinimumVersion(); - - // "the value of ClientHello.client_version" - return getClientVersion(); - } - - public ProtocolVersion getClientVersion() - { - return ProtocolVersion.TLSv12; - } - - public Hashtable getClientExtensions() - throws IOException - { - Hashtable clientExtensions = null; - - ProtocolVersion clientVersion = context.getClientVersion(); - - /* - * 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)) - { - // 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 }; - - // TODO Sort out ECDSA signatures and add them as the preferred option here - 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) - { - this.supportedSignatureAlgorithms.addElement(new SignatureAndHashAlgorithm(hashAlgorithms[i], - signatureAlgorithms[j])); - } - } - - /* - * RFC 5264 7.4.3. Currently, DSA [DSS] may only be used with SHA-1. - */ - this.supportedSignatureAlgorithms.addElement(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, - SignatureAlgorithm.dsa)); - - clientExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(clientExtensions); - - TlsUtils.addSignatureAlgorithmsExtension(clientExtensions, supportedSignatureAlgorithms); - } - - 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 - * and the point formats it can parse. Clients SHOULD send both the Supported Elliptic - * Curves Extension and the Supported Point Formats Extension. - */ - /* - * 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.secp384r1 }; - this.clientECPointFormats = new short[]{ ECPointFormat.uncompressed, - ECPointFormat.ansiX962_compressed_prime, ECPointFormat.ansiX962_compressed_char2, }; - - clientExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(clientExtensions); - - TlsECCUtils.addSupportedEllipticCurvesExtension(clientExtensions, namedCurves); - TlsECCUtils.addSupportedPointFormatsExtension(clientExtensions, clientECPointFormats); - } - - return clientExtensions; - } - - public ProtocolVersion getMinimumVersion() - { - return ProtocolVersion.TLSv10; - } - - 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 void notifySessionID(byte[] sessionID) - { - // Currently ignored - } - - public void notifySelectedCipherSuite(int selectedCipherSuite) - { - this.selectedCipherSuite = selectedCipherSuite; - } - - public void notifySelectedCompressionMethod(short selectedCompressionMethod) - { - this.selectedCompressionMethod = selectedCompressionMethod; - } - - 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) - { - /* - * RFC 5246 7.4.1.4.1. Servers MUST NOT send this extension. - */ - if (serverExtensions.containsKey(TlsUtils.EXT_signature_algorithms)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - int[] namedCurves = TlsECCUtils.getSupportedEllipticCurvesExtension(serverExtensions); - if (namedCurves != null) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - this.serverECPointFormats = TlsECCUtils.getSupportedPointFormatsExtension(serverExtensions); - if (this.serverECPointFormats != null && !TlsECCUtils.isECCCipherSuite(this.selectedCipherSuite)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - } - - public void processServerSupplementalData(Vector serverSupplementalData) - throws IOException - { - if (serverSupplementalData != null) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - } - - public Vector getClientSupplementalData() - throws IOException - { - return null; - } - - public TlsCompression getCompression() - throws IOException - { - switch (selectedCompressionMethod) - { - case CompressionMethod._null: - return new TlsNullCompression(); - - default: - /* - * Note: internal error here; the TlsProtocol implementation verifies that the - * server-selected compression method was in the list of client-offered compression - * methods, so if we now can't produce an implementation, we shouldn't have offered it! - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public void notifyNewSessionTicket(NewSessionTicket newSessionTicket) - throws IOException - { - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java b/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java deleted file mode 100644 index 0b9949f9..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.prng.DigestRandomGenerator; -import org.bouncycastle.crypto.prng.RandomGenerator; -import org.bouncycastle.util.Times; - -abstract class AbstractTlsContext - implements TlsContext -{ - private static long counter = Times.nanoTime(); - - private synchronized static long nextCounterValue() - { - return ++counter; - } - - private RandomGenerator nonceRandom; - private SecureRandom secureRandom; - private SecurityParameters securityParameters; - - private ProtocolVersion clientVersion = null; - private ProtocolVersion serverVersion = null; - private TlsSession session = null; - private Object userObject = null; - - AbstractTlsContext(SecureRandom secureRandom, SecurityParameters securityParameters) - { - secureRandom.setSeed(nextCounterValue()); - secureRandom.setSeed(Times.nanoTime()); - - this.nonceRandom = new DigestRandomGenerator(TlsUtils.createHash(HashAlgorithm.sha256)); - this.nonceRandom.addSeedMaterial(secureRandom.generateSeed(32)); - - this.secureRandom = secureRandom; - this.securityParameters = securityParameters; - } - - public RandomGenerator getNonceRandomGenerator() - { - return nonceRandom; - } - - public SecureRandom getSecureRandom() - { - return secureRandom; - } - - public SecurityParameters getSecurityParameters() - { - return securityParameters; - } - - public ProtocolVersion getClientVersion() - { - return clientVersion; - } - - void setClientVersion(ProtocolVersion clientVersion) - { - this.clientVersion = clientVersion; - } - - public ProtocolVersion getServerVersion() - { - return serverVersion; - } - - void setServerVersion(ProtocolVersion serverVersion) - { - this.serverVersion = serverVersion; - } - - public TlsSession getResumableSession() - { - return session; - } - - void setResumableSession(TlsSession session) - { - this.session = session; - } - - public Object getUserObject() - { - return userObject; - } - - public void setUserObject(Object userObject) - { - this.userObject = userObject; - } - - public byte[] exportKeyingMaterial(String asciiLabel, byte[] context_value, int length) - { - if (context_value != null && !TlsUtils.isValidUint16(context_value.length)) - { - throw new IllegalArgumentException("'context_value' must have length less than 2^16 (or be null)"); - } - - SecurityParameters sp = getSecurityParameters(); - byte[] cr = sp.getClientRandom(), sr = sp.getServerRandom(); - - int seedLength = cr.length + sr.length; - if (context_value != null) - { - seedLength += (2 + context_value.length); - } - - byte[] seed = new byte[seedLength]; - int seedPos = 0; - - System.arraycopy(cr, 0, seed, seedPos, cr.length); - seedPos += cr.length; - System.arraycopy(sr, 0, seed, seedPos, sr.length); - seedPos += sr.length; - 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) - { - throw new IllegalStateException("error in calculation of seed for export"); - } - - return TlsUtils.PRF(this, sp.getMasterSecret(), asciiLabel, seed, length); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsCredentials.java b/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsCredentials.java deleted file mode 100644 index b98743f3..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsCredentials.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public abstract class AbstractTlsCredentials - implements TlsCredentials -{ -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsEncryptionCredentials.java b/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsEncryptionCredentials.java deleted file mode 100644 index e6ff39ba..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsEncryptionCredentials.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public abstract class AbstractTlsEncryptionCredentials - extends AbstractTlsCredentials - implements TlsEncryptionCredentials -{ -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsKeyExchange.java b/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsKeyExchange.java deleted file mode 100644 index 43e80e64..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsKeyExchange.java +++ /dev/null @@ -1,166 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Vector; - -public abstract class AbstractTlsKeyExchange - implements TlsKeyExchange -{ - protected int keyExchange; - protected Vector supportedSignatureAlgorithms; - - protected TlsContext context; - - protected AbstractTlsKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms) - { - this.keyExchange = keyExchange; - this.supportedSignatureAlgorithms = supportedSignatureAlgorithms; - } - - public void init(TlsContext context) - { - this.context = context; - - ProtocolVersion clientVersion = context.getClientVersion(); - - if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(clientVersion)) - { - /* - * RFC 5264 7.4.1.4.1. If the client does not send the signature_algorithms extension, - * the server MUST do the following: - * - * - If the negotiated key exchange algorithm is one of (RSA, DHE_RSA, DH_RSA, RSA_PSK, - * ECDH_RSA, ECDHE_RSA), behave as if client had sent the value {sha1,rsa}. - * - * - If the negotiated key exchange algorithm is one of (DHE_DSS, DH_DSS), behave as if - * the client had sent the value {sha1,dsa}. - * - * - 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) - { - case KeyExchangeAlgorithm.DH_DSS: - case KeyExchangeAlgorithm.DHE_DSS: - case KeyExchangeAlgorithm.SRP_DSS: - { - this.supportedSignatureAlgorithms = TlsUtils.getDefaultDSSSignatureAlgorithms(); - break; - } - - case KeyExchangeAlgorithm.ECDH_ECDSA: - case KeyExchangeAlgorithm.ECDHE_ECDSA: - { - this.supportedSignatureAlgorithms = TlsUtils.getDefaultECDSASignatureAlgorithms(); - break; - } - - case KeyExchangeAlgorithm.DH_RSA: - case KeyExchangeAlgorithm.DHE_RSA: - case KeyExchangeAlgorithm.ECDH_RSA: - case KeyExchangeAlgorithm.ECDHE_RSA: - case KeyExchangeAlgorithm.RSA: - case KeyExchangeAlgorithm.RSA_PSK: - case KeyExchangeAlgorithm.SRP_RSA: - { - this.supportedSignatureAlgorithms = TlsUtils.getDefaultRSASignatureAlgorithms(); - break; - } - - case KeyExchangeAlgorithm.DHE_PSK: - case KeyExchangeAlgorithm.ECDHE_PSK: - case KeyExchangeAlgorithm.PSK: - case KeyExchangeAlgorithm.SRP: - break; - - default: - throw new IllegalStateException("unsupported key exchange algorithm"); - } - } - - } - else if (this.supportedSignatureAlgorithms != null) - { - throw new IllegalStateException("supported_signature_algorithms not allowed for " + clientVersion); - } - } - - public void processServerCertificate(Certificate serverCertificate) - throws IOException - { - 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 - { - /* - * 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 - * pair that appears in that extension. - */ - } - } - - public void processServerCredentials(TlsCredentials serverCredentials) - throws IOException - { - processServerCertificate(serverCredentials.getCertificate()); - } - - public boolean requiresServerKeyExchange() - { - return false; - } - - public byte[] generateServerKeyExchange() - throws IOException - { - if (requiresServerKeyExchange()) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - return null; - } - - public void skipServerKeyExchange() - throws IOException - { - if (requiresServerKeyExchange()) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - } - - public void processServerKeyExchange(InputStream input) - throws IOException - { - if (!requiresServerKeyExchange()) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - } - - public void skipClientCredentials() - throws IOException - { - } - - public void processClientCertificate(Certificate clientCertificate) - 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/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsPeer.java b/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsPeer.java deleted file mode 100644 index 26ad6d34..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsPeer.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public abstract class AbstractTlsPeer - implements TlsPeer -{ - public boolean shouldUseGMTUnixTime() - { - /* - * draft-mathewson-no-gmtunixtime-00 2. For the reasons we discuss above, we recommend that - * TLS implementors MUST by default set the entire value the ClientHello.Random and - * ServerHello.Random fields, including gmt_unix_time, to a cryptographically random - * sequence. - */ - return false; - } - - public void notifySecureRenegotiation(boolean secureRenegotiation) throws IOException - { - if (!secureRenegotiation) - { - /* - * RFC 5746 3.4/3.6. In this case, some clients/servers may want to terminate the handshake instead - * of continuing; see Section 4.1/4.3 for discussion. - */ - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - } - - public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause) - { - } - - public void notifyAlertReceived(short alertLevel, short alertDescription) - { - } - - public void notifyHandshakeComplete() throws IOException - { - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsServer.java b/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsServer.java deleted file mode 100644 index dd5c4409..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsServer.java +++ /dev/null @@ -1,335 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.util.Hashtable; -import java.util.Vector; - -import org.bouncycastle.util.Arrays; - -public abstract class AbstractTlsServer - extends AbstractTlsPeer - implements TlsServer -{ - protected TlsCipherFactory cipherFactory; - - protected TlsServerContext context; - - protected ProtocolVersion clientVersion; - protected int[] offeredCipherSuites; - protected short[] offeredCompressionMethods; - protected Hashtable clientExtensions; - - protected boolean encryptThenMACOffered; - protected short maxFragmentLengthOffered; - protected boolean truncatedHMacOffered; - protected Vector supportedSignatureAlgorithms; - protected boolean eccCipherSuitesOffered; - protected int[] namedCurves; - protected short[] clientECPointFormats, serverECPointFormats; - - protected ProtocolVersion serverVersion; - protected int selectedCipherSuite; - protected short selectedCompressionMethod; - protected Hashtable serverExtensions; - - public AbstractTlsServer() - { - this(new DefaultTlsCipherFactory()); - } - - public AbstractTlsServer(TlsCipherFactory cipherFactory) - { - this.cipherFactory = cipherFactory; - } - - protected boolean allowEncryptThenMAC() - { - return true; - } - - protected boolean allowTruncatedHMac() - { - return false; - } - - protected Hashtable checkServerExtensions() - { - return this.serverExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(this.serverExtensions); - } - - protected abstract int[] getCipherSuites(); - - protected short[] getCompressionMethods() - { - return new short[]{CompressionMethod._null}; - } - - protected ProtocolVersion getMaximumVersion() - { - return ProtocolVersion.TLSv11; - } - - protected ProtocolVersion getMinimumVersion() - { - return ProtocolVersion.TLSv10; - } - - 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) - { - /* - * 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 - * or point formats [...]. - */ - return TlsECCUtils.hasAnySupportedNamedCurves(); - } - - for (int i = 0; i < namedCurves.length; ++i) - { - int namedCurve = namedCurves[i]; - if (NamedCurve.isValid(namedCurve) - && (!NamedCurve.refersToASpecificNamedCurve(namedCurve) || TlsECCUtils.isSupportedNamedCurve(namedCurve))) - { - return true; - } - } - - return false; - } - - public void init(TlsServerContext context) - { - this.context = context; - } - - public void notifyClientVersion(ProtocolVersion clientVersion) - throws IOException - { - this.clientVersion = clientVersion; - } - - public void notifyOfferedCipherSuites(int[] offeredCipherSuites) - throws IOException - { - this.offeredCipherSuites = offeredCipherSuites; - this.eccCipherSuitesOffered = TlsECCUtils.containsECCCipherSuites(this.offeredCipherSuites); - } - - public void notifyOfferedCompressionMethods(short[] offeredCompressionMethods) - throws IOException - { - this.offeredCompressionMethods = offeredCompressionMethods; - } - - public void processClientExtensions(Hashtable clientExtensions) - throws IOException - { - this.clientExtensions = clientExtensions; - - if (clientExtensions != null) - { - this.encryptThenMACOffered = TlsExtensionsUtils.hasEncryptThenMACExtension(clientExtensions); - this.maxFragmentLengthOffered = TlsExtensionsUtils.getMaxFragmentLengthExtension(clientExtensions); - this.truncatedHMacOffered = TlsExtensionsUtils.hasTruncatedHMacExtension(clientExtensions); - - this.supportedSignatureAlgorithms = TlsUtils.getSignatureAlgorithmsExtension(clientExtensions); - 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)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - - this.namedCurves = TlsECCUtils.getSupportedEllipticCurvesExtension(clientExtensions); - this.clientECPointFormats = TlsECCUtils.getSupportedPointFormatsExtension(clientExtensions); - } - - /* - * 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)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - - public ProtocolVersion getServerVersion() - throws IOException - { - if (getMinimumVersion().isEqualOrEarlierVersionOf(clientVersion)) - { - ProtocolVersion maximumVersion = getMaximumVersion(); - if (clientVersion.isEqualOrEarlierVersionOf(maximumVersion)) - { - return serverVersion = clientVersion; - } - if (clientVersion.isLaterVersionOf(maximumVersion)) - { - return serverVersion = maximumVersion; - } - } - throw new TlsFatalAlert(AlertDescription.protocol_version); - } - - public int getSelectedCipherSuite() - throws IOException - { - /* - * TODO RFC 5246 7.4.3. In order to negotiate correctly, the server MUST check any candidate - * cipher suites against the "signature_algorithms" extension before selecting them. This is - * somewhat inelegant but is a compromise designed to minimize changes to the original - * cipher suite design. - */ - - /* - * RFC 4429 5.1. A server that receives a ClientHello containing one or both of these - * extensions MUST use the client's enumerated capabilities to guide its selection of an - * appropriate cipher suite. One of the proposed ECC cipher suites must be negotiated only - * if the server can successfully complete the handshake while using the curves and point - * formats supported by the client [...]. - */ - boolean eccCipherSuitesEnabled = supportsClientECCCapabilities(this.namedCurves, this.clientECPointFormats); - - int[] cipherSuites = getCipherSuites(); - for (int i = 0; i < cipherSuites.length; ++i) - { - int cipherSuite = cipherSuites[i]; - - if (Arrays.contains(this.offeredCipherSuites, cipherSuite) - && (eccCipherSuitesEnabled || !TlsECCUtils.isECCCipherSuite(cipherSuite)) - && TlsUtils.isValidCipherSuiteForVersion(cipherSuite, serverVersion)) - { - return this.selectedCipherSuite = cipherSuite; - } - } - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - - public short getSelectedCompressionMethod() - throws IOException - { - short[] compressionMethods = getCompressionMethods(); - for (int i = 0; i < compressionMethods.length; ++i) - { - if (Arrays.contains(offeredCompressionMethods, compressionMethods[i])) - { - return this.selectedCompressionMethod = compressionMethods[i]; - } - } - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - - // Hashtable is (Integer -> byte[]) - public Hashtable getServerExtensions() - throws IOException - { - if (this.encryptThenMACOffered && allowEncryptThenMAC()) - { - /* - * draft-ietf-tls-encrypt-then-mac-03 3. If a server receives an encrypt-then-MAC - * request extension from a client and then selects a stream or AEAD cipher suite, it - * MUST NOT send an encrypt-then-MAC response extension back to the client. - */ - if (TlsUtils.isBlockCipherSuite(this.selectedCipherSuite)) - { - TlsExtensionsUtils.addEncryptThenMACExtension(checkServerExtensions()); - } - } - - if (this.maxFragmentLengthOffered >= 0) - { - TlsExtensionsUtils.addMaxFragmentLengthExtension(checkServerExtensions(), this.maxFragmentLengthOffered); - } - - if (this.truncatedHMacOffered && allowTruncatedHMac()) - { - TlsExtensionsUtils.addTruncatedHMacExtension(checkServerExtensions()); - } - - 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.uncompressed, - ECPointFormat.ansiX962_compressed_prime, ECPointFormat.ansiX962_compressed_char2, }; - - TlsECCUtils.addSupportedPointFormatsExtension(checkServerExtensions(), serverECPointFormats); - } - - return serverExtensions; - } - - public Vector getServerSupplementalData() - throws IOException - { - return null; - } - - public CertificateStatus getCertificateStatus() - throws IOException - { - return null; - } - - public CertificateRequest getCertificateRequest() - throws IOException - { - return null; - } - - public void processClientSupplementalData(Vector clientSupplementalData) - throws IOException - { - if (clientSupplementalData != null) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - } - - public void notifyClientCertificate(Certificate clientCertificate) - throws IOException - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - public TlsCompression getCompression() - throws IOException - { - switch (selectedCompressionMethod) - { - case CompressionMethod._null: - return new TlsNullCompression(); - - default: - /* - * Note: internal error here; we selected the compression method, so if we now can't - * produce an implementation, we shouldn't have chosen it! - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - 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 - * ticket in the NewSessionTicket handshake message. - */ - return new NewSessionTicket(0L, TlsUtils.EMPTY_BYTES); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsSigner.java b/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsSigner.java deleted file mode 100644 index 3a1d6319..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsSigner.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; - -public abstract class AbstractTlsSigner - implements TlsSigner -{ - protected TlsContext context; - - public void init(TlsContext context) - { - this.context = context; - } - - public byte[] generateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) - throws CryptoException - { - return generateRawSignature(null, privateKey, md5AndSha1); - } - - public boolean verifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1) - throws CryptoException - { - return verifyRawSignature(null, sigBytes, publicKey, md5AndSha1); - } - - public Signer createSigner(AsymmetricKeyParameter privateKey) - { - return createSigner(null, privateKey); - } - - public Signer createVerifyer(AsymmetricKeyParameter publicKey) - { - return createVerifyer(null, publicKey); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsSignerCredentials.java b/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsSignerCredentials.java deleted file mode 100644 index 3452f527..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsSignerCredentials.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public abstract class AbstractTlsSignerCredentials - extends AbstractTlsCredentials - implements TlsSignerCredentials -{ - public SignatureAndHashAlgorithm getSignatureAndHashAlgorithm() - { - throw new IllegalStateException("TlsSignerCredentials implementation does not support (D)TLS 1.2+"); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AlertDescription.java b/core/src/main/java/org/bouncycastle/crypto/tls/AlertDescription.java deleted file mode 100644 index 91366be0..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AlertDescription.java +++ /dev/null @@ -1,216 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 5246 7.2. - */ -public class AlertDescription -{ - /** - * This message notifies the recipient that the sender will not send any more messages on this - * connection. Note that as of TLS 1.1, failure to properly close a connection no longer - * requires that a session not be resumed. This is a change from TLS 1.0 ("The session becomes - * unresumable if any connection is terminated without proper close_notify messages with level - * equal to warning.") to conform with widespread implementation practice. - */ - public static final short close_notify = 0; - - /** - * An inappropriate message was received. This alert is always fatal and should never be - * observed in communication between proper implementations. - */ - public static final short unexpected_message = 10; - - /** - * This alert is returned if a record is received with an incorrect MAC. This alert also MUST be - * returned if an alert is sent because a TLSCiphertext decrypted in an invalid way: either it - * wasn't an even multiple of the block length, or its padding values, when checked, weren't - * correct. This message is always fatal and should never be observed in communication between - * proper implementations (except when messages were corrupted in the network). - */ - public static final short bad_record_mac = 20; - - /** - * This alert was used in some earlier versions of TLS, and may have permitted certain attacks - * against the CBC mode [CBCATT]. It MUST NOT be sent by compliant implementations. - */ - public static final short decryption_failed = 21; - - /** - * A TLSCiphertext record was received that had a length more than 2^14+2048 bytes, or a record - * decrypted to a TLSCompressed record with more than 2^14+1024 bytes. This message is always - * fatal and should never be observed in communication between proper implementations (except - * when messages were corrupted in the network). - */ - public static final short record_overflow = 22; - - /** - * The decompression function received improper input (e.g., data that would expand to excessive - * length). This message is always fatal and should never be observed in communication between - * proper implementations. - */ - public static final short decompression_failure = 30; - - /** - * Reception of a handshake_failure alert message indicates that the sender was unable to - * negotiate an acceptable set of security parameters given the options available. This is a - * fatal error. - */ - public static final short handshake_failure = 40; - - /** - * This alert was used in SSLv3 but not any version of TLS. It MUST NOT be sent by compliant - * implementations. - */ - public static final short no_certificate = 41; - - /** - * A certificate was corrupt, contained signatures that did not verify correctly, etc. - */ - public static final short bad_certificate = 42; - - /** - * A certificate was of an unsupported type. - */ - public static final short unsupported_certificate = 43; - - /** - * A certificate was revoked by its signer. - */ - public static final short certificate_revoked = 44; - - /** - * A certificate has expired or is not currently valid. - */ - public static final short certificate_expired = 45; - - /** - * Some other (unspecified) issue arose in processing the certificate, rendering it - * unacceptable. - */ - public static final short certificate_unknown = 46; - - /** - * A field in the handshake was out of range or inconsistent with other fields. This message is - * always fatal. - */ - public static final short illegal_parameter = 47; - - /** - * A valid certificate chain or partial chain was received, but the certificate was not accepted - * because the CA certificate could not be located or couldn't be matched with a known, trusted - * CA. This message is always fatal. - */ - public static final short unknown_ca = 48; - - /** - * A valid certificate was received, but when access control was applied, the sender decided not - * to proceed with negotiation. This message is always fatal. - */ - public static final short access_denied = 49; - - /** - * A message could not be decoded because some field was out of the specified range or the - * length of the message was incorrect. This message is always fatal and should never be - * observed in communication between proper implementations (except when messages were corrupted - * in the network). - */ - public static final short decode_error = 50; - - /** - * A handshake cryptographic operation failed, including being unable to correctly verify a - * signature or validate a Finished message. This message is always fatal. - */ - public static final short decrypt_error = 51; - - /** - * This alert was used in some earlier versions of TLS. It MUST NOT be sent by compliant - * implementations. - */ - public static final short export_restriction = 60; - - /** - * The protocol version the client has attempted to negotiate is recognized but not supported. - * (For example, old protocol versions might be avoided for security reasons.) This message is - * always fatal. - */ - public static final short protocol_version = 70; - - /** - * Returned instead of handshake_failure when a negotiation has failed specifically because the - * server requires ciphers more secure than those supported by the client. This message is - * always fatal. - */ - public static final short insufficient_security = 71; - - /** - * An internal error unrelated to the peer or the correctness of the protocol (such as a memory - * allocation failure) makes it impossible to continue. This message is always fatal. - */ - public static final short internal_error = 80; - - /** - * This handshake is being canceled for some reason unrelated to a protocol failure. If the user - * cancels an operation after the handshake is complete, just closing the connection by sending - * a close_notify is more appropriate. This alert should be followed by a close_notify. This - * message is generally a warning. - */ - public static final short user_canceled = 90; - - /** - * Sent by the client in response to a hello request or by the server in response to a client - * hello after initial handshaking. Either of these would normally lead to renegotiation; when - * that is not appropriate, the recipient should respond with this alert. At that point, the - * original requester can decide whether to proceed with the connection. One case where this - * would be appropriate is where a server has spawned a process to satisfy a request; the - * process might receive security parameters (key length, authentication, etc.) at startup, and - * it might be difficult to communicate changes to these parameters after that point. This - * message is always a warning. - */ - public static final short no_renegotiation = 100; - - /** - * Sent by clients that receive an extended server hello containing an extension that they did - * not put in the corresponding client hello. This message is always fatal. - */ - public static final short unsupported_extension = 110; - - /* - * RFC 3546 - */ - - /** - * This alert is sent by servers who are unable to retrieve a certificate chain from the URL - * supplied by the client (see Section 3.3). This message MAY be fatal - for example if client - * authentication is required by the server for the handshake to continue and the server is - * unable to retrieve the certificate chain, it may send a fatal alert. - */ - public static final short certificate_unobtainable = 111; - - /** - * This alert is sent by servers that receive a server_name extension request, but do not - * recognize the server name. This message MAY be fatal. - */ - public static final short unrecognized_name = 112; - - /** - * This alert is sent by clients that receive an invalid certificate status response (see - * Section 3.6). This message is always fatal. - */ - public static final short bad_certificate_status_response = 113; - - /** - * This alert is sent by servers when a certificate hash does not match a client provided - * certificate_hash. This message is always fatal. - */ - public static final short bad_certificate_hash_value = 114; - - /* - * RFC 4279 - */ - - /** - * If the server does not recognize the PSK identity, it MAY respond with an - * "unknown_psk_identity" alert message. - */ - public static final short unknown_psk_identity = 115; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AlertLevel.java b/core/src/main/java/org/bouncycastle/crypto/tls/AlertLevel.java deleted file mode 100644 index 53e843a4..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AlertLevel.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 5246 7.2 - */ -public class AlertLevel -{ - public static final short warning = 1; - public static final short fatal = 2; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/AlwaysValidVerifyer.java b/core/src/main/java/org/bouncycastle/crypto/tls/AlwaysValidVerifyer.java deleted file mode 100644 index 961408ae..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/AlwaysValidVerifyer.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * A certificate verifyer, that will always return true. - * <pre> - * DO NOT USE THIS FILE UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING. - * </pre> - * - * @deprecated Perform certificate verification in TlsAuthentication implementation - */ -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) - { - return true; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/BulkCipherAlgorithm.java b/core/src/main/java/org/bouncycastle/crypto/tls/BulkCipherAlgorithm.java deleted file mode 100644 index 7f013b3a..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/BulkCipherAlgorithm.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 2246 - * <p> - * 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 static final int _null = 0; - public static final int rc4 = 1; - public static final int rc2 = 2; - public static final int des = 3; - public static final int _3des = 4; - public static final int des40 = 5; - - /* - * RFC 4346 - */ - public static final int aes = 6; - public static final int idea = 7; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ByteQueue.java b/core/src/main/java/org/bouncycastle/crypto/tls/ByteQueue.java deleted file mode 100644 index 560ea459..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ByteQueue.java +++ /dev/null @@ -1,153 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * A queue for bytes. This file could be more optimized. - */ -public class ByteQueue -{ - /** - * @return The smallest number which can be written as 2^x which is bigger than i. - */ - public static int nextTwoPow(int i) - { - /* - * This code is based of a lot of code I found on the Internet which mostly - * referenced a book called "Hacking delight". - */ - i |= (i >> 1); - i |= (i >> 2); - i |= (i >> 4); - i |= (i >> 8); - i |= (i >> 16); - return i + 1; - } - - /** - * The initial size for our buffer. - */ - private static final int DEFAULT_CAPACITY = 1024; - - /** - * The buffer where we store our data. - */ - private byte[] databuf; - - /** - * How many bytes at the beginning of the buffer are skipped. - */ - private int skipped = 0; - - /** - * How many bytes in the buffer are valid data. - */ - private int available = 0; - - public ByteQueue() - { - this(DEFAULT_CAPACITY); - } - - public ByteQueue(int capacity) - { - databuf = new byte[capacity]; - } - - /** - * Read data from the buffer. - * - * @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. - */ - public void read(byte[] buf, int offset, int len, int skip) - { - if ((buf.length - offset) < len) - { - throw new IllegalArgumentException("Buffer size of " + buf.length - + " is too small for a read of " + len + " bytes"); - } - if ((available - skip) < len) - { - throw new IllegalStateException("Not enough data to read"); - } - System.arraycopy(databuf, skipped + skip, buf, offset, len); - } - - /** - * Add some data to our buffer. - * - * @param buf A byte-array to read data from. - * @param off How many bytes to skip at the beginning of the array. - * @param len How many bytes to read from the array. - */ - public void addData(byte[] buf, int off, int len) - { - if ((skipped + available + len) > databuf.length) - { - int desiredSize = ByteQueue.nextTwoPow(available + len); - if (desiredSize > databuf.length) - { - byte[] tmp = new byte[desiredSize]; - System.arraycopy(databuf, skipped, tmp, 0, available); - databuf = tmp; - } - else - { - System.arraycopy(databuf, skipped, databuf, 0, available); - } - skipped = 0; - } - - System.arraycopy(buf, off, databuf, skipped + available, len); - available += len; - } - - /** - * Remove some bytes from our data from the beginning. - * - * @param i How many bytes to remove. - */ - public void removeData(int i) - { - if (i > available) - { - throw new IllegalStateException("Cannot remove " + i + " bytes, only got " + available); - } - - /* - * Skip the data. - */ - available -= i; - skipped += i; - } - - /** - * Remove data from the buffer. - * - * @param buf The buffer where the removed data will be copied to. - * @param off 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. - */ - public void removeData(byte[] buf, int off, int len, int skip) - { - read(buf, off, len, skip); - removeData(skip + len); - } - - public byte[] removeData(int len, int skip) - { - byte[] buf = new byte[len]; - removeData(buf, 0, len, skip); - return buf; - } - - /** - * @return The number of bytes which are available in this buffer. - */ - public int size() - { - return available; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CertChainType.java b/core/src/main/java/org/bouncycastle/crypto/tls/CertChainType.java deleted file mode 100644 index 8902ed79..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/CertChainType.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/* - * RFC 3546 3.3. - */ -public class CertChainType -{ - public static final short individual_certs = 0; - public static final short pkipath = 1; - - public static boolean isValid(short certChainType) - { - return certChainType >= individual_certs && certChainType <= pkipath; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/Certificate.java b/core/src/main/java/org/bouncycastle/crypto/tls/Certificate.java deleted file mode 100644 index 33a6edd4..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/Certificate.java +++ /dev/null @@ -1,148 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Vector; - -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ASN1Primitive; - -/** - * Parsing and encoding of a <i>Certificate</i> struct from RFC 4346. - * <pre> - * opaque ASN.1Cert<2^24-1>; - * - * struct { - * ASN.1Cert certificate_list<0..2^24-1>; - * } Certificate; - * </pre> - * - * @see org.bouncycastle.asn1.x509.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) - { - throw new IllegalArgumentException("'certificateList' cannot be null"); - } - - this.certificateList = certificateList; - } - - /** - * @deprecated use {@link #getCertificateList()} instead - */ - public org.bouncycastle.asn1.x509.Certificate[] getCerts() - { - return getCertificateList(); - } - - /** - * @return an array of {@link org.bouncycastle.asn1.x509.Certificate} representing a certificate - * chain. - */ - public org.bouncycastle.asn1.x509.Certificate[] getCertificateList() - { - return cloneCertificateList(); - } - - public org.bouncycastle.asn1.x509.Certificate getCertificateAt(int index) - { - return certificateList[index]; - } - - public int getLength() - { - return certificateList.length; - } - - /** - * @return <code>true</code> if this certificate chain contains no certificates, or - * <code>false</code> otherwise. - */ - public boolean isEmpty() - { - return certificateList.length == 0; - } - - /** - * Encode this {@link Certificate} to an {@link OutputStream}. - * - * @param output the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) - throws IOException - { - Vector derEncodings = new Vector(this.certificateList.length); - - int totalLength = 0; - for (int i = 0; i < this.certificateList.length; ++i) - { - byte[] derEncoding = certificateList[i].getEncoded(ASN1Encoding.DER); - derEncodings.addElement(derEncoding); - totalLength += derEncoding.length + 3; - } - - TlsUtils.checkUint24(totalLength); - TlsUtils.writeUint24(totalLength, output); - - for (int i = 0; i < derEncodings.size(); ++i) - { - byte[] derEncoding = (byte[])derEncodings.elementAt(i); - TlsUtils.writeOpaque24(derEncoding, output); - } - } - - /** - * Parse a {@link Certificate} from an {@link InputStream}. - * - * @param input the {@link InputStream} to parse from. - * @return a {@link Certificate} object. - * @throws IOException - */ - public static Certificate parse(InputStream input) - throws IOException - { - int totalLength = TlsUtils.readUint24(input); - if (totalLength == 0) - { - return EMPTY_CHAIN; - } - - byte[] certListData = TlsUtils.readFully(totalLength, input); - - ByteArrayInputStream buf = new ByteArrayInputStream(certListData); - - Vector certificate_list = new Vector(); - while (buf.available() > 0) - { - byte[] derEncoding = TlsUtils.readOpaque24(buf); - ASN1Primitive asn1Cert = TlsUtils.readDERObject(derEncoding); - certificate_list.addElement(org.bouncycastle.asn1.x509.Certificate.getInstance(asn1Cert)); - } - - org.bouncycastle.asn1.x509.Certificate[] certificateList = new org.bouncycastle.asn1.x509.Certificate[certificate_list.size()]; - for (int i = 0; i < certificate_list.size(); i++) - { - certificateList[i] = (org.bouncycastle.asn1.x509.Certificate)certificate_list.elementAt(i); - } - return new Certificate(certificateList); - } - - protected org.bouncycastle.asn1.x509.Certificate[] cloneCertificateList() - { - org.bouncycastle.asn1.x509.Certificate[] result = new org.bouncycastle.asn1.x509.Certificate[certificateList.length]; - System.arraycopy(certificateList, 0, result, 0, result.length); - return result; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateRequest.java b/core/src/main/java/org/bouncycastle/crypto/tls/CertificateRequest.java deleted file mode 100644 index 68e051ea..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateRequest.java +++ /dev/null @@ -1,158 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Vector; - -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.x500.X500Name; - -/** - * Parsing and encoding of a <i>CertificateRequest</i> struct from RFC 4346. - * <pre> - * struct { - * ClientCertificateType certificate_types<1..2^8-1>; - * DistinguishedName certificate_authorities<3..2^16-1>; - * } CertificateRequest; - * </pre> - * - * @see ClientCertificateType - * @see X500Name - */ -public class CertificateRequest -{ - protected short[] certificateTypes; - protected Vector supportedSignatureAlgorithms; - protected Vector certificateAuthorities; - - /** - * @param certificateTypes see {@link ClientCertificateType} for valid constants. - * @param certificateAuthorities a {@link Vector} of {@link X500Name}. - */ - public CertificateRequest(short[] certificateTypes, Vector supportedSignatureAlgorithms, Vector certificateAuthorities) - { - this.certificateTypes = certificateTypes; - this.supportedSignatureAlgorithms = supportedSignatureAlgorithms; - this.certificateAuthorities = certificateAuthorities; - } - - /** - * @return an array of certificate types - * @see ClientCertificateType - */ - public short[] getCertificateTypes() - { - return certificateTypes; - } - - /** - * @return a {@link Vector} of {@link SignatureAndHashAlgorithm} (or null before TLS 1.2). - */ - public Vector getSupportedSignatureAlgorithms() - { - return supportedSignatureAlgorithms; - } - - /** - * @return a {@link Vector} of {@link X500Name} - */ - public Vector getCertificateAuthorities() - { - return certificateAuthorities; - } - - /** - * Encode this {@link CertificateRequest} to an {@link OutputStream}. - * - * @param output the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) - throws IOException - { - if (certificateTypes == null || certificateTypes.length == 0) - { - TlsUtils.writeUint8(0, output); - } - else - { - TlsUtils.writeUint8ArrayWithUint8Length(certificateTypes, output); - } - - if (supportedSignatureAlgorithms != null) - { - // TODO Check whether SignatureAlgorithm.anonymous is allowed here - TlsUtils.encodeSupportedSignatureAlgorithms(supportedSignatureAlgorithms, false, output); - } - - if (certificateAuthorities == null || certificateAuthorities.isEmpty()) - { - TlsUtils.writeUint16(0, output); - } - else - { - Vector derEncodings = new Vector(certificateAuthorities.size()); - - int totalLength = 0; - for (int i = 0; i < certificateAuthorities.size(); ++i) - { - X500Name certificateAuthority = (X500Name)certificateAuthorities.elementAt(i); - byte[] derEncoding = certificateAuthority.getEncoded(ASN1Encoding.DER); - derEncodings.addElement(derEncoding); - totalLength += derEncoding.length + 2; - } - - TlsUtils.checkUint16(totalLength); - TlsUtils.writeUint16(totalLength, output); - - for (int i = 0; i < derEncodings.size(); ++i) - { - byte[] derEncoding = (byte[])derEncodings.elementAt(i); - TlsUtils.writeOpaque16(derEncoding, output); - } - } - } - - /** - * Parse a {@link CertificateRequest} from an {@link InputStream}. - * - * @param context - * the {@link TlsContext} of the current connection. - * @param input - * the {@link InputStream} to parse from. - * @return a {@link CertificateRequest} object. - * @throws IOException - */ - public static CertificateRequest parse(TlsContext context, InputStream input) - throws IOException - { - int numTypes = TlsUtils.readUint8(input); - short[] certificateTypes = new short[numTypes]; - for (int i = 0; i < numTypes; ++i) - { - certificateTypes[i] = TlsUtils.readUint8(input); - } - - Vector supportedSignatureAlgorithms = null; - if (TlsUtils.isTLSv12(context)) - { - // TODO Check whether SignatureAlgorithm.anonymous is allowed here - supportedSignatureAlgorithms = TlsUtils.parseSupportedSignatureAlgorithms(false, input); - } - - Vector certificateAuthorities = new Vector(); - byte[] certAuthData = TlsUtils.readOpaque16(input); - ByteArrayInputStream bis = new ByteArrayInputStream(certAuthData); - while (bis.available() > 0) - { - byte[] derEncoding = TlsUtils.readOpaque16(bis); - ASN1Primitive asn1 = TlsUtils.readDERObject(derEncoding); - certificateAuthorities.addElement(X500Name.getInstance(asn1)); - } - - return new CertificateRequest(certificateTypes, supportedSignatureAlgorithms, certificateAuthorities); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateStatus.java b/core/src/main/java/org/bouncycastle/crypto/tls/CertificateStatus.java deleted file mode 100644 index 34a0284a..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateStatus.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ocsp.OCSPResponse; - -public class CertificateStatus -{ - protected short statusType; - protected Object response; - - public CertificateStatus(short statusType, Object response) - { - if (!isCorrectType(statusType, response)) - { - throw new IllegalArgumentException("'response' is not an instance of the correct type"); - } - - this.statusType = statusType; - this.response = response; - } - - public short getStatusType() - { - return statusType; - } - - public Object getResponse() - { - return response; - } - - public OCSPResponse getOCSPResponse() - { - if (!isCorrectType(CertificateStatusType.ocsp, response)) - { - throw new IllegalStateException("'response' is not an OCSPResponse"); - } - return (OCSPResponse)response; - } - - /** - * Encode this {@link CertificateStatus} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) throws IOException - { - TlsUtils.writeUint8(statusType, output); - - switch (statusType) - { - case CertificateStatusType.ocsp: - byte[] derEncoding = ((OCSPResponse) response).getEncoded(ASN1Encoding.DER); - TlsUtils.writeOpaque24(derEncoding, output); - break; - default: - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - /** - * Parse a {@link CertificateStatus} from an {@link InputStream}. - * - * @param input - * the {@link InputStream} to parse from. - * @return a {@link CertificateStatus} object. - * @throws IOException - */ - public static CertificateStatus parse(InputStream input) throws IOException - { - short status_type = TlsUtils.readUint8(input); - Object response; - - switch (status_type) - { - case CertificateStatusType.ocsp: - { - byte[] derEncoding = TlsUtils.readOpaque24(input); - response = OCSPResponse.getInstance(TlsUtils.readDERObject(derEncoding)); - break; - } - default: - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - return new CertificateStatus(status_type, response); - } - - protected static boolean isCorrectType(short statusType, Object response) - { - switch (statusType) - { - case CertificateStatusType.ocsp: - return response instanceof OCSPResponse; - default: - throw new IllegalArgumentException("'statusType' is an unsupported value"); - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateStatusRequest.java b/core/src/main/java/org/bouncycastle/crypto/tls/CertificateStatusRequest.java deleted file mode 100644 index b947c488..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateStatusRequest.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class CertificateStatusRequest -{ - protected short statusType; - protected Object request; - - public CertificateStatusRequest(short statusType, Object request) - { - if (!isCorrectType(statusType, request)) - { - throw new IllegalArgumentException("'request' is not an instance of the correct type"); - } - - this.statusType = statusType; - this.request = request; - } - - public short getStatusType() - { - return statusType; - } - - public Object getRequest() - { - return request; - } - - public OCSPStatusRequest getOCSPStatusRequest() - { - if (!isCorrectType(CertificateStatusType.ocsp, request)) - { - throw new IllegalStateException("'request' is not an OCSPStatusRequest"); - } - return (OCSPStatusRequest)request; - } - - /** - * Encode this {@link CertificateStatusRequest} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) throws IOException - { - TlsUtils.writeUint8(statusType, output); - - switch (statusType) - { - case CertificateStatusType.ocsp: - ((OCSPStatusRequest) request).encode(output); - break; - default: - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - /** - * Parse a {@link CertificateStatusRequest} from an {@link InputStream}. - * - * @param input - * the {@link InputStream} to parse from. - * @return a {@link CertificateStatusRequest} object. - * @throws IOException - */ - public static CertificateStatusRequest parse(InputStream input) throws IOException - { - short status_type = TlsUtils.readUint8(input); - Object result; - - switch (status_type) - { - case CertificateStatusType.ocsp: - result = OCSPStatusRequest.parse(input); - break; - default: - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - return new CertificateStatusRequest(status_type, result); - } - - protected static boolean isCorrectType(short statusType, Object request) - { - switch (statusType) - { - case CertificateStatusType.ocsp: - return request instanceof OCSPStatusRequest; - default: - throw new IllegalArgumentException("'statusType' is an unsupported value"); - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateStatusType.java b/core/src/main/java/org/bouncycastle/crypto/tls/CertificateStatusType.java deleted file mode 100644 index bfe82981..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateStatusType.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public class CertificateStatusType -{ - /* - * RFC 3546 3.6 - */ - public static final short ocsp = 1; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateURL.java b/core/src/main/java/org/bouncycastle/crypto/tls/CertificateURL.java deleted file mode 100644 index aab89087..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateURL.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Vector; - -/* - * RFC 3546 3.3 - */ -public class CertificateURL -{ - protected short type; - protected Vector urlAndHashList; - - /** - * @param type - * see {@link CertChainType} for valid constants. - * @param urlAndHashList - * a {@link Vector} of {@link URLAndHash}. - */ - public CertificateURL(short type, Vector urlAndHashList) - { - if (!CertChainType.isValid(type)) - { - throw new IllegalArgumentException("'type' is not a valid CertChainType value"); - } - if (urlAndHashList == null || urlAndHashList.isEmpty()) - { - throw new IllegalArgumentException("'urlAndHashList' must have length > 0"); - } - - this.type = type; - this.urlAndHashList = urlAndHashList; - } - - /** - * @return {@link CertChainType} - */ - public short getType() - { - return type; - } - - /** - * @return a {@link Vector} of {@link URLAndHash} - */ - public Vector getURLAndHashList() - { - return urlAndHashList; - } - - /** - * Encode this {@link CertificateURL} to an {@link OutputStream}. - * - * @param output the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) - throws IOException - { - TlsUtils.writeUint8(this.type, output); - - ListBuffer16 buf = new ListBuffer16(); - for (int i = 0; i < this.urlAndHashList.size(); ++i) - { - URLAndHash urlAndHash = (URLAndHash)this.urlAndHashList.elementAt(i); - urlAndHash.encode(buf); - } - buf.encodeTo(output); - } - - /** - * Parse a {@link CertificateURL} from an {@link InputStream}. - * - * @param context - * the {@link TlsContext} of the current connection. - * @param input - * the {@link InputStream} to parse from. - * @return a {@link CertificateURL} object. - * @throws IOException - */ - public static CertificateURL parse(TlsContext context, InputStream input) - throws IOException - { - short type = TlsUtils.readUint8(input); - if (!CertChainType.isValid(type)) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - int totalLength = TlsUtils.readUint16(input); - if (totalLength < 1) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - byte[] urlAndHashListData = TlsUtils.readFully(totalLength, input); - - ByteArrayInputStream buf = new ByteArrayInputStream(urlAndHashListData); - - Vector url_and_hash_list = new Vector(); - while (buf.available() > 0) - { - URLAndHash url_and_hash = URLAndHash.parse(context, buf); - url_and_hash_list.addElement(url_and_hash); - } - - return new CertificateURL(type, url_and_hash_list); - } - - // TODO Could be more generally useful - class ListBuffer16 extends ByteArrayOutputStream - { - ListBuffer16() throws IOException - { - // Reserve space for length - TlsUtils.writeUint16(0, this); - } - - void encodeTo(OutputStream output) throws IOException - { - // Patch actual length back in - int length = count - 2; - TlsUtils.checkUint16(length); - TlsUtils.writeUint16(length, buf, 0); - output.write(buf, 0, count); - buf = null; - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateVerifyer.java b/core/src/main/java/org/bouncycastle/crypto/tls/CertificateVerifyer.java deleted file mode 100644 index 2e3715c1..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/CertificateVerifyer.java +++ /dev/null @@ -1,16 +0,0 @@ -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 -{ - /** - * @param certs The certs, which are part of the chain. - * @return True, if the chain is accepted, false otherwise. - */ - public boolean isValid(org.bouncycastle.asn1.x509.Certificate[] certs); -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/Chacha20Poly1305.java b/core/src/main/java/org/bouncycastle/crypto/tls/Chacha20Poly1305.java deleted file mode 100644 index a82045bf..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/Chacha20Poly1305.java +++ /dev/null @@ -1,156 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -import org.bouncycastle.crypto.Mac; -import org.bouncycastle.crypto.engines.ChaChaEngine; -import org.bouncycastle.crypto.generators.Poly1305KeyGenerator; -import org.bouncycastle.crypto.macs.Poly1305; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.crypto.params.ParametersWithIV; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Pack; - -public class Chacha20Poly1305 implements TlsCipher -{ - protected TlsContext context; - - protected ChaChaEngine encryptCipher; - protected ChaChaEngine decryptCipher; - - public Chacha20Poly1305(TlsContext context) throws IOException - { - if (!TlsUtils.isTLSv12(context)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - this.context = context; - - byte[] key_block = TlsUtils.calculateKeyBlock(context, 64); - - KeyParameter client_write_key = new KeyParameter(key_block, 0, 32); - KeyParameter server_write_key = new KeyParameter(key_block, 32, 32); - - this.encryptCipher = new ChaChaEngine(20); - this.decryptCipher = new ChaChaEngine(20); - - KeyParameter encryptKey, decryptKey; - if (context.isServer()) - { - encryptKey = server_write_key; - decryptKey = client_write_key; - } - else - { - encryptKey = client_write_key; - decryptKey = server_write_key; - } - - byte[] dummyNonce = new byte[8]; - - this.encryptCipher.init(true, new ParametersWithIV(encryptKey, dummyNonce)); - this.decryptCipher.init(false, new ParametersWithIV(decryptKey, dummyNonce)); - } - - public int getPlaintextLimit(int ciphertextLimit) - { - return ciphertextLimit - 16; - } - - public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) throws IOException - { - int ciphertextLength = len + 16; - - KeyParameter macKey = initRecordMAC(encryptCipher, true, seqNo); - - byte[] output = new byte[ciphertextLength]; - encryptCipher.processBytes(plaintext, offset, len, output, 0); - - byte[] additionalData = getAdditionalData(seqNo, type, len); - byte[] mac = calculateRecordMAC(macKey, additionalData, output, 0, len); - System.arraycopy(mac, 0, output, len, mac.length); - - return output; - } - - public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) throws IOException - { - if (getPlaintextLimit(len) < 0) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - int plaintextLength = len - 16; - - byte[] receivedMAC = Arrays.copyOfRange(ciphertext, offset + plaintextLength, offset + len); - - KeyParameter macKey = initRecordMAC(decryptCipher, false, seqNo); - - byte[] additionalData = getAdditionalData(seqNo, type, plaintextLength); - byte[] calculatedMAC = calculateRecordMAC(macKey, additionalData, ciphertext, offset, plaintextLength); - - if (!Arrays.constantTimeAreEqual(calculatedMAC, receivedMAC)) - { - throw new TlsFatalAlert(AlertDescription.bad_record_mac); - } - - byte[] output = new byte[plaintextLength]; - decryptCipher.processBytes(ciphertext, offset, plaintextLength, output, 0); - - return output; - } - - protected KeyParameter initRecordMAC(ChaChaEngine cipher, boolean forEncryption, long seqNo) - { - byte[] nonce = new byte[8]; - TlsUtils.writeUint64(seqNo, nonce, 0); - - cipher.init(forEncryption, new ParametersWithIV(null, nonce)); - - byte[] firstBlock = new byte[64]; - cipher.processBytes(firstBlock, 0, firstBlock.length, firstBlock, 0); - - // NOTE: The BC implementation puts 'r' after 'k' - System.arraycopy(firstBlock, 0, firstBlock, 32, 16); - KeyParameter macKey = new KeyParameter(firstBlock, 16, 32); - Poly1305KeyGenerator.clamp(macKey.getKey()); - return macKey; - } - - protected byte[] calculateRecordMAC(KeyParameter macKey, byte[] additionalData, byte[] buf, int off, int len) - { - Mac mac = new Poly1305(); - mac.init(macKey); - - updateRecordMAC(mac, additionalData, 0, additionalData.length); - updateRecordMAC(mac, buf, off, len); - - byte[] output = new byte[mac.getMacSize()]; - mac.doFinal(output, 0); - return output; - } - - protected void updateRecordMAC(Mac mac, byte[] buf, int off, int len) - { - mac.update(buf, off, len); - - byte[] longLen = Pack.longToLittleEndian(len & 0xFFFFFFFFL); - mac.update(longLen, 0, longLen.length); - } - - protected byte[] getAdditionalData(long seqNo, short type, int len) throws IOException - { - /* - * additional_data = seq_num + TLSCompressed.type + TLSCompressed.version + - * TLSCompressed.length - */ - byte[] additional_data = new byte[13]; - TlsUtils.writeUint64(seqNo, additional_data, 0); - TlsUtils.writeUint8(type, additional_data, 8); - TlsUtils.writeVersion(context.getServerVersion(), additional_data, 9); - TlsUtils.writeUint16(len, additional_data, 11); - - return additional_data; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ChangeCipherSpec.java b/core/src/main/java/org/bouncycastle/crypto/tls/ChangeCipherSpec.java deleted file mode 100644 index a858deda..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ChangeCipherSpec.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public class ChangeCipherSpec -{ - public static final short change_cipher_spec = 1; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CipherSuite.java b/core/src/main/java/org/bouncycastle/crypto/tls/CipherSuite.java deleted file mode 100644 index 3d4dccab..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/CipherSuite.java +++ /dev/null @@ -1,351 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 2246 A.5 - */ -public class CipherSuite -{ - public static final int TLS_NULL_WITH_NULL_NULL = 0x0000; - public static final int TLS_RSA_WITH_NULL_MD5 = 0x0001; - public static final int TLS_RSA_WITH_NULL_SHA = 0x0002; - public static final int TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003; - public static final int TLS_RSA_WITH_RC4_128_MD5 = 0x0004; - public static final int TLS_RSA_WITH_RC4_128_SHA = 0x0005; - public static final int TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x0006; - public static final int TLS_RSA_WITH_IDEA_CBC_SHA = 0x0007; - public static final int TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008; - public static final int TLS_RSA_WITH_DES_CBC_SHA = 0x0009; - public static final int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A; - public static final int TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000B; - public static final int TLS_DH_DSS_WITH_DES_CBC_SHA = 0x000C; - public static final int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D; - public static final int TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x000E; - public static final int TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000F; - public static final int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010; - public static final int TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011; - public static final int TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012; - public static final int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013; - public static final int TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014; - public static final int TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x0015; - public static final int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016; - public static final int TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x0017; - public static final int TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018; - public static final int TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0x0019; - public static final int TLS_DH_anon_WITH_DES_CBC_SHA = 0x001A; - public static final int TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001B; - - /* - * Note: The cipher suite values { 0x00, 0x1C } and { 0x00, 0x1D } are reserved to avoid - * collision with Fortezza-based cipher suites in SSL 3. - */ - - /* - * RFC 3268 - */ - public static final int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F; - public static final int TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030; - public static final int TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031; - public static final int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032; - public static final int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033; - public static final int TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x0034; - public static final int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035; - public static final int TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036; - public static final int TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037; - public static final int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038; - public static final int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039; - public static final int TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x003A; - - /* - * RFC 5932 - */ - public static final int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0041; - public static final int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0042; - public static final int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0043; - public static final int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044; - public static final int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0045; - public static final int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA = 0x0046; - - public static final int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0084; - public static final int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0085; - public static final int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0086; - public static final int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0087; - public static final int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088; - public static final int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA = 0x0089; - - public static final int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BA; - public static final int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BB; - public static final int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BC; - public static final int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BD; - public static final int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BE; - public static final int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BF; - - public static final int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C0; - public static final int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C1; - public static final int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C2; - public static final int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C3; - public static final int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C4; - public static final int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C5; - - /* - * RFC 4162 - */ - public static final int TLS_RSA_WITH_SEED_CBC_SHA = 0x0096; - public static final int TLS_DH_DSS_WITH_SEED_CBC_SHA = 0x0097; - public static final int TLS_DH_RSA_WITH_SEED_CBC_SHA = 0x0098; - public static final int TLS_DHE_DSS_WITH_SEED_CBC_SHA = 0x0099; - public static final int TLS_DHE_RSA_WITH_SEED_CBC_SHA = 0x009A; - public static final int TLS_DH_anon_WITH_SEED_CBC_SHA = 0x009B; - - /* - * RFC 4279 - */ - public static final int TLS_PSK_WITH_RC4_128_SHA = 0x008A; - public static final int TLS_PSK_WITH_3DES_EDE_CBC_SHA = 0x008B; - public static final int TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C; - public static final int TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D; - public static final int TLS_DHE_PSK_WITH_RC4_128_SHA = 0x008E; - public static final int TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA = 0x008F; - public static final int TLS_DHE_PSK_WITH_AES_128_CBC_SHA = 0x0090; - public static final int TLS_DHE_PSK_WITH_AES_256_CBC_SHA = 0x0091; - public static final int TLS_RSA_PSK_WITH_RC4_128_SHA = 0x0092; - public static final int TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA = 0x0093; - public static final int TLS_RSA_PSK_WITH_AES_128_CBC_SHA = 0x0094; - public static final int TLS_RSA_PSK_WITH_AES_256_CBC_SHA = 0x0095; - - /* - * RFC 4492 - */ - public static final int TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001; - public static final int TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002; - public static final int TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003; - public static final int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004; - public static final int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005; - public static final int TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006; - public static final int TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007; - public static final int TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008; - public static final int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009; - public static final int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A; - public static final int TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B; - public static final int TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C; - public static final int TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D; - public static final int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E; - public static final int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F; - public static final int TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010; - public static final int TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011; - public static final int TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012; - public static final int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013; - public static final int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014; - public static final int TLS_ECDH_anon_WITH_NULL_SHA = 0xC015; - public static final int TLS_ECDH_anon_WITH_RC4_128_SHA = 0xC016; - public static final int TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA = 0xC017; - public static final int TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0xC018; - public static final int TLS_ECDH_anon_WITH_AES_256_CBC_SHA = 0xC019; - - /* - * RFC 4785 - */ - public static final int TLS_PSK_WITH_NULL_SHA = 0x002C; - public static final int TLS_DHE_PSK_WITH_NULL_SHA = 0x002D; - public static final int TLS_RSA_PSK_WITH_NULL_SHA = 0x002E; - - /* - * RFC 5054 - */ - public static final int TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A; - public static final int TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B; - public static final int TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 0xC01C; - public static final int TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D; - public static final int TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E; - public static final int TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 0xC01F; - public static final int TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020; - public static final int TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021; - public static final int TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022; - - /* - * RFC 5246 - */ - public static final int TLS_RSA_WITH_NULL_SHA256 = 0x003B; - public static final int TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C; - public static final int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D; - public static final int TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E; - public static final int TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F; - public static final int TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040; - public static final int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067; - public static final int TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068; - public static final int TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069; - public static final int TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A; - public static final int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B; - public static final int TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x006C; - public static final int TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x006D; - - /* - * RFC 5288 - */ - public static final int TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C; - public static final int TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D; - public static final int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E; - public static final int TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F; - public static final int TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0; - public static final int TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1; - public static final int TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2; - public static final int TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3; - public static final int TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4; - public static final int TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5; - public static final int TLS_DH_anon_WITH_AES_128_GCM_SHA256 = 0x00A6; - public static final int TLS_DH_anon_WITH_AES_256_GCM_SHA384 = 0x00A7; - - /* - * RFC 5289 - */ - public static final int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023; - public static final int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024; - public static final int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025; - public static final int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026; - public static final int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027; - public static final int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028; - public static final int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029; - public static final int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A; - public static final int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B; - public static final int TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C; - public static final int TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D; - public static final int TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E; - public static final int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F; - public static final int TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030; - public static final int TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031; - public static final int TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032; - - /* - * RFC 5487 - */ - public static final int TLS_PSK_WITH_AES_128_GCM_SHA256 = 0x00A8; - public static final int TLS_PSK_WITH_AES_256_GCM_SHA384 = 0x00A9; - public static final int TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA; - public static final int TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB; - public static final int TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 = 0x00AC; - public static final int TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 = 0x00AD; - public static final int TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE; - public static final int TLS_PSK_WITH_AES_256_CBC_SHA384 = 0x00AF; - public static final int TLS_PSK_WITH_NULL_SHA256 = 0x00B0; - public static final int TLS_PSK_WITH_NULL_SHA384 = 0x00B1; - public static final int TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = 0x00B2; - public static final int TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = 0x00B3; - public static final int TLS_DHE_PSK_WITH_NULL_SHA256 = 0x00B4; - public static final int TLS_DHE_PSK_WITH_NULL_SHA384 = 0x00B5; - public static final int TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 = 0x00B6; - public static final int TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 = 0x00B7; - public static final int TLS_RSA_PSK_WITH_NULL_SHA256 = 0x00B8; - public static final int TLS_RSA_PSK_WITH_NULL_SHA384 = 0x00B9; - - /* - * RFC 5489 - */ - public static final int TLS_ECDHE_PSK_WITH_RC4_128_SHA = 0xC033; - public static final int TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = 0xC034; - public static final int TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035; - public static final int TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036; - public static final int TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 0xC037; - public static final int TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = 0xC038; - public static final int TLS_ECDHE_PSK_WITH_NULL_SHA = 0xC039; - public static final int TLS_ECDHE_PSK_WITH_NULL_SHA256 = 0xC03A; - public static final int TLS_ECDHE_PSK_WITH_NULL_SHA384 = 0xC03B; - - /* - * RFC 5746 - */ - public static final int TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF; - - /* - * RFC 6367 - */ - public static final int TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC072; - public static final int TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC073; - public static final int TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC074; - public static final int TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC075; - public static final int TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC076; - public static final int TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC077; - public static final int TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC078; - public static final int TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC079; - - public static final int TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07A; - public static final int TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07B; - public static final int TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07C; - public static final int TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07D; - public static final int TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07E; - public static final int TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07F; - public static final int TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC080; - public static final int TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC081; - public static final int TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC082; - public static final int TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC083; - public static final int TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 = 0xC084; - public static final int TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 = 0xC085; - public static final int TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC086; - public static final int TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC087; - public static final int TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC088; - public static final int TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC089; - public static final int TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08A; - public static final int TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08B; - public static final int TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08C; - public static final int TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08D; - - public static final int TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08E; - public static final int TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08F; - public static final int TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC090; - public static final int TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC091; - public static final int TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC092; - public static final int TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC093; - public static final int TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC094; - public static final int TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC095; - public static final int TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC096; - public static final int TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC097; - public static final int TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC098; - public static final int TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC099; - public static final int TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC09A; - public static final int TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC09B; - - /* - * RFC 6655 - */ - public static final int TLS_RSA_WITH_AES_128_CCM = 0xC09C; - public static final int TLS_RSA_WITH_AES_256_CCM = 0xC09D; - public static final int TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E; - public static final int TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F; - public static final int TLS_RSA_WITH_AES_128_CCM_8 = 0xC0A0; - public static final int TLS_RSA_WITH_AES_256_CCM_8 = 0xC0A1; - public static final int TLS_DHE_RSA_WITH_AES_128_CCM_8 = 0xC0A2; - public static final int TLS_DHE_RSA_WITH_AES_256_CCM_8 = 0xC0A3; - public static final int TLS_PSK_WITH_AES_128_CCM = 0xC0A4; - public static final int TLS_PSK_WITH_AES_256_CCM = 0xC0A5; - public static final int TLS_DHE_PSK_WITH_AES_128_CCM = 0xC0A6; - public static final int TLS_DHE_PSK_WITH_AES_256_CCM = 0xC0A7; - public static final int TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8; - public static final int TLS_PSK_WITH_AES_256_CCM_8 = 0xC0A9; - public static final int TLS_PSK_DHE_WITH_AES_128_CCM_8 = 0xC0AA; - public static final int TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB; - - /* - * draft-agl-tls-chacha20poly1305-04 - */ - public static final int TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC13; - public static final int TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC14; - public static final int TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC15; - - /* - * draft-josefsson-salsa20-tls-04 - */ - public static final int TLS_RSA_WITH_ESTREAM_SALSA20_SHA1 = 0xE410; - public static final int TLS_RSA_WITH_SALSA20_SHA1 = 0xE411; - public static final int TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1 = 0xE412; - public static final int TLS_ECDHE_RSA_WITH_SALSA20_SHA1 = 0xE413; - public static final int TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1 = 0xE414; - public static final int TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1 = 0xE415; - public static final int TLS_PSK_WITH_ESTREAM_SALSA20_SHA1 = 0xE416; - public static final int TLS_PSK_WITH_SALSA20_SHA1 = 0xE417; - public static final int TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1 = 0xE418; - public static final int TLS_ECDHE_PSK_WITH_SALSA20_SHA1 = 0xE419; - public static final int TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1 = 0xE41A; - public static final int TLS_RSA_PSK_WITH_SALSA20_SHA1 = 0xE41B; - public static final int TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1 = 0xE41C; - public static final int TLS_DHE_PSK_WITH_SALSA20_SHA1 = 0xE41D; - public static final int TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1 = 0xE41E; - public static final int TLS_DHE_RSA_WITH_SALSA20_SHA1 = 0xE41F; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CipherType.java b/core/src/main/java/org/bouncycastle/crypto/tls/CipherType.java deleted file mode 100644 index c6d845a6..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/CipherType.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 2246 - * <p> - * 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 static final int stream = 0; - public static final int block = 1; - - /* - * RFC 5246 - */ - public static final int aead = 2; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ClientAuthenticationType.java b/core/src/main/java/org/bouncycastle/crypto/tls/ClientAuthenticationType.java deleted file mode 100644 index 77e64607..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ClientAuthenticationType.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public class ClientAuthenticationType -{ - /* - * RFC 5077 4 - */ - public static final short anonymous = 0; - public static final short certificate_based = 1; - public static final short psk = 2; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ClientCertificateType.java b/core/src/main/java/org/bouncycastle/crypto/tls/ClientCertificateType.java deleted file mode 100644 index 6bddfc0f..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ClientCertificateType.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public class ClientCertificateType -{ - /* - * RFC 4346 7.4.4 - */ - public static final short rsa_sign = 1; - public static final short dss_sign = 2; - public static final short rsa_fixed_dh = 3; - public static final short dss_fixed_dh = 4; - public static final short rsa_ephemeral_dh_RESERVED = 5; - public static final short dss_ephemeral_dh_RESERVED = 6; - public static final short fortezza_dms_RESERVED = 20; - - /* - * RFC 4492 5.5 - */ - public static final short ecdsa_sign = 64; - public static final short rsa_fixed_ecdh = 65; - public static final short ecdsa_fixed_ecdh = 66; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java b/core/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java deleted file mode 100644 index 43b73bff..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java +++ /dev/null @@ -1,135 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.crypto.Digest; - -/** - * A combined hash, which implements md5(m) || sha1(m). - */ -class CombinedHash - implements TlsHandshakeHash -{ - protected TlsContext context; - protected Digest md5; - protected Digest sha1; - - CombinedHash() - { - this.md5 = TlsUtils.createHash(HashAlgorithm.md5); - this.sha1 = TlsUtils.createHash(HashAlgorithm.sha1); - } - - 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) - { - this.context = context; - } - - public TlsHandshakeHash notifyPRFDetermined() - { - return this; - } - - public void trackHashAlgorithm(short hashAlgorithm) - { - throw new IllegalStateException("CombinedHash only supports calculating the legacy PRF for handshake hash"); - } - - public void sealHashAlgorithms() - { - } - - public TlsHandshakeHash stopTracking() - { - return new CombinedHash(this); - } - - public Digest forkPRFHash() - { - return new CombinedHash(this); - } - - public byte[] getFinalHash(short hashAlgorithm) - { - throw new IllegalStateException("CombinedHash doesn't support multiple hashes"); - } - - /** - * @see org.bouncycastle.crypto.Digest#getAlgorithmName() - */ - public String getAlgorithmName() - { - return md5.getAlgorithmName() + " and " + sha1.getAlgorithmName(); - } - - /** - * @see org.bouncycastle.crypto.Digest#getDigestSize() - */ - public int getDigestSize() - { - return md5.getDigestSize() + sha1.getDigestSize(); - } - - /** - * @see org.bouncycastle.crypto.Digest#update(byte) - */ - public void update(byte in) - { - md5.update(in); - sha1.update(in); - } - - /** - * @see org.bouncycastle.crypto.Digest#update(byte[], int, int) - */ - 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) - */ - public int doFinal(byte[] out, int outOff) - { - if (context != null && TlsUtils.isSSL(context)) - { - ssl3Complete(md5, SSL3Mac.IPAD, SSL3Mac.OPAD, 48); - ssl3Complete(sha1, SSL3Mac.IPAD, SSL3Mac.OPAD, 40); - } - - int i1 = md5.doFinal(out, outOff); - int i2 = sha1.doFinal(out, outOff + i1); - return i1 + i2; - } - - /** - * @see org.bouncycastle.crypto.Digest#reset() - */ - public void reset() - { - md5.reset(); - sha1.reset(); - } - - protected void ssl3Complete(Digest d, byte[] ipad, byte[] opad, int padLength) - { - byte[] master_secret = context.getSecurityParameters().masterSecret; - - d.update(master_secret, 0, master_secret.length); - d.update(ipad, 0, padLength); - - byte[] tmp = new byte[d.getDigestSize()]; - d.doFinal(tmp, 0); - - d.update(master_secret, 0, master_secret.length); - d.update(opad, 0, padLength); - d.update(tmp, 0, tmp.length); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CompressionMethod.java b/core/src/main/java/org/bouncycastle/crypto/tls/CompressionMethod.java deleted file mode 100644 index 935d378f..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/CompressionMethod.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 2246 6.1 - */ -public class CompressionMethod -{ - public static final short _null = 0; - - /** - * @deprecated use '_null' instead - */ - public static final short NULL = _null; - - /* - * RFC 3749 2 - */ - public static final short DEFLATE = 1; - - /* - * Values from 224 decimal (0xE0) through 255 decimal (0xFF) - * inclusive are reserved for private use. - */ -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ConnectionEnd.java b/core/src/main/java/org/bouncycastle/crypto/tls/ConnectionEnd.java deleted file mode 100644 index bcbf607e..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ConnectionEnd.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 2246 - * <p> - * 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 static final int server = 0; - public static final int client = 1; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ContentType.java b/core/src/main/java/org/bouncycastle/crypto/tls/ContentType.java deleted file mode 100644 index 65ed9b60..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ContentType.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 2246 6.2.1 - */ -public class ContentType -{ - public static final short change_cipher_spec = 20; - public static final short alert = 21; - public static final short handshake = 22; - public static final short application_data = 23; - public static final short heartbeat = 24; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSClientProtocol.java b/core/src/main/java/org/bouncycastle/crypto/tls/DTLSClientProtocol.java deleted file mode 100644 index b88d8f33..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSClientProtocol.java +++ /dev/null @@ -1,831 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.security.SecureRandom; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import org.bouncycastle.util.Arrays; - -public class DTLSClientProtocol - extends DTLSProtocol -{ - public DTLSClientProtocol(SecureRandom secureRandom) - { - super(secureRandom); - } - - 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; - - ClientHandshakeState state = new ClientHandshakeState(); - state.client = client; - state.clientContext = new TlsClientContextImpl(secureRandom, securityParameters); - - securityParameters.clientRandom = TlsProtocol.createRandomBlock(client.shouldUseGMTUnixTime(), - state.clientContext.getNonceRandomGenerator()); - - client.init(state.clientContext); - - DTLSRecordLayer recordLayer = new DTLSRecordLayer(transport, state.clientContext, client, ContentType.handshake); - - TlsSession sessionToResume = state.client.getSessionToResume(); - if (sessionToResume != null) - { - SessionParameters sessionParameters = sessionToResume.exportSessionParameters(); - if (sessionParameters != null) - { - state.tlsSession = sessionToResume; - state.sessionParameters = sessionParameters; - } - } - - try - { - return clientHandshake(state, recordLayer); - } - catch (TlsFatalAlert fatalAlert) - { - recordLayer.fail(fatalAlert.getAlertDescription()); - throw fatalAlert; - } - catch (IOException e) - { - recordLayer.fail(AlertDescription.internal_error); - throw e; - } - catch (RuntimeException e) - { - recordLayer.fail(AlertDescription.internal_error); - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - protected DTLSTransport clientHandshake(ClientHandshakeState state, DTLSRecordLayer recordLayer) - throws IOException - { - SecurityParameters securityParameters = state.clientContext.getSecurityParameters(); - DTLSReliableHandshake handshake = new DTLSReliableHandshake(state.clientContext, recordLayer); - - byte[] clientHelloBody = generateClientHello(state, state.client); - handshake.sendMessage(HandshakeType.client_hello, clientHelloBody); - - DTLSReliableHandshake.Message serverMessage = handshake.receiveMessage(); - - while (serverMessage.getType() == HandshakeType.hello_verify_request) - { - ProtocolVersion recordLayerVersion = recordLayer.resetDiscoveredPeerVersion(); - ProtocolVersion client_version = state.clientContext.getClientVersion(); - - /* - * RFC 6347 4.2.1 DTLS 1.2 server implementations SHOULD use DTLS version 1.0 regardless of - * the version of TLS that is expected to be negotiated. DTLS 1.2 and 1.0 clients MUST use - * the version solely to indicate packet formatting (which is the same in both DTLS 1.2 and - * 1.0) and not as part of version negotiation. - */ - if (!recordLayerVersion.isEqualOrEarlierVersionOf(client_version)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - byte[] cookie = processHelloVerifyRequest(state, serverMessage.getBody()); - byte[] patched = patchClientHelloWithCookie(clientHelloBody, cookie); - - handshake.resetHandshakeMessagesDigest(); - handshake.sendMessage(HandshakeType.client_hello, patched); - - serverMessage = handshake.receiveMessage(); - } - - if (serverMessage.getType() == HandshakeType.server_hello) - { - reportServerVersion(state, recordLayer.getDiscoveredPeerVersion()); - - processServerHello(state, serverMessage.getBody()); - } - else - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - if (state.maxFragmentLength >= 0) - { - int plainTextLimit = 1 << (8 + state.maxFragmentLength); - recordLayer.setPlaintextLimit(plainTextLimit); - } - - securityParameters.cipherSuite = state.selectedCipherSuite; - securityParameters.compressionAlgorithm = state.selectedCompressionMethod; - securityParameters.prfAlgorithm = TlsProtocol.getPRFAlgorithm(state.clientContext, state.selectedCipherSuite); - - /* - * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify verify_data_length has - * a verify_data_length equal to 12. This includes all existing cipher suites. - */ - securityParameters.verifyDataLength = 12; - - handshake.notifyHelloComplete(); - - boolean resumedSession = state.selectedSessionID.length > 0 && state.tlsSession != null - && Arrays.areEqual(state.selectedSessionID, state.tlsSession.getSessionID()); - - if (resumedSession) - { - if (securityParameters.getCipherSuite() != state.sessionParameters.getCipherSuite() - || securityParameters.getCompressionAlgorithm() != state.sessionParameters.getCompressionAlgorithm()) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - securityParameters.masterSecret = Arrays.clone(state.sessionParameters.getMasterSecret()); - recordLayer.initPendingEpoch(state.client.getCipher()); - - // NOTE: Calculated exclusive of the actual Finished message from the server - byte[] expectedServerVerifyData = TlsUtils.calculateVerifyData(state.clientContext, ExporterLabel.server_finished, - TlsProtocol.getCurrentPRFHash(state.clientContext, handshake.getHandshakeHash(), null)); - processFinished(handshake.receiveMessageBody(HandshakeType.finished), expectedServerVerifyData); - - // NOTE: Calculated exclusive of the Finished message itself - byte[] clientVerifyData = TlsUtils.calculateVerifyData(state.clientContext, ExporterLabel.client_finished, - TlsProtocol.getCurrentPRFHash(state.clientContext, handshake.getHandshakeHash(), null)); - handshake.sendMessage(HandshakeType.finished, clientVerifyData); - - handshake.finish(); - - state.clientContext.setResumableSession(state.tlsSession); - - state.client.notifyHandshakeComplete(); - - return new DTLSTransport(recordLayer); - } - - invalidateSession(state); - - if (state.selectedSessionID.length > 0) - { - state.tlsSession = new TlsSessionImpl(state.selectedSessionID, null); - } - - serverMessage = handshake.receiveMessage(); - - if (serverMessage.getType() == HandshakeType.supplemental_data) - { - processServerSupplementalData(state, serverMessage.getBody()); - serverMessage = handshake.receiveMessage(); - } - else - { - state.client.processServerSupplementalData(null); - } - - state.keyExchange = state.client.getKeyExchange(); - state.keyExchange.init(state.clientContext); - - Certificate serverCertificate = null; - - if (serverMessage.getType() == HandshakeType.certificate) - { - serverCertificate = processServerCertificate(state, serverMessage.getBody()); - serverMessage = handshake.receiveMessage(); - } - else - { - // Okay, Certificate is optional - state.keyExchange.skipServerCredentials(); - } - - // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus - if (serverCertificate == null || serverCertificate.isEmpty()) - { - state.allowCertificateStatus = false; - } - - if (serverMessage.getType() == HandshakeType.certificate_status) - { - processCertificateStatus(state, serverMessage.getBody()); - serverMessage = handshake.receiveMessage(); - } - else - { - // Okay, CertificateStatus is optional - } - - if (serverMessage.getType() == HandshakeType.server_key_exchange) - { - processServerKeyExchange(state, serverMessage.getBody()); - serverMessage = handshake.receiveMessage(); - } - else - { - // Okay, ServerKeyExchange is optional - state.keyExchange.skipServerKeyExchange(); - } - - if (serverMessage.getType() == HandshakeType.certificate_request) - { - processCertificateRequest(state, serverMessage.getBody()); - - /* - * TODO Give the client a chance to immediately select the CertificateVerify hash - * algorithm here to avoid tracking the other hash algorithms unnecessarily? - */ - TlsUtils.trackHashAlgorithms(handshake.getHandshakeHash(), - state.certificateRequest.getSupportedSignatureAlgorithms()); - - serverMessage = handshake.receiveMessage(); - } - else - { - // Okay, CertificateRequest is optional - } - - if (serverMessage.getType() == HandshakeType.server_hello_done) - { - if (serverMessage.getBody().length != 0) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - } - else - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - handshake.getHandshakeHash().sealHashAlgorithms(); - - Vector clientSupplementalData = state.client.getClientSupplementalData(); - if (clientSupplementalData != null) - { - byte[] supplementalDataBody = generateSupplementalData(clientSupplementalData); - handshake.sendMessage(HandshakeType.supplemental_data, supplementalDataBody); - } - - if (state.certificateRequest != null) - { - state.clientCredentials = state.authentication.getClientCredentials(state.certificateRequest); - - /* - * RFC 5246 If no suitable certificate is available, the client MUST send a certificate - * message containing no certificates. - * - * NOTE: In previous RFCs, this was SHOULD instead of MUST. - */ - Certificate clientCertificate = null; - if (state.clientCredentials != null) - { - clientCertificate = state.clientCredentials.getCertificate(); - } - if (clientCertificate == null) - { - clientCertificate = Certificate.EMPTY_CHAIN; - } - - byte[] certificateBody = generateCertificate(clientCertificate); - handshake.sendMessage(HandshakeType.certificate, certificateBody); - } - - if (state.clientCredentials != null) - { - state.keyExchange.processClientCredentials(state.clientCredentials); - } - else - { - state.keyExchange.skipClientCredentials(); - } - - byte[] clientKeyExchangeBody = generateClientKeyExchange(state); - handshake.sendMessage(HandshakeType.client_key_exchange, clientKeyExchangeBody); - - TlsProtocol.establishMasterSecret(state.clientContext, state.keyExchange); - recordLayer.initPendingEpoch(state.client.getCipher()); - - TlsHandshakeHash prepareFinishHash = handshake.prepareToFinish(); - - if (state.clientCredentials != null && state.clientCredentials instanceof TlsSignerCredentials) - { - TlsSignerCredentials signerCredentials = (TlsSignerCredentials)state.clientCredentials; - - /* - * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 - */ - SignatureAndHashAlgorithm signatureAndHashAlgorithm; - byte[] hash; - - if (TlsUtils.isTLSv12(state.clientContext)) - { - signatureAndHashAlgorithm = signerCredentials.getSignatureAndHashAlgorithm(); - if (signatureAndHashAlgorithm == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - hash = prepareFinishHash.getFinalHash(signatureAndHashAlgorithm.getHash()); - } - else - { - signatureAndHashAlgorithm = null; - hash = TlsProtocol.getCurrentPRFHash(state.clientContext, prepareFinishHash, null); - } - - byte[] signature = signerCredentials.generateCertificateSignature(hash); - DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); - byte[] certificateVerifyBody = generateCertificateVerify(state, certificateVerify); - handshake.sendMessage(HandshakeType.certificate_verify, certificateVerifyBody); - } - - // NOTE: Calculated exclusive of the Finished message itself - byte[] clientVerifyData = TlsUtils.calculateVerifyData(state.clientContext, ExporterLabel.client_finished, - TlsProtocol.getCurrentPRFHash(state.clientContext, handshake.getHandshakeHash(), null)); - handshake.sendMessage(HandshakeType.finished, clientVerifyData); - - if (state.expectSessionTicket) - { - serverMessage = handshake.receiveMessage(); - if (serverMessage.getType() == HandshakeType.session_ticket) - { - processNewSessionTicket(state, serverMessage.getBody()); - } - else - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - } - - // NOTE: Calculated exclusive of the actual Finished message from the server - byte[] expectedServerVerifyData = TlsUtils.calculateVerifyData(state.clientContext, ExporterLabel.server_finished, - TlsProtocol.getCurrentPRFHash(state.clientContext, handshake.getHandshakeHash(), null)); - processFinished(handshake.receiveMessageBody(HandshakeType.finished), expectedServerVerifyData); - - handshake.finish(); - - if (state.tlsSession != null) - { - state.sessionParameters = new SessionParameters.Builder() - .setCipherSuite(securityParameters.cipherSuite) - .setCompressionAlgorithm(securityParameters.compressionAlgorithm) - .setMasterSecret(securityParameters.masterSecret) - .setPeerCertificate(serverCertificate) - .build(); - - state.tlsSession = TlsUtils.importSession(state.tlsSession.getSessionID(), state.sessionParameters); - - state.clientContext.setResumableSession(state.tlsSession); - } - - state.client.notifyHandshakeComplete(); - - return new DTLSTransport(recordLayer); - } - - protected byte[] generateCertificateVerify(ClientHandshakeState state, DigitallySigned certificateVerify) - throws IOException - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - certificateVerify.encode(buf); - return buf.toByteArray(); - } - - protected byte[] generateClientHello(ClientHandshakeState state, TlsClient client) - throws IOException - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - ProtocolVersion client_version = client.getClientVersion(); - if (!client_version.isDTLS()) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - state.clientContext.setClientVersion(client_version); - TlsUtils.writeVersion(client_version, buf); - - buf.write(state.clientContext.getSecurityParameters().getClientRandom()); - - // Session ID - byte[] session_id = TlsUtils.EMPTY_BYTES; - if (state.tlsSession != null) - { - session_id = state.tlsSession.getSessionID(); - if (session_id == null || session_id.length > 32) - { - session_id = TlsUtils.EMPTY_BYTES; - } - } - TlsUtils.writeOpaque8(session_id, buf); - - // Cookie - TlsUtils.writeOpaque8(TlsUtils.EMPTY_BYTES, buf); - - /* - * Cipher suites - */ - state.offeredCipherSuites = client.getCipherSuites(); - - // Integer -> byte[] - state.clientExtensions = client.getClientExtensions(); - - // Cipher Suites (and SCSV) - { - /* - * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, - * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the - * ClientHello. Including both is NOT RECOMMENDED. - */ - byte[] renegExtData = TlsUtils.getExtensionData(state.clientExtensions, TlsProtocol.EXT_RenegotiationInfo); - boolean noRenegExt = (null == renegExtData); - - boolean noSCSV = !Arrays.contains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); - - if (noRenegExt && noSCSV) - { - // TODO Consider whether to default to a client extension instead - state.offeredCipherSuites = Arrays.append(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); - } - - TlsUtils.writeUint16ArrayWithUint16Length(state.offeredCipherSuites, buf); - } - - // TODO Add support for compression - // Compression methods - // state.offeredCompressionMethods = client.getCompressionMethods(); - state.offeredCompressionMethods = new short[]{ CompressionMethod._null }; - - TlsUtils.writeUint8ArrayWithUint8Length(state.offeredCompressionMethods, buf); - - // Extensions - if (state.clientExtensions != null) - { - TlsProtocol.writeExtensions(buf, state.clientExtensions); - } - - return buf.toByteArray(); - } - - protected byte[] generateClientKeyExchange(ClientHandshakeState state) - throws IOException - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - state.keyExchange.generateClientKeyExchange(buf); - return buf.toByteArray(); - } - - protected void invalidateSession(ClientHandshakeState state) - { - if (state.sessionParameters != null) - { - state.sessionParameters.clear(); - state.sessionParameters = null; - } - - if (state.tlsSession != null) - { - state.tlsSession.invalidate(); - state.tlsSession = null; - } - } - - protected void processCertificateRequest(ClientHandshakeState state, byte[] body) - throws IOException - { - if (state.authentication == null) - { - /* - * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server to - * request client identification. - */ - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - - ByteArrayInputStream buf = new ByteArrayInputStream(body); - - state.certificateRequest = CertificateRequest.parse(state.clientContext, buf); - - TlsProtocol.assertEmpty(buf); - - state.keyExchange.validateCertificateRequest(state.certificateRequest); - } - - protected void processCertificateStatus(ClientHandshakeState state, byte[] body) - throws IOException - { - if (!state.allowCertificateStatus) - { - /* - * RFC 3546 3.6. If a server returns a "CertificateStatus" message, then the - * server MUST have included an extension of type "status_request" with empty - * "extension_data" in the extended server hello.. - */ - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - ByteArrayInputStream buf = new ByteArrayInputStream(body); - - state.certificateStatus = CertificateStatus.parse(buf); - - TlsProtocol.assertEmpty(buf); - - // TODO[RFC 3546] Figure out how to provide this to the client/authentication. - } - - protected byte[] processHelloVerifyRequest(ClientHandshakeState state, byte[] body) - throws IOException - { - ByteArrayInputStream buf = new ByteArrayInputStream(body); - - ProtocolVersion server_version = TlsUtils.readVersion(buf); - byte[] cookie = TlsUtils.readOpaque8(buf); - - TlsProtocol.assertEmpty(buf); - - // TODO Seems this behaviour is not yet in line with OpenSSL for DTLS 1.2 -// reportServerVersion(state, server_version); - if (!server_version.isEqualOrEarlierVersionOf(state.clientContext.getClientVersion())) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - /* - * RFC 6347 This specification increases the cookie size limit to 255 bytes for greater - * future flexibility. The limit remains 32 for previous versions of DTLS. - */ - if (!ProtocolVersion.DTLSv12.isEqualOrEarlierVersionOf(server_version) && cookie.length > 32) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - return cookie; - } - - protected void processNewSessionTicket(ClientHandshakeState state, byte[] body) - throws IOException - { - ByteArrayInputStream buf = new ByteArrayInputStream(body); - - NewSessionTicket newSessionTicket = NewSessionTicket.parse(buf); - - TlsProtocol.assertEmpty(buf); - - state.client.notifyNewSessionTicket(newSessionTicket); - } - - protected Certificate processServerCertificate(ClientHandshakeState state, byte[] body) - throws IOException - { - ByteArrayInputStream buf = new ByteArrayInputStream(body); - - Certificate serverCertificate = Certificate.parse(buf); - - TlsProtocol.assertEmpty(buf); - - state.keyExchange.processServerCertificate(serverCertificate); - state.authentication = state.client.getAuthentication(); - state.authentication.notifyServerCertificate(serverCertificate); - - return serverCertificate; - } - - protected void processServerHello(ClientHandshakeState state, byte[] body) - throws IOException - { - SecurityParameters securityParameters = state.clientContext.getSecurityParameters(); - - ByteArrayInputStream buf = new ByteArrayInputStream(body); - - ProtocolVersion server_version = TlsUtils.readVersion(buf); - reportServerVersion(state, server_version); - - securityParameters.serverRandom = TlsUtils.readFully(32, buf); - - state.selectedSessionID = TlsUtils.readOpaque8(buf); - if (state.selectedSessionID.length > 32) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - state.client.notifySessionID(state.selectedSessionID); - - state.selectedCipherSuite = TlsUtils.readUint16(buf); - if (!Arrays.contains(state.offeredCipherSuites, state.selectedCipherSuite) - || state.selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL - || state.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV - || !TlsUtils.isValidCipherSuiteForVersion(state.selectedCipherSuite, server_version)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - validateSelectedCipherSuite(state.selectedCipherSuite, AlertDescription.illegal_parameter); - - state.client.notifySelectedCipherSuite(state.selectedCipherSuite); - - state.selectedCompressionMethod = TlsUtils.readUint8(buf); - if (!Arrays.contains(state.offeredCompressionMethods, state.selectedCompressionMethod)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - state.client.notifySelectedCompressionMethod(state.selectedCompressionMethod); - - /* - * RFC3546 2.2 The extended server hello message format MAY be sent in place of the server - * hello message when the client has requested extended functionality via the extended - * client hello message specified in Section 2.1. ... Note that the extended server hello - * message is only sent in response to an extended client hello message. This prevents the - * possibility that the extended server hello message could "break" existing TLS 1.0 - * clients. - */ - - /* - * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore - * extensions appearing in the client hello, and send a server hello containing no - * extensions. - */ - - // Integer -> byte[] - Hashtable serverExtensions = TlsProtocol.readExtensions(buf); - - /* - * RFC 3546 2.2 Note that the extended server hello message is only sent in response to an - * 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) - { - Enumeration e = serverExtensions.keys(); - while (e.hasMoreElements()) - { - Integer extType = (Integer)e.nextElement(); - - /* - * RFC 5746 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, Section 7.4.1.4, on the server sending unsolicited extensions and is - * only allowed because the client is signaling its willingness to receive the - * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. TLS implementations - * MUST continue to comply with Section 7.4.1.4 for all other extensions. - */ - if (!extType.equals(TlsProtocol.EXT_RenegotiationInfo) - && null == TlsUtils.getExtensionData(state.clientExtensions, extType)) - { - /* - * 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 - * unless the same extension type appeared in the corresponding client hello. - * Thus clients MUST abort the handshake if they receive an extension type in - * the extended server hello that they did not request in the associated - * (extended) client hello. - */ - throw new TlsFatalAlert(AlertDescription.unsupported_extension); - } - } - - /* - * RFC 5746 3.4. Client Behavior: Initial Handshake - */ - { - /* - * When a ServerHello is received, the client MUST check if it includes the - * "renegotiation_info" extension: - */ - byte[] renegExtData = (byte[])serverExtensions.get(TlsProtocol.EXT_RenegotiationInfo); - if (renegExtData != 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" - * field is zero, and if it is not, MUST abort the handshake (by sending a fatal - * handshake_failure alert). - */ - state.secure_renegotiation = true; - - if (!Arrays.constantTimeAreEqual(renegExtData, - TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - } - } - - /* - * draft-ietf-tls-encrypt-then-mac-03 3. If a server receives an encrypt-then-MAC - * request extension from a client and then selects a stream or AEAD cipher suite, it - * MUST NOT send an encrypt-then-MAC response extension back to the client. - */ - boolean serverSentEncryptThenMAC = TlsExtensionsUtils.hasEncryptThenMACExtension(serverExtensions); - if (serverSentEncryptThenMAC && !TlsUtils.isBlockCipherSuite(state.selectedCipherSuite)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - securityParameters.encryptThenMAC = serverSentEncryptThenMAC; - - state.maxFragmentLength = evaluateMaxFragmentLengthExtension(state.clientExtensions, serverExtensions, - AlertDescription.illegal_parameter); - - securityParameters.truncatedHMac = TlsExtensionsUtils.hasTruncatedHMacExtension(serverExtensions); - - state.allowCertificateStatus = TlsUtils.hasExpectedEmptyExtensionData(serverExtensions, - TlsExtensionsUtils.EXT_status_request, AlertDescription.illegal_parameter); - - state.expectSessionTicket = TlsUtils.hasExpectedEmptyExtensionData(serverExtensions, - TlsProtocol.EXT_SessionTicket, AlertDescription.illegal_parameter); - } - - state.client.notifySecureRenegotiation(state.secure_renegotiation); - - if (state.clientExtensions != null) - { - state.client.processServerExtensions(serverExtensions); - } - } - - protected void processServerKeyExchange(ClientHandshakeState state, byte[] body) - throws IOException - { - ByteArrayInputStream buf = new ByteArrayInputStream(body); - - state.keyExchange.processServerKeyExchange(buf); - - TlsProtocol.assertEmpty(buf); - } - - protected void processServerSupplementalData(ClientHandshakeState state, byte[] body) - throws IOException - { - ByteArrayInputStream buf = new ByteArrayInputStream(body); - Vector serverSupplementalData = TlsProtocol.readSupplementalDataMessage(buf); - state.client.processServerSupplementalData(serverSupplementalData); - } - - protected void reportServerVersion(ClientHandshakeState state, ProtocolVersion server_version) - throws IOException - { - TlsClientContextImpl clientContext = state.clientContext; - ProtocolVersion currentServerVersion = clientContext.getServerVersion(); - if (null == currentServerVersion) - { - clientContext.setServerVersion(server_version); - state.client.notifyServerVersion(server_version); - } - else if (!currentServerVersion.equals(server_version)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - - protected static byte[] patchClientHelloWithCookie(byte[] clientHelloBody, byte[] cookie) - throws IOException - { - int sessionIDPos = 34; - int sessionIDLength = TlsUtils.readUint8(clientHelloBody, sessionIDPos); - - int cookieLengthPos = sessionIDPos + 1 + sessionIDLength; - int cookiePos = cookieLengthPos + 1; - - byte[] patched = new byte[clientHelloBody.length + cookie.length]; - System.arraycopy(clientHelloBody, 0, patched, 0, cookieLengthPos); - TlsUtils.checkUint8(cookie.length); - TlsUtils.writeUint8(cookie.length, patched, cookieLengthPos); - System.arraycopy(cookie, 0, patched, cookiePos, cookie.length); - System.arraycopy(clientHelloBody, cookiePos, patched, cookiePos + cookie.length, clientHelloBody.length - - cookiePos); - - return patched; - } - - protected static class ClientHandshakeState - { - TlsClient client = null; - TlsClientContextImpl clientContext = null; - TlsSession tlsSession = null; - SessionParameters sessionParameters = null; - SessionParameters.Builder sessionParametersBuilder = null; - int[] offeredCipherSuites = null; - short[] offeredCompressionMethods = null; - Hashtable clientExtensions = null; - byte[] selectedSessionID = null; - int selectedCipherSuite = -1; - short selectedCompressionMethod = -1; - boolean secure_renegotiation = false; - short maxFragmentLength = -1; - boolean allowCertificateStatus = false; - boolean expectSessionTicket = false; - TlsKeyExchange keyExchange = null; - TlsAuthentication authentication = null; - CertificateStatus certificateStatus = null; - CertificateRequest certificateRequest = null; - TlsCredentials clientCredentials = null; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSEpoch.java b/core/src/main/java/org/bouncycastle/crypto/tls/DTLSEpoch.java deleted file mode 100644 index 57dd42f6..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSEpoch.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.bouncycastle.crypto.tls; - -class DTLSEpoch -{ - private final DTLSReplayWindow replayWindow = new DTLSReplayWindow(); - - private final int epoch; - private final TlsCipher cipher; - - private long sequence_number = 0; - - DTLSEpoch(int epoch, TlsCipher cipher) - { - if (epoch < 0) - { - throw new IllegalArgumentException("'epoch' must be >= 0"); - } - if (cipher == null) - { - throw new IllegalArgumentException("'cipher' cannot be null"); - } - - this.epoch = epoch; - this.cipher = cipher; - } - - long allocateSequenceNumber() - { - // TODO Check for overflow - return sequence_number++; - } - - TlsCipher getCipher() - { - return cipher; - } - - int getEpoch() - { - return epoch; - } - - DTLSReplayWindow getReplayWindow() - { - return replayWindow; - } - - long getSequence_number() - { - return sequence_number; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSHandshakeRetransmit.java b/core/src/main/java/org/bouncycastle/crypto/tls/DTLSHandshakeRetransmit.java deleted file mode 100644 index 251d3a28..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSHandshakeRetransmit.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -interface DTLSHandshakeRetransmit -{ - void receivedHandshakeRecord(int epoch, byte[] buf, int off, int len) - throws IOException; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSProtocol.java b/core/src/main/java/org/bouncycastle/crypto/tls/DTLSProtocol.java deleted file mode 100644 index db43011b..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSProtocol.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.security.SecureRandom; -import java.util.Hashtable; -import java.util.Vector; - -import org.bouncycastle.util.Arrays; - -public abstract class DTLSProtocol -{ - protected final 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 - { - ByteArrayInputStream buf = new ByteArrayInputStream(body); - - byte[] verify_data = TlsUtils.readFully(expected_verify_data.length, buf); - - TlsProtocol.assertEmpty(buf); - - if (!Arrays.constantTimeAreEqual(expected_verify_data, verify_data)) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - } - - protected static short evaluateMaxFragmentLengthExtension(Hashtable clientExtensions, Hashtable serverExtensions, - short alertDescription) throws IOException - { - short maxFragmentLength = TlsExtensionsUtils.getMaxFragmentLengthExtension(serverExtensions); - if (maxFragmentLength >= 0 && maxFragmentLength != TlsExtensionsUtils.getMaxFragmentLengthExtension(clientExtensions)) - { - throw new TlsFatalAlert(alertDescription); - } - return maxFragmentLength; - } - - 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 - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - TlsProtocol.writeSupplementalData(buf, supplementalData); - return buf.toByteArray(); - } - - protected static void validateSelectedCipherSuite(int selectedCipherSuite, short alertDescription) - throws IOException - { - switch (TlsUtils.getEncryptionAlgorithm(selectedCipherSuite)) - { - case EncryptionAlgorithm.RC4_40: - case EncryptionAlgorithm.RC4_128: - throw new TlsFatalAlert(alertDescription); - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSReassembler.java b/core/src/main/java/org/bouncycastle/crypto/tls/DTLSReassembler.java deleted file mode 100644 index 788306c8..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSReassembler.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.util.Vector; - -class DTLSReassembler -{ - private final short msg_type; - private final byte[] body; - - private Vector missing = new Vector(); - - DTLSReassembler(short msg_type, int length) - { - this.msg_type = msg_type; - this.body = new byte[length]; - this.missing.addElement(new Range(0, length)); - } - - short getType() - { - return msg_type; - } - - byte[] getBodyIfComplete() - { - return missing.isEmpty() ? body : null; - } - - void contributeFragment(short msg_type, int length, byte[] buf, int off, int fragment_offset, - int fragment_length) - { - int fragment_end = fragment_offset + fragment_length; - - if (this.msg_type != msg_type || this.body.length != length || fragment_end > length) - { - return; - } - - if (fragment_length == 0) - { - // NOTE: Empty messages still require an empty fragment to complete it - if (fragment_offset == 0 && !missing.isEmpty()) - { - Range firstRange = (Range)missing.firstElement(); - if (firstRange.getEnd() == 0) - { - missing.removeElementAt(0); - } - } - return; - } - - for (int i = 0; i < missing.size(); ++i) - { - Range range = (Range)missing.elementAt(i); - if (range.getStart() >= fragment_end) - { - break; - } - if (range.getEnd() > fragment_offset) - { - - int copyStart = Math.max(range.getStart(), fragment_offset); - int copyEnd = Math.min(range.getEnd(), fragment_end); - int copyLength = copyEnd - copyStart; - - System.arraycopy(buf, off + copyStart - fragment_offset, body, copyStart, - copyLength); - - if (copyStart == range.getStart()) - { - if (copyEnd == range.getEnd()) - { - missing.removeElementAt(i--); - } - else - { - range.setStart(copyEnd); - } - } - else - { - if (copyEnd == range.getEnd()) - { - range.setEnd(copyStart); - } - else - { - missing.insertElementAt(new Range(copyEnd, range.getEnd()), ++i); - range.setEnd(copyStart); - } - } - } - } - } - - void reset() - { - this.missing.removeAllElements(); - this.missing.addElement(new Range(0, body.length)); - } - - private static class Range - { - private int start, end; - - Range(int start, int end) - { - this.start = start; - this.end = end; - } - - public int getStart() - { - return start; - } - - public void setStart(int start) - { - this.start = start; - } - - public int getEnd() - { - return end; - } - - public void setEnd(int end) - { - this.end = end; - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSRecordLayer.java b/core/src/main/java/org/bouncycastle/crypto/tls/DTLSRecordLayer.java deleted file mode 100644 index 15192395..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSRecordLayer.java +++ /dev/null @@ -1,516 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -class DTLSRecordLayer - implements DatagramTransport -{ - private static final int RECORD_HEADER_LENGTH = 13; - private static final int MAX_FRAGMENT_LENGTH = 1 << 14; - private static final long TCP_MSL = 1000L * 60 * 2; - private static final long RETRANSMIT_TIMEOUT = TCP_MSL * 2; - - private final DatagramTransport transport; - private final TlsContext context; - private final TlsPeer peer; - - private final ByteQueue recordQueue = new ByteQueue(); - - private volatile boolean closed = false; - private volatile boolean failed = false; - private volatile ProtocolVersion discoveredPeerVersion = null; - private volatile boolean inHandshake; - private volatile int plaintextLimit; - private DTLSEpoch currentEpoch, pendingEpoch; - private DTLSEpoch readEpoch, writeEpoch; - - private DTLSHandshakeRetransmit retransmit = null; - private DTLSEpoch retransmitEpoch = null; - private long retransmitExpiry = 0; - - DTLSRecordLayer(DatagramTransport transport, TlsContext context, TlsPeer peer, short contentType) - { - this.transport = transport; - this.context = context; - this.peer = peer; - - this.inHandshake = true; - - this.currentEpoch = new DTLSEpoch(0, new TlsNullCipher(context)); - this.pendingEpoch = null; - this.readEpoch = currentEpoch; - this.writeEpoch = currentEpoch; - - setPlaintextLimit(MAX_FRAGMENT_LENGTH); - } - - void setPlaintextLimit(int plaintextLimit) - { - this.plaintextLimit = plaintextLimit; - } - - ProtocolVersion getDiscoveredPeerVersion() - { - return discoveredPeerVersion; - } - - ProtocolVersion resetDiscoveredPeerVersion() - { - ProtocolVersion result = discoveredPeerVersion; - discoveredPeerVersion = null; - return result; - } - - void initPendingEpoch(TlsCipher pendingCipher) - { - if (pendingEpoch != null) - { - throw new IllegalStateException(); - } - - /* - * TODO "In order to ensure that any given sequence/epoch pair is unique, implementations - * MUST NOT allow the same epoch value to be reused within two times the TCP maximum segment - * lifetime." - */ - - // TODO Check for overflow - this.pendingEpoch = new DTLSEpoch(writeEpoch.getEpoch() + 1, pendingCipher); - } - - void handshakeSuccessful(DTLSHandshakeRetransmit retransmit) - { - if (readEpoch == currentEpoch || writeEpoch == currentEpoch) - { - // TODO - throw new IllegalStateException(); - } - - if (retransmit != null) - { - this.retransmit = retransmit; - this.retransmitEpoch = currentEpoch; - this.retransmitExpiry = System.currentTimeMillis() + RETRANSMIT_TIMEOUT; - } - - this.inHandshake = false; - this.currentEpoch = pendingEpoch; - this.pendingEpoch = null; - } - - void resetWriteEpoch() - { - if (retransmitEpoch != null) - { - this.writeEpoch = retransmitEpoch; - } - else - { - this.writeEpoch = currentEpoch; - } - } - - public int getReceiveLimit() - throws IOException - { - return Math.min(this.plaintextLimit, - readEpoch.getCipher().getPlaintextLimit(transport.getReceiveLimit() - RECORD_HEADER_LENGTH)); - } - - public int getSendLimit() - throws IOException - { - return Math.min(this.plaintextLimit, - writeEpoch.getCipher().getPlaintextLimit(transport.getSendLimit() - RECORD_HEADER_LENGTH)); - } - - public int receive(byte[] buf, int off, int len, int waitMillis) - throws IOException - { - byte[] record = null; - - for (;;) - { - int receiveLimit = Math.min(len, getReceiveLimit()) + RECORD_HEADER_LENGTH; - if (record == null || record.length < receiveLimit) - { - record = new byte[receiveLimit]; - } - - try - { - if (retransmit != null && System.currentTimeMillis() > retransmitExpiry) - { - retransmit = null; - retransmitEpoch = null; - } - - int received = receiveRecord(record, 0, receiveLimit, waitMillis); - if (received < 0) - { - return received; - } - if (received < RECORD_HEADER_LENGTH) - { - continue; - } - int length = TlsUtils.readUint16(record, 11); - if (received != (length + RECORD_HEADER_LENGTH)) - { - continue; - } - - short type = TlsUtils.readUint8(record, 0); - - // TODO Support user-specified custom protocols? - switch (type) - { - case ContentType.alert: - case ContentType.application_data: - case ContentType.change_cipher_spec: - case ContentType.handshake: - case ContentType.heartbeat: - break; - default: - // TODO Exception? - continue; - } - - int epoch = TlsUtils.readUint16(record, 3); - - DTLSEpoch recordEpoch = null; - if (epoch == readEpoch.getEpoch()) - { - recordEpoch = readEpoch; - } - 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, - received - RECORD_HEADER_LENGTH); - - recordEpoch.getReplayWindow().reportAuthenticated(seq); - - if (plaintext.length > this.plaintextLimit) - { - continue; - } - - if (discoveredPeerVersion == null) - { - discoveredPeerVersion = version; - } - - switch (type) - { - case ContentType.alert: - { - if (plaintext.length == 2) - { - short alertLevel = plaintext[0]; - short alertDescription = plaintext[1]; - - peer.notifyAlertReceived(alertLevel, alertDescription); - - if (alertLevel == AlertLevel.fatal) - { - fail(alertDescription); - throw new TlsFatalAlert(alertDescription); - } - - // TODO Can close_notify be a fatal alert? - if (alertDescription == AlertDescription.close_notify) - { - closeTransport(); - } - } - - continue; - } - 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: - { - // Implicitly receive change_cipher_spec and change to pending cipher state - - for (int i = 0; i < plaintext.length; ++i) - { - short message = TlsUtils.readUint8(plaintext, i); - if (message != ChangeCipherSpec.change_cipher_spec) - { - continue; - } - - if (pendingEpoch != null) - { - readEpoch = pendingEpoch; - } - } - - continue; - } - case ContentType.handshake: - { - if (!inHandshake) - { - if (retransmit != null) - { - retransmit.receivedHandshakeRecord(epoch, plaintext, 0, plaintext.length); - } - - // TODO Consider support for HelloRequest - continue; - } - break; - } - case ContentType.heartbeat: - { - // TODO[RFC 6520] - continue; - } - } - - /* - * NOTE: If we receive any non-handshake data in the new epoch implies the peer has - * received our final flight. - */ - if (!inHandshake && retransmit != null) - { - this.retransmit = null; - this.retransmitEpoch = null; - } - - System.arraycopy(plaintext, 0, buf, off, plaintext.length); - return plaintext.length; - } - 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 - { - short contentType = ContentType.application_data; - - if (this.inHandshake || this.writeEpoch == this.retransmitEpoch) - { - contentType = ContentType.handshake; - - short handshakeType = TlsUtils.readUint8(buf, off); - if (handshakeType == HandshakeType.finished) - { - DTLSEpoch nextEpoch = null; - if (this.inHandshake) - { - nextEpoch = pendingEpoch; - } - else if (this.writeEpoch == this.retransmitEpoch) - { - nextEpoch = currentEpoch; - } - - if (nextEpoch == null) - { - // TODO - throw new IllegalStateException(); - } - - // 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 }; - sendRecord(ContentType.change_cipher_spec, data, 0, data.length); - - writeEpoch = nextEpoch; - } - } - - sendRecord(contentType, buf, off, len); - } - - public void close() - throws IOException - { - if (!closed) - { - if (inHandshake) - { - warn(AlertDescription.user_canceled, "User canceled handshake"); - } - closeTransport(); - } - } - - void fail(short alertDescription) - { - if (!closed) - { - try - { - raiseAlert(AlertLevel.fatal, alertDescription, null, null); - } - catch (Exception e) - { - // Ignore - } - - failed = true; - - closeTransport(); - } - } - - void warn(short alertDescription, String message) - throws IOException - { - raiseAlert(AlertLevel.warning, alertDescription, message, null); - } - - 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 - * connection. The other party MUST respond with a close_notify alert of its own and - * close down the connection immediately, discarding any pending writes. - */ - - try - { - if (!failed) - { - warn(AlertDescription.close_notify, null); - } - transport.close(); - } - catch (Exception e) - { - // Ignore - } - - closed = true; - } - } - - private void raiseAlert(short alertLevel, short alertDescription, String message, Exception cause) - throws IOException - { - peer.notifyAlertRaised(alertLevel, alertDescription, message, cause); - - byte[] error = new byte[2]; - 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) - { - int length = 0; - if (recordQueue.size() >= RECORD_HEADER_LENGTH) - { - byte[] lengthBytes = new byte[2]; - recordQueue.read(lengthBytes, 0, 2, 11); - length = TlsUtils.readUint16(lengthBytes, 0); - } - - int received = Math.min(recordQueue.size(), RECORD_HEADER_LENGTH + length); - recordQueue.removeData(buf, off, received, 0); - return received; - } - - int received = transport.receive(buf, off, len, waitMillis); - if (received >= RECORD_HEADER_LENGTH) - { - int fragmentLength = TlsUtils.readUint16(buf, off + 11); - int recordLength = RECORD_HEADER_LENGTH + fragmentLength; - if (received > recordLength) - { - recordQueue.addData(buf, off + recordLength, received - recordLength); - received = recordLength; - } - } - - return received; - } - - private void sendRecord(short contentType, byte[] buf, int off, int len) - throws IOException - { - if (len > this.plaintextLimit) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - /* - * 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) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - int recordEpoch = writeEpoch.getEpoch(); - long recordSequenceNumber = writeEpoch.allocateSequenceNumber(); - - byte[] ciphertext = writeEpoch.getCipher().encodePlaintext( - getMacSequenceNumber(recordEpoch, recordSequenceNumber), contentType, buf, off, len); - - // TODO Check the ciphertext length? - - byte[] record = new byte[ciphertext.length + RECORD_HEADER_LENGTH]; - TlsUtils.writeUint8(contentType, record, 0); - ProtocolVersion version = discoveredPeerVersion != null ? discoveredPeerVersion : context.getClientVersion(); - TlsUtils.writeVersion(version, record, 1); - TlsUtils.writeUint16(recordEpoch, record, 3); - TlsUtils.writeUint48(recordSequenceNumber, record, 5); - TlsUtils.writeUint16(ciphertext.length, record, 11); - System.arraycopy(ciphertext, 0, record, RECORD_HEADER_LENGTH, ciphertext.length); - - transport.send(record, 0, record.length); - } - - private static long getMacSequenceNumber(int epoch, long sequence_number) - { - return ((epoch & 0xFFFFFFFFL) << 48) | sequence_number; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java b/core/src/main/java/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java deleted file mode 100644 index 50a5eeac..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java +++ /dev/null @@ -1,453 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import org.bouncycastle.util.Integers; - -class DTLSReliableHandshake -{ - private final static int MAX_RECEIVE_AHEAD = 10; - - private final DTLSRecordLayer recordLayer; - - private TlsHandshakeHash handshakeHash; - - private Hashtable currentInboundFlight = new Hashtable(); - private Hashtable previousInboundFlight = null; - private Vector outboundFlight = new Vector(); - private boolean sending = true; - - private int message_seq = 0, next_receive_seq = 0; - - DTLSReliableHandshake(TlsContext context, DTLSRecordLayer transport) - { - this.recordLayer = transport; - this.handshakeHash = new DeferredHash(); - this.handshakeHash.init(context); - } - - void notifyHelloComplete() - { - this.handshakeHash = handshakeHash.notifyPRFDetermined(); - } - - TlsHandshakeHash getHandshakeHash() - { - return handshakeHash; - } - - TlsHandshakeHash prepareToFinish() - { - TlsHandshakeHash result = handshakeHash; - this.handshakeHash = handshakeHash.stopTracking(); - return result; - } - - void sendMessage(short msg_type, byte[] body) - throws IOException - { - TlsUtils.checkUint24(body.length); - - if (!sending) - { - checkInboundFlight(); - sending = true; - outboundFlight.removeAllElements(); - } - - Message message = new Message(message_seq++, msg_type, body); - - outboundFlight.addElement(message); - - writeMessage(message); - updateHandshakeMessagesDigest(message); - } - - byte[] receiveMessageBody(short msg_type) - throws IOException - { - Message message = receiveMessage(); - if (message.getType() != msg_type) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - return message.getBody(); - } - - Message receiveMessage() - throws IOException - { - if (sending) - { - sending = false; - prepareInboundFlight(); - } - - // Check if we already have the next message waiting - { - DTLSReassembler next = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(next_receive_seq)); - if (next != null) - { - byte[] body = next.getBodyIfComplete(); - if (body != null) - { - previousInboundFlight = null; - return updateHandshakeMessagesDigest(new Message(next_receive_seq++, next.getType(), body)); - } - } - } - - byte[] buf = null; - - // TODO Check the conditions under which we should reset this - int readTimeoutMillis = 1000; - - for (;;) - { - int receiveLimit = recordLayer.getReceiveLimit(); - if (buf == null || buf.length < receiveLimit) - { - buf = new byte[receiveLimit]; - } - - // TODO Handle records containing multiple handshake messages - - try - { - for (; ; ) - { - int received = recordLayer.receive(buf, 0, receiveLimit, readTimeoutMillis); - if (received < 0) - { - break; - } - if (received < 12) - { - continue; - } - int fragment_length = TlsUtils.readUint24(buf, 9); - if (received != (fragment_length + 12)) - { - continue; - } - int seq = TlsUtils.readUint16(buf, 4); - 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) - { - continue; - } - - 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(Integers - .valueOf(seq)); - if (reassembler != null) - { - reassembler.contributeFragment(msg_type, length, buf, 12, fragment_offset, - fragment_length); - - if (checkAll(previousInboundFlight)) - { - resendOutboundFlight(); - - /* - * TODO[DTLS] implementations SHOULD back off handshake packet - * size during the retransmit backoff. - */ - readTimeoutMillis = Math.min(readTimeoutMillis * 2, 60000); - - resetAll(previousInboundFlight); - } - } - } - } - else - { - DTLSReassembler reassembler = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(seq)); - if (reassembler == null) - { - reassembler = new DTLSReassembler(msg_type, length); - currentInboundFlight.put(Integers.valueOf(seq), reassembler); - } - - reassembler.contributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); - - if (seq == next_receive_seq) - { - byte[] body = reassembler.getBodyIfComplete(); - if (body != null) - { - previousInboundFlight = null; - return updateHandshakeMessagesDigest(new Message(next_receive_seq++, - reassembler.getType(), body)); - } - } - } - } - } - catch (IOException e) - { - // NOTE: Assume this is a timeout for the moment - } - - resendOutboundFlight(); - - /* - * TODO[DTLS] implementations SHOULD back off handshake packet size during the - * retransmit backoff. - */ - readTimeoutMillis = Math.min(readTimeoutMillis * 2, 60000); - } - } - - void finish() - { - DTLSHandshakeRetransmit retransmit = null; - if (!sending) - { - checkInboundFlight(); - } - 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 - { - /* - * TODO Need to handle the case where the previous inbound flight contains - * messages from two epochs. - */ - if (len < 12) - { - return; - } - int fragment_length = TlsUtils.readUint24(buf, off + 9); - if (len != (fragment_length + 12)) - { - return; - } - int seq = TlsUtils.readUint16(buf, off + 4); - if (seq >= next_receive_seq) - { - return; - } - - short msg_type = TlsUtils.readUint8(buf, off); - - // 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) - { - return; - } - - DTLSReassembler reassembler = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(seq)); - if (reassembler != null) - { - reassembler.contributeFragment(msg_type, length, buf, off + 12, fragment_offset, - fragment_length); - if (checkAll(currentInboundFlight)) - { - resendOutboundFlight(); - resetAll(currentInboundFlight); - } - } - } - }; - } - - recordLayer.handshakeSuccessful(retransmit); - } - - void resetHandshakeMessagesDigest() - { - handshakeHash.reset(); - } - - /** - * Check that there are no "extra" messages left in the current inbound flight - */ - private void checkInboundFlight() - { - Enumeration e = currentInboundFlight.keys(); - while (e.hasMoreElements()) - { - Integer key = (Integer)e.nextElement(); - if (key.intValue() >= next_receive_seq) - { - // TODO Should this be considered an error? - } - } - } - - private void prepareInboundFlight() - { - resetAll(currentInboundFlight); - previousInboundFlight = currentInboundFlight; - currentInboundFlight = new Hashtable(); - } - - private void resendOutboundFlight() - throws IOException - { - recordLayer.resetWriteEpoch(); - 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) - { - byte[] body = message.getBody(); - byte[] buf = new byte[12]; - TlsUtils.writeUint8(message.getType(), buf, 0); - TlsUtils.writeUint24(body.length, buf, 1); - TlsUtils.writeUint16(message.getSeq(), buf, 4); - TlsUtils.writeUint24(0, buf, 6); - TlsUtils.writeUint24(body.length, buf, 9); - handshakeHash.update(buf, 0, buf.length); - handshakeHash.update(body, 0, body.length); - } - return message; - } - - 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) - { - // TODO Should we be throwing an exception here? - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - int length = message.getBody().length; - - // NOTE: Must still send a fragment if body is empty - int fragment_offset = 0; - do - { - int fragment_length = Math.min(length - fragment_offset, fragmentLimit); - writeHandshakeFragment(message, fragment_offset, fragment_length); - fragment_offset += fragment_length; - } - while (fragment_offset < length); - } - - private void writeHandshakeFragment(Message message, int fragment_offset, int fragment_length) - throws IOException - { - RecordLayerBuffer fragment = new RecordLayerBuffer(12 + fragment_length); - TlsUtils.writeUint8(message.getType(), fragment); - TlsUtils.writeUint24(message.getBody().length, fragment); - TlsUtils.writeUint16(message.getSeq(), fragment); - TlsUtils.writeUint24(fragment_offset, fragment); - TlsUtils.writeUint24(fragment_length, fragment); - fragment.write(message.getBody(), fragment_offset, fragment_length); - - fragment.sendToRecordLayer(recordLayer); - } - - private static boolean checkAll(Hashtable inboundFlight) - { - Enumeration e = inboundFlight.elements(); - while (e.hasMoreElements()) - { - if (((DTLSReassembler)e.nextElement()).getBodyIfComplete() == null) - { - return false; - } - } - return true; - } - - private static void resetAll(Hashtable inboundFlight) - { - Enumeration e = inboundFlight.elements(); - while (e.hasMoreElements()) - { - ((DTLSReassembler)e.nextElement()).reset(); - } - } - - 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) - { - this.message_seq = message_seq; - this.msg_type = msg_type; - this.body = body; - } - - public int getSeq() - { - return message_seq; - } - - public short getType() - { - return msg_type; - } - - public byte[] getBody() - { - return body; - } - } - - static class RecordLayerBuffer extends ByteArrayOutputStream - { - RecordLayerBuffer(int size) - { - super(size); - } - - void sendToRecordLayer(DTLSRecordLayer recordLayer) throws IOException - { - recordLayer.send(buf, 0, count); - buf = null; - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSReplayWindow.java b/core/src/main/java/org/bouncycastle/crypto/tls/DTLSReplayWindow.java deleted file mode 100644 index 00bbf147..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSReplayWindow.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 4347 4.1.2.5 Anti-replay - * <p/> - * Support fast rejection of duplicate records by maintaining a sliding receive window - */ -class DTLSReplayWindow -{ - private static final long VALID_SEQ_MASK = 0x0000FFFFFFFFFFFFL; - - private static final long WINDOW_SIZE = 64L; - - private long latestConfirmedSeq = -1; - private long bitmap = 0; - - /** - * 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. - * @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; - } - - /** - * 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) - { - bitmap |= (1L << diff); - } - } - else - { - long diff = seq - latestConfirmedSeq; - if (diff >= WINDOW_SIZE) - { - bitmap = 1; - } - else - { - bitmap <<= (int)diff; // for earlier JDKs - bitmap |= 1; - } - latestConfirmedSeq = seq; - } - } - - /** - * When a new epoch begins, sequence numbers begin again at 0 - */ - void reset() - { - latestConfirmedSeq = -1; - bitmap = 0; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSServerProtocol.java b/core/src/main/java/org/bouncycastle/crypto/tls/DTLSServerProtocol.java deleted file mode 100644 index 5f86eff5..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSServerProtocol.java +++ /dev/null @@ -1,667 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.security.SecureRandom; -import java.util.Hashtable; -import java.util.Vector; - -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.util.PublicKeyFactory; -import org.bouncycastle.util.Arrays; - -public class DTLSServerProtocol - extends DTLSProtocol -{ - protected boolean verifyRequests = true; - - public DTLSServerProtocol(SecureRandom secureRandom) - { - super(secureRandom); - } - - public boolean getVerifyRequests() - { - return verifyRequests; - } - - public void setVerifyRequests(boolean verifyRequests) - { - this.verifyRequests = verifyRequests; - } - - 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; - - ServerHandshakeState state = new ServerHandshakeState(); - state.server = server; - state.serverContext = new TlsServerContextImpl(secureRandom, securityParameters); - - securityParameters.serverRandom = TlsProtocol.createRandomBlock(server.shouldUseGMTUnixTime(), - state.serverContext.getNonceRandomGenerator()); - - server.init(state.serverContext); - - DTLSRecordLayer recordLayer = new DTLSRecordLayer(transport, state.serverContext, server, ContentType.handshake); - - // TODO Need to handle sending of HelloVerifyRequest without entering a full connection - - try - { - return serverHandshake(state, recordLayer); - } - catch (TlsFatalAlert fatalAlert) - { - recordLayer.fail(fatalAlert.getAlertDescription()); - throw fatalAlert; - } - catch (IOException e) - { - recordLayer.fail(AlertDescription.internal_error); - throw e; - } - catch (RuntimeException e) - { - recordLayer.fail(AlertDescription.internal_error); - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLayer recordLayer) - throws IOException - { - SecurityParameters securityParameters = state.serverContext.getSecurityParameters(); - DTLSReliableHandshake handshake = new DTLSReliableHandshake(state.serverContext, recordLayer); - - DTLSReliableHandshake.Message clientMessage = handshake.receiveMessage(); - - { - // NOTE: After receiving a record from the client, we discover the record layer version - ProtocolVersion client_version = recordLayer.getDiscoveredPeerVersion(); - // TODO Read RFCs for guidance on the expected record layer version number - state.serverContext.setClientVersion(client_version); - } - - if (clientMessage.getType() == HandshakeType.client_hello) - { - processClientHello(state, clientMessage.getBody()); - } - else - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - { - byte[] serverHelloBody = generateServerHello(state); - - if (state.maxFragmentLength >= 0) - { - int plainTextLimit = 1 << (8 + state.maxFragmentLength); - recordLayer.setPlaintextLimit(plainTextLimit); - } - - securityParameters.cipherSuite = state.selectedCipherSuite; - securityParameters.compressionAlgorithm = state.selectedCompressionMethod; - securityParameters.prfAlgorithm = TlsProtocol.getPRFAlgorithm(state.serverContext, - state.selectedCipherSuite); - - /* - * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify verify_data_length - * has a verify_data_length equal to 12. This includes all existing cipher suites. - */ - securityParameters.verifyDataLength = 12; - - handshake.sendMessage(HandshakeType.server_hello, serverHelloBody); - } - - handshake.notifyHelloComplete(); - - Vector serverSupplementalData = state.server.getServerSupplementalData(); - if (serverSupplementalData != null) - { - byte[] supplementalDataBody = generateSupplementalData(serverSupplementalData); - handshake.sendMessage(HandshakeType.supplemental_data, supplementalDataBody); - } - - state.keyExchange = state.server.getKeyExchange(); - state.keyExchange.init(state.serverContext); - - state.serverCredentials = state.server.getCredentials(); - - Certificate serverCertificate = null; - - if (state.serverCredentials == null) - { - state.keyExchange.skipServerCredentials(); - } - else - { - state.keyExchange.processServerCredentials(state.serverCredentials); - - serverCertificate = state.serverCredentials.getCertificate(); - byte[] certificateBody = generateCertificate(serverCertificate); - handshake.sendMessage(HandshakeType.certificate, certificateBody); - } - - // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus - if (serverCertificate == null || serverCertificate.isEmpty()) - { - state.allowCertificateStatus = false; - } - - if (state.allowCertificateStatus) - { - CertificateStatus certificateStatus = state.server.getCertificateStatus(); - if (certificateStatus != null) - { - byte[] certificateStatusBody = generateCertificateStatus(state, certificateStatus); - handshake.sendMessage(HandshakeType.certificate_status, certificateStatusBody); - } - } - - byte[] serverKeyExchange = state.keyExchange.generateServerKeyExchange(); - if (serverKeyExchange != null) - { - handshake.sendMessage(HandshakeType.server_key_exchange, serverKeyExchange); - } - - if (state.serverCredentials != null) - { - state.certificateRequest = state.server.getCertificateRequest(); - if (state.certificateRequest != null) - { - state.keyExchange.validateCertificateRequest(state.certificateRequest); - - byte[] certificateRequestBody = generateCertificateRequest(state, state.certificateRequest); - handshake.sendMessage(HandshakeType.certificate_request, certificateRequestBody); - - TlsUtils.trackHashAlgorithms(handshake.getHandshakeHash(), - state.certificateRequest.getSupportedSignatureAlgorithms()); - } - } - - handshake.sendMessage(HandshakeType.server_hello_done, TlsUtils.EMPTY_BYTES); - - handshake.getHandshakeHash().sealHashAlgorithms(); - - clientMessage = handshake.receiveMessage(); - - if (clientMessage.getType() == HandshakeType.supplemental_data) - { - processClientSupplementalData(state, clientMessage.getBody()); - clientMessage = handshake.receiveMessage(); - } - else - { - state.server.processClientSupplementalData(null); - } - - if (state.certificateRequest == null) - { - state.keyExchange.skipClientCredentials(); - } - else - { - if (clientMessage.getType() == HandshakeType.certificate) - { - processClientCertificate(state, clientMessage.getBody()); - clientMessage = handshake.receiveMessage(); - } - else - { - if (TlsUtils.isTLSv12(state.serverContext)) - { - /* - * RFC 5246 If no suitable certificate is available, the client MUST send a - * certificate message containing no certificates. - * - * NOTE: In previous RFCs, this was SHOULD instead of MUST. - */ - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - notifyClientCertificate(state, Certificate.EMPTY_CHAIN); - } - } - - if (clientMessage.getType() == HandshakeType.client_key_exchange) - { - processClientKeyExchange(state, clientMessage.getBody()); - } - else - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - TlsProtocol.establishMasterSecret(state.serverContext, state.keyExchange); - recordLayer.initPendingEpoch(state.server.getCipher()); - - TlsHandshakeHash prepareFinishHash = handshake.prepareToFinish(); - - /* - * 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 (expectCertificateVerifyMessage(state)) - { - byte[] certificateVerifyBody = handshake.receiveMessageBody(HandshakeType.certificate_verify); - processCertificateVerify(state, certificateVerifyBody, prepareFinishHash); - } - - // NOTE: Calculated exclusive of the actual Finished message from the client - byte[] expectedClientVerifyData = TlsUtils.calculateVerifyData(state.serverContext, ExporterLabel.client_finished, - TlsProtocol.getCurrentPRFHash(state.serverContext, handshake.getHandshakeHash(), null)); - processFinished(handshake.receiveMessageBody(HandshakeType.finished), expectedClientVerifyData); - - if (state.expectSessionTicket) - { - NewSessionTicket newSessionTicket = state.server.getNewSessionTicket(); - byte[] newSessionTicketBody = generateNewSessionTicket(state, newSessionTicket); - handshake.sendMessage(HandshakeType.session_ticket, newSessionTicketBody); - } - - // NOTE: Calculated exclusive of the Finished message itself - byte[] serverVerifyData = TlsUtils.calculateVerifyData(state.serverContext, ExporterLabel.server_finished, - TlsProtocol.getCurrentPRFHash(state.serverContext, handshake.getHandshakeHash(), null)); - handshake.sendMessage(HandshakeType.finished, serverVerifyData); - - handshake.finish(); - - state.server.notifyHandshakeComplete(); - - return new DTLSTransport(recordLayer); - } - - protected byte[] generateCertificateRequest(ServerHandshakeState state, CertificateRequest certificateRequest) - throws IOException - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - certificateRequest.encode(buf); - return buf.toByteArray(); - } - - protected byte[] generateCertificateStatus(ServerHandshakeState state, CertificateStatus certificateStatus) - throws IOException - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - certificateStatus.encode(buf); - return buf.toByteArray(); - } - - protected byte[] generateNewSessionTicket(ServerHandshakeState state, NewSessionTicket newSessionTicket) - throws IOException - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - newSessionTicket.encode(buf); - return buf.toByteArray(); - } - - protected byte[] generateServerHello(ServerHandshakeState state) - throws IOException - { - SecurityParameters securityParameters = state.serverContext.getSecurityParameters(); - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - ProtocolVersion server_version = state.server.getServerVersion(); - if (!server_version.isEqualOrEarlierVersionOf(state.serverContext.getClientVersion())) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - // TODO Read RFCs for guidance on the expected record layer version number - // recordStream.setReadVersion(server_version); - // recordStream.setWriteVersion(server_version); - // recordStream.setRestrictReadVersion(true); - state.serverContext.setServerVersion(server_version); - - TlsUtils.writeVersion(state.serverContext.getServerVersion(), buf); - - buf.write(securityParameters.getServerRandom()); - - /* - * The server may return an empty session_id to indicate that the session will not be cached - * and therefore cannot be resumed. - */ - TlsUtils.writeOpaque8(TlsUtils.EMPTY_BYTES, buf); - - state.selectedCipherSuite = state.server.getSelectedCipherSuite(); - if (!Arrays.contains(state.offeredCipherSuites, state.selectedCipherSuite) - || state.selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL - || state.selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV - || !TlsUtils.isValidCipherSuiteForVersion(state.selectedCipherSuite, server_version)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - validateSelectedCipherSuite(state.selectedCipherSuite, AlertDescription.internal_error); - - state.selectedCompressionMethod = state.server.getSelectedCompressionMethod(); - if (!Arrays.contains(state.offeredCompressionMethods, state.selectedCompressionMethod)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - TlsUtils.writeUint16(state.selectedCipherSuite, buf); - TlsUtils.writeUint8(state.selectedCompressionMethod, buf); - - state.serverExtensions = state.server.getServerExtensions(); - - /* - * RFC 5746 3.6. Server Behavior: Initial Handshake - */ - if (state.secure_renegotiation) - { - byte[] renegExtData = TlsUtils.getExtensionData(state.serverExtensions, TlsProtocol.EXT_RenegotiationInfo); - boolean noRenegExt = (null == renegExtData); - - 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, - * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed - * because the client is signaling its willingness to receive the extension via the - * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. - */ - - /* - * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty - * "renegotiation_info" extension in the ServerHello message. - */ - state.serverExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(state.serverExtensions); - state.serverExtensions.put(TlsProtocol.EXT_RenegotiationInfo, - TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES)); - } - } - - if (state.serverExtensions != null) - { - securityParameters.encryptThenMAC = TlsExtensionsUtils.hasEncryptThenMACExtension(state.serverExtensions); - - state.maxFragmentLength = evaluateMaxFragmentLengthExtension(state.clientExtensions, state.serverExtensions, - AlertDescription.internal_error); - - securityParameters.truncatedHMac = TlsExtensionsUtils.hasTruncatedHMacExtension(state.serverExtensions); - - state.allowCertificateStatus = TlsUtils.hasExpectedEmptyExtensionData(state.serverExtensions, - TlsExtensionsUtils.EXT_status_request, AlertDescription.internal_error); - - state.expectSessionTicket = TlsUtils.hasExpectedEmptyExtensionData(state.serverExtensions, - TlsProtocol.EXT_SessionTicket, AlertDescription.internal_error); - - TlsProtocol.writeExtensions(buf, state.serverExtensions); - } - - return buf.toByteArray(); - } - - protected void notifyClientCertificate(ServerHandshakeState state, Certificate clientCertificate) - throws IOException - { - if (state.certificateRequest == null) - { - throw new IllegalStateException(); - } - - if (state.clientCertificate != null) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - state.clientCertificate = clientCertificate; - - if (clientCertificate.isEmpty()) - { - state.keyExchange.skipClientCredentials(); - } - else - { - - /* - * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request - * message was non-empty, one of the certificates in the certificate chain SHOULD be - * issued by one of the listed CAs. - */ - - state.clientCertificateType = TlsUtils.getClientCertificateType(clientCertificate, - state.serverCredentials.getCertificate()); - - state.keyExchange.processClientCertificate(clientCertificate); - } - - /* - * RFC 5246 7.4.6. If the client does not send any certificates, the server MAY at its - * discretion either continue the handshake without client authentication, or respond with a - * fatal handshake_failure alert. Also, if some aspect of the certificate chain was - * unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its - * discretion either continue the handshake (considering the client unauthenticated) or send - * a fatal alert. - */ - state.server.notifyClientCertificate(clientCertificate); - } - - protected void processClientCertificate(ServerHandshakeState state, byte[] body) - throws IOException - { - ByteArrayInputStream buf = new ByteArrayInputStream(body); - - Certificate clientCertificate = Certificate.parse(buf); - - TlsProtocol.assertEmpty(buf); - - notifyClientCertificate(state, clientCertificate); - } - - protected void processCertificateVerify(ServerHandshakeState state, byte[] body, TlsHandshakeHash prepareFinishHash) - throws IOException - { - ByteArrayInputStream buf = new ByteArrayInputStream(body); - - DigitallySigned clientCertificateVerify = DigitallySigned.parse(state.serverContext, buf); - - TlsProtocol.assertEmpty(buf); - - // Verify the CertificateVerify message contains a correct signature. - boolean verified = false; - try - { - byte[] certificateVerifyHash; - if (TlsUtils.isTLSv12(state.serverContext)) - { - certificateVerifyHash = prepareFinishHash.getFinalHash(clientCertificateVerify.getAlgorithm().getHash()); - } - else - { - certificateVerifyHash = TlsProtocol.getCurrentPRFHash(state.serverContext, prepareFinishHash, null); - } - - org.bouncycastle.asn1.x509.Certificate x509Cert = state.clientCertificate.getCertificateAt(0); - SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(keyInfo); - - TlsSigner tlsSigner = TlsUtils.createTlsSigner(state.clientCertificateType); - tlsSigner.init(state.serverContext); - verified = tlsSigner.verifyRawSignature(clientCertificateVerify.getAlgorithm(), - clientCertificateVerify.getSignature(), publicKey, certificateVerifyHash); - } - catch (Exception e) - { - } - - if (!verified) - { - throw new TlsFatalAlert(AlertDescription.decrypt_error); - } - } - - 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()) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - /* - * Read the client random - */ - byte[] client_random = TlsUtils.readFully(32, buf); - - byte[] sessionID = TlsUtils.readOpaque8(buf); - if (sessionID.length > 32) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - // TODO RFC 4347 has the cookie length restricted to 32, but not in RFC 6347 - byte[] cookie = TlsUtils.readOpaque8(buf); - - int cipher_suites_length = TlsUtils.readUint16(buf); - if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - /* - * NOTE: "If the session_id field is not empty (implying a session resumption request) this - * vector must include at least the cipher_suite from that session." - */ - state.offeredCipherSuites = TlsUtils.readUint16Array(cipher_suites_length / 2, buf); - - int compression_methods_length = TlsUtils.readUint8(buf); - if (compression_methods_length < 1) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - state.offeredCompressionMethods = TlsUtils.readUint8Array(compression_methods_length, buf); - - /* - * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore - * extensions appearing in the client hello, and send a server hello containing no - * extensions. - */ - state.clientExtensions = TlsProtocol.readExtensions(buf); - - state.serverContext.setClientVersion(client_version); - - state.server.notifyClientVersion(client_version); - - state.serverContext.getSecurityParameters().clientRandom = client_random; - - state.server.notifyOfferedCipherSuites(state.offeredCipherSuites); - state.server.notifyOfferedCompressionMethods(state.offeredCompressionMethods); - - /* - * RFC 5746 3.6. Server Behavior: Initial Handshake - */ - { - /* - * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, - * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the - * ClientHello. Including both is NOT RECOMMENDED. - */ - - /* - * When a ClientHello is received, the server MUST check if it includes the - * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag - * to TRUE. - */ - if (Arrays.contains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) - { - state.secure_renegotiation = true; - } - - /* - * The server MUST check if the "renegotiation_info" extension is included in the - * ClientHello. - */ - byte[] renegExtData = TlsUtils.getExtensionData(state.clientExtensions, TlsProtocol.EXT_RenegotiationInfo); - if (renegExtData != null) - { - /* - * If the extension is present, set secure_renegotiation flag to TRUE. The - * server MUST then verify that the length of the "renegotiated_connection" - * field is zero, and if it is not, MUST abort the handshake. - */ - state.secure_renegotiation = true; - - if (!Arrays.constantTimeAreEqual(renegExtData, TlsProtocol.createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - } - } - - state.server.notifySecureRenegotiation(state.secure_renegotiation); - - if (state.clientExtensions != null) - { - state.server.processClientExtensions(state.clientExtensions); - } - } - - protected void processClientKeyExchange(ServerHandshakeState state, byte[] body) - throws IOException - { - ByteArrayInputStream buf = new ByteArrayInputStream(body); - - state.keyExchange.processClientKeyExchange(buf); - - TlsProtocol.assertEmpty(buf); - } - - 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) - { - return state.clientCertificateType >= 0 && TlsUtils.hasSigningCapability(state.clientCertificateType); - } - - protected static class ServerHandshakeState - { - TlsServer server = null; - TlsServerContextImpl serverContext = null; - int[] offeredCipherSuites; - short[] offeredCompressionMethods; - Hashtable clientExtensions; - int selectedCipherSuite = -1; - short selectedCompressionMethod = -1; - boolean secure_renegotiation = false; - short maxFragmentLength = -1; - boolean allowCertificateStatus = false; - boolean expectSessionTicket = false; - Hashtable serverExtensions = null; - TlsKeyExchange keyExchange = null; - TlsCredentials serverCredentials = null; - CertificateRequest certificateRequest = null; - short clientCertificateType = -1; - Certificate clientCertificate = null; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSTransport.java b/core/src/main/java/org/bouncycastle/crypto/tls/DTLSTransport.java deleted file mode 100644 index 45c2d30d..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DTLSTransport.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public class DTLSTransport - implements DatagramTransport -{ - private final DTLSRecordLayer recordLayer; - - DTLSTransport(DTLSRecordLayer recordLayer) - { - this.recordLayer = recordLayer; - } - - public int getReceiveLimit() - throws IOException - { - return recordLayer.getReceiveLimit(); - } - - public int getSendLimit() - throws IOException - { - return recordLayer.getSendLimit(); - } - - public int receive(byte[] buf, int off, int len, int waitMillis) - throws IOException - { - try - { - return recordLayer.receive(buf, off, len, waitMillis); - } - catch (TlsFatalAlert fatalAlert) - { - recordLayer.fail(fatalAlert.getAlertDescription()); - throw fatalAlert; - } - catch (IOException e) - { - recordLayer.fail(AlertDescription.internal_error); - throw 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 - { - recordLayer.send(buf, off, len); - } - catch (TlsFatalAlert fatalAlert) - { - recordLayer.fail(fatalAlert.getAlertDescription()); - throw fatalAlert; - } - catch (IOException e) - { - recordLayer.fail(AlertDescription.internal_error); - throw e; - } - catch (RuntimeException e) - { - recordLayer.fail(AlertDescription.internal_error); - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public void close() - throws IOException - { - recordLayer.close(); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DatagramTransport.java b/core/src/main/java/org/bouncycastle/crypto/tls/DatagramTransport.java deleted file mode 100644 index 14972146..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DatagramTransport.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public interface DatagramTransport -{ - int getReceiveLimit() - throws IOException; - - int getSendLimit() - 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 close() - throws IOException; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsAgreementCredentials.java b/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsAgreementCredentials.java deleted file mode 100644 index 78afb418..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsAgreementCredentials.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.math.BigInteger; - -import org.bouncycastle.crypto.BasicAgreement; -import org.bouncycastle.crypto.agreement.DHBasicAgreement; -import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.DHPrivateKeyParameters; -import org.bouncycastle.crypto.params.ECPrivateKeyParameters; -import org.bouncycastle.util.BigIntegers; - -public class DefaultTlsAgreementCredentials - extends AbstractTlsAgreementCredentials -{ - protected Certificate certificate; - protected AsymmetricKeyParameter privateKey; - - protected BasicAgreement basicAgreement; - protected boolean truncateAgreement; - - public DefaultTlsAgreementCredentials(Certificate certificate, AsymmetricKeyParameter privateKey) - { - if (certificate == null) - { - throw new IllegalArgumentException("'certificate' cannot be null"); - } - if (certificate.isEmpty()) - { - throw new IllegalArgumentException("'certificate' cannot be empty"); - } - if (privateKey == null) - { - throw new IllegalArgumentException("'privateKey' cannot be null"); - } - if (!privateKey.isPrivate()) - { - throw new IllegalArgumentException("'privateKey' must be private"); - } - - if (privateKey instanceof DHPrivateKeyParameters) - { - basicAgreement = new DHBasicAgreement(); - truncateAgreement = true; - } - else if (privateKey instanceof ECPrivateKeyParameters) - { - basicAgreement = new ECDHBasicAgreement(); - truncateAgreement = false; - } - else - { - throw new IllegalArgumentException("'privateKey' type not supported: " - + privateKey.getClass().getName()); - } - - this.certificate = certificate; - this.privateKey = privateKey; - } - - public Certificate getCertificate() - { - return certificate; - } - - public byte[] generateAgreement(AsymmetricKeyParameter peerPublicKey) - { - basicAgreement.init(privateKey); - BigInteger agreementValue = basicAgreement.calculateAgreement(peerPublicKey); - - if (truncateAgreement) - { - return BigIntegers.asUnsignedByteArray(agreementValue); - } - - return BigIntegers.asUnsignedByteArray(basicAgreement.getFieldSize(), agreementValue); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsCipherFactory.java b/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsCipherFactory.java deleted file mode 100644 index 92caeb50..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsCipherFactory.java +++ /dev/null @@ -1,237 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.StreamCipher; -import org.bouncycastle.crypto.digests.MD5Digest; -import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.crypto.digests.SHA256Digest; -import org.bouncycastle.crypto.digests.SHA384Digest; -import org.bouncycastle.crypto.digests.SHA512Digest; -import org.bouncycastle.crypto.engines.AESEngine; -import org.bouncycastle.crypto.engines.CamelliaEngine; -import org.bouncycastle.crypto.engines.DESedeEngine; -import org.bouncycastle.crypto.engines.RC4Engine; -import org.bouncycastle.crypto.engines.SEEDEngine; -import org.bouncycastle.crypto.engines.Salsa20Engine; -import org.bouncycastle.crypto.modes.AEADBlockCipher; -import org.bouncycastle.crypto.modes.CBCBlockCipher; -import org.bouncycastle.crypto.modes.CCMBlockCipher; -import org.bouncycastle.crypto.modes.GCMBlockCipher; - -public class DefaultTlsCipherFactory - extends AbstractTlsCipherFactory -{ - public TlsCipher createCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) - throws IOException - { - switch (encryptionAlgorithm) - { - case EncryptionAlgorithm._3DES_EDE_CBC: - return createDESedeCipher(context, macAlgorithm); - case EncryptionAlgorithm.AEAD_CHACHA20_POLY1305: - // NOTE: Ignores macAlgorithm - return createChaCha20Poly1305(context); - case EncryptionAlgorithm.AES_128_CBC: - return createAESCipher(context, 16, macAlgorithm); - case EncryptionAlgorithm.AES_128_CCM: - // NOTE: Ignores macAlgorithm - return createCipher_AES_CCM(context, 16, 16); - case EncryptionAlgorithm.AES_128_CCM_8: - // NOTE: Ignores macAlgorithm - return createCipher_AES_CCM(context, 16, 8); - case EncryptionAlgorithm.AES_256_CCM: - // NOTE: Ignores macAlgorithm - return createCipher_AES_CCM(context, 32, 16); - case EncryptionAlgorithm.AES_256_CCM_8: - // NOTE: Ignores macAlgorithm - return createCipher_AES_CCM(context, 32, 8); - case EncryptionAlgorithm.AES_128_GCM: - // NOTE: Ignores macAlgorithm - return createCipher_AES_GCM(context, 16, 16); - case EncryptionAlgorithm.AES_256_CBC: - return createAESCipher(context, 32, macAlgorithm); - case EncryptionAlgorithm.AES_256_GCM: - // NOTE: Ignores macAlgorithm - return createCipher_AES_GCM(context, 32, 16); - case EncryptionAlgorithm.CAMELLIA_128_CBC: - return createCamelliaCipher(context, 16, macAlgorithm); - case EncryptionAlgorithm.CAMELLIA_128_GCM: - // NOTE: Ignores macAlgorithm - return createCipher_Camellia_GCM(context, 16, 16); - case EncryptionAlgorithm.CAMELLIA_256_CBC: - return createCamelliaCipher(context, 32, macAlgorithm); - case EncryptionAlgorithm.CAMELLIA_256_GCM: - // NOTE: Ignores macAlgorithm - return createCipher_Camellia_GCM(context, 32, 16); - case EncryptionAlgorithm.ESTREAM_SALSA20: - return createSalsa20Cipher(context, 12, 32, macAlgorithm); - case EncryptionAlgorithm.NULL: - return createNullCipher(context, macAlgorithm); - case EncryptionAlgorithm.RC4_128: - return createRC4Cipher(context, 16, macAlgorithm); - case EncryptionAlgorithm.SALSA20: - return createSalsa20Cipher(context, 20, 32, macAlgorithm); - case EncryptionAlgorithm.SEED_CBC: - return createSEEDCipher(context, macAlgorithm); - default: - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - protected TlsBlockCipher createAESCipher(TlsContext context, int cipherKeySize, int macAlgorithm) - throws IOException - { - return new TlsBlockCipher(context, createAESBlockCipher(), createAESBlockCipher(), - createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), cipherKeySize); - } - - protected TlsBlockCipher createCamelliaCipher(TlsContext context, int cipherKeySize, int macAlgorithm) - throws IOException - { - return new TlsBlockCipher(context, createCamelliaBlockCipher(), - createCamelliaBlockCipher(), createHMACDigest(macAlgorithm), - createHMACDigest(macAlgorithm), cipherKeySize); - } - - protected TlsCipher createChaCha20Poly1305(TlsContext context) throws IOException - { - return new Chacha20Poly1305(context); - } - - protected TlsAEADCipher createCipher_AES_CCM(TlsContext context, int cipherKeySize, int macSize) - throws IOException - { - return new TlsAEADCipher(context, createAEADBlockCipher_AES_CCM(), - createAEADBlockCipher_AES_CCM(), cipherKeySize, macSize); - } - - protected TlsAEADCipher createCipher_AES_GCM(TlsContext context, int cipherKeySize, int macSize) - throws IOException - { - return new TlsAEADCipher(context, createAEADBlockCipher_AES_GCM(), - createAEADBlockCipher_AES_GCM(), cipherKeySize, macSize); - } - - protected TlsAEADCipher createCipher_Camellia_GCM(TlsContext context, int cipherKeySize, int macSize) - throws IOException - { - return new TlsAEADCipher(context, createAEADBlockCipher_Camellia_GCM(), - createAEADBlockCipher_Camellia_GCM(), cipherKeySize, macSize); - } - - protected TlsBlockCipher createDESedeCipher(TlsContext context, int macAlgorithm) - throws IOException - { - return new TlsBlockCipher(context, createDESedeBlockCipher(), createDESedeBlockCipher(), - createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), 24); - } - - protected TlsNullCipher createNullCipher(TlsContext context, int macAlgorithm) - throws IOException - { - return new TlsNullCipher(context, createHMACDigest(macAlgorithm), - createHMACDigest(macAlgorithm)); - } - - protected TlsStreamCipher createRC4Cipher(TlsContext context, int cipherKeySize, int macAlgorithm) - throws IOException - { - return new TlsStreamCipher(context, createRC4StreamCipher(), createRC4StreamCipher(), - createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), cipherKeySize, false); - } - - protected TlsStreamCipher createSalsa20Cipher(TlsContext context, int rounds, int cipherKeySize, int macAlgorithm) - throws IOException - { - return new TlsStreamCipher(context, createSalsa20StreamCipher(rounds), createSalsa20StreamCipher(rounds), - createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), cipherKeySize, true); - } - - protected TlsBlockCipher createSEEDCipher(TlsContext context, int macAlgorithm) - throws IOException - { - return new TlsBlockCipher(context, createSEEDBlockCipher(), createSEEDBlockCipher(), - createHMACDigest(macAlgorithm), createHMACDigest(macAlgorithm), 16); - } - - protected BlockCipher createAESEngine() - { - return new AESEngine(); - } - - protected BlockCipher createCamelliaEngine() - { - return new CamelliaEngine(); - } - - protected BlockCipher createAESBlockCipher() - { - return new CBCBlockCipher(createAESEngine()); - } - - protected AEADBlockCipher createAEADBlockCipher_AES_CCM() - { - return new CCMBlockCipher(createAESEngine()); - } - - protected AEADBlockCipher createAEADBlockCipher_AES_GCM() - { - // TODO Consider allowing custom configuration of multiplier - return new GCMBlockCipher(createAESEngine()); - } - - protected AEADBlockCipher createAEADBlockCipher_Camellia_GCM() - { - // TODO Consider allowing custom configuration of multiplier - return new GCMBlockCipher(createCamelliaEngine()); - } - - protected BlockCipher createCamelliaBlockCipher() - { - return new CBCBlockCipher(createCamelliaEngine()); - } - - protected BlockCipher createDESedeBlockCipher() - { - return new CBCBlockCipher(new DESedeEngine()); - } - - protected StreamCipher createRC4StreamCipher() - { - return new RC4Engine(); - } - - protected StreamCipher createSalsa20StreamCipher(int rounds) - { - return new Salsa20Engine(rounds); - } - - protected BlockCipher createSEEDBlockCipher() - { - return new CBCBlockCipher(new SEEDEngine()); - } - - protected Digest createHMACDigest(int macAlgorithm) throws IOException - { - switch (macAlgorithm) - { - case MACAlgorithm._null: - return null; - case MACAlgorithm.hmac_md5: - return TlsUtils.createHash(HashAlgorithm.md5); - case MACAlgorithm.hmac_sha1: - return TlsUtils.createHash(HashAlgorithm.sha1); - case MACAlgorithm.hmac_sha256: - return TlsUtils.createHash(HashAlgorithm.sha256); - case MACAlgorithm.hmac_sha384: - return TlsUtils.createHash(HashAlgorithm.sha384); - case MACAlgorithm.hmac_sha512: - return TlsUtils.createHash(HashAlgorithm.sha512); - default: - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsClient.java b/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsClient.java deleted file mode 100644 index 8f5b900e..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsClient.java +++ /dev/null @@ -1,453 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public abstract class DefaultTlsClient - extends AbstractTlsClient -{ - public DefaultTlsClient() - { - super(); - } - - public DefaultTlsClient(TlsCipherFactory cipherFactory) - { - super(cipherFactory); - } - - public int[] getCipherSuites() - { - return new int[] - { - CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, - CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, - CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, - }; - } - - public TlsKeyExchange getKeyExchange() - throws IOException - { - 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: - case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: - return createDHKeyExchange(KeyExchangeAlgorithm.DH_DSS); - - case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: - return createDHKeyExchange(KeyExchangeAlgorithm.DH_RSA); - - case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: - return createDHEKeyExchange(KeyExchangeAlgorithm.DHE_DSS); - - case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: - return createDHEKeyExchange(KeyExchangeAlgorithm.DHE_RSA); - - case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: - return createECDHKeyExchange(KeyExchangeAlgorithm.ECDH_ECDSA); - - case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: - return createECDHKeyExchange(KeyExchangeAlgorithm.ECDH_RSA); - - case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1: - return createECDHEKeyExchange(KeyExchangeAlgorithm.ECDHE_ECDSA); - - case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1: - return createECDHEKeyExchange(KeyExchangeAlgorithm.ECDHE_RSA); - - 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: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_RSA_WITH_NULL_MD5: - case CipherSuite.TLS_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_RSA_WITH_NULL_SHA256: - case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: - case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: - return createRSAKeyExchange(); - - default: - /* - * Note: internal error here; the TlsProtocol implementation verifies that the - * server-selected cipher suite was in the list of client-offered cipher suites, so if - * we now can't produce an implementation, we shouldn't have offered it! - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public TlsCipher getCipher() - throws IOException - { - 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: - case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm._3DES_EDE_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AEAD_CHACHA20_POLY1305, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha1); - - 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: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CCM, MACAlgorithm._null); - - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CCM_8, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha384); - - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CCM, MACAlgorithm._null); - - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CCM_8, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_128_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_128_CBC, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_128_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_CBC, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_CBC, MACAlgorithm.hmac_sha384); - - case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1: - return cipherFactory.createCipher(context, EncryptionAlgorithm.ESTREAM_SALSA20, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_RSA_WITH_NULL_MD5: - return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_md5); - - case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_RSA_WITH_NULL_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_RSA_WITH_NULL_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: - return cipherFactory.createCipher(context, EncryptionAlgorithm.RC4_128, MACAlgorithm.hmac_md5); - - case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.RC4_128, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1: - return cipherFactory.createCipher(context, EncryptionAlgorithm.SALSA20, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.SEED_CBC, MACAlgorithm.hmac_sha1); - - default: - /* - * Note: internal error here; the TlsProtocol implementation verifies that the - * server-selected cipher suite was in the list of client-offered cipher suites, so if - * we now can't produce an implementation, we shouldn't have offered it! - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - protected TlsKeyExchange createDHKeyExchange(int keyExchange) - { - return new TlsDHKeyExchange(keyExchange, supportedSignatureAlgorithms, null); - } - - protected TlsKeyExchange createDHEKeyExchange(int keyExchange) - { - return new TlsDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, null); - } - - protected TlsKeyExchange createECDHKeyExchange(int keyExchange) - { - return new TlsECDHKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, - serverECPointFormats); - } - - protected TlsKeyExchange createECDHEKeyExchange(int keyExchange) - { - return new TlsECDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, - serverECPointFormats); - } - - protected TlsKeyExchange createRSAKeyExchange() - { - return new TlsRSAKeyExchange(supportedSignatureAlgorithms); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsEncryptionCredentials.java b/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsEncryptionCredentials.java deleted file mode 100644 index 54bcd90c..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsEncryptionCredentials.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.encodings.PKCS1Encoding; -import org.bouncycastle.crypto.engines.RSABlindedEngine; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.crypto.params.RSAKeyParameters; - -public class DefaultTlsEncryptionCredentials extends AbstractTlsEncryptionCredentials -{ - protected TlsContext context; - protected Certificate certificate; - protected AsymmetricKeyParameter privateKey; - - public DefaultTlsEncryptionCredentials(TlsContext context, Certificate certificate, - AsymmetricKeyParameter privateKey) - { - if (certificate == null) - { - throw new IllegalArgumentException("'certificate' cannot be null"); - } - if (certificate.isEmpty()) - { - throw new IllegalArgumentException("'certificate' cannot be empty"); - } - if (privateKey == null) - { - throw new IllegalArgumentException("'privateKey' cannot be null"); - } - if (!privateKey.isPrivate()) - { - throw new IllegalArgumentException("'privateKey' must be private"); - } - - if (privateKey instanceof RSAKeyParameters) - { - } - else - { - throw new IllegalArgumentException("'privateKey' type not supported: " - + privateKey.getClass().getName()); - } - - this.context = context; - this.certificate = certificate; - this.privateKey = privateKey; - } - - public Certificate getCertificate() - { - return certificate; - } - - public byte[] decryptPreMasterSecret(byte[] encryptedPreMasterSecret) - throws IOException - { - return TlsRSAUtils.safeDecryptPreMasterSecret(context, (RSAKeyParameters)privateKey, encryptedPreMasterSecret); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsServer.java b/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsServer.java deleted file mode 100644 index f8f83465..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsServer.java +++ /dev/null @@ -1,550 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -import org.bouncycastle.crypto.agreement.DHStandardGroups; -import org.bouncycastle.crypto.params.DHParameters; - -public abstract class DefaultTlsServer - extends AbstractTlsServer -{ - public DefaultTlsServer() - { - super(); - } - - public DefaultTlsServer(TlsCipherFactory cipherFactory) - { - super(cipherFactory); - } - - protected TlsEncryptionCredentials getRSAEncryptionCredentials() - throws IOException - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - protected TlsSignerCredentials getRSASignerCredentials() - throws IOException - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - protected DHParameters getDHParameters() - { - return DHStandardGroups.rfc5114_1024_160; - } - - protected int[] getCipherSuites() - { - return new int[] - { - CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384, - CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, - CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256, - CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, - CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, - CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, - }; - } - - public TlsCredentials getCredentials() - throws IOException - { - 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: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_NULL_MD5: - case CipherSuite.TLS_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_RSA_WITH_NULL_SHA256: - case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: - case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: - return getRSAEncryptionCredentials(); - - case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1: - return getRSASignerCredentials(); - - default: - /* - * Note: internal error here; selected a key exchange we don't implement! - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public TlsKeyExchange getKeyExchange() - throws IOException - { - 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: - case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: - return createDHKeyExchange(KeyExchangeAlgorithm.DH_DSS); - - case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: - return createDHKeyExchange(KeyExchangeAlgorithm.DH_RSA); - - case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: - return createDHEKeyExchange(KeyExchangeAlgorithm.DHE_DSS); - - case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: - return createDHEKeyExchange(KeyExchangeAlgorithm.DHE_RSA); - - case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: - return createECDHKeyExchange(KeyExchangeAlgorithm.ECDH_ECDSA); - - case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: - return createECDHKeyExchange(KeyExchangeAlgorithm.ECDH_RSA); - - case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1: - return createECDHEKeyExchange(KeyExchangeAlgorithm.ECDHE_ECDSA); - - case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1: - return createECDHEKeyExchange(KeyExchangeAlgorithm.ECDHE_RSA); - - 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: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_RSA_WITH_NULL_MD5: - case CipherSuite.TLS_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_RSA_WITH_NULL_SHA256: - case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: - case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: - return createRSAKeyExchange(); - - default: - /* - * Note: internal error here; selected a key exchange we don't implement! - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public TlsCipher getCipher() - throws IOException - { - 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: - case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm._3DES_EDE_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AEAD_CHACHA20_POLY1305, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha1); - - 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: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CCM, MACAlgorithm._null); - - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CCM_8, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha384); - - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CCM, MACAlgorithm._null); - - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CCM_8, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_128_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_128_CBC, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_128_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_CBC, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_CBC, MACAlgorithm.hmac_sha384); - - case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1: - return cipherFactory.createCipher(context, EncryptionAlgorithm.ESTREAM_SALSA20, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_RSA_WITH_NULL_MD5: - return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_md5); - - case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_RSA_WITH_NULL_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_RSA_WITH_NULL_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: - return cipherFactory.createCipher(context, EncryptionAlgorithm.RC4_128, MACAlgorithm.hmac_md5); - - case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.RC4_128, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1: - return cipherFactory.createCipher(context, EncryptionAlgorithm.SALSA20, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.SEED_CBC, MACAlgorithm.hmac_sha1); - - default: - /* - * Note: internal error here; selected a cipher suite we don't implement! - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - protected TlsKeyExchange createDHKeyExchange(int keyExchange) - { - return new TlsDHKeyExchange(keyExchange, supportedSignatureAlgorithms, getDHParameters()); - } - - protected TlsKeyExchange createDHEKeyExchange(int keyExchange) - { - return new TlsDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, getDHParameters()); - } - - protected TlsKeyExchange createECDHKeyExchange(int keyExchange) - { - return new TlsECDHKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, - serverECPointFormats); - } - - protected TlsKeyExchange createECDHEKeyExchange(int keyExchange) - { - return new TlsECDHEKeyExchange(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, - serverECPointFormats); - } - - protected TlsKeyExchange createRSAKeyExchange() - { - return new TlsRSAKeyExchange(supportedSignatureAlgorithms); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsSignerCredentials.java b/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsSignerCredentials.java deleted file mode 100755 index 15bf4a40..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DefaultTlsSignerCredentials.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; -import org.bouncycastle.crypto.params.ECPrivateKeyParameters; -import org.bouncycastle.crypto.params.RSAKeyParameters; - -public class DefaultTlsSignerCredentials - extends AbstractTlsSignerCredentials -{ - protected TlsContext context; - protected Certificate certificate; - protected AsymmetricKeyParameter privateKey; - protected SignatureAndHashAlgorithm signatureAndHashAlgorithm; - - protected TlsSigner signer; - - public DefaultTlsSignerCredentials(TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey) - { - this(context, certificate, privateKey, null); - } - - public DefaultTlsSignerCredentials(TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey, - SignatureAndHashAlgorithm signatureAndHashAlgorithm) - { - if (certificate == null) - { - throw new IllegalArgumentException("'certificate' cannot be null"); - } - if (certificate.isEmpty()) - { - throw new IllegalArgumentException("'certificate' cannot be empty"); - } - if (privateKey == null) - { - throw new IllegalArgumentException("'privateKey' cannot be null"); - } - if (!privateKey.isPrivate()) - { - throw new IllegalArgumentException("'privateKey' must be private"); - } - if (TlsUtils.isTLSv12(context) && signatureAndHashAlgorithm == null) - { - throw new IllegalArgumentException("'signatureAndHashAlgorithm' cannot be null for (D)TLS 1.2+"); - } - - if (privateKey instanceof RSAKeyParameters) - { - this.signer = new TlsRSASigner(); - } - else if (privateKey instanceof DSAPrivateKeyParameters) - { - this.signer = new TlsDSSSigner(); - } - else if (privateKey instanceof ECPrivateKeyParameters) - { - this.signer = new TlsECDSASigner(); - } - else - { - throw new IllegalArgumentException("'privateKey' type not supported: " + privateKey.getClass().getName()); - } - - this.signer.init(context); - - this.context = context; - this.certificate = certificate; - this.privateKey = privateKey; - this.signatureAndHashAlgorithm = signatureAndHashAlgorithm; - } - - public Certificate getCertificate() - { - return certificate; - } - - public byte[] generateCertificateSignature(byte[] hash) - throws IOException - { - try - { - if (TlsUtils.isTLSv12(context)) - { - return signer.generateRawSignature(signatureAndHashAlgorithm, privateKey, hash); - } - else - { - return signer.generateRawSignature(privateKey, hash); - } - } - catch (CryptoException e) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public SignatureAndHashAlgorithm getSignatureAndHashAlgorithm() - { - return signatureAndHashAlgorithm; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DeferredHash.java b/core/src/main/java/org/bouncycastle/crypto/tls/DeferredHash.java deleted file mode 100644 index 274e69a3..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DeferredHash.java +++ /dev/null @@ -1,207 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.util.Enumeration; -import java.util.Hashtable; - -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.util.Shorts; - -/** - * Buffers input until the hash algorithm is determined. - */ -class DeferredHash - implements TlsHandshakeHash -{ - protected static final int BUFFERING_HASH_LIMIT = 4; - - protected TlsContext context; - - private DigestInputBuffer buf; - private Hashtable hashes; - private Short prfHashAlgorithm; - - DeferredHash() - { - this.buf = new DigestInputBuffer(); - this.hashes = new Hashtable(); - this.prfHashAlgorithm = null; - } - - private DeferredHash(Short prfHashAlgorithm, Digest prfHash) - { - this.buf = null; - this.hashes = new Hashtable(); - this.prfHashAlgorithm = prfHashAlgorithm; - hashes.put(prfHashAlgorithm, prfHash); - } - - public void init(TlsContext context) - { - this.context = context; - } - - public TlsHandshakeHash notifyPRFDetermined() - { - int prfAlgorithm = context.getSecurityParameters().getPrfAlgorithm(); - if (prfAlgorithm == PRFAlgorithm.tls_prf_legacy) - { - CombinedHash legacyHash = new CombinedHash(); - legacyHash.init(context); - buf.updateDigest(legacyHash); - return legacyHash.notifyPRFDetermined(); - } - - this.prfHashAlgorithm = Shorts.valueOf(TlsUtils.getHashAlgorithmForPRFAlgorithm(prfAlgorithm)); - - checkTrackingHash(prfHashAlgorithm); - - return this; - } - - public void trackHashAlgorithm(short hashAlgorithm) - { - if (buf == null) - { - throw new IllegalStateException("Too late to track more hash algorithms"); - } - - checkTrackingHash(Shorts.valueOf(hashAlgorithm)); - } - - public void sealHashAlgorithms() - { - checkStopBuffering(); - } - - public TlsHandshakeHash stopTracking() - { - Digest prfHash = TlsUtils.cloneHash(prfHashAlgorithm.shortValue(), (Digest)hashes.get(prfHashAlgorithm)); - if (buf != null) - { - buf.updateDigest(prfHash); - } - DeferredHash result = new DeferredHash(prfHashAlgorithm, prfHash); - result.init(context); - return result; - } - - public Digest forkPRFHash() - { - checkStopBuffering(); - - if (buf != null) - { - Digest prfHash = TlsUtils.createHash(prfHashAlgorithm.shortValue()); - buf.updateDigest(prfHash); - return prfHash; - } - - return TlsUtils.cloneHash(prfHashAlgorithm.shortValue(), (Digest)hashes.get(prfHashAlgorithm)); - } - - public byte[] getFinalHash(short hashAlgorithm) - { - Digest d = (Digest)hashes.get(Shorts.valueOf(hashAlgorithm)); - if (d == null) - { - throw new IllegalStateException("HashAlgorithm " + hashAlgorithm + " is not being tracked"); - } - - d = TlsUtils.cloneHash(hashAlgorithm, d); - if (buf != null) - { - buf.updateDigest(d); - } - - byte[] bs = new byte[d.getDigestSize()]; - d.doFinal(bs, 0); - return bs; - } - - public String getAlgorithmName() - { - throw new IllegalStateException("Use fork() to get a definite Digest"); - } - - public int getDigestSize() - { - throw new IllegalStateException("Use fork() to get a definite Digest"); - } - - public void update(byte input) - { - if (buf != null) - { - buf.write(input); - return; - } - - Enumeration e = hashes.elements(); - while (e.hasMoreElements()) - { - Digest hash = (Digest)e.nextElement(); - hash.update(input); - } - } - - public void update(byte[] input, int inOff, int len) - { - if (buf != null) - { - buf.write(input, inOff, len); - return; - } - - Enumeration e = hashes.elements(); - while (e.hasMoreElements()) - { - Digest hash = (Digest)e.nextElement(); - hash.update(input, inOff, len); - } - } - - public int doFinal(byte[] output, int outOff) - { - throw new IllegalStateException("Use fork() to get a definite Digest"); - } - - public void reset() - { - if (buf != null) - { - buf.reset(); - return; - } - - Enumeration e = hashes.elements(); - while (e.hasMoreElements()) - { - Digest hash = (Digest)e.nextElement(); - hash.reset(); - } - } - - protected void checkStopBuffering() - { - if (buf != null && hashes.size() <= BUFFERING_HASH_LIMIT) - { - Enumeration e = hashes.elements(); - while (e.hasMoreElements()) - { - Digest hash = (Digest)e.nextElement(); - buf.updateDigest(hash); - } - - this.buf = null; - } - } - - protected void checkTrackingHash(Short hashAlgorithm) - { - if (!hashes.containsKey(hashAlgorithm)) - { - Digest hash = TlsUtils.createHash(hashAlgorithm.shortValue()); - hashes.put(hashAlgorithm, hash); - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DigestAlgorithm.java b/core/src/main/java/org/bouncycastle/crypto/tls/DigestAlgorithm.java deleted file mode 100644 index 8bb89a66..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DigestAlgorithm.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 2246 - * <p> - * 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 static final int NULL = 0; - public static final int MD5 = 1; - public static final int SHA = 2; - - /* - * RFC 5246 - */ - public static final int SHA256 = 3; - public static final int SHA384 = 4; - public static final int SHA512 = 5; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DigestInputBuffer.java b/core/src/main/java/org/bouncycastle/crypto/tls/DigestInputBuffer.java deleted file mode 100644 index 7cfa8909..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DigestInputBuffer.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayOutputStream; - -import org.bouncycastle.crypto.Digest; - -class DigestInputBuffer extends ByteArrayOutputStream -{ - void updateDigest(Digest d) - { - d.update(this.buf, 0, count); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/DigitallySigned.java b/core/src/main/java/org/bouncycastle/crypto/tls/DigitallySigned.java deleted file mode 100644 index c366ca9d..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/DigitallySigned.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class DigitallySigned -{ - protected SignatureAndHashAlgorithm algorithm; - protected byte[] signature; - - public DigitallySigned(SignatureAndHashAlgorithm algorithm, byte[] signature) - { - if (signature == null) - { - throw new IllegalArgumentException("'signature' cannot be null"); - } - - this.algorithm = algorithm; - this.signature = signature; - } - - /** - * @return a {@link SignatureAndHashAlgorithm} (or null before TLS 1.2). - */ - public SignatureAndHashAlgorithm getAlgorithm() - { - return algorithm; - } - - public byte[] getSignature() - { - return signature; - } - - /** - * Encode this {@link DigitallySigned} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) throws IOException - { - if (algorithm != null) - { - algorithm.encode(output); - } - TlsUtils.writeOpaque16(signature, output); - } - - /** - * Parse a {@link DigitallySigned} from an {@link InputStream}. - * - * @param context - * the {@link TlsContext} of the current connection. - * @param input - * the {@link InputStream} to parse from. - * @return a {@link DigitallySigned} object. - * @throws IOException - */ - public static DigitallySigned parse(TlsContext context, InputStream input) throws IOException - { - SignatureAndHashAlgorithm algorithm = null; - if (TlsUtils.isTLSv12(context)) - { - algorithm = SignatureAndHashAlgorithm.parse(input); - } - byte[] signature = TlsUtils.readOpaque16(input); - return new DigitallySigned(algorithm, signature); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ECBasisType.java b/core/src/main/java/org/bouncycastle/crypto/tls/ECBasisType.java deleted file mode 100644 index 630dfcd6..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ECBasisType.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 4492 5.4. (Errata ID: 2389) - */ -public class ECBasisType -{ - public static final short ec_basis_trinomial = 1; - public static final short ec_basis_pentanomial = 2; - - public static boolean isValid(short ecBasisType) - { - return ecBasisType >= ec_basis_trinomial && ecBasisType <= ec_basis_pentanomial; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ECCurveType.java b/core/src/main/java/org/bouncycastle/crypto/tls/ECCurveType.java deleted file mode 100644 index 0b6542fc..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ECCurveType.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 4492 5.4 - */ -public class ECCurveType -{ - /** - * Indicates the elliptic curve domain parameters are conveyed verbosely, and the - * underlying finite field is a prime field. - */ - public static final short explicit_prime = 1; - - /** - * Indicates the elliptic curve domain parameters are conveyed verbosely, and the - * underlying finite field is a characteristic-2 field. - */ - public static final short explicit_char2 = 2; - - /** - * Indicates that a named curve is used. This option SHOULD be used when applicable. - */ - public static final short named_curve = 3; - - /* - * Values 248 through 255 are reserved for private use. - */ -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ECPointFormat.java b/core/src/main/java/org/bouncycastle/crypto/tls/ECPointFormat.java deleted file mode 100644 index 969d42ee..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ECPointFormat.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 4492 5.1.2 - */ -public class ECPointFormat -{ - public static final short uncompressed = 0; - public static final short ansiX962_compressed_prime = 1; - public static final short ansiX962_compressed_char2 = 2; - - /* - * reserved (248..255) - */ -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/EncryptionAlgorithm.java b/core/src/main/java/org/bouncycastle/crypto/tls/EncryptionAlgorithm.java deleted file mode 100644 index 2da2f76a..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/EncryptionAlgorithm.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 2246 - * <p> - * 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 static final int NULL = 0; - public static final int RC4_40 = 1; - public static final int RC4_128 = 2; - public static final int RC2_CBC_40 = 3; - public static final int IDEA_CBC = 4; - public static final int DES40_CBC = 5; - public static final int DES_CBC = 6; - public static final int _3DES_EDE_CBC = 7; - - /* - * RFC 3268 - */ - public static final int AES_128_CBC = 8; - public static final int AES_256_CBC = 9; - - /* - * RFC 5289 - */ - public static final int AES_128_GCM = 10; - public static final int AES_256_GCM = 11; - - /* - * RFC 5932 - */ - public static final int CAMELLIA_128_CBC = 12; - public static final int CAMELLIA_256_CBC = 13; - - /* - * RFC 4162 - */ - public static final int SEED_CBC = 14; - - /* - * RFC 6655 - */ - public static final int AES_128_CCM = 15; - public static final int AES_128_CCM_8 = 16; - public static final int AES_256_CCM = 17; - public static final int AES_256_CCM_8 = 18; - - /* - * RFC 6367 - */ - public static final int CAMELLIA_128_GCM = 19; - public static final int CAMELLIA_256_GCM = 20; - - /* - * draft-josefsson-salsa20-tls-04 - */ - public static final int ESTREAM_SALSA20 = 100; - public static final int SALSA20 = 101; - - /* - * draft-agl-tls-chacha20poly1305-04 - */ - public static final int AEAD_CHACHA20_POLY1305 = 102; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ExporterLabel.java b/core/src/main/java/org/bouncycastle/crypto/tls/ExporterLabel.java deleted file mode 100644 index 902720ac..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ExporterLabel.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 5705 - */ -public class ExporterLabel -{ - /* - * RFC 5246 - */ - public static final String client_finished = "client finished"; - public static final String server_finished = "server finished"; - public static final String master_secret = "master secret"; - public static final String key_expansion = "key expansion"; - - /* - * RFC 5216 - */ - public static final String client_EAP_encryption = "client EAP encryption"; - - /* - * RFC 5281 - */ - public static final String ttls_keying_material = "ttls keying material"; - public static final String ttls_challenge = "ttls challenge"; - - /* - * RFC 5764 - */ - public static final String dtls_srtp = "EXTRACTOR-dtls_srtp"; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ExtensionType.java b/core/src/main/java/org/bouncycastle/crypto/tls/ExtensionType.java deleted file mode 100644 index c0a7a90a..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ExtensionType.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public class ExtensionType -{ - /* - * RFC 2546 2.3. - */ - public static final int server_name = 0; - public static final int max_fragment_length = 1; - public static final int client_certificate_url = 2; - public static final int trusted_ca_keys = 3; - public static final int truncated_hmac = 4; - public static final int status_request = 5; - - /* - * RFC 4681 - */ - public static final int user_mapping = 6; - - /* - * RFC 4492 5.1. - */ - public static final int elliptic_curves = 10; - public static final int ec_point_formats = 11; - - /* - * RFC 5054 2.8.1. - */ - public static final int srp = 12; - - /* - * RFC 5246 7.4.1.4. - */ - public static final int signature_algorithms = 13; - - /* - * RFC 5764 9. - */ - public static final int use_srtp = 14; - - /* - * RFC 6520 6. - */ - public static final int heartbeat = 15; - - /* - * RFC 5077 7. - */ - public static final int session_ticket = 35; - - /* - * draft-ietf-tls-encrypt-then-mac-03 - */ - public static final int encrypt_then_mac = 22; - - /* - * RFC 5746 3.2. - */ - public static final int renegotiation_info = 0xff01; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/HandshakeType.java b/core/src/main/java/org/bouncycastle/crypto/tls/HandshakeType.java deleted file mode 100644 index c81660a5..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/HandshakeType.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public class HandshakeType -{ - /* - * 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; - public static final short certificate = 11; - public static final short server_key_exchange = 12; - public static final short certificate_request = 13; - public static final short server_hello_done = 14; - public static final short certificate_verify = 15; - public static final short client_key_exchange = 16; - public static final short finished = 20; - - /* - * RFC 3546 2.4 - */ - public static final short certificate_url = 21; - public static final short certificate_status = 22; - - /* - * (DTLS) RFC 4347 4.3.2 - */ - public static final short hello_verify_request = 3; - - /* - * RFC 4680 - */ - public static final short supplemental_data = 23; - - /* - * RFC 5077 - */ - public static final short session_ticket = 4; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/HashAlgorithm.java b/core/src/main/java/org/bouncycastle/crypto/tls/HashAlgorithm.java deleted file mode 100644 index dc7482b8..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/HashAlgorithm.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 5246 7.4.1.4.1 - */ -public class HashAlgorithm -{ - public static final short none = 0; - public static final short md5 = 1; - public static final short sha1 = 2; - public static final short sha224 = 3; - public static final short sha256 = 4; - public static final short sha384 = 5; - public static final short sha512 = 6; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatExtension.java b/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatExtension.java deleted file mode 100644 index f9f3670e..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatExtension.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class HeartbeatExtension -{ - protected short mode; - - public HeartbeatExtension(short mode) - { - if (!HeartbeatMode.isValid(mode)) - { - throw new IllegalArgumentException("'mode' is not a valid HeartbeatMode value"); - } - - this.mode = mode; - } - - public short getMode() - { - return mode; - } - - /** - * Encode this {@link HeartbeatExtension} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) throws IOException - { - TlsUtils.writeUint8(mode, output); - } - - /** - * Parse a {@link HeartbeatExtension} from an {@link InputStream}. - * - * @param input - * the {@link InputStream} to parse from. - * @return a {@link HeartbeatExtension} object. - * @throws IOException - */ - public static HeartbeatExtension parse(InputStream input) throws IOException - { - short mode = TlsUtils.readUint8(input); - if (!HeartbeatMode.isValid(mode)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - return new HeartbeatExtension(mode); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatMessage.java b/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatMessage.java deleted file mode 100644 index c6a447fc..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatMessage.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.io.Streams; - -public class HeartbeatMessage -{ - protected short type; - protected byte[] payload; - protected int paddingLength; - - public HeartbeatMessage(short type, byte[] payload, int paddingLength) - { - if (!HeartbeatMessageType.isValid(type)) - { - throw new IllegalArgumentException("'type' is not a valid HeartbeatMessageType value"); - } - if (payload == null || payload.length >= (1 << 16)) - { - throw new IllegalArgumentException("'payload' must have length < 2^16"); - } - if (paddingLength < 16) - { - throw new IllegalArgumentException("'paddingLength' must be at least 16"); - } - - this.type = type; - this.payload = payload; - this.paddingLength = paddingLength; - } - - /** - * Encode this {@link HeartbeatMessage} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(TlsContext context, OutputStream output) throws IOException - { - TlsUtils.writeUint8(type, output); - - TlsUtils.checkUint16(payload.length); - TlsUtils.writeUint16(payload.length, output); - output.write(payload); - - byte[] padding = new byte[paddingLength]; - context.getNonceRandomGenerator().nextBytes(padding); - output.write(padding); - } - - /** - * Parse a {@link HeartbeatMessage} from an {@link InputStream}. - * - * @param input - * the {@link InputStream} to parse from. - * @return a {@link HeartbeatMessage} object. - * @throws IOException - */ - public static HeartbeatMessage parse(InputStream input) throws IOException - { - short type = TlsUtils.readUint8(input); - if (!HeartbeatMessageType.isValid(type)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - int payload_length = TlsUtils.readUint16(input); - - PayloadBuffer buf = new PayloadBuffer(); - Streams.pipeAll(input, buf); - - byte[] payload = buf.toTruncatedByteArray(payload_length); - if (payload == null) - { - /* - * RFC 6520 4. If the payload_length of a received HeartbeatMessage is too large, the - * received HeartbeatMessage MUST be discarded silently. - */ - return null; - } - - int padding_length = buf.size() - payload.length; - - /* - * RFC 6520 4. The padding of a received HeartbeatMessage message MUST be ignored - */ - return new HeartbeatMessage(type, payload, padding_length); - } - - static class PayloadBuffer extends ByteArrayOutputStream - { - byte[] toTruncatedByteArray(int payloadLength) - { - /* - * RFC 6520 4. The padding_length MUST be at least 16. - */ - int minimumCount = payloadLength + 16; - if (count < minimumCount) - { - return null; - } - return Arrays.copyOf(buf, payloadLength); - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatMessageType.java b/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatMessageType.java deleted file mode 100644 index f1a3b43a..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatMessageType.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/* - * RFC 6520 3. - */ -public class HeartbeatMessageType -{ - public static final short heartbeat_request = 1; - public static final short heartbeat_response = 2; - - public static boolean isValid(short heartbeatMessageType) - { - return heartbeatMessageType >= heartbeat_request && heartbeatMessageType <= heartbeat_response; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatMode.java b/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatMode.java deleted file mode 100644 index 4024faaf..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/HeartbeatMode.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/* - * RFC 6520 - */ -public class HeartbeatMode -{ - public static final short peer_allowed_to_send = 1; - public static final short peer_not_allowed_to_send = 2; - - public static boolean isValid(short heartbeatMode) - { - return heartbeatMode >= peer_allowed_to_send && heartbeatMode <= peer_not_allowed_to_send; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/KeyExchangeAlgorithm.java b/core/src/main/java/org/bouncycastle/crypto/tls/KeyExchangeAlgorithm.java deleted file mode 100644 index d862d769..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/KeyExchangeAlgorithm.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 2246 - * <p> - * 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 KeyExchangeAlgorithm -{ - public static final int NULL = 0; - public static final int RSA = 1; - public static final int RSA_EXPORT = 2; - public static final int DHE_DSS = 3; - public static final int DHE_DSS_EXPORT = 4; - public static final int DHE_RSA = 5; - public static final int DHE_RSA_EXPORT = 6; - public static final int DH_DSS = 7; - public static final int DH_DSS_EXPORT = 8; - public static final int DH_RSA = 9; - 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 - */ - public static final int PSK = 13; - public static final int DHE_PSK = 14; - public static final int RSA_PSK = 15; - - /* - * RFC 4429 - */ - public static final int ECDH_ECDSA = 16; - public static final int ECDHE_ECDSA = 17; - public static final int ECDH_RSA = 18; - public static final int ECDHE_RSA = 19; - public static final int ECDH_anon = 20; - - /* - * RFC 5054 - */ - public static final int SRP = 21; - public static final int SRP_DSS = 22; - public static final int SRP_RSA = 23; - - /* - * RFC 5489 - */ - public static final int ECDHE_PSK = 24; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsAuthentication.java b/core/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsAuthentication.java deleted file mode 100644 index f638714e..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsAuthentication.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -/** - * A temporary class to wrap old CertificateVerifyer stuff for new TlsAuthentication - * - * @deprecated - */ -public class LegacyTlsAuthentication - extends ServerOnlyTlsAuthentication -{ - protected CertificateVerifyer verifyer; - - public LegacyTlsAuthentication(CertificateVerifyer verifyer) - { - this.verifyer = verifyer; - } - - public void notifyServerCertificate(Certificate serverCertificate) - throws IOException - { - if (!this.verifyer.isValid(serverCertificate.getCertificateList())) - { - throw new TlsFatalAlert(AlertDescription.user_canceled); - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsClient.java b/core/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsClient.java deleted file mode 100644 index 33217ac4..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/LegacyTlsClient.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -/** - * A temporary class to use LegacyTlsAuthentication - * - * @deprecated - */ -public class LegacyTlsClient - extends DefaultTlsClient -{ - /** - * @deprecated - */ - protected CertificateVerifyer verifyer; - - /** - * @deprecated - */ - public LegacyTlsClient(CertificateVerifyer verifyer) - { - super(); - - this.verifyer = verifyer; - } - - public TlsAuthentication getAuthentication() - throws IOException - { - return new LegacyTlsAuthentication(verifyer); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/MACAlgorithm.java b/core/src/main/java/org/bouncycastle/crypto/tls/MACAlgorithm.java deleted file mode 100644 index bd13ab89..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/MACAlgorithm.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 2246 - * <p> - * 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 static final int _null = 0; - public static final int md5 = 1; - public static final int sha = 2; - - /* - * RFC 5246 - */ - public static final int hmac_md5 = md5; - public static final int hmac_sha1 = sha; - public static final int hmac_sha256 = 3; - public static final int hmac_sha384 = 4; - public static final int hmac_sha512 = 5; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/MaxFragmentLength.java b/core/src/main/java/org/bouncycastle/crypto/tls/MaxFragmentLength.java deleted file mode 100644 index 6bc61b0c..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/MaxFragmentLength.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public class MaxFragmentLength -{ - /* - * RFC 3546 3.2. - */ - public static final short pow2_9 = 1; - public static final short pow2_10 = 2; - public static final short pow2_11 = 3; - public static final short pow2_12 = 4; - - public static boolean isValid(short maxFragmentLength) - { - return maxFragmentLength >= pow2_9 && maxFragmentLength <= pow2_12; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/NameType.java b/core/src/main/java/org/bouncycastle/crypto/tls/NameType.java deleted file mode 100644 index 9b0cd1b9..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/NameType.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public class NameType -{ - /* - * RFC 3546 3.1. - */ - public static final short host_name = 0; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/NamedCurve.java b/core/src/main/java/org/bouncycastle/crypto/tls/NamedCurve.java deleted file mode 100644 index 49fc923a..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/NamedCurve.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 4492 5.1.1 - * <p> - * 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 static final int sect163k1 = 1; - public static final int sect163r1 = 2; - public static final int sect163r2 = 3; - public static final int sect193r1 = 4; - public static final int sect193r2 = 5; - public static final int sect233k1 = 6; - public static final int sect233r1 = 7; - public static final int sect239k1 = 8; - public static final int sect283k1 = 9; - public static final int sect283r1 = 10; - public static final int sect409k1 = 11; - public static final int sect409r1 = 12; - public static final int sect571k1 = 13; - public static final int sect571r1 = 14; - public static final int secp160k1 = 15; - public static final int secp160r1 = 16; - public static final int secp160r2 = 17; - public static final int secp192k1 = 18; - public static final int secp192r1 = 19; - public static final int secp224k1 = 20; - public static final int secp224r1 = 21; - public static final int secp256k1 = 22; - public static final int secp256r1 = 23; - public static final int secp384r1 = 24; - public static final int secp521r1 = 25; - - /* - * RFC 7027 - */ - public static final int brainpoolP256r1 = 26; - public static final int brainpoolP384r1 = 27; - public static final int brainpoolP512r1 = 28; - - /* - * reserved (0xFE00..0xFEFF) - */ - - public static final int arbitrary_explicit_prime_curves = 0xFF01; - public static final int arbitrary_explicit_char2_curves = 0xFF02; - - public static boolean isValid(int namedCurve) - { - return (namedCurve >= sect163k1 && namedCurve <= brainpoolP512r1) - || (namedCurve >= arbitrary_explicit_prime_curves && namedCurve <= arbitrary_explicit_char2_curves); - } - - public static boolean refersToASpecificNamedCurve(int namedCurve) - { - switch (namedCurve) - { - case arbitrary_explicit_prime_curves: - case arbitrary_explicit_char2_curves: - return false; - default: - return true; - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/NewSessionTicket.java b/core/src/main/java/org/bouncycastle/crypto/tls/NewSessionTicket.java deleted file mode 100644 index 8f87a65e..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/NewSessionTicket.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class NewSessionTicket -{ - protected long ticketLifetimeHint; - protected byte[] ticket; - - public NewSessionTicket(long ticketLifetimeHint, byte[] ticket) - { - this.ticketLifetimeHint = ticketLifetimeHint; - this.ticket = ticket; - } - - public long getTicketLifetimeHint() - { - return ticketLifetimeHint; - } - - public byte[] getTicket() - { - return ticket; - } - - /** - * Encode this {@link NewSessionTicket} to an {@link OutputStream}. - * - * @param output the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) - throws IOException - { - TlsUtils.writeUint32(ticketLifetimeHint, output); - TlsUtils.writeOpaque16(ticket, output); - } - - /** - * Parse a {@link NewSessionTicket} from an {@link InputStream}. - * - * @param input the {@link InputStream} to parse from. - * @return a {@link NewSessionTicket} object. - * @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/core/src/main/java/org/bouncycastle/crypto/tls/OCSPStatusRequest.java b/core/src/main/java/org/bouncycastle/crypto/tls/OCSPStatusRequest.java deleted file mode 100644 index 473db23f..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/OCSPStatusRequest.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Vector; - -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ocsp.ResponderID; -import org.bouncycastle.asn1.x509.Extensions; - -/** - * RFC 3546 3.6 - */ -public class OCSPStatusRequest -{ - protected Vector responderIDList; - protected Extensions requestExtensions; - - /** - * @param responderIDList - * a {@link Vector} of {@link ResponderID}, specifying the list of trusted OCSP - * responders. An empty list has the special meaning that the responders are - * implicitly known to the server - e.g., by prior arrangement. - * @param requestExtensions - * OCSP request extensions. A null value means that there are no extensions. - */ - public OCSPStatusRequest(Vector responderIDList, Extensions requestExtensions) - { - this.responderIDList = responderIDList; - this.requestExtensions = requestExtensions; - } - - /** - * @return a {@link Vector} of {@link ResponderID} - */ - public Vector getResponderIDList() - { - return responderIDList; - } - - /** - * @return OCSP request extensions - */ - public Extensions getRequestExtensions() - { - return requestExtensions; - } - - /** - * Encode this {@link OCSPStatusRequest} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) throws IOException - { - if (responderIDList == null || responderIDList.isEmpty()) - { - TlsUtils.writeUint16(0, output); - } - else - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - for (int i = 0; i < responderIDList.size(); ++i) - { - ResponderID responderID = (ResponderID) responderIDList.elementAt(i); - byte[] derEncoding = responderID.getEncoded(ASN1Encoding.DER); - TlsUtils.writeOpaque16(derEncoding, buf); - } - TlsUtils.checkUint16(buf.size()); - TlsUtils.writeUint16(buf.size(), output); - buf.writeTo(output); - } - - if (requestExtensions == null) - { - TlsUtils.writeUint16(0, output); - } - else - { - byte[] derEncoding = requestExtensions.getEncoded(ASN1Encoding.DER); - TlsUtils.checkUint16(derEncoding.length); - TlsUtils.writeUint16(derEncoding.length, output); - output.write(derEncoding); - } - } - - /** - * Parse an {@link OCSPStatusRequest} from an {@link InputStream}. - * - * @param input - * the {@link InputStream} to parse from. - * @return an {@link OCSPStatusRequest} object. - * @throws IOException - */ - public static OCSPStatusRequest parse(InputStream input) throws IOException - { - Vector responderIDList = new Vector(); - { - int length = TlsUtils.readUint16(input); - if (length > 0) - { - byte[] data = TlsUtils.readFully(length, input); - ByteArrayInputStream buf = new ByteArrayInputStream(data); - do - { - byte[] derEncoding = TlsUtils.readOpaque16(buf); - ResponderID responderID = ResponderID.getInstance(TlsUtils.readDERObject(derEncoding)); - responderIDList.addElement(responderID); - } - while (buf.available() > 0); - } - } - - Extensions requestExtensions = null; - { - int length = TlsUtils.readUint16(input); - if (length > 0) - { - byte[] derEncoding = TlsUtils.readFully(length, input); - requestExtensions = Extensions.getInstance(TlsUtils.readDERObject(derEncoding)); - } - } - - return new OCSPStatusRequest(responderIDList, requestExtensions); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/PRFAlgorithm.java b/core/src/main/java/org/bouncycastle/crypto/tls/PRFAlgorithm.java deleted file mode 100644 index 33c27c4a..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/PRFAlgorithm.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 5246 - * <p> - * 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 -{ - /* - * Placeholder to refer to the legacy TLS algorithm - */ - public static final int tls_prf_legacy = 0; - - public static final int tls_prf_sha256 = 1; - - /* - * Implied by RFC 5288 - */ - public static final int tls_prf_sha384 = 2; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/PSKTlsClient.java b/core/src/main/java/org/bouncycastle/crypto/tls/PSKTlsClient.java deleted file mode 100644 index e442ce2f..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/PSKTlsClient.java +++ /dev/null @@ -1,256 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public abstract class PSKTlsClient - extends AbstractTlsClient -{ - protected TlsPSKIdentity pskIdentity; - - public PSKTlsClient(TlsPSKIdentity pskIdentity) - { - super(); - this.pskIdentity = pskIdentity; - } - - public PSKTlsClient(TlsCipherFactory cipherFactory, TlsPSKIdentity pskIdentity) - { - super(cipherFactory); - this.pskIdentity = pskIdentity; - } - - public int[] getCipherSuites() - { - return new int[] { CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, - CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, - CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA }; - } - - public TlsKeyExchange getKeyExchange() throws IOException - { - switch (selectedCipherSuite) - { - case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: - case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1: - case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: - case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: - return createPSKKeyExchange(KeyExchangeAlgorithm.DHE_PSK); - - case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1: - return createPSKKeyExchange(KeyExchangeAlgorithm.ECDHE_PSK); - - case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_PSK_WITH_AES_128_CCM: - case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: - case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_PSK_WITH_AES_256_CCM: - case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: - case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: - case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1: - return createPSKKeyExchange(KeyExchangeAlgorithm.PSK); - - case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1: - return createPSKKeyExchange(KeyExchangeAlgorithm.RSA_PSK); - - default: - /* - * Note: internal error here; the TlsProtocol implementation verifies that the - * server-selected cipher suite was in the list of client-offered cipher suites, so if - * we now can't produce an implementation, we shouldn't have offered it! - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public TlsCipher getCipher() throws IOException - { - switch (selectedCipherSuite) - { - case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm._3DES_EDE_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: - case CipherSuite.TLS_PSK_WITH_AES_128_CCM: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CCM, MACAlgorithm._null); - - case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: - case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CCM_8, MACAlgorithm._null); - - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha384); - - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: - case CipherSuite.TLS_PSK_WITH_AES_256_CCM: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CCM, MACAlgorithm._null); - - case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: - case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CCM_8, MACAlgorithm._null); - - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_128_CBC, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_128_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_CBC, MACAlgorithm.hmac_sha384); - - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.CAMELLIA_256_GCM, MACAlgorithm._null); - - case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1: - return cipherFactory.createCipher(context, EncryptionAlgorithm.ESTREAM_SALSA20, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: - return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha256); - - case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: - return cipherFactory.createCipher(context, EncryptionAlgorithm.NULL, MACAlgorithm.hmac_sha384); - - case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: - case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.RC4_128, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1: - case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1: - case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1: - return cipherFactory.createCipher(context, EncryptionAlgorithm.SALSA20, MACAlgorithm.hmac_sha1); - - default: - /* - * Note: internal error here; the TlsProtocol implementation verifies that the - * server-selected cipher suite was in the list of client-offered cipher suites, so if - * we now can't produce an implementation, we shouldn't have offered it! - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - protected TlsKeyExchange createPSKKeyExchange(int keyExchange) - { - return new TlsPSKKeyExchange(keyExchange, supportedSignatureAlgorithms, pskIdentity, null, namedCurves, - clientECPointFormats, serverECPointFormats); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ProtocolVersion.java b/core/src/main/java/org/bouncycastle/crypto/tls/ProtocolVersion.java deleted file mode 100644 index 8be2bec0..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ProtocolVersion.java +++ /dev/null @@ -1,158 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -import org.bouncycastle.util.Strings; - -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"); - public static final ProtocolVersion TLSv11 = new ProtocolVersion(0x0302, "TLS 1.1"); - public static final ProtocolVersion TLSv12 = new ProtocolVersion(0x0303, "TLS 1.2"); - public static final ProtocolVersion DTLSv10 = new ProtocolVersion(0xFEFF, "DTLS 1.0"); - public static final ProtocolVersion DTLSv12 = new ProtocolVersion(0xFEFD, "DTLS 1.2"); - - private int version; - private String name; - - private ProtocolVersion(int v, String name) - { - this.version = v & 0xffff; - this.name = name; - } - - public int getFullVersion() - { - return version; - } - - public int getMajorVersion() - { - return version >> 8; - } - - public int getMinorVersion() - { - return version & 0xff; - } - - public boolean isDTLS() - { - return getMajorVersion() == 0xFE; - } - - public boolean isSSL() - { - return this == SSLv3; - } - - public boolean isTLS() - { - return getMajorVersion() == 0x03; - } - - public ProtocolVersion getEquivalentTLSVersion() - { - if (!isDTLS()) - { - return this; - } - if (this == DTLSv10) - { - return TLSv11; - } - return TLSv12; - } - - 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()) - { - return false; - } - int diffMinorVersion = version.getMinorVersion() - getMinorVersion(); - return isDTLS() ? diffMinorVersion > 0 : diffMinorVersion < 0; - } - - public boolean equals(Object other) - { - return this == other || (other instanceof ProtocolVersion && equals((ProtocolVersion)other)); - } - - public boolean equals(ProtocolVersion other) - { - return other != null && this.version == other.version; - } - - public int hashCode() - { - return version; - } - - public static ProtocolVersion get(int major, int minor) - throws IOException - { - switch (major) - { - case 0x03: - { - switch (minor) - { - case 0x00: - return SSLv3; - case 0x01: - return TLSv10; - case 0x02: - return TLSv11; - case 0x03: - return TLSv12; - } - return getUnknownVersion(major, minor, "TLS"); - } - case 0xFE: - { - switch (minor) - { - case 0xFF: - return DTLSv10; - case 0xFE: - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - case 0xFD: - return DTLSv12; - } - return getUnknownVersion(major, minor, "DTLS"); - } - default: - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - } - - public String toString() - { - return name; - } - - private static ProtocolVersion getUnknownVersion(int major, int minor, String prefix) - throws IOException - { - TlsUtils.checkUint8(major); - TlsUtils.checkUint8(minor); - - int v = (major << 8) | minor; - String hex = Strings.toUpperCase(Integer.toHexString(0x10000 | v).substring(1)); - return new ProtocolVersion(v, prefix + " 0x" + hex); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/RecordStream.java b/core/src/main/java/org/bouncycastle/crypto/tls/RecordStream.java deleted file mode 100644 index 922b951d..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/RecordStream.java +++ /dev/null @@ -1,365 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * An implementation of the TLS 1.0/1.1/1.2 record layer, allowing downgrade to SSLv3. - */ -class RecordStream -{ - private static int DEFAULT_PLAINTEXT_LIMIT = (1 << 14); - - private TlsProtocol handler; - private InputStream input; - private OutputStream output; - private TlsCompression pendingCompression = null, readCompression = null, writeCompression = null; - private TlsCipher pendingCipher = null, readCipher = null, writeCipher = null; - private long readSeqNo = 0, writeSeqNo = 0; - private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - private TlsContext context = null; - private TlsHandshakeHash handshakeHash = null; - - private ProtocolVersion readVersion = null, writeVersion = null; - private boolean restrictReadVersion = true; - - private int plaintextLimit, compressedLimit, ciphertextLimit; - - RecordStream(TlsProtocol handler, InputStream input, OutputStream output) - { - this.handler = handler; - this.input = input; - this.output = output; - this.readCompression = new TlsNullCompression(); - this.writeCompression = this.readCompression; - this.readCipher = new TlsNullCipher(context); - this.writeCipher = this.readCipher; - - setPlaintextLimit(DEFAULT_PLAINTEXT_LIMIT); - } - - void init(TlsContext context) - { - this.context = context; - this.handshakeHash = new DeferredHash(); - this.handshakeHash.init(context); - } - - int getPlaintextLimit() - { - return plaintextLimit; - } - - void setPlaintextLimit(int plaintextLimit) - { - this.plaintextLimit = plaintextLimit; - this.compressedLimit = this.plaintextLimit + 1024; - this.ciphertextLimit = this.compressedLimit + 1024; - } - - ProtocolVersion getReadVersion() - { - return readVersion; - } - - void setReadVersion(ProtocolVersion readVersion) - { - this.readVersion = readVersion; - } - - void setWriteVersion(ProtocolVersion writeVersion) - { - this.writeVersion = writeVersion; - } - - /** - * RFC 5246 E.1. "Earlier versions of the TLS specification were not fully clear on what the - * record layer version number (TLSPlaintext.version) should contain when sending ClientHello - * (i.e., before it is known which version of the protocol will be employed). Thus, TLS servers - * compliant with this specification MUST accept any value {03,XX} as the record layer version - * number for ClientHello." - */ - void setRestrictReadVersion(boolean enabled) - { - this.restrictReadVersion = enabled; - } - - void setPendingConnectionState(TlsCompression tlsCompression, TlsCipher tlsCipher) - { - this.pendingCompression = tlsCompression; - this.pendingCipher = tlsCipher; - } - - void sentWriteCipherSpec() - throws IOException - { - if (pendingCompression == null || pendingCipher == null) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - this.writeCompression = this.pendingCompression; - this.writeCipher = this.pendingCipher; - this.writeSeqNo = 0; - } - - void receivedReadCipherSpec() - throws IOException - { - if (pendingCompression == null || pendingCipher == null) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - this.readCompression = this.pendingCompression; - this.readCipher = this.pendingCipher; - this.readSeqNo = 0; - } - - void finaliseHandshake() - throws IOException - { - if (readCompression != pendingCompression || writeCompression != pendingCompression - || readCipher != pendingCipher || writeCipher != pendingCipher) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - pendingCompression = null; - pendingCipher = null; - } - - public boolean readRecord() - throws IOException - { - byte[] recordHeader = TlsUtils.readAllOrNothing(5, input); - if (recordHeader == null) - { - return false; - } - - short type = TlsUtils.readUint8(recordHeader, 0); - - /* - * RFC 5246 6. If a TLS implementation receives an unexpected record type, it MUST send an - * unexpected_message alert. - */ - checkType(type, AlertDescription.unexpected_message); - - if (!restrictReadVersion) - { - int version = TlsUtils.readVersionRaw(recordHeader, 1); - if ((version & 0xffffff00) != 0x0300) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - else - { - ProtocolVersion version = TlsUtils.readVersion(recordHeader, 1); - if (readVersion == null) - { - readVersion = version; - } - else if (!version.equals(readVersion)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - - int length = TlsUtils.readUint16(recordHeader, 3); - byte[] plaintext = decodeAndVerify(type, input, length); - handler.processRecord(type, plaintext, 0, plaintext.length); - return true; - } - - protected byte[] decodeAndVerify(short type, InputStream input, int len) - throws IOException - { - checkLength(len, ciphertextLimit, AlertDescription.record_overflow); - - byte[] buf = TlsUtils.readFully(len, input); - byte[] decoded = readCipher.decodeCiphertext(readSeqNo++, type, buf, 0, buf.length); - - checkLength(decoded.length, compressedLimit, AlertDescription.record_overflow); - - /* - * TODO RFC5264 6.2.2. Implementation note: Decompression functions are responsible for - * ensuring that messages cannot cause internal buffer overflows. - */ - OutputStream cOut = readCompression.decompress(buffer); - if (cOut != buffer) - { - cOut.write(decoded, 0, decoded.length); - cOut.flush(); - decoded = getBufferContents(); - } - - /* - * RFC 5264 6.2.2. If the decompression function encounters a TLSCompressed.fragment that - * would decompress to a length in excess of 2^14 bytes, it should report a fatal - * decompression failure error. - */ - checkLength(decoded.length, plaintextLimit, AlertDescription.decompression_failure); - - /* - * RFC 5264 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, - * or ChangeCipherSpec content types. - */ - if (decoded.length < 1 && type != ContentType.application_data) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - return decoded; - } - - protected void writeRecord(short type, byte[] plaintext, int plaintextOffset, int plaintextLength) - throws IOException - { - // Never send anything until a valid ClientHello has been received - if (writeVersion == null) - { - return; - } - - /* - * RFC 5264 6. Implementations MUST NOT send record types not defined in this document - * unless negotiated by some extension. - */ - checkType(type, AlertDescription.internal_error); - - /* - * RFC 5264 6.2.1 The length should not exceed 2^14. - */ - checkLength(plaintextLength, plaintextLimit, AlertDescription.internal_error); - - /* - * 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) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - if (type == ContentType.handshake) - { - updateHandshakeData(plaintext, plaintextOffset, plaintextLength); - } - - OutputStream cOut = writeCompression.compress(buffer); - - byte[] ciphertext; - if (cOut == buffer) - { - ciphertext = writeCipher.encodePlaintext(writeSeqNo++, type, plaintext, plaintextOffset, plaintextLength); - } - else - { - cOut.write(plaintext, plaintextOffset, plaintextLength); - cOut.flush(); - byte[] compressed = getBufferContents(); - - /* - * RFC5264 6.2.2. Compression must be lossless and may not increase the content length - * by more than 1024 bytes. - */ - checkLength(compressed.length, plaintextLength + 1024, AlertDescription.internal_error); - - ciphertext = writeCipher.encodePlaintext(writeSeqNo++, type, compressed, 0, compressed.length); - } - - /* - * RFC 5264 6.2.3. The length may not exceed 2^14 + 2048. - */ - checkLength(ciphertext.length, ciphertextLimit, AlertDescription.internal_error); - - byte[] record = new byte[ciphertext.length + 5]; - TlsUtils.writeUint8(type, record, 0); - TlsUtils.writeVersion(writeVersion, record, 1); - TlsUtils.writeUint16(ciphertext.length, record, 3); - System.arraycopy(ciphertext, 0, record, 5, ciphertext.length); - output.write(record); - output.flush(); - } - - void notifyHelloComplete() - { - this.handshakeHash = handshakeHash.notifyPRFDetermined(); - } - - TlsHandshakeHash getHandshakeHash() - { - return handshakeHash; - } - - TlsHandshakeHash prepareToFinish() - { - TlsHandshakeHash result = handshakeHash; - this.handshakeHash = handshakeHash.stopTracking(); - return result; - } - - void updateHandshakeData(byte[] message, int offset, int len) - { - handshakeHash.update(message, offset, len); - } - - protected void safeClose() - { - try - { - input.close(); - } - catch (IOException e) - { - } - - try - { - output.close(); - } - catch (IOException e) - { - } - } - - protected void flush() - throws IOException - { - output.flush(); - } - - private byte[] getBufferContents() - { - byte[] contents = buffer.toByteArray(); - buffer.reset(); - return contents; - } - - private static void checkType(short type, short alertDescription) - throws IOException - { - switch (type) - { - case ContentType.application_data: - case ContentType.alert: - case ContentType.change_cipher_spec: - case ContentType.handshake: - case ContentType.heartbeat: - break; - default: - throw new TlsFatalAlert(alertDescription); - } - } - - private static void checkLength(int length, int limit, short alertDescription) - throws IOException - { - if (length > limit) - { - throw new TlsFatalAlert(alertDescription); - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/SRPTlsClient.java b/core/src/main/java/org/bouncycastle/crypto/tls/SRPTlsClient.java deleted file mode 100644 index 15295ea8..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/SRPTlsClient.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.util.Hashtable; - -import org.bouncycastle.util.Arrays; - -public abstract class SRPTlsClient - extends AbstractTlsClient -{ - /** - * @deprecated use TlsSRPUtils.EXT_SRP instead - */ - public static final Integer EXT_SRP = TlsSRPUtils.EXT_SRP; - - protected byte[] identity; - protected 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) - { - 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_128_CBC_SHA }; - } - - public Hashtable getClientExtensions() - throws IOException - { - Hashtable clientExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(super.getClientExtensions()); - TlsSRPUtils.addSRPExtension(clientExtensions, this.identity); - return clientExtensions; - } - - public void processServerExtensions(Hashtable serverExtensions) - throws IOException - { - if (!TlsUtils.hasExpectedEmptyExtensionData(serverExtensions, TlsSRPUtils.EXT_SRP, AlertDescription.illegal_parameter)) - { - // No explicit guidance in RFC 5054 here; we allow an optional empty extension from server - } - } - - public TlsKeyExchange getKeyExchange() - throws IOException - { - - 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: - return createSRPKeyExchange(KeyExchangeAlgorithm.SRP); - - case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: - return createSRPKeyExchange(KeyExchangeAlgorithm.SRP_RSA); - - case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: - return createSRPKeyExchange(KeyExchangeAlgorithm.SRP_DSS); - - default: - /* - * Note: internal error here; the TlsProtocol implementation verifies that the - * server-selected cipher suite was in the list of client-offered cipher suites, so if - * we now can't produce an implementation, we shouldn't have offered it! - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public TlsCipher getCipher() - throws IOException - { - - 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: - return cipherFactory.createCipher(context, EncryptionAlgorithm._3DES_EDE_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_128_CBC, MACAlgorithm.hmac_sha1); - - case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: - return cipherFactory.createCipher(context, EncryptionAlgorithm.AES_256_CBC, MACAlgorithm.hmac_sha1); - - default: - /* - * Note: internal error here; the TlsProtocol implementation verifies that the - * server-selected cipher suite was in the list of client-offered cipher suites, so if - * we now can't produce an implementation, we shouldn't have offered it! - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - protected TlsKeyExchange createSRPKeyExchange(int keyExchange) - { - return new TlsSRPKeyExchange(keyExchange, supportedSignatureAlgorithms, identity, password); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/SRTPProtectionProfile.java b/core/src/main/java/org/bouncycastle/crypto/tls/SRTPProtectionProfile.java deleted file mode 100644 index 1faac960..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/SRTPProtectionProfile.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public class SRTPProtectionProfile -{ - /* - * RFC 5764 4.1.2. - */ - public static final int SRTP_AES128_CM_HMAC_SHA1_80 = 0x0001; - public static final int SRTP_AES128_CM_HMAC_SHA1_32 = 0x0002; - public static final int SRTP_NULL_HMAC_SHA1_80 = 0x0005; - public static final int SRTP_NULL_HMAC_SHA1_32 = 0x0006; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/SSL3Mac.java b/core/src/main/java/org/bouncycastle/crypto/tls/SSL3Mac.java deleted file mode 100644 index 7d838590..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/SSL3Mac.java +++ /dev/null @@ -1,114 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Mac; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.util.Arrays; - -/** - * HMAC implementation based on original internet draft for HMAC (RFC 2104) - * <p> - * The difference is that padding is concatenated versus XORed with the key - * <p> - * H(K + opad, H(K + ipad, text)) - */ -public class SSL3Mac - implements Mac -{ - private final static byte IPAD_BYTE = (byte)0x36; - private final static byte OPAD_BYTE = (byte)0x5C; - - static final byte[] IPAD = genPad(IPAD_BYTE, 48); - static final byte[] OPAD = genPad(OPAD_BYTE, 48); - - private Digest digest; - - private byte[] secret; - private int padLength; - - /** - * 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) - { - this.digest = digest; - - if (digest.getDigestSize() == 20) - { - this.padLength = 40; - } - else - { - this.padLength = 48; - } - } - - public String getAlgorithmName() - { - return digest.getAlgorithmName() + "/SSL3MAC"; - } - - public Digest getUnderlyingDigest() - { - return digest; - } - - public void init(CipherParameters params) - { - secret = Arrays.clone(((KeyParameter)params).getKey()); - - reset(); - } - - public int getMacSize() - { - return digest.getDigestSize(); - } - - public void update(byte in) - { - digest.update(in); - } - - public void update(byte[] in, int inOff, int len) - { - digest.update(in, inOff, len); - } - - public int doFinal(byte[] out, int outOff) - { - byte[] tmp = new byte[digest.getDigestSize()]; - digest.doFinal(tmp, 0); - - digest.update(secret, 0, secret.length); - digest.update(OPAD, 0, padLength); - digest.update(tmp, 0, tmp.length); - - int len = digest.doFinal(out, outOff); - - reset(); - - return len; - } - - /** - * Reset the mac generator. - */ - public void reset() - { - digest.reset(); - digest.update(secret, 0, secret.length); - digest.update(IPAD, 0, padLength); - } - - private static byte[] genPad(byte b, int count) - { - byte[] padding = new byte[count]; - Arrays.fill(padding, b); - return padding; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/SecurityParameters.java b/core/src/main/java/org/bouncycastle/crypto/tls/SecurityParameters.java deleted file mode 100644 index 6b0eb6db..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/SecurityParameters.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.util.Arrays; - -public class SecurityParameters -{ - int entity = -1; - int cipherSuite = -1; - short compressionAlgorithm = -1; - int prfAlgorithm = -1; - int verifyDataLength = -1; - byte[] masterSecret = null; - byte[] clientRandom = null; - byte[] serverRandom = null; - - // TODO Keep these internal, since it's maybe not the ideal place for them - short maxFragmentLength = -1; - boolean truncatedHMac = false; - boolean encryptThenMAC = false; - - void copySessionParametersFrom(SecurityParameters other) - { - this.entity = other.entity; - this.cipherSuite = other.cipherSuite; - this.compressionAlgorithm = other.compressionAlgorithm; - this.prfAlgorithm = other.prfAlgorithm; - this.verifyDataLength = other.verifyDataLength; - this.masterSecret = Arrays.clone(other.masterSecret); - } - - void clear() - { - if (this.masterSecret != null) - { - Arrays.fill(this.masterSecret, (byte)0); - this.masterSecret = null; - } - } - - /** - * @return {@link ConnectionEnd} - */ - public int getEntity() - { - return entity; - } - - /** - * @return {@link CipherSuite} - */ - public int getCipherSuite() - { - return cipherSuite; - } - - /** - * @return {@link CompressionMethod} - */ - public short getCompressionAlgorithm() - { - return compressionAlgorithm; - } - - /** - * @return {@link PRFAlgorithm} - */ - public int getPrfAlgorithm() - { - return prfAlgorithm; - } - - public int getVerifyDataLength() - { - return verifyDataLength; - } - - public byte[] getMasterSecret() - { - return masterSecret; - } - - public byte[] getClientRandom() - { - return clientRandom; - } - - public byte[] getServerRandom() - { - return serverRandom; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ServerDHParams.java b/core/src/main/java/org/bouncycastle/crypto/tls/ServerDHParams.java deleted file mode 100644 index c3050f1b..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ServerDHParams.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigInteger; - -import org.bouncycastle.crypto.params.DHParameters; -import org.bouncycastle.crypto.params.DHPublicKeyParameters; - -public class ServerDHParams -{ - protected DHPublicKeyParameters publicKey; - - public ServerDHParams(DHPublicKeyParameters publicKey) - { - if (publicKey == null) - { - throw new IllegalArgumentException("'publicKey' cannot be null"); - } - - this.publicKey = publicKey; - } - - public DHPublicKeyParameters getPublicKey() - { - return publicKey; - } - - /** - * Encode this {@link ServerDHParams} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) throws IOException - { - DHParameters dhParameters = publicKey.getParameters(); - BigInteger Ys = publicKey.getY(); - - TlsDHUtils.writeDHParameter(dhParameters.getP(), output); - TlsDHUtils.writeDHParameter(dhParameters.getG(), output); - TlsDHUtils.writeDHParameter(Ys, output); - } - - /** - * Parse a {@link ServerDHParams} from an {@link InputStream}. - * - * @param input - * the {@link InputStream} to parse from. - * @return a {@link ServerDHParams} object. - * @throws IOException - */ - public static ServerDHParams parse(InputStream input) throws IOException - { - BigInteger p = TlsDHUtils.readDHParameter(input); - BigInteger g = TlsDHUtils.readDHParameter(input); - BigInteger Ys = TlsDHUtils.readDHParameter(input); - - return new ServerDHParams(new DHPublicKeyParameters(Ys, new DHParameters(p, g))); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ServerName.java b/core/src/main/java/org/bouncycastle/crypto/tls/ServerName.java deleted file mode 100644 index df9a4395..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ServerName.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.bouncycastle.util.Strings; - -public class ServerName -{ - protected short nameType; - protected Object name; - - public ServerName(short nameType, Object name) - { - if (!isCorrectType(nameType, name)) - { - throw new IllegalArgumentException("'name' is not an instance of the correct type"); - } - - this.nameType = nameType; - this.name = name; - } - - public short getNameType() - { - return nameType; - } - - public Object getName() - { - return name; - } - - public String getHostName() - { - if (!isCorrectType(NameType.host_name, name)) - { - throw new IllegalStateException("'name' is not a HostName string"); - } - return (String)name; - } - - /** - * Encode this {@link ServerName} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) throws IOException - { - TlsUtils.writeUint8(nameType, output); - - switch (nameType) - { - case NameType.host_name: - byte[] utf8Encoding = Strings.toUTF8ByteArray((String)name); - if (utf8Encoding.length < 1) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - TlsUtils.writeOpaque16(utf8Encoding, output); - break; - default: - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - /** - * Parse a {@link ServerName} from an {@link InputStream}. - * - * @param input - * the {@link InputStream} to parse from. - * @return a {@link ServerName} object. - * @throws IOException - */ - public static ServerName parse(InputStream input) throws IOException - { - short name_type = TlsUtils.readUint8(input); - Object name; - - switch (name_type) - { - case NameType.host_name: - { - byte[] utf8Encoding = TlsUtils.readOpaque16(input); - if (utf8Encoding.length < 1) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - name = Strings.fromUTF8ByteArray(utf8Encoding); - break; - } - default: - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - return new ServerName(name_type, name); - } - - protected static boolean isCorrectType(short nameType, Object name) - { - switch (nameType) - { - case NameType.host_name: - return name instanceof String; - default: - throw new IllegalArgumentException("'name' is an unsupported value"); - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ServerNameList.java b/core/src/main/java/org/bouncycastle/crypto/tls/ServerNameList.java deleted file mode 100644 index 1dc81f01..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ServerNameList.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Vector; - -public class ServerNameList -{ - protected Vector serverNameList; - - /** - * @param serverNameList a {@link Vector} of {@link ServerName}. - */ - public ServerNameList(Vector serverNameList) - { - if (serverNameList == null || serverNameList.isEmpty()) - { - throw new IllegalArgumentException("'serverNameList' must not be null or empty"); - } - - this.serverNameList = serverNameList; - } - - /** - * @return a {@link Vector} of {@link ServerName}. - */ - public Vector getServerNameList() - { - return serverNameList; - } - - /** - * Encode this {@link ServerNameList} to an {@link OutputStream}. - * - * @param output - * the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) throws IOException - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - for (int i = 0; i < serverNameList.size(); ++i) - { - ServerName entry = (ServerName)serverNameList.elementAt(i); - entry.encode(buf); - } - - TlsUtils.checkUint16(buf.size()); - TlsUtils.writeUint16(buf.size(), output); - buf.writeTo(output); - } - - /** - * Parse a {@link ServerNameList} from an {@link InputStream}. - * - * @param input - * the {@link InputStream} to parse from. - * @return a {@link ServerNameList} object. - * @throws IOException - */ - public static ServerNameList parse(InputStream input) throws IOException - { - int length = TlsUtils.readUint16(input); - if (length < 1) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - byte[] data = TlsUtils.readFully(length, input); - - ByteArrayInputStream buf = new ByteArrayInputStream(data); - - Vector server_name_list = new Vector(); - while (buf.available() > 0) - { - ServerName entry = ServerName.parse(buf); - server_name_list.addElement(entry); - } - - return new ServerNameList(server_name_list); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/ServerOnlyTlsAuthentication.java b/core/src/main/java/org/bouncycastle/crypto/tls/ServerOnlyTlsAuthentication.java deleted file mode 100644 index eccbb3f6..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/ServerOnlyTlsAuthentication.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public abstract class ServerOnlyTlsAuthentication - implements TlsAuthentication -{ - public final TlsCredentials getClientCredentials(CertificateRequest certificateRequest) - { - return null; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/SessionParameters.java b/core/src/main/java/org/bouncycastle/crypto/tls/SessionParameters.java deleted file mode 100644 index 68412f84..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/SessionParameters.java +++ /dev/null @@ -1,142 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Hashtable; - -import org.bouncycastle.util.Arrays; - -public final class SessionParameters -{ - public static final class Builder - { - private int cipherSuite = -1; - private short compressionAlgorithm = -1; - private byte[] masterSecret = null; - private Certificate peerCertificate = null; - private byte[] encodedServerExtensions = null; - - public Builder() - { - } - - public SessionParameters build() - { - validate(this.cipherSuite >= 0, "cipherSuite"); - validate(this.compressionAlgorithm >= 0, "compressionAlgorithm"); - validate(this.masterSecret != null, "masterSecret"); - return new SessionParameters(cipherSuite, compressionAlgorithm, masterSecret, peerCertificate, - encodedServerExtensions); - } - - public Builder setCipherSuite(int cipherSuite) - { - this.cipherSuite = cipherSuite; - return this; - } - - public Builder setCompressionAlgorithm(short compressionAlgorithm) - { - this.compressionAlgorithm = compressionAlgorithm; - return this; - } - - public Builder setMasterSecret(byte[] masterSecret) - { - this.masterSecret = masterSecret; - return this; - } - - public Builder setPeerCertificate(Certificate peerCertificate) - { - this.peerCertificate = peerCertificate; - return this; - } - - public Builder setServerExtensions(Hashtable serverExtensions) - throws IOException - { - if (serverExtensions == null) - { - encodedServerExtensions = null; - } - else - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - TlsProtocol.writeExtensions(buf, serverExtensions); - encodedServerExtensions = buf.toByteArray(); - } - return this; - } - - private void validate(boolean condition, String parameter) - { - if (!condition) - { - throw new IllegalStateException("Required session parameter '" + parameter + "' not configured"); - } - } - } - - private int cipherSuite; - private short compressionAlgorithm; - private byte[] masterSecret; - private Certificate peerCertificate; - private byte[] encodedServerExtensions; - - private SessionParameters(int cipherSuite, short compressionAlgorithm, byte[] masterSecret, - Certificate peerCertificate, byte[] encodedServerExtensions) - { - this.cipherSuite = cipherSuite; - this.compressionAlgorithm = compressionAlgorithm; - this.masterSecret = Arrays.clone(masterSecret); - this.peerCertificate = peerCertificate; - this.encodedServerExtensions = encodedServerExtensions; - } - - public void clear() - { - if (this.masterSecret != null) - { - Arrays.fill(this.masterSecret, (byte)0); - } - } - - public SessionParameters copy() - { - return new SessionParameters(cipherSuite, compressionAlgorithm, masterSecret, peerCertificate, - encodedServerExtensions); - } - - public int getCipherSuite() - { - return cipherSuite; - } - - public short getCompressionAlgorithm() - { - return compressionAlgorithm; - } - - public byte[] getMasterSecret() - { - return masterSecret; - } - - public Certificate getPeerCertificate() - { - return peerCertificate; - } - - public Hashtable readServerExtensions() throws IOException - { - if (encodedServerExtensions == null) - { - return null; - } - - ByteArrayInputStream buf = new ByteArrayInputStream(encodedServerExtensions); - return TlsProtocol.readExtensions(buf); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/SignatureAlgorithm.java b/core/src/main/java/org/bouncycastle/crypto/tls/SignatureAlgorithm.java deleted file mode 100644 index 820c80cd..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/SignatureAlgorithm.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 5246 7.4.1.4.1 (in RFC 2246, there were no specific values assigned) - */ -public class SignatureAlgorithm -{ - public static final short anonymous = 0; - public static final short rsa = 1; - public static final short dsa = 2; - public static final short ecdsa = 3; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/SignatureAndHashAlgorithm.java b/core/src/main/java/org/bouncycastle/crypto/tls/SignatureAndHashAlgorithm.java deleted file mode 100644 index 9404a72f..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/SignatureAndHashAlgorithm.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * RFC 5246 7.4.1.4.1 - */ -public class SignatureAndHashAlgorithm -{ - protected short hash; - protected short signature; - - /** - * @param hash {@link HashAlgorithm} - * @param signature {@link SignatureAlgorithm} - */ - public SignatureAndHashAlgorithm(short hash, short signature) - { - if (!TlsUtils.isValidUint8(hash)) - { - throw new IllegalArgumentException("'hash' should be a uint8"); - } - if (!TlsUtils.isValidUint8(signature)) - { - throw new IllegalArgumentException("'signature' should be a uint8"); - } - if (signature == SignatureAlgorithm.anonymous) - { - throw new IllegalArgumentException("'signature' MUST NOT be \"anonymous\""); - } - - this.hash = hash; - this.signature = signature; - } - - /** - * @return {@link HashAlgorithm} - */ - public short getHash() - { - return hash; - } - - /** - * @return {@link SignatureAlgorithm} - */ - public short getSignature() - { - return signature; - } - - public boolean equals(Object obj) - { - if (!(obj instanceof SignatureAndHashAlgorithm)) - { - return false; - } - SignatureAndHashAlgorithm other = (SignatureAndHashAlgorithm)obj; - return other.getHash() == getHash() && other.getSignature() == getSignature(); - } - - public int hashCode() - { - return (getHash() << 16) | getSignature(); - } - - /** - * Encode this {@link SignatureAndHashAlgorithm} to an {@link OutputStream}. - * - * @param output the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) - throws IOException - { - TlsUtils.writeUint8(getHash(), output); - TlsUtils.writeUint8(getSignature(), output); - } - - /** - * Parse a {@link SignatureAndHashAlgorithm} from an {@link InputStream}. - * - * @param input the {@link InputStream} to parse from. - * @return a {@link SignatureAndHashAlgorithm} object. - * @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/core/src/main/java/org/bouncycastle/crypto/tls/SignerInputBuffer.java b/core/src/main/java/org/bouncycastle/crypto/tls/SignerInputBuffer.java deleted file mode 100644 index 8293135f..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/SignerInputBuffer.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayOutputStream; - -import org.bouncycastle.crypto.Signer; - -class SignerInputBuffer extends ByteArrayOutputStream -{ - void updateSigner(Signer s) - { - s.update(this.buf, 0, count); - } -}
\ No newline at end of file diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataEntry.java b/core/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataEntry.java deleted file mode 100644 index 4080aaa9..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataEntry.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public class SupplementalDataEntry -{ - protected int dataType; - protected byte[] data; - - public SupplementalDataEntry(int dataType, byte[] data) - { - this.dataType = dataType; - this.data = data; - } - - public int getDataType() - { - return dataType; - } - - public byte[] getData() - { - return data; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataType.java b/core/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataType.java deleted file mode 100644 index 218f36b1..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/SupplementalDataType.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 4680 - */ -public class SupplementalDataType -{ - /* - * RFC 4681 - */ - public static final int user_mapping_data = 0; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsAEADCipher.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsAEADCipher.java deleted file mode 100644 index bb9306a1..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsAEADCipher.java +++ /dev/null @@ -1,193 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -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 -{ - protected TlsContext context; - protected int macSize; - protected int nonce_explicit_length; - - protected AEADBlockCipher encryptCipher; - protected AEADBlockCipher decryptCipher; - - protected byte[] encryptImplicitNonce, decryptImplicitNonce; - - public TlsAEADCipher(TlsContext context, AEADBlockCipher clientWriteCipher, AEADBlockCipher serverWriteCipher, - int cipherKeySize, int macSize) throws IOException - { - if (!TlsUtils.isTLSv12(context)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - this.context = context; - this.macSize = macSize; - - // NOTE: Valid for RFC 5288/6655 ciphers but may need review for other AEAD ciphers - this.nonce_explicit_length = 8; - - // TODO SecurityParameters.fixed_iv_length - int fixed_iv_length = 4; - - int key_block_size = (2 * cipherKeySize) + (2 * fixed_iv_length); - - byte[] key_block = TlsUtils.calculateKeyBlock(context, key_block_size); - - int offset = 0; - - KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize); - offset += cipherKeySize; - KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize); - offset += cipherKeySize; - byte[] client_write_IV = Arrays.copyOfRange(key_block, offset, offset + fixed_iv_length); - offset += fixed_iv_length; - byte[] server_write_IV = Arrays.copyOfRange(key_block, offset, offset + fixed_iv_length); - offset += fixed_iv_length; - - if (offset != key_block_size) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - KeyParameter encryptKey, decryptKey; - 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 - { - this.encryptCipher = clientWriteCipher; - this.decryptCipher = serverWriteCipher; - this.encryptImplicitNonce = client_write_IV; - this.decryptImplicitNonce = server_write_IV; - encryptKey = client_write_key; - decryptKey = server_write_key; - } - - byte[] dummyNonce = new byte[fixed_iv_length + nonce_explicit_length]; - - this.encryptCipher.init(true, new AEADParameters(encryptKey, 8 * macSize, dummyNonce)); - this.decryptCipher.init(false, new AEADParameters(decryptKey, 8 * macSize, dummyNonce)); - } - - 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 - { - byte[] nonce = new byte[this.encryptImplicitNonce.length + nonce_explicit_length]; - System.arraycopy(encryptImplicitNonce, 0, nonce, 0, encryptImplicitNonce.length); - - /* - * RFC 5288/6655 The nonce_explicit MAY be the 64-bit sequence number. - * - * (May need review for other AEAD ciphers). - */ - TlsUtils.writeUint64(seqNo, nonce, encryptImplicitNonce.length); - - int plaintextOffset = offset; - int plaintextLength = len; - int ciphertextLength = encryptCipher.getOutputSize(plaintextLength); - - byte[] output = new byte[nonce_explicit_length + ciphertextLength]; - System.arraycopy(nonce, encryptImplicitNonce.length, output, 0, nonce_explicit_length); - int outputPos = nonce_explicit_length; - - byte[] additionalData = getAdditionalData(seqNo, type, plaintextLength); - AEADParameters parameters = new AEADParameters(null, 8 * macSize, nonce, additionalData); - - try - { - encryptCipher.init(true, parameters); - outputPos += encryptCipher.processBytes(plaintext, plaintextOffset, plaintextLength, output, outputPos); - outputPos += encryptCipher.doFinal(output, outputPos); - } - catch (Exception e) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - if (outputPos != output.length) - { - // NOTE: Existing AEAD cipher implementations all give exact output lengths - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - return output; - } - - public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) - throws IOException - { - if (getPlaintextLimit(len) < 0) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - byte[] nonce = new byte[this.decryptImplicitNonce.length + nonce_explicit_length]; - System.arraycopy(decryptImplicitNonce, 0, nonce, 0, decryptImplicitNonce.length); - System.arraycopy(ciphertext, offset, nonce, decryptImplicitNonce.length, nonce_explicit_length); - - int ciphertextOffset = offset + nonce_explicit_length; - int ciphertextLength = len - nonce_explicit_length; - int plaintextLength = decryptCipher.getOutputSize(ciphertextLength); - - byte[] output = new byte[plaintextLength]; - int outputPos = 0; - - byte[] additionalData = getAdditionalData(seqNo, type, plaintextLength); - AEADParameters parameters = new AEADParameters(null, 8 * macSize, nonce, additionalData); - - try - { - decryptCipher.init(false, parameters); - outputPos += decryptCipher.processBytes(ciphertext, ciphertextOffset, ciphertextLength, output, outputPos); - outputPos += decryptCipher.doFinal(output, outputPos); - } - catch (Exception e) - { - throw new TlsFatalAlert(AlertDescription.bad_record_mac); - } - - if (outputPos != output.length) - { - // NOTE: Existing AEAD cipher implementations all give exact output lengths - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - return output; - } - - protected byte[] getAdditionalData(long seqNo, short type, int len) - throws IOException - { - /* - * additional_data = seq_num + TLSCompressed.type + TLSCompressed.version + - * TLSCompressed.length - */ - - byte[] additional_data = new byte[13]; - TlsUtils.writeUint64(seqNo, additional_data, 0); - TlsUtils.writeUint8(type, additional_data, 8); - TlsUtils.writeVersion(context.getServerVersion(), additional_data, 9); - TlsUtils.writeUint16(len, additional_data, 11); - - return additional_data; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsAgreementCredentials.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsAgreementCredentials.java deleted file mode 100644 index 525cdb38..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsAgreementCredentials.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; - -public interface TlsAgreementCredentials - extends TlsCredentials -{ - byte[] generateAgreement(AsymmetricKeyParameter peerPublicKey) - throws IOException; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsAuthentication.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsAuthentication.java deleted file mode 100755 index 62c2616e..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsAuthentication.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -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; - - /** - * 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; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsBlockCipher.java deleted file mode 100644 index 9a79226c..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsBlockCipher.java +++ /dev/null @@ -1,386 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.security.SecureRandom; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.crypto.params.ParametersWithIV; -import org.bouncycastle.util.Arrays; - -/** - * A generic TLS 1.0-1.2 / SSLv3 block cipher. This can be used for AES or 3DES for example. - */ -public class TlsBlockCipher - implements TlsCipher -{ - protected TlsContext context; - protected byte[] randomData; - protected boolean useExplicitIV; - private boolean encryptThenMAC; - - protected BlockCipher encryptCipher; - protected BlockCipher decryptCipher; - - protected TlsMac writeMac; - protected TlsMac readMac; - - public TlsMac getWriteMac() - { - return writeMac; - } - - public TlsMac getReadMac() - { - return readMac; - } - - public TlsBlockCipher(TlsContext context, BlockCipher clientWriteCipher, BlockCipher serverWriteCipher, - Digest clientWriteDigest, Digest serverWriteDigest, int cipherKeySize) throws IOException - { - this.context = context; - - this.randomData = new byte[256]; - context.getNonceRandomGenerator().nextBytes(randomData); - - this.useExplicitIV = TlsUtils.isTLSv11(context); - this.encryptThenMAC = context.getSecurityParameters().encryptThenMAC; - - int key_block_size = (2 * cipherKeySize) + clientWriteDigest.getDigestSize() - + serverWriteDigest.getDigestSize(); - - // From TLS 1.1 onwards, block ciphers don't need client_write_IV - if (!useExplicitIV) - { - key_block_size += clientWriteCipher.getBlockSize() + serverWriteCipher.getBlockSize(); - } - - byte[] key_block = TlsUtils.calculateKeyBlock(context, key_block_size); - - int offset = 0; - - TlsMac clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, - clientWriteDigest.getDigestSize()); - offset += clientWriteDigest.getDigestSize(); - TlsMac serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, - serverWriteDigest.getDigestSize()); - offset += serverWriteDigest.getDigestSize(); - - KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize); - offset += cipherKeySize; - KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize); - offset += cipherKeySize; - - byte[] client_write_IV, server_write_IV; - if (useExplicitIV) - { - client_write_IV = new byte[clientWriteCipher.getBlockSize()]; - server_write_IV = new byte[serverWriteCipher.getBlockSize()]; - } - 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) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - CipherParameters encryptParams, decryptParams; - 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 - { - this.writeMac = clientWriteMac; - this.readMac = serverWriteMac; - this.encryptCipher = clientWriteCipher; - this.decryptCipher = serverWriteCipher; - encryptParams = new ParametersWithIV(client_write_key, client_write_IV); - decryptParams = new ParametersWithIV(server_write_key, server_write_IV); - } - - this.encryptCipher.init(true, encryptParams); - this.decryptCipher.init(false, decryptParams); - } - - public int getPlaintextLimit(int ciphertextLimit) - { - int blockSize = encryptCipher.getBlockSize(); - int macSize = writeMac.getSize(); - - int plaintextLimit = ciphertextLimit; - - // An explicit IV consumes 1 block - if (useExplicitIV) - { - plaintextLimit -= blockSize; - } - - // Leave room for the MAC, and require block-alignment - if (encryptThenMAC) - { - plaintextLimit -= macSize; - plaintextLimit -= plaintextLimit % blockSize; - } - else - { - plaintextLimit -= plaintextLimit % blockSize; - plaintextLimit -= macSize; - } - - // Minimum 1 byte of padding - --plaintextLimit; - - return plaintextLimit; - } - - public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) - { - int blockSize = encryptCipher.getBlockSize(); - int macSize = writeMac.getSize(); - - ProtocolVersion version = context.getServerVersion(); - - int enc_input_length = len; - if (!encryptThenMAC) - { - enc_input_length += macSize; - } - - int padding_length = blockSize - 1 - (enc_input_length % blockSize); - - // TODO[DTLS] Consider supporting in DTLS (without exceeding send limit though) - 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); - padding_length += actualExtraPadBlocks * blockSize; - } - - int totalSize = len + macSize + padding_length + 1; - if (useExplicitIV) - { - totalSize += blockSize; - } - - byte[] outBuf = new byte[totalSize]; - int outOff = 0; - - if (useExplicitIV) - { - byte[] explicitIV = new byte[blockSize]; - context.getNonceRandomGenerator().nextBytes(explicitIV); - - encryptCipher.init(true, new ParametersWithIV(null, explicitIV)); - - System.arraycopy(explicitIV, 0, outBuf, outOff, blockSize); - outOff += blockSize; - } - - int blocks_start = outOff; - - System.arraycopy(plaintext, offset, outBuf, outOff, len); - outOff += len; - - if (!encryptThenMAC) - { - byte[] mac = writeMac.calculateMac(seqNo, type, plaintext, offset, len); - System.arraycopy(mac, 0, outBuf, outOff, mac.length); - outOff += mac.length; - } - - for (int i = 0; i <= padding_length; i++) - { - outBuf[outOff++] = (byte)padding_length; - } - - for (int i = blocks_start; i < outOff; i += blockSize) - { - encryptCipher.processBlock(outBuf, i, outBuf, i); - } - - if (encryptThenMAC) - { - byte[] mac = writeMac.calculateMac(seqNo, type, outBuf, 0, outOff); - System.arraycopy(mac, 0, outBuf, outOff, mac.length); - outOff += mac.length; - } - -// assert outBuf.length == outOff; - - return outBuf; - } - - 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 = blockSize; - if (encryptThenMAC) - { - minLen += macSize; - } - else - { - minLen = Math.max(minLen, macSize + 1); - } - - if (useExplicitIV) - { - minLen += blockSize; - } - - if (len < minLen) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - int blocks_length = len; - if (encryptThenMAC) - { - blocks_length -= macSize; - } - - if (blocks_length % blockSize != 0) - { - throw new TlsFatalAlert(AlertDescription.decryption_failed); - } - - if (encryptThenMAC) - { - int end = offset + len; - byte[] receivedMac = Arrays.copyOfRange(ciphertext, end - macSize, end); - byte[] calculatedMac = readMac.calculateMac(seqNo, type, ciphertext, offset, len - macSize); - - boolean badMac = !Arrays.constantTimeAreEqual(calculatedMac, receivedMac); - - if (badMac) - { - throw new TlsFatalAlert(AlertDescription.bad_record_mac); - } - } - - if (useExplicitIV) - { - decryptCipher.init(false, new ParametersWithIV(null, ciphertext, offset, blockSize)); - - offset += blockSize; - blocks_length -= blockSize; - } - - for (int i = 0; i < blocks_length; i += blockSize) - { - decryptCipher.processBlock(ciphertext, offset + i, ciphertext, offset + i); - } - - // If there's anything wrong with the padding, this will return zero - int totalPad = checkPaddingConstantTime(ciphertext, offset, blocks_length, blockSize, encryptThenMAC ? 0 : macSize); - - int dec_output_length = blocks_length - totalPad; - - if (!encryptThenMAC) - { - dec_output_length -= macSize; - int macInputLen = dec_output_length; - int macOff = offset + macInputLen; - byte[] receivedMac = Arrays.copyOfRange(ciphertext, macOff, macOff + macSize); - byte[] calculatedMac = readMac.calculateMacConstantTime(seqNo, type, ciphertext, offset, macInputLen, - blocks_length - macSize, randomData); - - boolean badMac = !Arrays.constantTimeAreEqual(calculatedMac, receivedMac); - - if (badMac || totalPad == 0) - { - throw new TlsFatalAlert(AlertDescription.bad_record_mac); - } - } - - return Arrays.copyOfRange(ciphertext, offset, offset + dec_output_length); - } - - 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; - int totalPad = padlen + 1; - - int dummyIndex = 0; - byte padDiff = 0; - - if ((TlsUtils.isSSL(context) && totalPad > blockSize) || (macSize + totalPad > len)) - { - totalPad = 0; - } - else - { - int padPos = end - totalPad; - do - { - padDiff |= (buf[padPos++] ^ lastByte); - } - while (padPos < end); - - dummyIndex = totalPad; - - if (padDiff != 0) - { - totalPad = 0; - } - } - - // Run some extra dummy checks so the number of checks is always constant - { - byte[] dummyPad = randomData; - while (dummyIndex < 256) - { - padDiff |= (dummyPad[dummyIndex++] ^ lastByte); - } - // Ensure the above loop is not eliminated - dummyPad[0] ^= padDiff; - } - - return totalPad; - } - - protected int chooseExtraPadBlocks(SecureRandom r, int max) - { - // return r.nextInt(max + 1); - - int x = r.nextInt(); - int n = lowestBitSet(x); - return Math.min(n, max); - } - - protected int lowestBitSet(int x) - { - if (x == 0) - { - return 32; - } - - int n = 0; - while ((x & 1) == 0) - { - ++n; - x >>= 1; - } - return n; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsCipher.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsCipher.java deleted file mode 100644 index 2f0af080..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsCipher.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public interface TlsCipher -{ - int getPlaintextLimit(int ciphertextLimit); - - 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; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsCipherFactory.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsCipherFactory.java deleted file mode 100644 index 74074747..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsCipherFactory.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public interface TlsCipherFactory -{ - /** - * See enumeration classes EncryptionAlgorithm, MACAlgorithm for appropriate argument values - */ - TlsCipher createCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) - throws IOException; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsClient.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsClient.java deleted file mode 100644 index 8b29c1f7..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsClient.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.util.Hashtable; -import java.util.Vector; - -public interface TlsClient - extends TlsPeer -{ - void init(TlsClientContext context); - - /** - * Return the session this client wants to resume, if any. Note that the peer's certificate - * chain for the session (if any) may need to be periodically revalidated. - * - * @return A {@link TlsSession} representing the resumable session to be used for this - * connection, or null to use a new session. - * @see SessionParameters#getPeerCertificate() - */ - TlsSession getSessionToResume(); - - ProtocolVersion getClientHelloRecordLayerVersion(); - - ProtocolVersion getClientVersion(); - - int[] getCipherSuites(); - - short[] getCompressionMethods(); - - // Hashtable is (Integer -> byte[]) - Hashtable getClientExtensions() - throws IOException; - - void notifyServerVersion(ProtocolVersion selectedVersion) - throws IOException; - - /** - * Notifies the client of the session_id sent in the ServerHello. - * - * @param sessionID - * @see TlsContext#getResumableSession() - */ - void notifySessionID(byte[] sessionID); - - void notifySelectedCipherSuite(int selectedCipherSuite); - - void notifySelectedCompressionMethod(short selectedCompressionMethod); - - // Hashtable is (Integer -> byte[]) - void processServerExtensions(Hashtable serverExtensions) - throws IOException; - - // Vector is (SupplementalDataEntry) - void processServerSupplementalData(Vector serverSupplementalData) - throws IOException; - - TlsKeyExchange getKeyExchange() - throws IOException; - - TlsAuthentication getAuthentication() - throws IOException; - - // Vector is (SupplementalDataEntry) - Vector getClientSupplementalData() - throws IOException; - - /** - * RFC 5077 3.3. NewSessionTicket Handshake Message - * <p> - * 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. <i>RFC 5077 4. Recommended Ticket Construction</i>. - * - * @param newSessionTicket The ticket. - * @throws IOException - */ - void notifyNewSessionTicket(NewSessionTicket newSessionTicket) - throws IOException; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsClientContext.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsClientContext.java deleted file mode 100644 index db9f15b7..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsClientContext.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public interface TlsClientContext - extends TlsContext -{ -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsClientContextImpl.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsClientContextImpl.java deleted file mode 100644 index b3201443..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsClientContextImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.security.SecureRandom; - -class TlsClientContextImpl - extends AbstractTlsContext - implements TlsClientContext -{ - TlsClientContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) - { - super(secureRandom, securityParameters); - } - - public boolean isServer() - { - return false; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsClientProtocol.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsClientProtocol.java deleted file mode 100644 index d4d19ef7..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsClientProtocol.java +++ /dev/null @@ -1,917 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.SecureRandom; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import org.bouncycastle.crypto.prng.ThreadedSeedGenerator; -import org.bouncycastle.util.Arrays; - -public class TlsClientProtocol - extends TlsProtocol -{ - protected TlsClient tlsClient = null; - protected TlsClientContextImpl tlsClientContext = null; - - protected byte[] selectedSessionID = null; - - protected TlsKeyExchange keyExchange = null; - protected TlsAuthentication authentication = null; - - protected CertificateStatus certificateStatus = null; - protected CertificateRequest certificateRequest = null; - - 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. - */ - ThreadedSeedGenerator tsg = new ThreadedSeedGenerator(); - SecureRandom random = new SecureRandom(); - - /* - * Hopefully, 20 bytes in fast mode are good enough. - */ - random.setSeed(tsg.generateSeed(20, true)); - - return random; - } - - /** - * @deprecated use alternate constructor taking an explicit {@link SecureRandom} - */ - public TlsClientProtocol(InputStream input, OutputStream output) - { - this(input, output, createSecureRandom()); - } - - public TlsClientProtocol(InputStream input, OutputStream output, SecureRandom secureRandom) - { - super(input, output, secureRandom); - } - - /** - * Initiates a TLS handshake in the role of client - * - * @param tlsClient The {@link TlsClient} to use for the handshake. - * @throws IOException If handshake was not successful. - */ - public void connect(TlsClient tlsClient) throws IOException - { - if (tlsClient == null) - { - throw new IllegalArgumentException("'tlsClient' cannot be null"); - } - if (this.tlsClient != null) - { - throw new IllegalStateException("'connect' can only be called once"); - } - - this.tlsClient = tlsClient; - - this.securityParameters = new SecurityParameters(); - this.securityParameters.entity = ConnectionEnd.client; - - this.tlsClientContext = new TlsClientContextImpl(secureRandom, securityParameters); - - this.securityParameters.clientRandom = createRandomBlock(tlsClient.shouldUseGMTUnixTime(), - tlsClientContext.getNonceRandomGenerator()); - - this.tlsClient.init(tlsClientContext); - this.recordStream.init(tlsClientContext); - - TlsSession sessionToResume = tlsClient.getSessionToResume(); - if (sessionToResume != null) - { - SessionParameters sessionParameters = sessionToResume.exportSessionParameters(); - if (sessionParameters != null) - { - this.tlsSession = sessionToResume; - this.sessionParameters = sessionParameters; - } - } - - sendClientHelloMessage(); - this.connection_state = CS_CLIENT_HELLO; - - completeHandshake(); - } - - protected void cleanupHandshake() - { - super.cleanupHandshake(); - - this.selectedSessionID = null; - this.keyExchange = null; - this.authentication = null; - this.certificateStatus = null; - this.certificateRequest = null; - } - - protected AbstractTlsContext getContext() - { - return tlsClientContext; - } - - protected TlsPeer getPeer() - { - return tlsClient; - } - - protected void handleHandshakeMessage(short type, byte[] data) - throws IOException - { - ByteArrayInputStream buf = new ByteArrayInputStream(data); - - if (this.resumedSession) - { - if (type != HandshakeType.finished || this.connection_state != CS_SERVER_HELLO) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - processFinishedMessage(buf); - this.connection_state = CS_SERVER_FINISHED; - - sendFinishedMessage(); - this.connection_state = CS_CLIENT_FINISHED; - this.connection_state = CS_END; - - return; - } - - 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: - { - // Parse the Certificate message and send to cipher suite - - this.peerCertificate = Certificate.parse(buf); - - assertEmpty(buf); - - // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus - if (this.peerCertificate == null || this.peerCertificate.isEmpty()) - { - this.allowCertificateStatus = false; - } - - this.keyExchange.processServerCertificate(this.peerCertificate); - - this.authentication = tlsClient.getAuthentication(); - this.authentication.notifyServerCertificate(this.peerCertificate); - - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - this.connection_state = CS_SERVER_CERTIFICATE; - break; - } - case HandshakeType.certificate_status: - { - switch (this.connection_state) - { - case CS_SERVER_CERTIFICATE: - { - if (!this.allowCertificateStatus) - { - /* - * RFC 3546 3.6. If a server returns a "CertificateStatus" message, then the - * server MUST have included an extension of type "status_request" with empty - * "extension_data" in the extended server hello.. - */ - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - this.certificateStatus = CertificateStatus.parse(buf); - - assertEmpty(buf); - - // TODO[RFC 3546] Figure out how to provide this to the client/authentication. - - this.connection_state = CS_CERTIFICATE_STATUS; - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - break; - } - case HandshakeType.finished: - { - 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. - */ - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - // NB: Fall through to next case label - } - case CS_SERVER_SESSION_TICKET: - { - processFinishedMessage(buf); - this.connection_state = CS_SERVER_FINISHED; - this.connection_state = CS_END; - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - break; - } - case HandshakeType.server_hello: - { - switch (this.connection_state) - { - case CS_CLIENT_HELLO: - { - receiveServerHelloMessage(buf); - this.connection_state = CS_SERVER_HELLO; - - if (this.securityParameters.maxFragmentLength >= 0) - { - int plainTextLimit = 1 << (8 + this.securityParameters.maxFragmentLength); - recordStream.setPlaintextLimit(plainTextLimit); - } - - this.securityParameters.prfAlgorithm = getPRFAlgorithm(getContext(), - this.securityParameters.getCipherSuite()); - - /* - * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify - * verify_data_length has a verify_data_length equal to 12. This includes all - * existing cipher suites. - */ - this.securityParameters.verifyDataLength = 12; - - this.recordStream.notifyHelloComplete(); - - if (this.resumedSession) - { - this.securityParameters.masterSecret = Arrays.clone(this.sessionParameters.getMasterSecret()); - this.recordStream.setPendingConnectionState(getPeer().getCompression(), getPeer().getCipher()); - - sendChangeCipherSpecMessage(); - } - else - { - invalidateSession(); - - if (this.selectedSessionID.length > 0) - { - this.tlsSession = new TlsSessionImpl(this.selectedSessionID, null); - } - } - - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - break; - } - case HandshakeType.supplemental_data: - { - switch (this.connection_state) - { - case CS_SERVER_HELLO: - { - handleSupplementalData(readSupplementalDataMessage(buf)); - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - break; - } - case HandshakeType.server_hello_done: - { - switch (this.connection_state) - { - case CS_SERVER_HELLO: - { - handleSupplementalData(null); - // NB: Fall through to next case label - } - case CS_SERVER_SUPPLEMENTAL_DATA: - { - // There was no server certificate message; check it's OK - this.keyExchange.skipServerCredentials(); - this.authentication = null; - - // NB: Fall through to next case label - } - case CS_SERVER_CERTIFICATE: - case CS_CERTIFICATE_STATUS: - { - // There was no server key exchange message; check it's OK - this.keyExchange.skipServerKeyExchange(); - - // NB: Fall through to next case label - } - case CS_SERVER_KEY_EXCHANGE: - case CS_CERTIFICATE_REQUEST: - { - assertEmpty(buf); - - this.connection_state = CS_SERVER_HELLO_DONE; - - this.recordStream.getHandshakeHash().sealHashAlgorithms(); - - Vector clientSupplementalData = tlsClient.getClientSupplementalData(); - if (clientSupplementalData != null) - { - sendSupplementalDataMessage(clientSupplementalData); - } - this.connection_state = CS_CLIENT_SUPPLEMENTAL_DATA; - - TlsCredentials clientCreds = null; - if (certificateRequest == null) - { - this.keyExchange.skipClientCredentials(); - } - else - { - clientCreds = this.authentication.getClientCredentials(certificateRequest); - - if (clientCreds == null) - { - this.keyExchange.skipClientCredentials(); - - /* - * RFC 5246 If no suitable certificate is available, the client MUST send a - * certificate message containing no certificates. - * - * NOTE: In previous RFCs, this was SHOULD instead of MUST. - */ - sendCertificateMessage(Certificate.EMPTY_CHAIN); - } - else - { - this.keyExchange.processClientCredentials(clientCreds); - - sendCertificateMessage(clientCreds.getCertificate()); - } - } - - this.connection_state = CS_CLIENT_CERTIFICATE; - - /* - * Send the client key exchange message, depending on the key exchange we are using - * in our CipherSuite. - */ - sendClientKeyExchangeMessage(); - this.connection_state = CS_CLIENT_KEY_EXCHANGE; - - establishMasterSecret(getContext(), keyExchange); - recordStream.setPendingConnectionState(getPeer().getCompression(), getPeer().getCipher()); - - TlsHandshakeHash prepareFinishHash = recordStream.prepareToFinish(); - - if (clientCreds != null && clientCreds instanceof TlsSignerCredentials) - { - TlsSignerCredentials signerCredentials = (TlsSignerCredentials)clientCreds; - - /* - * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 - */ - SignatureAndHashAlgorithm signatureAndHashAlgorithm; - byte[] hash; - - if (TlsUtils.isTLSv12(getContext())) - { - signatureAndHashAlgorithm = signerCredentials.getSignatureAndHashAlgorithm(); - if (signatureAndHashAlgorithm == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - hash = prepareFinishHash.getFinalHash(signatureAndHashAlgorithm.getHash()); - } - else - { - signatureAndHashAlgorithm = null; - hash = getCurrentPRFHash(getContext(), prepareFinishHash, null); - } - - byte[] signature = signerCredentials.generateCertificateSignature(hash); - DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); - sendCertificateVerifyMessage(certificateVerify); - - this.connection_state = CS_CERTIFICATE_VERIFY; - } - - sendChangeCipherSpecMessage(); - sendFinishedMessage(); - this.connection_state = CS_CLIENT_FINISHED; - break; - } - default: - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - break; - } - 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: - { - // There was no server certificate message; check it's OK - this.keyExchange.skipServerCredentials(); - this.authentication = null; - - // NB: Fall through to next case label - } - case CS_SERVER_CERTIFICATE: - case CS_CERTIFICATE_STATUS: - { - this.keyExchange.processServerKeyExchange(buf); - - assertEmpty(buf); - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - this.connection_state = CS_SERVER_KEY_EXCHANGE; - break; - } - case HandshakeType.certificate_request: - { - switch (this.connection_state) - { - case CS_SERVER_CERTIFICATE: - case CS_CERTIFICATE_STATUS: - { - // There was no server key exchange message; check it's OK - this.keyExchange.skipServerKeyExchange(); - - // NB: Fall through to next case label - } - 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. - */ - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - - this.certificateRequest = CertificateRequest.parse(getContext(), buf); - - assertEmpty(buf); - - this.keyExchange.validateCertificateRequest(this.certificateRequest); - - /* - * TODO Give the client a chance to immediately select the CertificateVerify hash - * algorithm here to avoid tracking the other hash algorithms unnecessarily? - */ - TlsUtils.trackHashAlgorithms(this.recordStream.getHandshakeHash(), - this.certificateRequest.getSupportedSignatureAlgorithms()); - - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - this.connection_state = CS_CERTIFICATE_REQUEST; - break; - } - case HandshakeType.session_ticket: - { - switch (this.connection_state) - { - case CS_CLIENT_FINISHED: - { - 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. - */ - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - /* - * RFC 5077 3.4. If the client receives a session ticket from the server, then it - * discards any Session ID that was sent in the ServerHello. - */ - invalidateSession(); - - receiveNewSessionTicketMessage(buf); - this.connection_state = CS_SERVER_SESSION_TICKET; - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - } - case HandshakeType.hello_request: - { - assertEmpty(buf); - - /* - * RFC 2246 7.4.1.1 Hello request This message will be ignored by the client if the - * client is currently negotiating a session. This message may be ignored by the client - * 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_END) - { - /* - * RFC 5746 4.5 SSLv3 clients that refuse renegotiation SHOULD use a fatal - * handshake_failure alert. - */ - if (TlsUtils.isSSL(getContext())) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - - String message = "Renegotiation not supported"; - raiseWarning(AlertDescription.no_renegotiation, message); - } - break; - } - case HandshakeType.client_hello: - case HandshakeType.client_key_exchange: - case HandshakeType.certificate_verify: - case HandshakeType.hello_verify_request: - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - } - - protected void handleSupplementalData(Vector serverSupplementalData) - throws IOException - { - this.tlsClient.processServerSupplementalData(serverSupplementalData); - this.connection_state = CS_SERVER_SUPPLEMENTAL_DATA; - - this.keyExchange = tlsClient.getKeyExchange(); - this.keyExchange.init(getContext()); - } - - protected void receiveNewSessionTicketMessage(ByteArrayInputStream buf) - throws IOException - { - NewSessionTicket newSessionTicket = NewSessionTicket.parse(buf); - - TlsProtocol.assertEmpty(buf); - - tlsClient.notifyNewSessionTicket(newSessionTicket); - } - - protected void receiveServerHelloMessage(ByteArrayInputStream buf) - throws IOException - { - ProtocolVersion server_version = TlsUtils.readVersion(buf); - if (server_version.isDTLS()) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - // Check that this matches what the server is sending in the record layer - if (!server_version.equals(this.recordStream.getReadVersion())) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - ProtocolVersion client_version = getContext().getClientVersion(); - if (!server_version.isEqualOrEarlierVersionOf(client_version)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - this.recordStream.setWriteVersion(server_version); - getContext().setServerVersion(server_version); - this.tlsClient.notifyServerVersion(server_version); - - /* - * Read the server random - */ - this.securityParameters.serverRandom = TlsUtils.readFully(32, buf); - - this.selectedSessionID = TlsUtils.readOpaque8(buf); - if (this.selectedSessionID.length > 32) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - this.tlsClient.notifySessionID(this.selectedSessionID); - - this.resumedSession = this.selectedSessionID.length > 0 && this.tlsSession != null - && Arrays.areEqual(this.selectedSessionID, this.tlsSession.getSessionID()); - - /* - * Find out which CipherSuite the server has chosen and check that it was one of the offered - * ones, and is a valid selection for the negotiated version. - */ - int selectedCipherSuite = TlsUtils.readUint16(buf); - if (!Arrays.contains(this.offeredCipherSuites, selectedCipherSuite) - || selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL - || selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV - || !TlsUtils.isValidCipherSuiteForVersion(selectedCipherSuite, server_version)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - this.tlsClient.notifySelectedCipherSuite(selectedCipherSuite); - - /* - * Find out which CompressionMethod the server has chosen and check that it was one of the - * offered ones. - */ - short selectedCompressionMethod = TlsUtils.readUint8(buf); - if (!Arrays.contains(this.offeredCompressionMethods, selectedCompressionMethod)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - this.tlsClient.notifySelectedCompressionMethod(selectedCompressionMethod); - - /* - * RFC3546 2.2 The extended server hello message format MAY be sent in place of the server - * hello message when the client has requested extended functionality via the extended - * client hello message specified in Section 2.1. ... Note that the extended server hello - * message is only sent in response to an extended client hello message. This prevents the - * possibility that the extended server hello message could "break" existing TLS 1.0 - * clients. - */ - this.serverExtensions = readExtensions(buf); - - /* - * RFC 3546 2.2 Note that the extended server hello message is only sent in response to an - * extended client hello message. - * - * However, see RFC 5746 exception below. We always include the SCSV, so an Extended Server - * Hello is always allowed. - */ - if (this.serverExtensions != null) - { - Enumeration e = this.serverExtensions.keys(); - while (e.hasMoreElements()) - { - Integer extType = (Integer)e.nextElement(); - - /* - * RFC 5746 3.6. 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, Section 7.4.1.4, on the server sending unsolicited extensions and is - * only allowed because the client is signaling its willingness to receive the - * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. - */ - if (extType.equals(EXT_RenegotiationInfo)) - { - continue; - } - - /* - * RFC 3546 2.3. If [...] the older session is resumed, then the server MUST ignore - * extensions appearing in the client hello, and send a server hello containing no - * extensions[.] - */ - if (this.resumedSession) - { - // TODO[compat-gnutls] GnuTLS test server sends server extensions e.g. ec_point_formats - // TODO[compat-openssl] OpenSSL test server sends server extensions e.g. ec_point_formats - // TODO[compat-polarssl] PolarSSL test server sends server extensions e.g. ec_point_formats -// throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - /* - * 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 client - * receives an extension type in ServerHello that it did not request in the - * associated ClientHello, it MUST abort the handshake with an unsupported_extension - * fatal alert. - */ - if (null == TlsUtils.getExtensionData(this.clientExtensions, extType)) - { - throw new TlsFatalAlert(AlertDescription.unsupported_extension); - } - } - } - - /* - * RFC 5746 3.4. Client Behavior: Initial Handshake - */ - { - /* - * When a ServerHello is received, the client MUST check if it includes the - * "renegotiation_info" extension: - */ - byte[] renegExtData = TlsUtils.getExtensionData(this.serverExtensions, EXT_RenegotiationInfo); - if (renegExtData != 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" - * field is zero, and if it is not, MUST abort the handshake (by sending a fatal - * handshake_failure alert). - */ - this.secure_renegotiation = true; - - if (!Arrays.constantTimeAreEqual(renegExtData, createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - } - } - - // TODO[compat-gnutls] GnuTLS test server fails to send renegotiation_info extension when resuming - this.tlsClient.notifySecureRenegotiation(this.secure_renegotiation); - - Hashtable sessionClientExtensions = clientExtensions, sessionServerExtensions = serverExtensions; - if (this.resumedSession) - { - if (selectedCipherSuite != this.sessionParameters.getCipherSuite() - || selectedCompressionMethod != this.sessionParameters.getCompressionAlgorithm()) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - sessionClientExtensions = null; - sessionServerExtensions = this.sessionParameters.readServerExtensions(); - } - - this.securityParameters.cipherSuite = selectedCipherSuite; - this.securityParameters.compressionAlgorithm = selectedCompressionMethod; - - if (sessionServerExtensions != null) - { - /* - * draft-ietf-tls-encrypt-then-mac-03 3. If a server receives an encrypt-then-MAC - * request extension from a client and then selects a stream or AEAD cipher suite, it - * MUST NOT send an encrypt-then-MAC response extension back to the client. - */ - boolean serverSentEncryptThenMAC = TlsExtensionsUtils.hasEncryptThenMACExtension(sessionServerExtensions); - if (serverSentEncryptThenMAC && !TlsUtils.isBlockCipherSuite(selectedCipherSuite)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - this.securityParameters.encryptThenMAC = serverSentEncryptThenMAC; - - this.securityParameters.maxFragmentLength = processMaxFragmentLengthExtension(sessionClientExtensions, - sessionServerExtensions, AlertDescription.illegal_parameter); - - this.securityParameters.truncatedHMac = TlsExtensionsUtils.hasTruncatedHMacExtension(sessionServerExtensions); - - /* - * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in - * a session resumption handshake. - */ - this.allowCertificateStatus = !this.resumedSession - && TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, - TlsExtensionsUtils.EXT_status_request, AlertDescription.illegal_parameter); - - this.expectSessionTicket = !this.resumedSession - && TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, TlsProtocol.EXT_SessionTicket, - AlertDescription.illegal_parameter); - } - - if (sessionClientExtensions != null) - { - this.tlsClient.processServerExtensions(sessionServerExtensions); - } - } - - protected void sendCertificateVerifyMessage(DigitallySigned certificateVerify) - throws IOException - { - HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate_verify); - - certificateVerify.encode(message); - - message.writeToRecordStream(); - } - - protected void sendClientHelloMessage() - throws IOException - { - this.recordStream.setWriteVersion(this.tlsClient.getClientHelloRecordLayerVersion()); - - ProtocolVersion client_version = this.tlsClient.getClientVersion(); - if (client_version.isDTLS()) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - getContext().setClientVersion(client_version); - - /* - * TODO RFC 5077 3.4. When presenting a ticket, the client MAY generate and include a - * Session ID in the TLS ClientHello. - */ - byte[] session_id = TlsUtils.EMPTY_BYTES; - if (this.tlsSession != null) - { - session_id = this.tlsSession.getSessionID(); - if (session_id == null || session_id.length > 32) - { - session_id = TlsUtils.EMPTY_BYTES; - } - } - - this.offeredCipherSuites = this.tlsClient.getCipherSuites(); - - this.offeredCompressionMethods = this.tlsClient.getCompressionMethods(); - - if (session_id.length > 0 && this.sessionParameters != null) - { - if (!Arrays.contains(this.offeredCipherSuites, sessionParameters.getCipherSuite()) - || !Arrays.contains(this.offeredCompressionMethods, sessionParameters.getCompressionAlgorithm())) - { - session_id = TlsUtils.EMPTY_BYTES; - } - } - - this.clientExtensions = this.tlsClient.getClientExtensions(); - - HandshakeMessage message = new HandshakeMessage(HandshakeType.client_hello); - - TlsUtils.writeVersion(client_version, message); - - message.write(this.securityParameters.getClientRandom()); - - TlsUtils.writeOpaque8(session_id, message); - - // Cipher Suites (and SCSV) - { - /* - * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, - * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the - * ClientHello. Including both is NOT RECOMMENDED. - */ - byte[] renegExtData = TlsUtils.getExtensionData(clientExtensions, EXT_RenegotiationInfo); - boolean noRenegExt = (null == renegExtData); - - boolean noSCSV = !Arrays.contains(offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); - - if (noRenegExt && noSCSV) - { - // TODO Consider whether to default to a client extension instead -// this.clientExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(this.clientExtensions); -// this.clientExtensions.put(EXT_RenegotiationInfo, createRenegotiationInfo(TlsUtils.EMPTY_BYTES)); - this.offeredCipherSuites = Arrays.append(offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); - } - - TlsUtils.writeUint16ArrayWithUint16Length(offeredCipherSuites, message); - } - - TlsUtils.writeUint8ArrayWithUint8Length(offeredCompressionMethods, message); - - if (clientExtensions != null) - { - writeExtensions(message, clientExtensions); - } - - message.writeToRecordStream(); - } - - protected void sendClientKeyExchangeMessage() - throws IOException - { - HandshakeMessage message = new HandshakeMessage(HandshakeType.client_key_exchange); - - this.keyExchange.generateClientKeyExchange(message); - - message.writeToRecordStream(); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsCompression.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsCompression.java deleted file mode 100644 index cdeb7e33..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsCompression.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.OutputStream; - -public interface TlsCompression -{ - OutputStream compress(OutputStream output); - - OutputStream decompress(OutputStream output); -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsContext.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsContext.java deleted file mode 100644 index b3d7d985..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsContext.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.prng.RandomGenerator; - -public interface TlsContext -{ - RandomGenerator getNonceRandomGenerator(); - - SecureRandom getSecureRandom(); - - SecurityParameters getSecurityParameters(); - - boolean isServer(); - - ProtocolVersion getClientVersion(); - - ProtocolVersion getServerVersion(); - - /** - * Used to get the resumable session, if any, used by this connection. Only available after the - * handshake has successfully completed. - * - * @return A {@link TlsSession} representing the resumable session used by this connection, or - * null if no resumable session available. - * @see TlsPeer#notifyHandshakeComplete() - */ - TlsSession getResumableSession(); - - Object getUserObject(); - - void setUserObject(Object userObject); - - /** - * 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 - * @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/core/src/main/java/org/bouncycastle/crypto/tls/TlsCredentials.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsCredentials.java deleted file mode 100644 index b8a8747e..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsCredentials.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public interface TlsCredentials -{ - Certificate getCertificate(); -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsDHEKeyExchange.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsDHEKeyExchange.java deleted file mode 100644 index 0abaee69..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsDHEKeyExchange.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Vector; - -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.params.DHParameters; -import org.bouncycastle.util.io.TeeInputStream; - -public class TlsDHEKeyExchange - extends TlsDHKeyExchange -{ - protected TlsSignerCredentials serverCredentials = null; - - public TlsDHEKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, DHParameters dhParameters) - { - super(keyExchange, supportedSignatureAlgorithms, dhParameters); - } - - public void processServerCredentials(TlsCredentials serverCredentials) - throws IOException - { - if (!(serverCredentials instanceof TlsSignerCredentials)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - processServerCertificate(serverCredentials.getCertificate()); - - this.serverCredentials = (TlsSignerCredentials)serverCredentials; - } - - public byte[] generateServerKeyExchange() - throws IOException - { - if (this.dhParameters == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - DigestInputBuffer buf = new DigestInputBuffer(); - - this.dhAgreeServerPrivateKey = TlsDHUtils.generateEphemeralServerKeyExchange(context.getSecureRandom(), - this.dhParameters, buf); - - /* - * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 - */ - SignatureAndHashAlgorithm signatureAndHashAlgorithm; - Digest d; - - if (TlsUtils.isTLSv12(context)) - { - signatureAndHashAlgorithm = serverCredentials.getSignatureAndHashAlgorithm(); - if (signatureAndHashAlgorithm == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - d = TlsUtils.createHash(signatureAndHashAlgorithm.getHash()); - } - else - { - signatureAndHashAlgorithm = null; - d = new CombinedHash(); - } - - SecurityParameters securityParameters = context.getSecurityParameters(); - d.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); - d.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); - buf.updateDigest(d); - - byte[] hash = new byte[d.getDigestSize()]; - d.doFinal(hash, 0); - - byte[] signature = serverCredentials.generateCertificateSignature(hash); - - DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); - signed_params.encode(buf); - - return buf.toByteArray(); - } - - public void processServerKeyExchange(InputStream input) - throws IOException - { - SecurityParameters securityParameters = context.getSecurityParameters(); - - SignerInputBuffer buf = new SignerInputBuffer(); - InputStream teeIn = new TeeInputStream(input, buf); - - ServerDHParams params = ServerDHParams.parse(teeIn); - - DigitallySigned signed_params = DigitallySigned.parse(context, input); - - Signer signer = initVerifyer(tlsSigner, signed_params.getAlgorithm(), securityParameters); - buf.updateSigner(signer); - if (!signer.verifySignature(signed_params.getSignature())) - { - throw new TlsFatalAlert(AlertDescription.decrypt_error); - } - - this.dhAgreeServerPublicKey = TlsDHUtils.validateDHPublicKey(params.getPublicKey()); - } - - protected Signer initVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, SecurityParameters securityParameters) - { - Signer signer = tlsSigner.createVerifyer(algorithm, this.serverPublicKey); - signer.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); - signer.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); - return signer; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsDHKeyExchange.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsDHKeyExchange.java deleted file mode 100644 index 7d79f6a4..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsDHKeyExchange.java +++ /dev/null @@ -1,208 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.OutputStream; -import java.math.BigInteger; -import java.util.Vector; - -import org.bouncycastle.asn1.x509.KeyUsage; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.DHParameters; -import org.bouncycastle.crypto.params.DHPrivateKeyParameters; -import org.bouncycastle.crypto.params.DHPublicKeyParameters; -import org.bouncycastle.crypto.util.PublicKeyFactory; - -/** - * TLS 1.0/1.1 DH key exchange. - */ -public class TlsDHKeyExchange - extends AbstractTlsKeyExchange -{ - protected static final BigInteger ONE = BigInteger.valueOf(1); - protected static final BigInteger TWO = BigInteger.valueOf(2); - - protected TlsSigner tlsSigner; - protected DHParameters dhParameters; - - protected AsymmetricKeyParameter serverPublicKey; - protected DHPublicKeyParameters dhAgreeServerPublicKey; - protected TlsAgreementCredentials agreementCredentials; - protected DHPrivateKeyParameters dhAgreeClientPrivateKey; - - protected DHPrivateKeyParameters dhAgreeServerPrivateKey; - protected DHPublicKeyParameters dhAgreeClientPublicKey; - - public TlsDHKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, DHParameters dhParameters) - { - super(keyExchange, supportedSignatureAlgorithms); - - switch (keyExchange) - { - case KeyExchangeAlgorithm.DH_RSA: - case KeyExchangeAlgorithm.DH_DSS: - this.tlsSigner = null; - break; - case KeyExchangeAlgorithm.DHE_RSA: - this.tlsSigner = new TlsRSASigner(); - break; - case KeyExchangeAlgorithm.DHE_DSS: - this.tlsSigner = new TlsDSSSigner(); - break; - default: - throw new IllegalArgumentException("unsupported key exchange algorithm"); - } - - this.dhParameters = dhParameters; - } - - public void init(TlsContext context) - { - super.init(context); - - if (this.tlsSigner != null) - { - this.tlsSigner.init(context); - } - } - - public void skipServerCredentials() - throws IOException - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - public void processServerCertificate(Certificate serverCertificate) - throws IOException - { - if (serverCertificate.isEmpty()) - { - throw new TlsFatalAlert(AlertDescription.bad_certificate); - } - - org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); - - SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - try - { - this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); - } - catch (RuntimeException e) - { - throw new TlsFatalAlert(AlertDescription.unsupported_certificate); - } - - if (tlsSigner == null) - { - try - { - this.dhAgreeServerPublicKey = TlsDHUtils.validateDHPublicKey((DHPublicKeyParameters)this.serverPublicKey); - } - catch (ClassCastException e) - { - throw new TlsFatalAlert(AlertDescription.certificate_unknown); - } - - TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyAgreement); - } - else - { - if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) - { - throw new TlsFatalAlert(AlertDescription.certificate_unknown); - } - - TlsUtils.validateKeyUsage(x509Cert, KeyUsage.digitalSignature); - } - - super.processServerCertificate(serverCertificate); - } - - public boolean requiresServerKeyExchange() - { - switch (keyExchange) - { - case KeyExchangeAlgorithm.DHE_DSS: - case KeyExchangeAlgorithm.DHE_RSA: - case KeyExchangeAlgorithm.DH_anon: - return true; - default: - return false; - } - } - - public void validateCertificateRequest(CertificateRequest certificateRequest) - throws IOException - { - short[] types = certificateRequest.getCertificateTypes(); - for (int i = 0; i < types.length; ++i) - { - switch (types[i]) - { - case ClientCertificateType.rsa_sign: - case ClientCertificateType.dss_sign: - case ClientCertificateType.rsa_fixed_dh: - case ClientCertificateType.dss_fixed_dh: - case ClientCertificateType.ecdsa_sign: - break; - default: - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - } - - 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) - { - // OK - } - else - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - 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) - { - this.dhAgreeClientPrivateKey = TlsDHUtils.generateEphemeralClientKeyExchange(context.getSecureRandom(), - dhAgreeServerPublicKey.getParameters(), output); - } - } - - public byte[] generatePremasterSecret() - throws IOException - { - if (agreementCredentials != null) - { - return agreementCredentials.generateAgreement(dhAgreeServerPublicKey); - } - - if (dhAgreeServerPrivateKey != null) - { - return TlsDHUtils.calculateDHBasicAgreement(dhAgreeClientPublicKey, dhAgreeServerPrivateKey); - } - - if (dhAgreeClientPrivateKey != null) - { - return TlsDHUtils.calculateDHBasicAgreement(dhAgreeServerPublicKey, dhAgreeClientPrivateKey); - } - - throw new TlsFatalAlert(AlertDescription.internal_error); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsDHUtils.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsDHUtils.java deleted file mode 100644 index 748c8797..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsDHUtils.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigInteger; -import java.security.SecureRandom; - -import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.agreement.DHBasicAgreement; -import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator; -import org.bouncycastle.crypto.params.DHKeyGenerationParameters; -import org.bouncycastle.crypto.params.DHParameters; -import org.bouncycastle.crypto.params.DHPrivateKeyParameters; -import org.bouncycastle.crypto.params.DHPublicKeyParameters; -import org.bouncycastle.util.BigIntegers; - -public class TlsDHUtils -{ - static final BigInteger ONE = BigInteger.valueOf(1); - static final BigInteger TWO = BigInteger.valueOf(2); - - public static boolean areCompatibleParameters(DHParameters a, DHParameters b) - { - return a.getP().equals(b.getP()) && a.getG().equals(b.getG()); - } - - public static byte[] calculateDHBasicAgreement(DHPublicKeyParameters publicKey, DHPrivateKeyParameters privateKey) - { - DHBasicAgreement basicAgreement = new DHBasicAgreement(); - basicAgreement.init(privateKey); - BigInteger agreementValue = basicAgreement.calculateAgreement(publicKey); - - /* - * RFC 5246 8.1.2. Leading bytes of Z that contain all zero bits are stripped before it is - * used as the pre_master_secret. - */ - return BigIntegers.asUnsignedByteArray(agreementValue); - } - - public static AsymmetricCipherKeyPair generateDHKeyPair(SecureRandom random, 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 - { - AsymmetricCipherKeyPair kp = generateDHKeyPair(random, dhParams); - - DHPublicKeyParameters dh_public = (DHPublicKeyParameters) kp.getPublic(); - writeDHParameter(dh_public.getY(), output); - - return (DHPrivateKeyParameters) kp.getPrivate(); - } - - public static DHPrivateKeyParameters generateEphemeralServerKeyExchange(SecureRandom random, DHParameters dhParams, - OutputStream output) throws IOException - { - AsymmetricCipherKeyPair kp = TlsDHUtils.generateDHKeyPair(random, dhParams); - - DHPublicKeyParameters dhPublicKey = (DHPublicKeyParameters)kp.getPublic(); - ServerDHParams params = new ServerDHParams(dhPublicKey); - params.encode(output); - - return (DHPrivateKeyParameters)kp.getPrivate(); - } - - public static DHPublicKeyParameters validateDHPublicKey(DHPublicKeyParameters key) throws IOException - { - BigInteger Y = key.getY(); - DHParameters params = key.getParameters(); - BigInteger p = params.getP(); - BigInteger g = params.getG(); - - if (!p.isProbablePrime(2)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - 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) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - // TODO See RFC 2631 for more discussion of Diffie-Hellman validation - - return key; - } - - 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 - { - TlsUtils.writeOpaque16(BigIntegers.asUnsignedByteArray(x), output); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsDSASigner.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsDSASigner.java deleted file mode 100644 index caaad59a..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsDSASigner.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.DSA; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.digests.NullDigest; -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 byte[] generateRawSignature(SignatureAndHashAlgorithm algorithm, - AsymmetricKeyParameter privateKey, byte[] hash) - throws CryptoException - { - Signer signer = makeSigner(algorithm, true, true, - new ParametersWithRandom(privateKey, this.context.getSecureRandom())); - if (algorithm == null) - { - // Note: Only use the SHA1 part of the (MD5/SHA1) hash - signer.update(hash, 16, 20); - } - else - { - signer.update(hash, 0, hash.length); - } - return signer.generateSignature(); - } - - public boolean verifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, - AsymmetricKeyParameter publicKey, byte[] hash) - throws CryptoException - { - Signer signer = makeSigner(algorithm, true, false, publicKey); - if (algorithm == null) - { - // Note: Only use the SHA1 part of the (MD5/SHA1) hash - signer.update(hash, 16, 20); - } - else - { - signer.update(hash, 0, hash.length); - } - return signer.verifySignature(sigBytes); - } - - public Signer createSigner(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey) - { - return makeSigner(algorithm, false, true, privateKey); - } - - public Signer createVerifyer(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter publicKey) - { - return makeSigner(algorithm, false, false, publicKey); - } - - protected CipherParameters makeInitParameters(boolean forSigning, CipherParameters cp) - { - return cp; - } - - protected Signer makeSigner(SignatureAndHashAlgorithm algorithm, boolean raw, boolean forSigning, - CipherParameters cp) - { - if ((algorithm != null) != TlsUtils.isTLSv12(context)) - { - throw new IllegalStateException(); - } - - // TODO For TLS 1.2+, lift the SHA-1 restriction here - if (algorithm != null - && (algorithm.getHash() != HashAlgorithm.sha1 || algorithm.getSignature() != getSignatureAlgorithm())) - { - throw new IllegalStateException(); - } - - short hashAlgorithm = algorithm == null ? HashAlgorithm.sha1 : algorithm.getHash(); - Digest d = raw ? new NullDigest() : TlsUtils.createHash(hashAlgorithm); - - Signer s = new DSADigestSigner(createDSAImpl(hashAlgorithm), d); - s.init(forSigning, makeInitParameters(forSigning, cp)); - return s; - } - - protected abstract short getSignatureAlgorithm(); - - protected abstract DSA createDSAImpl(short hashAlgorithm); -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsDSSSigner.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsDSSSigner.java deleted file mode 100644 index 2914b7e4..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsDSSSigner.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.crypto.DSA; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.DSAPublicKeyParameters; -import org.bouncycastle.crypto.signers.DSASigner; -import org.bouncycastle.crypto.signers.HMacDSAKCalculator; - -public class TlsDSSSigner - extends TlsDSASigner -{ - public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) - { - return publicKey instanceof DSAPublicKeyParameters; - } - - protected DSA createDSAImpl(short hashAlgorithm) - { - return new DSASigner(new HMacDSAKCalculator(TlsUtils.createHash(hashAlgorithm))); - } - - protected short getSignatureAlgorithm() - { - return SignatureAlgorithm.dsa; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java deleted file mode 100644 index e9f96f06..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java +++ /dev/null @@ -1,690 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigInteger; -import java.security.SecureRandom; -import java.util.Hashtable; - -import org.bouncycastle.asn1.x9.ECNamedCurveTable; -import org.bouncycastle.asn1.x9.X9ECParameters; -import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; -import org.bouncycastle.crypto.ec.CustomNamedCurves; -import org.bouncycastle.crypto.generators.ECKeyPairGenerator; -import org.bouncycastle.crypto.params.ECDomainParameters; -import org.bouncycastle.crypto.params.ECKeyGenerationParameters; -import org.bouncycastle.crypto.params.ECPrivateKeyParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.math.ec.ECAlgorithms; -import org.bouncycastle.math.ec.ECCurve; -import org.bouncycastle.math.ec.ECFieldElement; -import org.bouncycastle.math.ec.ECPoint; -import org.bouncycastle.math.field.PolynomialExtensionField; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.BigIntegers; -import org.bouncycastle.util.Integers; - -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", - "sect193r2", "sect233k1", "sect233r1", "sect239k1", "sect283k1", "sect283r1", "sect409k1", "sect409r1", - "sect571k1", "sect571r1", "secp160k1", "secp160r1", "secp160r2", "secp192k1", "secp192r1", "secp224k1", - "secp224r1", "secp256k1", "secp256r1", "secp384r1", "secp521r1", - "brainpoolP256r1", "brainpoolP384r1", "brainpoolP512r1"}; - - 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 - { - extensions.put(EXT_ec_point_formats, createSupportedPointFormatsExtension(ecPointFormats)); - } - - public static int[] getSupportedEllipticCurvesExtension(Hashtable extensions) throws IOException - { - byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_elliptic_curves); - return extensionData == null ? null : readSupportedEllipticCurvesExtension(extensionData); - } - - public static short[] getSupportedPointFormatsExtension(Hashtable extensions) throws IOException - { - byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_ec_point_formats); - return extensionData == null ? null : readSupportedPointFormatsExtension(extensionData); - } - - public static byte[] createSupportedEllipticCurvesExtension(int[] namedCurves) throws IOException - { - if (namedCurves == null || namedCurves.length < 1) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - return TlsUtils.encodeUint16ArrayWithUint16Length(namedCurves); - } - - public static byte[] createSupportedPointFormatsExtension(short[] ecPointFormats) throws IOException - { - if (ecPointFormats == null || !Arrays.contains(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. - */ - - // NOTE: We add it at the end (lowest preference) - ecPointFormats = Arrays.append(ecPointFormats, ECPointFormat.uncompressed); - } - - return TlsUtils.encodeUint8ArrayWithUint8Length(ecPointFormats); - } - - public static int[] readSupportedEllipticCurvesExtension(byte[] extensionData) throws IOException - { - if (extensionData == null) - { - throw new IllegalArgumentException("'extensionData' cannot be null"); - } - - ByteArrayInputStream buf = new ByteArrayInputStream(extensionData); - - int length = TlsUtils.readUint16(buf); - if (length < 2 || (length & 1) != 0) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - int[] namedCurves = TlsUtils.readUint16Array(length / 2, buf); - - TlsProtocol.assertEmpty(buf); - - return namedCurves; - } - - public static short[] readSupportedPointFormatsExtension(byte[] extensionData) throws IOException - { - if (extensionData == null) - { - throw new IllegalArgumentException("'extensionData' cannot be null"); - } - - ByteArrayInputStream buf = new ByteArrayInputStream(extensionData); - - short length = TlsUtils.readUint8(buf); - if (length < 1) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - short[] ecPointFormats = TlsUtils.readUint8Array(length, buf); - - TlsProtocol.assertEmpty(buf); - - if (!Arrays.contains(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. - */ - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - return ecPointFormats; - } - - public static String getNameOfNamedCurve(int namedCurve) - { - return isSupportedNamedCurve(namedCurve) ? curveNames[namedCurve - 1] : null; - } - - public static ECDomainParameters getParametersForNamedCurve(int namedCurve) - { - String curveName = getNameOfNamedCurve(namedCurve); - if (curveName == null) - { - return null; - } - - // Parameters are lazily created the first time a particular curve is accessed - - X9ECParameters ecP = CustomNamedCurves.getByName(curveName); - if (ecP == null) - { - ecP = ECNamedCurveTable.getByName(curveName); - if (ecP == null) - { - return null; - } - } - - // It's a bit inefficient to do this conversion every time - return new ECDomainParameters(ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); - } - - 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])) - { - return true; - } - } - return false; - } - - public static boolean isECCCipherSuite(int cipherSuite) - { - switch (cipherSuite) - { - /* - * RFC 4492 - */ - 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: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: - case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: - - /* - * RFC 5289 - */ - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - - /* - * RFC 5489 - */ - case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: - - /* - * RFC 6367 - */ - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: - - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - - case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: - - /* - * draft-agl-tls-chacha20poly1305-04 - */ - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - - /* - * draft-josefsson-salsa20-tls-04 - */ - case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1: - - return true; - - default: - return false; - } - } - - 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) - { - return (namedCurve > 0 && namedCurve <= curveNames.length); - } - - public static boolean isCompressionPreferred(short[] ecPointFormats, short compressionFormat) - { - if (ecPointFormats == null) - { - return false; - } - for (int i = 0; i < ecPointFormats.length; ++i) - { - short ecPointFormat = ecPointFormats[i]; - if (ecPointFormat == ECPointFormat.uncompressed) - { - return false; - } - if (ecPointFormat == compressionFormat) - { - return true; - } - } - return false; - } - - public static byte[] serializeECFieldElement(int fieldSize, BigInteger x) throws IOException - { - return BigIntegers.asUnsignedByteArray((fieldSize + 7) / 8, x); - } - - public static byte[] serializeECPoint(short[] ecPointFormats, ECPoint point) throws IOException - { - ECCurve curve = point.getCurve(); - - /* - * RFC 4492 5.7. ...an elliptic curve point in uncompressed or compressed format. Here, the - * format MUST conform to what the server has requested through a Supported Point Formats - * Extension if this extension was used, and MUST be uncompressed if this extension was not - * used. - */ - boolean compressed = false; - if (ECAlgorithms.isFpCurve(curve)) - { - compressed = isCompressionPreferred(ecPointFormats, ECPointFormat.ansiX962_compressed_prime); - } - else if (ECAlgorithms.isF2mCurve(curve)) - { - compressed = isCompressionPreferred(ecPointFormats, ECPointFormat.ansiX962_compressed_char2); - } - return point.getEncoded(compressed); - } - - public static byte[] serializeECPublicKey(short[] ecPointFormats, ECPublicKeyParameters keyParameters) - throws IOException - { - return serializeECPoint(ecPointFormats, keyParameters.getQ()); - } - - public static BigInteger deserializeECFieldElement(int fieldSize, byte[] encoding) throws IOException - { - int requiredLength = (fieldSize + 7) / 8; - 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 - { - if (encoding == null || encoding.length < 1) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - short actualFormat; - switch (encoding[0]) - { - case 0x02: // compressed - case 0x03: // compressed - { - if (ECAlgorithms.isF2mCurve(curve)) - { - actualFormat = ECPointFormat.ansiX962_compressed_char2; - } - else if (ECAlgorithms.isFpCurve(curve)) - { - actualFormat = ECPointFormat.ansiX962_compressed_prime; - } - else - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - break; - } - case 0x04: // uncompressed - { - actualFormat = ECPointFormat.uncompressed; - break; - } - case 0x00: // infinity - case 0x06: // hybrid - case 0x07: // hybrid - default: - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - if (!Arrays.contains(ecPointFormats, actualFormat)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - return curve.decodePoint(encoding); - } - - public static ECPublicKeyParameters deserializeECPublicKey(short[] ecPointFormats, ECDomainParameters curve_params, - byte[] encoding) throws IOException - { - try - { - ECPoint Y = deserializeECPoint(ecPointFormats, curve_params.getCurve(), encoding); - return new ECPublicKeyParameters(Y, curve_params); - } - catch (RuntimeException e) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - - public static byte[] calculateECDHBasicAgreement(ECPublicKeyParameters publicKey, ECPrivateKeyParameters privateKey) - { - ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement(); - basicAgreement.init(privateKey); - BigInteger agreementValue = basicAgreement.calculateAgreement(publicKey); - - /* - * RFC 4492 5.10. Note that this octet string (Z in IEEE 1363 terminology) as output by - * FE2OSP, the Field Element to Octet String Conversion Primitive, has constant length for - * any given field; leading zeros found in this octet string MUST NOT be truncated. - */ - return BigIntegers.asUnsignedByteArray(basicAgreement.getFieldSize(), agreementValue); - } - - public static AsymmetricCipherKeyPair generateECKeyPair(SecureRandom random, ECDomainParameters ecParams) - { - ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); - keyPairGenerator.init(new ECKeyGenerationParameters(ecParams, random)); - return keyPairGenerator.generateKeyPair(); - } - - public static ECPrivateKeyParameters generateEphemeralClientKeyExchange(SecureRandom random, short[] ecPointFormats, - ECDomainParameters ecParams, OutputStream output) throws IOException - { - AsymmetricCipherKeyPair kp = generateECKeyPair(random, ecParams); - - ECPublicKeyParameters ecPublicKey = (ECPublicKeyParameters) kp.getPublic(); - writeECPoint(ecPointFormats, ecPublicKey.getQ(), output); - - return (ECPrivateKeyParameters) kp.getPrivate(); - } - - 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 - { - BigInteger K = readECParameter(input); - if (K.bitLength() < 32) - { - int k = K.intValue(); - if (k > 0 && k < fieldSize) - { - return k; - } - } - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - public static BigInteger readECFieldElement(int fieldSize, InputStream input) throws IOException - { - return deserializeECFieldElement(fieldSize, TlsUtils.readOpaque8(input)); - } - - 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 - { - try - { - short curveType = TlsUtils.readUint8(input); - - switch (curveType) - { - case ECCurveType.explicit_prime: - { - checkNamedCurve(namedCurves, NamedCurve.arbitrary_explicit_prime_curves); - - BigInteger prime_p = readECParameter(input); - BigInteger a = readECFieldElement(prime_p.bitLength(), input); - BigInteger b = readECFieldElement(prime_p.bitLength(), input); - byte[] baseEncoding = TlsUtils.readOpaque8(input); - BigInteger order = readECParameter(input); - BigInteger cofactor = readECParameter(input); - ECCurve curve = new ECCurve.Fp(prime_p, a, b, order, cofactor); - ECPoint base = deserializeECPoint(ecPointFormats, curve, baseEncoding); - return new ECDomainParameters(curve, base, order, cofactor); - } - case ECCurveType.explicit_char2: - { - checkNamedCurve(namedCurves, NamedCurve.arbitrary_explicit_char2_curves); - - int m = TlsUtils.readUint16(input); - short basis = TlsUtils.readUint8(input); - if (!ECBasisType.isValid(basis)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - int k1 = readECExponent(m, input), k2 = -1, k3 = -1; - if (basis == ECBasisType.ec_basis_pentanomial) - { - k2 = readECExponent(m, input); - k3 = readECExponent(m, input); - } - - BigInteger a = readECFieldElement(m, input); - BigInteger b = readECFieldElement(m, input); - byte[] baseEncoding = TlsUtils.readOpaque8(input); - BigInteger order = readECParameter(input); - BigInteger cofactor = readECParameter(input); - - ECCurve curve = (basis == ECBasisType.ec_basis_pentanomial) - ? new ECCurve.F2m(m, k1, k2, k3, a, b, order, cofactor) - : new ECCurve.F2m(m, k1, a, b, order, cofactor); - - ECPoint base = deserializeECPoint(ecPointFormats, curve, baseEncoding); - - return new ECDomainParameters(curve, base, order, cofactor); - } - case ECCurveType.named_curve: - { - int namedCurve = TlsUtils.readUint16(input); - 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 curves are not allowed here [...]. - */ - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - checkNamedCurve(namedCurves, namedCurve); - - return getParametersForNamedCurve(namedCurve); - } - default: - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - catch (RuntimeException e) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - - private static void checkNamedCurve(int[] namedCurves, int namedCurve) throws IOException - { - if (namedCurves != null && !Arrays.contains(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 - * and compression techniques specified by the client. - */ - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - - public static void writeECExponent(int k, OutputStream output) throws IOException - { - BigInteger K = BigInteger.valueOf(k); - writeECParameter(K, output); - } - - public static void writeECFieldElement(ECFieldElement x, OutputStream output) throws IOException - { - TlsUtils.writeOpaque8(x.getEncoded(), output); - } - - 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 - { - TlsUtils.writeOpaque8(BigIntegers.asUnsignedByteArray(x), output); - } - - public static void writeExplicitECParameters(short[] ecPointFormats, ECDomainParameters ecParameters, - OutputStream output) throws IOException - { - ECCurve curve = ecParameters.getCurve(); - - if (ECAlgorithms.isFpCurve(curve)) - { - TlsUtils.writeUint8(ECCurveType.explicit_prime, output); - - writeECParameter(curve.getField().getCharacteristic(), output); - } - else if (ECAlgorithms.isF2mCurve(curve)) - { - PolynomialExtensionField field = (PolynomialExtensionField)curve.getField(); - int[] exponents = field.getMinimalPolynomial().getExponentsPresent(); - - TlsUtils.writeUint8(ECCurveType.explicit_char2, output); - - int m = exponents[exponents.length - 1]; - TlsUtils.checkUint16(m); - TlsUtils.writeUint16(m, output); - - if (exponents.length == 3) - { - TlsUtils.writeUint8(ECBasisType.ec_basis_trinomial, output); - writeECExponent(exponents[1], output); - } - else if (exponents.length == 5) - { - TlsUtils.writeUint8(ECBasisType.ec_basis_pentanomial, output); - writeECExponent(exponents[1], output); - writeECExponent(exponents[2], output); - writeECExponent(exponents[3], output); - } - else - { - throw new IllegalArgumentException("Only trinomial and pentomial curves are supported"); - } - } - else - { - throw new IllegalArgumentException("'ecParameters' not a known curve type"); - } - - writeECFieldElement(curve.getA(), output); - writeECFieldElement(curve.getB(), output); - TlsUtils.writeOpaque8(serializeECPoint(ecPointFormats, ecParameters.getG()), output); - writeECParameter(ecParameters.getN(), output); - writeECParameter(ecParameters.getH(), output); - } - - public static void writeECPoint(short[] ecPointFormats, ECPoint point, OutputStream output) throws IOException - { - TlsUtils.writeOpaque8(serializeECPoint(ecPointFormats, point), output); - } - - public static void writeNamedECParameters(int namedCurve, OutputStream output) throws IOException - { - 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 - * curves are not allowed here [...]. - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - TlsUtils.writeUint8(ECCurveType.named_curve, output); - TlsUtils.checkUint16(namedCurve); - TlsUtils.writeUint16(namedCurve, output); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsECDHEKeyExchange.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsECDHEKeyExchange.java deleted file mode 100644 index b112af57..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsECDHEKeyExchange.java +++ /dev/null @@ -1,221 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Vector; - -import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.params.ECDomainParameters; -import org.bouncycastle.crypto.params.ECPrivateKeyParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.io.TeeInputStream; - -/** - * ECDHE key exchange (see RFC 4492) - */ -public class TlsECDHEKeyExchange - extends TlsECDHKeyExchange -{ - protected TlsSignerCredentials serverCredentials = null; - - public TlsECDHEKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, int[] namedCurves, - short[] clientECPointFormats, short[] serverECPointFormats) - { - super(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats); - } - - public void processServerCredentials(TlsCredentials serverCredentials) - throws IOException - { - if (!(serverCredentials instanceof TlsSignerCredentials)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - processServerCertificate(serverCredentials.getCertificate()); - - this.serverCredentials = (TlsSignerCredentials)serverCredentials; - } - - 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) - { - // TODO Let the peer choose the default named curve - namedCurve = NamedCurve.secp256r1; - } - else - { - for (int i = 0; i < namedCurves.length; ++i) - { - int entry = namedCurves[i]; - if (NamedCurve.isValid(entry) && TlsECCUtils.isSupportedNamedCurve(entry)) - { - namedCurve = entry; - break; - } - } - } - - ECDomainParameters curve_params = null; - if (namedCurve >= 0) - { - curve_params = TlsECCUtils.getParametersForNamedCurve(namedCurve); - } - else - { - /* - * If no named curves are suitable, check if the client supports explicit curves. - */ - if (Arrays.contains(namedCurves, NamedCurve.arbitrary_explicit_prime_curves)) - { - curve_params = TlsECCUtils.getParametersForNamedCurve(NamedCurve.secp256r1); - } - else if (Arrays.contains(namedCurves, NamedCurve.arbitrary_explicit_char2_curves)) - { - curve_params = TlsECCUtils.getParametersForNamedCurve(NamedCurve.sect283r1); - } - } - - if (curve_params == null) - { - /* - * NOTE: We shouldn't have negotiated ECDHE key exchange since we apparently can't find - * a suitable curve. - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - AsymmetricCipherKeyPair kp = TlsECCUtils.generateECKeyPair(context.getSecureRandom(), curve_params); - this.ecAgreePrivateKey = (ECPrivateKeyParameters)kp.getPrivate(); - - DigestInputBuffer buf = new DigestInputBuffer(); - - if (namedCurve < 0) - { - TlsECCUtils.writeExplicitECParameters(clientECPointFormats, curve_params, buf); - } - else - { - TlsECCUtils.writeNamedECParameters(namedCurve, buf); - } - - ECPublicKeyParameters ecPublicKey = (ECPublicKeyParameters) kp.getPublic(); - TlsECCUtils.writeECPoint(clientECPointFormats, ecPublicKey.getQ(), buf); - - /* - * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 - */ - SignatureAndHashAlgorithm signatureAndHashAlgorithm; - Digest d; - - if (TlsUtils.isTLSv12(context)) - { - signatureAndHashAlgorithm = serverCredentials.getSignatureAndHashAlgorithm(); - if (signatureAndHashAlgorithm == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - d = TlsUtils.createHash(signatureAndHashAlgorithm.getHash()); - } - else - { - signatureAndHashAlgorithm = null; - d = new CombinedHash(); - } - - SecurityParameters securityParameters = context.getSecurityParameters(); - d.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); - d.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); - buf.updateDigest(d); - - byte[] hash = new byte[d.getDigestSize()]; - d.doFinal(hash, 0); - - byte[] signature = serverCredentials.generateCertificateSignature(hash); - - DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); - signed_params.encode(buf); - - return buf.toByteArray(); - } - - public void processServerKeyExchange(InputStream input) - throws IOException - { - SecurityParameters securityParameters = context.getSecurityParameters(); - - SignerInputBuffer buf = new SignerInputBuffer(); - InputStream teeIn = new TeeInputStream(input, buf); - - ECDomainParameters curve_params = TlsECCUtils.readECParameters(namedCurves, clientECPointFormats, teeIn); - - byte[] point = TlsUtils.readOpaque8(teeIn); - - DigitallySigned signed_params = DigitallySigned.parse(context, input); - - Signer signer = initVerifyer(tlsSigner, signed_params.getAlgorithm(), securityParameters); - buf.updateSigner(signer); - if (!signer.verifySignature(signed_params.getSignature())) - { - throw new TlsFatalAlert(AlertDescription.decrypt_error); - } - - this.ecAgreePublicKey = TlsECCUtils.validateECPublicKey(TlsECCUtils.deserializeECPublicKey( - clientECPointFormats, curve_params, point)); - } - - 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 - * the use of a long-term ECDH client key would jeopardize the forward secrecy property of - * these algorithms. - */ - short[] types = certificateRequest.getCertificateTypes(); - for (int i = 0; i < types.length; ++i) - { - switch (types[i]) - { - case ClientCertificateType.rsa_sign: - case ClientCertificateType.dss_sign: - case ClientCertificateType.ecdsa_sign: - break; - default: - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - } - - public void processClientCredentials(TlsCredentials clientCredentials) - throws IOException - { - if (clientCredentials instanceof TlsSignerCredentials) - { - // OK - } - else - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - protected Signer initVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, SecurityParameters securityParameters) - { - Signer signer = tlsSigner.createVerifyer(algorithm, this.serverPublicKey); - signer.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); - signer.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); - return signer; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsECDHKeyExchange.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsECDHKeyExchange.java deleted file mode 100644 index 94563520..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsECDHKeyExchange.java +++ /dev/null @@ -1,219 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Vector; - -import org.bouncycastle.asn1.x509.KeyUsage; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ECDomainParameters; -import org.bouncycastle.crypto.params.ECPrivateKeyParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.util.PublicKeyFactory; - -/** - * ECDH key exchange (see RFC 4492) - */ -public class TlsECDHKeyExchange extends AbstractTlsKeyExchange -{ - protected TlsSigner tlsSigner; - protected int[] namedCurves; - protected short[] clientECPointFormats, serverECPointFormats; - - protected AsymmetricKeyParameter serverPublicKey; - protected TlsAgreementCredentials agreementCredentials; - - protected ECPrivateKeyParameters ecAgreePrivateKey; - protected ECPublicKeyParameters ecAgreePublicKey; - - public TlsECDHKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, int[] namedCurves, - short[] clientECPointFormats, short[] serverECPointFormats) - { - super(keyExchange, supportedSignatureAlgorithms); - - switch (keyExchange) - { - case KeyExchangeAlgorithm.ECDHE_RSA: - this.tlsSigner = new TlsRSASigner(); - break; - case KeyExchangeAlgorithm.ECDHE_ECDSA: - this.tlsSigner = new TlsECDSASigner(); - break; - case KeyExchangeAlgorithm.ECDH_RSA: - case KeyExchangeAlgorithm.ECDH_ECDSA: - this.tlsSigner = null; - break; - default: - throw new IllegalArgumentException("unsupported key exchange algorithm"); - } - - this.keyExchange = keyExchange; - this.namedCurves = namedCurves; - this.clientECPointFormats = clientECPointFormats; - this.serverECPointFormats = serverECPointFormats; - } - - public void init(TlsContext context) - { - super.init(context); - - if (this.tlsSigner != null) - { - this.tlsSigner.init(context); - } - } - - public void skipServerCredentials() throws IOException - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - public void processServerCertificate(Certificate serverCertificate) throws IOException - { - if (serverCertificate.isEmpty()) - { - throw new TlsFatalAlert(AlertDescription.bad_certificate); - } - - org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); - - SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - try - { - this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); - } - catch (RuntimeException e) - { - throw new TlsFatalAlert(AlertDescription.unsupported_certificate); - } - - if (tlsSigner == null) - { - try - { - this.ecAgreePublicKey = TlsECCUtils.validateECPublicKey((ECPublicKeyParameters) this.serverPublicKey); - } - catch (ClassCastException e) - { - throw new TlsFatalAlert(AlertDescription.certificate_unknown); - } - - TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyAgreement); - } - else - { - if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) - { - throw new TlsFatalAlert(AlertDescription.certificate_unknown); - } - - TlsUtils.validateKeyUsage(x509Cert, KeyUsage.digitalSignature); - } - - super.processServerCertificate(serverCertificate); - } - - public boolean requiresServerKeyExchange() - { - switch (keyExchange) - { - case KeyExchangeAlgorithm.ECDHE_ECDSA: - case KeyExchangeAlgorithm.ECDHE_RSA: - case KeyExchangeAlgorithm.ECDH_anon: - return true; - default: - return false; - } - } - - 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 - * the use of a long-term ECDH client key would jeopardize the forward secrecy property of - * these algorithms. - */ - short[] types = certificateRequest.getCertificateTypes(); - for (int i = 0; i < types.length; ++i) - { - switch (types[i]) - { - case ClientCertificateType.rsa_sign: - case ClientCertificateType.dss_sign: - case ClientCertificateType.ecdsa_sign: - case ClientCertificateType.rsa_fixed_ecdh: - case ClientCertificateType.ecdsa_fixed_ecdh: - break; - default: - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - } - - 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) - { - // OK - } - else - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public void generateClientKeyExchange(OutputStream output) throws IOException - { - if (agreementCredentials == null) - { - this.ecAgreePrivateKey = TlsECCUtils.generateEphemeralClientKeyExchange(context.getSecureRandom(), - serverECPointFormats, ecAgreePublicKey.getParameters(), output); - } - } - - 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 - { - if (ecAgreePublicKey != null) - { - // For ecdsa_fixed_ecdh and rsa_fixed_ecdh, the key arrived in the client certificate - return; - } - - byte[] point = TlsUtils.readOpaque8(input); - - ECDomainParameters curve_params = this.ecAgreePrivateKey.getParameters(); - - this.ecAgreePublicKey = TlsECCUtils.validateECPublicKey(TlsECCUtils.deserializeECPublicKey( - serverECPointFormats, curve_params, point)); - } - - public byte[] generatePremasterSecret() throws IOException - { - if (agreementCredentials != null) - { - return agreementCredentials.generateAgreement(ecAgreePublicKey); - } - - if (ecAgreePrivateKey != null) - { - return TlsECCUtils.calculateECDHBasicAgreement(ecAgreePublicKey, ecAgreePrivateKey); - } - - throw new TlsFatalAlert(AlertDescription.internal_error); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsECDSASigner.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsECDSASigner.java deleted file mode 100644 index aa4c546e..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsECDSASigner.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.crypto.DSA; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.signers.ECDSASigner; -import org.bouncycastle.crypto.signers.HMacDSAKCalculator; - -public class TlsECDSASigner - extends TlsDSASigner -{ - public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) - { - return publicKey instanceof ECPublicKeyParameters; - } - - protected DSA createDSAImpl(short hashAlgorithm) - { - return new ECDSASigner(new HMacDSAKCalculator(TlsUtils.createHash(hashAlgorithm))); - } - - protected short getSignatureAlgorithm() - { - return SignatureAlgorithm.ecdsa; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsEncryptionCredentials.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsEncryptionCredentials.java deleted file mode 100644 index f2928963..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsEncryptionCredentials.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public interface TlsEncryptionCredentials extends TlsCredentials -{ - byte[] decryptPreMasterSecret(byte[] encryptedPreMasterSecret) - throws IOException; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsExtensionsUtils.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsExtensionsUtils.java deleted file mode 100644 index a59a1d5a..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsExtensionsUtils.java +++ /dev/null @@ -1,267 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Hashtable; - -import org.bouncycastle.util.Integers; - -public class TlsExtensionsUtils -{ - public static final Integer EXT_encrypt_then_mac = Integers.valueOf(ExtensionType.encrypt_then_mac); - public static final Integer EXT_heartbeat = Integers.valueOf(ExtensionType.heartbeat); - public static final Integer EXT_max_fragment_length = Integers.valueOf(ExtensionType.max_fragment_length); - public static final Integer EXT_server_name = Integers.valueOf(ExtensionType.server_name); - public static final Integer EXT_status_request = Integers.valueOf(ExtensionType.status_request); - public static final Integer EXT_truncated_hmac = Integers.valueOf(ExtensionType.truncated_hmac); - - public static Hashtable ensureExtensionsInitialised(Hashtable extensions) - { - return extensions == null ? new Hashtable() : extensions; - } - - public static void addEncryptThenMACExtension(Hashtable extensions) - { - extensions.put(EXT_encrypt_then_mac, createEncryptThenMACExtension()); - } - - public static void addHeartbeatExtension(Hashtable extensions, HeartbeatExtension heartbeatExtension) - throws IOException - { - extensions.put(EXT_heartbeat, createHeartbeatExtension(heartbeatExtension)); - } - - public static void addMaxFragmentLengthExtension(Hashtable extensions, short maxFragmentLength) - throws IOException - { - extensions.put(EXT_max_fragment_length, createMaxFragmentLengthExtension(maxFragmentLength)); - } - - public static void addServerNameExtension(Hashtable extensions, ServerNameList serverNameList) - throws IOException - { - extensions.put(EXT_server_name, createServerNameExtension(serverNameList)); - } - - public static void addStatusRequestExtension(Hashtable extensions, CertificateStatusRequest statusRequest) - throws IOException - { - extensions.put(EXT_status_request, createStatusRequestExtension(statusRequest)); - } - - public static void addTruncatedHMacExtension(Hashtable extensions) - { - extensions.put(EXT_truncated_hmac, createTruncatedHMacExtension()); - } - - public static HeartbeatExtension getHeartbeatExtension(Hashtable extensions) - throws IOException - { - byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_heartbeat); - return extensionData == null ? null : readHeartbeatExtension(extensionData); - } - - public static short getMaxFragmentLengthExtension(Hashtable extensions) - throws IOException - { - byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_max_fragment_length); - return extensionData == null ? -1 : readMaxFragmentLengthExtension(extensionData); - } - - public static ServerNameList getServerNameExtension(Hashtable extensions) - throws IOException - { - byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_server_name); - return extensionData == null ? null : readServerNameExtension(extensionData); - } - - public static CertificateStatusRequest getStatusRequestExtension(Hashtable extensions) - throws IOException - { - byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_status_request); - return extensionData == null ? null : readStatusRequestExtension(extensionData); - } - - public static boolean hasEncryptThenMACExtension(Hashtable extensions) throws IOException - { - byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_encrypt_then_mac); - return extensionData == null ? false : readEncryptThenMACExtension(extensionData); - } - - public static boolean hasTruncatedHMacExtension(Hashtable extensions) throws IOException - { - byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_truncated_hmac); - return extensionData == null ? false : readTruncatedHMacExtension(extensionData); - } - - public static byte[] createEmptyExtensionData() - { - return TlsUtils.EMPTY_BYTES; - } - - public static byte[] createEncryptThenMACExtension() - { - return createEmptyExtensionData(); - } - - public static byte[] createHeartbeatExtension(HeartbeatExtension heartbeatExtension) - throws IOException - { - if (heartbeatExtension == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - heartbeatExtension.encode(buf); - - return buf.toByteArray(); - } - - public static byte[] createMaxFragmentLengthExtension(short maxFragmentLength) - throws IOException - { - if (!MaxFragmentLength.isValid(maxFragmentLength)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - return new byte[]{ (byte)maxFragmentLength }; - } - - public static byte[] createServerNameExtension(ServerNameList serverNameList) - throws IOException - { - if (serverNameList == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - serverNameList.encode(buf); - - return buf.toByteArray(); - } - - public static byte[] createStatusRequestExtension(CertificateStatusRequest statusRequest) - throws IOException - { - if (statusRequest == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - statusRequest.encode(buf); - - return buf.toByteArray(); - } - - public static byte[] createTruncatedHMacExtension() - { - return createEmptyExtensionData(); - } - - private static boolean readEmptyExtensionData(byte[] extensionData) throws IOException - { - if (extensionData == null) - { - throw new IllegalArgumentException("'extensionData' cannot be null"); - } - - if (extensionData.length != 0) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - return true; - } - - public static boolean readEncryptThenMACExtension(byte[] extensionData) throws IOException - { - return readEmptyExtensionData(extensionData); - } - - public static HeartbeatExtension readHeartbeatExtension(byte[] extensionData) - throws IOException - { - if (extensionData == null) - { - throw new IllegalArgumentException("'extensionData' cannot be null"); - } - - ByteArrayInputStream buf = new ByteArrayInputStream(extensionData); - - HeartbeatExtension heartbeatExtension = HeartbeatExtension.parse(buf); - - TlsProtocol.assertEmpty(buf); - - return heartbeatExtension; - } - - public static short readMaxFragmentLengthExtension(byte[] extensionData) - throws IOException - { - if (extensionData == null) - { - throw new IllegalArgumentException("'extensionData' cannot be null"); - } - - if (extensionData.length != 1) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - short maxFragmentLength = (short)extensionData[0]; - - if (!MaxFragmentLength.isValid(maxFragmentLength)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - return maxFragmentLength; - } - - public static ServerNameList readServerNameExtension(byte[] extensionData) - throws IOException - { - if (extensionData == null) - { - throw new IllegalArgumentException("'extensionData' cannot be null"); - } - - ByteArrayInputStream buf = new ByteArrayInputStream(extensionData); - - ServerNameList serverNameList = ServerNameList.parse(buf); - - TlsProtocol.assertEmpty(buf); - - return serverNameList; - } - - public static CertificateStatusRequest readStatusRequestExtension(byte[] extensionData) - throws IOException - { - if (extensionData == null) - { - throw new IllegalArgumentException("'extensionData' cannot be null"); - } - - ByteArrayInputStream buf = new ByteArrayInputStream(extensionData); - - CertificateStatusRequest statusRequest = CertificateStatusRequest.parse(buf); - - TlsProtocol.assertEmpty(buf); - - return statusRequest; - } - - public static boolean readTruncatedHMacExtension(byte[] extensionData) throws IOException - { - return readEmptyExtensionData(extensionData); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsFatalAlert.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsFatalAlert.java deleted file mode 100644 index 61cec318..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsFatalAlert.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public class TlsFatalAlert - extends IOException -{ - private static final long serialVersionUID = 3584313123679111168L; - - private short alertDescription; - - public TlsFatalAlert(short alertDescription) - { - this.alertDescription = alertDescription; - } - - public short getAlertDescription() - { - return alertDescription; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsHandshakeHash.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsHandshakeHash.java deleted file mode 100644 index 4ccfe72b..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsHandshakeHash.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.crypto.Digest; - -public interface TlsHandshakeHash - extends Digest -{ - void init(TlsContext context); - - TlsHandshakeHash notifyPRFDetermined(); - - void trackHashAlgorithm(short hashAlgorithm); - - void sealHashAlgorithms(); - - TlsHandshakeHash stopTracking(); - - Digest forkPRFHash(); - - byte[] getFinalHash(short hashAlgorithm); -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsInputStream.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsInputStream.java deleted file mode 100644 index a2cf74e8..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsInputStream.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; - -/** - * An InputStream for an TLS 1.0 connection. - */ -class TlsInputStream - extends InputStream -{ - private byte[] buf = new byte[1]; - private TlsProtocol handler = null; - - TlsInputStream(TlsProtocol handler) - { - this.handler = handler; - } - - public int available() - throws IOException - { - return this.handler.applicationDataAvailable(); - } - - public int read(byte[] buf, int offset, int len) - throws IOException - { - return this.handler.readApplicationData(buf, offset, len); - } - - public int read() - throws IOException - { - if (this.read(buf) < 0) - { - return -1; - } - return buf[0] & 0xff; - } - - public void close() - throws IOException - { - handler.close(); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsKeyExchange.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsKeyExchange.java deleted file mode 100644 index 50455907..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsKeyExchange.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * A generic interface for key exchange implementations in TLS 1.0/1.1. - */ -public interface TlsKeyExchange -{ - void init(TlsContext context); - - void skipServerCredentials() - throws IOException; - - void processServerCredentials(TlsCredentials serverCredentials) - throws IOException; - - void processServerCertificate(Certificate serverCertificate) - throws IOException; - - boolean requiresServerKeyExchange(); - - byte[] generateServerKeyExchange() - throws IOException; - - void skipServerKeyExchange() - throws IOException; - - void processServerKeyExchange(InputStream input) - throws IOException; - - void validateCertificateRequest(CertificateRequest certificateRequest) - throws IOException; - - void skipClientCredentials() - throws IOException; - - void processClientCredentials(TlsCredentials clientCredentials) - throws IOException; - - void processClientCertificate(Certificate clientCertificate) - throws IOException; - - void generateClientKeyExchange(OutputStream output) - throws IOException; - - void processClientKeyExchange(InputStream input) - throws IOException; - - byte[] generatePremasterSecret() - throws IOException; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsMac.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsMac.java deleted file mode 100644 index 00e0c79f..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsMac.java +++ /dev/null @@ -1,172 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Mac; -import org.bouncycastle.crypto.digests.LongDigest; -import org.bouncycastle.crypto.macs.HMac; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.util.Arrays; - -/** - * A generic TLS MAC implementation, acting as an HMAC based on some underlying Digest. - */ -public class TlsMac -{ - protected TlsContext context; - protected byte[] secret; - protected Mac mac; - protected int digestBlockSize; - protected int digestOverhead; - protected int macLength; - - /** - * 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 keyLen The length of the key. - */ - public TlsMac(TlsContext context, Digest digest, byte[] key, int keyOff, int keyLen) - { - this.context = context; - - KeyParameter keyParameter = new KeyParameter(key, keyOff, keyLen); - - this.secret = Arrays.clone(keyParameter.getKey()); - - // TODO This should check the actual algorithm, not rely on the engine type - if (digest instanceof LongDigest) - { - this.digestBlockSize = 128; - this.digestOverhead = 16; - } - else - { - this.digestBlockSize = 64; - this.digestOverhead = 8; - } - - if (TlsUtils.isSSL(context)) - { - this.mac = new SSL3Mac(digest); - - // TODO This should check the actual algorithm, not assume based on the digest size - 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 - { - this.mac = new HMac(digest); - - // NOTE: The input pad for HMAC is always a full digest block - } - - this.mac.init(keyParameter); - - this.macLength = mac.getMacSize(); - if (context.getSecurityParameters().truncatedHMac) - { - this.macLength = Math.min(this.macLength, 10); - } - } - - /** - * @return the MAC write secret - */ - public byte[] getMACSecret() - { - return this.secret; - } - - /** - * @return The output length of this MAC. - */ - public int getSize() - { - return macLength; - } - - /** - * 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. - * @return A new byte-buffer containing the MAC value. - */ - public byte[] calculateMac(long seqNo, short type, byte[] message, int offset, int length) - { - ProtocolVersion serverVersion = context.getServerVersion(); - boolean isSSL = serverVersion.isSSL(); - - byte[] macHeader = new byte[isSSL ? 11 : 13]; - TlsUtils.writeUint64(seqNo, macHeader, 0); - TlsUtils.writeUint8(type, macHeader, 8); - if (!isSSL) - { - TlsUtils.writeVersion(serverVersion, macHeader, 9); - } - TlsUtils.writeUint16(length, macHeader, macHeader.length - 2); - - mac.update(macHeader, 0, macHeader.length); - mac.update(message, offset, length); - - byte[] result = new byte[mac.getMacSize()]; - mac.doFinal(result, 0); - return truncate(result); - } - - public byte[] calculateMacConstantTime(long seqNo, short type, byte[] message, int offset, int length, - int fullLength, byte[] dummyData) - { - /* - * Actual MAC only calculated on 'length' bytes... - */ - byte[] result = calculateMac(seqNo, type, message, offset, length); - - /* - * ...but ensure a constant number of complete digest blocks are processed (as many as would - * be needed for 'fullLength' bytes of input). - */ - int headerLength = TlsUtils.isSSL(context) ? 11 : 13; - - // How many extra full blocks do we need to calculate? - int extra = getDigestBlockCount(headerLength + fullLength) - getDigestBlockCount(headerLength + length); - - while (--extra >= 0) - { - mac.update(dummyData, 0, digestBlockSize); - } - - // One more byte in case the implementation is "lazy" about processing blocks - mac.update(dummyData[0]); - mac.reset(); - - return result; - } - - protected int getDigestBlockCount(int inputLength) - { - // NOTE: This calculation assumes a minimum of 1 pad byte - return (inputLength + digestOverhead) / digestBlockSize; - } - - protected byte[] truncate(byte[] bs) - { - if (bs.length <= macLength) - { - return bs; - } - - return Arrays.copyOf(bs, macLength); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java deleted file mode 100644 index d1f6986b..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCipher.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.util.Arrays; - -/** - * A NULL CipherSuite with optional MAC - */ -public class TlsNullCipher - implements TlsCipher -{ - protected TlsContext context; - - protected TlsMac writeMac; - protected TlsMac readMac; - - public TlsNullCipher(TlsContext context) - { - this.context = context; - this.writeMac = null; - this.readMac = null; - } - - public TlsNullCipher(TlsContext context, Digest clientWriteDigest, Digest serverWriteDigest) - throws IOException - { - if ((clientWriteDigest == null) != (serverWriteDigest == null)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - this.context = context; - - TlsMac clientWriteMac = null, serverWriteMac = null; - - if (clientWriteDigest != null) - { - int key_block_size = clientWriteDigest.getDigestSize() - + serverWriteDigest.getDigestSize(); - byte[] key_block = TlsUtils.calculateKeyBlock(context, key_block_size); - - int offset = 0; - - clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, - clientWriteDigest.getDigestSize()); - offset += clientWriteDigest.getDigestSize(); - - serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, - serverWriteDigest.getDigestSize()); - offset += serverWriteDigest.getDigestSize(); - - if (offset != key_block_size) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - if (context.isServer()) - { - writeMac = serverWriteMac; - readMac = clientWriteMac; - } - else - { - writeMac = clientWriteMac; - readMac = serverWriteMac; - } - } - - public int getPlaintextLimit(int ciphertextLimit) - { - int result = ciphertextLimit; - if (writeMac != null) - { - result -= writeMac.getSize(); - } - return result; - } - - public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) - throws IOException - { - if (writeMac == null) - { - return Arrays.copyOfRange(plaintext, offset, offset + len); - } - - byte[] mac = writeMac.calculateMac(seqNo, type, plaintext, offset, len); - byte[] ciphertext = new byte[len + mac.length]; - System.arraycopy(plaintext, offset, ciphertext, 0, len); - System.arraycopy(mac, 0, ciphertext, len, mac.length); - return ciphertext; - } - - public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) - throws IOException - { - if (readMac == null) - { - return Arrays.copyOfRange(ciphertext, offset, offset + len); - } - - int macSize = readMac.getSize(); - if (len < macSize) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - int macInputLen = len - macSize; - - byte[] receivedMac = Arrays.copyOfRange(ciphertext, offset + macInputLen, offset + len); - byte[] computedMac = readMac.calculateMac(seqNo, type, ciphertext, offset, macInputLen); - - if (!Arrays.constantTimeAreEqual(receivedMac, computedMac)) - { - throw new TlsFatalAlert(AlertDescription.bad_record_mac); - } - - return Arrays.copyOfRange(ciphertext, offset, offset + macInputLen); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCompression.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCompression.java deleted file mode 100644 index 13a85abf..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsNullCompression.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.OutputStream; - -public class TlsNullCompression - implements TlsCompression -{ - public OutputStream compress(OutputStream output) - { - return output; - } - - public OutputStream decompress(OutputStream output) - { - return output; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsOutputStream.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsOutputStream.java deleted file mode 100644 index d9532414..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsOutputStream.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * An OutputStream for an TLS connection. - */ -class TlsOutputStream - extends OutputStream -{ - private byte[] buf = new byte[1]; - private TlsProtocol handler; - - TlsOutputStream(TlsProtocol handler) - { - this.handler = handler; - } - - public void write(byte buf[], int offset, int len) - throws IOException - { - this.handler.writeData(buf, offset, len); - } - - public void write(int arg0) - throws IOException - { - buf[0] = (byte)arg0; - this.write(buf, 0, 1); - } - - public void close() - throws IOException - { - handler.close(); - } - - public void flush() - throws IOException - { - handler.flush(); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsPSKIdentity.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsPSKIdentity.java deleted file mode 100644 index 2f6eea26..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsPSKIdentity.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public interface TlsPSKIdentity -{ - void skipIdentityHint(); - - void notifyIdentityHint(byte[] psk_identity_hint); - - byte[] getPSKIdentity(); - - byte[] getPSK(); -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsPSKKeyExchange.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsPSKKeyExchange.java deleted file mode 100644 index 7217bac6..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsPSKKeyExchange.java +++ /dev/null @@ -1,285 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Vector; - -import org.bouncycastle.asn1.x509.KeyUsage; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.DHParameters; -import org.bouncycastle.crypto.params.DHPrivateKeyParameters; -import org.bouncycastle.crypto.params.DHPublicKeyParameters; -import org.bouncycastle.crypto.params.RSAKeyParameters; -import org.bouncycastle.crypto.util.PublicKeyFactory; - -/** - * TLS 1.0 PSK key exchange (RFC 4279). - */ -public class TlsPSKKeyExchange - extends AbstractTlsKeyExchange -{ - protected TlsPSKIdentity pskIdentity; - protected DHParameters dhParameters; - protected int[] namedCurves; - protected short[] clientECPointFormats, serverECPointFormats; - - protected byte[] psk_identity_hint = null; - - protected DHPrivateKeyParameters dhAgreePrivateKey = null; - protected DHPublicKeyParameters dhAgreePublicKey = null; - - protected AsymmetricKeyParameter serverPublicKey = null; - protected RSAKeyParameters rsaServerPublicKey = null; - protected TlsEncryptionCredentials serverCredentials = null; - protected byte[] premasterSecret; - - public TlsPSKKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, TlsPSKIdentity pskIdentity, - DHParameters dhParameters, int[] namedCurves, short[] clientECPointFormats, short[] serverECPointFormats) - { - super(keyExchange, supportedSignatureAlgorithms); - - switch (keyExchange) - { - case KeyExchangeAlgorithm.DHE_PSK: - case KeyExchangeAlgorithm.ECDHE_PSK: - case KeyExchangeAlgorithm.PSK: - case KeyExchangeAlgorithm.RSA_PSK: - break; - default: - throw new IllegalArgumentException("unsupported key exchange algorithm"); - } - - this.pskIdentity = pskIdentity; - this.dhParameters = dhParameters; - this.namedCurves = namedCurves; - this.clientECPointFormats = clientECPointFormats; - this.serverECPointFormats = serverECPointFormats; - } - - public void skipServerCredentials() - throws IOException - { - if (keyExchange == KeyExchangeAlgorithm.RSA_PSK) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - } - - public void processServerCredentials(TlsCredentials serverCredentials) - throws IOException - { - if (!(serverCredentials instanceof TlsEncryptionCredentials)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - processServerCertificate(serverCredentials.getCertificate()); - - this.serverCredentials = (TlsEncryptionCredentials)serverCredentials; - } - - public byte[] generateServerKeyExchange() throws IOException - { - // TODO[RFC 4279] Need a server-side PSK API to determine hint and resolve identities to keys - this.psk_identity_hint = null; - - if (this.psk_identity_hint == null && !requiresServerKeyExchange()) - { - return null; - } - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - if (this.psk_identity_hint == null) - { - TlsUtils.writeOpaque16(TlsUtils.EMPTY_BYTES, buf); - } - else - { - TlsUtils.writeOpaque16(this.psk_identity_hint, buf); - } - - if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) - { - if (this.dhParameters == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - this.dhAgreePrivateKey = TlsDHUtils.generateEphemeralServerKeyExchange(context.getSecureRandom(), - this.dhParameters, buf); - } - else if (this.keyExchange == KeyExchangeAlgorithm.ECDHE_PSK) - { - // TODO[RFC 5489] - } - - return buf.toByteArray(); - } - - public void processServerCertificate(Certificate serverCertificate) - throws IOException - { - if (keyExchange != KeyExchangeAlgorithm.RSA_PSK) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - if (serverCertificate.isEmpty()) - { - throw new TlsFatalAlert(AlertDescription.bad_certificate); - } - - org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); - - SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - try - { - this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); - } - catch (RuntimeException e) - { - throw new TlsFatalAlert(AlertDescription.unsupported_certificate); - } - - // Sanity check the PublicKeyFactory - if (this.serverPublicKey.isPrivate()) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - this.rsaServerPublicKey = validateRSAPublicKey((RSAKeyParameters)this.serverPublicKey); - - TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyEncipherment); - - super.processServerCertificate(serverCertificate); - } - - public boolean requiresServerKeyExchange() - { - switch (keyExchange) - { - case KeyExchangeAlgorithm.DHE_PSK: - case KeyExchangeAlgorithm.ECDHE_PSK: - return true; - default: - return false; - } - } - - public void processServerKeyExchange(InputStream input) - throws IOException - { - this.psk_identity_hint = TlsUtils.readOpaque16(input); - - if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) - { - ServerDHParams serverDHParams = ServerDHParams.parse(input); - - this.dhAgreePublicKey = TlsDHUtils.validateDHPublicKey(serverDHParams.getPublicKey()); - } - else if (this.keyExchange == KeyExchangeAlgorithm.ECDHE_PSK) - { - // TODO[RFC 5489] - } - } - - public void validateCertificateRequest(CertificateRequest certificateRequest) - throws IOException - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - public void processClientCredentials(TlsCredentials clientCredentials) - throws IOException - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - public void generateClientKeyExchange(OutputStream output) - throws IOException - { - if (psk_identity_hint == null) - { - pskIdentity.skipIdentityHint(); - } - else - { - pskIdentity.notifyIdentityHint(psk_identity_hint); - } - - byte[] psk_identity = pskIdentity.getPSKIdentity(); - - TlsUtils.writeOpaque16(psk_identity, output); - - if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) - { - this.dhAgreePrivateKey = TlsDHUtils.generateEphemeralClientKeyExchange(context.getSecureRandom(), - dhAgreePublicKey.getParameters(), output); - } - else if (this.keyExchange == KeyExchangeAlgorithm.ECDHE_PSK) - { - // TODO[RFC 5489] - throw new TlsFatalAlert(AlertDescription.internal_error); - } - else if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK) - { - this.premasterSecret = TlsRSAUtils.generateEncryptedPreMasterSecret(context, this.rsaServerPublicKey, - output); - } - } - - public byte[] generatePremasterSecret() - throws IOException - { - byte[] psk = pskIdentity.getPSK(); - byte[] other_secret = generateOtherSecret(psk.length); - - ByteArrayOutputStream buf = new ByteArrayOutputStream(4 + other_secret.length + psk.length); - TlsUtils.writeOpaque16(other_secret, buf); - TlsUtils.writeOpaque16(psk, buf); - return buf.toByteArray(); - } - - protected byte[] generateOtherSecret(int pskLength) throws IOException - { - if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK) - { - if (dhAgreePrivateKey != null) - { - return TlsDHUtils.calculateDHBasicAgreement(dhAgreePublicKey, dhAgreePrivateKey); - } - - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - if (this.keyExchange == KeyExchangeAlgorithm.ECDHE_PSK) - { - // TODO[RFC 5489] - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK) - { - return this.premasterSecret; - } - - return new byte[pskLength]; - } - - protected RSAKeyParameters validateRSAPublicKey(RSAKeyParameters key) - throws IOException - { - // TODO What is the minimum bit length required? - // key.getModulus().bitLength(); - - if (!key.getExponent().isProbablePrime(2)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - return key; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsPeer.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsPeer.java deleted file mode 100644 index 1ee2e5fa..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsPeer.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public interface TlsPeer -{ - /** - * draft-mathewson-no-gmtunixtime-00 2. "If existing users of a TLS implementation may rely on - * gmt_unix_time containing the current time, we recommend that implementors MAY provide the - * ability to set gmt_unix_time as an option only, off by default." - * - * @return <code>true</code> if the current time should be used in the gmt_unix_time field of - * Random, or <code>false</code> if gmt_unix_time should contain a cryptographically - * random value. - */ - boolean shouldUseGMTUnixTime(); - - void notifySecureRenegotiation(boolean secureNegotiation) throws IOException; - - TlsCompression getCompression() throws IOException; - - TlsCipher getCipher() throws IOException; - - /** - * 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. - */ - 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} - */ - void notifyAlertReceived(short alertLevel, short alertDescription); - - /** - * Notifies the peer that the handshake has been successfully completed. - */ - void notifyHandshakeComplete() throws IOException; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsProtocol.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsProtocol.java deleted file mode 100644 index 02629056..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsProtocol.java +++ /dev/null @@ -1,1184 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.SecureRandom; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.prng.RandomGenerator; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Integers; - -/** - * An implementation of all high level protocols in TLS 1.0/1.1. - */ -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); - - private static final String TLS_ERROR_MESSAGE = "Internal TLS error, this could be an attack"; - - /* - * Our Connection states - */ - protected static final short CS_START = 0; - protected static final short CS_CLIENT_HELLO = 1; - protected static final short CS_SERVER_HELLO = 2; - protected static final short CS_SERVER_SUPPLEMENTAL_DATA = 3; - protected static final short CS_SERVER_CERTIFICATE = 4; - protected static final short CS_CERTIFICATE_STATUS = 5; - protected static final short CS_SERVER_KEY_EXCHANGE = 6; - protected static final short CS_CERTIFICATE_REQUEST = 7; - protected static final short CS_SERVER_HELLO_DONE = 8; - protected static final short CS_CLIENT_SUPPLEMENTAL_DATA = 9; - protected static final short CS_CLIENT_CERTIFICATE = 10; - protected static final short CS_CLIENT_KEY_EXCHANGE = 11; - protected static final short CS_CERTIFICATE_VERIFY = 12; - protected static final short CS_CLIENT_FINISHED = 13; - protected static final short CS_SERVER_SESSION_TICKET = 14; - protected static final short CS_SERVER_FINISHED = 15; - protected static final short CS_END = 16; - - /* - * Queues for data from some protocols. - */ - private ByteQueue applicationDataQueue = new ByteQueue(); - private ByteQueue alertQueue = new ByteQueue(2); - private ByteQueue handshakeQueue = new ByteQueue(); -// private ByteQueue heartbeatQueue = new ByteQueue(); - - /* - * The Record Stream we use - */ - protected RecordStream recordStream; - protected SecureRandom secureRandom; - - private TlsInputStream tlsInputStream = null; - private TlsOutputStream tlsOutputStream = null; - - private volatile boolean closed = false; - private volatile boolean failedWithError = false; - private volatile boolean appDataReady = false; - private volatile boolean splitApplicationDataRecords = true; - private byte[] expected_verify_data = null; - - protected TlsSession tlsSession = null; - protected SessionParameters sessionParameters = null; - protected SecurityParameters securityParameters = null; - protected Certificate peerCertificate = null; - - protected int[] offeredCipherSuites = null; - protected short[] offeredCompressionMethods = null; - protected Hashtable clientExtensions = null; - protected Hashtable serverExtensions = null; - - protected short connection_state = CS_START; - protected boolean resumedSession = false; - protected boolean receivedChangeCipherSpec = false; - protected boolean secure_renegotiation = false; - protected boolean allowCertificateStatus = false; - protected boolean expectSessionTicket = false; - - public TlsProtocol(InputStream input, OutputStream output, SecureRandom secureRandom) - { - this.recordStream = new RecordStream(this, input, output); - this.secureRandom = secureRandom; - } - - protected abstract AbstractTlsContext getContext(); - - protected abstract TlsPeer getPeer(); - - protected void handleChangeCipherSpecMessage() throws IOException - { - } - - protected abstract void handleHandshakeMessage(short type, byte[] buf) - throws IOException; - - protected void handleWarningMessage(short description) - throws IOException - { - } - - protected void cleanupHandshake() - { - if (this.expected_verify_data != null) - { - Arrays.fill(this.expected_verify_data, (byte)0); - this.expected_verify_data = null; - } - - this.securityParameters.clear(); - this.peerCertificate = null; - - this.offeredCipherSuites = null; - this.offeredCompressionMethods = null; - this.clientExtensions = null; - this.serverExtensions = null; - - this.resumedSession = false; - this.receivedChangeCipherSpec = false; - this.secure_renegotiation = false; - this.allowCertificateStatus = false; - this.expectSessionTicket = false; - } - - protected void completeHandshake() - throws IOException - { - try - { - /* - * We will now read data, until we have completed the handshake. - */ - while (this.connection_state != CS_END) - { - if (this.closed) - { - // TODO What kind of exception/alert? - } - - safeReadRecord(); - } - - this.recordStream.finaliseHandshake(); - - this.splitApplicationDataRecords = !TlsUtils.isTLSv11(getContext()); - - /* - * If this was an initial handshake, we are now ready to send and receive application data. - */ - if (!appDataReady) - { - this.appDataReady = true; - - this.tlsInputStream = new TlsInputStream(this); - this.tlsOutputStream = new TlsOutputStream(this); - } - - if (this.tlsSession != null) - { - if (this.sessionParameters == null) - { - this.sessionParameters = new SessionParameters.Builder() - .setCipherSuite(this.securityParameters.cipherSuite) - .setCompressionAlgorithm(this.securityParameters.compressionAlgorithm) - .setMasterSecret(this.securityParameters.masterSecret) - .setPeerCertificate(this.peerCertificate) - // TODO Consider filtering extensions that aren't relevant to resumed sessions - .setServerExtensions(this.serverExtensions) - .build(); - - this.tlsSession = new TlsSessionImpl(this.tlsSession.getSessionID(), this.sessionParameters); - } - - getContext().setResumableSession(this.tlsSession); - } - - getPeer().notifyHandshakeComplete(); - } - finally - { - cleanupHandshake(); - } - } - - 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) - { - case ContentType.alert: - { - alertQueue.addData(buf, offset, len); - processAlert(); - break; - } - case ContentType.application_data: - { - if (!appDataReady) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - applicationDataQueue.addData(buf, offset, len); - processApplicationData(); - break; - } - case ContentType.change_cipher_spec: - { - processChangeCipherSpec(buf, offset, len); - break; - } - case ContentType.handshake: - { - handshakeQueue.addData(buf, offset, len); - processHandshake(); - break; - } - case ContentType.heartbeat: - { - if (!appDataReady) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - // TODO[RFC 6520] -// heartbeatQueue.addData(buf, offset, len); -// processHeartbeat(); - } - default: - /* - * Uh, we don't know this protocol. - * - * RFC2246 defines on page 13, that we should ignore this. - */ - } - } - - private void processHandshake() - throws IOException - { - boolean read; - do - { - read = false; - /* - * We need the first 4 bytes, they contain type and length of the message. - */ - if (handshakeQueue.size() >= 4) - { - byte[] beginning = new byte[4]; - handshakeQueue.read(beginning, 0, 4, 0); - ByteArrayInputStream bis = new ByteArrayInputStream(beginning); - short type = TlsUtils.readUint8(bis); - int len = TlsUtils.readUint24(bis); - - /* - * Check if we have enough bytes in the buffer to read the full message. - */ - if (handshakeQueue.size() >= (len + 4)) - { - /* - * Read the message. - */ - byte[] buf = handshakeQueue.removeData(len, 4); - - /* - * RFC 2246 7.4.9. The value handshake_messages includes all handshake messages - * starting at client hello up to, but not including, this finished message. - * [..] Note: [Also,] Hello Request messages are omitted from handshake hashes. - */ - switch (type) - { - case HandshakeType.hello_request: - break; - case HandshakeType.finished: - { - if (this.expected_verify_data == null) - { - this.expected_verify_data = createVerifyData(!getContext().isServer()); - } - - // NB: Fall through to next case label - } - default: - recordStream.updateHandshakeData(beginning, 0, 4); - recordStream.updateHandshakeData(buf, 0, len); - break; - } - - /* - * Now, parse the message. - */ - handleHandshakeMessage(type, buf); - read = true; - } - } - } - while (read); - } - - private void processApplicationData() - { - /* - * There is nothing we need to do here. - * - * This function could be used for callbacks when application data arrives in the future. - */ - } - - private void processAlert() - throws IOException - { - while (alertQueue.size() >= 2) - { - /* - * An alert is always 2 bytes. Read the alert. - */ - byte[] tmp = alertQueue.removeData(2, 0); - short level = tmp[0]; - short description = tmp[1]; - - getPeer().notifyAlertReceived(level, description); - - if (level == AlertLevel.fatal) - { - /* - * RFC 2246 7.2.1. The session becomes unresumable if any connection is terminated - * without proper close_notify messages with level equal to warning. - */ - invalidateSession(); - - this.failedWithError = true; - this.closed = true; - - recordStream.safeClose(); - - throw new IOException(TLS_ERROR_MESSAGE); - } - 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) - { - handleClose(false); - } - - /* - * If it is just a warning, we continue. - */ - handleWarningMessage(description); - } - } - } - - /** - * 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. - */ - private void processChangeCipherSpec(byte[] buf, int off, int len) - throws IOException - { - for (int i = 0; i < len; ++i) - { - short message = TlsUtils.readUint8(buf, off + i); - - if (message != ChangeCipherSpec.change_cipher_spec) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - if (this.receivedChangeCipherSpec - || alertQueue.size() > 0 - || handshakeQueue.size() > 0) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - recordStream.receivedReadCipherSpec(); - - this.receivedChangeCipherSpec = true; - - handleChangeCipherSpecMessage(); - } - } - - protected int applicationDataAvailable() - throws IOException - { - return applicationDataQueue.size(); - } - - /** - * 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. - * @return The number of bytes read. - * @throws IOException If something goes wrong during reading data. - */ - protected int readApplicationData(byte[] buf, int offset, int len) - throws IOException - { - if (len < 1) - { - return 0; - } - - while (applicationDataQueue.size() == 0) - { - /* - * We need to read some data. - */ - if (this.closed) - { - if (this.failedWithError) - { - /* - * Something went terribly wrong, we should throw an IOException - */ - throw new IOException(TLS_ERROR_MESSAGE); - } - - /* - * Connection has been closed, there is no more data to read. - */ - return -1; - } - - safeReadRecord(); - } - - len = Math.min(len, applicationDataQueue.size()); - applicationDataQueue.removeData(buf, offset, len, 0); - return len; - } - - protected void safeReadRecord() - throws IOException - { - try - { - if (!recordStream.readRecord()) - { - // TODO It would be nicer to allow graceful connection close if between records -// this.failWithError(AlertLevel.warning, AlertDescription.close_notify); - throw new EOFException(); - } - } - catch (TlsFatalAlert e) - { - if (!this.closed) - { - this.failWithError(AlertLevel.fatal, e.getAlertDescription(), "Failed to read record", e); - } - throw e; - } - catch (IOException e) - { - if (!this.closed) - { - this.failWithError(AlertLevel.fatal, AlertDescription.internal_error, "Failed to read record", e); - } - throw e; - } - catch (RuntimeException e) - { - if (!this.closed) - { - this.failWithError(AlertLevel.fatal, AlertDescription.internal_error, "Failed to read record", e); - } - throw e; - } - } - - 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) - { - this.failWithError(AlertLevel.fatal, e.getAlertDescription(), "Failed to write record", e); - } - throw e; - } - catch (IOException e) - { - if (!closed) - { - this.failWithError(AlertLevel.fatal, AlertDescription.internal_error, "Failed to write record", e); - } - throw e; - } - catch (RuntimeException e) - { - if (!closed) - { - this.failWithError(AlertLevel.fatal, AlertDescription.internal_error, "Failed to write record", e); - } - throw e; - } - } - - /** - * Send some application data to the remote system. - * <p/> - * 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. - */ - 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) - { - /* - * RFC 5246 6.2.1. Zero-length fragments of Application data MAY be sent as they are - * potentially useful as a traffic analysis countermeasure. - * - * NOTE: Actually, implementations appear to have settled on 1/n-1 record splitting. - */ - - if (this.splitApplicationDataRecords) - { - /* - * Protect against known IV attack! - * - * DO NOT REMOVE THIS CODE, EXCEPT YOU KNOW EXACTLY WHAT YOU ARE DOING HERE. - */ - safeWriteRecord(ContentType.application_data, buf, offset, 1); - ++offset; - --len; - } - - if (len > 0) - { - // Fragment data according to the current fragment limit. - int toWrite = Math.min(len, recordStream.getPlaintextLimit()); - safeWriteRecord(ContentType.application_data, buf, offset, toWrite); - offset += toWrite; - len -= toWrite; - } - } - } - - protected void writeHandshakeMessage(byte[] buf, int off, int len) throws IOException - { - while (len > 0) - { - // Fragment data according to the current fragment limit. - int toWrite = Math.min(len, recordStream.getPlaintextLimit()); - safeWriteRecord(ContentType.handshake, buf, off, toWrite); - off += toWrite; - len -= toWrite; - } - } - - /** - * @return An OutputStream which can be used to send data. - */ - public OutputStream getOutputStream() - { - return this.tlsOutputStream; - } - - /** - * @return An InputStream which can be used to read data. - */ - public InputStream getInputStream() - { - return this.tlsInputStream; - } - - /** - * Terminate this connection with an alert. Can be used for normal closure too. - * - * @param alertLevel - * See {@link AlertLevel} for values. - * @param alertDescription - * See {@link AlertDescription} for values. - * @throws IOException - * If alert was fatal. - */ - protected void failWithError(short alertLevel, short alertDescription, String message, Exception cause) - throws IOException - { - /* - * Check if the connection is still open. - */ - if (!closed) - { - /* - * Prepare the message - */ - this.closed = true; - - if (alertLevel == AlertLevel.fatal) - { - /* - * RFC 2246 7.2.1. The session becomes unresumable if any connection is terminated - * without proper close_notify messages with level equal to warning. - */ - // TODO This isn't quite in the right place. Also, as of TLS 1.1 the above is obsolete. - invalidateSession(); - - this.failedWithError = true; - } - raiseAlert(alertLevel, alertDescription, message, cause); - recordStream.safeClose(); - if (alertLevel != AlertLevel.fatal) - { - return; - } - } - - throw new IOException(TLS_ERROR_MESSAGE); - } - - protected void invalidateSession() - { - if (this.sessionParameters != null) - { - this.sessionParameters.clear(); - this.sessionParameters = null; - } - - if (this.tlsSession != null) - { - this.tlsSession.invalidate(); - this.tlsSession = null; - } - } - - protected void processFinishedMessage(ByteArrayInputStream buf) - throws IOException - { - byte[] verify_data = TlsUtils.readFully(expected_verify_data.length, buf); - - assertEmpty(buf); - - /* - * Compare both checksums. - */ - if (!Arrays.constantTimeAreEqual(expected_verify_data, verify_data)) - { - /* - * Wrong checksum in the finished message. - */ - throw new TlsFatalAlert(AlertDescription.decrypt_error); - } - } - - protected void raiseAlert(short alertLevel, short alertDescription, String message, Exception cause) - throws IOException - { - getPeer().notifyAlertRaised(alertLevel, alertDescription, message, cause); - - byte[] error = new byte[2]; - error[0] = (byte)alertLevel; - error[1] = (byte)alertDescription; - - safeWriteRecord(ContentType.alert, error, 0, 2); - } - - protected void raiseWarning(short alertDescription, String message) - throws IOException - { - raiseAlert(AlertLevel.warning, alertDescription, message, null); - } - - protected void sendCertificateMessage(Certificate certificate) - throws IOException - { - if (certificate == null) - { - certificate = Certificate.EMPTY_CHAIN; - } - - if (certificate.getLength() == 0) - { - TlsContext context = getContext(); - if (!context.isServer()) - { - ProtocolVersion serverVersion = getContext().getServerVersion(); - if (serverVersion.isSSL()) - { - String message = serverVersion.toString() + " client didn't provide credentials"; - raiseWarning(AlertDescription.no_certificate, message); - return; - } - } - } - - HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate); - - certificate.encode(message); - - message.writeToRecordStream(); - } - - 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 - { - byte[] verify_data = createVerifyData(getContext().isServer()); - - HandshakeMessage message = new HandshakeMessage(HandshakeType.finished, verify_data.length); - - message.write(verify_data); - - message.writeToRecordStream(); - } - - protected void sendSupplementalDataMessage(Vector supplementalData) - throws IOException - { - HandshakeMessage message = new HandshakeMessage(HandshakeType.supplemental_data); - - writeSupplementalData(message, supplementalData); - - message.writeToRecordStream(); - } - - protected byte[] createVerifyData(boolean isServer) - { - TlsContext context = getContext(); - - if (isServer) - { - return TlsUtils.calculateVerifyData(context, ExporterLabel.server_finished, - getCurrentPRFHash(getContext(), recordStream.getHandshakeHash(), TlsUtils.SSL_SERVER)); - } - - return TlsUtils.calculateVerifyData(context, ExporterLabel.client_finished, - getCurrentPRFHash(getContext(), recordStream.getHandshakeHash(), TlsUtils.SSL_CLIENT)); - } - - /** - * Closes this connection. - * - * @throws IOException If something goes wrong during closing. - */ - public void close() - throws IOException - { - handleClose(true); - } - - 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, "Connection closed", null); - } - } - - protected void flush() - throws IOException - { - recordStream.flush(); - } - - protected short processMaxFragmentLengthExtension(Hashtable clientExtensions, Hashtable serverExtensions, short alertDescription) - throws IOException - { - short maxFragmentLength = TlsExtensionsUtils.getMaxFragmentLengthExtension(serverExtensions); - if (maxFragmentLength >= 0 && !this.resumedSession) - { - if (maxFragmentLength != TlsExtensionsUtils.getMaxFragmentLengthExtension(clientExtensions)) - { - throw new TlsFatalAlert(alertDescription); - } - } - return maxFragmentLength; - } - - /** - * Make sure the InputStream 'buf' now empty. Fail otherwise. - * - * @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) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - } - - protected static byte[] createRandomBlock(boolean useGMTUnixTime, RandomGenerator randomGenerator) - { - byte[] result = new byte[32]; - randomGenerator.nextBytes(result); - - if (useGMTUnixTime) - { - TlsUtils.writeGMTUnixTime(result, 0); - } - - return result; - } - - protected static byte[] createRenegotiationInfo(byte[] renegotiated_connection) - throws IOException - { - return TlsUtils.encodeOpaque8(renegotiated_connection); - } - - protected static void establishMasterSecret(TlsContext context, TlsKeyExchange keyExchange) - throws IOException - { - byte[] pre_master_secret = keyExchange.generatePremasterSecret(); - - try - { - context.getSecurityParameters().masterSecret = TlsUtils.calculateMasterSecret(context, pre_master_secret); - } - 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); - } - } - } - - /** - * 'sender' only relevant to SSLv3 - */ - protected static byte[] getCurrentPRFHash(TlsContext context, TlsHandshakeHash handshakeHash, byte[] sslSender) - { - Digest d = handshakeHash.forkPRFHash(); - - if (sslSender != null && TlsUtils.isSSL(context)) - { - d.update(sslSender, 0, sslSender.length); - } - - byte[] bs = new byte[d.getDigestSize()]; - d.doFinal(bs, 0); - return bs; - } - - protected static Hashtable readExtensions(ByteArrayInputStream input) - throws IOException - { - if (input.available() < 1) - { - return null; - } - - byte[] extBytes = TlsUtils.readOpaque16(input); - - assertEmpty(input); - - ByteArrayInputStream buf = new ByteArrayInputStream(extBytes); - - // Integer -> byte[] - Hashtable extensions = new Hashtable(); - - while (buf.available() > 0) - { - Integer extension_type = Integers.valueOf(TlsUtils.readUint16(buf)); - byte[] extension_data = TlsUtils.readOpaque16(buf); - - /* - * RFC 3546 2.3 There MUST NOT be more than one extension of the same type. - */ - if (null != extensions.put(extension_type, extension_data)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - - return extensions; - } - - protected static Vector readSupplementalDataMessage(ByteArrayInputStream input) - throws IOException - { - byte[] supp_data = TlsUtils.readOpaque24(input); - - assertEmpty(input); - - ByteArrayInputStream buf = new ByteArrayInputStream(supp_data); - - Vector supplementalData = new Vector(); - - while (buf.available() > 0) - { - int supp_data_type = TlsUtils.readUint16(buf); - byte[] data = TlsUtils.readOpaque16(buf); - - supplementalData.addElement(new SupplementalDataEntry(supp_data_type, data)); - } - - return supplementalData; - } - - protected static void writeExtensions(OutputStream output, Hashtable extensions) - throws IOException - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - Enumeration keys = extensions.keys(); - while (keys.hasMoreElements()) - { - Integer key = (Integer)keys.nextElement(); - int extension_type = key.intValue(); - byte[] extension_data = (byte[])extensions.get(key); - - TlsUtils.checkUint16(extension_type); - TlsUtils.writeUint16(extension_type, buf); - TlsUtils.writeOpaque16(extension_data, buf); - } - - byte[] extBytes = buf.toByteArray(); - - TlsUtils.writeOpaque16(extBytes, output); - } - - 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); - - int supp_data_type = entry.getDataType(); - TlsUtils.checkUint16(supp_data_type); - TlsUtils.writeUint16(supp_data_type, buf); - TlsUtils.writeOpaque16(entry.getData(), buf); - } - - byte[] supp_data = buf.toByteArray(); - - TlsUtils.writeOpaque24(supp_data, output); - } - - protected static int getPRFAlgorithm(TlsContext context, int ciphersuite) throws IOException - { - boolean isTLSv12 = TlsUtils.isTLSv12(context); - - switch (ciphersuite) - { - case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: - case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: - case CipherSuite.TLS_PSK_WITH_AES_128_CCM: - case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: - case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_PSK_WITH_AES_256_CCM: - case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_NULL_SHA256: - { - if (isTLSv12) - { - return PRFAlgorithm.tls_prf_sha256; - } - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: - { - if (isTLSv12) - { - return PRFAlgorithm.tls_prf_sha384; - } - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: - { - if (isTLSv12) - { - return PRFAlgorithm.tls_prf_sha384; - } - return PRFAlgorithm.tls_prf_legacy; - } - - default: - { - if (isTLSv12) - { - return PRFAlgorithm.tls_prf_sha256; - } - return PRFAlgorithm.tls_prf_legacy; - } - } - } - - class HandshakeMessage extends ByteArrayOutputStream - { - HandshakeMessage(short handshakeType) throws IOException - { - this(handshakeType, 60); - } - - HandshakeMessage(short handshakeType, int length) throws IOException - { - super(length + 4); - TlsUtils.writeUint8(handshakeType, this); - // Reserve space for length - count += 3; - } - - void writeToRecordStream() throws IOException - { - // Patch actual length back in - int length = count - 4; - TlsUtils.checkUint24(length); - TlsUtils.writeUint24(length, buf, 1); - writeHandshakeMessage(buf, 0, count); - buf = null; - } - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsProtocolHandler.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsProtocolHandler.java deleted file mode 100644 index 6b9e8eb0..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsProtocolHandler.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.InputStream; -import java.io.OutputStream; -import java.security.SecureRandom; - -/** - * @deprecated use TlsClientProtocol instead - */ -public class TlsProtocolHandler - extends TlsClientProtocol -{ - public TlsProtocolHandler(InputStream is, OutputStream os) - { - super(is, os); - } - - public TlsProtocolHandler(InputStream is, OutputStream os, SecureRandom sr) - { - super(is, os, sr); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSAKeyExchange.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSAKeyExchange.java deleted file mode 100644 index cd3eb0c3..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSAKeyExchange.java +++ /dev/null @@ -1,191 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Vector; - -import org.bouncycastle.asn1.x509.KeyUsage; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.RSAKeyParameters; -import org.bouncycastle.crypto.util.PublicKeyFactory; -import org.bouncycastle.util.io.Streams; - -/** - * TLS 1.0/1.1 and SSLv3 RSA key exchange. - */ -public class TlsRSAKeyExchange - extends AbstractTlsKeyExchange -{ - protected AsymmetricKeyParameter serverPublicKey = null; - - protected RSAKeyParameters rsaServerPublicKey = null; - - protected TlsEncryptionCredentials serverCredentials = null; - - protected byte[] premasterSecret; - - public TlsRSAKeyExchange(Vector supportedSignatureAlgorithms) - { - super(KeyExchangeAlgorithm.RSA, supportedSignatureAlgorithms); - } - - public void skipServerCredentials() - throws IOException - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - public void processServerCredentials(TlsCredentials serverCredentials) - throws IOException - { - if (!(serverCredentials instanceof TlsEncryptionCredentials)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - processServerCertificate(serverCredentials.getCertificate()); - - this.serverCredentials = (TlsEncryptionCredentials)serverCredentials; - } - - public void processServerCertificate(Certificate serverCertificate) - throws IOException - { - if (serverCertificate.isEmpty()) - { - throw new TlsFatalAlert(AlertDescription.bad_certificate); - } - - org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); - - SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - try - { - this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); - } - catch (RuntimeException e) - { - throw new TlsFatalAlert(AlertDescription.unsupported_certificate); - } - - // Sanity check the PublicKeyFactory - if (this.serverPublicKey.isPrivate()) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - this.rsaServerPublicKey = validateRSAPublicKey((RSAKeyParameters)this.serverPublicKey); - - TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyEncipherment); - - super.processServerCertificate(serverCertificate); - } - - public void validateCertificateRequest(CertificateRequest certificateRequest) - throws IOException - { - short[] types = certificateRequest.getCertificateTypes(); - for (int i = 0; i < types.length; ++i) - { - switch (types[i]) - { - case ClientCertificateType.rsa_sign: - case ClientCertificateType.dss_sign: - case ClientCertificateType.ecdsa_sign: - break; - default: - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - } - - public void processClientCredentials(TlsCredentials clientCredentials) - throws IOException - { - if (!(clientCredentials instanceof TlsSignerCredentials)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public void generateClientKeyExchange(OutputStream output) - throws IOException - { - this.premasterSecret = TlsRSAUtils.generateEncryptedPreMasterSecret(context, rsaServerPublicKey, output); - } - - public void processClientKeyExchange(InputStream input) - throws IOException - { - byte[] encryptedPreMasterSecret; - if (TlsUtils.isSSL(context)) - { - // TODO Do any SSLv3 clients actually include the length? - encryptedPreMasterSecret = Streams.readAll(input); - } - else - { - encryptedPreMasterSecret = TlsUtils.readOpaque16(input); - } - - this.premasterSecret = serverCredentials.decryptPreMasterSecret(encryptedPreMasterSecret); - } - - public byte[] generatePremasterSecret() - throws IOException - { - if (this.premasterSecret == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - byte[] tmp = this.premasterSecret; - this.premasterSecret = null; - return tmp; - } - - // Would be needed to process RSA_EXPORT server key exchange - // protected void processRSAServerKeyExchange(InputStream is, Signer signer) throws IOException - // { - // InputStream sigIn = is; - // if (signer != null) - // { - // sigIn = new SignerInputStream(is, signer); - // } - // - // byte[] modulusBytes = TlsUtils.readOpaque16(sigIn); - // byte[] exponentBytes = TlsUtils.readOpaque16(sigIn); - // - // if (signer != null) - // { - // byte[] sigByte = TlsUtils.readOpaque16(is); - // - // if (!signer.verifySignature(sigByte)) - // { - // handler.failWithError(AlertLevel.fatal, AlertDescription.bad_certificate); - // } - // } - // - // BigInteger modulus = new BigInteger(1, modulusBytes); - // BigInteger exponent = new BigInteger(1, exponentBytes); - // - // this.rsaServerPublicKey = validateRSAPublicKey(new RSAKeyParameters(false, modulus, - // exponent)); - // } - - protected RSAKeyParameters validateRSAPublicKey(RSAKeyParameters key) - throws IOException - { - // TODO What is the minimum bit length required? - // key.getModulus().bitLength(); - - if (!key.getExponent().isProbablePrime(2)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - return key; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSASigner.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSASigner.java deleted file mode 100644 index 35538a70..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSASigner.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.crypto.AsymmetricBlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.digests.NullDigest; -import org.bouncycastle.crypto.encodings.PKCS1Encoding; -import org.bouncycastle.crypto.engines.RSABlindedEngine; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.crypto.params.RSAKeyParameters; -import org.bouncycastle.crypto.signers.GenericSigner; -import org.bouncycastle.crypto.signers.RSADigestSigner; - -public class TlsRSASigner - extends AbstractTlsSigner -{ - public byte[] generateRawSignature(SignatureAndHashAlgorithm algorithm, - AsymmetricKeyParameter privateKey, byte[] hash) - throws CryptoException - { - Signer signer = makeSigner(algorithm, true, true, - new ParametersWithRandom(privateKey, this.context.getSecureRandom())); - signer.update(hash, 0, hash.length); - return signer.generateSignature(); - } - - public boolean verifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, - AsymmetricKeyParameter publicKey, byte[] hash) - throws CryptoException - { - Signer signer = makeSigner(algorithm, true, false, publicKey); - signer.update(hash, 0, hash.length); - return signer.verifySignature(sigBytes); - } - - public Signer createSigner(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey) - { - return makeSigner(algorithm, false, true, new ParametersWithRandom(privateKey, this.context.getSecureRandom())); - } - - public Signer createVerifyer(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter publicKey) - { - return makeSigner(algorithm, false, false, publicKey); - } - - public boolean isValidPublicKey(AsymmetricKeyParameter publicKey) - { - return publicKey instanceof RSAKeyParameters && !publicKey.isPrivate(); - } - - protected Signer makeSigner(SignatureAndHashAlgorithm algorithm, boolean raw, boolean forSigning, - CipherParameters cp) - { - if ((algorithm != null) != TlsUtils.isTLSv12(context)) - { - throw new IllegalStateException(); - } - - if (algorithm != null && algorithm.getSignature() != SignatureAlgorithm.rsa) - { - throw new IllegalStateException(); - } - - Digest d; - if (raw) - { - d = new NullDigest(); - } - else if (algorithm == null) - { - d = new CombinedHash(); - } - else - { - d = TlsUtils.createHash(algorithm.getHash()); - } - - Signer s; - if (algorithm != null) - { - /* - * 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, TlsUtils.getOIDForHashAlgorithm(algorithm.getHash())); - } - else - { - /* - * RFC 5246 4.7. Note that earlier versions of TLS used a different RSA signature scheme - * that did not include a DigestInfo encoding. - */ - s = new GenericSigner(createRSAImpl(), d); - } - s.init(forSigning, cp); - return s; - } - - 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. - * Accordingly, implementations that use static RSA keys MUST use RSA blinding or some other - * anti-timing technique, as described in [TIMING]. - */ - return new PKCS1Encoding(new RSABlindedEngine()); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java deleted file mode 100644 index 1fe4fa52..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsRSAUtils.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.OutputStream; - -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.encodings.PKCS1Encoding; -import org.bouncycastle.crypto.engines.RSABlindedEngine; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.crypto.params.RSAKeyParameters; -import org.bouncycastle.util.Arrays; - -public class TlsRSAUtils -{ - public static byte[] generateEncryptedPreMasterSecret(TlsContext context, RSAKeyParameters rsaServerPublicKey, - OutputStream output) throws IOException - { - /* - * Choose a PremasterSecret and send it encrypted to the server - */ - byte[] premasterSecret = new byte[48]; - context.getSecureRandom().nextBytes(premasterSecret); - TlsUtils.writeVersion(context.getClientVersion(), premasterSecret, 0); - - PKCS1Encoding encoding = new PKCS1Encoding(new RSABlindedEngine()); - encoding.init(true, new ParametersWithRandom(rsaServerPublicKey, context.getSecureRandom())); - - try - { - byte[] encryptedPreMasterSecret = encoding.processBlock(premasterSecret, 0, premasterSecret.length); - - if (TlsUtils.isSSL(context)) - { - // TODO Do any SSLv3 servers actually expect the length? - output.write(encryptedPreMasterSecret); - } - else - { - TlsUtils.writeOpaque16(encryptedPreMasterSecret, output); - } - } - catch (InvalidCipherTextException e) - { - /* - * This should never happen, only during decryption. - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - return premasterSecret; - } - - /** - * @deprecated {@link TlsEncryptionCredentials#decryptPreMasterSecret(byte[])} is expected to decrypt safely - */ - public static byte[] safeDecryptPreMasterSecret(TlsContext context, TlsEncryptionCredentials encryptionCredentials, - byte[] encryptedPreMasterSecret) throws IOException - { - return encryptionCredentials.decryptPreMasterSecret(encryptedPreMasterSecret); - } - - public static byte[] safeDecryptPreMasterSecret(TlsContext context, RSAKeyParameters rsaServerPrivateKey, - byte[] encryptedPreMasterSecret) - { - /* - * RFC 5246 7.4.7.1. - */ - ProtocolVersion clientVersion = context.getClientVersion(); - - // TODO Provide as configuration option? - boolean versionNumberCheckDisabled = false; - - /* - * Generate 48 random bytes we can use as a Pre-Master-Secret, if the - * PKCS1 padding check should fail. - */ - byte[] fallback = new byte[48]; - context.getSecureRandom().nextBytes(fallback); - - byte[] M = Arrays.clone(fallback); - try - { - PKCS1Encoding encoding = new PKCS1Encoding(new RSABlindedEngine(), fallback); - encoding.init(false, - new ParametersWithRandom(rsaServerPrivateKey, context.getSecureRandom())); - - M = encoding.processBlock(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.length); - } - catch (Exception e) - { - /* - * This should never happen since the decryption should never throw an exception - * and return a random value instead. - * - * 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 - * expected. Instead, it MUST continue the handshake with a randomly generated - * premaster secret. - */ - } - - /* - * If ClientHello.client_version is TLS 1.1 or higher, server implementations MUST - * check the version number [..]. - */ - 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. - * - * So there is nothing to do here. - */ - } - else - { - /* - * OK, we need to compare the version number in the decrypted Pre-Master-Secret with the - * clientVersion received during the handshake. If they don't match, we replace the - * decrypted Pre-Master-Secret with a random one. - */ - int correct = (clientVersion.getMajorVersion() ^ (M[0] & 0xff)) - | (clientVersion.getMinorVersion() ^ (M[1] & 0xff)); - correct |= correct >> 1; - correct |= correct >> 2; - correct |= correct >> 4; - int mask = ~((correct & 1) - 1); - - /* - * mask will be all bits set to 0xff if the version number differed. - */ - for (int i = 0; i < 48; i++) - { - M[i] = (byte)((M[i] & (~mask)) | (fallback[i] & mask)); - } - } - return M; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSRPKeyExchange.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsSRPKeyExchange.java deleted file mode 100644 index 9e81fe67..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSRPKeyExchange.java +++ /dev/null @@ -1,205 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigInteger; -import java.util.Vector; - -import org.bouncycastle.asn1.x509.KeyUsage; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.agreement.srp.SRP6Client; -import org.bouncycastle.crypto.agreement.srp.SRP6Util; -import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.util.PublicKeyFactory; -import org.bouncycastle.util.BigIntegers; -import org.bouncycastle.util.io.TeeInputStream; - -/** - * TLS 1.1 SRP key exchange (RFC 5054). - */ -public class TlsSRPKeyExchange extends AbstractTlsKeyExchange -{ - protected TlsSigner tlsSigner; - protected byte[] identity; - protected byte[] password; - - protected AsymmetricKeyParameter serverPublicKey = null; - - protected byte[] s = null; - protected BigInteger B = null; - protected SRP6Client srpClient = new SRP6Client(); - - public TlsSRPKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, byte[] identity, byte[] password) - { - super(keyExchange, supportedSignatureAlgorithms); - - switch (keyExchange) - { - case KeyExchangeAlgorithm.SRP: - this.tlsSigner = null; - break; - case KeyExchangeAlgorithm.SRP_RSA: - this.tlsSigner = new TlsRSASigner(); - break; - case KeyExchangeAlgorithm.SRP_DSS: - this.tlsSigner = new TlsDSSSigner(); - break; - default: - throw new IllegalArgumentException("unsupported key exchange algorithm"); - } - - this.keyExchange = keyExchange; - this.identity = identity; - this.password = password; - } - - public void init(TlsContext context) - { - super.init(context); - - if (this.tlsSigner != null) { - this.tlsSigner.init(context); - } - } - - public void skipServerCredentials() throws IOException - { - if (tlsSigner != null) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - } - - public void processServerCertificate(Certificate serverCertificate) throws IOException - { - if (tlsSigner == null) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - if (serverCertificate.isEmpty()) - { - throw new TlsFatalAlert(AlertDescription.bad_certificate); - } - - org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0); - - SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - try - { - this.serverPublicKey = PublicKeyFactory.createKey(keyInfo); - } - catch (RuntimeException e) - { - throw new TlsFatalAlert(AlertDescription.unsupported_certificate); - } - - if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) - { - throw new TlsFatalAlert(AlertDescription.certificate_unknown); - } - - TlsUtils.validateKeyUsage(x509Cert, KeyUsage.digitalSignature); - - super.processServerCertificate(serverCertificate); - } - - public boolean requiresServerKeyExchange() - { - return true; - } - - public void processServerKeyExchange(InputStream input) throws IOException - { - SecurityParameters securityParameters = context.getSecurityParameters(); - - SignerInputBuffer buf = null; - InputStream teeIn = input; - - if (tlsSigner != null) - { - buf = new SignerInputBuffer(); - teeIn = new TeeInputStream(input, buf); - } - - byte[] NBytes = TlsUtils.readOpaque16(teeIn); - byte[] gBytes = TlsUtils.readOpaque16(teeIn); - byte[] sBytes = TlsUtils.readOpaque8(teeIn); - byte[] BBytes = TlsUtils.readOpaque16(teeIn); - - if (buf != null) - { - DigitallySigned signed_params = DigitallySigned.parse(context, input); - - Signer signer = initVerifyer(tlsSigner, signed_params.getAlgorithm(), securityParameters); - buf.updateSigner(signer); - if (!signer.verifySignature(signed_params.getSignature())) - { - throw new TlsFatalAlert(AlertDescription.decrypt_error); - } - } - - BigInteger N = new BigInteger(1, NBytes); - BigInteger g = new BigInteger(1, gBytes); - - // TODO Validate group parameters (see RFC 5054) -// throw new TlsFatalAlert(AlertDescription.insufficient_security); - - this.s = sBytes; - - /* - * RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter" alert if - * B % N = 0. - */ - try - { - this.B = SRP6Util.validatePublicValue(N, new BigInteger(1, BBytes)); - } - catch (CryptoException e) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - this.srpClient.init(N, g, TlsUtils.createHash(HashAlgorithm.sha1), context.getSecureRandom()); - } - - public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - public void processClientCredentials(TlsCredentials clientCredentials) throws IOException - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - public void generateClientKeyExchange(OutputStream output) throws IOException - { - BigInteger A = srpClient.generateClientCredentials(s, this.identity, this.password); - TlsUtils.writeOpaque16(BigIntegers.asUnsignedByteArray(A), output); - } - - 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) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - } - - protected Signer initVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, SecurityParameters securityParameters) - { - Signer signer = tlsSigner.createVerifyer(algorithm, this.serverPublicKey); - signer.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length); - signer.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); - return signer; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSRPUtils.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsSRPUtils.java deleted file mode 100644 index c1b3365e..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSRPUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.Hashtable; - -import org.bouncycastle.util.Integers; - -public class TlsSRPUtils -{ - public static final Integer EXT_SRP = Integers.valueOf(ExtensionType.srp); - - public static void addSRPExtension(Hashtable extensions, byte[] identity) throws IOException - { - extensions.put(EXT_SRP, createSRPExtension(identity)); - } - - public static byte[] getSRPExtension(Hashtable extensions) throws IOException - { - byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_SRP); - return extensionData == null ? null : readSRPExtension(extensionData); - } - - public static byte[] createSRPExtension(byte[] identity) throws IOException - { - if (identity == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - return TlsUtils.encodeOpaque8(identity); - } - - public static byte[] readSRPExtension(byte[] extensionData) throws IOException - { - if (extensionData == null) - { - throw new IllegalArgumentException("'extensionData' cannot be null"); - } - - ByteArrayInputStream buf = new ByteArrayInputStream(extensionData); - byte[] identity = TlsUtils.readOpaque8(buf); - - TlsProtocol.assertEmpty(buf); - - return identity; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSRTPUtils.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsSRTPUtils.java deleted file mode 100644 index da98b7a1..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSRTPUtils.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Hashtable; - -import org.bouncycastle.util.Integers; - -/** - * RFC 5764 DTLS Extension to Establish Keys for SRTP. - */ -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 - { - extensions.put(EXT_use_srtp, createUseSRTPExtension(useSRTPData)); - } - - public static UseSRTPData getUseSRTPExtension(Hashtable extensions) - throws IOException - { - byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_use_srtp); - return extensionData == null ? null : readUseSRTPExtension(extensionData); - } - - public static byte[] createUseSRTPExtension(UseSRTPData useSRTPData) - throws IOException - { - if (useSRTPData == null) - { - throw new IllegalArgumentException("'useSRTPData' cannot be null"); - } - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - // SRTPProtectionProfiles - TlsUtils.writeUint16ArrayWithUint16Length(useSRTPData.getProtectionProfiles(), buf); - - // srtp_mki - TlsUtils.writeOpaque8(useSRTPData.getMki(), buf); - - return buf.toByteArray(); - } - - public static UseSRTPData readUseSRTPExtension(byte[] extensionData) - throws IOException - { - if (extensionData == null) - { - throw new IllegalArgumentException("'extensionData' cannot be null"); - } - - ByteArrayInputStream buf = new ByteArrayInputStream(extensionData); - - // SRTPProtectionProfiles - int length = TlsUtils.readUint16(buf); - if (length < 2 || (length & 1) != 0) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - int[] protectionProfiles = TlsUtils.readUint16Array(length / 2, buf); - - // srtp_mki - byte[] mki = TlsUtils.readOpaque8(buf); - - TlsProtocol.assertEmpty(buf); - - return new UseSRTPData(protectionProfiles, mki); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsServer.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsServer.java deleted file mode 100644 index d97c16d5..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsServer.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.util.Hashtable; -import java.util.Vector; - -public interface TlsServer - extends TlsPeer -{ - void init(TlsServerContext context); - - void notifyClientVersion(ProtocolVersion clientVersion) throws IOException; - - void notifyOfferedCipherSuites(int[] offeredCipherSuites) - throws IOException; - - void notifyOfferedCompressionMethods(short[] offeredCompressionMethods) - throws IOException; - - // Hashtable is (Integer -> byte[]) - void processClientExtensions(Hashtable clientExtensions) - throws IOException; - - ProtocolVersion getServerVersion() - throws IOException; - - int getSelectedCipherSuite() - throws IOException; - - short getSelectedCompressionMethod() - throws IOException; - - // Hashtable is (Integer -> byte[]) - Hashtable getServerExtensions() - throws IOException; - - // Vector is (SupplementalDataEntry) - Vector getServerSupplementalData() - throws IOException; - - TlsCredentials getCredentials() - throws IOException; - - /** - * This method will be called (only) if the server included an extension of type - * "status_request" with empty "extension_data" in the extended server hello. See <i>RFC 3546 - * 3.6. Certificate Status Request</i>. If a non-null {@link CertificateStatus} is returned, it - * is sent to the client as a handshake message of type "certificate_status". - * - * @return A {@link CertificateStatus} to be sent to the client (or null for none). - * @throws IOException - */ - CertificateStatus getCertificateStatus() - throws IOException; - - TlsKeyExchange getKeyExchange() - throws IOException; - - CertificateRequest getCertificateRequest() - throws IOException; - - // Vector is (SupplementalDataEntry) - void processClientSupplementalData(Vector clientSupplementalData) - throws IOException; - - /** - * Called by the protocol handler to report the client certificate, only if - * {@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). - * @throws IOException - */ - void notifyClientCertificate(Certificate clientCertificate) - throws IOException; - - /** - * RFC 5077 3.3. NewSessionTicket Handshake Message. - * <p> - * This method will be called (only) if a NewSessionTicket extension was sent by the server. See - * <i>RFC 5077 4. Recommended Ticket Construction</i> for recommended format and protection. - * - * @return The ticket. - * @throws IOException - */ - NewSessionTicket getNewSessionTicket() - throws IOException; -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsServerContext.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsServerContext.java deleted file mode 100644 index 37a0c952..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsServerContext.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public interface TlsServerContext - extends TlsContext -{ -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsServerContextImpl.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsServerContextImpl.java deleted file mode 100644 index 48f028a0..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsServerContextImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.security.SecureRandom; - -class TlsServerContextImpl - extends AbstractTlsContext - implements TlsServerContext -{ - TlsServerContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) - { - super(secureRandom, securityParameters); - } - - public boolean isServer() - { - return true; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsServerProtocol.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsServerProtocol.java deleted file mode 100644 index 8499b83e..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsServerProtocol.java +++ /dev/null @@ -1,778 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.SecureRandom; -import java.util.Vector; - -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.util.PublicKeyFactory; -import org.bouncycastle.util.Arrays; - -public class TlsServerProtocol - extends TlsProtocol -{ - protected TlsServer tlsServer = null; - protected TlsServerContextImpl tlsServerContext = null; - - protected TlsKeyExchange keyExchange = null; - protected TlsCredentials serverCredentials = null; - protected CertificateRequest certificateRequest = null; - - protected short clientCertificateType = -1; - protected TlsHandshakeHash prepareFinishHash = null; - - 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. - */ - public void accept(TlsServer tlsServer) - throws IOException - { - if (tlsServer == null) - { - throw new IllegalArgumentException("'tlsServer' cannot be null"); - } - if (this.tlsServer != null) - { - throw new IllegalStateException("'accept' can only be called once"); - } - - this.tlsServer = tlsServer; - - this.securityParameters = new SecurityParameters(); - this.securityParameters.entity = ConnectionEnd.server; - - this.tlsServerContext = new TlsServerContextImpl(secureRandom, securityParameters); - - this.securityParameters.serverRandom = createRandomBlock(tlsServer.shouldUseGMTUnixTime(), - tlsServerContext.getNonceRandomGenerator()); - - this.tlsServer.init(tlsServerContext); - this.recordStream.init(tlsServerContext); - - this.recordStream.setRestrictReadVersion(false); - - completeHandshake(); - } - - protected void cleanupHandshake() - { - super.cleanupHandshake(); - - this.keyExchange = null; - this.serverCredentials = null; - this.certificateRequest = null; - this.prepareFinishHash = null; - } - - protected AbstractTlsContext getContext() - { - return tlsServerContext; - } - - protected TlsPeer getPeer() - { - return tlsServer; - } - - 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: - { - receiveClientHelloMessage(buf); - this.connection_state = CS_CLIENT_HELLO; - - sendServerHelloMessage(); - this.connection_state = CS_SERVER_HELLO; - - Vector serverSupplementalData = tlsServer.getServerSupplementalData(); - if (serverSupplementalData != null) - { - sendSupplementalDataMessage(serverSupplementalData); - } - this.connection_state = CS_SERVER_SUPPLEMENTAL_DATA; - - this.keyExchange = tlsServer.getKeyExchange(); - this.keyExchange.init(getContext()); - - this.serverCredentials = tlsServer.getCredentials(); - - Certificate serverCertificate = null; - - if (this.serverCredentials == null) - { - this.keyExchange.skipServerCredentials(); - } - else - { - this.keyExchange.processServerCredentials(this.serverCredentials); - - serverCertificate = this.serverCredentials.getCertificate(); - sendCertificateMessage(serverCertificate); - } - this.connection_state = CS_SERVER_CERTIFICATE; - - // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus - if (serverCertificate == null || serverCertificate.isEmpty()) - { - this.allowCertificateStatus = false; - } - - if (this.allowCertificateStatus) - { - CertificateStatus certificateStatus = tlsServer.getCertificateStatus(); - if (certificateStatus != null) - { - sendCertificateStatusMessage(certificateStatus); - } - } - - this.connection_state = CS_CERTIFICATE_STATUS; - - byte[] serverKeyExchange = this.keyExchange.generateServerKeyExchange(); - if (serverKeyExchange != null) - { - sendServerKeyExchangeMessage(serverKeyExchange); - } - this.connection_state = CS_SERVER_KEY_EXCHANGE; - - if (this.serverCredentials != null) - { - this.certificateRequest = tlsServer.getCertificateRequest(); - if (this.certificateRequest != null) - { - this.keyExchange.validateCertificateRequest(certificateRequest); - - sendCertificateRequestMessage(certificateRequest); - - TlsUtils.trackHashAlgorithms(this.recordStream.getHandshakeHash(), - this.certificateRequest.getSupportedSignatureAlgorithms()); - } - } - this.connection_state = CS_CERTIFICATE_REQUEST; - - sendServerHelloDoneMessage(); - this.connection_state = CS_SERVER_HELLO_DONE; - - this.recordStream.getHandshakeHash().sealHashAlgorithms(); - - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - break; - } - 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: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - break; - } - 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) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - receiveCertificateMessage(buf); - this.connection_state = CS_CLIENT_CERTIFICATE; - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - break; - } - 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) - { - this.keyExchange.skipClientCredentials(); - } - else - { - if (TlsUtils.isTLSv12(getContext())) - { - /* - * RFC 5246 If no suitable certificate is available, the client MUST send a - * certificate message containing no certificates. - * - * NOTE: In previous RFCs, this was SHOULD instead of MUST. - */ - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - else if (TlsUtils.isSSL(getContext())) - { - if (this.peerCertificate == null) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - } - else - { - notifyClientCertificate(Certificate.EMPTY_CHAIN); - } - } - // NB: Fall through to next case label - } - case CS_CLIENT_CERTIFICATE: - { - receiveClientKeyExchangeMessage(buf); - this.connection_state = CS_CLIENT_KEY_EXCHANGE; - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - break; - } - 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 (!expectCertificateVerifyMessage()) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - receiveCertificateVerifyMessage(buf); - this.connection_state = CS_CERTIFICATE_VERIFY; - - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - break; - } - case HandshakeType.finished: - { - switch (this.connection_state) - { - case CS_CLIENT_KEY_EXCHANGE: - { - if (expectCertificateVerifyMessage()) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - // NB: Fall through to next case label - } - case CS_CERTIFICATE_VERIFY: - { - processFinishedMessage(buf); - this.connection_state = CS_CLIENT_FINISHED; - - if (this.expectSessionTicket) - { - sendNewSessionTicketMessage(tlsServer.getNewSessionTicket()); - sendChangeCipherSpecMessage(); - } - this.connection_state = CS_SERVER_SESSION_TICKET; - - sendFinishedMessage(); - this.connection_state = CS_SERVER_FINISHED; - this.connection_state = CS_END; - break; - } - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - break; - } - case HandshakeType.hello_request: - case HandshakeType.hello_verify_request: - case HandshakeType.server_hello: - case HandshakeType.server_key_exchange: - case HandshakeType.certificate_request: - case HandshakeType.server_hello_done: - case HandshakeType.session_ticket: - default: - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - } - - 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 (TlsUtils.isSSL(getContext()) && certificateRequest != null) - { - notifyClientCertificate(Certificate.EMPTY_CHAIN); - } - break; - } - default: - { - super.handleWarningMessage(description); - } - } - } - - protected void notifyClientCertificate(Certificate clientCertificate) - throws IOException - { - if (certificateRequest == null) - { - throw new IllegalStateException(); - } - - if (this.peerCertificate != null) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - this.peerCertificate = clientCertificate; - - if (clientCertificate.isEmpty()) - { - this.keyExchange.skipClientCredentials(); - } - else - { - - /* - * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request - * message was non-empty, one of the certificates in the certificate chain SHOULD be - * issued by one of the listed CAs. - */ - - this.clientCertificateType = TlsUtils.getClientCertificateType(clientCertificate, - this.serverCredentials.getCertificate()); - - this.keyExchange.processClientCertificate(clientCertificate); - } - - /* - * RFC 5246 7.4.6. If the client does not send any certificates, the server MAY at its - * discretion either continue the handshake without client authentication, or respond with a - * fatal handshake_failure alert. Also, if some aspect of the certificate chain was - * unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its - * discretion either continue the handshake (considering the client unauthenticated) or send - * a fatal alert. - */ - this.tlsServer.notifyClientCertificate(clientCertificate); - } - - protected void receiveCertificateMessage(ByteArrayInputStream buf) - throws IOException - { - Certificate clientCertificate = Certificate.parse(buf); - - assertEmpty(buf); - - notifyClientCertificate(clientCertificate); - } - - protected void receiveCertificateVerifyMessage(ByteArrayInputStream buf) - throws IOException - { - DigitallySigned clientCertificateVerify = DigitallySigned.parse(getContext(), buf); - - assertEmpty(buf); - - // Verify the CertificateVerify message contains a correct signature. - boolean verified = false; - try - { - byte[] certificateVerifyHash; - if (TlsUtils.isTLSv12(getContext())) - { - certificateVerifyHash = prepareFinishHash.getFinalHash(clientCertificateVerify.getAlgorithm().getHash()); - } - else - { - certificateVerifyHash = TlsProtocol.getCurrentPRFHash(getContext(), prepareFinishHash, null); - } - - org.bouncycastle.asn1.x509.Certificate x509Cert = this.peerCertificate.getCertificateAt(0); - SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(keyInfo); - - TlsSigner tlsSigner = TlsUtils.createTlsSigner(this.clientCertificateType); - tlsSigner.init(getContext()); - verified = tlsSigner.verifyRawSignature(clientCertificateVerify.getAlgorithm(), - clientCertificateVerify.getSignature(), publicKey, certificateVerifyHash); - } - catch (Exception e) - { - } - - if (!verified) - { - throw new TlsFatalAlert(AlertDescription.decrypt_error); - } - } - - protected void receiveClientHelloMessage(ByteArrayInputStream buf) - throws IOException - { - ProtocolVersion client_version = TlsUtils.readVersion(buf); - if (client_version.isDTLS()) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - byte[] client_random = TlsUtils.readFully(32, buf); - - /* - * TODO RFC 5077 3.4. If a ticket is presented by the client, the server MUST NOT attempt to - * use the Session ID in the ClientHello for stateful session resumption. - */ - byte[] sessionID = TlsUtils.readOpaque8(buf); - if (sessionID.length > 32) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - /* - * TODO RFC 5246 7.4.1.2. If the session_id field is not empty (implying a session - * resumption request), this vector MUST include at least the cipher_suite from that - * session. - */ - int cipher_suites_length = TlsUtils.readUint16(buf); - if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - this.offeredCipherSuites = TlsUtils.readUint16Array(cipher_suites_length / 2, buf); - - /* - * TODO RFC 5246 7.4.1.2. If the session_id field is not empty (implying a session - * resumption request), it MUST include the compression_method from that session. - */ - int compression_methods_length = TlsUtils.readUint8(buf); - if (compression_methods_length < 1) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - this.offeredCompressionMethods = TlsUtils.readUint8Array(compression_methods_length, buf); - - /* - * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore - * extensions appearing in the client hello, and send a server hello containing no - * extensions. - */ - this.clientExtensions = readExtensions(buf); - - getContext().setClientVersion(client_version); - - tlsServer.notifyClientVersion(client_version); - - securityParameters.clientRandom = client_random; - - tlsServer.notifyOfferedCipherSuites(offeredCipherSuites); - tlsServer.notifyOfferedCompressionMethods(offeredCompressionMethods); - - /* - * RFC 5746 3.6. Server Behavior: Initial Handshake - */ - { - /* - * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, - * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the - * ClientHello. Including both is NOT RECOMMENDED. - */ - - /* - * When a ClientHello is received, the server MUST check if it includes the - * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag - * to TRUE. - */ - if (Arrays.contains(offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) - { - this.secure_renegotiation = true; - } - - /* - * The server MUST check if the "renegotiation_info" extension is included in the - * ClientHello. - */ - byte[] renegExtData = TlsUtils.getExtensionData(clientExtensions, EXT_RenegotiationInfo); - if (renegExtData != null) - { - /* - * If the extension is present, set secure_renegotiation flag to TRUE. The - * server MUST then verify that the length of the "renegotiated_connection" - * field is zero, and if it is not, MUST abort the handshake. - */ - this.secure_renegotiation = true; - - if (!Arrays.constantTimeAreEqual(renegExtData, createRenegotiationInfo(TlsUtils.EMPTY_BYTES))) - { - throw new TlsFatalAlert(AlertDescription.handshake_failure); - } - } - } - - tlsServer.notifySecureRenegotiation(this.secure_renegotiation); - - if (clientExtensions != null) - { - tlsServer.processClientExtensions(clientExtensions); - } - } - - protected void receiveClientKeyExchangeMessage(ByteArrayInputStream buf) - throws IOException - { - this.keyExchange.processClientKeyExchange(buf); - - assertEmpty(buf); - - establishMasterSecret(getContext(), keyExchange); - recordStream.setPendingConnectionState(getPeer().getCompression(), getPeer().getCipher()); - - this.prepareFinishHash = recordStream.prepareToFinish(); - - if (!expectSessionTicket) - { - sendChangeCipherSpecMessage(); - } - } - - protected void sendCertificateRequestMessage(CertificateRequest certificateRequest) - throws IOException - { - HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate_request); - - certificateRequest.encode(message); - - message.writeToRecordStream(); - } - - protected void sendCertificateStatusMessage(CertificateStatus certificateStatus) - throws IOException - { - HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate_status); - - certificateStatus.encode(message); - - message.writeToRecordStream(); - } - - protected void sendNewSessionTicketMessage(NewSessionTicket newSessionTicket) - throws IOException - { - if (newSessionTicket == null) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - HandshakeMessage message = new HandshakeMessage(HandshakeType.session_ticket); - - newSessionTicket.encode(message); - - message.writeToRecordStream(); - } - - protected void sendServerHelloMessage() - throws IOException - { - HandshakeMessage message = new HandshakeMessage(HandshakeType.server_hello); - - ProtocolVersion server_version = tlsServer.getServerVersion(); - if (!server_version.isEqualOrEarlierVersionOf(getContext().getClientVersion())) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - recordStream.setReadVersion(server_version); - recordStream.setWriteVersion(server_version); - recordStream.setRestrictReadVersion(true); - getContext().setServerVersion(server_version); - - TlsUtils.writeVersion(server_version, message); - - message.write(this.securityParameters.serverRandom); - - /* - * The server may return an empty session_id to indicate that the session will not be cached - * and therefore cannot be resumed. - */ - TlsUtils.writeOpaque8(TlsUtils.EMPTY_BYTES, message); - - int selectedCipherSuite = tlsServer.getSelectedCipherSuite(); - if (!Arrays.contains(this.offeredCipherSuites, selectedCipherSuite) - || selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL - || selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV - || !TlsUtils.isValidCipherSuiteForVersion(selectedCipherSuite, server_version)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - securityParameters.cipherSuite = selectedCipherSuite; - - short selectedCompressionMethod = tlsServer.getSelectedCompressionMethod(); - if (!Arrays.contains(this.offeredCompressionMethods, selectedCompressionMethod)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - securityParameters.compressionAlgorithm = selectedCompressionMethod; - - TlsUtils.writeUint16(selectedCipherSuite, message); - TlsUtils.writeUint8(selectedCompressionMethod, message); - - this.serverExtensions = tlsServer.getServerExtensions(); - - /* - * RFC 5746 3.6. Server Behavior: Initial Handshake - */ - if (this.secure_renegotiation) - { - byte[] renegExtData = TlsUtils.getExtensionData(this.serverExtensions, EXT_RenegotiationInfo); - boolean noRenegExt = (null == renegExtData); - - 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, - * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed - * because the client is signaling its willingness to receive the extension via the - * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. - */ - - /* - * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty - * "renegotiation_info" extension in the ServerHello message. - */ - this.serverExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(this.serverExtensions); - this.serverExtensions.put(EXT_RenegotiationInfo, createRenegotiationInfo(TlsUtils.EMPTY_BYTES)); - } - } - - /* - * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore - * extensions appearing in the client hello, and send a server hello containing no - * extensions. - */ - - if (this.serverExtensions != null) - { - this.securityParameters.encryptThenMAC = TlsExtensionsUtils.hasEncryptThenMACExtension(this.serverExtensions); - - this.securityParameters.maxFragmentLength = processMaxFragmentLengthExtension(clientExtensions, - this.serverExtensions, AlertDescription.internal_error); - - this.securityParameters.truncatedHMac = TlsExtensionsUtils.hasTruncatedHMacExtension(this.serverExtensions); - - /* - * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in - * a session resumption handshake. - */ - this.allowCertificateStatus = !this.resumedSession - && TlsUtils.hasExpectedEmptyExtensionData(this.serverExtensions, TlsExtensionsUtils.EXT_status_request, - AlertDescription.internal_error); - - this.expectSessionTicket = !this.resumedSession - && TlsUtils.hasExpectedEmptyExtensionData(this.serverExtensions, TlsProtocol.EXT_SessionTicket, - AlertDescription.internal_error); - - writeExtensions(message, this.serverExtensions); - } - - if (this.securityParameters.maxFragmentLength >= 0) - { - int plainTextLimit = 1 << (8 + this.securityParameters.maxFragmentLength); - recordStream.setPlaintextLimit(plainTextLimit); - } - - securityParameters.prfAlgorithm = getPRFAlgorithm(getContext(), securityParameters.getCipherSuite()); - - /* - * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify verify_data_length has - * a verify_data_length equal to 12. This includes all existing cipher suites. - */ - securityParameters.verifyDataLength = 12; - - message.writeToRecordStream(); - - this.recordStream.notifyHelloComplete(); - } - - protected void sendServerHelloDoneMessage() - throws IOException - { - byte[] message = new byte[4]; - TlsUtils.writeUint8(HandshakeType.server_hello_done, message, 0); - TlsUtils.writeUint24(0, message, 1); - - writeHandshakeMessage(message, 0, message.length); - } - - protected void sendServerKeyExchangeMessage(byte[] serverKeyExchange) - throws IOException - { - HandshakeMessage message = new HandshakeMessage(HandshakeType.server_key_exchange, serverKeyExchange.length); - - message.write(serverKeyExchange); - - message.writeToRecordStream(); - } - - protected boolean expectCertificateVerifyMessage() - { - return this.clientCertificateType >= 0 && TlsUtils.hasSigningCapability(this.clientCertificateType); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSession.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsSession.java deleted file mode 100644 index 9b5ad460..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSession.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bouncycastle.crypto.tls; - -public interface TlsSession -{ - SessionParameters exportSessionParameters(); - - byte[] getSessionID(); - - void invalidate(); - - boolean isResumable(); -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSessionImpl.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsSessionImpl.java deleted file mode 100644 index 615c4424..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSessionImpl.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.util.Arrays; - -class TlsSessionImpl implements TlsSession -{ - final byte[] sessionID; - SessionParameters sessionParameters; - - TlsSessionImpl(byte[] sessionID, SessionParameters sessionParameters) - { - if (sessionID == null) - { - throw new IllegalArgumentException("'sessionID' cannot be null"); - } - if (sessionID.length < 1 || sessionID.length > 32) - { - throw new IllegalArgumentException("'sessionID' must have length between 1 and 32 bytes, inclusive"); - } - - this.sessionID = Arrays.clone(sessionID); - this.sessionParameters = sessionParameters; - } - - public synchronized SessionParameters exportSessionParameters() - { - return this.sessionParameters == null ? null : this.sessionParameters.copy(); - } - - public synchronized byte[] getSessionID() - { - return sessionID; - } - - public synchronized void invalidate() - { - if (this.sessionParameters != null) - { - this.sessionParameters.clear(); - this.sessionParameters = null; - } - } - - public synchronized boolean isResumable() - { - return this.sessionParameters != null; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSigner.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsSigner.java deleted file mode 100644 index 68826d2a..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSigner.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; - -public interface TlsSigner -{ - void init(TlsContext context); - - byte[] generateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) - throws CryptoException; - - byte[] generateRawSignature(SignatureAndHashAlgorithm algorithm, - AsymmetricKeyParameter privateKey, byte[] hash) - throws CryptoException; - - boolean verifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1) - throws CryptoException; - - boolean verifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, - AsymmetricKeyParameter publicKey, byte[] hash) - throws CryptoException; - - Signer createSigner(AsymmetricKeyParameter privateKey); - - Signer createSigner(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey); - - Signer createVerifyer(AsymmetricKeyParameter publicKey); - - Signer createVerifyer(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter publicKey); - - boolean isValidPublicKey(AsymmetricKeyParameter publicKey); -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSignerCredentials.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsSignerCredentials.java deleted file mode 100644 index 39ee99c0..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsSignerCredentials.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -public interface TlsSignerCredentials - extends TlsCredentials -{ - byte[] generateCertificateSignature(byte[] hash) - throws IOException; - - SignatureAndHashAlgorithm getSignatureAndHashAlgorithm(); -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsStreamCipher.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsStreamCipher.java deleted file mode 100644 index f8077aa6..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsStreamCipher.java +++ /dev/null @@ -1,178 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.StreamCipher; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.crypto.params.ParametersWithIV; -import org.bouncycastle.util.Arrays; - -public class TlsStreamCipher - implements TlsCipher -{ - protected TlsContext context; - - protected StreamCipher encryptCipher; - protected StreamCipher decryptCipher; - - protected TlsMac writeMac; - protected TlsMac readMac; - - protected boolean usesNonce; - - /** - * @deprecated Use version with additional 'usesNonce' argument - */ - public TlsStreamCipher(TlsContext context, StreamCipher clientWriteCipher, - StreamCipher serverWriteCipher, Digest clientWriteDigest, Digest serverWriteDigest, - int cipherKeySize) throws IOException - { - this(context, clientWriteCipher, serverWriteCipher, clientWriteDigest, serverWriteDigest, cipherKeySize, false); - } - - public TlsStreamCipher(TlsContext context, StreamCipher clientWriteCipher, - StreamCipher serverWriteCipher, Digest clientWriteDigest, Digest serverWriteDigest, - int cipherKeySize, boolean usesNonce) throws IOException - { - boolean isServer = context.isServer(); - - this.context = context; - this.usesNonce = usesNonce; - - this.encryptCipher = clientWriteCipher; - this.decryptCipher = serverWriteCipher; - - int key_block_size = (2 * cipherKeySize) + clientWriteDigest.getDigestSize() - + serverWriteDigest.getDigestSize(); - - byte[] key_block = TlsUtils.calculateKeyBlock(context, key_block_size); - - int offset = 0; - - // Init MACs - TlsMac clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, - clientWriteDigest.getDigestSize()); - offset += clientWriteDigest.getDigestSize(); - TlsMac serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, - serverWriteDigest.getDigestSize()); - offset += serverWriteDigest.getDigestSize(); - - // Build keys - KeyParameter clientWriteKey = new KeyParameter(key_block, offset, cipherKeySize); - offset += cipherKeySize; - KeyParameter serverWriteKey = new KeyParameter(key_block, offset, cipherKeySize); - offset += cipherKeySize; - - if (offset != key_block_size) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - CipherParameters encryptParams, decryptParams; - if (isServer) - { - this.writeMac = serverWriteMac; - this.readMac = clientWriteMac; - this.encryptCipher = serverWriteCipher; - this.decryptCipher = clientWriteCipher; - encryptParams = serverWriteKey; - decryptParams = clientWriteKey; - } - else - { - this.writeMac = clientWriteMac; - this.readMac = serverWriteMac; - this.encryptCipher = clientWriteCipher; - this.decryptCipher = serverWriteCipher; - encryptParams = clientWriteKey; - decryptParams = serverWriteKey; - } - - if (usesNonce) - { - byte[] dummyNonce = new byte[8]; - encryptParams = new ParametersWithIV(encryptParams, dummyNonce); - decryptParams = new ParametersWithIV(decryptParams, dummyNonce); - } - - this.encryptCipher.init(true, encryptParams); - this.decryptCipher.init(false, decryptParams); - } - - public int getPlaintextLimit(int ciphertextLimit) - { - return ciphertextLimit - writeMac.getSize(); - } - - public byte[] encodePlaintext(long seqNo, short type, byte[] plaintext, int offset, int len) - { - /* - * draft-josefsson-salsa20-tls-04 2.1 Note that Salsa20 requires a 64-bit nonce. That - * nonce is updated on the encryption of every TLS record, and is set to be the 64-bit TLS - * record sequence number. In case of DTLS the 64-bit nonce is formed as the concatenation - * of the 16-bit epoch with the 48-bit sequence number. - */ - if (usesNonce) - { - updateIV(encryptCipher, true, seqNo); - } - - byte[] outBuf = new byte[len + writeMac.getSize()]; - - encryptCipher.processBytes(plaintext, offset, len, outBuf, 0); - - byte[] mac = writeMac.calculateMac(seqNo, type, plaintext, offset, len); - encryptCipher.processBytes(mac, 0, mac.length, outBuf, len); - - return outBuf; - } - - public byte[] decodeCiphertext(long seqNo, short type, byte[] ciphertext, int offset, int len) - throws IOException - { - /* - * draft-josefsson-salsa20-tls-04 2.1 Note that Salsa20 requires a 64-bit nonce. That - * nonce is updated on the encryption of every TLS record, and is set to be the 64-bit TLS - * record sequence number. In case of DTLS the 64-bit nonce is formed as the concatenation - * of the 16-bit epoch with the 48-bit sequence number. - */ - if (usesNonce) - { - updateIV(decryptCipher, false, seqNo); - } - - int macSize = readMac.getSize(); - if (len < macSize) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - - int plaintextLength = len - macSize; - - byte[] deciphered = new byte[len]; - decryptCipher.processBytes(ciphertext, offset, len, deciphered, 0); - checkMAC(seqNo, type, deciphered, plaintextLength, len, deciphered, 0, plaintextLength); - return Arrays.copyOfRange(deciphered, 0, plaintextLength); - } - - private void checkMAC(long seqNo, short type, byte[] recBuf, int recStart, int recEnd, byte[] calcBuf, int calcOff, int calcLen) - throws IOException - { - byte[] receivedMac = Arrays.copyOfRange(recBuf, recStart, recEnd); - byte[] computedMac = readMac.calculateMac(seqNo, type, calcBuf, calcOff, calcLen); - - if (!Arrays.constantTimeAreEqual(receivedMac, computedMac)) - { - throw new TlsFatalAlert(AlertDescription.bad_record_mac); - } - } - - private void updateIV(StreamCipher cipher, boolean forEncryption, long seqNo) - { - byte[] nonce = new byte[8]; - TlsUtils.writeUint64(seqNo, nonce, 0); - cipher.init(forEncryption, new ParametersWithIV(null, nonce)); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsUtils.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsUtils.java deleted file mode 100644 index 7986647f..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsUtils.java +++ /dev/null @@ -1,1780 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Hashtable; -import java.util.Vector; - -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x509.Extensions; -import org.bouncycastle.asn1.x509.KeyUsage; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.digests.MD5Digest; -import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.crypto.digests.SHA224Digest; -import org.bouncycastle.crypto.digests.SHA256Digest; -import org.bouncycastle.crypto.digests.SHA384Digest; -import org.bouncycastle.crypto.digests.SHA512Digest; -import org.bouncycastle.crypto.macs.HMac; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.DSAPublicKeyParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.crypto.params.RSAKeyParameters; -import org.bouncycastle.crypto.util.PublicKeyFactory; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Integers; -import org.bouncycastle.util.Strings; -import org.bouncycastle.util.io.Streams; - -/** - * Some helper functions for MicroTLS. - */ -public class TlsUtils -{ - public static final byte[] EMPTY_BYTES = new byte[0]; - - public static final Integer EXT_signature_algorithms = Integers.valueOf(ExtensionType.signature_algorithms); - - public static void checkUint8(short i) throws IOException - { - if (!isValidUint8(i)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static void checkUint8(int i) throws IOException - { - if (!isValidUint8(i)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static void checkUint8(long i) throws IOException - { - if (!isValidUint8(i)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static void checkUint16(int i) throws IOException - { - if (!isValidUint16(i)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static void checkUint16(long i) throws IOException - { - if (!isValidUint16(i)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static void checkUint24(int i) throws IOException - { - if (!isValidUint24(i)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static void checkUint24(long i) throws IOException - { - if (!isValidUint24(i)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static void checkUint32(long i) throws IOException - { - if (!isValidUint32(i)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static void checkUint48(long i) throws IOException - { - if (!isValidUint48(i)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static void checkUint64(long i) throws IOException - { - if (!isValidUint64(i)) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static boolean isValidUint8(short i) - { - return (i & 0xFF) == i; - } - - public static boolean isValidUint8(int i) - { - return (i & 0xFF) == i; - } - - public static boolean isValidUint8(long i) - { - return (i & 0xFFL) == i; - } - - public static boolean isValidUint16(int i) - { - return (i & 0xFFFF) == i; - } - - public static boolean isValidUint16(long i) - { - return (i & 0xFFFFL) == i; - } - - public static boolean isValidUint24(int i) - { - return (i & 0xFFFFFF) == i; - } - - public static boolean isValidUint24(long i) - { - return (i & 0xFFFFFFL) == i; - } - - public static boolean isValidUint32(long i) - { - return (i & 0xFFFFFFFFL) == i; - } - - public static boolean isValidUint48(long i) - { - return (i & 0xFFFFFFFFFFFFL) == i; - } - - public static boolean isValidUint64(long i) - { - return true; - } - - public static boolean isSSL(TlsContext context) - { - return context.getServerVersion().isSSL(); - } - - public static boolean isTLSv11(TlsContext context) - { - return ProtocolVersion.TLSv11.isEqualOrEarlierVersionOf(context.getServerVersion().getEquivalentTLSVersion()); - } - - public static boolean isTLSv12(TlsContext context) - { - return ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(context.getServerVersion().getEquivalentTLSVersion()); - } - - public static void writeUint8(short i, OutputStream output) - throws IOException - { - output.write(i); - } - - public static void writeUint8(int i, OutputStream output) - throws IOException - { - output.write(i); - } - - public static void writeUint8(short i, byte[] buf, int offset) - { - buf[offset] = (byte)i; - } - - public static void writeUint8(int i, byte[] buf, int offset) - { - buf[offset] = (byte)i; - } - - public static void writeUint16(int i, OutputStream output) - throws IOException - { - output.write(i >>> 8); - output.write(i); - } - - public static void writeUint16(int i, byte[] buf, int offset) - { - buf[offset] = (byte)(i >>> 8); - buf[offset + 1] = (byte)i; - } - - public static void writeUint24(int i, OutputStream output) - throws IOException - { - output.write((byte)(i >>> 16)); - output.write((byte)(i >>> 8)); - output.write((byte)i); - } - - public static void writeUint24(int i, byte[] buf, int offset) - { - buf[offset] = (byte)(i >>> 16); - buf[offset + 1] = (byte)(i >>> 8); - buf[offset + 2] = (byte)i; - } - - public static void writeUint32(long i, OutputStream output) - throws IOException - { - output.write((byte)(i >>> 24)); - output.write((byte)(i >>> 16)); - output.write((byte)(i >>> 8)); - output.write((byte)i); - } - - public static void writeUint32(long i, byte[] buf, int offset) - { - buf[offset] = (byte)(i >>> 24); - buf[offset + 1] = (byte)(i >>> 16); - buf[offset + 2] = (byte)(i >>> 8); - buf[offset + 3] = (byte)i; - } - - public static void writeUint48(long i, OutputStream output) - throws IOException - { - output.write((byte)(i >>> 40)); - output.write((byte)(i >>> 32)); - output.write((byte)(i >>> 24)); - output.write((byte)(i >>> 16)); - output.write((byte)(i >>> 8)); - output.write((byte)i); - } - - public static void writeUint48(long i, byte[] buf, int offset) - { - buf[offset] = (byte)(i >>> 40); - buf[offset + 1] = (byte)(i >>> 32); - buf[offset + 2] = (byte)(i >>> 24); - buf[offset + 3] = (byte)(i >>> 16); - buf[offset + 4] = (byte)(i >>> 8); - buf[offset + 5] = (byte)i; - } - - public static void writeUint64(long i, OutputStream output) - throws IOException - { - output.write((byte)(i >>> 56)); - output.write((byte)(i >>> 48)); - output.write((byte)(i >>> 40)); - output.write((byte)(i >>> 32)); - output.write((byte)(i >>> 24)); - output.write((byte)(i >>> 16)); - output.write((byte)(i >>> 8)); - output.write((byte)i); - } - - public static void writeUint64(long i, byte[] buf, int offset) - { - buf[offset] = (byte)(i >>> 56); - buf[offset + 1] = (byte)(i >>> 48); - buf[offset + 2] = (byte)(i >>> 40); - buf[offset + 3] = (byte)(i >>> 32); - buf[offset + 4] = (byte)(i >>> 24); - buf[offset + 5] = (byte)(i >>> 16); - buf[offset + 6] = (byte)(i >>> 8); - buf[offset + 7] = (byte)i; - } - - public static void writeOpaque8(byte[] buf, OutputStream output) - throws IOException - { - checkUint8(buf.length); - writeUint8(buf.length, output); - output.write(buf); - } - - public static void writeOpaque16(byte[] buf, OutputStream output) - throws IOException - { - checkUint16(buf.length); - writeUint16(buf.length, output); - output.write(buf); - } - - public static void writeOpaque24(byte[] buf, OutputStream output) - throws IOException - { - checkUint24(buf.length); - writeUint24(buf.length, output); - output.write(buf); - } - - public static void writeUint8Array(short[] uints, OutputStream output) - throws IOException - { - for (int i = 0; i < uints.length; ++i) - { - writeUint8(uints[i], output); - } - } - - public static void writeUint8Array(short[] uints, byte[] buf, int offset) - throws IOException - { - for (int i = 0; i < uints.length; ++i) - { - writeUint8(uints[i], buf, offset); - ++offset; - } - } - - public static void writeUint8ArrayWithUint8Length(short[] uints, OutputStream output) - throws IOException - { - checkUint8(uints.length); - writeUint8(uints.length, output); - writeUint8Array(uints, output); - } - - public static void writeUint8ArrayWithUint8Length(short[] uints, byte[] buf, int offset) - throws IOException - { - checkUint8(uints.length); - writeUint8(uints.length, buf, offset); - writeUint8Array(uints, buf, offset + 1); - } - - public static void writeUint16Array(int[] uints, OutputStream output) - throws IOException - { - for (int i = 0; i < uints.length; ++i) - { - writeUint16(uints[i], output); - } - } - - public static void writeUint16Array(int[] uints, byte[] buf, int offset) - throws IOException - { - for (int i = 0; i < uints.length; ++i) - { - writeUint16(uints[i], buf, offset); - offset += 2; - } - } - - public static void writeUint16ArrayWithUint16Length(int[] uints, OutputStream output) - throws IOException - { - int length = 2 * uints.length; - checkUint16(length); - writeUint16(length, output); - writeUint16Array(uints, output); - } - - public static void writeUint16ArrayWithUint16Length(int[] uints, byte[] buf, int offset) - throws IOException - { - int length = 2 * uints.length; - checkUint16(length); - writeUint16(length, buf, offset); - writeUint16Array(uints, buf, offset + 2); - } - - public static byte[] encodeOpaque8(byte[] buf) - throws IOException - { - checkUint8(buf.length); - return Arrays.prepend(buf, (byte)buf.length); - } - - public static byte[] encodeUint8ArrayWithUint8Length(short[] uints) throws IOException - { - byte[] result = new byte[1 + uints.length]; - writeUint8ArrayWithUint8Length(uints, result, 0); - return result; - } - - public static byte[] encodeUint16ArrayWithUint16Length(int[] uints) throws IOException - { - int length = 2 * uints.length; - byte[] result = new byte[2 + length]; - writeUint16ArrayWithUint16Length(uints, result, 0); - return result; - } - - public static short readUint8(InputStream input) - throws IOException - { - int i = input.read(); - if (i < 0) - { - throw new EOFException(); - } - return (short)i; - } - - public static short readUint8(byte[] buf, int offset) - { - return (short)buf[offset]; - } - - public static int readUint16(InputStream input) - throws IOException - { - int i1 = input.read(); - int i2 = input.read(); - if (i2 < 0) - { - throw new EOFException(); - } - return i1 << 8 | i2; - } - - public static int readUint16(byte[] buf, int offset) - { - int n = (buf[offset] & 0xff) << 8; - n |= (buf[++offset] & 0xff); - return n; - } - - public static int readUint24(InputStream input) - throws IOException - { - int i1 = input.read(); - int i2 = input.read(); - int i3 = input.read(); - if (i3 < 0) - { - throw new EOFException(); - } - return (i1 << 16) | (i2 << 8) | i3; - } - - public static int readUint24(byte[] buf, int offset) - { - int n = (buf[offset] & 0xff) << 16; - n |= (buf[++offset] & 0xff) << 8; - n |= (buf[++offset] & 0xff); - return n; - } - - public static long readUint32(InputStream input) - throws IOException - { - int i1 = input.read(); - int i2 = input.read(); - int i3 = input.read(); - int i4 = input.read(); - if (i4 < 0) - { - throw new EOFException(); - } - return ((i1 << 2) | (i2 << 16) | (i3 << 8) | i4) & 0xFFFFFFFFL; - } - - public static long readUint32(byte[] buf, int offset) - { - int n = (buf[offset] & 0xff) << 24; - n |= (buf[++offset] & 0xff) << 16; - n |= (buf[++offset] & 0xff) << 8; - n |= (buf[++offset] & 0xff); - return n & 0xFFFFFFFFL; - } - - public static long readUint48(InputStream input) - throws IOException - { - int hi = readUint24(input); - int lo = readUint24(input); - return ((long)(hi & 0xffffffffL) << 24) | (long)(lo & 0xffffffffL); - } - - public static long readUint48(byte[] buf, int offset) - { - int hi = readUint24(buf, offset); - int lo = readUint24(buf, offset + 3); - return ((long)(hi & 0xffffffffL) << 24) | (long)(lo & 0xffffffffL); - } - - public static byte[] readAllOrNothing(int length, InputStream input) - throws IOException - { - if (length < 1) - { - return EMPTY_BYTES; - } - byte[] buf = new byte[length]; - int read = Streams.readFully(input, buf); - if (read == 0) - { - return null; - } - if (read != length) - { - throw new EOFException(); - } - return buf; - } - - public static byte[] readFully(int length, InputStream input) - throws IOException - { - if (length < 1) - { - return EMPTY_BYTES; - } - byte[] buf = new byte[length]; - if (length != Streams.readFully(input, buf)) - { - throw new EOFException(); - } - return buf; - } - - public static void readFully(byte[] buf, InputStream input) - throws IOException - { - int length = buf.length; - if (length > 0 && length != Streams.readFully(input, buf)) - { - throw new EOFException(); - } - } - - public static byte[] readOpaque8(InputStream input) - throws IOException - { - short length = readUint8(input); - return readFully(length, input); - } - - public static byte[] readOpaque16(InputStream input) - throws IOException - { - int length = readUint16(input); - return readFully(length, input); - } - - 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 - { - short[] uints = new short[count]; - for (int i = 0; i < count; ++i) - { - uints[i] = readUint8(input); - } - return uints; - } - - public static int[] readUint16Array(int count, InputStream input) - throws IOException - { - int[] uints = new int[count]; - for (int i = 0; i < count; ++i) - { - uints[i] = readUint16(input); - } - return uints; - } - - 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 - { - int i1 = input.read(); - int i2 = input.read(); - if (i2 < 0) - { - throw new EOFException(); - } - return ProtocolVersion.get(i1, i2); - } - - public static int readVersionRaw(byte[] buf, int offset) - throws IOException - { - return (buf[offset] << 8) | buf[offset + 1]; - } - - public static int readVersionRaw(InputStream input) - throws IOException - { - int i1 = input.read(); - int i2 = input.read(); - if (i2 < 0) - { - throw new EOFException(); - } - return (i1 << 8) | i2; - } - - public static ASN1Primitive readASN1Object(byte[] encoding) throws IOException - { - ASN1InputStream asn1 = new ASN1InputStream(encoding); - ASN1Primitive result = asn1.readObject(); - if (null == result) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - if (null != asn1.readObject()) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - return result; - } - - public static ASN1Primitive readDERObject(byte[] encoding) throws IOException - { - /* - * NOTE: The current ASN.1 parsing code can't enforce DER-only parsing, but since DER is - * canonical, we can check it by re-encoding the result and comparing to the original. - */ - ASN1Primitive result = readASN1Object(encoding); - byte[] check = result.getEncoded(ASN1Encoding.DER); - if (!Arrays.areEqual(check, encoding)) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - return result; - } - - public static void writeGMTUnixTime(byte[] buf, int offset) - { - int t = (int)(System.currentTimeMillis() / 1000L); - buf[offset] = (byte)(t >>> 24); - buf[offset + 1] = (byte)(t >>> 16); - buf[offset + 2] = (byte)(t >>> 8); - buf[offset + 3] = (byte)t; - } - - 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) - { - buf[offset] = (byte)version.getMajorVersion(); - buf[offset + 1] = (byte)version.getMinorVersion(); - } - - public static Vector getDefaultDSSSignatureAlgorithms() - { - return vectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.dsa)); - } - - public static Vector getDefaultECDSASignatureAlgorithms() - { - return vectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.ecdsa)); - } - - public static Vector getDefaultRSASignatureAlgorithms() - { - return vectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.rsa)); - } - - public static byte[] getExtensionData(Hashtable extensions, Integer extensionType) - { - return extensions == null ? null : (byte[])extensions.get(extensionType); - } - - public static boolean hasExpectedEmptyExtensionData(Hashtable extensions, Integer extensionType, - short alertDescription) throws IOException - { - byte[] extension_data = getExtensionData(extensions, extensionType); - if (extension_data == null) - { - return false; - } - if (extension_data.length != 0) - { - throw new TlsFatalAlert(alertDescription); - } - return true; - } - - public static TlsSession importSession(byte[] sessionID, SessionParameters sessionParameters) - { - return new TlsSessionImpl(sessionID, sessionParameters); - } - - public static boolean isSignatureAlgorithmsExtensionAllowed(ProtocolVersion clientVersion) - { - return ProtocolVersion.TLSv12.isEqualOrEarlierVersionOf(clientVersion.getEquivalentTLSVersion()); - } - - /** - * Add a 'signature_algorithms' extension to existing extensions. - * - * @param extensions A {@link Hashtable} to add the extension to. - * @param supportedSignatureAlgorithms {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. - * @throws IOException - */ - public static void addSignatureAlgorithmsExtension(Hashtable extensions, Vector supportedSignatureAlgorithms) - throws IOException - { - extensions.put(EXT_signature_algorithms, createSignatureAlgorithmsExtension(supportedSignatureAlgorithms)); - } - - /** - * 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 - { - byte[] extensionData = getExtensionData(extensions, EXT_signature_algorithms); - return extensionData == null ? null : readSignatureAlgorithmsExtension(extensionData); - } - - /** - * 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 - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - // supported_signature_algorithms - encodeSupportedSignatureAlgorithms(supportedSignatureAlgorithms, false, buf); - - return buf.toByteArray(); - } - - /** - * Read 'signature_algorithms' extension data. - * - * @param extensionData The extension data. - * @return A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. - * @throws IOException - */ - public static Vector readSignatureAlgorithmsExtension(byte[] extensionData) - throws IOException - { - if (extensionData == null) - { - throw new IllegalArgumentException("'extensionData' cannot be null"); - } - - ByteArrayInputStream buf = new ByteArrayInputStream(extensionData); - - // supported_signature_algorithms - Vector supported_signature_algorithms = parseSupportedSignatureAlgorithms(false, buf); - - TlsProtocol.assertEmpty(buf); - - return supported_signature_algorithms; - } - - public static void encodeSupportedSignatureAlgorithms(Vector supportedSignatureAlgorithms, boolean allowAnonymous, - OutputStream output) throws IOException - { - if (supportedSignatureAlgorithms == null || supportedSignatureAlgorithms.size() < 1 - || supportedSignatureAlgorithms.size() >= (1 << 15)) - { - throw new IllegalArgumentException( - "'supportedSignatureAlgorithms' must have length from 1 to (2^15 - 1)"); - } - - // supported_signature_algorithms - int length = 2 * supportedSignatureAlgorithms.size(); - TlsUtils.checkUint16(length); - TlsUtils.writeUint16(length, output); - for (int i = 0; i < supportedSignatureAlgorithms.size(); ++i) - { - SignatureAndHashAlgorithm entry = (SignatureAndHashAlgorithm)supportedSignatureAlgorithms.elementAt(i); - if (!allowAnonymous && entry.getSignature() == SignatureAlgorithm.anonymous) - { - /* - * RFC 5246 7.4.1.4.1 The "anonymous" value is meaningless in this context but used - * in Section 7.4.3. It MUST NOT appear in this extension. - */ - throw new IllegalArgumentException( - "SignatureAlgorithm.anonymous MUST NOT appear in the signature_algorithms extension"); - } - entry.encode(output); - } - } - - public static Vector parseSupportedSignatureAlgorithms(boolean allowAnonymous, InputStream input) - throws IOException - { - // supported_signature_algorithms - int length = TlsUtils.readUint16(input); - if (length < 2 || (length & 1) != 0) - { - throw new TlsFatalAlert(AlertDescription.decode_error); - } - int count = length / 2; - Vector supportedSignatureAlgorithms = new Vector(count); - for (int i = 0; i < count; ++i) - { - SignatureAndHashAlgorithm entry = SignatureAndHashAlgorithm.parse(input); - if (!allowAnonymous && entry.getSignature() == SignatureAlgorithm.anonymous) - { - /* - * RFC 5246 7.4.1.4.1 The "anonymous" value is meaningless in this context but used - * in Section 7.4.3. It MUST NOT appear in this extension. - */ - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - supportedSignatureAlgorithms.addElement(entry); - } - return supportedSignatureAlgorithms; - } - - public static byte[] PRF(TlsContext context, byte[] secret, String asciiLabel, byte[] seed, int size) - { - ProtocolVersion version = context.getServerVersion(); - - if (version.isSSL()) - { - throw new IllegalStateException("No PRF available for SSLv3 session"); - } - - byte[] label = Strings.toByteArray(asciiLabel); - byte[] labelSeed = concat(label, seed); - - int prfAlgorithm = context.getSecurityParameters().getPrfAlgorithm(); - - if (prfAlgorithm == PRFAlgorithm.tls_prf_legacy) - { - return PRF_legacy(secret, label, labelSeed, size); - } - - Digest prfDigest = createPRFHash(prfAlgorithm); - byte[] buf = new byte[size]; - hmac_hash(prfDigest, secret, labelSeed, buf); - return buf; - } - - public static byte[] PRF_legacy(byte[] secret, String asciiLabel, byte[] seed, int size) - { - byte[] label = Strings.toByteArray(asciiLabel); - byte[] labelSeed = concat(label, seed); - - return PRF_legacy(secret, label, labelSeed, size); - } - - static byte[] PRF_legacy(byte[] secret, byte[] label, byte[] labelSeed, int size) - { - int s_half = (secret.length + 1) / 2; - byte[] s1 = new byte[s_half]; - byte[] s2 = new byte[s_half]; - System.arraycopy(secret, 0, s1, 0, s_half); - System.arraycopy(secret, secret.length - s_half, s2, 0, s_half); - - byte[] b1 = new byte[size]; - byte[] b2 = new byte[size]; - hmac_hash(createHash(HashAlgorithm.md5), s1, labelSeed, b1); - hmac_hash(createHash(HashAlgorithm.sha1), s2, labelSeed, b2); - for (int i = 0; i < size; i++) - { - b1[i] ^= b2[i]; - } - return b1; - } - - static byte[] concat(byte[] a, byte[] b) - { - byte[] c = new byte[a.length + b.length]; - System.arraycopy(a, 0, c, 0, a.length); - System.arraycopy(b, 0, c, a.length, b.length); - return c; - } - - static void hmac_hash(Digest digest, byte[] secret, byte[] seed, byte[] out) - { - HMac mac = new HMac(digest); - mac.init(new KeyParameter(secret)); - byte[] a = seed; - int size = digest.getDigestSize(); - int iterations = (out.length + size - 1) / size; - byte[] buf = new byte[mac.getMacSize()]; - byte[] buf2 = new byte[mac.getMacSize()]; - for (int i = 0; i < iterations; i++) - { - mac.update(a, 0, a.length); - mac.doFinal(buf, 0); - a = buf; - mac.update(a, 0, a.length); - mac.update(seed, 0, seed.length); - mac.doFinal(buf2, 0); - System.arraycopy(buf2, 0, out, (size * i), Math.min(size, out.length - (size * i))); - } - } - - static void validateKeyUsage(org.bouncycastle.asn1.x509.Certificate c, int keyUsageBits) - throws IOException - { - Extensions exts = c.getTBSCertificate().getExtensions(); - if (exts != null) - { - KeyUsage ku = KeyUsage.fromExtensions(exts); - if (ku != null) - { - int bits = ku.getBytes()[0] & 0xff; - if ((bits & keyUsageBits) != keyUsageBits) - { - throw new TlsFatalAlert(AlertDescription.certificate_unknown); - } - } - } - } - - static byte[] calculateKeyBlock(TlsContext context, int size) - { - SecurityParameters securityParameters = context.getSecurityParameters(); - byte[] master_secret = securityParameters.getMasterSecret(); - byte[] seed = concat(securityParameters.getServerRandom(), - securityParameters.getClientRandom()); - - if (isSSL(context)) - { - return calculateKeyBlock_SSL(master_secret, seed, size); - } - - return PRF(context, master_secret, ExporterLabel.key_expansion, seed, size); - } - - static byte[] calculateKeyBlock_SSL(byte[] master_secret, byte[] random, int size) - { - Digest md5 = createHash(HashAlgorithm.md5); - Digest sha1 = createHash(HashAlgorithm.sha1); - int md5Size = md5.getDigestSize(); - byte[] shatmp = new byte[sha1.getDigestSize()]; - byte[] tmp = new byte[size + md5Size]; - - int i = 0, pos = 0; - while (pos < size) - { - byte[] ssl3Const = SSL3_CONST[i]; - - sha1.update(ssl3Const, 0, ssl3Const.length); - sha1.update(master_secret, 0, master_secret.length); - sha1.update(random, 0, random.length); - sha1.doFinal(shatmp, 0); - - md5.update(master_secret, 0, master_secret.length); - md5.update(shatmp, 0, shatmp.length); - md5.doFinal(tmp, pos); - - pos += md5Size; - ++i; - } - - byte rval[] = new byte[size]; - System.arraycopy(tmp, 0, rval, 0, size); - return rval; - } - - static byte[] calculateMasterSecret(TlsContext context, byte[] pre_master_secret) - { - SecurityParameters securityParameters = context.getSecurityParameters(); - byte[] seed = concat(securityParameters.getClientRandom(), securityParameters.getServerRandom()); - - if (isSSL(context)) - { - return calculateMasterSecret_SSL(pre_master_secret, seed); - } - - return PRF(context, pre_master_secret, ExporterLabel.master_secret, seed, 48); - } - - static byte[] calculateMasterSecret_SSL(byte[] pre_master_secret, byte[] random) - { - Digest md5 = createHash(HashAlgorithm.md5); - Digest sha1 = createHash(HashAlgorithm.sha1); - int md5Size = md5.getDigestSize(); - byte[] shatmp = new byte[sha1.getDigestSize()]; - - byte[] rval = new byte[md5Size * 3]; - int pos = 0; - - for (int i = 0; i < 3; ++i) - { - byte[] ssl3Const = SSL3_CONST[i]; - - sha1.update(ssl3Const, 0, ssl3Const.length); - sha1.update(pre_master_secret, 0, pre_master_secret.length); - sha1.update(random, 0, random.length); - sha1.doFinal(shatmp, 0); - - md5.update(pre_master_secret, 0, pre_master_secret.length); - md5.update(shatmp, 0, shatmp.length); - md5.doFinal(rval, pos); - - pos += md5Size; - } - - return rval; - } - - static byte[] calculateVerifyData(TlsContext context, String asciiLabel, byte[] handshakeHash) - { - if (isSSL(context)) - { - return handshakeHash; - } - - SecurityParameters securityParameters = context.getSecurityParameters(); - byte[] master_secret = securityParameters.getMasterSecret(); - int verify_data_length = securityParameters.getVerifyDataLength(); - - return PRF(context, master_secret, asciiLabel, handshakeHash, verify_data_length); - } - - public static Digest createHash(short hashAlgorithm) - { - switch (hashAlgorithm) - { - case HashAlgorithm.md5: - return new MD5Digest(); - case HashAlgorithm.sha1: - return new SHA1Digest(); - case HashAlgorithm.sha224: - return new SHA224Digest(); - case HashAlgorithm.sha256: - return new SHA256Digest(); - case HashAlgorithm.sha384: - return new SHA384Digest(); - case HashAlgorithm.sha512: - return new SHA512Digest(); - default: - throw new IllegalArgumentException("unknown HashAlgorithm"); - } - } - - public static Digest cloneHash(short hashAlgorithm, Digest hash) - { - switch (hashAlgorithm) - { - case HashAlgorithm.md5: - return new MD5Digest((MD5Digest)hash); - case HashAlgorithm.sha1: - return new SHA1Digest((SHA1Digest)hash); - case HashAlgorithm.sha224: - return new SHA224Digest((SHA224Digest)hash); - case HashAlgorithm.sha256: - return new SHA256Digest((SHA256Digest)hash); - case HashAlgorithm.sha384: - return new SHA384Digest((SHA384Digest)hash); - case HashAlgorithm.sha512: - return new SHA512Digest((SHA512Digest)hash); - default: - throw new IllegalArgumentException("unknown HashAlgorithm"); - } - } - - public static Digest createPRFHash(int prfAlgorithm) - { - switch (prfAlgorithm) - { - case PRFAlgorithm.tls_prf_legacy: - return new CombinedHash(); - default: - return createHash(getHashAlgorithmForPRFAlgorithm(prfAlgorithm)); - } - } - - public static Digest clonePRFHash(int prfAlgorithm, Digest hash) - { - switch (prfAlgorithm) - { - case PRFAlgorithm.tls_prf_legacy: - return new CombinedHash((CombinedHash)hash); - default: - return cloneHash(getHashAlgorithmForPRFAlgorithm(prfAlgorithm), hash); - } - } - - public static short getHashAlgorithmForPRFAlgorithm(int prfAlgorithm) - { - switch (prfAlgorithm) - { - case PRFAlgorithm.tls_prf_legacy: - throw new IllegalArgumentException("legacy PRF not a valid algorithm"); - case PRFAlgorithm.tls_prf_sha256: - return HashAlgorithm.sha256; - case PRFAlgorithm.tls_prf_sha384: - return HashAlgorithm.sha384; - default: - throw new IllegalArgumentException("unknown PRFAlgorithm"); - } - } - - public static ASN1ObjectIdentifier getOIDForHashAlgorithm(short hashAlgorithm) - { - switch (hashAlgorithm) - { - case HashAlgorithm.md5: - return PKCSObjectIdentifiers.md5; - case HashAlgorithm.sha1: - return X509ObjectIdentifiers.id_SHA1; - case HashAlgorithm.sha224: - return NISTObjectIdentifiers.id_sha224; - case HashAlgorithm.sha256: - return NISTObjectIdentifiers.id_sha256; - case HashAlgorithm.sha384: - return NISTObjectIdentifiers.id_sha384; - case HashAlgorithm.sha512: - return NISTObjectIdentifiers.id_sha512; - default: - throw new IllegalArgumentException("unknown HashAlgorithm"); - } - } - - static short getClientCertificateType(Certificate clientCertificate, Certificate serverCertificate) - throws IOException - { - if (clientCertificate.isEmpty()) - { - return -1; - } - - org.bouncycastle.asn1.x509.Certificate x509Cert = clientCertificate.getCertificateAt(0); - SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); - try - { - AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(keyInfo); - if (publicKey.isPrivate()) - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - /* - * TODO RFC 5246 7.4.6. The certificates MUST be signed using an acceptable hash/ - * signature algorithm pair, as described in Section 7.4.4. Note that this relaxes the - * constraints on certificate-signing algorithms found in prior versions of TLS. - */ - - /* - * RFC 5246 7.4.6. Client Certificate - */ - - /* - * RSA public key; the certificate MUST allow the key to be used for signing with the - * signature scheme and hash algorithm that will be employed in the certificate verify - * message. - */ - if (publicKey instanceof RSAKeyParameters) - { - validateKeyUsage(x509Cert, KeyUsage.digitalSignature); - return ClientCertificateType.rsa_sign; - } - - /* - * DSA public key; the certificate MUST allow the key to be used for signing with the - * hash algorithm that will be employed in the certificate verify message. - */ - if (publicKey instanceof DSAPublicKeyParameters) - { - validateKeyUsage(x509Cert, KeyUsage.digitalSignature); - return ClientCertificateType.dss_sign; - } - - /* - * ECDSA-capable public key; the certificate MUST allow the key to be used for signing - * with the hash algorithm that will be employed in the certificate verify message; the - * public key MUST use a curve and point format supported by the server. - */ - if (publicKey instanceof ECPublicKeyParameters) - { - validateKeyUsage(x509Cert, KeyUsage.digitalSignature); - // TODO Check the curve and point format - return ClientCertificateType.ecdsa_sign; - } - - // TODO Add support for ClientCertificateType.*_fixed_* - - } - catch (Exception e) - { - } - - throw new TlsFatalAlert(AlertDescription.unsupported_certificate); - } - - static void trackHashAlgorithms(TlsHandshakeHash handshakeHash, Vector supportedSignatureAlgorithms) - { - if (supportedSignatureAlgorithms != null) - { - for (int i = 0; i < supportedSignatureAlgorithms.size(); ++i) - { - SignatureAndHashAlgorithm signatureAndHashAlgorithm = (SignatureAndHashAlgorithm) - supportedSignatureAlgorithms.elementAt(i); - short hashAlgorithm = signatureAndHashAlgorithm.getHash(); - handshakeHash.trackHashAlgorithm(hashAlgorithm); - } - } - } - - public static boolean hasSigningCapability(short clientCertificateType) - { - switch (clientCertificateType) - { - case ClientCertificateType.dss_sign: - case ClientCertificateType.ecdsa_sign: - case ClientCertificateType.rsa_sign: - return true; - default: - return false; - } - } - - public static TlsSigner createTlsSigner(short clientCertificateType) - { - switch (clientCertificateType) - { - case ClientCertificateType.dss_sign: - return new TlsDSSSigner(); - case ClientCertificateType.ecdsa_sign: - return new TlsECDSASigner(); - case ClientCertificateType.rsa_sign: - return new TlsRSASigner(); - default: - throw new IllegalArgumentException("'clientCertificateType' is not a type with signing capability"); - } - } - - 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(); - - private static byte[][] genConst() - { - int n = 10; - byte[][] arr = new byte[n][]; - for (int i = 0; i < n; i++) - { - byte[] b = new byte[i + 1]; - Arrays.fill(b, (byte)('A' + i)); - arr[i] = b; - } - return arr; - } - - private static Vector vectorOfOne(Object obj) - { - Vector v = new Vector(1); - v.addElement(obj); - return v; - } - - public static int getCipherType(int ciphersuite) throws IOException - { - switch (getEncryptionAlgorithm(ciphersuite)) - { - case EncryptionAlgorithm.AES_128_GCM: - case EncryptionAlgorithm.AES_256_GCM: - case EncryptionAlgorithm.AES_128_CCM: - case EncryptionAlgorithm.AES_128_CCM_8: - case EncryptionAlgorithm.AES_256_CCM: - case EncryptionAlgorithm.AES_256_CCM_8: - case EncryptionAlgorithm.CAMELLIA_128_GCM: - case EncryptionAlgorithm.CAMELLIA_256_GCM: - case EncryptionAlgorithm.AEAD_CHACHA20_POLY1305: - return CipherType.aead; - - case EncryptionAlgorithm.RC2_CBC_40: - case EncryptionAlgorithm.IDEA_CBC: - case EncryptionAlgorithm.DES40_CBC: - case EncryptionAlgorithm.DES_CBC: - case EncryptionAlgorithm._3DES_EDE_CBC: - case EncryptionAlgorithm.AES_128_CBC: - case EncryptionAlgorithm.AES_256_CBC: - case EncryptionAlgorithm.CAMELLIA_128_CBC: - case EncryptionAlgorithm.CAMELLIA_256_CBC: - case EncryptionAlgorithm.SEED_CBC: - return CipherType.block; - - case EncryptionAlgorithm.RC4_40: - case EncryptionAlgorithm.RC4_128: - case EncryptionAlgorithm.ESTREAM_SALSA20: - case EncryptionAlgorithm.SALSA20: - return CipherType.stream; - - default: - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static int getEncryptionAlgorithm(int ciphersuite) throws IOException - { - switch (ciphersuite) - { - 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: - case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: - return EncryptionAlgorithm._3DES_EDE_CBC; - - case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - return EncryptionAlgorithm.AEAD_CHACHA20_POLY1305; - - case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: - return EncryptionAlgorithm.AES_128_CBC; - - 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: - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: - return EncryptionAlgorithm.AES_128_CBC; - - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_PSK_WITH_AES_128_CCM: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM: - return EncryptionAlgorithm.AES_128_CCM; - - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: - case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: - return EncryptionAlgorithm.AES_128_CCM_8; - - case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: - return EncryptionAlgorithm.AES_128_GCM; - - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: - case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: - return EncryptionAlgorithm.AES_256_CBC; - - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: - return EncryptionAlgorithm.AES_256_CBC; - - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: - return EncryptionAlgorithm.AES_256_CBC; - - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_PSK_WITH_AES_256_CCM: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM: - return EncryptionAlgorithm.AES_256_CCM; - - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: - case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: - return EncryptionAlgorithm.AES_256_CCM_8; - - case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: - return EncryptionAlgorithm.AES_256_GCM; - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: - return EncryptionAlgorithm.CAMELLIA_128_CBC; - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: - return EncryptionAlgorithm.CAMELLIA_128_CBC; - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: - return EncryptionAlgorithm.CAMELLIA_128_GCM; - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: - return EncryptionAlgorithm.CAMELLIA_256_CBC; - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: - return EncryptionAlgorithm.CAMELLIA_256_CBC; - - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: - return EncryptionAlgorithm.CAMELLIA_256_CBC; - - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: - return EncryptionAlgorithm.CAMELLIA_256_GCM; - - case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1: - case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1: - return EncryptionAlgorithm.ESTREAM_SALSA20; - - case CipherSuite.TLS_RSA_WITH_NULL_MD5: - return EncryptionAlgorithm.NULL; - - case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: - case CipherSuite.TLS_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: - case CipherSuite.TLS_RSA_WITH_NULL_SHA: - return EncryptionAlgorithm.NULL; - - case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: - case CipherSuite.TLS_RSA_WITH_NULL_SHA256: - return EncryptionAlgorithm.NULL; - - case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_PSK_WITH_NULL_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: - return EncryptionAlgorithm.NULL; - - case CipherSuite.TLS_DH_anon_WITH_RC4_128_MD5: - case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: - return EncryptionAlgorithm.RC4_128; - - case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: - case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: - case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: - case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: - return EncryptionAlgorithm.RC4_128; - - case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1: - case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1: - case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1: - case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1: - case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1: - case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1: - return EncryptionAlgorithm.SALSA20; - - case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: - case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: - return EncryptionAlgorithm.SEED_CBC; - - default: - throw new TlsFatalAlert(AlertDescription.internal_error); - } - } - - public static ProtocolVersion getMinimumVersion(int ciphersuite) - { - switch (ciphersuite) - { - case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: - case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: - case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: - case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: - case CipherSuite.TLS_PSK_WITH_AES_128_CCM: - case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: - case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_PSK_WITH_AES_256_CCM: - case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: - case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM: - case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM: - case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: - case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: - case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: - case CipherSuite.TLS_RSA_WITH_NULL_SHA256: - return ProtocolVersion.TLSv12; - - default: - return ProtocolVersion.SSLv3; - } - } - - public static boolean isAEADCipherSuite(int ciphersuite) throws IOException - { - return CipherType.aead == getCipherType(ciphersuite); - } - - public static boolean isBlockCipherSuite(int ciphersuite) throws IOException - { - return CipherType.block == getCipherType(ciphersuite); - } - - public static boolean isStreamCipherSuite(int ciphersuite) throws IOException - { - return CipherType.stream == getCipherType(ciphersuite); - } - - public static boolean isValidCipherSuiteForVersion(int cipherSuite, ProtocolVersion serverVersion) - { - return getMinimumVersion(cipherSuite).isEqualOrEarlierVersionOf(serverVersion.getEquivalentTLSVersion()); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/UDPTransport.java b/core/src/main/java/org/bouncycastle/crypto/tls/UDPTransport.java deleted file mode 100644 index d5f0769e..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/UDPTransport.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; - -public class UDPTransport - implements DatagramTransport -{ - protected final static int MIN_IP_OVERHEAD = 20; - protected final static int MAX_IP_OVERHEAD = MIN_IP_OVERHEAD + 64; - protected final static int UDP_OVERHEAD = 8; - - protected final DatagramSocket socket; - protected final int receiveLimit, sendLimit; - - public UDPTransport(DatagramSocket socket, int mtu) - throws IOException - { - if (!socket.isBound() || !socket.isConnected()) - { - throw new IllegalArgumentException("'socket' must be bound and connected"); - } - - this.socket = socket; - - // NOTE: As of JDK 1.6, can use NetworkInterface.getMTU - - this.receiveLimit = mtu - MIN_IP_OVERHEAD - UDP_OVERHEAD; - this.sendLimit = mtu - MAX_IP_OVERHEAD - UDP_OVERHEAD; - } - - public int getReceiveLimit() - { - return receiveLimit; - } - - public int getSendLimit() - { - // TODO[DTLS] Implement Path-MTU discovery? - return sendLimit; - } - - 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()) - { - /* - * 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 - * which will be fragmented." - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - DatagramPacket packet = new DatagramPacket(buf, off, len); - socket.send(packet); - } - - public void close() - throws IOException - { - socket.close(); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/URLAndHash.java b/core/src/main/java/org/bouncycastle/crypto/tls/URLAndHash.java deleted file mode 100644 index c32a904a..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/URLAndHash.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.bouncycastle.util.Strings; - -/** - * RFC 6066 5. - */ -public class URLAndHash -{ - protected String url; - protected byte[] sha1Hash; - - public URLAndHash(String url, byte[] sha1Hash) - { - if (url == null || url.length() < 1 || url.length() >= (1 << 16)) - { - throw new IllegalArgumentException("'url' must have length from 1 to (2^16 - 1)"); - } - if (sha1Hash != null && sha1Hash.length != 20) - { - throw new IllegalArgumentException("'sha1Hash' must have length == 20, if present"); - } - - this.url = url; - this.sha1Hash = sha1Hash; - } - - public String getURL() - { - return url; - } - - public byte[] getSHA1Hash() - { - return sha1Hash; - } - - /** - * Encode this {@link URLAndHash} to an {@link OutputStream}. - * - * @param output the {@link OutputStream} to encode to. - * @throws IOException - */ - public void encode(OutputStream output) - throws IOException - { - byte[] urlEncoding = Strings.toByteArray(this.url); - TlsUtils.writeOpaque16(urlEncoding, output); - - if (this.sha1Hash == null) - { - TlsUtils.writeUint8(0, output); - } - else - { - TlsUtils.writeUint8(1, output); - output.write(this.sha1Hash); - } - } - - /** - * Parse a {@link URLAndHash} from an {@link InputStream}. - * - * @param context - * the {@link TlsContext} of the current connection. - * @param input - * the {@link InputStream} to parse from. - * @return a {@link URLAndHash} object. - * @throws IOException - */ - public static URLAndHash parse(TlsContext context, InputStream input) - throws IOException - { - byte[] urlEncoding = TlsUtils.readOpaque16(input); - if (urlEncoding.length < 1) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - String url = Strings.fromByteArray(urlEncoding); - - byte[] sha1Hash = null; - short padding = TlsUtils.readUint8(input); - switch (padding) - { - case 0: - if (TlsUtils.isTLSv12(context)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - break; - case 1: - sha1Hash = TlsUtils.readFully(20, input); - break; - default: - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - - return new URLAndHash(url, sha1Hash); - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/UseSRTPData.java b/core/src/main/java/org/bouncycastle/crypto/tls/UseSRTPData.java deleted file mode 100644 index bc2cf10c..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/UseSRTPData.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 5764 4.1.1 - */ -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. - */ - public UseSRTPData(int[] protectionProfiles, byte[] mki) - { - if (protectionProfiles == null || protectionProfiles.length < 1 - || protectionProfiles.length >= (1 << 15)) - { - throw new IllegalArgumentException( - "'protectionProfiles' must have length from 1 to (2^15 - 1)"); - } - - if (mki == null) - { - mki = TlsUtils.EMPTY_BYTES; - } - else if (mki.length > 255) - { - throw new IllegalArgumentException("'mki' cannot be longer than 255 bytes"); - } - - this.protectionProfiles = protectionProfiles; - this.mki = mki; - } - - /** - * @return see {@link SRTPProtectionProfile} for valid constants. - */ - public int[] getProtectionProfiles() - { - return protectionProfiles; - } - - /** - * @return valid lengths from 0 to 255. - */ - public byte[] getMki() - { - return mki; - } -} diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/UserMappingType.java b/core/src/main/java/org/bouncycastle/crypto/tls/UserMappingType.java deleted file mode 100644 index 8f6ae7ba..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/tls/UserMappingType.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bouncycastle.crypto.tls; - -/** - * RFC 4681 - */ -public class UserMappingType -{ - /* - * RFC 4681 - */ - public static final short upn_domain_hint = 64; -} |