Skip to content

Commit

Permalink
GenCACert - do not set fields with empty value (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
maditya authored Jun 4, 2021
1 parent 442446a commit 649add1
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 5 deletions.
26 changes: 21 additions & 5 deletions x509cert/x509.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,30 @@ func GenCACert(config *crypki.CAConfig, signer crypto.Signer, hostname string, i
start := uint64(time.Now().Unix())
end := start + config.ValidityPeriod
start -= 3600
var country, locality, province, org, orgUnit []string
if config.Country != "" {
country = []string{config.Country}
}
if config.Locality != "" {
locality = []string{config.Locality}
}
if config.State != "" {
province = []string{config.State}
}
if config.Organization != "" {
org = []string{config.Organization}
}
if config.OrganizationalUnit != "" {
orgUnit = []string{config.OrganizationalUnit}
}

subj := pkix.Name{
CommonName: config.CommonName,
Country: []string{config.Country},
Locality: []string{config.Locality},
Province: []string{config.State},
Organization: []string{config.Organization},
OrganizationalUnit: []string{config.OrganizationalUnit},
Country: country,
Locality: locality,
Province: province,
Organization: org,
OrganizationalUnit: orgUnit,
}
template := &x509.Certificate{
Subject: subj,
Expand Down
141 changes: 141 additions & 0 deletions x509cert/x509_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
package x509cert

import (
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"net"
"reflect"
"testing"

"github.com/theparanoids/crypki"
Expand Down Expand Up @@ -64,3 +72,136 @@ func TestGetPublicKeyAlgorithm(t *testing.T) {
})
}
}

func TestGenCACert(t *testing.T) {
t.Parallel()
pka := crypki.ECDSA
sa := crypki.ECDSAWithSHA384
eckey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
tests := map[string]struct {
cfg *crypki.CAConfig
signer crypto.Signer
hostname string
ips []net.IP
pka crypki.PublicKeyAlgorithm
sa crypki.SignatureAlgorithm
wantSubj pkix.Name
expectError bool
}{
"all-fields": {
cfg: &crypki.CAConfig{
Country: "US",
Locality: "Sunnyvale",
State: "CA",
Organization: "Foo Org",
OrganizationalUnit: "Foo Org Unit",
CommonName: "foo.example.com",
},
signer: eckey,
hostname: "hostname.example.com",
pka: pka,
sa: sa,
wantSubj: pkix.Name{
CommonName: "foo.example.com",
Country: []string{"US"},
Locality: []string{"Sunnyvale"},
Province: []string{"CA"},
Organization: []string{"Foo Org"},
OrganizationalUnit: []string{"Foo Org Unit"},
},
},
"no-ST": {
cfg: &crypki.CAConfig{
Country: "US",
Locality: "Sunnyvale",
Organization: "Foo Org",
OrganizationalUnit: "Foo Org Unit",
CommonName: "foo.example.com",
},
signer: eckey,
hostname: "hostname.example.com",
pka: pka,
sa: sa,
wantSubj: pkix.Name{
CommonName: "foo.example.com",
Country: []string{"US"},
Locality: []string{"Sunnyvale"},
Organization: []string{"Foo Org"},
OrganizationalUnit: []string{"Foo Org Unit"},
},
},
"no-L": {
cfg: &crypki.CAConfig{
Country: "US",
State: "CA",
Organization: "Foo Org",
OrganizationalUnit: "Foo Org Unit",
CommonName: "foo.example.com",
},
signer: eckey,
hostname: "hostname.example.com",
pka: pka,
sa: sa,
wantSubj: pkix.Name{
CommonName: "foo.example.com",
Country: []string{"US"},
Province: []string{"CA"},
Organization: []string{"Foo Org"},
OrganizationalUnit: []string{"Foo Org Unit"},
},
},
"no-Org": {
cfg: &crypki.CAConfig{
Country: "US",
Locality: "Sunnyvale",
State: "CA",
OrganizationalUnit: "Foo Org Unit",
CommonName: "foo.example.com",
},
signer: eckey,
hostname: "hostname.example.com",
pka: pka,
sa: sa,
wantSubj: pkix.Name{
CommonName: "foo.example.com",
Country: []string{"US"},
Locality: []string{"Sunnyvale"},
Province: []string{"CA"},
OrganizationalUnit: []string{"Foo Org Unit"},
},
},
// TODO: add tests to validate other fields in the ca cert, including the signature.
}
for name, tt := range tests {
name, tt := name, tt
t.Run(name, func(t *testing.T) {
t.Parallel()
got, err := GenCACert(tt.cfg, tt.signer, tt.hostname, tt.ips, tt.pka, tt.sa)
if err != nil {
if !tt.expectError {
t.Error("unexpected error")
}
}
if tt.expectError {
t.Error("expected error")
}
block, _ := pem.Decode(got)
if block == nil || block.Type != "CERTIFICATE" {
t.Error("unable to decode PEM block containing the certificate")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
t.Error("failed to parse certificate: " + err.Error())
}
// skip checking Names field in subject
tt.wantSubj.Names = cert.Subject.Names
if !reflect.DeepEqual(cert.Subject, tt.wantSubj) {
t.Errorf("subject mismatch:\n got: \n%+v\n want: \n%+v\n", cert.Subject, tt.wantSubj)
}
})
}

}

0 comments on commit 649add1

Please sign in to comment.