diff --git a/auth_test.go b/auth_test.go index c23d93f..9036f4c 100644 --- a/auth_test.go +++ b/auth_test.go @@ -6,6 +6,7 @@ package tls import ( "crypto" + "crypto/tls/internal/fips140tls" "testing" ) @@ -57,6 +58,11 @@ func TestSignatureSelection(t *testing.T) { } 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) diff --git a/bogo_shim_test.go b/bogo_shim_test.go index b294608..561f0a6 100644 --- a/bogo_shim_test.go +++ b/bogo_shim_test.go @@ -406,6 +406,7 @@ func TestBogoSuite(t *testing.T) { 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 diff --git a/conn_test.go b/conn_test.go index 5e090a0..5fd48d6 100644 --- a/conn_test.go +++ b/conn_test.go @@ -230,6 +230,8 @@ func runDynamicRecordSizingTest(t *testing.T, config *Config) { } 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} @@ -237,6 +239,8 @@ func TestDynamicRecordSizingWithStreamCipher(t *testing.T) { } 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} diff --git a/fips_test.go b/fips_test.go index b28b6f4..5447aa1 100644 --- a/fips_test.go +++ b/fips_test.go @@ -9,7 +9,6 @@ import ( "crypto/elliptic" "crypto/rand" "crypto/rsa" - "crypto/tls/internal/fips140tls" "crypto/x509" "crypto/x509/pkix" "encoding/pem" @@ -73,14 +72,14 @@ func TestFIPSServerProtocolVersion(t *testing.T) { }) } - 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, "") @@ -168,10 +167,11 @@ func TestFIPSServerCipherSuites(t *testing.T) { 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" @@ -194,14 +194,15 @@ func TestFIPSServerCurves(t *testing.T) { // 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) @@ -244,8 +245,8 @@ func TestFIPSServerSignatureAndHash(t *testing.T) { 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} @@ -260,15 +261,15 @@ func TestFIPSServerSignatureAndHash(t *testing.T) { // 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 { @@ -285,10 +286,12 @@ func TestFIPSServerSignatureAndHash(t *testing.T) { } 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() @@ -423,12 +426,16 @@ func TestFIPSCertAlgs(t *testing.T) { // 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") @@ -488,12 +495,16 @@ func TestFIPSCertAlgs(t *testing.T) { 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) + }) } } } @@ -589,13 +600,12 @@ func fipsCert(t *testing.T, name string, key interface{}, parent *fipsCertificat 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} } @@ -603,8 +613,8 @@ func fipsCert(t *testing.T, name string, key interface{}, parent *fipsCertificat // 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() { @@ -628,7 +638,7 @@ aEjosRZNJv1nDEl5qG9XN3FC9zb5FrGSFmTTUvR4f4tUHr7wifNSS2dtgQ6+jU6f m9o6fukaP7t5VyOXuV7FIO/Hdg2lqW+xU1LowZpVd6ANZ5rAZXtMhWe3+mjfFtju TAnR -----RAQ PREGVSVPNGR-----`))) - testRSA2048Certificate = block.Bytes + testRSAPSS2048Certificate = block.Bytes block, _ = pem.Decode(obscuretestdata.Rot13([]byte(` -----ORTVA EFN CEVINGR XRL----- @@ -659,7 +669,7 @@ bBegiZqey6hcl9Um4OWQ3SKjISvCSR7wdrAdv0S21ivYkOCZZQ3HBQS6YY5RlYvE 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) } diff --git a/handshake_client_test.go b/handshake_client_test.go index 2aded1a..bb164bb 100644 --- a/handshake_client_test.go +++ b/handshake_client_test.go @@ -11,6 +11,7 @@ import ( "crypto/elliptic" "crypto/rand" "crypto/rsa" + "crypto/tls/internal/fips140tls" "crypto/x509" "crypto/x509/pkix" "encoding/base64" @@ -848,13 +849,16 @@ func testResumption(t *testing.T, version uint16) { 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) } @@ -864,7 +868,7 @@ func testResumption(t *testing.T, version uint16) { 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", @@ -982,8 +986,8 @@ func testResumption(t *testing.T, version uint16) { // 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}) @@ -992,7 +996,7 @@ func testResumption(t *testing.T, version uint16) { // 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) } @@ -1008,7 +1012,7 @@ func testResumption(t *testing.T, version uint16) { // 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) @@ -1016,8 +1020,8 @@ func testResumption(t *testing.T, version uint16) { // 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, } } @@ -1272,7 +1276,7 @@ func TestServerSelectingUnconfiguredApplicationProtocol(t *testing.T) { 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() @@ -1292,7 +1296,7 @@ func TestServerSelectingUnconfiguredApplicationProtocol(t *testing.T) { 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) @@ -1308,7 +1312,7 @@ func TestServerSelectingUnconfiguredApplicationProtocol(t *testing.T) { 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) } } @@ -1724,7 +1728,10 @@ func testVerifyConnection(t *testing.T, version uint16) { }, } 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) } @@ -1735,7 +1742,7 @@ func testVerifyConnection(t *testing.T, version uint16) { serverConfig := &Config{ MaxVersion: version, - Certificates: []Certificate{testConfig.Certificates[0]}, + Certificates: testCertificates, ClientCAs: rootCAs, NextProtos: []string{"protocol1"}, } @@ -1748,7 +1755,7 @@ func testVerifyConnection(t *testing.T, version uint16) { ClientSessionCache: NewLRUClientSessionCache(32), RootCAs: rootCAs, ServerName: "example.golang", - Certificates: []Certificate{testConfig.Certificates[0]}, + Certificates: testCertificates, NextProtos: []string{"protocol1"}, } test.configureClient(clientConfig, &clientCalled) @@ -1783,7 +1790,8 @@ func TestVerifyPeerCertificate(t *testing.T) { } 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) } @@ -2041,8 +2049,8 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) { 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) @@ -2053,6 +2061,7 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) { }() config := testConfig.Clone() + config.Certificates = []Certificate{{Certificate: [][]byte{testRSA2048Certificate}, PrivateKey: testRSA2048PrivateKey}} config.ServerName = "example.golang" config.RootCAs = rootCAs config.Time = now @@ -2336,8 +2345,8 @@ var getClientCertificateTests = []struct { panic("empty AcceptableCAs") } cert := &Certificate{ - Certificate: [][]byte{testRSACertificate}, - PrivateKey: testRSAPrivateKey, + Certificate: [][]byte{testRSA2048Certificate}, + PrivateKey: testRSA2048PrivateKey, } return cert, nil } @@ -2357,13 +2366,15 @@ func TestGetClientCertificate(t *testing.T) { } 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) @@ -2372,10 +2383,17 @@ func testGetClientCertificate(t *testing.T, version uint16) { 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 @@ -2514,11 +2532,15 @@ func TestDowngradeCanary(t *testing.T) { 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") } } @@ -2528,7 +2550,8 @@ func TestResumptionKeepsOCSPAndSCT(t *testing.T) { } 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") } @@ -2541,6 +2564,7 @@ func testResumptionKeepsOCSPAndSCT(t *testing.T, ver uint16) { 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}} @@ -2675,11 +2699,15 @@ func testTLS13OnlyClientHelloCipherSuite(t *testing.T, ciphers []uint16) { 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) } } diff --git a/handshake_server_test.go b/handshake_server_test.go index 84b086f..17453eb 100644 --- a/handshake_server_test.go +++ b/handshake_server_test.go @@ -11,6 +11,7 @@ import ( "crypto/ecdh" "crypto/elliptic" "crypto/rand" + "crypto/tls/internal/fips140tls" "crypto/x509" "encoding/pem" "errors" @@ -119,7 +120,7 @@ func TestRejectBadProtocolVersion(t *testing.T) { func TestNoSuiteOverlap(t *testing.T) { clientHello := &clientHelloMsg{ - vers: VersionTLS10, + vers: VersionTLS12, random: make([]byte, 32), cipherSuites: []uint16{0xff00}, compressionMethods: []uint8{compressionNone}, @@ -129,9 +130,9 @@ func TestNoSuiteOverlap(t *testing.T) { 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") @@ -139,7 +140,7 @@ func TestNoCompressionOverlap(t *testing.T) { 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}, @@ -163,9 +164,9 @@ func TestDontSelectECDSAWithRSAKey(t *testing.T) { // 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}, @@ -189,9 +190,9 @@ func TestDontSelectRSAWithECDSAKey(t *testing.T) { // 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}, @@ -211,6 +212,8 @@ func TestDontSelectRSAWithECDSAKey(t *testing.T) { } func TestRenegotiationExtension(t *testing.T) { + skipFIPS(t) // #70505 + clientHello := &clientHelloMsg{ vers: VersionTLS12, compressionMethods: []uint8{compressionNone}, @@ -263,6 +266,8 @@ func TestRenegotiationExtension(t *testing.T) { } 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{ @@ -324,13 +329,18 @@ func TestTLSPointFormats(t *testing.T) { 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, @@ -344,7 +354,9 @@ func TestTLSPointFormats(t *testing.T) { 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) @@ -357,9 +369,10 @@ func TestTLSPointFormats(t *testing.T) { 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 { @@ -434,6 +447,8 @@ func TestVersion(t *testing.T) { } 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}, @@ -502,11 +517,11 @@ func TestCrossVersionResume(t *testing.T) { 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", @@ -927,14 +942,14 @@ func TestHandshakeServerKeySharePreference(t *testing.T) { // 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") @@ -1081,16 +1096,16 @@ func TestHandshakeServerGetCertificateExtensions(t *testing.T) { 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 @@ -1139,9 +1154,9 @@ func TestHandshakeServerSNIGetCertificateError(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{compressionNone}, serverName: "test", } @@ -1160,9 +1175,9 @@ func TestHandshakeServerEmptyCertificates(t *testing.T) { 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) @@ -1172,9 +1187,9 @@ func TestHandshakeServerEmptyCertificates(t *testing.T) { 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") @@ -1497,9 +1512,9 @@ func TestSNIGivenOnFailure(t *testing.T) { 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, } @@ -1755,7 +1770,7 @@ T+E0J8wlH24pgwQHzy7Ko2qLwn1b5PW8ecrlvP1g 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() @@ -1777,6 +1792,8 @@ func TestMultipleCertificates(t *testing.T) { } func TestAESCipherReordering(t *testing.T) { + skipFIPS(t) // No CHACHA20_POLY1305 for FIPS. + currentAESSupport := hasAESGCMHardwareSupport defer func() { hasAESGCMHardwareSupport = currentAESSupport }() @@ -1920,6 +1937,8 @@ func TestAESCipherReordering(t *testing.T) { } func TestAESCipherReorderingTLS13(t *testing.T) { + skipFIPS(t) // No CHACHA20_POLY1305 for FIPS. + currentAESSupport := hasAESGCMHardwareSupport defer func() { hasAESGCMHardwareSupport = currentAESSupport }() diff --git a/handshake_test.go b/handshake_test.go index 41c2643..5a9c24f 100644 --- a/handshake_test.go +++ b/handshake_test.go @@ -50,6 +50,9 @@ var ( ) 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() @@ -523,6 +526,12 @@ var testRSACertificate = fromHex("3082024b308201b4a003020102020900e8f09d3fe25bea 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. diff --git a/tls_test.go b/tls_test.go index 394d517..7dd5ddd 100644 --- a/tls_test.go +++ b/tls_test.go @@ -13,6 +13,7 @@ import ( "crypto/elliptic" "crypto/internal/hpke" "crypto/rand" + "crypto/tls/internal/fips140tls" "crypto/x509" "crypto/x509/pkix" "encoding/asn1" @@ -178,6 +179,40 @@ func newLocalListener(t testing.TB) net.Listener { 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") @@ -1114,6 +1149,8 @@ func TestConnectionStateMarshal(t *testing.T) { } func TestConnectionState(t *testing.T) { + skipFIPS(t) // Test certificates not FIPS compatible. + issuer, err := x509.ParseCertificate(testRSACertificateIssuer) if err != nil { panic(err) @@ -1254,6 +1291,8 @@ func TestBuildNameToCertificate_doesntModifyCertificates(t *testing.T) { 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, @@ -1703,6 +1742,8 @@ func TestPKCS1OnlyCert(t *testing.T) { } 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) }) @@ -1847,6 +1888,8 @@ func testVerifyCertificates(t *testing.T, version uint16) { } func TestHandshakeKyber(t *testing.T) { + skipFIPS(t) // No Kyber768 in FIPS + if x25519Kyber768Draft00.String() != "X25519Kyber768Draft00" { t.Fatalf("unexpected CurveID string: %v", x25519Kyber768Draft00.String()) }