mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-02 11:37:36 +03:00
For tests that are interested in testing the difference between TLS in FIPS 140-3 required mode or otherwise two new helpers are introduced, runWithFIPSEnabled and runWithFIPSDisabled. They take care of forcing the correct TLS FIPS 140-3 state regardless of the overal GODEBUG=fips state, and restoring it afterwards. For the tests that use features or test data not appropriate for TLS in FIPS 140-3 required mode we add skips. For some tests we can make them appropriate for both TLS FIPS 140-3 required or not by tweaking some parameters that weren't important to the subject under test, but would otherwise preclude TLS FIPS 140-3 required mode (e.g. because they used TLS 1.0 when the test could use TLS 1.2 instead). For others, switching test certificates to a RSA 2048 hierarchy is sufficient. We avoid regenerating the existing RSA 1024 certs as 2048 since it would invalidate recorded static flow data. Tests that rely on static message flows (primarily the client and server handshake) tests are skipped due to FIPS mode being non-deterministic and inappropriate for this style of testing. Change-Id: I311f3828dac890bb3ff8ebda6ed73d50f0797110 Reviewed-on: https://go-review.googlesource.com/c/go/+/629736 Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Filippo Valsorda <filippo@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
174 lines
7.1 KiB
Go
174 lines
7.1 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/tls/internal/fips140tls"
|
|
"testing"
|
|
)
|
|
|
|
func TestSignatureSelection(t *testing.T) {
|
|
rsaCert := &Certificate{
|
|
Certificate: [][]byte{testRSACertificate},
|
|
PrivateKey: testRSAPrivateKey,
|
|
}
|
|
pkcs1Cert := &Certificate{
|
|
Certificate: [][]byte{testRSACertificate},
|
|
PrivateKey: testRSAPrivateKey,
|
|
SupportedSignatureAlgorithms: []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256},
|
|
}
|
|
ecdsaCert := &Certificate{
|
|
Certificate: [][]byte{testP256Certificate},
|
|
PrivateKey: testP256PrivateKey,
|
|
}
|
|
ed25519Cert := &Certificate{
|
|
Certificate: [][]byte{testEd25519Certificate},
|
|
PrivateKey: testEd25519PrivateKey,
|
|
}
|
|
|
|
tests := []struct {
|
|
cert *Certificate
|
|
peerSigAlgs []SignatureScheme
|
|
tlsVersion uint16
|
|
|
|
expectedSigAlg SignatureScheme
|
|
expectedSigType uint8
|
|
expectedHash crypto.Hash
|
|
}{
|
|
{rsaCert, []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256}, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1},
|
|
{rsaCert, []SignatureScheme{PKCS1WithSHA512, PKCS1WithSHA1}, VersionTLS12, PKCS1WithSHA512, signaturePKCS1v15, crypto.SHA512},
|
|
{rsaCert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS12, PSSWithSHA256, signatureRSAPSS, crypto.SHA256},
|
|
{pkcs1Cert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS12, PKCS1WithSHA256, signaturePKCS1v15, crypto.SHA256},
|
|
{rsaCert, []SignatureScheme{PSSWithSHA384, PKCS1WithSHA1}, VersionTLS13, PSSWithSHA384, signatureRSAPSS, crypto.SHA384},
|
|
{ecdsaCert, []SignatureScheme{ECDSAWithSHA1}, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1},
|
|
{ecdsaCert, []SignatureScheme{ECDSAWithP256AndSHA256}, VersionTLS12, ECDSAWithP256AndSHA256, signatureECDSA, crypto.SHA256},
|
|
{ecdsaCert, []SignatureScheme{ECDSAWithP256AndSHA256}, VersionTLS13, ECDSAWithP256AndSHA256, signatureECDSA, crypto.SHA256},
|
|
{ed25519Cert, []SignatureScheme{Ed25519}, VersionTLS12, Ed25519, signatureEd25519, directSigning},
|
|
{ed25519Cert, []SignatureScheme{Ed25519}, VersionTLS13, Ed25519, signatureEd25519, directSigning},
|
|
|
|
// TLS 1.2 without signature_algorithms extension
|
|
{rsaCert, nil, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1},
|
|
{ecdsaCert, nil, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1},
|
|
|
|
// TLS 1.2 does not restrict the ECDSA curve (our ecdsaCert is P-256)
|
|
{ecdsaCert, []SignatureScheme{ECDSAWithP384AndSHA384}, VersionTLS12, ECDSAWithP384AndSHA384, signatureECDSA, crypto.SHA384},
|
|
}
|
|
|
|
for testNo, test := range tests {
|
|
if fips140tls.Required() && (test.expectedHash == crypto.SHA1 || test.expectedSigAlg == Ed25519) {
|
|
t.Logf("skipping test[%d] - not compatible with TLS FIPS mode", testNo)
|
|
continue
|
|
}
|
|
|
|
sigAlg, err := selectSignatureScheme(test.tlsVersion, test.cert, test.peerSigAlgs)
|
|
if err != nil {
|
|
t.Errorf("test[%d]: unexpected selectSignatureScheme error: %v", testNo, err)
|
|
}
|
|
if test.expectedSigAlg != sigAlg {
|
|
t.Errorf("test[%d]: expected signature scheme %v, got %v", testNo, test.expectedSigAlg, sigAlg)
|
|
}
|
|
sigType, hashFunc, err := typeAndHashFromSignatureScheme(sigAlg)
|
|
if err != nil {
|
|
t.Errorf("test[%d]: unexpected typeAndHashFromSignatureScheme error: %v", testNo, err)
|
|
}
|
|
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)
|
|
}
|
|
}
|
|
|
|
brokenCert := &Certificate{
|
|
Certificate: [][]byte{testRSACertificate},
|
|
PrivateKey: testRSAPrivateKey,
|
|
SupportedSignatureAlgorithms: []SignatureScheme{Ed25519},
|
|
}
|
|
|
|
badTests := []struct {
|
|
cert *Certificate
|
|
peerSigAlgs []SignatureScheme
|
|
tlsVersion uint16
|
|
}{
|
|
{rsaCert, []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithSHA1}, VersionTLS12},
|
|
{ecdsaCert, []SignatureScheme{PKCS1WithSHA256, PKCS1WithSHA1}, VersionTLS12},
|
|
{rsaCert, []SignatureScheme{0}, VersionTLS12},
|
|
{ed25519Cert, []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithSHA1}, VersionTLS12},
|
|
{ecdsaCert, []SignatureScheme{Ed25519}, VersionTLS12},
|
|
{brokenCert, []SignatureScheme{Ed25519}, VersionTLS12},
|
|
{brokenCert, []SignatureScheme{PKCS1WithSHA256}, VersionTLS12},
|
|
// RFC 5246, Section 7.4.1.4.1, says to only consider {sha1,ecdsa} as
|
|
// default when the extension is missing, and RFC 8422 does not update
|
|
// it. Anyway, if a stack supports Ed25519 it better support sigalgs.
|
|
{ed25519Cert, nil, VersionTLS12},
|
|
// TLS 1.3 has no default signature_algorithms.
|
|
{rsaCert, nil, VersionTLS13},
|
|
{ecdsaCert, nil, VersionTLS13},
|
|
{ed25519Cert, nil, VersionTLS13},
|
|
// Wrong curve, which TLS 1.3 checks
|
|
{ecdsaCert, []SignatureScheme{ECDSAWithP384AndSHA384}, VersionTLS13},
|
|
// TLS 1.3 does not support PKCS1v1.5 or SHA-1.
|
|
{rsaCert, []SignatureScheme{PKCS1WithSHA256}, VersionTLS13},
|
|
{pkcs1Cert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS13},
|
|
{ecdsaCert, []SignatureScheme{ECDSAWithSHA1}, VersionTLS13},
|
|
// The key can be too small for the hash.
|
|
{rsaCert, []SignatureScheme{PSSWithSHA512}, VersionTLS12},
|
|
}
|
|
|
|
for testNo, test := range badTests {
|
|
sigAlg, err := selectSignatureScheme(test.tlsVersion, test.cert, test.peerSigAlgs)
|
|
if err == nil {
|
|
t.Errorf("test[%d]: unexpected success, got %v", testNo, sigAlg)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestLegacyTypeAndHash(t *testing.T) {
|
|
sigType, hashFunc, err := legacyTypeAndHashFromPublicKey(testRSAPrivateKey.Public())
|
|
if err != nil {
|
|
t.Errorf("RSA: unexpected error: %v", err)
|
|
}
|
|
if expectedSigType := signaturePKCS1v15; expectedSigType != sigType {
|
|
t.Errorf("RSA: expected signature type %#x, got %#x", expectedSigType, sigType)
|
|
}
|
|
if expectedHashFunc := crypto.MD5SHA1; expectedHashFunc != hashFunc {
|
|
t.Errorf("RSA: expected hash %#x, got %#x", expectedHashFunc, hashFunc)
|
|
}
|
|
|
|
sigType, hashFunc, err = legacyTypeAndHashFromPublicKey(testECDSAPrivateKey.Public())
|
|
if err != nil {
|
|
t.Errorf("ECDSA: unexpected error: %v", err)
|
|
}
|
|
if expectedSigType := signatureECDSA; expectedSigType != sigType {
|
|
t.Errorf("ECDSA: expected signature type %#x, got %#x", expectedSigType, sigType)
|
|
}
|
|
if expectedHashFunc := crypto.SHA1; expectedHashFunc != hashFunc {
|
|
t.Errorf("ECDSA: expected hash %#x, got %#x", expectedHashFunc, hashFunc)
|
|
}
|
|
|
|
// Ed25519 is not supported by TLS 1.0 and 1.1.
|
|
_, _, err = legacyTypeAndHashFromPublicKey(testEd25519PrivateKey.Public())
|
|
if err == nil {
|
|
t.Errorf("Ed25519: unexpected success")
|
|
}
|
|
}
|
|
|
|
// TestSupportedSignatureAlgorithms checks that all supportedSignatureAlgorithms
|
|
// have valid type and hash information.
|
|
func TestSupportedSignatureAlgorithms(t *testing.T) {
|
|
for _, sigAlg := range supportedSignatureAlgorithms() {
|
|
sigType, hash, err := typeAndHashFromSignatureScheme(sigAlg)
|
|
if err != nil {
|
|
t.Errorf("%v: unexpected error: %v", sigAlg, err)
|
|
}
|
|
if sigType == 0 {
|
|
t.Errorf("%v: missing signature type", sigAlg)
|
|
}
|
|
if hash == 0 && sigAlg != Ed25519 {
|
|
t.Errorf("%v: missing hash", sigAlg)
|
|
}
|
|
}
|
|
}
|