utls/auth_test.go
Filippo Valsorda 28958b0da6 crypto/tls: add support for Ed25519 certificates in TLS 1.2 and 1.3
Support for Ed25519 certificates was added in CL 175478, this wires them
up into the TLS stack according to RFC 8422 (TLS 1.2) and RFC 8446 (TLS 1.3).

RFC 8422 also specifies support for TLS 1.0 and 1.1, and I initially
implemented that, but even OpenSSL doesn't take the complexity, so I
just dropped it. It would have required keeping a buffer of the
handshake transcript in order to do the direct Ed25519 signatures. We
effectively need to support TLS 1.2 because it shares ClientHello
signature algorithms with TLS 1.3.

While at it, reordered the advertised signature algorithms in the rough
order we would want to use them, also based on what curves have fast
constant-time implementations.

Client and client auth tests changed because of the change in advertised
signature algorithms in ClientHello and CertificateRequest.

Fixes #25355

Change-Id: I9fdd839afde4fd6b13fcbc5cc7017fd8c35085ee
Reviewed-on: https://go-review.googlesource.com/c/go/+/177698
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2019-05-17 16:13:45 +00:00

113 lines
5.3 KiB
Go

// 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"
"crypto/ed25519"
"testing"
)
func TestSignatureSelection(t *testing.T) {
rsaCert := &testRSAPrivateKey.PublicKey
ecdsaCert := &testECDSAPrivateKey.PublicKey
ed25519Cert := testEd25519PrivateKey.Public().(ed25519.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 // if tlsVersion == VersionTLS12
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},
// All results are fixed for Ed25519. RFC 8422, Section 5.10.
{ed25519Cert, []SignatureScheme{Ed25519}, []SignatureScheme{ECDSAWithSHA1, Ed25519}, VersionTLS12, Ed25519, signatureEd25519, directSigning},
{ed25519Cert, nil, nil, VersionTLS12, Ed25519, signatureEd25519, directSigning},
}
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.tlsVersion == VersionTLS12 && 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},
{ed25519Cert, sigsECDSAWithSHA, sigsECDSAWithSHA, VersionTLS12},
{ed25519Cert, []SignatureScheme{Ed25519}, sigsECDSAWithSHA, VersionTLS12},
{ecdsaCert, []SignatureScheme{Ed25519}, []SignatureScheme{Ed25519}, VersionTLS12},
{ed25519Cert, nil, nil, VersionTLS11},
{ed25519Cert, nil, nil, VersionTLS10},
{ed25519Cert, nil, nil, VersionSSL30},
// 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)
}
}
}