diff options
Diffstat (limited to 'x509util')
| -rw-r--r-- | x509util/x509util.go | 11 | ||||
| -rw-r--r-- | x509util/x509util_test.go | 155 | 
2 files changed, 162 insertions, 4 deletions
| diff --git a/x509util/x509util.go b/x509util/x509util.go index 751aa29..f95b136 100644 --- a/x509util/x509util.go +++ b/x509util/x509util.go @@ -9,6 +9,7 @@ import (  	"io/ioutil"  ) +// TODO: remove LoadCertificates  // LoadCertificates loads a PEM-encoded list of certificates from file  func LoadCertificates(path string) ([]*x509.Certificate, error) {  	pem, err := ioutil.ReadFile(path) @@ -18,6 +19,7 @@ func LoadCertificates(path string) ([]*x509.Certificate, error) {  	return NewCertificateList(pem)  } +// TODO: remove LoadTrustAnchors  // LoadTrustAnchors loads a list of PEM-encoded certificates from file  func LoadTrustAnchors(path string) ([]*x509.Certificate, *x509.CertPool, error) {  	pem, err := ioutil.ReadFile(path) @@ -31,6 +33,7 @@ func LoadTrustAnchors(path string) ([]*x509.Certificate, *x509.CertPool, error)  	return anchorList, NewCertPool(anchorList), nil  } +// TODO: remove LoadEd25519SigningKey  // LoadEd25519SigningKey loads an Ed25519 private key from a given path  func LoadEd25519SigningKey(path string) (ed25519.PrivateKey, error) {  	data, err := ioutil.ReadFile(path) @@ -47,7 +50,7 @@ func NewCertificateList(rest []byte) ([]*x509.Certificate, error) {  		var block *pem.Block  		block, rest = pem.Decode(rest)  		if block == nil { -			break // TODO: fix such that new line in input is OK? +			return nil, fmt.Errorf("no block: probably caused by leading white space")  		}  		if block.Type != "CERTIFICATE" {  			return nil, fmt.Errorf("unexpected pem block type: %v", block.Type) @@ -97,12 +100,12 @@ func NewEd25519PrivateKey(data []byte) (ed25519.PrivateKey, error) {  }  // ParseDerChain parses a list of DER-encoded X.509 certificates, such that the -// first (zero-index) string is interpretted as an end-entity certificate and -// the remaining ones as the an intermediate CertPool. +// first (zero-index) blob is interpretted as an end-entity certificate and +// 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 +		return nil, nil, err // TODO: don't think the len check works now..  	}  	intermediatePool := x509.NewCertPool()  	for _, certificate := range certificates[1:] { diff --git a/x509util/x509util_test.go b/x509util/x509util_test.go new file mode 100644 index 0000000..772ff41 --- /dev/null +++ b/x509util/x509util_test.go @@ -0,0 +1,155 @@ +package x509util + +import ( +	"fmt" +	"testing" +) + +func TestNewEd25519PrivateKey(t *testing.T) { +} + +func TestNewCertificateList(t *testing.T) { +	for _, table := range []struct { +		description string +		pem         []byte +		wantErr     bool +		wantSerial  []string +	}{ +		{ +			description: "invalid block type", +			pem: []byte(`-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIH65lXoCT4N9q4mPmDcsmAqIqG9CrqrB4KV2nqBC9JlZ +-----END PRIVATE KEY-----`), +			wantErr: true, +		}, +		{ +			description: "bad block bytes: not a certificate", +			pem: []byte(`-----BEGIN CERTIFICATE----- +MC4CAQAwBQYDK2VwBCIEIH65lXoCT4N9q4mPmDcsmAqIqG9CrqrB4KV2nqBC9JlZ +-----END CERTIFICATE-----`), +			wantErr: true, +		}, +		{ +			description: "bad block bytes: truncated certificate", +			pem: []byte(`-----BEGIN CERTIFICATE----- +MIIBbDCCAR4CFDfeuu6XURfn7AE4WShuwZBHEaLIMAUGAytlcDBsMQswCQYDVQQG +-----END CERTIFICATE-----`), +			wantErr: true, +		}, +		{ +			description: "bad block bytes: truncated certificate in list", +			pem: []byte(`-----BEGIN CERTIFICATE----- +MIIBbDCCAR4CFDfeuu6XURfn7AE4WShuwZBHEaLIMAUGAytlcDBsMQswCQYDVQQG +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB7jCCAaCgAwIBAgICEAAwBQYDK2VwMGwxCzAJBgNVBAYTAk5BMQswCQYDVQQI +DAJOQTELMAkGA1UEBwwCTkExCzAJBgNVBAoMAk5BMQswCQYDVQQLDAJOQTEWMBQG +A1UEAwwNc3RmZSB0ZXN0ZGF0YTERMA8GCSqGSIb3DQEJARYCTkEwHhcNMjAxMTAz +MTgzMjE4WhcNMzIwMTIxMTgzMjE4WjBsMQswCQYDVQQGEwJOQTELMAkGA1UECAwC +TkExCzAJBgNVBAcMAk5BMQswCQYDVQQKDAJOQTELMAkGA1UECwwCTkExFjAUBgNV +BAMMDXN0ZmUgdGVzdGRhdGExETAPBgkqhkiG9w0BCQEWAk5BMCowBQYDK2VwAyEA +F1yPPpjHKDAKN73pBFGXzAvIjdkLLimydu2y1HLMOiKjZjBkMB0GA1UdDgQWBBQ6 +P7JQ7yXtrTh7YkVU0I78P9A+nDAfBgNVHSMEGDAWgBQBvsxROtKU6zmr/SxcfTMD +sAQcMTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIChDAFBgMrZXAD +QQBm1GMV0ADPnXRWnelCW9tcyTh0p9hKefuSy/MNx7/XLHKnM5fX+yHqD84QOxES +Vc510vi4dM8I+e/vcoBsmMQP +-----END CERTIFICATE-----`), +			wantErr: true, +		}, +		{ +			description: "bad block: unwanted white spaces", +			pem: []byte(` +				-----BEGIN CERTIFICATE----- +				MIIBbDCCAR4CFDfeuu6XURfn7AE4WShuwZBHEaLIMAUGAytlcDBsMQswCQYDVQQG +				EwJOQTELMAkGA1UECAwCTkExCzAJBgNVBAcMAk5BMQswCQYDVQQKDAJOQTELMAkG +				A1UECwwCTkExFjAUBgNVBAMMDXN0ZmUgdGVzdGRhdGExETAPBgkqhkiG9w0BCQEW +				Ak5BMB4XDTIwMTEwMzE4MzI0MFoXDTMyMDEyMTE4MzI0MFowRTELMAkGA1UEBhMC +				QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp +				dHMgUHR5IEx0ZDAqMAUGAytlcAMhAJvk390ZvwULplBri03Od4LLz+Sf/OUHu+20 +				wik+T9y5MAUGAytlcANBANekliXq4ttoClBJDZoktIQxyHHNcWyXFrj1HlOaT5bC +				I3GIqqZ60Ua3jKytnEsKsD2rLMPItDwmG6wYSecy2ws= +				-----END CERTIFICATE----- +			`), +			wantErr: true, +		}, +		{ +			description: "ok certificate list: empty", +			pem:         []byte{}, +			wantSerial:  nil, +		}, +		{ +			description: "ok certificate list: size 1", +			pem: []byte(`-----BEGIN CERTIFICATE----- +MIIBbDCCAR4CFDfeuu6XURfn7AE4WShuwZBHEaLIMAUGAytlcDBsMQswCQYDVQQG +EwJOQTELMAkGA1UECAwCTkExCzAJBgNVBAcMAk5BMQswCQYDVQQKDAJOQTELMAkG +A1UECwwCTkExFjAUBgNVBAMMDXN0ZmUgdGVzdGRhdGExETAPBgkqhkiG9w0BCQEW +Ak5BMB4XDTIwMTEwMzE4MzI0MFoXDTMyMDEyMTE4MzI0MFowRTELMAkGA1UEBhMC +QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp +dHMgUHR5IEx0ZDAqMAUGAytlcAMhAJvk390ZvwULplBri03Od4LLz+Sf/OUHu+20 +wik+T9y5MAUGAytlcANBANekliXq4ttoClBJDZoktIQxyHHNcWyXFrj1HlOaT5bC +I3GIqqZ60Ua3jKytnEsKsD2rLMPItDwmG6wYSecy2ws= +-----END CERTIFICATE-----`), +			wantSerial: []string{ +				"318961541902906095038704399034602270237826065096", +			}, +		}, +		{ +			description: "ok certificate list: size 2", +			pem: []byte(`-----BEGIN CERTIFICATE----- +MIIBbDCCAR4CFDfeuu6XURfn7AE4WShuwZBHEaLIMAUGAytlcDBsMQswCQYDVQQG +EwJOQTELMAkGA1UECAwCTkExCzAJBgNVBAcMAk5BMQswCQYDVQQKDAJOQTELMAkG +A1UECwwCTkExFjAUBgNVBAMMDXN0ZmUgdGVzdGRhdGExETAPBgkqhkiG9w0BCQEW +Ak5BMB4XDTIwMTEwMzE4MzI0MFoXDTMyMDEyMTE4MzI0MFowRTELMAkGA1UEBhMC +QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp +dHMgUHR5IEx0ZDAqMAUGAytlcAMhAJvk390ZvwULplBri03Od4LLz+Sf/OUHu+20 +wik+T9y5MAUGAytlcANBANekliXq4ttoClBJDZoktIQxyHHNcWyXFrj1HlOaT5bC +I3GIqqZ60Ua3jKytnEsKsD2rLMPItDwmG6wYSecy2ws= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB7jCCAaCgAwIBAgICEAAwBQYDK2VwMGwxCzAJBgNVBAYTAk5BMQswCQYDVQQI +DAJOQTELMAkGA1UEBwwCTkExCzAJBgNVBAoMAk5BMQswCQYDVQQLDAJOQTEWMBQG +A1UEAwwNc3RmZSB0ZXN0ZGF0YTERMA8GCSqGSIb3DQEJARYCTkEwHhcNMjAxMTAz +MTgzMjE4WhcNMzIwMTIxMTgzMjE4WjBsMQswCQYDVQQGEwJOQTELMAkGA1UECAwC +TkExCzAJBgNVBAcMAk5BMQswCQYDVQQKDAJOQTELMAkGA1UECwwCTkExFjAUBgNV +BAMMDXN0ZmUgdGVzdGRhdGExETAPBgkqhkiG9w0BCQEWAk5BMCowBQYDK2VwAyEA +F1yPPpjHKDAKN73pBFGXzAvIjdkLLimydu2y1HLMOiKjZjBkMB0GA1UdDgQWBBQ6 +P7JQ7yXtrTh7YkVU0I78P9A+nDAfBgNVHSMEGDAWgBQBvsxROtKU6zmr/SxcfTMD +sAQcMTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIChDAFBgMrZXAD +QQBm1GMV0ADPnXRWnelCW9tcyTh0p9hKefuSy/MNx7/XLHKnM5fX+yHqD84QOxES +Vc510vi4dM8I+e/vcoBsmMQP +-----END CERTIFICATE-----`), +			wantSerial: []string{ +				"318961541902906095038704399034602270237826065096", +				"4096", +			}, +		}, +	} { +		list, err := NewCertificateList(table.pem) +		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 := len(list), len(table.wantSerial); got != want { +			t.Errorf("got list of length %d but wanted %d in test %q", got, want, table.description) +		} +		for i, certificate := range list { +			if got, want := fmt.Sprintf("%v", certificate.SerialNumber), table.wantSerial[i]; got != want { +				t.Errorf("Got serial number %s but wanted %s on index %d and test %q", got, want, i, table.description) +			} +		} +	} +} + +func TestNewCertPool(t *testing.T) { +} + +func TestParseDerChain(t *testing.T) { +} + +func TestParseDerList(t *testing.T) { +} + +func TestVerifyChain(t *testing.T) { +} | 
