// Check that all crypto packages compile (and test correctly, in longmode) with fips.
if fipsSupported() {
- /* TODO(cpu): Restore in #629736
// Test standard crypto packages with fips140=on.
t.registerTest("GODEBUG=fips140=on go test crypto/...", &goTest{
variant: "gofips140",
env: []string{"GODEBUG=fips140=on"},
- skip: "TestHandshake|TestServerResumption|TestClientAuth|TestRenegotiate", // TODO(cpu): remove in #629736
pkg: "crypto/...",
- })*/
+ })
// Test that earlier FIPS snapshots build.
// In long mode, test that they work too.
import (
"crypto"
+ "crypto/tls/internal/fips140tls"
"testing"
)
}
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 testenv.Builder() != "" && runtime.GOOS == "windows" {
t.Skip("#66913: windows network connections are flakey on builders")
}
+ skipFIPS(t)
// In order to make Go test caching work as expected, we stat the
// bogo_config.json file, so that the Go testing hooks know that it is
}
func TestDynamicRecordSizingWithStreamCipher(t *testing.T) {
+ skipFIPS(t) // No RC4 in FIPS mode.
+
config := testConfig.Clone()
config.MaxVersion = VersionTLS12
config.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA}
}
func TestDynamicRecordSizingWithCBC(t *testing.T) {
+ skipFIPS(t) // No CBC cipher suites in defaultCipherSuitesFIPS.
+
config := testConfig.Clone()
config.MaxVersion = VersionTLS12
config.CipherSuites = []uint16{TLS_RSA_WITH_AES_256_CBC_SHA}
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
- "crypto/tls/internal/fips140tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
})
}
- test(t, "VersionTLS10", VersionTLS10, "")
- test(t, "VersionTLS11", VersionTLS11, "")
- test(t, "VersionTLS12", VersionTLS12, "")
- test(t, "VersionTLS13", VersionTLS13, "")
+ runWithFIPSDisabled(t, func(t *testing.T) {
+ test(t, "VersionTLS10", VersionTLS10, "")
+ test(t, "VersionTLS11", VersionTLS11, "")
+ test(t, "VersionTLS12", VersionTLS12, "")
+ test(t, "VersionTLS13", VersionTLS13, "")
+ })
- t.Run("fips140tls", func(t *testing.T) {
- fips140tls.Force()
- defer fips140tls.TestingOnlyAbandon()
+ runWithFIPSEnabled(t, func(t *testing.T) {
test(t, "VersionTLS10", VersionTLS10, "supported versions")
test(t, "VersionTLS11", VersionTLS11, "supported versions")
test(t, "VersionTLS12", VersionTLS12, "")
clientHello.supportedVersions = []uint16{VersionTLS13}
}
- testClientHello(t, serverConfig, clientHello)
- t.Run("fips140tls", func(t *testing.T) {
- fips140tls.Force()
- defer fips140tls.TestingOnlyAbandon()
+ runWithFIPSDisabled(t, func(t *testing.T) {
+ testClientHello(t, serverConfig, clientHello)
+ })
+
+ runWithFIPSEnabled(t, func(t *testing.T) {
msg := ""
if !isFIPSCipherSuite(id) {
msg = "no cipher suite supported by both client and server"
// x25519Kyber768Draft00 is not supported standalone.
clientConfig.CurvePreferences = append(clientConfig.CurvePreferences, X25519)
}
- if _, _, err := testHandshake(t, clientConfig, serverConfig); err != nil {
- t.Fatalf("got error: %v, expected success", err)
- }
- // With fips140tls forced, bad curves should be rejected.
- t.Run("fips140tls", func(t *testing.T) {
- fips140tls.Force()
- defer fips140tls.TestingOnlyAbandon()
+ runWithFIPSDisabled(t, func(t *testing.T) {
+ if _, _, err := testHandshake(t, clientConfig, serverConfig); err != nil {
+ t.Fatalf("got error: %v, expected success", err)
+ }
+ })
+
+ // With fipstls forced, bad curves should be rejected.
+ runWithFIPSEnabled(t, func(t *testing.T) {
_, _, err := testHandshake(t, clientConfig, serverConfig)
if err != nil && isFIPSCurve(curveid) {
t.Fatalf("got error: %v, expected success", err)
switch sigType {
case signaturePKCS1v15, signatureRSAPSS:
serverConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
- serverConfig.Certificates[0].Certificate = [][]byte{testRSA2048Certificate}
- serverConfig.Certificates[0].PrivateKey = testRSA2048PrivateKey
+ serverConfig.Certificates[0].Certificate = [][]byte{testRSAPSS2048Certificate}
+ serverConfig.Certificates[0].PrivateKey = testRSAPSS2048PrivateKey
case signatureEd25519:
serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
serverConfig.Certificates[0].Certificate = [][]byte{testEd25519Certificate}
// 1.3, and the ECDSA ones bind to the curve used.
serverConfig.MaxVersion = VersionTLS12
- clientErr, serverErr := fipsHandshake(t, testConfig, serverConfig)
- if clientErr != nil {
- t.Fatalf("expected handshake with %#x to succeed; client error: %v; server error: %v", sigHash, clientErr, serverErr)
- }
+ runWithFIPSDisabled(t, func(t *testing.T) {
+ clientErr, serverErr := fipsHandshake(t, testConfig, serverConfig)
+ if clientErr != nil {
+ t.Fatalf("expected handshake with %#x to succeed; client error: %v; server error: %v", sigHash, clientErr, serverErr)
+ }
+ })
- // With fips140tls forced, bad curves should be rejected.
- t.Run("fips140tls", func(t *testing.T) {
- fips140tls.Force()
- defer fips140tls.TestingOnlyAbandon()
+ // With fipstls forced, bad curves should be rejected.
+ runWithFIPSEnabled(t, func(t *testing.T) {
clientErr, _ := fipsHandshake(t, testConfig, serverConfig)
if isFIPSSignatureScheme(sigHash) {
if clientErr != nil {
}
func TestFIPSClientHello(t *testing.T) {
+ runWithFIPSEnabled(t, testFIPSClientHello)
+}
+
+func testFIPSClientHello(t *testing.T) {
// Test that no matter what we put in the client config,
// the client does not offer non-FIPS configurations.
- fips140tls.Force()
- defer fips140tls.TestingOnlyAbandon()
c, s := net.Pipe()
defer c.Close()
// exhaustive test with computed answers.
r1pool := x509.NewCertPool()
r1pool.AddCert(R1.cert)
- testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
- testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
- fips140tls.Force()
- testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
- testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
- fips140tls.TestingOnlyAbandon()
+
+ runWithFIPSDisabled(t, func(t *testing.T) {
+ testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
+ testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
+ })
+
+ runWithFIPSEnabled(t, func(t *testing.T) {
+ testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
+ testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
+ })
if t.Failed() {
t.Fatal("basic test failed, skipping exhaustive test")
addRoot(r&1, R1)
addRoot(r&2, R2)
rootName = rootName[1:] // strip leading comma
- testServerCert(t, listName+"->"+rootName[1:], pool, leaf.key, list, shouldVerify)
- testClientCert(t, listName+"->"+rootName[1:]+"(client cert)", pool, leaf.key, list, shouldVerify)
- fips140tls.Force()
- testServerCert(t, listName+"->"+rootName[1:]+" (fips)", pool, leaf.key, list, shouldVerifyFIPS)
- testClientCert(t, listName+"->"+rootName[1:]+" (fips, client cert)", pool, leaf.key, list, shouldVerifyFIPS)
- fips140tls.TestingOnlyAbandon()
+
+ runWithFIPSDisabled(t, func(t *testing.T) {
+ testServerCert(t, listName+"->"+rootName[1:], pool, leaf.key, list, shouldVerify)
+ testClientCert(t, listName+"->"+rootName[1:]+"(client cert)", pool, leaf.key, list, shouldVerify)
+ })
+
+ runWithFIPSEnabled(t, func(t *testing.T) {
+ testServerCert(t, listName+"->"+rootName[1:]+" (fips)", pool, leaf.key, list, shouldVerifyFIPS)
+ testClientCert(t, listName+"->"+rootName[1:]+" (fips, client cert)", pool, leaf.key, list, shouldVerifyFIPS)
+ })
}
}
}
t.Fatal(err)
}
- fips140tls.Force()
- defer fips140tls.TestingOnlyAbandon()
-
fipsOK := mode&fipsCertFIPSOK != 0
- if fipsAllowCert(cert) != fipsOK {
- t.Errorf("fipsAllowCert(cert with %s key) = %v, want %v", desc, !fipsOK, fipsOK)
- }
+ runWithFIPSEnabled(t, func(t *testing.T) {
+ if fipsAllowCert(cert) != fipsOK {
+ t.Errorf("fipsAllowCert(cert with %s key) = %v, want %v", desc, !fipsOK, fipsOK)
+ }
+ })
return &fipsCertificate{name, org, parentOrg, der, cert, key, fipsOK}
}
// A self-signed test certificate with an RSA key of size 2048, for testing
// RSA-PSS with SHA512. SAN of example.golang.
var (
- testRSA2048Certificate []byte
- testRSA2048PrivateKey *rsa.PrivateKey
+ testRSAPSS2048Certificate []byte
+ testRSAPSS2048PrivateKey *rsa.PrivateKey
)
func init() {
m9o6fukaP7t5VyOXuV7FIO/Hdg2lqW+xU1LowZpVd6ANZ5rAZXtMhWe3+mjfFtju
TAnR
-----RAQ PREGVSVPNGR-----`)))
- testRSA2048Certificate = block.Bytes
+ testRSAPSS2048Certificate = block.Bytes
block, _ = pem.Decode(obscuretestdata.Rot13([]byte(`
-----ORTVA EFN CEVINGR XRL-----
9I4kIZF8XKkit7ekfhdmZCfpIvnJHY6JAIOufQ2+92qUkFKmm5RWXD==
-----RAQ EFN CEVINGR XRL-----`)))
var err error
- testRSA2048PrivateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
+ testRSAPSS2048PrivateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
panic(err)
}
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
+ "crypto/tls/internal/fips140tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/base64"
if testing.Short() {
t.Skip("skipping in -short mode")
}
+
+ // Note: using RSA 2048 test certificates because they are compatible with FIPS mode.
+ testCertificates := []Certificate{{Certificate: [][]byte{testRSA2048Certificate}, PrivateKey: testRSA2048PrivateKey}}
serverConfig := &Config{
MaxVersion: version,
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
- Certificates: testConfig.Certificates,
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
+ Certificates: testCertificates,
}
- issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ issuer, err := x509.ParseCertificate(testRSA2048CertificateIssuer)
if err != nil {
panic(err)
}
clientConfig := &Config{
MaxVersion: version,
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
ClientSessionCache: NewLRUClientSessionCache(32),
RootCAs: rootCAs,
ServerName: "example.golang",
// before the serverConfig is used works.
serverConfig = &Config{
MaxVersion: version,
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
- Certificates: testConfig.Certificates,
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
+ Certificates: testCertificates,
}
serverConfig.SetSessionTicketKeys([][32]byte{key2})
// In TLS 1.3, cross-cipher suite resumption is allowed as long as the KDF
// hash matches. Also, Config.CipherSuites does not apply to TLS 1.3.
if version != VersionTLS13 {
- clientConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA}
+ clientConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}
testResumeState("DifferentCipherSuite", false)
testResumeState("DifferentCipherSuiteRecovers", true)
}
// Use a different curve than the client to force a HelloRetryRequest.
CurvePreferences: []CurveID{CurveP521, CurveP384, CurveP256},
MaxVersion: version,
- Certificates: testConfig.Certificates,
+ Certificates: testCertificates,
}
testResumeState("InitialHandshake", false)
testResumeState("WithHelloRetryRequest", true)
// Reset serverConfig back.
serverConfig = &Config{
MaxVersion: version,
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
- Certificates: testConfig.Certificates,
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
+ Certificates: testCertificates,
}
}
go func() {
client := Client(c, &Config{
ServerName: "foo",
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
NextProtos: []string{"http", "something-else"},
})
errChan <- client.Handshake()
serverHello := &serverHelloMsg{
vers: VersionTLS12,
random: make([]byte, 32),
- cipherSuite: TLS_RSA_WITH_AES_128_GCM_SHA256,
+ cipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
alpnProtocol: "how-about-this",
}
serverHelloBytes := mustMarshal(t, serverHello)
s.Close()
if err := <-errChan; !strings.Contains(err.Error(), "server selected unadvertised ALPN protocol") {
- t.Fatalf("Expected error about unconfigured cipher suite but got %q", err)
+ t.Fatalf("Expected error about unconfigured ALPN protocol but got %q", err)
}
}
},
}
for _, test := range tests {
- issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ // Note: using RSA 2048 test certificates because they are compatible with FIPS mode.
+ testCertificates := []Certificate{{Certificate: [][]byte{testRSA2048Certificate}, PrivateKey: testRSA2048PrivateKey}}
+
+ issuer, err := x509.ParseCertificate(testRSA2048CertificateIssuer)
if err != nil {
panic(err)
}
serverConfig := &Config{
MaxVersion: version,
- Certificates: []Certificate{testConfig.Certificates[0]},
+ Certificates: testCertificates,
ClientCAs: rootCAs,
NextProtos: []string{"protocol1"},
}
ClientSessionCache: NewLRUClientSessionCache(32),
RootCAs: rootCAs,
ServerName: "example.golang",
- Certificates: []Certificate{testConfig.Certificates[0]},
+ Certificates: testCertificates,
NextProtos: []string{"protocol1"},
}
test.configureClient(clientConfig, &clientCalled)
}
func testVerifyPeerCertificate(t *testing.T, version uint16) {
- issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ // Note: using RSA 2048 test certificates because they are compatible with FIPS mode.
+ issuer, err := x509.ParseCertificate(testRSA2048CertificateIssuer)
if err != nil {
panic(err)
}
config.Time = now
config.MaxVersion = version
config.Certificates = make([]Certificate, 1)
- config.Certificates[0].Certificate = [][]byte{testRSACertificate}
- config.Certificates[0].PrivateKey = testRSAPrivateKey
+ config.Certificates[0].Certificate = [][]byte{testRSA2048Certificate}
+ config.Certificates[0].PrivateKey = testRSA2048PrivateKey
config.Certificates[0].SignedCertificateTimestamps = [][]byte{[]byte("dummy sct 1"), []byte("dummy sct 2")}
config.Certificates[0].OCSPStaple = []byte("dummy ocsp")
test.configureServer(config, &serverCalled)
}()
config := testConfig.Clone()
+ config.Certificates = []Certificate{{Certificate: [][]byte{testRSA2048Certificate}, PrivateKey: testRSA2048PrivateKey}}
config.ServerName = "example.golang"
config.RootCAs = rootCAs
config.Time = now
panic("empty AcceptableCAs")
}
cert := &Certificate{
- Certificate: [][]byte{testRSACertificate},
- PrivateKey: testRSAPrivateKey,
+ Certificate: [][]byte{testRSA2048Certificate},
+ PrivateKey: testRSA2048PrivateKey,
}
return cert, nil
}
}
func testGetClientCertificate(t *testing.T, version uint16) {
- issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ // Note: using RSA 2048 test certificates because they are compatible with FIPS mode.
+ issuer, err := x509.ParseCertificate(testRSA2048CertificateIssuer)
if err != nil {
panic(err)
}
for i, test := range getClientCertificateTests {
serverConfig := testConfig.Clone()
+ serverConfig.Certificates = []Certificate{{Certificate: [][]byte{testRSA2048Certificate}, PrivateKey: testRSA2048PrivateKey}}
serverConfig.ClientAuth = VerifyClientCertIfGiven
serverConfig.RootCAs = x509.NewCertPool()
serverConfig.RootCAs.AddCert(issuer)
serverConfig.MaxVersion = version
clientConfig := testConfig.Clone()
+ clientConfig.Certificates = []Certificate{{Certificate: [][]byte{testRSA2048Certificate}, PrivateKey: testRSA2048PrivateKey}}
clientConfig.MaxVersion = version
test.setup(clientConfig, serverConfig)
+ // TLS 1.1 isn't available for FIPS required
+ if fips140tls.Required() && clientConfig.MaxVersion == VersionTLS11 {
+ t.Logf("skipping test %d for FIPS mode", i)
+ continue
+ }
+
type serverResult struct {
cs ConnectionState
err error
if err := testDowngradeCanary(t, VersionTLS12, VersionTLS12); err != nil {
t.Errorf("client didn't ignore expected TLS 1.2 canary")
}
- if err := testDowngradeCanary(t, VersionTLS11, VersionTLS11); err != nil {
- t.Errorf("client unexpectedly reacted to a canary in TLS 1.1")
- }
- if err := testDowngradeCanary(t, VersionTLS10, VersionTLS10); err != nil {
- t.Errorf("client unexpectedly reacted to a canary in TLS 1.0")
+ if !fips140tls.Required() {
+ if err := testDowngradeCanary(t, VersionTLS11, VersionTLS11); err != nil {
+ t.Errorf("client unexpectedly reacted to a canary in TLS 1.1")
+ }
+ if err := testDowngradeCanary(t, VersionTLS10, VersionTLS10); err != nil {
+ t.Errorf("client unexpectedly reacted to a canary in TLS 1.0")
+ }
+ } else {
+ t.Logf("skiping TLS 1.1 and TLS 1.0 downgrade canary checks in FIPS mode")
}
}
}
func testResumptionKeepsOCSPAndSCT(t *testing.T, ver uint16) {
- issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ // Note: using RSA 2048 test certificates because they are compatible with FIPS mode.
+ issuer, err := x509.ParseCertificate(testRSA2048CertificateIssuer)
if err != nil {
t.Fatalf("failed to parse test issuer")
}
RootCAs: roots,
}
serverConfig := testConfig.Clone()
+ serverConfig.Certificates = []Certificate{{Certificate: [][]byte{testRSA2048Certificate}, PrivateKey: testRSA2048PrivateKey}}
serverConfig.MaxVersion = ver
serverConfig.Certificates[0].OCSPStaple = []byte{1, 2, 3}
serverConfig.Certificates[0].SignedCertificateTimestamps = [][]byte{{4, 5, 6}}
serverConfig := &Config{
Certificates: testConfig.Certificates,
GetConfigForClient: func(chi *ClientHelloInfo) (*Config, error) {
- if len(chi.CipherSuites) != len(defaultCipherSuitesTLS13NoAES) {
+ expectedCiphersuites := defaultCipherSuitesTLS13NoAES
+ if fips140tls.Required() {
+ expectedCiphersuites = defaultCipherSuitesTLS13FIPS
+ }
+ if len(chi.CipherSuites) != len(expectedCiphersuites) {
t.Errorf("only TLS 1.3 suites should be advertised, got=%x", chi.CipherSuites)
} else {
- for i := range defaultCipherSuitesTLS13NoAES {
- if want, got := defaultCipherSuitesTLS13NoAES[i], chi.CipherSuites[i]; want != got {
+ for i := range expectedCiphersuites {
+ if want, got := expectedCiphersuites[i], chi.CipherSuites[i]; want != got {
t.Errorf("cipher at index %d does not match, want=%x, got=%x", i, want, got)
}
}
"crypto/ecdh"
"crypto/elliptic"
"crypto/rand"
+ "crypto/tls/internal/fips140tls"
"crypto/x509"
"encoding/pem"
"errors"
func TestNoSuiteOverlap(t *testing.T) {
clientHello := &clientHelloMsg{
- vers: VersionTLS10,
+ vers: VersionTLS12,
random: make([]byte, 32),
cipherSuites: []uint16{0xff00},
compressionMethods: []uint8{compressionNone},
func TestNoCompressionOverlap(t *testing.T) {
clientHello := &clientHelloMsg{
- vers: VersionTLS10,
+ vers: VersionTLS12,
random: make([]byte, 32),
- cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ cipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
compressionMethods: []uint8{0xff},
}
testClientHelloFailure(t, testConfig, clientHello, "client does not support uncompressed connections")
func TestNoRC4ByDefault(t *testing.T) {
clientHello := &clientHelloMsg{
- vers: VersionTLS10,
+ vers: VersionTLS12,
random: make([]byte, 32),
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
compressionMethods: []uint8{compressionNone},
// Test that, even when both sides support an ECDSA cipher suite, it
// won't be selected if the server's private key doesn't support it.
clientHello := &clientHelloMsg{
- vers: VersionTLS10,
+ vers: VersionTLS12,
random: make([]byte, 32),
- cipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
+ cipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
compressionMethods: []uint8{compressionNone},
supportedCurves: []CurveID{CurveP256},
supportedPoints: []uint8{pointFormatUncompressed},
// Test that, even when both sides support an RSA cipher suite, it
// won't be selected if the server's private key doesn't support it.
clientHello := &clientHelloMsg{
- vers: VersionTLS10,
+ vers: VersionTLS12,
random: make([]byte, 32),
- cipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
+ cipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
compressionMethods: []uint8{compressionNone},
supportedCurves: []CurveID{CurveP256},
supportedPoints: []uint8{pointFormatUncompressed},
}
func TestRenegotiationExtension(t *testing.T) {
+ skipFIPS(t) // #70505
+
clientHello := &clientHelloMsg{
vers: VersionTLS12,
compressionMethods: []uint8{compressionNone},
}
func TestTLS12OnlyCipherSuites(t *testing.T) {
+ skipFIPS(t) // No TLS 1.1 in FIPS mode.
+
// Test that a Server doesn't select a TLS 1.2-only cipher suite when
// the client negotiates TLS 1.1.
clientHello := &clientHelloMsg{
supportedPoints []uint8
wantSupportedPoints bool
}{
- {"ECC", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{pointFormatUncompressed}, true},
- {"ECC without ec_point_format", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, nil, false},
- {"ECC with extra values", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{13, 37, pointFormatUncompressed, 42}, true},
+ {"ECC", []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, []CurveID{CurveP256}, []uint8{pointFormatUncompressed}, true},
+ {"ECC without ec_point_format", []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, []CurveID{CurveP256}, nil, false},
+ {"ECC with extra values", []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, []CurveID{CurveP256}, []uint8{13, 37, pointFormatUncompressed, 42}, true},
{"RSA", []uint16{TLS_RSA_WITH_AES_256_GCM_SHA384}, nil, nil, false},
{"RSA with ec_point_format", []uint16{TLS_RSA_WITH_AES_256_GCM_SHA384}, nil, []uint8{pointFormatUncompressed}, false},
}
for _, tt := range tests {
+ // The RSA subtests should be enabled for FIPS 140 required mode: #70505
+ if strings.HasPrefix(tt.name, "RSA") && fips140tls.Required() {
+ t.Logf("skipping in FIPS mode.")
+ continue
+ }
t.Run(tt.name, func(t *testing.T) {
clientHello := &clientHelloMsg{
vers: VersionTLS12,
c, s := localPipe(t)
replyChan := make(chan any)
go func() {
- cli := Client(c, testConfig)
+ clientConfig := testConfig.Clone()
+ clientConfig.Certificates = []Certificate{{Certificate: [][]byte{testRSA2048Certificate}, PrivateKey: testRSA2048PrivateKey}}
+ cli := Client(c, clientConfig)
cli.vers = clientHello.vers
if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil {
testFatal(t, err)
replyChan <- reply
}
}()
- config := testConfig.Clone()
- config.CipherSuites = clientHello.cipherSuites
- Server(s, config).Handshake()
+ serverConfig := testConfig.Clone()
+ serverConfig.Certificates = []Certificate{{Certificate: [][]byte{testRSA2048Certificate}, PrivateKey: testRSA2048PrivateKey}}
+ serverConfig.CipherSuites = clientHello.cipherSuites
+ Server(s, serverConfig).Handshake()
s.Close()
reply := <-replyChan
if err, ok := reply.(error); ok {
}
func TestCipherSuitePreference(t *testing.T) {
+ skipFIPS(t) // No RC4 or CHACHA20_POLY1305 in FIPS mode.
+
serverConfig := &Config{
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
func testCrossVersionResume(t *testing.T, version uint16) {
serverConfig := &Config{
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
Certificates: testConfig.Certificates,
}
clientConfig := &Config{
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
InsecureSkipVerify: true,
ClientSessionCache: NewLRUClientSessionCache(1),
ServerName: "servername",
// TestHandshakeServerUnsupportedKeyShare tests a client that sends a key share
// that's not in the supported groups list.
func TestHandshakeServerUnsupportedKeyShare(t *testing.T) {
- pk, _ := ecdh.X25519().GenerateKey(rand.Reader)
+ pk, _ := ecdh.P384().GenerateKey(rand.Reader)
clientHello := &clientHelloMsg{
vers: VersionTLS12,
random: make([]byte, 32),
supportedVersions: []uint16{VersionTLS13},
- cipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256},
+ cipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
compressionMethods: []uint8{compressionNone},
- keyShares: []keyShare{{group: X25519, data: pk.PublicKey().Bytes()}},
+ keyShares: []keyShare{{group: CurveP384, data: pk.PublicKey().Bytes()}},
supportedCurves: []CurveID{CurveP256},
}
testClientHelloFailure(t, testConfig, clientHello, "client sent key share for group it does not support")
testVersions := []uint16{VersionTLS12, VersionTLS13}
for _, vers := range testVersions {
t.Run(fmt.Sprintf("TLS version %04x", vers), func(t *testing.T) {
- pk, _ := ecdh.X25519().GenerateKey(rand.Reader)
+ pk, _ := ecdh.P256().GenerateKey(rand.Reader)
clientHello := &clientHelloMsg{
vers: vers,
random: make([]byte, 32),
- cipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256},
+ cipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
compressionMethods: []uint8{compressionNone},
serverName: "test",
- keyShares: []keyShare{{group: X25519, data: pk.PublicKey().Bytes()}},
- supportedCurves: []CurveID{X25519},
- supportedSignatureAlgorithms: []SignatureScheme{Ed25519},
+ keyShares: []keyShare{{group: CurveP256, data: pk.PublicKey().Bytes()}},
+ supportedCurves: []CurveID{CurveP256},
+ supportedSignatureAlgorithms: []SignatureScheme{ECDSAWithP256AndSHA256},
}
// the clientHelloMsg initialized just above is serialized with
}
clientHello := &clientHelloMsg{
- vers: VersionTLS10,
+ vers: VersionTLS12,
random: make([]byte, 32),
- cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ cipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
compressionMethods: []uint8{compressionNone},
serverName: "test",
}
serverConfig.Certificates = nil
clientHello := &clientHelloMsg{
- vers: VersionTLS10,
+ vers: VersionTLS12,
random: make([]byte, 32),
- cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ cipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
compressionMethods: []uint8{compressionNone},
}
testClientHelloFailure(t, serverConfig, clientHello, errMsg)
serverConfig.GetCertificate = nil
clientHello = &clientHelloMsg{
- vers: VersionTLS10,
+ vers: VersionTLS12,
random: make([]byte, 32),
- cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ cipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
compressionMethods: []uint8{compressionNone},
}
testClientHelloFailure(t, serverConfig, clientHello, "no certificates")
const expectedServerName = "test.testing"
clientHello := &clientHelloMsg{
- vers: VersionTLS10,
+ vers: VersionTLS12,
random: make([]byte, 32),
- cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ cipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
compressionMethods: []uint8{compressionNone},
serverName: expectedServerName,
}
func TestMultipleCertificates(t *testing.T) {
clientConfig := testConfig.Clone()
- clientConfig.CipherSuites = []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}
+ clientConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
clientConfig.MaxVersion = VersionTLS12
serverConfig := testConfig.Clone()
}
func TestAESCipherReordering(t *testing.T) {
+ skipFIPS(t) // No CHACHA20_POLY1305 for FIPS.
+
currentAESSupport := hasAESGCMHardwareSupport
defer func() { hasAESGCMHardwareSupport = currentAESSupport }()
}
func TestAESCipherReorderingTLS13(t *testing.T) {
+ skipFIPS(t) // No CHACHA20_POLY1305 for FIPS.
+
currentAESSupport := hasAESGCMHardwareSupport
defer func() { hasAESGCMHardwareSupport = currentAESSupport }()
)
func runTestAndUpdateIfNeeded(t *testing.T, name string, run func(t *testing.T, update bool), wait bool) {
+ // FIPS mode is non-deterministic and so isn't suited for testing against static test transcripts.
+ skipFIPS(t)
+
success := t.Run(name, func(t *testing.T) {
if !*update && !wait {
t.Parallel()
var testRSACertificateIssuer = fromHex("3082021930820182a003020102020900ca5e4e811a965964300d06092a864886f70d01010b0500301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f74301e170d3136303130313030303030305a170d3235303130313030303030305a301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f7430819f300d06092a864886f70d010101050003818d0030818902818100d667b378bb22f34143b6cd2008236abefaf2852adf3ab05e01329e2c14834f5105df3f3073f99dab5442d45ee5f8f57b0111c8cb682fbb719a86944eebfffef3406206d898b8c1b1887797c9c5006547bb8f00e694b7a063f10839f269f2c34fff7a1f4b21fbcd6bfdfb13ac792d1d11f277b5c5b48600992203059f2a8f8cc50203010001a35d305b300e0603551d0f0101ff040403020204301d0603551d250416301406082b0601050507030106082b06010505070302300f0603551d130101ff040530030101ff30190603551d0e041204104813494d137e1631bba301d5acab6e7b300d06092a864886f70d01010b050003818100c1154b4bab5266221f293766ae4138899bd4c5e36b13cee670ceeaa4cbdf4f6679017e2fe649765af545749fe4249418a56bd38a04b81e261f5ce86b8d5c65413156a50d12449554748c59a30c515bc36a59d38bddf51173e899820b282e40aa78c806526fd184fb6b4cf186ec728edffa585440d2b3225325f7ab580e87dd76")
+var testRSA2048Certificate = fromHex("30820316308201fea003020102020900e8f09d3fe25beaa6300d06092a864886f70d01010b0500301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f74301e170d3136303130313030303030305a170d3338303130313030303030305a301a310b3009060355040a1302476f310b300906035504031302476f30820122300d06092a864886f70d01010105000382010f003082010a0282010100e0ac47db9ba1b7f98a996c62dc1d248d4ee570544136fe4e911e22fccc0fe2b20982f3c4cdd8f4065c5068c873ca0a768b80dc915edc66541a5f26cdea44e56e411221e2f9927bf4e009fee76dbe0e118dcc13392efd6f42d8eb2fd5bc8f63ac77800c84d3be90c20c321273254b9137ef61f825dad1ec2c5e75aa4be6d3104899bd5ac400da7ab942b4227a3870ae5bb97870aa09a1082fb8e78b944cd7fd1b0c6fb1cce03b5430b12ef9ce2d95e01821766e998df0cc99202a57cf030577bd2dc0ec85a49f203511bb6f0e9f43398ead0958f8d7534c61e81daf4501faaa68d9cbc725b58401900fa48a3e2333b15c88cf0c5cc8f33fb9464f9d5f5768b8f10203010001a35a3058300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b06010505070302300c0603551d130101ff0402300030190603551d1104123010820e6578616d706c652e676f6c616e67300d06092a864886f70d01010b050003820101009e83f835e2da08204ee6f8bdca793cf83c7aec175349c1642dfbe9f4d0dcfb1aedb4d0122e16c2ad92e63dd31cce10ca5dd04be48cded0fdc8fea49e891d9d93e778a67d54b619ac167ce7bb0f6000ca00c5677d09df3eb10080134ba32bfe4132d33954dc479cb266288d53d3f43af9c78c0ca59d396498bdc56d4966dc6b7e49081f7f2ae1d704bb9f9effed93c57d3b738da02edff3999e3f1a5dce2b093951947d233d9c6b6a12b4b1611826aa02544980089eebbcf22a1a96bd35a3ddf638578989334a93d5081fab442b4383ba6213b7cdd74110582244a2abd937828b311d8dd69178756db7874293b9810c5c2e833f91d49d283a62caaf359141997f")
+
+var testRSA2048CertificateIssuer = fromHex("308203223082020aa003020102020900ca5e4e811a965964300d06092a864886f70d01010b0500301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f74301e170d3136303130313030303030305a170d3235303130313030303030305a301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f7430820122300d06092a864886f70d01010105000382010f003082010a0282010100b308c1720c7054abe66e1be6f8a11246808215a810e8936e47601f7ec1afeb02ad69a5000959d4e08ebc4455ef90b39616f380b8ff2e76f29942d7e009cf010824fe56f69140ac39b761595255ec2aa35155ca2eea884f57b25f8a52f41f56f65b0197cb6c637f9adfa97d8ac27565449f64e67f8b918646ffd630601b0badd8d38aea421fe413ee94f10ea5874c2fd6d8c1b9febaa5ca0ce759993a232c9c48e52230bbf58777b0c30e07e9e0914133730d844b9887b950d5a17c779ac69de2d9c65d26f1ea46c7dd7ac636af6d77df7c9218f78c7b5f08b025867f343ac66cd43a657ac44bfd7e9d07e95a22ff9a0babf72dcffc66eba0a1d90731f67e3bbd0203010001a361305f300e0603551d0f0101ff040403020204301d0603551d250416301406082b0601050507030106082b06010505070302300f0603551d130101ff040530030101ff301d0603551d0e0416041460145a6ce2e8a15b1b68db9a4752ce8684d6ba2d300d06092a864886f70d01010b050003820101001d342fe0b50a25d57a8b13bc14d0abb1eea7431ee752aa423e1306654183e44e9d48bbf592cd32ce77310fdc4e8bbcd724fc43d2723f454bfe605ff90d38d8c6fe60b36c6f4d2d7e4e79bceeb2484f0565274b0d0c4a8562370677624a4c133e332a9e63d4b47544c14e4908ee8685dd0760ae6f4ab089ede2b0cdc595ecefbee7d8be80d57b2d4e4510b6ceda54d1a5980540214191d81cc89a983da43d4043f8efe97a2e231c5153bded520acce87ec8c64a3408f0eb4c742c4a877e8b5b7b7f72497734a41a95994a7a103262ea6d598d03fd5cb0579ed4702424da8893334c58215bc655d49656aedcd02d18676f45d6b9469ae04b89abe9b358391cce99")
+
+var testRSA2048PrivateKey, _ = x509.ParsePKCS1PrivateKey(fromHex("308204a40201000282010100e0ac47db9ba1b7f98a996c62dc1d248d4ee570544136fe4e911e22fccc0fe2b20982f3c4cdd8f4065c5068c873ca0a768b80dc915edc66541a5f26cdea44e56e411221e2f9927bf4e009fee76dbe0e118dcc13392efd6f42d8eb2fd5bc8f63ac77800c84d3be90c20c321273254b9137ef61f825dad1ec2c5e75aa4be6d3104899bd5ac400da7ab942b4227a3870ae5bb97870aa09a1082fb8e78b944cd7fd1b0c6fb1cce03b5430b12ef9ce2d95e01821766e998df0cc99202a57cf030577bd2dc0ec85a49f203511bb6f0e9f43398ead0958f8d7534c61e81daf4501faaa68d9cbc725b58401900fa48a3e2333b15c88cf0c5cc8f33fb9464f9d5f5768b8f10203010001028201007aac96efca229b199e1bf79a63256677e1c455792bc2a348b2e409a68ea57dda486740430d4290bb885c3f5a741eb567d4f41f7b2098a726f4df4f88cf899edc7c9b31f584dffedece15a7212642c7dbbdd8d806392a183e1fc30af36169c9bab9e528f0bdcd27ad4c8b6a97849da6452c6809de61848db80c3ba3289e785042cdfd46fbfee5f78adcba2927fcd8cbe9dcaa97190457eaa45d77adbe0db820aff0c8511d837ab5b307bad5f85afd2cc70d9659ec58045d97ced1eb7950670ac559449c0305fddefda1bac88d36629a177f65abad182c6470830b39e7f6dbdef4df813ccaef01d5a42d37213b2b9647e2ff56a63e6b6a4b6e8a1567bbfd77042102818100eb66f205e8507c78f7167dbef3ddf02fde6a67bd15152609e9296576e28c79678177145ae98e0a2fee58fdb3d626fb6beae3e0ae0b76bc47d16fcdeb16f0caca8a0902779979382609705ae84514de480c2fb2ddda3049347cc1bde9f1a359747079ef3dce020a3c186c90e63bc20b5489a40d768b1c1c35c679edc5662e18c702818100f454ffff95b126b55cb13b68a3841600fc0bc69ff4064f7ceb122495fa972fdb05ca2fa1c6e2e84432f81c96875ab12226e8ce92ba808c4f6325f27ce058791f05db96e623687d3cfc198e748a07521a8c7ee9e7e8faf95b0985be82b867a49f7d5d50fac3881d2c39dedfdbca3ebe847b859c9864cf7a543e4688f5a60118870281806cee737ac65950704daeebbb8c701c709a54d4f28baa00b33f6137a1bf0e5033d4963d2620c3e8f4eb2fe51eee2f95d3079c31e1784e96ac093fdaa33a376d3032961ebd27990fa192669abab715041385082196461c6813d0d37ac5a25afbcf452937cb7ae438c63c6b28d651bae6b1550c446aa1cefd42e9388d0df6cdc80b02818100cac172c33504923bb494fad8e5c0a9c5dd63244bfe63f238969632b82700a95cd71c2694d887d9f92656d0da75ae640a1441e392cda3f94bb3da7cb4f6335527d2639c809467946e34423cfe26c0d6786398ba20922d1b1a59f79bd5bc937d8040b75c890c13fb298548977a3c05ff71cf535c54f66b5a77684a7e4363a3cb2702818100a4d782f35d5a07f9c1f8f9c378564b220387d1e481cc856b631de7637d8bb77c851db070122050ac230dc6e45edf4523471c717c1cb86a36b2fd3358fae349d51be54d71d7dbeaa6af668323e2b51933f0b8488aa12723e0f32207068b4aa64ed54bcef4acbbbe35b92802faba7ed45ae52bef8313d9ef4393ccc5cf868ddbf8"))
+
// testRSAPSSCertificate has signatureAlgorithm rsassaPss, but subjectPublicKeyInfo
// algorithm rsaEncryption, for use with the rsa_pss_rsae_* SignatureSchemes.
// See also TestRSAPSSKeyError. testRSAPSSCertificate is self-signed.
"crypto/elliptic"
"crypto/internal/hpke"
"crypto/rand"
+ "crypto/tls/internal/fips140tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
return ln
}
+func runWithFIPSEnabled(t *testing.T, testFunc func(t *testing.T)) {
+ originalFIPS := fips140tls.Required()
+ defer func() {
+ if originalFIPS {
+ fips140tls.Force()
+ } else {
+ fips140tls.TestingOnlyAbandon()
+ }
+ }()
+
+ fips140tls.Force()
+ t.Run("fips140tls", testFunc)
+}
+
+func runWithFIPSDisabled(t *testing.T, testFunc func(t *testing.T)) {
+ originalFIPS := fips140tls.Required()
+ defer func() {
+ if originalFIPS {
+ fips140tls.Force()
+ } else {
+ fips140tls.TestingOnlyAbandon()
+ }
+ }()
+
+ fips140tls.TestingOnlyAbandon()
+ t.Run("no-fips140tls", testFunc)
+}
+
+func skipFIPS(t *testing.T) {
+ if fips140tls.Required() {
+ t.Skip("skipping test in FIPS mode")
+ }
+}
+
func TestDialTimeout(t *testing.T) {
if testing.Short() {
t.Skip("skipping in short mode")
}
func TestConnectionState(t *testing.T) {
+ skipFIPS(t) // Test certificates not FIPS compatible.
+
issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
if err != nil {
panic(err)
func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }
func TestClientHelloInfo_SupportsCertificate(t *testing.T) {
+ skipFIPS(t) // Test certificates not FIPS compatible.
+
rsaCert := &Certificate{
Certificate: [][]byte{testRSACertificate},
PrivateKey: testRSAPrivateKey,
}
func TestVerifyCertificates(t *testing.T) {
+ skipFIPS(t) // Test certificates not FIPS compatible.
+
// See https://go.dev/issue/31641.
t.Run("TLSv12", func(t *testing.T) { testVerifyCertificates(t, VersionTLS12) })
t.Run("TLSv13", func(t *testing.T) { testVerifyCertificates(t, VersionTLS13) })
}
func TestHandshakeKyber(t *testing.T) {
+ skipFIPS(t) // No Kyber768 in FIPS
+
if x25519Kyber768Draft00.String() != "X25519Kyber768Draft00" {
t.Fatalf("unexpected CurveID string: %v", x25519Kyber768Draft00.String())
}