diff options
| author | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2020-11-27 17:13:41 +0100 | 
|---|---|---|
| committer | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2020-11-27 17:13:41 +0100 | 
| commit | 782d895d8d6e66938a3fa6914d8e93a79c949771 (patch) | |
| tree | 8f3c5c21317a34cc6192c979a4fb9c440b941972 /x509util | |
| parent | 11d95a45d7416d3f8c8a03051588cf8097e7246f (diff) | |
added ParseDerChain tests
Diffstat (limited to 'x509util')
| -rw-r--r-- | x509util/x509util.go | 7 | ||||
| -rw-r--r-- | x509util/x509util_test.go | 112 | 
2 files changed, 100 insertions, 19 deletions
| diff --git a/x509util/x509util.go b/x509util/x509util.go index f95b136..c3ebd4b 100644 --- a/x509util/x509util.go +++ b/x509util/x509util.go @@ -104,8 +104,11 @@ func NewEd25519PrivateKey(data []byte) (ed25519.PrivateKey, error) {  // the remaining ones as its intermediate CertPool.  func ParseDerChain(chain [][]byte) (*x509.Certificate, *x509.CertPool, error) {  	certificates, err := ParseDerList(chain) -	if err != nil || len(certificates) == 0 { -		return nil, nil, err // TODO: don't think the len check works now.. +	if err != nil { +		return nil, nil, err +	} +	if len(certificates) == 0 { +		return nil, nil, fmt.Errorf("empty certificate chain")  	}  	intermediatePool := x509.NewCertPool()  	for _, certificate := range certificates[1:] { diff --git a/x509util/x509util_test.go b/x509util/x509util_test.go index 538ef45..298293b 100644 --- a/x509util/x509util_test.go +++ b/x509util/x509util_test.go @@ -5,6 +5,8 @@ import (  	"fmt"  	"testing" +	"crypto/x509" +  	"github.com/system-transparency/stfe/x509util/testdata"  ) @@ -150,8 +152,66 @@ func TestNewCertPool(t *testing.T) {  	}  } -// TODO: TestParseDerChain  func TestParseDerChain(t *testing.T) { +	for _, table := range []struct { +		description string +		chain       [][]byte +		wantErr     bool +	}{ +		{ +			description: "invalid chain: empty", +			wantErr:     true, +		}, +		{ +			description: "invalid chain: first certificate: byte is missing", +			chain: [][]byte{ +				mustMakeDerList(t, testdata.IntermediateChain)[0][1:], +				mustMakeDerList(t, testdata.IntermediateChain)[1], +			}, +			wantErr: true, +		}, +		{ +			description: "valid chain: size 1", +			chain:       mustMakeDerList(t, testdata.EndEntityCertificate), +		}, +		{ +			description: "valid chain: size 2", +			chain:       mustMakeDerList(t, testdata.IntermediateChain), +		}, +		{ +			description: "valid chain: size 3", +			chain:       mustMakeDerList(t, testdata.RootChain), +		}, +	} { +		cert, pool, err := ParseDerChain(table.chain) +		if got, want := err != nil, table.wantErr; got != want { +			t.Errorf("got error=%v but wanted %v in test %q: %v", got, want, table.description, err) +		} +		if err != nil { +			continue +		} + +		if got, want := cert.Raw, table.chain[0]; !bytes.Equal(got, want) { +			t.Errorf("got end-entity certificate %X but wanted %X in test %q", got, want, table.description) +		} +		if got, want := len(pool.Subjects()), len(table.chain)-1; got != want { +			t.Errorf("got %d intermediates but wanted %d in test %q", got, want, table.description) +			continue +		} +		for _, der := range table.chain[1:] { +			want := mustMakeCertificate(t, der).RawSubject +			ok := false +			for _, got := range pool.Subjects() { +				if bytes.Equal(got, want) { +					ok = true +					break +				} +			} +			if !ok { +				t.Errorf("want subject %X but found no match in test %q", want, table.description) +			} +		} +	}  }  func TestParseDerList(t *testing.T) { @@ -161,9 +221,18 @@ func TestParseDerList(t *testing.T) {  		wantErr     bool  	}{  		{ -			description: "invalid certificate: first byte is missing", +			description: "invalid certificate: first certificate: byte is missing", +			list: [][]byte{ +				mustMakeDerList(t, testdata.IntermediateChain)[0][1:], +				mustMakeDerList(t, testdata.IntermediateChain)[1], +			}, +			wantErr: true, +		}, +		{ +			description: "invalid certificate: second certificate: byte is missing",  			list: [][]byte{ -				mustMakeDerList(t, testdata.EndEntityCertificate)[0][1:], +				mustMakeDerList(t, testdata.IntermediateChain)[0], +				mustMakeDerList(t, testdata.IntermediateChain)[1][1:],  			},  			wantErr: true,  		}, @@ -203,20 +272,6 @@ func TestParseDerList(t *testing.T) {  	}  } -// mustMakeDerList must create a list of DER-encoded certificates from PEM -func mustMakeDerList(t *testing.T, pem []byte) [][]byte { -	certs, err := NewCertificateList(pem) -	if err != nil { -		t.Fatalf("must parse pem-encoded certificates: %v", err) -	} - -	list := make([][]byte, 0, len(certs)) -	for _, cert := range certs { -		list = append(list, cert.Raw) -	} -	return list -} -  func TestVerifyChain(t *testing.T) {  	for _, table := range []struct {  		description string @@ -252,3 +307,26 @@ func TestVerifyChain(t *testing.T) {  		}  	}  } + +// mustMakeDerList must parse a PEM-encoded list of certificates to DER +func mustMakeDerList(t *testing.T, pem []byte) [][]byte { +	certs, err := NewCertificateList(pem) +	if err != nil { +		t.Fatalf("must parse pem-encoded certificates: %v", err) +	} + +	list := make([][]byte, 0, len(certs)) +	for _, cert := range certs { +		list = append(list, cert.Raw) +	} +	return list +} + +// mustMakeCertificate must parse a DER-encoded certificate +func mustMakeCertificate(t *testing.T, der []byte) *x509.Certificate { +	cert, err := x509.ParseCertificate(der) +	if err != nil { +		t.Fatalf("must parsse der-encoded certificate: %v", err) +	} +	return cert +} | 
