diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:23:18 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:23:18 +0000 |
commit | 43a123c1ae6613b3efeed291fa552ecd909d3acf (patch) | |
tree | fd92518b7024bc74031f78a1cf9e454b65e73665 /src/crypto/x509/boring_test.go | |
parent | Initial commit. (diff) | |
download | golang-1.20-43a123c1ae6613b3efeed291fa552ecd909d3acf.tar.xz golang-1.20-43a123c1ae6613b3efeed291fa552ecd909d3acf.zip |
Adding upstream version 1.20.14.upstream/1.20.14upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/crypto/x509/boring_test.go')
-rw-r--r-- | src/crypto/x509/boring_test.go | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/crypto/x509/boring_test.go b/src/crypto/x509/boring_test.go new file mode 100644 index 0000000..33fd0ed --- /dev/null +++ b/src/crypto/x509/boring_test.go @@ -0,0 +1,142 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build boringcrypto + +package x509 + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/internal/boring/fipstls" + "crypto/rand" + "crypto/rsa" + "crypto/x509/pkix" + "fmt" + "math/big" + "strings" + "testing" + "time" +) + +const ( + boringCertCA = iota + boringCertLeaf + boringCertFIPSOK = 0x80 +) + +func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey { + k, err := rsa.GenerateKey(rand.Reader, size) + if err != nil { + t.Fatal(err) + } + return k +} + +func boringECDSAKey(t *testing.T, curve elliptic.Curve) *ecdsa.PrivateKey { + k, err := ecdsa.GenerateKey(curve, rand.Reader) + if err != nil { + t.Fatal(err) + } + return k +} + +type boringCertificate struct { + name string + org string + parentOrg string + der []byte + cert *Certificate + key interface{} + fipsOK bool +} + +func TestBoringAllowCert(t *testing.T) { + R1 := testBoringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK) + R2 := testBoringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA) + R3 := testBoringCert(t, "R3", boringRSAKey(t, 4096), nil, boringCertCA|boringCertFIPSOK) + + M1_R1 := testBoringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK) + M2_R1 := testBoringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA) + + I_R1 := testBoringCert(t, "I_R1", boringRSAKey(t, 3072), R1, boringCertCA|boringCertFIPSOK) + testBoringCert(t, "I_R2", I_R1.key, R2, boringCertCA|boringCertFIPSOK) + testBoringCert(t, "I_M1", I_R1.key, M1_R1, boringCertCA|boringCertFIPSOK) + testBoringCert(t, "I_M2", I_R1.key, M2_R1, boringCertCA|boringCertFIPSOK) + + I_R3 := testBoringCert(t, "I_R3", boringRSAKey(t, 3072), R3, boringCertCA|boringCertFIPSOK) + testBoringCert(t, "I_R3", I_R3.key, R3, boringCertCA|boringCertFIPSOK) + + testBoringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK) + testBoringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf) +} + +func testBoringCert(t *testing.T, name string, key interface{}, parent *boringCertificate, mode int) *boringCertificate { + org := name + parentOrg := "" + if i := strings.Index(org, "_"); i >= 0 { + org = org[:i] + parentOrg = name[i+1:] + } + tmpl := &Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + Organization: []string{org}, + }, + NotBefore: time.Unix(0, 0), + NotAfter: time.Unix(0, 0), + + KeyUsage: KeyUsageKeyEncipherment | KeyUsageDigitalSignature, + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}, + BasicConstraintsValid: true, + } + if mode&^boringCertFIPSOK == boringCertLeaf { + tmpl.DNSNames = []string{"example.com"} + } else { + tmpl.IsCA = true + tmpl.KeyUsage |= KeyUsageCertSign + } + + var pcert *Certificate + var pkey interface{} + if parent != nil { + pcert = parent.cert + pkey = parent.key + } else { + pcert = tmpl + pkey = key + } + + var pub interface{} + var desc string + switch k := key.(type) { + case *rsa.PrivateKey: + pub = &k.PublicKey + desc = fmt.Sprintf("RSA-%d", k.N.BitLen()) + case *ecdsa.PrivateKey: + pub = &k.PublicKey + desc = "ECDSA-" + k.Curve.Params().Name + default: + t.Fatalf("invalid key %T", key) + } + + der, err := CreateCertificate(rand.Reader, tmpl, pcert, pub, pkey) + if err != nil { + t.Fatal(err) + } + cert, err := ParseCertificate(der) + if err != nil { + t.Fatal(err) + } + + // Tell isBoringCertificate to enforce FIPS restrictions for this check. + fipstls.Force() + defer fipstls.Abandon() + + fipsOK := mode&boringCertFIPSOK != 0 + if boringAllowCert(cert) != fipsOK { + t.Errorf("boringAllowCert(cert with %s key) = %v, want %v", desc, !fipsOK, fipsOK) + } + return &boringCertificate{name, org, parentOrg, der, cert, key, fipsOK} +} |