diff --git a/crypto/src/tls/DtlsClientProtocol.cs b/crypto/src/tls/DtlsClientProtocol.cs
index 44f574e3a..fd9985ab5 100644
--- a/crypto/src/tls/DtlsClientProtocol.cs
+++ b/crypto/src/tls/DtlsClientProtocol.cs
@@ -237,12 +237,6 @@ namespace Org.BouncyCastle.Tls
TlsUtilities.EstablishServerSigAlgs(securityParameters, state.certificateRequest);
- /*
- * TODO Give the client a chance to immediately select the CertificateVerify hash
- * algorithm here to avoid tracking the other hash algorithms unnecessarily?
- */
- TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, securityParameters.ServerSigAlgs);
-
serverMessage = handshake.ReceiveMessage();
}
else
@@ -262,54 +256,68 @@ namespace Org.BouncyCastle.Tls
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
- IList clientSupplementalData = state.client.GetClientSupplementalData();
- if (clientSupplementalData != null)
- {
- byte[] supplementalDataBody = GenerateSupplementalData(clientSupplementalData);
- handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody);
- }
+ TlsCredentials clientAuthCredentials = null;
+ TlsCredentialedSigner clientAuthSigner = null;
+ Certificate clientAuthCertificate = null;
+ SignatureAndHashAlgorithm clientAuthAlgorithm = null;
+ TlsStreamSigner clientAuthStreamSigner = null;
- if (null != state.certificateRequest)
+ if (state.certificateRequest != null)
{
- state.clientCredentials = TlsUtilities.EstablishClientCredentials(state.authentication,
+ clientAuthCredentials = TlsUtilities.EstablishClientCredentials(state.authentication,
state.certificateRequest);
+ if (clientAuthCredentials != null)
+ {
+ clientAuthCertificate = clientAuthCredentials.Certificate;
- /*
- * 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.
- */
+ if (clientAuthCredentials is TlsCredentialedSigner)
+ {
+ clientAuthSigner = (TlsCredentialedSigner)clientAuthCredentials;
+ clientAuthAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(
+ securityParameters.NegotiatedVersion, clientAuthSigner);
+ clientAuthStreamSigner = clientAuthSigner.GetStreamSigner();
- Certificate clientCertificate = null;
- if (null != state.clientCredentials)
- {
- clientCertificate = state.clientCredentials.Certificate;
- }
+ if (ProtocolVersion.DTLSv12.Equals(securityParameters.NegotiatedVersion))
+ {
+ TlsUtilities.VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs,
+ clientAuthAlgorithm, AlertDescription.internal_error);
+
+ if (clientAuthStreamSigner == null)
+ {
+ TlsUtilities.TrackHashAlgorithmClient(handshake.HandshakeHash, clientAuthAlgorithm);
+ }
+ }
- SendCertificateMessage(state.clientContext, handshake, clientCertificate, null);
+ if (clientAuthStreamSigner != null)
+ {
+ handshake.HandshakeHash.ForceBuffering();
+ }
+ }
+ }
}
- TlsCredentialedSigner credentialedSigner = null;
- TlsStreamSigner streamSigner = null;
+ handshake.HandshakeHash.SealHashAlgorithms();
- if (null != state.clientCredentials)
+ if (clientAuthCredentials == null)
{
- state.keyExchange.ProcessClientCredentials(state.clientCredentials);
-
- if (state.clientCredentials is TlsCredentialedSigner)
- {
- credentialedSigner = (TlsCredentialedSigner)state.clientCredentials;
- streamSigner = credentialedSigner.GetStreamSigner();
- }
+ state.keyExchange.SkipClientCredentials();
}
else
{
- state.keyExchange.SkipClientCredentials();
+ state.keyExchange.ProcessClientCredentials(clientAuthCredentials);
}
- bool forceBuffering = streamSigner != null;
- TlsUtilities.SealHandshakeHash(state.clientContext, handshake.HandshakeHash, forceBuffering);
+ IList clientSupplementalData = state.client.GetClientSupplementalData();
+ if (clientSupplementalData != null)
+ {
+ byte[] supplementalDataBody = GenerateSupplementalData(clientSupplementalData);
+ handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody);
+ }
+
+ if (null != state.certificateRequest)
+ {
+ SendCertificateMessage(state.clientContext, handshake, clientAuthCertificate, null);
+ }
byte[] clientKeyExchangeBody = GenerateClientKeyExchange(state);
handshake.SendMessage(HandshakeType.client_key_exchange, clientKeyExchangeBody);
@@ -319,18 +327,16 @@ namespace Org.BouncyCastle.Tls
TlsProtocol.EstablishMasterSecret(state.clientContext, state.keyExchange);
recordLayer.InitPendingEpoch(TlsUtilities.InitCipher(state.clientContext));
+ if (clientAuthSigner != null)
{
- if (credentialedSigner != null)
- {
- DigitallySigned certificateVerify = TlsUtilities.GenerateCertificateVerifyClient(
- state.clientContext, credentialedSigner, streamSigner, handshake.HandshakeHash);
- byte[] certificateVerifyBody = GenerateCertificateVerify(state, certificateVerify);
- handshake.SendMessage(HandshakeType.certificate_verify, certificateVerifyBody);
- }
-
- handshake.PrepareToFinish();
+ DigitallySigned certificateVerify = TlsUtilities.GenerateCertificateVerifyClient(state.clientContext,
+ clientAuthSigner, clientAuthAlgorithm, clientAuthStreamSigner, handshake.HandshakeHash);
+ byte[] certificateVerifyBody = GenerateCertificateVerify(state, certificateVerify);
+ handshake.SendMessage(HandshakeType.certificate_verify, certificateVerifyBody);
}
+ handshake.PrepareToFinish();
+
securityParameters.m_localVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext,
handshake.HandshakeHash, false);
handshake.SendMessage(HandshakeType.finished, securityParameters.LocalVerifyData);
@@ -973,7 +979,6 @@ namespace Org.BouncyCastle.Tls
internal TlsAuthentication authentication = null;
internal CertificateStatus certificateStatus = null;
internal CertificateRequest certificateRequest = null;
- internal TlsCredentials clientCredentials = null;
internal TlsHeartbeat heartbeat = null;
internal short heartbeatPolicy = HeartbeatMode.peer_not_allowed_to_send;
}
|