diff options
author | Gibheer <gibheer+git@zero-knowledge.org> | 2017-05-12 15:27:44 +0200 |
---|---|---|
committer | Gibheer <gibheer+git@zero-knowledge.org> | 2017-05-12 15:27:44 +0200 |
commit | b6c44317f540dac8763e720767b0e73940a0b6c5 (patch) | |
tree | fac6e911056ba12da589dac4ad1f32aa63430f78 | |
parent | fd88bca2872e589b451cde3767dbc59d82bd1c83 (diff) |
add proper pem interface
This should finally resolve the completely broken and wrong API to get a
pem representation of a resource.
-rw-r--r-- | certificate.go | 24 | ||||
-rw-r--r-- | ecdsa.go | 12 | ||||
-rw-r--r-- | ed25519.go | 9 | ||||
-rw-r--r-- | rsa.go | 13 | ||||
-rw-r--r-- | types.go | 10 |
5 files changed, 59 insertions, 9 deletions
diff --git a/certificate.go b/certificate.go index 3adb530..b90e9fa 100644 --- a/certificate.go +++ b/certificate.go @@ -81,10 +81,18 @@ func LoadCertificateSignRequest(raw []byte) (*CertificateRequest, error) { return (*CertificateRequest)(csr), nil } +// ToPem returns a pem.Block representing the CertificateRequest. +func (c *CertificateRequest) ToPem() (pem.Block, error) { + return pem.Block{Type: PemLabelCertificateRequest, Bytes: c.Raw}, nil +} + // Return the certificate sign request as a pem block. func (c *CertificateRequest) MarshalPem() (io.WriterTo, error) { - block := &pem.Block{Type: PemLabelCertificateRequest, Bytes: c.Raw} - return marshalledPemBlock(pem.EncodeToMemory(block)), nil + if block, err := c.ToPem(); err != nil { + return nil, err + } else { + return marshalledPemBlock(pem.EncodeToMemory(&block)), nil + } } // Convert the certificate sign request to a certificate using the private key @@ -152,8 +160,16 @@ func LoadCertificate(raw []byte) (*Certificate, error) { // marshal the certificate to a pem block func (c *Certificate) MarshalPem() (io.WriterTo, error) { - block := &pem.Block{Type: PemLabelCertificate, Bytes: c.Raw} - return marshalledPemBlock(pem.EncodeToMemory(block)), nil + if block, err := c.ToPem(); err != nil { + return nil, err + } else { + return marshalledPemBlock(pem.EncodeToMemory(&block)), nil + } +} + +// ToPem returns the pem block of the certificate. +func (c *Certificate) ToPem() (pem.Block, error) { + return pem.Block{Type: PemLabelCertificate, Bytes: c.Raw}, nil } // Check if the certificate options have the required fields set. @@ -78,14 +78,22 @@ func (pr EcdsaPrivateKey) PrivateKey() crypto.PrivateKey { // This function implements the Pemmer interface to marshal the private key // into a pem block. func (pr EcdsaPrivateKey) MarshalPem() (io.WriterTo, error) { - asn1, err := x509.MarshalECPrivateKey(pr.private_key) + pem_block, err := pr.ToPem() if err != nil { return nil, err } - pem_block := pem.Block{Type: PemLabelEcdsa, Bytes: asn1} return marshalledPemBlock(pem.EncodeToMemory(&pem_block)), nil } +// This function implements ToPem to return the raw pem block. +func (pr EcdsaPrivateKey) ToPem() (pem.Block, error) { + asn1, err := x509.MarshalECPrivateKey(pr.private_key) + if err != nil { + return pem.Block{}, err + } + return pem.Block{Type: PemLabelEcdsa, Bytes: asn1}, nil +} + // This functoin loads an ecdsa public key from the asn.1 representation. func LoadPublicKeyEcdsa(raw []byte) (*EcdsaPublicKey, error) { raw_pub, err := x509.ParsePKIXPublicKey(raw) @@ -70,10 +70,17 @@ func (pr *Ed25519PrivateKey) Sign(message []byte, hash crypto.Hash) ([]byte, err // Export the private key into the Pem format. func (pr Ed25519PrivateKey) MarshalPem() (io.WriterTo, error) { - pem_block := pem.Block{Type: PemLabelEd25519, Bytes: pr.private_key[:]} + pem_block, err := pr.ToPem() + if err != nil { // it does not currently return an error, but maybe that will change + return nil, err + } return marshalledPemBlock(pem.EncodeToMemory(&pem_block)), nil } +func (pr Ed25519PrivateKey) ToPem() (pem.Block, error) { + return pem.Block{Type: PemLabelEd25519, Bytes: pr.private_key[:]}, nil +} + // Load the public key from a raw byte stream. // TODO should this be read from ASN.1? All other functions do that. func LoadPublicKeyEd25519(raw []byte) (*Ed25519PublicKey, error) { @@ -61,11 +61,20 @@ func (pr RsaPrivateKey) PrivateKey() crypto.PrivateKey { } func (pr RsaPrivateKey) MarshalPem() (io.WriterTo, error) { - asn1 := x509.MarshalPKCS1PrivateKey(pr.private_key) - pem_block := pem.Block{Type: PemLabelRsa, Bytes: asn1} + pem_block, err := pr.ToPem() + if err != nil { // it does not currently return an error, but maybe that will change + return nil, err + } return marshalledPemBlock(pem.EncodeToMemory(&pem_block)), nil } +func (pr RsaPrivateKey) ToPem() (pem.Block, error) { + return pem.Block{ + Type: PemLabelRsa, + Bytes: x509.MarshalPKCS1PrivateKey(pr.private_key), + }, nil +} + // restore a rsa public key func LoadPublicKeyRsa(raw []byte) (*RsaPublicKey, error) { pub := &RsaPublicKey{} @@ -16,6 +16,7 @@ package pki import ( "crypto" + "encoding/pem" "io" ) @@ -35,6 +36,9 @@ type ( // Return the original go structure of the private key. PrivateKey() crypto.PrivateKey + + // ToPem must return a pem block of the private key. + ToPem() (pem.Block, error) } // PublicKey is used by the different crypto implementations to provide the @@ -52,4 +56,10 @@ type ( Pemmer interface { MarshalPem() (io.WriterTo, error) } + + // ToPem returns the raw pem block to make it possible to write the result to + // any place. + PemOutput interface { + ToPem() (pem.Block, error) + } ) |