aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGibheer <gibheer+git@zero-knowledge.org>2017-05-12 15:27:44 +0200
committerGibheer <gibheer+git@zero-knowledge.org>2017-05-12 15:27:44 +0200
commitb6c44317f540dac8763e720767b0e73940a0b6c5 (patch)
treefac6e911056ba12da589dac4ad1f32aa63430f78
parentfd88bca2872e589b451cde3767dbc59d82bd1c83 (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.go24
-rw-r--r--ecdsa.go12
-rw-r--r--ed25519.go9
-rw-r--r--rsa.go13
-rw-r--r--types.go10
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.
diff --git a/ecdsa.go b/ecdsa.go
index 66b73f5..8bf432d 100644
--- a/ecdsa.go
+++ b/ecdsa.go
@@ -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)
diff --git a/ed25519.go b/ed25519.go
index 602ac52..f7a0e12 100644
--- a/ed25519.go
+++ b/ed25519.go
@@ -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) {
diff --git a/rsa.go b/rsa.go
index 76296ed..7d575cb 100644
--- a/rsa.go
+++ b/rsa.go
@@ -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{}
diff --git a/types.go b/types.go
index 47fe31a..53db1a9 100644
--- a/types.go
+++ b/types.go
@@ -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)
+ }
)