Source file src/crypto/tls/fips140_test.go

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package tls
     6  
     7  import (
     8  	"crypto/ecdsa"
     9  	"crypto/elliptic"
    10  	"crypto/internal/boring"
    11  	"crypto/rand"
    12  	"crypto/rsa"
    13  	"crypto/x509"
    14  	"crypto/x509/pkix"
    15  	"encoding/pem"
    16  	"fmt"
    17  	"internal/obscuretestdata"
    18  	"internal/testenv"
    19  	"math/big"
    20  	"net"
    21  	"os"
    22  	"runtime"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  )
    27  
    28  func allCipherSuitesIncludingTLS13() []uint16 {
    29  	s := allCipherSuites()
    30  	for _, suite := range cipherSuitesTLS13 {
    31  		s = append(s, suite.id)
    32  	}
    33  	return s
    34  }
    35  
    36  func isTLS13CipherSuite(id uint16) bool {
    37  	for _, suite := range cipherSuitesTLS13 {
    38  		if id == suite.id {
    39  			return true
    40  		}
    41  	}
    42  	return false
    43  }
    44  
    45  func generateKeyShare(group CurveID) keyShare {
    46  	ke, err := keyExchangeForCurveID(group)
    47  	if err != nil {
    48  		panic(err)
    49  	}
    50  	_, shares, err := ke.keyShares(rand.Reader)
    51  	if err != nil {
    52  		panic(err)
    53  	}
    54  	return shares[0]
    55  }
    56  
    57  func TestFIPSServerProtocolVersion(t *testing.T) {
    58  	test := func(t *testing.T, name string, v uint16, msg string) {
    59  		t.Run(name, func(t *testing.T) {
    60  			serverConfig := testConfig.Clone()
    61  			serverConfig.MinVersion = VersionSSL30
    62  			clientConfig := testConfig.Clone()
    63  			clientConfig.MinVersion = v
    64  			clientConfig.MaxVersion = v
    65  			_, _, err := testHandshake(t, clientConfig, serverConfig)
    66  			if msg == "" {
    67  				if err != nil {
    68  					t.Fatalf("got error: %v, expected success", err)
    69  				}
    70  			} else {
    71  				if err == nil {
    72  					t.Fatalf("got success, expected error")
    73  				}
    74  				if !strings.Contains(err.Error(), msg) {
    75  					t.Fatalf("got error %v, expected %q", err, msg)
    76  				}
    77  			}
    78  		})
    79  	}
    80  
    81  	runWithFIPSDisabled(t, func(t *testing.T) {
    82  		test(t, "VersionTLS10", VersionTLS10, "")
    83  		test(t, "VersionTLS11", VersionTLS11, "")
    84  		test(t, "VersionTLS12", VersionTLS12, "")
    85  		test(t, "VersionTLS13", VersionTLS13, "")
    86  	})
    87  
    88  	runWithFIPSEnabled(t, func(t *testing.T) {
    89  		test(t, "VersionTLS10", VersionTLS10, "supported versions")
    90  		test(t, "VersionTLS11", VersionTLS11, "supported versions")
    91  		test(t, "VersionTLS12", VersionTLS12, "")
    92  		test(t, "VersionTLS13", VersionTLS13, "")
    93  	})
    94  }
    95  
    96  func isFIPSVersion(v uint16) bool {
    97  	return v == VersionTLS12 || v == VersionTLS13
    98  }
    99  
   100  func isFIPSCipherSuite(id uint16) bool {
   101  	name := CipherSuiteName(id)
   102  	if isTLS13CipherSuite(id) {
   103  		switch id {
   104  		case TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384:
   105  			return true
   106  		case TLS_CHACHA20_POLY1305_SHA256:
   107  			return false
   108  		default:
   109  			panic("unknown TLS 1.3 cipher suite: " + name)
   110  		}
   111  	}
   112  	switch id {
   113  	case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
   114  		TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
   115  		TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
   116  		TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
   117  		return true
   118  	case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
   119  		TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
   120  		// Only for the native module.
   121  		return !boring.Enabled
   122  	}
   123  	switch {
   124  	case strings.Contains(name, "CHACHA20"):
   125  		return false
   126  	case strings.HasSuffix(name, "_SHA"): // SHA-1
   127  		return false
   128  	case strings.HasPrefix(name, "TLS_RSA"): // RSA kex
   129  		return false
   130  	default:
   131  		panic("unknown cipher suite: " + name)
   132  	}
   133  }
   134  
   135  func isFIPSCurve(id CurveID) bool {
   136  	switch id {
   137  	case CurveP256, CurveP384, CurveP521:
   138  		return true
   139  	case X25519MLKEM768, SecP256r1MLKEM768, SecP384r1MLKEM1024:
   140  		// Only for the native module.
   141  		return !boring.Enabled
   142  	case X25519:
   143  		return false
   144  	default:
   145  		panic("unknown curve: " + id.String())
   146  	}
   147  }
   148  
   149  func isECDSA(id uint16) bool {
   150  	for _, suite := range cipherSuites {
   151  		if suite.id == id {
   152  			return suite.flags&suiteECSign == suiteECSign
   153  		}
   154  	}
   155  	return false // TLS 1.3 cipher suites are not tied to the signature algorithm.
   156  }
   157  
   158  func isFIPSSignatureScheme(alg SignatureScheme) bool {
   159  	switch alg {
   160  	case PKCS1WithSHA256,
   161  		ECDSAWithP256AndSHA256,
   162  		PKCS1WithSHA384,
   163  		ECDSAWithP384AndSHA384,
   164  		PKCS1WithSHA512,
   165  		ECDSAWithP521AndSHA512,
   166  		PSSWithSHA256,
   167  		PSSWithSHA384,
   168  		PSSWithSHA512:
   169  		return true
   170  	case Ed25519:
   171  		// Only for the native module.
   172  		return !boring.Enabled
   173  	case PKCS1WithSHA1, ECDSAWithSHA1:
   174  		return false
   175  	default:
   176  		panic("unknown signature scheme: " + alg.String())
   177  	}
   178  }
   179  
   180  func TestFIPSServerCipherSuites(t *testing.T) {
   181  	serverConfig := testConfig.Clone()
   182  	serverConfig.Certificates = make([]Certificate, 1)
   183  
   184  	for _, id := range allCipherSuitesIncludingTLS13() {
   185  		if isECDSA(id) {
   186  			serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
   187  			serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
   188  		} else {
   189  			serverConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
   190  			serverConfig.Certificates[0].PrivateKey = testRSAPrivateKey
   191  		}
   192  		serverConfig.BuildNameToCertificate()
   193  		t.Run(fmt.Sprintf("suite=%s", CipherSuiteName(id)), func(t *testing.T) {
   194  			clientHello := &clientHelloMsg{
   195  				vers:                         VersionTLS12,
   196  				random:                       make([]byte, 32),
   197  				cipherSuites:                 []uint16{id},
   198  				compressionMethods:           []uint8{compressionNone},
   199  				supportedCurves:              defaultCurvePreferences(),
   200  				keyShares:                    []keyShare{generateKeyShare(CurveP256)},
   201  				supportedPoints:              []uint8{pointFormatUncompressed},
   202  				supportedVersions:            []uint16{VersionTLS12},
   203  				supportedSignatureAlgorithms: allowedSignatureAlgorithmsFIPS,
   204  			}
   205  			if isTLS13CipherSuite(id) {
   206  				clientHello.supportedVersions = []uint16{VersionTLS13}
   207  			}
   208  
   209  			runWithFIPSDisabled(t, func(t *testing.T) {
   210  				testClientHello(t, serverConfig, clientHello)
   211  			})
   212  
   213  			runWithFIPSEnabled(t, func(t *testing.T) {
   214  				msg := ""
   215  				if !isFIPSCipherSuite(id) {
   216  					msg = "no cipher suite supported by both client and server"
   217  				}
   218  				testClientHelloFailure(t, serverConfig, clientHello, msg)
   219  			})
   220  		})
   221  	}
   222  }
   223  
   224  func TestFIPSServerCurves(t *testing.T) {
   225  	serverConfig := testConfig.Clone()
   226  	serverConfig.CurvePreferences = nil
   227  	serverConfig.BuildNameToCertificate()
   228  
   229  	for _, curveid := range defaultCurvePreferences() {
   230  		t.Run(fmt.Sprintf("curve=%v", curveid), func(t *testing.T) {
   231  			clientConfig := testConfig.Clone()
   232  			clientConfig.CurvePreferences = []CurveID{curveid}
   233  
   234  			runWithFIPSDisabled(t, func(t *testing.T) {
   235  				if _, _, err := testHandshake(t, clientConfig, serverConfig); err != nil {
   236  					t.Fatalf("got error: %v, expected success", err)
   237  				}
   238  			})
   239  
   240  			// With fipstls forced, bad curves should be rejected.
   241  			runWithFIPSEnabled(t, func(t *testing.T) {
   242  				_, _, err := testHandshake(t, clientConfig, serverConfig)
   243  				if err != nil && isFIPSCurve(curveid) {
   244  					t.Fatalf("got error: %v, expected success", err)
   245  				} else if err == nil && !isFIPSCurve(curveid) {
   246  					t.Fatalf("got success, expected error")
   247  				}
   248  			})
   249  		})
   250  	}
   251  }
   252  
   253  func fipsHandshake(t *testing.T, clientConfig, serverConfig *Config) (clientErr, serverErr error) {
   254  	c, s := localPipe(t)
   255  	client := Client(c, clientConfig)
   256  	server := Server(s, serverConfig)
   257  	done := make(chan error, 1)
   258  	go func() {
   259  		done <- client.Handshake()
   260  		c.Close()
   261  	}()
   262  	serverErr = server.Handshake()
   263  	s.Close()
   264  	clientErr = <-done
   265  	return
   266  }
   267  
   268  func TestFIPSServerSignatureAndHash(t *testing.T) {
   269  	defer func() {
   270  		testingOnlySupportedSignatureAlgorithms = nil
   271  	}()
   272  	defer func(godebug string) {
   273  		os.Setenv("GODEBUG", godebug)
   274  	}(os.Getenv("GODEBUG"))
   275  	os.Setenv("GODEBUG", "tlssha1=1")
   276  
   277  	for _, sigHash := range defaultSupportedSignatureAlgorithms() {
   278  		t.Run(fmt.Sprintf("%v", sigHash), func(t *testing.T) {
   279  			serverConfig := testConfig.Clone()
   280  			serverConfig.Certificates = make([]Certificate, 1)
   281  
   282  			testingOnlySupportedSignatureAlgorithms = []SignatureScheme{sigHash}
   283  
   284  			sigType, _, _ := typeAndHashFromSignatureScheme(sigHash)
   285  			switch sigType {
   286  			case signaturePKCS1v15, signatureRSAPSS:
   287  				serverConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
   288  				serverConfig.Certificates[0].Certificate = [][]byte{testRSAPSS2048Certificate}
   289  				serverConfig.Certificates[0].PrivateKey = testRSAPSS2048PrivateKey
   290  			case signatureEd25519:
   291  				serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
   292  				serverConfig.Certificates[0].Certificate = [][]byte{testEd25519Certificate}
   293  				serverConfig.Certificates[0].PrivateKey = testEd25519PrivateKey
   294  			case signatureECDSA:
   295  				serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
   296  				serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
   297  				serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
   298  			}
   299  			serverConfig.BuildNameToCertificate()
   300  			// PKCS#1 v1.5 signature algorithms can't be used standalone in TLS
   301  			// 1.3, and the ECDSA ones bind to the curve used.
   302  			serverConfig.MaxVersion = VersionTLS12
   303  
   304  			runWithFIPSDisabled(t, func(t *testing.T) {
   305  				clientErr, serverErr := fipsHandshake(t, testConfig, serverConfig)
   306  				if clientErr != nil {
   307  					t.Fatalf("expected handshake with %v to succeed; client error: %v; server error: %v", sigHash, clientErr, serverErr)
   308  				}
   309  			})
   310  
   311  			// With fipstls forced, bad curves should be rejected.
   312  			runWithFIPSEnabled(t, func(t *testing.T) {
   313  				clientErr, _ := fipsHandshake(t, testConfig, serverConfig)
   314  				if isFIPSSignatureScheme(sigHash) {
   315  					if clientErr != nil {
   316  						t.Fatalf("expected handshake with %v to succeed; err=%v", sigHash, clientErr)
   317  					}
   318  				} else {
   319  					if clientErr == nil {
   320  						t.Fatalf("expected handshake with %v to fail, but it succeeded", sigHash)
   321  					}
   322  				}
   323  			})
   324  		})
   325  	}
   326  }
   327  
   328  func TestFIPSClientHello(t *testing.T) {
   329  	runWithFIPSEnabled(t, testFIPSClientHello)
   330  }
   331  
   332  func testFIPSClientHello(t *testing.T) {
   333  	// Test that no matter what we put in the client config,
   334  	// the client does not offer non-FIPS configurations.
   335  
   336  	c, s := net.Pipe()
   337  	defer c.Close()
   338  	defer s.Close()
   339  
   340  	clientConfig := testConfig.Clone()
   341  	// All sorts of traps for the client to avoid.
   342  	clientConfig.MinVersion = VersionSSL30
   343  	clientConfig.MaxVersion = VersionTLS13
   344  	clientConfig.CipherSuites = allCipherSuites()
   345  	clientConfig.CurvePreferences = defaultCurvePreferences()
   346  
   347  	go Client(c, clientConfig).Handshake()
   348  	srv := Server(s, testConfig)
   349  	msg, err := srv.readHandshake(nil)
   350  	if err != nil {
   351  		t.Fatal(err)
   352  	}
   353  	hello, ok := msg.(*clientHelloMsg)
   354  	if !ok {
   355  		t.Fatalf("unexpected message type %T", msg)
   356  	}
   357  
   358  	if !isFIPSVersion(hello.vers) {
   359  		t.Errorf("client vers=%#x", hello.vers)
   360  	}
   361  	for _, v := range hello.supportedVersions {
   362  		if !isFIPSVersion(v) {
   363  			t.Errorf("client offered disallowed version %#x", v)
   364  		}
   365  	}
   366  	for _, id := range hello.cipherSuites {
   367  		if !isFIPSCipherSuite(id) {
   368  			t.Errorf("client offered disallowed suite %v", CipherSuiteName(id))
   369  		}
   370  	}
   371  	for _, id := range hello.supportedCurves {
   372  		if !isFIPSCurve(id) {
   373  			t.Errorf("client offered disallowed curve %v", id)
   374  		}
   375  	}
   376  	for _, sigHash := range hello.supportedSignatureAlgorithms {
   377  		if !isFIPSSignatureScheme(sigHash) {
   378  			t.Errorf("client offered disallowed signature-and-hash %v", sigHash)
   379  		}
   380  	}
   381  }
   382  
   383  func TestFIPSCertAlgs(t *testing.T) {
   384  	// arm and wasm time out generating keys. Nothing in this test is
   385  	// architecture-specific, so just don't bother on those.
   386  	if testenv.CPUIsSlow() {
   387  		t.Skipf("skipping on %s/%s because key generation takes too long", runtime.GOOS, runtime.GOARCH)
   388  	}
   389  
   390  	// Set up some roots, intermediate CAs, and leaf certs with various algorithms.
   391  	// X_Y is X signed by Y.
   392  	R1 := fipsCert(t, "R1", fipsRSAKey(t, 2048), nil, fipsCertCA|fipsCertFIPSOK)
   393  	R2 := fipsCert(t, "R2", fipsRSAKey(t, 1024), nil, fipsCertCA)
   394  	R3 := fipsCert(t, "R3", fipsRSAKey(t, 4096), nil, fipsCertCA|fipsCertFIPSOK)
   395  
   396  	M1_R1 := fipsCert(t, "M1_R1", fipsECDSAKey(t, elliptic.P256()), R1, fipsCertCA|fipsCertFIPSOK)
   397  	M2_R1 := fipsCert(t, "M2_R1", fipsECDSAKey(t, elliptic.P224()), R1, fipsCertCA)
   398  
   399  	I_R1 := fipsCert(t, "I_R1", fipsRSAKey(t, 3072), R1, fipsCertCA|fipsCertFIPSOK)
   400  	I_R2 := fipsCert(t, "I_R2", I_R1.key, R2, fipsCertCA|fipsCertFIPSOK)
   401  	I_M1 := fipsCert(t, "I_M1", I_R1.key, M1_R1, fipsCertCA|fipsCertFIPSOK)
   402  	I_M2 := fipsCert(t, "I_M2", I_R1.key, M2_R1, fipsCertCA|fipsCertFIPSOK)
   403  
   404  	I_R3 := fipsCert(t, "I_R3", fipsRSAKey(t, 3072), R3, fipsCertCA|fipsCertFIPSOK)
   405  	fipsCert(t, "I_R3", I_R3.key, R3, fipsCertCA|fipsCertFIPSOK)
   406  
   407  	L1_I := fipsCert(t, "L1_I", fipsECDSAKey(t, elliptic.P384()), I_R1, fipsCertLeaf|fipsCertFIPSOK)
   408  	L2_I := fipsCert(t, "L2_I", fipsRSAKey(t, 1024), I_R1, fipsCertLeaf)
   409  
   410  	// client verifying server cert
   411  	testServerCert := func(t *testing.T, desc string, pool *x509.CertPool, key any, list [][]byte, ok bool) {
   412  		clientConfig := testConfig.Clone()
   413  		clientConfig.RootCAs = pool
   414  		clientConfig.InsecureSkipVerify = false
   415  		clientConfig.ServerName = "example.com"
   416  
   417  		serverConfig := testConfig.Clone()
   418  		serverConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
   419  		serverConfig.BuildNameToCertificate()
   420  
   421  		clientErr, _ := fipsHandshake(t, clientConfig, serverConfig)
   422  
   423  		if (clientErr == nil) == ok {
   424  			if ok {
   425  				t.Logf("%s: accept", desc)
   426  			} else {
   427  				t.Logf("%s: reject", desc)
   428  			}
   429  		} else {
   430  			if ok {
   431  				t.Errorf("%s: BAD reject (%v)", desc, clientErr)
   432  			} else {
   433  				t.Errorf("%s: BAD accept", desc)
   434  			}
   435  		}
   436  	}
   437  
   438  	// server verifying client cert
   439  	testClientCert := func(t *testing.T, desc string, pool *x509.CertPool, key any, list [][]byte, ok bool) {
   440  		clientConfig := testConfig.Clone()
   441  		clientConfig.ServerName = "example.com"
   442  		clientConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
   443  
   444  		serverConfig := testConfig.Clone()
   445  		serverConfig.ClientCAs = pool
   446  		serverConfig.ClientAuth = RequireAndVerifyClientCert
   447  
   448  		_, serverErr := fipsHandshake(t, clientConfig, serverConfig)
   449  
   450  		if (serverErr == nil) == ok {
   451  			if ok {
   452  				t.Logf("%s: accept", desc)
   453  			} else {
   454  				t.Logf("%s: reject", desc)
   455  			}
   456  		} else {
   457  			if ok {
   458  				t.Errorf("%s: BAD reject (%v)", desc, serverErr)
   459  			} else {
   460  				t.Errorf("%s: BAD accept", desc)
   461  			}
   462  		}
   463  	}
   464  
   465  	// Run simple basic test with known answers before proceeding to
   466  	// exhaustive test with computed answers.
   467  	r1pool := x509.NewCertPool()
   468  	r1pool.AddCert(R1.cert)
   469  
   470  	runWithFIPSDisabled(t, func(t *testing.T) {
   471  		testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
   472  		testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
   473  	})
   474  
   475  	runWithFIPSEnabled(t, func(t *testing.T) {
   476  		testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
   477  		testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
   478  	})
   479  
   480  	if t.Failed() {
   481  		t.Fatal("basic test failed, skipping exhaustive test")
   482  	}
   483  
   484  	if testing.Short() {
   485  		t.Logf("basic test passed; skipping exhaustive test in -short mode")
   486  		return
   487  	}
   488  
   489  	for l := 1; l <= 2; l++ {
   490  		leaf := L1_I
   491  		if l == 2 {
   492  			leaf = L2_I
   493  		}
   494  		for i := 0; i < 64; i++ {
   495  			reachable := map[string]bool{leaf.parentOrg: true}
   496  			reachableFIPS := map[string]bool{leaf.parentOrg: leaf.fipsOK}
   497  			list := [][]byte{leaf.der}
   498  			listName := leaf.name
   499  			addList := func(cond int, c *fipsCertificate) {
   500  				if cond != 0 {
   501  					list = append(list, c.der)
   502  					listName += "," + c.name
   503  					if reachable[c.org] {
   504  						reachable[c.parentOrg] = true
   505  					}
   506  					if reachableFIPS[c.org] && c.fipsOK {
   507  						reachableFIPS[c.parentOrg] = true
   508  					}
   509  				}
   510  			}
   511  			addList(i&1, I_R1)
   512  			addList(i&2, I_R2)
   513  			addList(i&4, I_M1)
   514  			addList(i&8, I_M2)
   515  			addList(i&16, M1_R1)
   516  			addList(i&32, M2_R1)
   517  
   518  			for r := 1; r <= 3; r++ {
   519  				pool := x509.NewCertPool()
   520  				rootName := ","
   521  				shouldVerify := false
   522  				shouldVerifyFIPS := false
   523  				addRoot := func(cond int, c *fipsCertificate) {
   524  					if cond != 0 {
   525  						rootName += "," + c.name
   526  						pool.AddCert(c.cert)
   527  						if reachable[c.org] {
   528  							shouldVerify = true
   529  						}
   530  						if reachableFIPS[c.org] && c.fipsOK {
   531  							shouldVerifyFIPS = true
   532  						}
   533  					}
   534  				}
   535  				addRoot(r&1, R1)
   536  				addRoot(r&2, R2)
   537  				rootName = rootName[1:] // strip leading comma
   538  
   539  				runWithFIPSDisabled(t, func(t *testing.T) {
   540  					testServerCert(t, listName+"->"+rootName[1:], pool, leaf.key, list, shouldVerify)
   541  					testClientCert(t, listName+"->"+rootName[1:]+"(client cert)", pool, leaf.key, list, shouldVerify)
   542  				})
   543  
   544  				runWithFIPSEnabled(t, func(t *testing.T) {
   545  					testServerCert(t, listName+"->"+rootName[1:]+" (fips)", pool, leaf.key, list, shouldVerifyFIPS)
   546  					testClientCert(t, listName+"->"+rootName[1:]+" (fips, client cert)", pool, leaf.key, list, shouldVerifyFIPS)
   547  				})
   548  			}
   549  		}
   550  	}
   551  }
   552  
   553  const (
   554  	fipsCertCA = iota
   555  	fipsCertLeaf
   556  	fipsCertFIPSOK = 0x80
   557  )
   558  
   559  func fipsRSAKey(t *testing.T, size int) *rsa.PrivateKey {
   560  	k, err := rsa.GenerateKey(rand.Reader, size)
   561  	if err != nil {
   562  		t.Fatal(err)
   563  	}
   564  	return k
   565  }
   566  
   567  func fipsECDSAKey(t *testing.T, curve elliptic.Curve) *ecdsa.PrivateKey {
   568  	k, err := ecdsa.GenerateKey(curve, rand.Reader)
   569  	if err != nil {
   570  		t.Fatal(err)
   571  	}
   572  	return k
   573  }
   574  
   575  type fipsCertificate struct {
   576  	name      string
   577  	org       string
   578  	parentOrg string
   579  	der       []byte
   580  	cert      *x509.Certificate
   581  	key       any
   582  	fipsOK    bool
   583  }
   584  
   585  func fipsCert(t *testing.T, name string, key any, parent *fipsCertificate, mode int) *fipsCertificate {
   586  	org := name
   587  	parentOrg := ""
   588  	if i := strings.Index(org, "_"); i >= 0 {
   589  		org = org[:i]
   590  		parentOrg = name[i+1:]
   591  	}
   592  	tmpl := &x509.Certificate{
   593  		SerialNumber: big.NewInt(1),
   594  		Subject: pkix.Name{
   595  			Organization: []string{org},
   596  		},
   597  		NotBefore: time.Unix(0, 0),
   598  		NotAfter:  time.Unix(0, 0),
   599  
   600  		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
   601  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
   602  		BasicConstraintsValid: true,
   603  	}
   604  	if mode&^fipsCertFIPSOK == fipsCertLeaf {
   605  		tmpl.DNSNames = []string{"example.com"}
   606  	} else {
   607  		tmpl.IsCA = true
   608  		tmpl.KeyUsage |= x509.KeyUsageCertSign
   609  	}
   610  
   611  	var pcert *x509.Certificate
   612  	var pkey any
   613  	if parent != nil {
   614  		pcert = parent.cert
   615  		pkey = parent.key
   616  	} else {
   617  		pcert = tmpl
   618  		pkey = key
   619  	}
   620  
   621  	var pub any
   622  	var desc string
   623  	switch k := key.(type) {
   624  	case *rsa.PrivateKey:
   625  		pub = &k.PublicKey
   626  		desc = fmt.Sprintf("RSA-%d", k.N.BitLen())
   627  	case *ecdsa.PrivateKey:
   628  		pub = &k.PublicKey
   629  		desc = "ECDSA-" + k.Curve.Params().Name
   630  	default:
   631  		t.Fatalf("invalid key %T", key)
   632  	}
   633  
   634  	der, err := x509.CreateCertificate(rand.Reader, tmpl, pcert, pub, pkey)
   635  	if err != nil {
   636  		t.Fatal(err)
   637  	}
   638  	cert, err := x509.ParseCertificate(der)
   639  	if err != nil {
   640  		t.Fatal(err)
   641  	}
   642  
   643  	fipsOK := mode&fipsCertFIPSOK != 0
   644  	runWithFIPSEnabled(t, func(t *testing.T) {
   645  		if isCertificateAllowedFIPS(cert) != fipsOK {
   646  			t.Errorf("fipsAllowCert(cert with %s key) = %v, want %v", desc, !fipsOK, fipsOK)
   647  		}
   648  	})
   649  
   650  	return &fipsCertificate{name, org, parentOrg, der, cert, key, fipsOK}
   651  }
   652  
   653  // A self-signed test certificate with an RSA key of size 2048, for testing
   654  // RSA-PSS with SHA512. SAN of example.golang.
   655  var (
   656  	testRSAPSS2048Certificate []byte
   657  	testRSAPSS2048PrivateKey  *rsa.PrivateKey
   658  )
   659  
   660  func init() {
   661  	block, _ := pem.Decode(obscuretestdata.Rot13([]byte(`
   662  -----ORTVA PREGVSVPNGR-----
   663  ZVVP/mPPNrrtNjVONtVENYUUK/xu4+4mZH9QnemORpDjQDLWXbMVuipANDRYODNj
   664  RwRDZN4TN1HRPuZUDJAgMFOQomNrSj0kZGNkZQRkAGN0ZQInSj0lZQRlZwxkAGN0
   665  ZQInZOVkRQNBOtAIONbGO0SwoJHtD28jttRvZN0TPFdTFVo3QDRONDHNN4VOQjNj
   666  ttRXNbVONDPs8sx0A6vrPOK4VBIVsXvgg4xTpBDYrvzPsfwddUplfZVITRgSFZ6R
   667  4Nl141s/7VdqJ0HgVdAo4CKuEBVQ7lQkE284kY6KoPhi/g5uC3HpruLp3uzYvlIq
   668  ZxMDvMJgsHHWs/1dBgZ+buAt59YEJc4q+6vK0yn1WY3RjPVpxxAwW9uDoS7Co2PF
   669  +RF9Lb55XNnc8XBoycpE8ZOFA38odajwsDqPKiBRBwnz2UHkXmRSK5ZN+sN0zr4P
   670  vbPpPEYJXy+TbA9S8sNOsbM+G+2rny4QYhB95eKE8FeBVIOu3KSBe/EIuwgKpAIS
   671  MXpiQg6q68I6wNXNLXz5ayw9TCcq4i+eNtZONNTwHQOBZN4TN1HqQjRO/jDRNjVS
   672  bQNGOtAIUFHRQQNXOtteOtRSODpQNGNZOtAIUEZONs8RNwNNZOxTN1HqRDDFZOPP
   673  QzI4LJ1joTHhM29fLJ5aZN0TPFdTFVo3QDROPjHNN4VONDPBbLfIpSPOuobdr3JU
   674  qP6I7KKKRPzawu01e8u80li0AE379aFQ3pj2Z+UXinKlfJdey5uwTIXj0igjQ81e
   675  I4WmQh7VsVbt5z8+DAP+7YdQMfm88iQXBefblFIBzHPtzPXSKrj+YN+rB/vDRWGe
   676  7rafqqBrKWRc27Rq5iJ+xzJJ3Dztyp2Tjl8jSeZQVdaeaBmON4bPaQRtgKWg0mbt
   677  aEjosRZNJv1nDEl5qG9XN3FC9zb5FrGSFmTTUvR4f4tUHr7wifNSS2dtgQ6+jU6f
   678  m9o6fukaP7t5VyOXuV7FIO/Hdg2lqW+xU1LowZpVd6ANZ5rAZXtMhWe3+mjfFtju
   679  TAnR
   680  -----RAQ PREGVSVPNGR-----`)))
   681  	testRSAPSS2048Certificate = block.Bytes
   682  
   683  	block, _ = pem.Decode(obscuretestdata.Rot13([]byte(`
   684  -----ORTVA EFN CEVINGR XRL-----
   685  ZVVRcNVONNXPNDRNa/U5AQrbattI+PQyFUlbeorWOaQxP3bcta7V6du3ZeQPSEuY
   686  EHwBuBNZgrAK/+lXaIgSYFXwJ+Q14HGvN+8t8HqiBZF+y2jee/7rLG91UUbJUA4M
   687  v4fyKGWTHVzIeK1SPK/9nweGCdVGLBsF0IdrUshby9WJgFF9kZNvUWWQLlsLHTkr
   688  m29txiuRiJXBrFtTdsPwz5nKRsQNHwq/T6c8V30UDy7muQb2cgu1ZFfkOI+GNCaj
   689  AWahNbdNaNxF1vcsudQsEsUjNK6Tsx/gazcrNl7wirn10sRdmvSDLq1kGd/0ILL7
   690  I3QIEJFaYj7rariSrbjPtTPchM5L/Ew6KrY/djVQNDNONbVONDPAcZMvsq/it42u
   691  UqPiYhMnLF0E7FhaSycbKRfygTqYSfac0VsbWM/htSDOFNVVsYjZhzH6bKN1m7Hi
   692  98nVLI61QrCeGPQIQSOfUoAzC8WNb8JgohfRojq5mlbO7YLT2+pyxWxyJR73XdHd
   693  ezV+HWrlFpy2Tva7MGkOKm1JCOx9IjpajxrnKctNFVOJ23suRPZ9taLRRjnOrm5G
   694  6Zr8q1gUgLDi7ifXr7eb9j9/UXeEKrwdLXX1YkxusSevlI+z8YMWMa2aKBn6T3tS
   695  Ao8Dx1Hx5CHORAOzlZSWuG4Z/hhFd4LgZeeB2tv8D+sCuhTmp5FfuLXEOc0J4C5e
   696  zgIPgRSENbTONZRAOVSYeI2+UfTw0kLSnfXbi/DCr6UFGE1Uu2VMBAc+bX4bfmJR
   697  wOG4IpaVGzcy6gP1Jl4TpekwAtXVSMNw+1k1YHHYqbeKxhT8le0gNuT9mAlsJfFl
   698  CeFbiP0HIome8Wkkyn+xDIkRDDdJDkCyRIhY8xKnVQN6Ylg1Uchn2YiCNbTONADM
   699  p6Yd2G7+OkYkAqv2z8xMmrw5xtmOc/KqIfoSJEyroVK2XeSUfeUmG9CHx3QR1iMX
   700  Z6cmGg94aDuJFxQtPnj1FbuRyW3USVSjphfS1FWNp3cDrcq8ht6VLqycQZYgOw/C
   701  /5C6OIHgtb05R4+V/G3vLngztyDkGgyM0ExFI2yyNbTONYBKxXSK7nuCis0JxfQu
   702  hGshSBGCbbjtDT0RctJ0jEqPkrt/WYvp3yFQ0tfggDI2JfErpelJpknryEt10EzB
   703  38OobtzunS4kitfFihwBsvMGR8bX1G43Z+6AXfVyZY3LVYocH/9nWkCJl0f2QdQe
   704  pDWuMeyx+cmwON7Oas/HEqjkNbTNXE/PAj14Q+zeY3LYoovPKvlqdkIjki5cqMqm
   705  8guv3GApfJP4vTHEqpIdosHvaICqWvKr/Xnp3JTPrEWnSItoXNBkYgv1EO5ZxVut
   706  Q8rlhcOdx4J1Y1txekdfqw4GSykxjZljwy2R2F4LlD8COg6I04QbIEMfVXmdm+CS
   707  HvbaCd0PtLOPLKidvbWuCrjxBd/L5jeQOrMJ1SDX5DQ9J5Z8/5mkq4eqiWgwuoWc
   708  bBegiZqey6hcl9Um4OWQ3SKjISvCSR7wdrAdv0S21ivYkOCZZQ3HBQS6YY5RlYvE
   709  9I4kIZF8XKkit7ekfhdmZCfpIvnJHY6JAIOufQ2+92qUkFKmm5RWXD==
   710  -----RAQ EFN CEVINGR XRL-----`)))
   711  	var err error
   712  	testRSAPSS2048PrivateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
   713  	if err != nil {
   714  		panic(err)
   715  	}
   716  }
   717  

View as plain text