diff --git a/tls/src/main/java/org/bouncycastle/tls/Certificate.java b/tls/src/main/java/org/bouncycastle/tls/Certificate.java index 43e4f02a41..bc5eb1b94c 100644 --- a/tls/src/main/java/org/bouncycastle/tls/Certificate.java +++ b/tls/src/main/java/org/bouncycastle/tls/Certificate.java @@ -83,7 +83,12 @@ private static CertificateEntry[] convert(TlsCertificate[] certificateList) public Certificate(TlsCertificate[] certificateList) { - this(null, convert(certificateList)); + this(CertificateType.X509, certificateList); + } + + public Certificate(short certificateType, TlsCertificate[] certificateList) + { + this(certificateType, null, convert(certificateList)); } public Certificate(byte[] certificateRequestContext, CertificateEntry[] certificateEntryList) diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSClientProtocol.java b/tls/src/main/java/org/bouncycastle/tls/DTLSClientProtocol.java index 78e3abef0f..310fce70e1 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DTLSClientProtocol.java +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSClientProtocol.java @@ -1060,10 +1060,11 @@ else if (TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, TlsExte securityParameters.statusRequestVersion = 1; } + TlsCrypto crypto = clientContext.getCrypto(); securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension( - sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + crypto, sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension( - sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + crypto, sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); state.expectSessionTicket = TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, TlsProtocol.EXT_SessionTicket, AlertDescription.illegal_parameter); diff --git a/tls/src/main/java/org/bouncycastle/tls/DTLSServerProtocol.java b/tls/src/main/java/org/bouncycastle/tls/DTLSServerProtocol.java index db29ab6f2f..c203df4f9f 100644 --- a/tls/src/main/java/org/bouncycastle/tls/DTLSServerProtocol.java +++ b/tls/src/main/java/org/bouncycastle/tls/DTLSServerProtocol.java @@ -690,10 +690,11 @@ else if (TlsUtils.hasExpectedEmptyExtensionData(state.serverExtensions, securityParameters.statusRequestVersion = 1; } + TlsCrypto crypto = serverContext.getCrypto(); securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension( - clientHelloExtensions, state.serverExtensions, AlertDescription.internal_error); + crypto, clientHelloExtensions, state.serverExtensions, AlertDescription.internal_error); securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension( - clientHelloExtensions, state.serverExtensions, AlertDescription.internal_error); + crypto, clientHelloExtensions, state.serverExtensions, AlertDescription.internal_error); state.expectSessionTicket = TlsUtils.hasExpectedEmptyExtensionData(state.serverExtensions, TlsProtocol.EXT_SessionTicket, AlertDescription.internal_error); diff --git a/tls/src/main/java/org/bouncycastle/tls/TlsClientProtocol.java b/tls/src/main/java/org/bouncycastle/tls/TlsClientProtocol.java index 217bcafd46..5a1480925d 100644 --- a/tls/src/main/java/org/bouncycastle/tls/TlsClientProtocol.java +++ b/tls/src/main/java/org/bouncycastle/tls/TlsClientProtocol.java @@ -9,6 +9,7 @@ import java.util.Vector; import org.bouncycastle.tls.crypto.TlsAgreement; +import org.bouncycastle.tls.crypto.TlsCrypto; import org.bouncycastle.tls.crypto.TlsSecret; import org.bouncycastle.tls.crypto.TlsStreamSigner; import org.bouncycastle.util.Arrays; @@ -1441,10 +1442,11 @@ else if (TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, TlsExte securityParameters.statusRequestVersion = 1; } + TlsCrypto crypto = tlsClientContext.getCrypto(); securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension( - sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + crypto, sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension( - sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + crypto, sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); this.expectSessionTicket = TlsUtils.hasExpectedEmptyExtensionData(sessionServerExtensions, TlsProtocol.EXT_SessionTicket, AlertDescription.illegal_parameter); @@ -1561,10 +1563,11 @@ protected void receive13EncryptedExtensions(ByteArrayInputStream buf) securityParameters.statusRequestVersion = clientExtensions.containsKey(TlsExtensionsUtils.EXT_status_request) ? 1 : 0; + TlsCrypto crypto = tlsClientContext.getCrypto(); securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension13( - sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + crypto, sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension13( - sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + crypto, sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); } this.expectSessionTicket = false; diff --git a/tls/src/main/java/org/bouncycastle/tls/TlsServerProtocol.java b/tls/src/main/java/org/bouncycastle/tls/TlsServerProtocol.java index fb9b5ce772..4ab0fff70f 100644 --- a/tls/src/main/java/org/bouncycastle/tls/TlsServerProtocol.java +++ b/tls/src/main/java/org/bouncycastle/tls/TlsServerProtocol.java @@ -366,9 +366,9 @@ protected ServerHello generate13ServerHello(ClientHello clientHello, HandshakeMe if (!securityParameters.isResumedSession()) { securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension13( - clientHelloExtensions, serverEncryptedExtensions, AlertDescription.internal_error); + crypto, clientHelloExtensions, serverEncryptedExtensions, AlertDescription.internal_error); securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension13( - clientHelloExtensions, serverEncryptedExtensions, AlertDescription.internal_error); + crypto, clientHelloExtensions, serverEncryptedExtensions, AlertDescription.internal_error); } } @@ -826,10 +826,11 @@ else if (TlsUtils.hasExpectedEmptyExtensionData(serverExtensions, TlsExtensionsU securityParameters.statusRequestVersion = 1; } + TlsCrypto crypto = tlsServerContext.getCrypto(); securityParameters.clientCertificateType = TlsUtils.processClientCertificateTypeExtension( - clientExtensions, serverExtensions, AlertDescription.internal_error); + crypto, clientExtensions, serverExtensions, AlertDescription.internal_error); securityParameters.serverCertificateType = TlsUtils.processServerCertificateTypeExtension( - clientExtensions, serverExtensions, AlertDescription.internal_error); + crypto, clientExtensions, serverExtensions, AlertDescription.internal_error); this.expectSessionTicket = TlsUtils.hasExpectedEmptyExtensionData(serverExtensions, TlsProtocol.EXT_SessionTicket, AlertDescription.internal_error); diff --git a/tls/src/main/java/org/bouncycastle/tls/TlsUtils.java b/tls/src/main/java/org/bouncycastle/tls/TlsUtils.java index ae0a9dcebc..3bc84c7781 100644 --- a/tls/src/main/java/org/bouncycastle/tls/TlsUtils.java +++ b/tls/src/main/java/org/bouncycastle/tls/TlsUtils.java @@ -6307,7 +6307,7 @@ static short processMaxFragmentLengthExtension(Hashtable clientExtensions, Hasht return maxFragmentLength; } - static short processClientCertificateTypeExtension(Hashtable clientExtensions, Hashtable serverExtensions, + static short processClientCertificateTypeExtension(TlsCrypto tlsCrypto, Hashtable clientExtensions, Hashtable serverExtensions, short alertDescription) throws IOException { @@ -6317,7 +6317,7 @@ static short processClientCertificateTypeExtension(Hashtable clientExtensions, H return CertificateType.X509; } - if (!CertificateType.isValid(serverValue)) + if (!tlsCrypto.isCertificateTypeValid(serverValue)) { throw new TlsFatalAlert(alertDescription, "Unknown value for client_certificate_type"); } @@ -6331,17 +6331,17 @@ static short processClientCertificateTypeExtension(Hashtable clientExtensions, H return serverValue; } - static short processClientCertificateTypeExtension13(Hashtable clientExtensions, Hashtable serverExtensions, + static short processClientCertificateTypeExtension13(TlsCrypto tlsCrypto, Hashtable clientExtensions, Hashtable serverExtensions, short alertDescription) throws IOException { - short certificateType = processClientCertificateTypeExtension(clientExtensions, serverExtensions, + short certificateType = processClientCertificateTypeExtension(tlsCrypto, clientExtensions, serverExtensions, alertDescription); return validateCertificateType13(certificateType, alertDescription); } - static short processServerCertificateTypeExtension(Hashtable clientExtensions, Hashtable serverExtensions, + static short processServerCertificateTypeExtension(TlsCrypto tlsCrypto, Hashtable clientExtensions, Hashtable serverExtensions, short alertDescription) throws IOException { @@ -6351,7 +6351,7 @@ static short processServerCertificateTypeExtension(Hashtable clientExtensions, H return CertificateType.X509; } - if (!CertificateType.isValid(serverValue)) + if (!tlsCrypto.isCertificateTypeValid(serverValue)) { throw new TlsFatalAlert(alertDescription, "Unknown value for server_certificate_type"); } @@ -6365,11 +6365,11 @@ static short processServerCertificateTypeExtension(Hashtable clientExtensions, H return serverValue; } - static short processServerCertificateTypeExtension13(Hashtable clientExtensions, Hashtable serverExtensions, + static short processServerCertificateTypeExtension13(TlsCrypto tlsCrypto, Hashtable clientExtensions, Hashtable serverExtensions, short alertDescription) throws IOException { - short certificateType = processServerCertificateTypeExtension(clientExtensions, serverExtensions, + short certificateType = processServerCertificateTypeExtension(tlsCrypto, clientExtensions, serverExtensions, alertDescription); return validateCertificateType13(certificateType, alertDescription); diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCrypto.java b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCrypto.java index 46b41a1d23..f145292d82 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCrypto.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/TlsCrypto.java @@ -18,6 +18,15 @@ */ public interface TlsCrypto { + + /** + * Return true if this TlsCrypto can support the passed in certificate type. + * + * @param certificateType the certificate type of interest. + * @return true if certificateType is supported, false otherwise. + */ + boolean isCertificateTypeValid(short certificateType); + /** * Return true if this TlsCrypto would use a stream verifier for any of the passed in algorithms. This * method is only relevant to handshakes negotiating (D)TLS 1.2. diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/AbstractTlsCrypto.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/AbstractTlsCrypto.java index d8ffa4fa14..c8a4ff59d9 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/AbstractTlsCrypto.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/AbstractTlsCrypto.java @@ -1,5 +1,6 @@ package org.bouncycastle.tls.crypto.impl; +import org.bouncycastle.tls.CertificateType; import org.bouncycastle.tls.crypto.TlsCrypto; import org.bouncycastle.tls.crypto.TlsSecret; @@ -21,4 +22,9 @@ public TlsSecret adoptSecret(TlsSecret secret) throw new IllegalArgumentException("unrecognized TlsSecret - cannot copy data: " + secret.getClass().getName()); } + + public boolean isCertificateTypeValid(short certificateType) + { + return CertificateType.isValid(certificateType); + } }