diff --git a/crypto/src/tls/TlsUtilities.cs b/crypto/src/tls/TlsUtilities.cs
index 05d38c59c..72ff92271 100644
--- a/crypto/src/tls/TlsUtilities.cs
+++ b/crypto/src/tls/TlsUtilities.cs
@@ -1068,16 +1068,22 @@ namespace Org.BouncyCastle.Tls
public static IList GetDefaultSupportedSignatureAlgorithms(TlsContext context)
{
+ return GetSupportedSignatureAlgorithms(context, DefaultSupportedSigAlgs);
+ }
+
+ public static IList GetSupportedSignatureAlgorithms(TlsContext context, IList candidates)
+ {
TlsCrypto crypto = context.Crypto;
IList result = Platform.CreateArrayList(DefaultSupportedSigAlgs.Count);
- foreach (SignatureAndHashAlgorithm sigAndHashAlg in DefaultSupportedSigAlgs)
+ foreach (SignatureAndHashAlgorithm sigAndHashAlg in candidates)
{
AddIfSupported(result, crypto, sigAndHashAlg);
}
return result;
}
+ [Obsolete("Will be removed")]
public static SignatureAndHashAlgorithm GetSignatureAndHashAlgorithm(TlsContext context,
TlsCredentialedSigner signerCredentials)
{
@@ -1085,14 +1091,19 @@ namespace Org.BouncyCastle.Tls
}
internal static SignatureAndHashAlgorithm GetSignatureAndHashAlgorithm(ProtocolVersion negotiatedVersion,
- TlsCredentialedSigner signerCredentials)
+ TlsCredentialedSigner credentialedSigner)
{
SignatureAndHashAlgorithm signatureAndHashAlgorithm = null;
- if (IsTlsV12(negotiatedVersion))
+ if (IsSignatureAlgorithmsExtensionAllowed(negotiatedVersion))
{
- signatureAndHashAlgorithm = signerCredentials.SignatureAndHashAlgorithm;
+ signatureAndHashAlgorithm = credentialedSigner.SignatureAndHashAlgorithm;
if (signatureAndHashAlgorithm == null)
+ {
+ /*
+ * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
+ */
throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
}
return signatureAndHashAlgorithm;
}
@@ -1347,6 +1358,14 @@ namespace Org.BouncyCastle.Tls
public static void VerifySupportedSignatureAlgorithm(IList supportedSignatureAlgorithms,
SignatureAndHashAlgorithm signatureAlgorithm)
{
+ VerifySupportedSignatureAlgorithm(supportedSignatureAlgorithms, signatureAlgorithm,
+ AlertDescription.illegal_parameter);
+ }
+
+ /// <exception cref="IOException"/>
+ internal static void VerifySupportedSignatureAlgorithm(IList supportedSignatureAlgorithms,
+ SignatureAndHashAlgorithm signatureAlgorithm, short alertDescription)
+ {
if (supportedSignatureAlgorithms == null || supportedSignatureAlgorithms.Count < 1
|| supportedSignatureAlgorithms.Count >= (1 << 15))
{
@@ -1358,7 +1377,7 @@ namespace Org.BouncyCastle.Tls
if (signatureAlgorithm.Signature == SignatureAlgorithm.anonymous
|| !ContainsSignatureAlgorithm(supportedSignatureAlgorithms, signatureAlgorithm))
{
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+ throw new TlsFatalAlert(alertDescription);
}
}
@@ -2088,7 +2107,7 @@ namespace Org.BouncyCastle.Tls
TlsHash h = algorithm == null
? new CombinedHash(crypto)
- : CreateHash(crypto, algorithm.Hash);
+ : CreateHash(crypto, algorithm);
SecurityParameters sp = context.SecurityParameters;
// NOTE: The implicit copy here is intended (and important)
@@ -2124,48 +2143,38 @@ namespace Org.BouncyCastle.Tls
}
internal static DigitallySigned GenerateCertificateVerifyClient(TlsClientContext clientContext,
- TlsCredentialedSigner credentialedSigner, TlsStreamSigner streamSigner, TlsHandshakeHash handshakeHash)
+ TlsCredentialedSigner clientAuthSigner, SignatureAndHashAlgorithm clientAuthAlgorithm,
+ TlsStreamSigner clientAuthStreamSigner, TlsHandshakeHash handshakeHash)
{
SecurityParameters securityParameters = clientContext.SecurityParameters;
- ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion;
-
- if (IsTlsV13(negotiatedVersion))
+ if (IsTlsV13(securityParameters.NegotiatedVersion))
{
- // Should be using GenerateCertificateVerify13 instead
+ // Should be using Generate13CertificateVerify instead
throw new TlsFatalAlert(AlertDescription.internal_error);
}
- /*
- * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
- */
- SignatureAndHashAlgorithm signatureAndHashAlgorithm = GetSignatureAndHashAlgorithm(negotiatedVersion,
- credentialedSigner);
-
byte[] signature;
- if (streamSigner != null)
+ if (clientAuthStreamSigner != null)
{
- handshakeHash.CopyBufferTo(streamSigner.GetOutputStream());
- signature = streamSigner.GetSignature();
+ handshakeHash.CopyBufferTo(clientAuthStreamSigner.Stream);
+ signature = clientAuthStreamSigner.GetSignature();
}
else
{
byte[] hash;
- if (signatureAndHashAlgorithm == null)
+ if (clientAuthAlgorithm == null)
{
hash = securityParameters.SessionHash;
}
else
{
- int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm);
- int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
-
- hash = handshakeHash.GetFinalHash(cryptoHashAlgorithm);
+ hash = handshakeHash.GetFinalHash(SignatureScheme.GetCryptoHashAlgorithm(clientAuthAlgorithm));
}
- signature = credentialedSigner.GenerateRawSignature(hash);
+ signature = clientAuthSigner.GenerateRawSignature(hash);
}
- return new DigitallySigned(signatureAndHashAlgorithm, signature);
+ return new DigitallySigned(clientAuthAlgorithm, signature);
}
internal static DigitallySigned Generate13CertificateVerify(TlsContext context,
@@ -2195,16 +2204,13 @@ namespace Org.BouncyCastle.Tls
if (null != streamSigner)
{
- Stream output = streamSigner.GetOutputStream();
+ Stream output = streamSigner.Stream;
output.Write(header, 0, header.Length);
output.Write(prfHash, 0, prfHash.Length);
return streamSigner.GetSignature();
}
- int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm);
- int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
-
- TlsHash tlsHash = crypto.CreateHash(cryptoHashAlgorithm);
+ TlsHash tlsHash = CreateHash(crypto, signatureAndHashAlgorithm);
tlsHash.Update(header, 0, header.Length);
tlsHash.Update(prfHash, 0, prfHash.Length);
byte[] hash = tlsHash.CalculateHash();
@@ -2224,22 +2230,17 @@ namespace Org.BouncyCastle.Tls
{
signatureAlgorithm = verifyingCert.GetLegacySignatureAlgorithm();
- short clientCertType = GetLegacyClientCertType(signatureAlgorithm);
- if (clientCertType < 0 || !Arrays.Contains(certificateRequest.CertificateTypes, clientCertType))
- throw new TlsFatalAlert(AlertDescription.unsupported_certificate);
+ CheckClientCertificateType(certificateRequest, GetLegacyClientCertType(signatureAlgorithm),
+ AlertDescription.unsupported_certificate);
}
else
{
- signatureAlgorithm = sigAndHashAlg.Signature;
+ VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs, sigAndHashAlg);
- // TODO Is it possible (maybe only pre-1.2 to check this immediately when the Certificate arrives?
- if (!IsValidSignatureAlgorithmForCertificateVerify(signatureAlgorithm,
- certificateRequest.CertificateTypes))
- {
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
- }
+ signatureAlgorithm = sigAndHashAlg.Signature;
- VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs, sigAndHashAlg);
+ CheckClientCertificateType(certificateRequest,
+ SignatureAlgorithm.GetClientCertificateType(signatureAlgorithm), AlertDescription.illegal_parameter);
}
// Verify the CertificateVerify message contains a correct signature.
@@ -2251,7 +2252,7 @@ namespace Org.BouncyCastle.Tls
if (streamVerifier != null)
{
- handshakeHash.CopyBufferTo(streamVerifier.GetOutputStream());
+ handshakeHash.CopyBufferTo(streamVerifier.Stream);
verified = streamVerifier.IsVerified();
}
else
@@ -2259,10 +2260,7 @@ namespace Org.BouncyCastle.Tls
byte[] hash;
if (IsTlsV12(serverContext))
{
- int signatureScheme = SignatureScheme.From(sigAndHashAlg);
- int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
-
- hash = handshakeHash.GetFinalHash(cryptoHashAlgorithm);
+ hash = handshakeHash.GetFinalHash(SignatureScheme.GetCryptoHashAlgorithm(sigAndHashAlg));
}
else
{
@@ -2287,62 +2285,54 @@ namespace Org.BouncyCastle.Tls
}
}
+ /// <exception cref="IOException"/>
internal static void Verify13CertificateVerifyClient(TlsServerContext serverContext,
- CertificateRequest certificateRequest, DigitallySigned certificateVerify, TlsHandshakeHash handshakeHash)
+ TlsHandshakeHash handshakeHash, CertificateVerify certificateVerify)
{
SecurityParameters securityParameters = serverContext.SecurityParameters;
- Certificate clientCertificate = securityParameters.PeerCertificate;
- TlsCertificate verifyingCert = clientCertificate.GetCertificateAt(0);
-
- SignatureAndHashAlgorithm sigAndHashAlg = certificateVerify.Algorithm;
- VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs, sigAndHashAlg);
-
- int signatureScheme = SignatureScheme.From(sigAndHashAlg);
-
- // Verify the CertificateVerify message contains a correct signature.
- bool verified;
- try
- {
- TlsVerifier verifier = verifyingCert.CreateVerifier(signatureScheme);
- verified = Verify13CertificateVerify(serverContext.Crypto, certificateVerify, verifier,
- "TLS 1.3, client CertificateVerify", handshakeHash);
- }
- catch (TlsFatalAlert e)
- {
- throw e;
- }
- catch (Exception e)
- {
- throw new TlsFatalAlert(AlertDescription.decrypt_error, e);
- }
+ IList supportedAlgorithms = securityParameters.ServerSigAlgs;
+ TlsCertificate certificate = securityParameters.PeerCertificate.GetCertificateAt(0);
- if (!verified)
- {
- throw new TlsFatalAlert(AlertDescription.decrypt_error);
- }
+ Verify13CertificateVerify(supportedAlgorithms, "TLS 1.3, client CertificateVerify", handshakeHash,
+ certificate, certificateVerify);
}
+ /// <exception cref="IOException"/>
internal static void Verify13CertificateVerifyServer(TlsClientContext clientContext,
- DigitallySigned certificateVerify, TlsHandshakeHash handshakeHash)
+ TlsHandshakeHash handshakeHash, CertificateVerify certificateVerify)
{
SecurityParameters securityParameters = clientContext.SecurityParameters;
- Certificate serverCertificate = securityParameters.PeerCertificate;
- TlsCertificate verifyingCert = serverCertificate.GetCertificateAt(0);
- SignatureAndHashAlgorithm sigAndHashAlg = certificateVerify.Algorithm;
- VerifySupportedSignatureAlgorithm(securityParameters.ClientSigAlgs, sigAndHashAlg);
+ IList supportedAlgorithms = securityParameters.ClientSigAlgs;
+ TlsCertificate certificate = securityParameters.PeerCertificate.GetCertificateAt(0);
- int signatureScheme = SignatureScheme.From(sigAndHashAlg);
+ Verify13CertificateVerify(supportedAlgorithms, "TLS 1.3, server CertificateVerify", handshakeHash,
+ certificate, certificateVerify);
+ }
+ /// <exception cref="IOException"/>
+ private static void Verify13CertificateVerify(IList supportedAlgorithms, string contextString,
+ TlsHandshakeHash handshakeHash, TlsCertificate certificate, CertificateVerify certificateVerify)
+ {
// Verify the CertificateVerify message contains a correct signature.
bool verified;
try
{
- TlsVerifier verifier = verifyingCert.CreateVerifier(signatureScheme);
+ int signatureScheme = certificateVerify.Algorithm;
+
+ SignatureAndHashAlgorithm algorithm = SignatureScheme.GetSignatureAndHashAlgorithm(signatureScheme);
+ VerifySupportedSignatureAlgorithm(supportedAlgorithms, algorithm);
+
+ Tls13Verifier verifier = certificate.CreateVerifier(signatureScheme);
+
+ byte[] header = GetCertificateVerifyHeader(contextString);
+ byte[] prfHash = GetCurrentPrfHash(handshakeHash);
- verified = Verify13CertificateVerify(clientContext.Crypto, certificateVerify, verifier,
- "TLS 1.3, server CertificateVerify", handshakeHash);
+ Stream output = verifier.Stream;
+ output.Write(header, 0, header.Length);
+ output.Write(prfHash, 0, prfHash.Length);
+ verified = verifier.VerifySignature(certificateVerify.Signature);
}
catch (TlsFatalAlert e)
{
@@ -2359,32 +2349,6 @@ namespace Org.BouncyCastle.Tls
}
}
- private static bool Verify13CertificateVerify(TlsCrypto crypto, DigitallySigned certificateVerify,
- TlsVerifier verifier, string contextString, TlsHandshakeHash handshakeHash)
- {
- TlsStreamVerifier streamVerifier = verifier.GetStreamVerifier(certificateVerify);
-
- byte[] header = GetCertificateVerifyHeader(contextString);
- byte[] prfHash = GetCurrentPrfHash(handshakeHash);
-
- if (null != streamVerifier)
- {
- Stream output = streamVerifier.GetOutputStream();
- output.Write(header, 0, header.Length);
- output.Write(prfHash, 0, prfHash.Length);
- return streamVerifier.IsVerified();
- }
-
- int signatureScheme = SignatureScheme.From(certificateVerify.Algorithm);
- int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
-
- TlsHash tlsHash = crypto.CreateHash(cryptoHashAlgorithm);
- tlsHash.Update(header, 0, header.Length);
- tlsHash.Update(prfHash, 0, prfHash.Length);
- byte[] hash = tlsHash.CalculateHash();
- return verifier.VerifyRawSignature(certificateVerify, hash);
- }
-
private static byte[] GetCertificateVerifyHeader(string contextString)
{
int count = contextString.Length;
@@ -2409,13 +2373,13 @@ namespace Org.BouncyCastle.Tls
/*
* RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
*/
- SignatureAndHashAlgorithm algorithm = GetSignatureAndHashAlgorithm(context, credentials);
+ SignatureAndHashAlgorithm algorithm = GetSignatureAndHashAlgorithm(context.ServerVersion, credentials);
TlsStreamSigner streamSigner = credentials.GetStreamSigner();
byte[] signature;
if (streamSigner != null)
{
- SendSignatureInput(context, extraSignatureInput, digestBuffer, streamSigner.GetOutputStream());
+ SendSignatureInput(context, extraSignatureInput, digestBuffer, streamSigner.Stream);
signature = streamSigner.GetSignature();
}
else
@@ -2461,7 +2425,7 @@ namespace Org.BouncyCastle.Tls
bool verified;
if (streamVerifier != null)
{
- SendSignatureInput(context, null, digestBuffer, streamVerifier.GetOutputStream());
+ SendSignatureInput(context, null, digestBuffer, streamVerifier.Stream);
verified = streamVerifier.IsVerified();
}
else
@@ -2476,28 +2440,28 @@ namespace Org.BouncyCastle.Tls
}
}
+ internal static void TrackHashAlgorithmClient(TlsHandshakeHash handshakeHash,
+ SignatureAndHashAlgorithm signatureAndHashAlgorithm)
+ {
+ int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureAndHashAlgorithm);
+ if (cryptoHashAlgorithm >= 0)
+ {
+ handshakeHash.TrackHashAlgorithm(cryptoHashAlgorithm);
+ }
+ }
+
internal static void TrackHashAlgorithms(TlsHandshakeHash handshakeHash, IList supportedSignatureAlgorithms)
{
- if (supportedSignatureAlgorithms != null)
+ foreach (SignatureAndHashAlgorithm signatureAndHashAlgorithm in supportedSignatureAlgorithms)
{
- foreach (SignatureAndHashAlgorithm signatureAndHashAlgorithm in supportedSignatureAlgorithms)
+ int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureAndHashAlgorithm);
+ if (cryptoHashAlgorithm >= 0)
{
- /*
- * TODO We could validate the signature algorithm part. Currently the impact is
- * that we might be tracking extra hashes pointlessly (but there are only a
- * limited number of recognized hash algorithms).
- */
- int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm);
- int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
-
- if (cryptoHashAlgorithm >= 0)
- {
- handshakeHash.TrackHashAlgorithm(cryptoHashAlgorithm);
- }
- else if (HashAlgorithm.Intrinsic == signatureAndHashAlgorithm.Hash)
- {
- handshakeHash.ForceBuffering();
- }
+ handshakeHash.TrackHashAlgorithm(cryptoHashAlgorithm);
+ }
+ else if (HashAlgorithm.Intrinsic == signatureAndHashAlgorithm.Hash)
+ {
+ handshakeHash.ForceBuffering();
}
}
}
@@ -3896,14 +3860,6 @@ namespace Org.BouncyCastle.Tls
&& NamedGroup.CanBeNegotiated(keyShareGroup, negotiatedVersion);
}
- internal static bool IsValidSignatureAlgorithmForCertificateVerify(short signatureAlgorithm,
- short[] clientCertificateTypes)
- {
- short clientCertificateType = SignatureAlgorithm.GetClientCertificateType(signatureAlgorithm);
-
- return clientCertificateType >= 0 && Arrays.Contains(clientCertificateTypes, clientCertificateType);
- }
-
internal static bool IsValidSignatureAlgorithmForServerKeyExchange(short signatureAlgorithm,
int keyExchangeAlgorithm)
{
@@ -4238,21 +4194,14 @@ namespace Org.BouncyCastle.Tls
return handshakeHash.ForkPrfHash().CalculateHash();
}
- internal static void SealHandshakeHash(TlsContext context, TlsHandshakeHash handshakeHash, bool forceBuffering)
+ private static TlsHash CreateHash(TlsCrypto crypto, short hashAlgorithm)
{
- if (forceBuffering || !context.Crypto.HasAllRawSignatureAlgorithms())
- {
- handshakeHash.ForceBuffering();
- }
-
- handshakeHash.SealHashAlgorithms();
+ return crypto.CreateHash(TlsCryptoUtilities.GetHash(hashAlgorithm));
}
- private static TlsHash CreateHash(TlsCrypto crypto, short hashAlgorithm)
+ private static TlsHash CreateHash(TlsCrypto crypto, SignatureAndHashAlgorithm signatureAndHashAlgorithm)
{
- int cryptoHashAlgorithm = TlsCryptoUtilities.GetHash(hashAlgorithm);
-
- return crypto.CreateHash(cryptoHashAlgorithm);
+ return crypto.CreateHash(SignatureScheme.GetCryptoHashAlgorithm(signatureAndHashAlgorithm));
}
/// <exception cref="IOException"/>
@@ -4793,6 +4742,17 @@ namespace Org.BouncyCastle.Tls
return (TlsCredentialedSigner)credentials;
}
+ /// <exception cref="IOException"/>
+ private static void CheckClientCertificateType(CertificateRequest certificateRequest,
+ short clientCertificateType, short alertDescription)
+ {
+ if (clientCertificateType < 0
+ || !Arrays.Contains(certificateRequest.CertificateTypes, clientCertificateType))
+ {
+ throw new TlsFatalAlert(alertDescription);
+ }
+ }
+
private static void CheckDowngradeMarker(byte[] randomBlock, byte[] downgradeMarker)
{
int len = downgradeMarker.Length;
@@ -4839,8 +4799,11 @@ namespace Org.BouncyCastle.Tls
MemoryStream buf)
{
SecurityParameters securityParameters = clientContext.SecurityParameters;
- if (null != securityParameters.PeerCertificate)
+ if (KeyExchangeAlgorithm.IsAnonymous(securityParameters.KeyExchangeAlgorithm)
+ || null != securityParameters.PeerCertificate)
+ {
throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ }
MemoryStream endPointHash = new MemoryStream();
|