|
|
@@ -0,0 +1,101 @@ |
|
|
|
// Copyright 2017 The Go Authors. All rights reserved. |
|
|
|
// Use of this source code is governed by a BSD-style |
|
|
|
// license that can be found in the LICENSE file. |
|
|
|
|
|
|
|
package tls |
|
|
|
|
|
|
|
import ( |
|
|
|
"crypto" |
|
|
|
"testing" |
|
|
|
) |
|
|
|
|
|
|
|
func TestSignatureSelection(t *testing.T) { |
|
|
|
rsaCert := &testRSAPrivateKey.PublicKey |
|
|
|
ecdsaCert := &testECDSAPrivateKey.PublicKey |
|
|
|
sigsPKCS1WithSHA := []SignatureScheme{PKCS1WithSHA256, PKCS1WithSHA1} |
|
|
|
sigsPSSWithSHA := []SignatureScheme{PSSWithSHA256, PSSWithSHA384} |
|
|
|
sigsECDSAWithSHA := []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithSHA1} |
|
|
|
|
|
|
|
tests := []struct { |
|
|
|
pubkey crypto.PublicKey |
|
|
|
peerSigAlgs []SignatureScheme |
|
|
|
ourSigAlgs []SignatureScheme |
|
|
|
tlsVersion uint16 |
|
|
|
|
|
|
|
expectedSigAlg SignatureScheme // or 0 if ignored |
|
|
|
expectedSigType uint8 |
|
|
|
expectedHash crypto.Hash |
|
|
|
}{ |
|
|
|
// Hash is fixed for RSA in TLS 1.1 and before. |
|
|
|
// https://tools.ietf.org/html/rfc4346#page-44 |
|
|
|
{rsaCert, nil, nil, VersionTLS11, 0, signaturePKCS1v15, crypto.MD5SHA1}, |
|
|
|
{rsaCert, nil, nil, VersionTLS10, 0, signaturePKCS1v15, crypto.MD5SHA1}, |
|
|
|
{rsaCert, nil, nil, VersionSSL30, 0, signaturePKCS1v15, crypto.MD5SHA1}, |
|
|
|
|
|
|
|
// Before TLS 1.2, there is no signature_algorithms extension |
|
|
|
// nor field in CertificateRequest and digitally-signed and thus |
|
|
|
// it should be ignored. |
|
|
|
{rsaCert, sigsPKCS1WithSHA, nil, VersionTLS11, 0, signaturePKCS1v15, crypto.MD5SHA1}, |
|
|
|
{rsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS11, 0, signaturePKCS1v15, crypto.MD5SHA1}, |
|
|
|
// Use SHA-1 for TLS 1.0 and 1.1 with ECDSA, see https://tools.ietf.org/html/rfc4492#page-20 |
|
|
|
{ecdsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS11, 0, signatureECDSA, crypto.SHA1}, |
|
|
|
{ecdsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS10, 0, signatureECDSA, crypto.SHA1}, |
|
|
|
|
|
|
|
// TLS 1.2 without signature_algorithms extension |
|
|
|
// https://tools.ietf.org/html/rfc5246#page-47 |
|
|
|
{rsaCert, nil, sigsPKCS1WithSHA, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1}, |
|
|
|
{ecdsaCert, nil, sigsPKCS1WithSHA, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1}, |
|
|
|
|
|
|
|
{rsaCert, []SignatureScheme{PKCS1WithSHA1}, sigsPKCS1WithSHA, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1}, |
|
|
|
{rsaCert, []SignatureScheme{PKCS1WithSHA256}, sigsPKCS1WithSHA, VersionTLS12, PKCS1WithSHA256, signaturePKCS1v15, crypto.SHA256}, |
|
|
|
// "sha_hash" may denote hashes other than SHA-1 |
|
|
|
// https://tools.ietf.org/html/draft-ietf-tls-rfc4492bis-17#page-17 |
|
|
|
{ecdsaCert, []SignatureScheme{ECDSAWithSHA1}, sigsECDSAWithSHA, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1}, |
|
|
|
{ecdsaCert, []SignatureScheme{ECDSAWithP256AndSHA256}, sigsECDSAWithSHA, VersionTLS12, ECDSAWithP256AndSHA256, signatureECDSA, crypto.SHA256}, |
|
|
|
|
|
|
|
// RSASSA-PSS is defined in TLS 1.3 for TLS 1.2 |
|
|
|
// https://tools.ietf.org/html/draft-ietf-tls-tls13-21#page-45 |
|
|
|
{rsaCert, []SignatureScheme{PSSWithSHA256}, sigsPSSWithSHA, VersionTLS12, PSSWithSHA256, signatureRSAPSS, crypto.SHA256}, |
|
|
|
} |
|
|
|
|
|
|
|
for testNo, test := range tests { |
|
|
|
sigAlg, sigType, hashFunc, err := pickSignatureAlgorithm(test.pubkey, test.peerSigAlgs, test.ourSigAlgs, test.tlsVersion) |
|
|
|
if err != nil { |
|
|
|
t.Errorf("test[%d]: unexpected error: %v", testNo, err) |
|
|
|
} |
|
|
|
if test.expectedSigAlg != 0 && test.expectedSigAlg != sigAlg { |
|
|
|
t.Errorf("test[%d]: expected signature scheme %#x, got %#x", testNo, test.expectedSigAlg, sigAlg) |
|
|
|
} |
|
|
|
if test.expectedSigType != sigType { |
|
|
|
t.Errorf("test[%d]: expected signature algorithm %#x, got %#x", testNo, test.expectedSigType, sigType) |
|
|
|
} |
|
|
|
if test.expectedHash != hashFunc { |
|
|
|
t.Errorf("test[%d]: expected hash function %#x, got %#x", testNo, test.expectedHash, hashFunc) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
badTests := []struct { |
|
|
|
pubkey crypto.PublicKey |
|
|
|
peerSigAlgs []SignatureScheme |
|
|
|
ourSigAlgs []SignatureScheme |
|
|
|
tlsVersion uint16 |
|
|
|
}{ |
|
|
|
{rsaCert, sigsECDSAWithSHA, sigsPKCS1WithSHA, VersionTLS12}, |
|
|
|
{ecdsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS12}, |
|
|
|
{ecdsaCert, sigsECDSAWithSHA, sigsPKCS1WithSHA, VersionTLS12}, |
|
|
|
{rsaCert, []SignatureScheme{0}, sigsPKCS1WithSHA, VersionTLS12}, |
|
|
|
|
|
|
|
// ECDSA is unspecified for SSL 3.0 in RFC 4492. |
|
|
|
// TODO a SSL 3.0 client cannot advertise signature_algorithms, |
|
|
|
// but if an application feeds an ECDSA certificate anyway, it |
|
|
|
// will be accepted rather than trigger a handshake failure. Ok? |
|
|
|
//{ecdsaCert, nil, nil, VersionSSL30}, |
|
|
|
} |
|
|
|
|
|
|
|
for testNo, test := range badTests { |
|
|
|
sigAlg, sigType, hashFunc, err := pickSignatureAlgorithm(test.pubkey, test.peerSigAlgs, test.ourSigAlgs, test.tlsVersion) |
|
|
|
if err == nil { |
|
|
|
t.Errorf("test[%d]: unexpected success, got %#x %#x %#x", testNo, sigAlg, sigType, hashFunc) |
|
|
|
} |
|
|
|
} |
|
|
|
} |