diff --git a/pkg/certificates/ca_test.go b/pkg/certificates/ca_test.go index 7118bf217..28fd7b9d0 100644 --- a/pkg/certificates/ca_test.go +++ b/pkg/certificates/ca_test.go @@ -10,12 +10,14 @@ import ( "encoding/pem" "fmt" "io" + "net" "reflect" "testing" "time" "github.com/ansible/receptor/pkg/certificates" "github.com/ansible/receptor/pkg/certificates/mock_certificates" + "github.com/ansible/receptor/pkg/utils" "go.uber.org/mock/gomock" ) @@ -80,61 +82,9 @@ FdaOLykGKfMCYVBP+xs97IJO8En/5N9QQwc+N4cfCg9/BWoZKHPbRx/V+57VEj0m NotBefore: goodCaTimeBefore, } - goodCaPrivateKeyBlock, _ := pem.Decode([]byte(`-----BEGIN RSA PRIVATE KEY----- -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 ------END RSA PRIVATE KEY-----`)) - - goodCaPrivateKey, err := x509.ParsePKCS1PrivateKey(goodCaPrivateKeyBlock.Bytes) + goodCaPrivateKey, err := setupGoodPrivateKey() if err != nil { - t.Errorf("Error parsing Private Key: %v", err) + t.Fatal(err) } tests := []struct { @@ -299,20 +249,36 @@ func setupGoodCertRequest() (certificates.CertOptions, *x509.CertificateRequest, return certificates.CertOptions{}, &x509.CertificateRequest{}, err } + goodDNSName := "receptor.TEST" + goodIPAddress := net.ParseIP("127.0.0.1").To4() + goodNodeIDs := goodDNSName + goodCertOptions := certificates.CertOptions{ Bits: 4096, CommonName: "Ansible Automation Controller Nodes Mesh", - NotAfter: goodCaTimeAfter, - NotBefore: goodCaTimeBefore, + CertNames: certificates.CertNames{ + DNSNames: []string{goodDNSName}, + IPAddresses: []net.IP{goodIPAddress}, + NodeIDs: []string{goodNodeIDs}, + }, + NotAfter: goodCaTimeAfter, + NotBefore: goodCaTimeBefore, + } + + goodSubjectAltNamesExtension, err := utils.MakeReceptorSAN(goodCertOptions.CertNames.DNSNames, goodCertOptions.IPAddresses, goodCertOptions.NodeIDs) + if err != nil { + return goodCertOptions, &x509.CertificateRequest{}, err } goodCertificateRequest := &x509.CertificateRequest{ - Attributes: nil, - DNSNames: nil, - EmailAddresses: nil, - Extensions: nil, + Attributes: nil, + DNSNames: []string{goodDNSName}, + EmailAddresses: nil, + Extensions: []pkix.Extension{ + *goodSubjectAltNamesExtension, + }, ExtraExtensions: nil, - IPAddresses: nil, + IPAddresses: []net.IP{goodIPAddress}, PublicKeyAlgorithm: x509.RSA, SignatureAlgorithm: x509.SHA256WithRSA, Subject: pkix.Name{ @@ -335,18 +301,8 @@ func setupGoodCertRequest() (certificates.CertOptions, *x509.CertificateRequest, return goodCertOptions, goodCertificateRequest, nil } -func TestCreateCertReqValid(t *testing.T) { - type args struct { - opts *certificates.CertOptions - privateKey *rsa.PrivateKey - } - - goodCertOptions, goodCertificateRequest, err := setupGoodCertRequest() - if err != nil { - t.Fatal(err) - } - - goodPrivateKeyBlock, _ := pem.Decode([]byte(`-----BEGIN RSA PRIVATE KEY----- +func setupGoodPrivateKey() (*rsa.PrivateKey, error) { + goodPrivateKeyBlock, rest := pem.Decode([]byte(`-----BEGIN RSA PRIVATE KEY----- MIIJKAIBAAKCAgEAp17EU0yKFdjqoec7zSc0AWDmT6cZpys8C74HqKeOArJPvswE b4OVyKZj20hFNj2N6TRry0x+pw+eP2XziEc0jdIqb33K6SbZKyezmKNYF+0TlzN9 Md249inCf3DIDImTEC6j3oCobTByxs9E1/tDHyeY6k5aMFY0gMlISuqTLX9iEqR6 @@ -398,9 +354,41 @@ P/Hli/j17jC7TdgC26JhtVHH7K5xC6iNL03Pf3GTSvwN1vK1BY2reoz1FtQrGZvM rydzkVNNVeMVX2TER9yc8AdFqkRlaBWHmO61rYmV+N1quLM0uMVsu55ZNCY= -----END RSA PRIVATE KEY-----`)) + if goodPrivateKeyBlock == nil { + return &rsa.PrivateKey{}, fmt.Errorf("Failed to decode PEM block containing private key") + } + + wantBlockType := "RSA PRIVATE KEY" + if goodPrivateKeyBlock.Type != wantBlockType { + return &rsa.PrivateKey{}, fmt.Errorf("Decoded PEM block: got: %v, want: %v", goodPrivateKeyBlock.Type, wantBlockType) + } + + if len(rest) > 0 { + return &rsa.PrivateKey{}, fmt.Errorf("Unexpected extra data in PEM block: %q", rest) + } + goodPrivateKey, err := x509.ParsePKCS1PrivateKey(goodPrivateKeyBlock.Bytes) if err != nil { - t.Errorf("Error parsing Private Key: %v", err) + return goodPrivateKey, fmt.Errorf("Error parsing Private Key: %v", err) + } + + return goodPrivateKey, nil +} + +func TestCreateCertReqValid(t *testing.T) { + type args struct { + opts *certificates.CertOptions + privateKey *rsa.PrivateKey + } + + goodCertOptions, goodCertificateRequest, err := setupGoodCertRequest() + if err != nil { + t.Fatal(err) + } + + goodPrivateKey, err := setupGoodPrivateKey() + if err != nil { + t.Fatal(err) } tests := []struct { @@ -587,3 +575,99 @@ func TestCreateCertReqWithKeyNegative(t *testing.T) { }) } } + +func TestGetReqNames(t *testing.T) { + type args struct { + request *x509.CertificateRequest + } + + _, goodCertificateRequest, err := setupGoodCertRequest() + if err != nil { + t.Fatal(err) + } + + goodDNSNames := goodCertificateRequest.DNSNames + goodIPAddresses := goodCertificateRequest.IPAddresses + goodNodeIDs := goodDNSNames + + tests := []struct { + name string + args args + want *certificates.CertNames + wantErr bool + }{ + { + name: "Positive test", + args: args{ + request: goodCertificateRequest, + }, + want: &certificates.CertNames{ + DNSNames: goodDNSNames, + NodeIDs: goodNodeIDs, + IPAddresses: goodIPAddresses, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := certificates.GetReqNames(tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("GetReqNames() error = %v, wantErr %v", err, tt.wantErr) + + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetReqNames() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetReqNamesNegative(t *testing.T) { + type args struct { + request *x509.CertificateRequest + } + + _, goodCertificateRequest, err := setupGoodCertRequest() + if err != nil { + t.Fatal(err) + } + + goodCertificateRequest.Extensions = []pkix.Extension{ + { + Id: utils.OIDSubjectAltName, + Critical: true, + Value: nil, + }, + } + + tests := []struct { + name string + args args + want *certificates.CertNames + wantErr bool + }{ + { + name: "Negative test", + args: args{ + request: goodCertificateRequest, + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := certificates.GetReqNames(tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("GetReqNames() error = %v, wantErr %v", err, tt.wantErr) + + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetReqNames() = %v, want %v", got, tt.want) + } + }) + } +}