aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/client.go2
-rw-r--r--x509util/x509util.go92
2 files changed, 41 insertions, 53 deletions
diff --git a/client/client.go b/client/client.go
index 4658a25..9462e0c 100644
--- a/client/client.go
+++ b/client/client.go
@@ -46,7 +46,7 @@ func NewClient(log *descriptor.Log, client *http.Client, useHttp bool, chain []*
// private key, and a json-encoded list of log operators (see descriptor).
// Chain and key paths may be left out by passing the empty string: "".
func NewClientFromPath(logId, chainPath, keyPath, operatorsPath string, cli *http.Client, useHttp bool) (*Client, error) {
- c, err := x509util.LoadChain(chainPath)
+ c, err := x509util.LoadCertificates(chainPath)
if err != nil && chainPath != "" {
return nil, err
}
diff --git a/x509util/x509util.go b/x509util/x509util.go
index 37688ad..e67b7b5 100644
--- a/x509util/x509util.go
+++ b/x509util/x509util.go
@@ -9,15 +9,40 @@ import (
"io/ioutil"
)
+// LoadCertificates loads a PEM-encoded list of certificates from file
+func LoadCertificates(path string) ([]*x509.Certificate, error) {
+ pem, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil, fmt.Errorf("failed reading certificate chain: %v", err)
+ }
+ return NewCertificateList(pem)
+}
+
// LoadTrustAnchors loads a list of PEM-encoded certificates from file
func LoadTrustAnchors(path string) ([]*x509.Certificate, *x509.CertPool, error) {
- rest, err := ioutil.ReadFile(path)
+ pem, err := ioutil.ReadFile(path)
if err != nil {
return nil, nil, fmt.Errorf("failed reading trust anchors: %v", err)
}
+ anchorList, err := NewCertificateList(pem)
+ if err != nil || len(anchorList) == 0 {
+ return nil, nil, fmt.Errorf("failed parsing trust anchors: %v", err)
+ }
+ return anchorList, NewCertPool(anchorList), nil
+}
- pool := x509.NewCertPool()
- var anchors []*x509.Certificate
+// LoadEd25519SigningKey loads an Ed25519 private key from a given path
+func LoadEd25519SigningKey(path string) (ed25519.PrivateKey, error) {
+ data, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil, fmt.Errorf("failed reading private key: %v", err)
+ }
+ return NewEd25519PrivateKey(data)
+}
+
+// NewCertificateList parses a block of PEM-encoded certificates
+func NewCertificateList(rest []byte) ([]*x509.Certificate, error) {
+ var certificates []*x509.Certificate
for len(rest) > 0 {
var block *pem.Block
block, rest = pem.Decode(rest)
@@ -25,35 +50,29 @@ func LoadTrustAnchors(path string) ([]*x509.Certificate, *x509.CertPool, error)
break
}
if block.Type != "CERTIFICATE" {
- return nil, nil, fmt.Errorf("unexpected PEM block type: %s", block.Type)
+ return nil, fmt.Errorf("unexpected pem block type: %v", block.Type)
}
certificate, err := x509.ParseCertificate(block.Bytes)
if err != nil {
- return nil, nil, fmt.Errorf("invalid trust anchor before rest(%s): %v", rest, err)
+ return nil, fmt.Errorf("failed parsing x509 certificate: %v", err)
}
-
- anchors = append(anchors, certificate)
- pool.AddCert(certificate)
+ certificates = append(certificates, certificate)
}
-
- if len(anchors) == 0 {
- return nil, nil, fmt.Errorf("found no valid trust anchor in: %s", path)
- }
- return anchors, pool, nil
+ return certificates, nil
}
-// LoadEd25519SigningKey loads an Ed25519 private key from a given path
-func LoadEd25519SigningKey(path string) (ed25519.PrivateKey, error) {
- data, err := ioutil.ReadFile(path)
- if err != nil {
- return nil, fmt.Errorf("failed reading private key: %v", err)
+// NewCertPool returns a new cert pool from a list of certificates
+func NewCertPool(certificates []*x509.Certificate) *x509.CertPool {
+ pool := x509.NewCertPool()
+ for _, certificate := range certificates {
+ pool.AddCert(certificate)
}
- return ParseEd25519PrivateKey(data)
+ return pool
}
-// ParseEd25519PrivateKey parses a PEM-encoded private key block
-func ParseEd25519PrivateKey(data []byte) (ed25519.PrivateKey, error) {
+// NewEd25519PrivateKey creates a new ed25519 private-key from a PEM block
+func NewEd25519PrivateKey(data []byte) (ed25519.PrivateKey, error) {
block, rest := pem.Decode(data)
if block == nil {
return nil, fmt.Errorf("pem block: is empty")
@@ -77,37 +96,6 @@ func ParseEd25519PrivateKey(data []byte) (ed25519.PrivateKey, error) {
}
}
-// LoadChain loads a PEM-encoded certificate chain from a given path
-func LoadChain(path string) ([]*x509.Certificate, error) {
- blob, err := ioutil.ReadFile(path)
- if err != nil {
- return nil, fmt.Errorf("failed reading certificate chain: %v", err)
- }
- return ParseChain(blob)
-}
-
-// ParseChain parses a PEM-encoded certificate chain
-func ParseChain(rest []byte) ([]*x509.Certificate, error) {
- var chain []*x509.Certificate
- for len(rest) > 0 {
- var block *pem.Block
- block, rest = pem.Decode(rest)
- if block == nil {
- break
- }
- if block.Type != "CERTIFICATE" {
- return nil, fmt.Errorf("unexpected pem block type: %v", block.Type)
- }
-
- certificate, err := x509.ParseCertificate(block.Bytes)
- if err != nil {
- return nil, fmt.Errorf("failed parsing x509 certificate: %v", err)
- }
- chain = append(chain, certificate)
- }
- return chain, nil
-}
-
// 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.