diff --git a/crypto/src/crypto/macs/HMac.cs b/crypto/src/crypto/macs/HMac.cs
index 460f3c5a0..3d42aec0f 100644
--- a/crypto/src/crypto/macs/HMac.cs
+++ b/crypto/src/crypto/macs/HMac.cs
@@ -136,11 +136,15 @@ namespace Org.BouncyCastle.Crypto.Macs
*/
public virtual void Reset()
{
- // Reset underlying digest
- digest.Reset();
-
- // Initialise the digest
- digest.BlockUpdate(inputPad, 0, inputPad.Length);
+ if (ipadState != null)
+ {
+ ((IMemoable)digest).Reset(ipadState);
+ }
+ else
+ {
+ digest.Reset();
+ digest.BlockUpdate(inputPad, 0, inputPad.Length);
+ }
}
private static void XorPad(byte[] pad, int len, byte n)
diff --git a/crypto/src/crypto/signers/PssSigner.cs b/crypto/src/crypto/signers/PssSigner.cs
index 66efa51b8..2a941df47 100644
--- a/crypto/src/crypto/signers/PssSigner.cs
+++ b/crypto/src/crypto/signers/PssSigner.cs
@@ -15,7 +15,7 @@ namespace Org.BouncyCastle.Crypto.Signers
public class PssSigner
: ISigner
{
- public const byte TrailerImplicit = (byte)0xBC;
+ public const byte TrailerImplicit = 0xBC;
private readonly IDigest contentDigest1, contentDigest2;
private readonly IDigest mgfDigest;
@@ -33,23 +33,23 @@ namespace Org.BouncyCastle.Crypto.Signers
private byte[] block;
private byte trailer;
- public static PssSigner CreateRawSigner(
- IAsymmetricBlockCipher cipher,
- IDigest digest)
+ public static PssSigner CreateRawSigner(IAsymmetricBlockCipher cipher, IDigest digest)
{
return new PssSigner(cipher, new NullDigest(), digest, digest, digest.GetDigestSize(), null, TrailerImplicit);
}
- public static PssSigner CreateRawSigner(
- IAsymmetricBlockCipher cipher,
- IDigest contentDigest,
- IDigest mgfDigest,
- int saltLen,
- byte trailer)
+ public static PssSigner CreateRawSigner(IAsymmetricBlockCipher cipher, IDigest contentDigest, IDigest mgfDigest,
+ int saltLen, byte trailer)
{
return new PssSigner(cipher, new NullDigest(), contentDigest, mgfDigest, saltLen, null, trailer);
}
+ public static PssSigner CreateRawSigner(IAsymmetricBlockCipher cipher, IDigest contentDigest, IDigest mgfDigest,
+ byte[] salt, byte trailer)
+ {
+ return new PssSigner(cipher, new NullDigest(), contentDigest, mgfDigest, salt.Length, salt, trailer);
+ }
+
public PssSigner(
IAsymmetricBlockCipher cipher,
IDigest digest)
@@ -225,6 +225,9 @@ namespace Org.BouncyCastle.Crypto.Signers
/// </summary>
public virtual byte[] GenerateSignature()
{
+ if (contentDigest1.GetDigestSize() != hLen)
+ throw new InvalidOperationException();
+
contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen);
if (sLen != 0)
@@ -271,7 +274,10 @@ namespace Org.BouncyCastle.Crypto.Signers
public virtual bool VerifySignature(
byte[] signature)
{
- contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen);
+ if (contentDigest1.GetDigestSize() != hLen)
+ throw new InvalidOperationException();
+
+ contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen);
byte[] b = cipher.ProcessBlock(signature, 0, signature.Length);
Arrays.Fill(block, 0, block.Length - b.Length, 0);
diff --git a/crypto/src/tls/AbstractTlsPeer.cs b/crypto/src/tls/AbstractTlsPeer.cs
index 6d29953ee..4e1b28e58 100644
--- a/crypto/src/tls/AbstractTlsPeer.cs
+++ b/crypto/src/tls/AbstractTlsPeer.cs
@@ -26,8 +26,7 @@ namespace Org.BouncyCastle.Tls
/// <returns>an array of supported <see cref="ProtocolVersion"/> values.</returns>
protected virtual ProtocolVersion[] GetSupportedVersions()
{
- // TODO[tls13] Enable TLSv13 by default in due course
- return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10);
+ return ProtocolVersion.TLSv13.DownTo(ProtocolVersion.TLSv12);
}
protected abstract int[] GetSupportedCipherSuites();
diff --git a/crypto/src/tls/CertificateVerify.cs b/crypto/src/tls/CertificateVerify.cs
new file mode 100644
index 000000000..7c9f02735
--- /dev/null
+++ b/crypto/src/tls/CertificateVerify.cs
@@ -0,0 +1,57 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Tls
+{
+ public sealed class CertificateVerify
+ {
+ private readonly int m_algorithm;
+ private readonly byte[] m_signature;
+
+ public CertificateVerify(int algorithm, byte[] signature)
+ {
+ if (!TlsUtilities.IsValidUint16(algorithm))
+ throw new ArgumentException("algorithm");
+ if (signature == null)
+ throw new ArgumentNullException("signature");
+
+ this.m_algorithm = algorithm;
+ this.m_signature = signature;
+ }
+
+ /// <returns>a <see cref="SignatureScheme"/> value.</returns>
+ public int Algorithm
+ {
+ get { return m_algorithm; }
+ }
+
+ public byte[] Signature
+ {
+ get { return m_signature; }
+ }
+
+ /// <summary>Encode this <see cref="CertificateVerify"/> to a <see cref="Stream"/>.</summary>
+ /// <param name="output">the <see cref="Stream"/> to encode to.</param>
+ /// <exception cref="IOException"/>
+ public void Encode(Stream output)
+ {
+ TlsUtilities.WriteUint16(m_algorithm, output);
+ TlsUtilities.WriteOpaque16(m_signature, output);
+ }
+
+ /// <summary>Parse a <see cref="CertificateVerify"/> from a <see cref="Stream"/>.</summary>
+ /// <param name="context">the <see cref="TlsContext"/> of the current connection.</param>
+ /// <param name="input">the <see cref="Stream"/> to parse from.</param>
+ /// <returns>a <see cref="CertificateVerify"/> object.</returns>
+ /// <exception cref="IOException"/>
+ public static CertificateVerify Parse(TlsContext context, Stream input)
+ {
+ if (!TlsUtilities.IsTlsV13(context))
+ throw new InvalidOperationException();
+
+ int algorithm = TlsUtilities.ReadUint16(input);
+ byte[] signature = TlsUtilities.ReadOpaque16(input);
+ return new CertificateVerify(algorithm, signature);
+ }
+ }
+}
diff --git a/crypto/src/tls/DefaultTlsClient.cs b/crypto/src/tls/DefaultTlsClient.cs
index a2a742633..00827b5e7 100644
--- a/crypto/src/tls/DefaultTlsClient.cs
+++ b/crypto/src/tls/DefaultTlsClient.cs
@@ -10,10 +10,10 @@ namespace Org.BouncyCastle.Tls
private static readonly int[] DefaultCipherSuites = new int[]
{
/*
- * TODO[tls13] TLS 1.3
+ * TLS 1.3
*/
- //CipherSuite.TLS_CHACHA20_POLY1305_SHA256,
- //CipherSuite.TLS_AES_128_GCM_SHA256,
+ CipherSuite.TLS_CHACHA20_POLY1305_SHA256,
+ CipherSuite.TLS_AES_128_GCM_SHA256,
/*
* pre-TLS 1.3
diff --git a/crypto/src/tls/DefaultTlsServer.cs b/crypto/src/tls/DefaultTlsServer.cs
index de8a3f4a0..2df6c37eb 100644
--- a/crypto/src/tls/DefaultTlsServer.cs
+++ b/crypto/src/tls/DefaultTlsServer.cs
@@ -11,11 +11,11 @@ namespace Org.BouncyCastle.Tls
private static readonly int[] DefaultCipherSuites = new int[]
{
/*
- * TODO[tls13] TLS 1.3
+ * TLS 1.3
*/
- //CipherSuite.TLS_CHACHA20_POLY1305_SHA256,
- //CipherSuite.TLS_AES_256_GCM_SHA384,
- //CipherSuite.TLS_AES_128_GCM_SHA256,
+ CipherSuite.TLS_CHACHA20_POLY1305_SHA256,
+ CipherSuite.TLS_AES_256_GCM_SHA384,
+ CipherSuite.TLS_AES_128_GCM_SHA256,
/*
* pre-TLS 1.3
@@ -85,10 +85,6 @@ namespace Org.BouncyCastle.Tls
case KeyExchangeAlgorithm.DHE_DSS:
return GetDsaSignerCredentials();
- case KeyExchangeAlgorithm.DH_anon:
- case KeyExchangeAlgorithm.ECDH_anon:
- return null;
-
case KeyExchangeAlgorithm.ECDHE_ECDSA:
return GetECDsaSignerCredentials();
diff --git a/crypto/src/tls/DigitallySigned.cs b/crypto/src/tls/DigitallySigned.cs
index e977b350b..137847ada 100644
--- a/crypto/src/tls/DigitallySigned.cs
+++ b/crypto/src/tls/DigitallySigned.cs
@@ -5,27 +5,27 @@ namespace Org.BouncyCastle.Tls
{
public sealed class DigitallySigned
{
- private readonly SignatureAndHashAlgorithm algorithm;
- private readonly byte[] signature;
+ private readonly SignatureAndHashAlgorithm m_algorithm;
+ private readonly byte[] m_signature;
public DigitallySigned(SignatureAndHashAlgorithm algorithm, byte[] signature)
{
if (signature == null)
throw new ArgumentNullException("signature");
- this.algorithm = algorithm;
- this.signature = signature;
+ this.m_algorithm = algorithm;
+ this.m_signature = signature;
}
/// <returns>a <see cref="SignatureAndHashAlgorithm"/> (or null before TLS 1.2).</returns>
public SignatureAndHashAlgorithm Algorithm
{
- get { return algorithm; }
+ get { return m_algorithm; }
}
public byte[] Signature
{
- get { return signature; }
+ get { return m_signature; }
}
/// <summary>Encode this <see cref="DigitallySigned"/> to a <see cref="Stream"/>.</summary>
@@ -33,11 +33,11 @@ namespace Org.BouncyCastle.Tls
/// <exception cref="IOException"/>
public void Encode(Stream output)
{
- if (algorithm != null)
+ if (m_algorithm != null)
{
- algorithm.Encode(output);
+ m_algorithm.Encode(output);
}
- TlsUtilities.WriteOpaque16(signature, output);
+ TlsUtilities.WriteOpaque16(m_signature, output);
}
/// <summary>Parse a <see cref="DigitallySigned"/> from a <see cref="Stream"/>.</summary>
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;
}
diff --git a/crypto/src/tls/DtlsServerProtocol.cs b/crypto/src/tls/DtlsServerProtocol.cs
index b49122423..b01c6e34f 100644
--- a/crypto/src/tls/DtlsServerProtocol.cs
+++ b/crypto/src/tls/DtlsServerProtocol.cs
@@ -155,7 +155,13 @@ namespace Org.BouncyCastle.Tls
}
state.keyExchange = TlsUtilities.InitKeyExchangeServer(state.serverContext, state.server);
- state.serverCredentials = TlsUtilities.EstablishServerCredentials(state.server);
+
+ state.serverCredentials = null;
+
+ if (!KeyExchangeAlgorithm.IsAnonymous(securityParameters.KeyExchangeAlgorithm))
+ {
+ state.serverCredentials = TlsUtilities.EstablishServerCredentials(state.server);
+ }
// Server certificate
{
@@ -225,17 +231,34 @@ namespace Org.BouncyCastle.Tls
TlsUtilities.EstablishServerSigAlgs(securityParameters, state.certificateRequest);
- TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, securityParameters.ServerSigAlgs);
+ if (ProtocolVersion.DTLSv12.Equals(securityParameters.NegotiatedVersion))
+ {
+ TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, securityParameters.ServerSigAlgs);
- byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest);
- handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody);
+ if (state.serverContext.Crypto.HasAnyStreamVerifiers(securityParameters.ServerSigAlgs))
+ {
+ handshake.HandshakeHash.ForceBuffering();
+ }
+ }
+ else
+ {
+ if (state.serverContext.Crypto.HasAnyStreamVerifiersLegacy(state.certificateRequest.CertificateTypes))
+ {
+ handshake.HandshakeHash.ForceBuffering();
+ }
+ }
}
}
- handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes);
+ handshake.HandshakeHash.SealHashAlgorithms();
- bool forceBuffering = false;
- TlsUtilities.SealHandshakeHash(state.serverContext, handshake.HandshakeHash, forceBuffering);
+ if (null != state.certificateRequest)
+ {
+ byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest);
+ handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody);
+ }
+
+ handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes);
clientMessage = handshake.ReceiveMessage();
diff --git a/crypto/src/tls/KeyExchangeAlgorithm.cs b/crypto/src/tls/KeyExchangeAlgorithm.cs
index 1dfa6db66..fdb2773f1 100644
--- a/crypto/src/tls/KeyExchangeAlgorithm.cs
+++ b/crypto/src/tls/KeyExchangeAlgorithm.cs
@@ -59,5 +59,18 @@ namespace Org.BouncyCastle.Tls
* GMT 0024-2014
*/
public const int SM2 = 25;
+
+ public static bool IsAnonymous(int keyExchangeAlgorithm)
+ {
+ switch (keyExchangeAlgorithm)
+ {
+ case DH_anon:
+ case DH_anon_EXPORT:
+ case ECDH_anon:
+ return true;
+ default:
+ return false;
+ }
+ }
}
}
diff --git a/crypto/src/tls/ProtocolVersion.cs b/crypto/src/tls/ProtocolVersion.cs
index f37ce382d..f516aed2a 100644
--- a/crypto/src/tls/ProtocolVersion.cs
+++ b/crypto/src/tls/ProtocolVersion.cs
@@ -14,6 +14,7 @@ namespace Org.BouncyCastle.Tls
public static readonly ProtocolVersion TLSv13 = new ProtocolVersion(0x0304, "TLS 1.3");
public static readonly ProtocolVersion DTLSv10 = new ProtocolVersion(0xFEFF, "DTLS 1.0");
public static readonly ProtocolVersion DTLSv12 = new ProtocolVersion(0xFEFD, "DTLS 1.2");
+ public static readonly ProtocolVersion DTLSv13 = new ProtocolVersion(0xFEFC, "DTLS 1.3");
internal static readonly ProtocolVersion CLIENT_EARLIEST_SUPPORTED_DTLS = DTLSv10;
internal static readonly ProtocolVersion CLIENT_EARLIEST_SUPPORTED_TLS = SSLv3;
@@ -225,17 +226,22 @@ namespace Org.BouncyCastle.Tls
{
switch (MajorVersion)
{
- case 0x03:
- return this;
- case 0xFE:
- switch (MinorVersion)
- {
- case 0xFF: return TLSv11;
- case 0xFD: return TLSv12;
- default: return null;
- }
+ case 0x03:
+ return this;
+ case 0xFE:
+ switch (MinorVersion)
+ {
+ case 0xFF:
+ return TLSv11;
+ case 0xFD:
+ return TLSv12;
+ case 0xFC:
+ return TLSv13;
default:
return null;
+ }
+ default:
+ return null;
}
}
@@ -247,15 +253,20 @@ namespace Org.BouncyCastle.Tls
case 0x03:
switch (minor)
{
- case 0xFF: return null;
- default: return Get(major, minor + 1);
+ case 0xFF:
+ return null;
+ default:
+ return Get(major, minor + 1);
}
case 0xFE:
switch (minor)
{
- case 0x00: return null;
- case 0xFF: return DTLSv12;
- default: return Get(major, minor - 1);
+ case 0x00:
+ return null;
+ case 0xFF:
+ return DTLSv12;
+ default:
+ return Get(major, minor - 1);
}
default:
return null;
@@ -267,21 +278,26 @@ namespace Org.BouncyCastle.Tls
int major = MajorVersion, minor = MinorVersion;
switch (major)
{
- case 0x03:
- switch (minor)
- {
- case 0x00: return null;
- default: return Get(major, minor - 1);
- }
- case 0xFE:
- switch (minor)
- {
- case 0xFF: return null;
- case 0xFD: return DTLSv10;
- default: return Get(major, minor + 1);
- }
+ case 0x03:
+ switch (minor)
+ {
+ case 0x00:
+ return null;
default:
+ return Get(major, minor - 1);
+ }
+ case 0xFE:
+ switch (minor)
+ {
+ case 0xFF:
return null;
+ case 0xFD:
+ return DTLSv10;
+ default:
+ return Get(major, minor + 1);
+ }
+ default:
+ return null;
}
}
@@ -367,6 +383,8 @@ namespace Org.BouncyCastle.Tls
throw new ArgumentException("{0xFE, 0xFE} is a reserved protocol version");
case 0xFD:
return DTLSv12;
+ case 0xFC:
+ return DTLSv13;
}
return GetUnknownVersion(major, minor, "DTLS");
}
diff --git a/crypto/src/tls/PskTlsClient.cs b/crypto/src/tls/PskTlsClient.cs
index 3e9a00390..c475be63b 100644
--- a/crypto/src/tls/PskTlsClient.cs
+++ b/crypto/src/tls/PskTlsClient.cs
@@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Tls
protected override ProtocolVersion[] GetSupportedVersions()
{
- return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10);
+ return ProtocolVersion.TLSv12.Only();
}
protected override int[] GetSupportedCipherSuites()
diff --git a/crypto/src/tls/PskTlsServer.cs b/crypto/src/tls/PskTlsServer.cs
index 7197b6ad8..968cd5ce3 100644
--- a/crypto/src/tls/PskTlsServer.cs
+++ b/crypto/src/tls/PskTlsServer.cs
@@ -40,7 +40,7 @@ namespace Org.BouncyCastle.Tls
protected override ProtocolVersion[] GetSupportedVersions()
{
- return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10);
+ return ProtocolVersion.TLSv12.Only();
}
protected override int[] GetSupportedCipherSuites()
diff --git a/crypto/src/tls/SignatureAlgorithm.cs b/crypto/src/tls/SignatureAlgorithm.cs
index 726504c52..baf5620e3 100644
--- a/crypto/src/tls/SignatureAlgorithm.cs
+++ b/crypto/src/tls/SignatureAlgorithm.cs
@@ -86,20 +86,16 @@ namespace Org.BouncyCastle.Tls
return "dsa";
case ecdsa:
return "ecdsa";
- case ed25519:
- return "ed25519";
- case ed448:
- return "ed448";
- case gostr34102012_256:
- return "gostr34102012_256";
- case gostr34102012_512:
- return "gostr34102012_512";
case rsa_pss_rsae_sha256:
return "rsa_pss_rsae_sha256";
case rsa_pss_rsae_sha384:
return "rsa_pss_rsae_sha384";
case rsa_pss_rsae_sha512:
return "rsa_pss_rsae_sha512";
+ case ed25519:
+ return "ed25519";
+ case ed448:
+ return "ed448";
case rsa_pss_pss_sha256:
return "rsa_pss_pss_sha256";
case rsa_pss_pss_sha384:
@@ -112,6 +108,10 @@ namespace Org.BouncyCastle.Tls
return "ecdsa_brainpoolP384r1tls13_sha384";
case ecdsa_brainpoolP512r1tls13_sha512:
return "ecdsa_brainpoolP512r1tls13_sha512";
+ case gostr34102012_256:
+ return "gostr34102012_256";
+ case gostr34102012_512:
+ return "gostr34102012_512";
default:
return "UNKNOWN";
}
@@ -121,5 +121,32 @@ namespace Org.BouncyCastle.Tls
{
return GetName(signatureAlgorithm) + "(" + signatureAlgorithm + ")";
}
+
+ public static bool IsRecognized(short signatureAlgorithm)
+ {
+ switch (signatureAlgorithm)
+ {
+ case anonymous:
+ case rsa:
+ case dsa:
+ case ecdsa:
+ case rsa_pss_rsae_sha256:
+ case rsa_pss_rsae_sha384:
+ case rsa_pss_rsae_sha512:
+ case ed25519:
+ case ed448:
+ case rsa_pss_pss_sha256:
+ case rsa_pss_pss_sha384:
+ case rsa_pss_pss_sha512:
+ case ecdsa_brainpoolP256r1tls13_sha256:
+ case ecdsa_brainpoolP384r1tls13_sha384:
+ case ecdsa_brainpoolP512r1tls13_sha512:
+ case gostr34102012_256:
+ case gostr34102012_512:
+ return true;
+ default:
+ return false;
+ }
+ }
}
}
diff --git a/crypto/src/tls/SignatureScheme.cs b/crypto/src/tls/SignatureScheme.cs
index 4b934133d..ed8e3c21b 100644
--- a/crypto/src/tls/SignatureScheme.cs
+++ b/crypto/src/tls/SignatureScheme.cs
@@ -92,11 +92,16 @@ namespace Org.BouncyCastle.Tls
if (HashAlgorithm.Intrinsic == hashAlgorithm || !HashAlgorithm.IsRecognized(hashAlgorithm))
return -1;
- return TlsCryptoUtilities.GetHash(GetHashAlgorithm(signatureScheme));
+ return TlsCryptoUtilities.GetHash(hashAlgorithm);
}
}
}
+ public static int GetCryptoHashAlgorithm(SignatureAndHashAlgorithm signatureAndHashAlgorithm)
+ {
+ return GetCryptoHashAlgorithm(From(signatureAndHashAlgorithm));
+ }
+
public static string GetName(int signatureScheme)
{
switch (signatureScheme)
diff --git a/crypto/src/tls/SrpTlsClient.cs b/crypto/src/tls/SrpTlsClient.cs
index a2b0e9461..f6f6472bc 100644
--- a/crypto/src/tls/SrpTlsClient.cs
+++ b/crypto/src/tls/SrpTlsClient.cs
@@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Tls
protected override ProtocolVersion[] GetSupportedVersions()
{
- return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10);
+ return ProtocolVersion.TLSv12.Only();
}
protected virtual bool RequireSrpServerExtension
diff --git a/crypto/src/tls/SrpTlsServer.cs b/crypto/src/tls/SrpTlsServer.cs
index 58f89ee22..1e2f09e03 100644
--- a/crypto/src/tls/SrpTlsServer.cs
+++ b/crypto/src/tls/SrpTlsServer.cs
@@ -44,7 +44,7 @@ namespace Org.BouncyCastle.Tls
protected override ProtocolVersion[] GetSupportedVersions()
{
- return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10);
+ return ProtocolVersion.TLSv12.Only();
}
protected override int[] GetSupportedCipherSuites()
diff --git a/crypto/src/tls/TlsClientProtocol.cs b/crypto/src/tls/TlsClientProtocol.cs
index cb59289ae..ba2b565ca 100644
--- a/crypto/src/tls/TlsClientProtocol.cs
+++ b/crypto/src/tls/TlsClientProtocol.cs
@@ -450,24 +450,27 @@ namespace Org.BouncyCastle.Tls
{
Process13HelloRetryRequest(serverHello);
m_handshakeHash.NotifyPrfDetermined();
+ m_handshakeHash.SealHashAlgorithms();
TlsUtilities.AdjustTranscriptForRetry(m_handshakeHash);
buf.UpdateHash(m_handshakeHash);
this.m_connectionState = CS_SERVER_HELLO_RETRY_REQUEST;
Send13ClientHelloRetry();
- m_handshakeHash.SealHashAlgorithms();
this.m_connectionState = CS_CLIENT_HELLO_RETRY;
}
else
{
ProcessServerHello(serverHello);
m_handshakeHash.NotifyPrfDetermined();
+ if (TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion))
+ {
+ m_handshakeHash.SealHashAlgorithms();
+ }
buf.UpdateHash(m_handshakeHash);
this.m_connectionState = CS_SERVER_HELLO;
if (TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion))
{
- m_handshakeHash.SealHashAlgorithms();
Process13ServerHelloCoda(serverHello, false);
}
}
@@ -526,61 +529,70 @@ namespace Org.BouncyCastle.Tls
this.m_connectionState = CS_SERVER_HELLO_DONE;
- IList clientSupplementalData = m_tlsClient.GetClientSupplementalData();
- if (clientSupplementalData != null)
+ TlsCredentials clientAuthCredentials = null;
+ TlsCredentialedSigner clientAuthSigner = null;
+ Certificate clientAuthCertificate = null;
+ SignatureAndHashAlgorithm clientAuthAlgorithm = null;
+ TlsStreamSigner clientAuthStreamSigner = null;
+
+ if (m_certificateRequest != null)
{
- SendSupplementalDataMessage(clientSupplementalData);
- this.m_connectionState = CS_CLIENT_SUPPLEMENTAL_DATA;
+ clientAuthCredentials = TlsUtilities.EstablishClientCredentials(m_authentication,
+ m_certificateRequest);
+ if (clientAuthCredentials != null)
+ {
+ clientAuthCertificate = clientAuthCredentials.Certificate;
+
+ if (clientAuthCredentials is TlsCredentialedSigner)
+ {
+ clientAuthSigner = (TlsCredentialedSigner)clientAuthCredentials;
+ clientAuthAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(
+ securityParameters.NegotiatedVersion, clientAuthSigner);
+ clientAuthStreamSigner = clientAuthSigner.GetStreamSigner();
+
+ if (ProtocolVersion.TLSv12.Equals(securityParameters.NegotiatedVersion))
+ {
+ TlsUtilities.VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs,
+ clientAuthAlgorithm, AlertDescription.internal_error);
+
+ if (clientAuthStreamSigner == null)
+ {
+ TlsUtilities.TrackHashAlgorithmClient(m_handshakeHash, clientAuthAlgorithm);
+ }
+ }
+
+ if (clientAuthStreamSigner != null)
+ {
+ m_handshakeHash.ForceBuffering();
+ }
+ }
+ }
}
- TlsCredentialedSigner credentialedSigner = null;
- TlsStreamSigner streamSigner = null;
+ m_handshakeHash.SealHashAlgorithms();
- if (m_certificateRequest == null)
+ if (clientAuthCredentials == null)
{
m_keyExchange.SkipClientCredentials();
}
else
{
- Certificate clientCertificate = null;
-
- TlsCredentials clientCredentials = TlsUtilities.EstablishClientCredentials(m_authentication,
- m_certificateRequest);
- if (null == clientCredentials)
- {
- m_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.
- */
- }
- else
- {
- m_keyExchange.ProcessClientCredentials(clientCredentials);
-
- clientCertificate = clientCredentials.Certificate;
-
- if (clientCredentials is TlsCredentialedSigner)
- {
- credentialedSigner = (TlsCredentialedSigner)clientCredentials;
- streamSigner = credentialedSigner.GetStreamSigner();
- }
- }
+ m_keyExchange.ProcessClientCredentials(clientAuthCredentials);
+ }
- SendCertificateMessage(clientCertificate, null);
- this.m_connectionState = CS_CLIENT_CERTIFICATE;
+ IList clientSupplementalData = m_tlsClient.GetClientSupplementalData();
+ if (clientSupplementalData != null)
+ {
+ SendSupplementalDataMessage(clientSupplementalData);
+ this.m_connectionState = CS_CLIENT_SUPPLEMENTAL_DATA;
}
- bool forceBuffering = streamSigner != null;
- TlsUtilities.SealHandshakeHash(m_tlsClientContext, m_handshakeHash, forceBuffering);
+ if (m_certificateRequest != null)
+ {
+ SendCertificateMessage(clientAuthCertificate, null);
+ this.m_connectionState = CS_CLIENT_CERTIFICATE;
+ }
- /*
- * Send the client key exchange message, depending on the key exchange we are using
- * in our CipherSuite.
- */
SendClientKeyExchange();
this.m_connectionState = CS_CLIENT_KEY_EXCHANGE;
@@ -601,10 +613,11 @@ namespace Org.BouncyCastle.Tls
m_recordStream.SetPendingCipher(TlsUtilities.InitCipher(m_tlsClientContext));
- if (credentialedSigner != null)
+ if (clientAuthSigner != null)
{
DigitallySigned certificateVerify = TlsUtilities.GenerateCertificateVerifyClient(
- m_tlsClientContext, credentialedSigner, streamSigner, m_handshakeHash);
+ m_tlsClientContext, clientAuthSigner, clientAuthAlgorithm, clientAuthStreamSigner,
+ m_handshakeHash);
SendCertificateVerifyMessage(certificateVerify);
this.m_connectionState = CS_CLIENT_CERTIFICATE_VERIFY;
}
@@ -674,13 +687,6 @@ namespace Org.BouncyCastle.Tls
ReceiveCertificateRequest(buf);
TlsUtilities.EstablishServerSigAlgs(securityParameters, m_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(m_handshakeHash, securityParameters.ServerSigAlgs);
-
break;
}
default:
@@ -1467,12 +1473,11 @@ namespace Org.BouncyCastle.Tls
if (null == serverCertificate || serverCertificate.IsEmpty)
throw new TlsFatalAlert(AlertDescription.internal_error);
- // TODO[tls13] Actual structure is 'CertificateVerify' in RFC 8446, consider adding for clarity
- DigitallySigned certificateVerify = DigitallySigned.Parse(m_tlsClientContext, buf);
+ CertificateVerify certificateVerify = CertificateVerify.Parse(m_tlsClientContext, buf);
AssertEmpty(buf);
- TlsUtilities.Verify13CertificateVerifyServer(m_tlsClientContext, certificateVerify, m_handshakeHash);
+ TlsUtilities.Verify13CertificateVerifyServer(m_tlsClientContext, m_handshakeHash, certificateVerify);
}
/// <exception cref="IOException"/>
diff --git a/crypto/src/tls/TlsServerProtocol.cs b/crypto/src/tls/TlsServerProtocol.cs
index 0ab8a7a98..c90ef4109 100644
--- a/crypto/src/tls/TlsServerProtocol.cs
+++ b/crypto/src/tls/TlsServerProtocol.cs
@@ -907,6 +907,7 @@ namespace Org.BouncyCastle.Tls
if (serverHello.IsHelloRetryRequest())
{
TlsUtilities.AdjustTranscriptForRetry(m_handshakeHash);
+
SendServerHelloMessage(serverHello);
this.m_connectionState = CS_SERVER_HELLO_RETRY_REQUEST;
@@ -952,7 +953,12 @@ namespace Org.BouncyCastle.Tls
this.m_keyExchange = TlsUtilities.InitKeyExchangeServer(m_tlsServerContext, m_tlsServer);
- TlsCredentials serverCredentials = TlsUtilities.EstablishServerCredentials(m_tlsServer);
+ TlsCredentials serverCredentials = null;
+
+ if (!KeyExchangeAlgorithm.IsAnonymous(securityParameters.KeyExchangeAlgorithm))
+ {
+ serverCredentials = TlsUtilities.EstablishServerCredentials(m_tlsServer);
+ }
// Server certificate
{
@@ -1026,19 +1032,36 @@ namespace Org.BouncyCastle.Tls
TlsUtilities.EstablishServerSigAlgs(securityParameters, m_certificateRequest);
- TlsUtilities.TrackHashAlgorithms(m_handshakeHash, securityParameters.ServerSigAlgs);
+ if (ProtocolVersion.TLSv12.Equals(securityParameters.NegotiatedVersion))
+ {
+ TlsUtilities.TrackHashAlgorithms(m_handshakeHash, securityParameters.ServerSigAlgs);
- SendCertificateRequestMessage(m_certificateRequest);
- this.m_connectionState = CS_SERVER_CERTIFICATE_REQUEST;
+ if (m_tlsServerContext.Crypto.HasAnyStreamVerifiers(securityParameters.ServerSigAlgs))
+ {
+ m_handshakeHash.ForceBuffering();
+ }
+ }
+ else
+ {
+ if (m_tlsServerContext.Crypto.HasAnyStreamVerifiersLegacy(m_certificateRequest.CertificateTypes))
+ {
+ m_handshakeHash.ForceBuffering();
+ }
+ }
}
}
+ m_handshakeHash.SealHashAlgorithms();
+
+ if (null != m_certificateRequest)
+ {
+ SendCertificateRequestMessage(m_certificateRequest);
+ this.m_connectionState = CS_SERVER_CERTIFICATE_REQUEST;
+ }
+
SendServerHelloDoneMessage();
this.m_connectionState = CS_SERVER_HELLO_DONE;
- bool forceBuffering = false;
- TlsUtilities.SealHandshakeHash(m_tlsServerContext, m_handshakeHash, forceBuffering);
-
break;
}
default:
@@ -1281,13 +1304,11 @@ namespace Org.BouncyCastle.Tls
if (null == clientCertificate || clientCertificate.IsEmpty)
throw new TlsFatalAlert(AlertDescription.internal_error);
- // TODO[tls13] Actual structure is 'CertificateVerify' in RFC 8446, consider adding for clarity
- DigitallySigned certificateVerify = DigitallySigned.Parse(m_tlsServerContext, buf);
+ CertificateVerify certificateVerify = CertificateVerify.Parse(m_tlsServerContext, buf);
AssertEmpty(buf);
- TlsUtilities.Verify13CertificateVerifyClient(m_tlsServerContext, m_certificateRequest, certificateVerify,
- m_handshakeHash);
+ TlsUtilities.Verify13CertificateVerifyClient(m_tlsServerContext, m_handshakeHash, certificateVerify);
}
/// <exception cref="IOException"/>
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();
diff --git a/crypto/src/tls/crypto/CryptoSignatureAlgorithm.cs b/crypto/src/tls/crypto/CryptoSignatureAlgorithm.cs
index ed58820b8..15435cab5 100644
--- a/crypto/src/tls/crypto/CryptoSignatureAlgorithm.cs
+++ b/crypto/src/tls/crypto/CryptoSignatureAlgorithm.cs
@@ -15,6 +15,9 @@ namespace Org.BouncyCastle.Tls.Crypto
public const int rsa_pss_pss_sha256 = 9;
public const int rsa_pss_pss_sha384 = 10;
public const int rsa_pss_pss_sha512 = 11;
+ public const int ecdsa_brainpoolP256r1tls13_sha256 = 26;
+ public const int ecdsa_brainpoolP384r1tls13_sha384 = 27;
+ public const int ecdsa_brainpoolP512r1tls13_sha512 = 28;
public const int gostr34102012_256 = 64;
public const int gostr34102012_512 = 65;
public const int sm2 = 200;
diff --git a/crypto/src/tls/crypto/Tls13Verifier.cs b/crypto/src/tls/crypto/Tls13Verifier.cs
new file mode 100644
index 000000000..143ea7394
--- /dev/null
+++ b/crypto/src/tls/crypto/Tls13Verifier.cs
@@ -0,0 +1,14 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Tls.Crypto
+{
+ public interface Tls13Verifier
+ {
+ /// <exception cref="IOException"/>
+ Stream Stream { get; }
+
+ /// <exception cref="IOException"/>
+ bool VerifySignature(byte[] signature);
+ }
+}
diff --git a/crypto/src/tls/crypto/TlsCertificate.cs b/crypto/src/tls/crypto/TlsCertificate.cs
index fe507a662..6b3e3220a 100644
--- a/crypto/src/tls/crypto/TlsCertificate.cs
+++ b/crypto/src/tls/crypto/TlsCertificate.cs
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Tls.Crypto
/// <param name="signatureScheme"><see cref="SignatureScheme"/></param>
/// <exception cref="IOException"/>
- TlsVerifier CreateVerifier(int signatureScheme);
+ Tls13Verifier CreateVerifier(int signatureScheme);
/// <exception cref="IOException"/>
byte[] GetEncoded();
diff --git a/crypto/src/tls/crypto/TlsCrypto.cs b/crypto/src/tls/crypto/TlsCrypto.cs
index 4dab6bc57..27c5fb9e1 100644
--- a/crypto/src/tls/crypto/TlsCrypto.cs
+++ b/crypto/src/tls/crypto/TlsCrypto.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.IO;
using Org.BouncyCastle.Math;
@@ -10,11 +11,22 @@ namespace Org.BouncyCastle.Tls.Crypto
/// cryptography in the API.</summary>
public interface TlsCrypto
{
- /// <summary>Return true if this TlsCrypto can perform raw signatures and verifications for all supported
- /// algorithms.</summary>
- /// <returns>true if this instance can perform raw signatures and verifications for all supported algorithms,
- /// false otherwise.</returns>
- bool HasAllRawSignatureAlgorithms();
+ /// <summary>Return true if this TlsCrypto would use a stream verifier for any of the passed in algorithms.
+ /// </summary>
+ /// <remarks>This method is only relevant to handshakes negotiating (D)TLS 1.2.</remarks>
+ /// <param name="signatureAndHashAlgorithms">A <see cref="IList">list</see> of
+ /// <see cref="SignatureAndHashAlgorithm"/> values.</param>
+ /// <returns>true if this instance would use a stream verifier for any of the passed in algorithms, otherwise
+ /// false.</returns>
+ bool HasAnyStreamVerifiers(IList signatureAndHashAlgorithms);
+
+ /// <summary>Return true if this TlsCrypto would use a stream verifier for any of the passed in algorithms.
+ /// </summary>
+ /// <remarks>This method is only relevant to handshakes negotiating (D)TLS versions older than 1.2.</remarks>
+ /// <param name="clientCertificateTypes">An array of <see cref="ClientCertificateType"/> values.</param>
+ /// <returns>true if this instance would use a stream verifier for any of the passed in algorithms, otherwise
+ /// false.</returns>
+ bool HasAnyStreamVerifiersLegacy(short[] clientCertificateTypes);
/// <summary>Return true if this TlsCrypto can support the passed in hash algorithm.</summary>
/// <param name="cryptoHashAlgorithm">the algorithm of interest.</param>
diff --git a/crypto/src/tls/crypto/TlsCryptoUtilities.cs b/crypto/src/tls/crypto/TlsCryptoUtilities.cs
index 757eda1be..98ac87a83 100644
--- a/crypto/src/tls/crypto/TlsCryptoUtilities.cs
+++ b/crypto/src/tls/crypto/TlsCryptoUtilities.cs
@@ -1,6 +1,11 @@
using System;
using System.IO;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+
namespace Org.BouncyCastle.Tls.Crypto
{
public abstract class TlsCryptoUtilities
@@ -108,6 +113,30 @@ namespace Org.BouncyCastle.Tls.Crypto
}
}
+ public static DerObjectIdentifier GetOidForHash(int cryptoHashAlgorithm)
+ {
+ switch (cryptoHashAlgorithm)
+ {
+ case CryptoHashAlgorithm.md5:
+ return PkcsObjectIdentifiers.MD5;
+ case CryptoHashAlgorithm.sha1:
+ return X509ObjectIdentifiers.IdSha1;
+ case CryptoHashAlgorithm.sha224:
+ return NistObjectIdentifiers.IdSha224;
+ case CryptoHashAlgorithm.sha256:
+ return NistObjectIdentifiers.IdSha256;
+ case CryptoHashAlgorithm.sha384:
+ return NistObjectIdentifiers.IdSha384;
+ case CryptoHashAlgorithm.sha512:
+ return NistObjectIdentifiers.IdSha512;
+ // TODO[RFC 8998]
+ //case CryptoHashAlgorithm.sm3:
+ // return GMObjectIdentifiers.sm3;
+ default:
+ throw new ArgumentException();
+ }
+ }
+
public static int GetSignature(short signatureAlgorithm)
{
switch (signatureAlgorithm)
@@ -134,6 +163,12 @@ namespace Org.BouncyCastle.Tls.Crypto
return CryptoSignatureAlgorithm.rsa_pss_pss_sha384;
case SignatureAlgorithm.rsa_pss_pss_sha512:
return CryptoSignatureAlgorithm.rsa_pss_pss_sha512;
+ case SignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256:
+ return CryptoSignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256;
+ case SignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384:
+ return CryptoSignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384;
+ case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512:
+ return CryptoSignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512;
case SignatureAlgorithm.gostr34102012_256:
return CryptoSignatureAlgorithm.gostr34102012_256;
case SignatureAlgorithm.gostr34102012_512:
diff --git a/crypto/src/tls/crypto/TlsStreamSigner.cs b/crypto/src/tls/crypto/TlsStreamSigner.cs
index 8f79346bf..c3634fe27 100644
--- a/crypto/src/tls/crypto/TlsStreamSigner.cs
+++ b/crypto/src/tls/crypto/TlsStreamSigner.cs
@@ -6,7 +6,7 @@ namespace Org.BouncyCastle.Tls.Crypto
public interface TlsStreamSigner
{
/// <exception cref="IOException"/>
- Stream GetOutputStream();
+ Stream Stream { get; }
/// <exception cref="IOException"/>
byte[] GetSignature();
diff --git a/crypto/src/tls/crypto/TlsStreamVerifier.cs b/crypto/src/tls/crypto/TlsStreamVerifier.cs
index 9d18a9c9c..33b0e3879 100644
--- a/crypto/src/tls/crypto/TlsStreamVerifier.cs
+++ b/crypto/src/tls/crypto/TlsStreamVerifier.cs
@@ -6,7 +6,7 @@ namespace Org.BouncyCastle.Tls.Crypto
public interface TlsStreamVerifier
{
/// <exception cref="IOException"/>
- Stream GetOutputStream();
+ Stream Stream { get; }
/// <exception cref="IOException"/>
bool IsVerified();
diff --git a/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs b/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs
index 39d86c241..87fe66dff 100644
--- a/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs
+++ b/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs
@@ -1,5 +1,5 @@
using System;
-using System.IO;
+using System.Collections;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
@@ -12,7 +12,9 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl
public abstract class AbstractTlsCrypto
: TlsCrypto
{
- public abstract bool HasAllRawSignatureAlgorithms();
+ public abstract bool HasAnyStreamVerifiers(IList signatureAndHashAlgorithms);
+
+ public abstract bool HasAnyStreamVerifiersLegacy(short[] clientCertificateTypes);
public abstract bool HasCryptoHashAlgorithm(int cryptoHashAlgorithm);
diff --git a/crypto/src/tls/crypto/impl/LegacyTls13Verifier.cs b/crypto/src/tls/crypto/impl/LegacyTls13Verifier.cs
new file mode 100644
index 000000000..294a14da4
--- /dev/null
+++ b/crypto/src/tls/crypto/impl/LegacyTls13Verifier.cs
@@ -0,0 +1,60 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Tls.Crypto.Impl
+{
+ public sealed class LegacyTls13Verifier
+ : TlsVerifier
+ {
+ private readonly int m_signatureScheme;
+ private readonly Tls13Verifier m_tls13Verifier;
+
+ public LegacyTls13Verifier(int signatureScheme, Tls13Verifier tls13Verifier)
+ {
+ if (!TlsUtilities.IsValidUint16(signatureScheme))
+ throw new ArgumentException("signatureScheme");
+ if (tls13Verifier == null)
+ throw new ArgumentNullException("tls13Verifier");
+
+ this.m_signatureScheme = signatureScheme;
+ this.m_tls13Verifier = tls13Verifier;
+ }
+
+ public TlsStreamVerifier GetStreamVerifier(DigitallySigned digitallySigned)
+ {
+ SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm;
+ if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme)
+ throw new InvalidOperationException("Invalid algorithm: " + algorithm);
+
+ return new TlsStreamVerifierImpl(m_tls13Verifier, digitallySigned.Signature);
+ }
+
+ public bool VerifyRawSignature(DigitallySigned digitallySigned, byte[] hash)
+ {
+ throw new NotSupportedException();
+ }
+
+ private class TlsStreamVerifierImpl
+ : TlsStreamVerifier
+ {
+ private readonly Tls13Verifier m_tls13Verifier;
+ private readonly byte[] m_signature;
+
+ internal TlsStreamVerifierImpl(Tls13Verifier tls13Verifier, byte[] signature)
+ {
+ this.m_tls13Verifier = tls13Verifier;
+ this.m_signature = signature;
+ }
+
+ public Stream Stream
+ {
+ get { return m_tls13Verifier.Stream; }
+ }
+
+ public bool IsVerified()
+ {
+ return m_tls13Verifier.VerifySignature(m_signature);
+ }
+ }
+ }
+}
diff --git a/crypto/src/tls/crypto/impl/TlsAeadCipher.cs b/crypto/src/tls/crypto/impl/TlsAeadCipher.cs
index ec76e98c1..04f9ce80f 100644
--- a/crypto/src/tls/crypto/impl/TlsAeadCipher.cs
+++ b/crypto/src/tls/crypto/impl/TlsAeadCipher.cs
@@ -175,14 +175,13 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl
try
{
- m_encryptCipher.Init(nonce, m_macSize, additionalData);
-
Array.Copy(plaintext, plaintextOffset, output, outputPos, plaintextLength);
if (m_isTlsV13)
{
output[outputPos + plaintextLength] = (byte)contentType;
}
+ m_encryptCipher.Init(nonce, m_macSize, additionalData);
outputPos += m_encryptCipher.DoFinal(output, outputPos, plaintextLength + extraLength, output,
outputPos);
}
@@ -354,7 +353,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl
Array.Copy(iv, 0, nonce, 0, m_fixed_iv_length);
// NOTE: Ensure dummy nonce is not part of the generated sequence(s)
- iv [0] ^= 0x80;
+ iv[0] ^= 0x80;
cipher.Init(iv, m_macSize, null);
}
diff --git a/crypto/src/tls/crypto/impl/bc/BcTls13Verifier.cs b/crypto/src/tls/crypto/impl/bc/BcTls13Verifier.cs
new file mode 100644
index 000000000..ba4d0ccf8
--- /dev/null
+++ b/crypto/src/tls/crypto/impl/bc/BcTls13Verifier.cs
@@ -0,0 +1,32 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.IO;
+
+namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
+{
+ internal sealed class BcTls13Verifier
+ : Tls13Verifier
+ {
+ private readonly SignerSink m_output;
+
+ internal BcTls13Verifier(ISigner verifier)
+ {
+ if (verifier == null)
+ throw new ArgumentNullException("verifier");
+
+ this.m_output = new SignerSink(verifier);
+ }
+
+ public Stream Stream
+ {
+ get { return m_output; }
+ }
+
+ public bool VerifySignature(byte[] signature)
+ {
+ return m_output.Signer.VerifySignature(signature);
+ }
+ }
+}
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsCertificate.cs b/crypto/src/tls/crypto/impl/bc/BcTlsCertificate.cs
index 469785dc2..7e946ce23 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsCertificate.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsCertificate.cs
@@ -4,7 +4,9 @@ using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
@@ -87,38 +89,56 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
{
switch (signatureAlgorithm)
{
- case SignatureAlgorithm.rsa_pss_rsae_sha256:
- case SignatureAlgorithm.rsa_pss_rsae_sha384:
- case SignatureAlgorithm.rsa_pss_rsae_sha512:
case SignatureAlgorithm.ed25519:
case SignatureAlgorithm.ed448:
- case SignatureAlgorithm.rsa_pss_pss_sha256:
- case SignatureAlgorithm.rsa_pss_pss_sha384:
- case SignatureAlgorithm.rsa_pss_pss_sha512:
- return CreateVerifier(SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm));
+ {
+ int signatureScheme = SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm);
+ Tls13Verifier tls13Verifier = CreateVerifier(signatureScheme);
+ return new LegacyTls13Verifier(signatureScheme, tls13Verifier);
+ }
}
ValidateKeyUsage(KeyUsage.DigitalSignature);
switch (signatureAlgorithm)
{
- case SignatureAlgorithm.rsa:
- ValidateRsa_Pkcs1();
- return new BcTlsRsaVerifier(m_crypto, GetPubKeyRsa());
-
case SignatureAlgorithm.dsa:
return new BcTlsDsaVerifier(m_crypto, GetPubKeyDss());
case SignatureAlgorithm.ecdsa:
return new BcTlsECDsaVerifier(m_crypto, GetPubKeyEC());
+ case SignatureAlgorithm.rsa:
+ {
+ ValidateRsa_Pkcs1();
+ return new BcTlsRsaVerifier(m_crypto, GetPubKeyRsa());
+ }
+
+ case SignatureAlgorithm.rsa_pss_pss_sha256:
+ case SignatureAlgorithm.rsa_pss_pss_sha384:
+ case SignatureAlgorithm.rsa_pss_pss_sha512:
+ {
+ ValidateRsa_Pss_Pss(signatureAlgorithm);
+ int signatureScheme = SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm);
+ return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme);
+ }
+
+ case SignatureAlgorithm.rsa_pss_rsae_sha256:
+ case SignatureAlgorithm.rsa_pss_rsae_sha384:
+ case SignatureAlgorithm.rsa_pss_rsae_sha512:
+ {
+ ValidateRsa_Pss_Rsae();
+ int signatureScheme = SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm);
+ return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme);
+ }
+
default:
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
}
}
/// <exception cref="IOException"/>
- public virtual TlsVerifier CreateVerifier(int signatureScheme)
+ public virtual Tls13Verifier CreateVerifier(int signatureScheme)
{
ValidateKeyUsage(KeyUsage.DigitalSignature);
@@ -131,13 +151,31 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
case SignatureScheme.ecdsa_secp384r1_sha384:
case SignatureScheme.ecdsa_secp521r1_sha512:
case SignatureScheme.ecdsa_sha1:
- return new BcTlsECDsa13Verifier(m_crypto, GetPubKeyEC(), signatureScheme);
+ {
+ int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
+ IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
+
+ ISigner verifier = new DsaDigestSigner(new ECDsaSigner(), digest);
+ verifier.Init(false, GetPubKeyEC());
+
+ return new BcTls13Verifier(verifier);
+ }
case SignatureScheme.ed25519:
- return new BcTlsEd25519Verifier(m_crypto, GetPubKeyEd25519());
+ {
+ Ed25519Signer verifier = new Ed25519Signer();
+ verifier.Init(false, GetPubKeyEd25519());
+
+ return new BcTls13Verifier(verifier);
+ }
case SignatureScheme.ed448:
- return new BcTlsEd448Verifier(m_crypto, GetPubKeyEd448());
+ {
+ Ed448Signer verifier = new Ed448Signer(TlsUtilities.EmptyBytes);
+ verifier.Init(false, GetPubKeyEd448());
+
+ return new BcTls13Verifier(verifier);
+ }
case SignatureScheme.rsa_pkcs1_sha1:
case SignatureScheme.rsa_pkcs1_sha256:
@@ -145,7 +183,15 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
case SignatureScheme.rsa_pkcs1_sha512:
{
ValidateRsa_Pkcs1();
- return new BcTlsRsaVerifier(m_crypto, GetPubKeyRsa());
+
+ int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
+ IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
+
+ RsaDigestSigner verifier = new RsaDigestSigner(digest,
+ TlsCryptoUtilities.GetOidForHash(cryptoHashAlgorithm));
+ verifier.Init(false, GetPubKeyRsa());
+
+ return new BcTls13Verifier(verifier);
}
case SignatureScheme.rsa_pss_pss_sha256:
@@ -153,7 +199,14 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
case SignatureScheme.rsa_pss_pss_sha512:
{
ValidateRsa_Pss_Pss(SignatureScheme.GetSignatureAlgorithm(signatureScheme));
- return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme);
+
+ int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
+ IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
+
+ PssSigner verifier = new PssSigner(new RsaEngine(), digest, digest.GetDigestSize());
+ verifier.Init(false, GetPubKeyRsa());
+
+ return new BcTls13Verifier(verifier);
}
case SignatureScheme.rsa_pss_rsae_sha256:
@@ -161,12 +214,27 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
case SignatureScheme.rsa_pss_rsae_sha512:
{
ValidateRsa_Pss_Rsae();
- return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme);
+
+ int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme);
+ IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
+
+ PssSigner verifier = new PssSigner(new RsaEngine(), digest, digest.GetDigestSize());
+ verifier.Init(false, GetPubKeyRsa());
+
+ return new BcTls13Verifier(verifier);
}
// TODO[RFC 8998]
//case SignatureScheme.sm2sig_sm3:
- // return new BcTlsSM2Verifier(m_crypto, GetPubKeyEC(), Strings.ToByteArray("TLSv1.3+GM+Cipher+Suite"));
+ //{
+ // ParametersWithID parametersWithID = new ParametersWithID(GetPubKeyEC(),
+ // Strings.ToByteArray("TLSv1.3+GM+Cipher+Suite"));
+
+ // SM2Signer verifier = new SM2Signer();
+ // verifier.Init(false, parametersWithID);
+
+ // return new BcTls13Verifier(verifier);
+ //}
default:
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs
index a56835105..38062829e 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Agreement.Srp;
@@ -152,9 +153,22 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
return new BcTlsNonceGenerator(randomGenerator);
}
- public override bool HasAllRawSignatureAlgorithms()
+ public override bool HasAnyStreamVerifiers(IList signatureAndHashAlgorithms)
+ {
+ foreach (SignatureAndHashAlgorithm algorithm in signatureAndHashAlgorithms)
+ {
+ switch (SignatureScheme.From(algorithm))
+ {
+ case SignatureScheme.ed25519:
+ case SignatureScheme.ed448:
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public override bool HasAnyStreamVerifiersLegacy(short[] clientCertificateTypes)
{
- // TODO[RFC 8422] Revisit the need to buffer the handshake for "Intrinsic" hash signatures
return false;
}
@@ -219,16 +233,39 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
{
switch (encryptionAlgorithm)
{
- case EncryptionAlgorithm.DES40_CBC:
+ case EncryptionAlgorithm.AES_128_CBC:
+ case EncryptionAlgorithm.AES_128_CCM:
+ case EncryptionAlgorithm.AES_128_CCM_8:
+ case EncryptionAlgorithm.AES_128_GCM:
+ case EncryptionAlgorithm.AES_256_CBC:
+ case EncryptionAlgorithm.AES_256_CCM:
+ case EncryptionAlgorithm.AES_256_CCM_8:
+ case EncryptionAlgorithm.AES_256_GCM:
+ case EncryptionAlgorithm.ARIA_128_CBC:
+ case EncryptionAlgorithm.ARIA_128_GCM:
+ case EncryptionAlgorithm.ARIA_256_CBC:
+ case EncryptionAlgorithm.ARIA_256_GCM:
+ case EncryptionAlgorithm.CAMELLIA_128_CBC:
+ case EncryptionAlgorithm.CAMELLIA_128_GCM:
+ case EncryptionAlgorithm.CAMELLIA_256_CBC:
+ case EncryptionAlgorithm.CAMELLIA_256_GCM:
+ case EncryptionAlgorithm.CHACHA20_POLY1305:
+ case EncryptionAlgorithm.cls_3DES_EDE_CBC:
+ case EncryptionAlgorithm.NULL:
+ case EncryptionAlgorithm.SEED_CBC:
+ case EncryptionAlgorithm.SM4_CBC:
+ case EncryptionAlgorithm.SM4_CCM:
+ case EncryptionAlgorithm.SM4_GCM:
+ return true;
+
case EncryptionAlgorithm.DES_CBC:
+ case EncryptionAlgorithm.DES40_CBC:
case EncryptionAlgorithm.IDEA_CBC:
case EncryptionAlgorithm.RC2_CBC_40:
case EncryptionAlgorithm.RC4_128:
case EncryptionAlgorithm.RC4_40:
- return false;
-
default:
- return true;
+ return false;
}
}
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs b/crypto/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs
deleted file mode 100644
index 159b17c0b..000000000
--- a/crypto/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-
-using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.Digests;
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Crypto.Signers;
-
-namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
-{
- /// <summary>Implementation class for verification of ECDSA signatures in TLS 1.3+ using the BC light-weight API.
- /// </summary>
- public class BcTlsECDsa13Verifier
- : BcTlsVerifier
- {
- private readonly int m_signatureScheme;
-
- public BcTlsECDsa13Verifier(BcTlsCrypto crypto, ECPublicKeyParameters publicKey, int signatureScheme)
- : base(crypto, publicKey)
- {
- if (!SignatureScheme.IsECDsa(signatureScheme))
- throw new ArgumentException("signatureScheme");
-
- this.m_signatureScheme = signatureScheme;
- }
-
- public override bool VerifyRawSignature(DigitallySigned digitallySigned, byte[] hash)
- {
- SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm;
- if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme)
- throw new InvalidOperationException("Invalid algorithm: " + algorithm);
-
- IDsa dsa = new ECDsaSigner();
-
- ISigner signer = new DsaDigestSigner(dsa, new NullDigest());
- signer.Init(false, m_publicKey);
- signer.BlockUpdate(hash, 0, hash.Length);
- return signer.VerifySignature(digitallySigned.Signature);
- }
- }
-}
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs b/crypto/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs
deleted file mode 100644
index a787bb92a..000000000
--- a/crypto/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Crypto.Signers;
-
-namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
-{
- public class BcTlsEd25519Verifier
- : BcTlsVerifier
- {
- public BcTlsEd25519Verifier(BcTlsCrypto crypto, Ed25519PublicKeyParameters publicKey)
- : base(crypto, publicKey)
- {
- }
-
- public override TlsStreamVerifier GetStreamVerifier(DigitallySigned digitallySigned)
- {
- SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm;
- if (algorithm == null || SignatureScheme.From(algorithm) != SignatureScheme.ed25519)
- throw new InvalidOperationException("Invalid algorithm: " + algorithm);
-
- Ed25519Signer verifier = new Ed25519Signer();
- verifier.Init(false, m_publicKey);
-
- return new BcTlsStreamVerifier(verifier, digitallySigned.Signature);
- }
- }
-}
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs b/crypto/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs
deleted file mode 100644
index 7940d0757..000000000
--- a/crypto/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Crypto.Signers;
-
-namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
-{
- public class BcTlsEd448Verifier
- : BcTlsVerifier
- {
- public BcTlsEd448Verifier(BcTlsCrypto crypto, Ed448PublicKeyParameters publicKey)
- : base(crypto, publicKey)
- {
- }
-
- public override TlsStreamVerifier GetStreamVerifier(DigitallySigned digitallySigned)
- {
- SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm;
- if (algorithm == null || SignatureScheme.From(algorithm) != SignatureScheme.ed448)
- throw new InvalidOperationException("Invalid algorithm: " + algorithm);
-
- Ed448Signer verifier = new Ed448Signer(TlsUtilities.EmptyBytes);
- verifier.Init(false, m_publicKey);
-
- return new BcTlsStreamVerifier(verifier, digitallySigned.Signature);
- }
- }
-}
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs b/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs
index 3e7d1ceef..1b33573f6 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs
@@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
this.m_signatureScheme = signatureScheme;
}
- public override TlsStreamSigner GetStreamSigner(SignatureAndHashAlgorithm algorithm)
+ public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash)
{
if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme)
throw new InvalidOperationException("Invalid algorithm: " + algorithm);
@@ -30,10 +30,18 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(m_signatureScheme);
IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
- PssSigner signer = new PssSigner(new RsaBlindedEngine(), digest, digest.GetDigestSize());
+ PssSigner signer = PssSigner.CreateRawSigner(new RsaBlindedEngine(), digest, digest, digest.GetDigestSize(),
+ PssSigner.TrailerImplicit);
signer.Init(true, new ParametersWithRandom(m_privateKey, m_crypto.SecureRandom));
-
- return new BcTlsStreamSigner(signer);
+ signer.BlockUpdate(hash, 0, hash.Length);
+ try
+ {
+ return signer.GenerateSignature();
+ }
+ catch (CryptoException e)
+ {
+ throw new TlsFatalAlert(AlertDescription.internal_error, e);
+ }
}
}
}
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs b/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs
index dc8cebdd9..18c2082aa 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs
@@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
this.m_signatureScheme = signatureScheme;
}
- public override TlsStreamVerifier GetStreamVerifier(DigitallySigned digitallySigned)
+ public override bool VerifyRawSignature(DigitallySigned digitallySigned, byte[] hash)
{
SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm;
if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme)
@@ -31,10 +31,11 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(m_signatureScheme);
IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm);
- PssSigner verifier = new PssSigner(new RsaEngine(), digest, digest.GetDigestSize());
+ PssSigner verifier = PssSigner.CreateRawSigner(new RsaEngine(), digest, digest, digest.GetDigestSize(),
+ PssSigner.TrailerImplicit);
verifier.Init(false, m_publicKey);
-
- return new BcTlsStreamVerifier(verifier, digitallySigned.Signature);
+ verifier.BlockUpdate(hash, 0, hash.Length);
+ return verifier.VerifySignature(digitallySigned.Signature);
}
}
}
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs b/crypto/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs
index 158fb053e..21db0af8e 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs
@@ -16,9 +16,9 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
this.m_output = new SignerSink(signer);
}
- public Stream GetOutputStream()
+ public Stream Stream
{
- return m_output;
+ get { return m_output; }
}
public byte[] GetSignature()
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs b/crypto/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs
index 0848a30dd..edf13e6ec 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs
@@ -18,9 +18,9 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
this.m_signature = signature;
}
- public Stream GetOutputStream()
+ public Stream Stream
{
- return m_output;
+ get { return m_output; }
}
public bool IsVerified()
diff --git a/crypto/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs b/crypto/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs
index 4d9506857..4093fc52f 100644
--- a/crypto/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs
@@ -24,9 +24,9 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
this.m_output = new TeeOutputStream(outputSigner, outputVerifier);
}
- public Stream GetOutputStream()
+ public Stream Stream
{
- return m_output;
+ get { return m_output; }
}
public byte[] GetSignature()
|