summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-05-05 17:09:14 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-05-05 17:09:14 +0700
commit66bea84d9d009eace8144628954a962601673f69 (patch)
tree1ed888c7d164f4229375e91289d75e436dc7f674
parentChange method to property (diff)
downloadBouncyCastle.NET-ed25519-66bea84d9d009eace8144628954a962601673f69.tar.xz
Rework TLS 1.3 verifiers
-rw-r--r--crypto/BouncyCastle.Android.csproj7
-rw-r--r--crypto/BouncyCastle.csproj7
-rw-r--r--crypto/BouncyCastle.iOS.csproj7
-rw-r--r--crypto/crypto.csproj35
-rw-r--r--crypto/src/tls/CertificateVerify.cs57
-rw-r--r--crypto/src/tls/TlsClientProtocol.cs5
-rw-r--r--crypto/src/tls/TlsServerProtocol.cs6
-rw-r--r--crypto/src/tls/TlsUtilities.cs94
-rw-r--r--crypto/src/tls/crypto/Tls13Verifier.cs14
-rw-r--r--crypto/src/tls/crypto/TlsCertificate.cs2
-rw-r--r--crypto/src/tls/crypto/TlsCryptoUtilities.cs29
-rw-r--r--crypto/src/tls/crypto/impl/LegacyTls13Verifier.cs60
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTls13Verifier.cs32
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsCertificate.cs106
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs40
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs28
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs28
-rw-r--r--crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs21
18 files changed, 350 insertions, 228 deletions
diff --git a/crypto/BouncyCastle.Android.csproj b/crypto/BouncyCastle.Android.csproj
index 3d84af346..9f584cd3b 100644
--- a/crypto/BouncyCastle.Android.csproj
+++ b/crypto/BouncyCastle.Android.csproj
@@ -1611,6 +1611,7 @@
     <Compile Include="src\tls\CertificateStatusType.cs" />
     <Compile Include="src\tls\CertificateType.cs" />
     <Compile Include="src\tls\CertificateUrl.cs" />
+    <Compile Include="src\tls\CertificateVerify.cs" />
     <Compile Include="src\tls\ChangeCipherSpec.cs" />
     <Compile Include="src\tls\ChannelBinding.cs" />
     <Compile Include="src\tls\CipherSuite.cs" />
@@ -1633,6 +1634,7 @@
     <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedDecryptor.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedSigner.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcSsl3Hmac.cs" />
+    <Compile Include="src\tls\crypto\impl\bc\BcTls13Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsAeadCipherImpl.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsBlockCipherImpl.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsCertificate.cs" />
@@ -1646,13 +1648,10 @@
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDH.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDomain.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Signer.cs" />
-    <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaSigner.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaVerifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Signer.cs" />
-    <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Signer.cs" />
-    <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsHash.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsHmac.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsNonceGenerator.cs" />
@@ -1674,6 +1673,7 @@
     <Compile Include="src\tls\crypto\impl\bc\BcX25519Domain.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcX448.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcX448Domain.cs" />
+    <Compile Include="src\tls\crypto\impl\LegacyTls13Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\RsaUtilities.cs" />
     <Compile Include="src\tls\crypto\impl\TlsAeadCipher.cs" />
     <Compile Include="src\tls\crypto\impl\TlsAeadCipherImpl.cs" />
@@ -1685,6 +1685,7 @@
     <Compile Include="src\tls\crypto\impl\TlsSuiteMac.cs" />
     <Compile Include="src\tls\crypto\Srp6Group.cs" />
     <Compile Include="src\tls\crypto\Srp6StandardGroups.cs" />
+    <Compile Include="src\tls\crypto\Tls13Verifier.cs" />
     <Compile Include="src\tls\crypto\TlsAgreement.cs" />
     <Compile Include="src\tls\crypto\TlsCertificate.cs" />
     <Compile Include="src\tls\crypto\TlsCertificateRole.cs" />
diff --git a/crypto/BouncyCastle.csproj b/crypto/BouncyCastle.csproj
index 84d7bf6fc..82ea19337 100644
--- a/crypto/BouncyCastle.csproj
+++ b/crypto/BouncyCastle.csproj
@@ -1605,6 +1605,7 @@
     <Compile Include="src\tls\CertificateStatusType.cs" />
     <Compile Include="src\tls\CertificateType.cs" />
     <Compile Include="src\tls\CertificateUrl.cs" />
+    <Compile Include="src\tls\CertificateVerify.cs" />
     <Compile Include="src\tls\ChangeCipherSpec.cs" />
     <Compile Include="src\tls\ChannelBinding.cs" />
     <Compile Include="src\tls\CipherSuite.cs" />
@@ -1627,6 +1628,7 @@
     <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedDecryptor.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedSigner.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcSsl3Hmac.cs" />
+    <Compile Include="src\tls\crypto\impl\bc\BcTls13Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsAeadCipherImpl.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsBlockCipherImpl.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsCertificate.cs" />
@@ -1640,13 +1642,10 @@
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDH.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDomain.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Signer.cs" />
-    <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaSigner.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaVerifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Signer.cs" />
-    <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Signer.cs" />
-    <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsHash.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsHmac.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsNonceGenerator.cs" />
@@ -1668,6 +1667,7 @@
     <Compile Include="src\tls\crypto\impl\bc\BcX25519Domain.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcX448.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcX448Domain.cs" />
+    <Compile Include="src\tls\crypto\impl\LegacyTls13Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\RsaUtilities.cs" />
     <Compile Include="src\tls\crypto\impl\TlsAeadCipher.cs" />
     <Compile Include="src\tls\crypto\impl\TlsAeadCipherImpl.cs" />
@@ -1679,6 +1679,7 @@
     <Compile Include="src\tls\crypto\impl\TlsSuiteMac.cs" />
     <Compile Include="src\tls\crypto\Srp6Group.cs" />
     <Compile Include="src\tls\crypto\Srp6StandardGroups.cs" />
+    <Compile Include="src\tls\crypto\Tls13Verifier.cs" />
     <Compile Include="src\tls\crypto\TlsAgreement.cs" />
     <Compile Include="src\tls\crypto\TlsCertificate.cs" />
     <Compile Include="src\tls\crypto\TlsCertificateRole.cs" />
diff --git a/crypto/BouncyCastle.iOS.csproj b/crypto/BouncyCastle.iOS.csproj
index d76444e71..31ac62f93 100644
--- a/crypto/BouncyCastle.iOS.csproj
+++ b/crypto/BouncyCastle.iOS.csproj
@@ -1606,6 +1606,7 @@
     <Compile Include="src\tls\CertificateStatusType.cs" />
     <Compile Include="src\tls\CertificateType.cs" />
     <Compile Include="src\tls\CertificateUrl.cs" />
+    <Compile Include="src\tls\CertificateVerify.cs" />
     <Compile Include="src\tls\ChangeCipherSpec.cs" />
     <Compile Include="src\tls\ChannelBinding.cs" />
     <Compile Include="src\tls\CipherSuite.cs" />
@@ -1628,6 +1629,7 @@
     <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedDecryptor.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedSigner.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcSsl3Hmac.cs" />
+    <Compile Include="src\tls\crypto\impl\bc\BcTls13Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsAeadCipherImpl.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsBlockCipherImpl.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsCertificate.cs" />
@@ -1641,13 +1643,10 @@
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDH.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDomain.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Signer.cs" />
-    <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaSigner.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaVerifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Signer.cs" />
-    <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Signer.cs" />
-    <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsHash.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsHmac.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcTlsNonceGenerator.cs" />
@@ -1669,6 +1668,7 @@
     <Compile Include="src\tls\crypto\impl\bc\BcX25519Domain.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcX448.cs" />
     <Compile Include="src\tls\crypto\impl\bc\BcX448Domain.cs" />
+    <Compile Include="src\tls\crypto\impl\LegacyTls13Verifier.cs" />
     <Compile Include="src\tls\crypto\impl\RsaUtilities.cs" />
     <Compile Include="src\tls\crypto\impl\TlsAeadCipher.cs" />
     <Compile Include="src\tls\crypto\impl\TlsAeadCipherImpl.cs" />
@@ -1680,6 +1680,7 @@
     <Compile Include="src\tls\crypto\impl\TlsSuiteMac.cs" />
     <Compile Include="src\tls\crypto\Srp6Group.cs" />
     <Compile Include="src\tls\crypto\Srp6StandardGroups.cs" />
+    <Compile Include="src\tls\crypto\Tls13Verifier.cs" />
     <Compile Include="src\tls\crypto\TlsAgreement.cs" />
     <Compile Include="src\tls\crypto\TlsCertificate.cs" />
     <Compile Include="src\tls\crypto\TlsCertificateRole.cs" />
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj
index 092331032..1529174f1 100644
--- a/crypto/crypto.csproj
+++ b/crypto/crypto.csproj
@@ -7914,6 +7914,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\tls\CertificateVerify.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\tls\ChangeCipherSpec.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -8024,6 +8029,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\tls\crypto\impl\bc\BcTls13Verifier.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\tls\crypto\impl\bc\BcTlsAeadCipherImpl.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -8089,11 +8099,6 @@
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "src\tls\crypto\impl\bc\BcTlsECDsa13Verifier.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-                <File
                     RelPath = "src\tls\crypto\impl\bc\BcTlsECDsaSigner.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -8109,21 +8114,11 @@
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "src\tls\crypto\impl\bc\BcTlsEd25519Verifier.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-                <File
                     RelPath = "src\tls\crypto\impl\bc\BcTlsEd448Signer.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "src\tls\crypto\impl\bc\BcTlsEd448Verifier.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-                <File
                     RelPath = "src\tls\crypto\impl\bc\BcTlsHash.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -8229,6 +8224,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\tls\crypto\impl\LegacyTls13Verifier.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\tls\crypto\impl\RsaUtilities.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -8284,6 +8284,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\tls\crypto\Tls13Verifier.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\tls\crypto\TlsAgreement.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
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/TlsClientProtocol.cs b/crypto/src/tls/TlsClientProtocol.cs
index cb59289ae..89e7c4ba9 100644
--- a/crypto/src/tls/TlsClientProtocol.cs
+++ b/crypto/src/tls/TlsClientProtocol.cs
@@ -1467,12 +1467,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..523fc0030 100644
--- a/crypto/src/tls/TlsServerProtocol.cs
+++ b/crypto/src/tls/TlsServerProtocol.cs
@@ -1281,13 +1281,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 13155d26e..0bee76c0a 100644
--- a/crypto/src/tls/TlsUtilities.cs
+++ b/crypto/src/tls/TlsUtilities.cs
@@ -2282,62 +2282,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);
+            IList supportedAlgorithms = securityParameters.ServerSigAlgs;
+            TlsCertificate certificate = securityParameters.PeerCertificate.GetCertificateAt(0);
 
-                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);
-            }
-
-            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)
             {
@@ -2354,32 +2346,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.Stream;
-                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;
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/TlsCryptoUtilities.cs b/crypto/src/tls/crypto/TlsCryptoUtilities.cs
index 757eda1be..4ce48f738 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)
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/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/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/test/src/tls/crypto/test/BcTlsCryptoTest.cs b/crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs
index 494175261..9e2679fbb 100644
--- a/crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs
+++ b/crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs
@@ -752,25 +752,12 @@ namespace Org.BouncyCastle.Tls.Crypto.Tests
                 signature = credentialedSigner.GenerateRawSignature(hash);
             }
 
-            DigitallySigned digitallySigned = new DigitallySigned(
-                SignatureScheme.GetSignatureAndHashAlgorithm(signatureScheme), signature);
-
             TlsCertificate tlsCertificate = credentialedSigner.Certificate.GetCertificateAt(0);
-            TlsVerifier tlsVerifier = tlsCertificate.CreateVerifier(signatureScheme);
+            Tls13Verifier tls13Verifier = tlsCertificate.CreateVerifier(signatureScheme);
 
-            bool verified;
-            TlsStreamVerifier tlsStreamVerifier = tlsVerifier.GetStreamVerifier(digitallySigned);
-            if (null != tlsStreamVerifier)
-            {
-                Stream output = tlsStreamVerifier.Stream;
-                output.Write(message, 0, message.Length);
-                verified = tlsStreamVerifier.IsVerified();
-            }
-            else
-            {
-                byte[] hash = ImplPrehash(signatureScheme, message);
-                verified = tlsVerifier.VerifyRawSignature(digitallySigned, hash);
-            }
+            Stream output13 = tls13Verifier.Stream;
+            output13.Write(message, 0, message.Length);
+            bool verified = tls13Verifier.VerifySignature(signature);
 
             Assert.IsTrue(verified);
         }