1// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package qtls
6
7import (
8	"crypto"
9	"testing"
10)
11
12func TestSignatureSelection(t *testing.T) {
13	rsaCert := &Certificate{
14		Certificate: [][]byte{testRSACertificate},
15		PrivateKey:  testRSAPrivateKey,
16	}
17	pkcs1Cert := &Certificate{
18		Certificate:                  [][]byte{testRSACertificate},
19		PrivateKey:                   testRSAPrivateKey,
20		SupportedSignatureAlgorithms: []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256},
21	}
22	ecdsaCert := &Certificate{
23		Certificate: [][]byte{testP256Certificate},
24		PrivateKey:  testP256PrivateKey,
25	}
26	ed25519Cert := &Certificate{
27		Certificate: [][]byte{testEd25519Certificate},
28		PrivateKey:  testEd25519PrivateKey,
29	}
30
31	tests := []struct {
32		cert        *Certificate
33		peerSigAlgs []SignatureScheme
34		tlsVersion  uint16
35
36		expectedSigAlg  SignatureScheme
37		expectedSigType uint8
38		expectedHash    crypto.Hash
39	}{
40		{rsaCert, []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256}, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1},
41		{rsaCert, []SignatureScheme{PKCS1WithSHA512, PKCS1WithSHA1}, VersionTLS12, PKCS1WithSHA512, signaturePKCS1v15, crypto.SHA512},
42		{rsaCert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS12, PSSWithSHA256, signatureRSAPSS, crypto.SHA256},
43		{pkcs1Cert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS12, PKCS1WithSHA256, signaturePKCS1v15, crypto.SHA256},
44		{rsaCert, []SignatureScheme{PSSWithSHA384, PKCS1WithSHA1}, VersionTLS13, PSSWithSHA384, signatureRSAPSS, crypto.SHA384},
45		{ecdsaCert, []SignatureScheme{ECDSAWithSHA1}, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1},
46		{ecdsaCert, []SignatureScheme{ECDSAWithP256AndSHA256}, VersionTLS12, ECDSAWithP256AndSHA256, signatureECDSA, crypto.SHA256},
47		{ecdsaCert, []SignatureScheme{ECDSAWithP256AndSHA256}, VersionTLS13, ECDSAWithP256AndSHA256, signatureECDSA, crypto.SHA256},
48		{ed25519Cert, []SignatureScheme{Ed25519}, VersionTLS12, Ed25519, signatureEd25519, directSigning},
49		{ed25519Cert, []SignatureScheme{Ed25519}, VersionTLS13, Ed25519, signatureEd25519, directSigning},
50
51		// TLS 1.2 without signature_algorithms extension
52		{rsaCert, nil, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1},
53		{ecdsaCert, nil, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1},
54
55		// TLS 1.2 does not restrict the ECDSA curve (our ecdsaCert is P-256)
56		{ecdsaCert, []SignatureScheme{ECDSAWithP384AndSHA384}, VersionTLS12, ECDSAWithP384AndSHA384, signatureECDSA, crypto.SHA384},
57	}
58
59	for testNo, test := range tests {
60		sigAlg, err := selectSignatureScheme(test.tlsVersion, test.cert, test.peerSigAlgs)
61		if err != nil {
62			t.Errorf("test[%d]: unexpected selectSignatureScheme error: %v", testNo, err)
63		}
64		if test.expectedSigAlg != sigAlg {
65			t.Errorf("test[%d]: expected signature scheme %v, got %v", testNo, test.expectedSigAlg, sigAlg)
66		}
67		sigType, hashFunc, err := typeAndHashFromSignatureScheme(sigAlg)
68		if err != nil {
69			t.Errorf("test[%d]: unexpected typeAndHashFromSignatureScheme error: %v", testNo, err)
70		}
71		if test.expectedSigType != sigType {
72			t.Errorf("test[%d]: expected signature algorithm %#x, got %#x", testNo, test.expectedSigType, sigType)
73		}
74		if test.expectedHash != hashFunc {
75			t.Errorf("test[%d]: expected hash function %#x, got %#x", testNo, test.expectedHash, hashFunc)
76		}
77	}
78
79	brokenCert := &Certificate{
80		Certificate:                  [][]byte{testRSACertificate},
81		PrivateKey:                   testRSAPrivateKey,
82		SupportedSignatureAlgorithms: []SignatureScheme{Ed25519},
83	}
84
85	badTests := []struct {
86		cert        *Certificate
87		peerSigAlgs []SignatureScheme
88		tlsVersion  uint16
89	}{
90		{rsaCert, []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithSHA1}, VersionTLS12},
91		{ecdsaCert, []SignatureScheme{PKCS1WithSHA256, PKCS1WithSHA1}, VersionTLS12},
92		{rsaCert, []SignatureScheme{0}, VersionTLS12},
93		{ed25519Cert, []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithSHA1}, VersionTLS12},
94		{ecdsaCert, []SignatureScheme{Ed25519}, VersionTLS12},
95		{brokenCert, []SignatureScheme{Ed25519}, VersionTLS12},
96		{brokenCert, []SignatureScheme{PKCS1WithSHA256}, VersionTLS12},
97		// RFC 5246, Section 7.4.1.4.1, says to only consider {sha1,ecdsa} as
98		// default when the extension is missing, and RFC 8422 does not update
99		// it. Anyway, if a stack supports Ed25519 it better support sigalgs.
100		{ed25519Cert, nil, VersionTLS12},
101		// TLS 1.3 has no default signature_algorithms.
102		{rsaCert, nil, VersionTLS13},
103		{ecdsaCert, nil, VersionTLS13},
104		{ed25519Cert, nil, VersionTLS13},
105		// Wrong curve, which TLS 1.3 checks
106		{ecdsaCert, []SignatureScheme{ECDSAWithP384AndSHA384}, VersionTLS13},
107		// TLS 1.3 does not support PKCS1v1.5 or SHA-1.
108		{rsaCert, []SignatureScheme{PKCS1WithSHA256}, VersionTLS13},
109		{pkcs1Cert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS13},
110		{ecdsaCert, []SignatureScheme{ECDSAWithSHA1}, VersionTLS13},
111		// The key can be too small for the hash.
112		{rsaCert, []SignatureScheme{PSSWithSHA512}, VersionTLS12},
113	}
114
115	for testNo, test := range badTests {
116		sigAlg, err := selectSignatureScheme(test.tlsVersion, test.cert, test.peerSigAlgs)
117		if err == nil {
118			t.Errorf("test[%d]: unexpected success, got %v", testNo, sigAlg)
119		}
120	}
121}
122
123func TestLegacyTypeAndHash(t *testing.T) {
124	sigType, hashFunc, err := legacyTypeAndHashFromPublicKey(testRSAPrivateKey.Public())
125	if err != nil {
126		t.Errorf("RSA: unexpected error: %v", err)
127	}
128	if expectedSigType := signaturePKCS1v15; expectedSigType != sigType {
129		t.Errorf("RSA: expected signature type %#x, got %#x", expectedSigType, sigType)
130	}
131	if expectedHashFunc := crypto.MD5SHA1; expectedHashFunc != hashFunc {
132		t.Errorf("RSA: expected hash %#x, got %#x", expectedHashFunc, hashFunc)
133	}
134
135	sigType, hashFunc, err = legacyTypeAndHashFromPublicKey(testECDSAPrivateKey.Public())
136	if err != nil {
137		t.Errorf("ECDSA: unexpected error: %v", err)
138	}
139	if expectedSigType := signatureECDSA; expectedSigType != sigType {
140		t.Errorf("ECDSA: expected signature type %#x, got %#x", expectedSigType, sigType)
141	}
142	if expectedHashFunc := crypto.SHA1; expectedHashFunc != hashFunc {
143		t.Errorf("ECDSA: expected hash %#x, got %#x", expectedHashFunc, hashFunc)
144	}
145
146	// Ed25519 is not supported by TLS 1.0 and 1.1.
147	_, _, err = legacyTypeAndHashFromPublicKey(testEd25519PrivateKey.Public())
148	if err == nil {
149		t.Errorf("Ed25519: unexpected success")
150	}
151}
152
153// TestSupportedSignatureAlgorithms checks that all supportedSignatureAlgorithms
154// have valid type and hash information.
155func TestSupportedSignatureAlgorithms(t *testing.T) {
156	for _, sigAlg := range supportedSignatureAlgorithms {
157		sigType, hash, err := typeAndHashFromSignatureScheme(sigAlg)
158		if err != nil {
159			t.Errorf("%v: unexpected error: %v", sigAlg, err)
160		}
161		if sigType == 0 {
162			t.Errorf("%v: missing signature type", sigAlg)
163		}
164		if hash == 0 && sigAlg != Ed25519 {
165			t.Errorf("%v: missing hash", sigAlg)
166		}
167	}
168}
169