diff options
Diffstat (limited to 'vendor/git.zero-knowledge.org')
-rw-r--r-- | vendor/git.zero-knowledge.org/gibheer/pki/AUTHORS | 3 | ||||
-rw-r--r-- | vendor/git.zero-knowledge.org/gibheer/pki/LICENSE | 13 | ||||
-rw-r--r-- | vendor/git.zero-knowledge.org/gibheer/pki/README.md | 7 | ||||
-rw-r--r-- | vendor/git.zero-knowledge.org/gibheer/pki/certificate.go | 181 | ||||
-rw-r--r-- | vendor/git.zero-knowledge.org/gibheer/pki/ecdsa.go | 142 | ||||
-rw-r--r-- | vendor/git.zero-knowledge.org/gibheer/pki/ed25519.go | 119 | ||||
-rw-r--r-- | vendor/git.zero-knowledge.org/gibheer/pki/pem_marshal.go | 16 | ||||
-rw-r--r-- | vendor/git.zero-knowledge.org/gibheer/pki/rsa.go | 115 | ||||
-rw-r--r-- | vendor/git.zero-knowledge.org/gibheer/pki/types.go | 66 |
9 files changed, 662 insertions, 0 deletions
diff --git a/vendor/git.zero-knowledge.org/gibheer/pki/AUTHORS b/vendor/git.zero-knowledge.org/gibheer/pki/AUTHORS new file mode 100644 index 0000000..3d1b9f5 --- /dev/null +++ b/vendor/git.zero-knowledge.org/gibheer/pki/AUTHORS @@ -0,0 +1,3 @@ +This is the list of contributors to this project: + +* Stefan Radomski diff --git a/vendor/git.zero-knowledge.org/gibheer/pki/LICENSE b/vendor/git.zero-knowledge.org/gibheer/pki/LICENSE new file mode 100644 index 0000000..c0f36b1 --- /dev/null +++ b/vendor/git.zero-knowledge.org/gibheer/pki/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2014, the authors of pkictl <gibheer@zero-knowledge.org> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/git.zero-knowledge.org/gibheer/pki/README.md b/vendor/git.zero-knowledge.org/gibheer/pki/README.md new file mode 100644 index 0000000..8c9a336 --- /dev/null +++ b/vendor/git.zero-knowledge.org/gibheer/pki/README.md @@ -0,0 +1,7 @@ +pki +=== + +This is a small library to make building private keys, public keys, signatures +and most of the certificate stuff a bit easier. + +For a cli you can take a look at [pkictl](https://git.zero-knowledge.org/gibheer/pkictl) diff --git a/vendor/git.zero-knowledge.org/gibheer/pki/certificate.go b/vendor/git.zero-knowledge.org/gibheer/pki/certificate.go new file mode 100644 index 0000000..b90e9fa --- /dev/null +++ b/vendor/git.zero-knowledge.org/gibheer/pki/certificate.go @@ -0,0 +1,181 @@ +package pki + +import ( + "crypto/rand" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "io" + "math/big" + "net" + "time" +) + +// labels used in the pem file format to mark certificate sign requests and certificates +const ( + PemLabelCertificateRequest = "CERTIFICATE REQUEST" + PemLabelCertificate = "CERTIFICATE" +) + +type ( + // Use CertificateData to fill in the minimum data you need to create a certificate + // sign request. + CertificateData struct { + Subject pkix.Name + + DNSNames []string + EmailAddresses []string + IPAddresses []net.IP + } + + // Certificate is an alias on the x509.Certificate to add some methods. + Certificate x509.Certificate + // CertificateRequest is an alias on the x509.CertificateRequest to add some methods. + CertificateRequest x509.CertificateRequest + + // CertificateOptions is used to provide the necessary information to create + // a certificate from a certificate sign request. + CertificateOptions struct { + SerialNumber *big.Int + NotBefore time.Time + NotAfter time.Time // Validity bounds. + IsCA bool + // how many sub ca are allowed between this ca and the end/final certificate + // if it is -1, then no limit will be set + CALength int + KeyUsage x509.KeyUsage // for what can the certificate be used + KeyExtendedUsage []x509.ExtKeyUsage // extended usage for the certificate + CRLUrls []string + } +) + +// Create a new set of certificate data. +func NewCertificateData() *CertificateData { + return &CertificateData{Subject: pkix.Name{}} +} + +// Create a certificate sign request from the input data and the private key of +// the request creator. +func (c *CertificateData) ToCertificateRequest(private_key PrivateKey) (*CertificateRequest, error) { + csr := &x509.CertificateRequest{} + + csr.Subject = c.Subject + csr.DNSNames = c.DNSNames + csr.IPAddresses = c.IPAddresses + csr.EmailAddresses = c.EmailAddresses + + csr_asn1, err := x509.CreateCertificateRequest(rand.Reader, csr, private_key.PrivateKey()) + if err != nil { + return nil, err + } + return LoadCertificateSignRequest(csr_asn1) +} + +// Load a certificate sign request from its asn1 representation. +func LoadCertificateSignRequest(raw []byte) (*CertificateRequest, error) { + csr, err := x509.ParseCertificateRequest(raw) + if err != nil { + return nil, err + } + 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) { + 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 +// of the signer and the certificate of the signer. +// If the certificate is null, the sign request will be used to sign itself. +// Please also see the certificate options struct for information on mandatory fields. +// For more information, please read http://golang.org/pkg/crypto/x509/#CreateCertificate +func (c *CertificateRequest) ToCertificate(private_key PrivateKey, + cert_opts CertificateOptions, ca *Certificate) (*Certificate, error) { + + if err := cert_opts.Valid(); err != nil { + return nil, err + } + + template := &x509.Certificate{} + template.Subject = c.Subject + template.DNSNames = c.DNSNames + template.IPAddresses = c.IPAddresses + template.EmailAddresses = c.EmailAddresses + + // if no ca is given, we have to set IsCA to self sign + if ca == nil { + template.IsCA = true + } + + template.NotBefore = cert_opts.NotBefore + template.NotAfter = cert_opts.NotAfter + template.KeyUsage = cert_opts.KeyUsage + template.ExtKeyUsage = cert_opts.KeyExtendedUsage + template.CRLDistributionPoints = cert_opts.CRLUrls + template.IsCA = cert_opts.IsCA + if cert_opts.IsCA { + template.BasicConstraintsValid = true + } + if cert_opts.CALength >= 0 { + template.MaxPathLen = cert_opts.CALength + template.MaxPathLenZero = true + template.BasicConstraintsValid = true + } + template.SerialNumber = cert_opts.SerialNumber + + var cert_asn1 []byte + var err error + // if we have no ca which can sign the cert, a self signed cert is wanted + // (or isn't it? Maybe we should split creation of the template? But that would be ugly) + if ca == nil { + cert_asn1, err = x509.CreateCertificate(rand.Reader, template, template, c.PublicKey, private_key.PrivateKey()) + } else { + cert_asn1, err = x509.CreateCertificate(rand.Reader, template, (*x509.Certificate)(ca), c.PublicKey, private_key.PrivateKey()) + } + if err != nil { + return nil, err + } + return LoadCertificate(cert_asn1) +} + +// Load a certificate from its asn1 representation. +func LoadCertificate(raw []byte) (*Certificate, error) { + cert, err := x509.ParseCertificate(raw) + if err != nil { + return nil, err + } + return (*Certificate)(cert), nil +} + +// marshal the certificate to a pem block +func (c *Certificate) MarshalPem() (io.WriterTo, error) { + 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. +func (co *CertificateOptions) Valid() error { + if co.SerialNumber == nil { + return fmt.Errorf("No serial number set!") + } + return nil +} diff --git a/vendor/git.zero-knowledge.org/gibheer/pki/ecdsa.go b/vendor/git.zero-knowledge.org/gibheer/pki/ecdsa.go new file mode 100644 index 0000000..4202bd6 --- /dev/null +++ b/vendor/git.zero-knowledge.org/gibheer/pki/ecdsa.go @@ -0,0 +1,142 @@ +package pki + +import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "encoding/asn1" + "encoding/pem" + "errors" + "io" + "math/big" +) + +// This label is used as the type in the pem encoding of ECDSA private keys. +const PemLabelEcdsa = "EC PRIVATE KEY" + +type ( + // This type handles the function calls to the ecdsa private key by + // implementing the interface. + EcdsaPrivateKey struct { + private_key *ecdsa.PrivateKey + } + + // EcdsaPublicKey is the specific public key type for ecdsa. It implements the + // the PublicKey interface. + EcdsaPublicKey struct { + public_key *ecdsa.PublicKey + } + + // This struct is used to marshal and parse the ecdsa signature. + signatureEcdsa struct { + R, S *big.Int + } +) + +// Create a new ECDSA private key using the specified curve. +// For available curves, please take a look at the crypto/elliptic package. +func NewPrivateKeyEcdsa(curve elliptic.Curve) (*EcdsaPrivateKey, error) { + key, err := ecdsa.GenerateKey(curve, rand.Reader) + if err != nil { + return nil, err + } + return &EcdsaPrivateKey{key}, nil +} + +// Load the private key from the asn1 representation. +func LoadPrivateKeyEcdsa(raw []byte) (*EcdsaPrivateKey, error) { + key, err := x509.ParseECPrivateKey(raw) + if err != nil { + return nil, err + } + return &EcdsaPrivateKey{key}, nil +} + +// Create a new public key from the private key. +func (pr EcdsaPrivateKey) Public() PublicKey { + return &EcdsaPublicKey{pr.private_key.Public().(*ecdsa.PublicKey)} +} + +// Sign a message using the private key and the provided hash function. +func (pr EcdsaPrivateKey) Sign(message []byte, hash crypto.Hash) ([]byte, error) { + empty := make([]byte, 0) + if !hash.Available() { + return empty, errors.New("Hash method is not available!") + } + hashed_message := hash.New() + hashed_message.Write(message) + return pr.private_key.Sign(rand.Reader, hashed_message.Sum(nil), hash) +} + +// This function returns the crypto.PrivateKey structure of the ECDSA key. +func (pr EcdsaPrivateKey) PrivateKey() crypto.PrivateKey { + return pr.private_key +} + +// This function implements the Pemmer interface to marshal the private key +// into a pem block. +func (pr EcdsaPrivateKey) MarshalPem() (io.WriterTo, error) { + pem_block, err := pr.ToPem() + if err != nil { + return nil, err + } + 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) + if err != nil { + return nil, err + } + + pub, ok := raw_pub.(*ecdsa.PublicKey) + if !ok { + return nil, errors.New("Not an ecdsa key!") + } + return &EcdsaPublicKey{pub}, nil +} + +// ToPem returns the pem block of the public key. +func (pu *EcdsaPublicKey) ToPem() (pem.Block, error) { + asn1, err := x509.MarshalPKIXPublicKey(pu.public_key) + if err != nil { + return pem.Block{}, err + } + return pem.Block{Type: PemLabelPublic, Bytes: asn1}, nil +} + +// This function implements the Pemmer interface to marshal the public key into +// a pem block. +func (pu *EcdsaPublicKey) MarshalPem() (io.WriterTo, error) { + if block, err := pu.ToPem(); err != nil { + return nil, err + } else { + return marshalledPemBlock(pem.EncodeToMemory(&block)), nil + } +} + +// This function verifies a message using the public key, signature and hash +// function. +// The hash function must be the same as was used to create the signature. +func (pu *EcdsaPublicKey) Verify(message []byte, signature_raw []byte, hash crypto.Hash) (bool, error) { + var sig signatureEcdsa + _, err := asn1.Unmarshal(signature_raw, &sig) + if err != nil { + return false, err + } + hashed_message := hash.New() + hashed_message.Write(message) + return ecdsa.Verify(pu.public_key, hashed_message.Sum(nil), sig.R, sig.S), nil +} diff --git a/vendor/git.zero-knowledge.org/gibheer/pki/ed25519.go b/vendor/git.zero-knowledge.org/gibheer/pki/ed25519.go new file mode 100644 index 0000000..0104beb --- /dev/null +++ b/vendor/git.zero-knowledge.org/gibheer/pki/ed25519.go @@ -0,0 +1,119 @@ +package pki + +import ( + "bytes" + "crypto" + "crypto/ed25519" + "crypto/rand" + "encoding/pem" + "errors" + "fmt" + "io" +) + +const ( + PemLabelEd25519 = "ED25519 PRIVATE KEY" // TODO find correct label +) + +type ( + Ed25519PrivateKey struct { + private_key ed25519.PrivateKey + } + + Ed25519PublicKey struct { + public_key ed25519.PublicKey + } +) + +// Create a new private key of type ed25519. +func NewPrivateKeyEd25519() (*Ed25519PrivateKey, error) { + _, pr_raw, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + return nil, err + } + return &Ed25519PrivateKey{pr_raw}, nil +} + +// Restore an ed25519 private key from a raw byte stream. +// TODO does this have to be asn1? all other functions expect asn1 +func LoadPrivateKeyEd25519(raw []byte) (*Ed25519PrivateKey, error) { + pr_loaded := make([]byte, ed25519.PrivateKeySize) + length := copy(pr_loaded, raw) + if length != ed25519.PrivateKeySize { + return nil, fmt.Errorf("private key length incorrect - got: %d - expected: %d", length, ed25519.PrivateKeySize) + } + return &Ed25519PrivateKey{pr_loaded}, nil +} + +// TODO implement the raw API for the private key +func (pr *Ed25519PrivateKey) PrivateKey() crypto.PrivateKey { + return nil +} + +// Return the public key for this private key. +func (pr *Ed25519PrivateKey) Public() PublicKey { + buf := bytes.NewBufferString(string(pr.private_key[:])) // create a bytes buffer to read the private key + pu_raw, _, err := ed25519.GenerateKey(buf) // use the already built private key again + if err != nil { + return nil + } + return &Ed25519PublicKey{pu_raw} +} + +// Hash the message given the hash algorythm and sign the hash using the private key. +func (pr *Ed25519PrivateKey) Sign(message []byte, hash crypto.Hash) ([]byte, error) { + hashed_message := hash.New() + hashed_message.Write(message) + result := ed25519.Sign(pr.private_key, hashed_message.Sum(nil))[:] + return result, nil +} + +// Export the private key into the Pem format. +func (pr Ed25519PrivateKey) MarshalPem() (io.WriterTo, error) { + 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) { + pu_loaded := make([]byte, ed25519.PublicKeySize) + length := copy(pu_loaded, raw) + if length != ed25519.PublicKeySize { + return nil, errors.New("public key length incorrect") + } + return &Ed25519PublicKey{pu_loaded}, nil +} + +// ToPem returns the pem encoded public key. +func (pu Ed25519PublicKey) ToPem() (pem.Block, error) { + return pem.Block{Type: PemLabelPublic, Bytes: pu.public_key[:]}, nil +} + +// Export the public key into the pem format. +func (pu Ed25519PublicKey) MarshalPem() (io.WriterTo, error) { + pem_block, err := pu.ToPem() + if err != nil { + return nil, err + } + return marshalledPemBlock(pem.EncodeToMemory(&pem_block)), nil +} + +// Hash the message with the hash algorythm and check the signature against the result. +func (pu Ed25519PublicKey) Verify(message []byte, signature []byte, hash crypto.Hash) (bool, error) { + sig := make([]byte, ed25519.SignatureSize) + length := copy(sig[:], signature) + if length != ed25519.SignatureSize { + return false, errors.New("signature does not fit length") + } + hashed_message := hash.New() + hashed_message.Write(message) + return ed25519.Verify(pu.public_key, hashed_message.Sum(nil), sig), nil +} diff --git a/vendor/git.zero-knowledge.org/gibheer/pki/pem_marshal.go b/vendor/git.zero-knowledge.org/gibheer/pki/pem_marshal.go new file mode 100644 index 0000000..89bd477 --- /dev/null +++ b/vendor/git.zero-knowledge.org/gibheer/pki/pem_marshal.go @@ -0,0 +1,16 @@ +package pki + +import ( + "io" +) + +type ( + marshalledPemBlock []byte +) + +// This function writes the marshalled pem block to a writer and returns the +// number of written bytes and eventual errors. +func (b marshalledPemBlock) WriteTo(stream io.Writer) (int64, error) { + numBytes, err := stream.Write(b) + return int64(numBytes), err +} diff --git a/vendor/git.zero-knowledge.org/gibheer/pki/rsa.go b/vendor/git.zero-knowledge.org/gibheer/pki/rsa.go new file mode 100644 index 0000000..b4024ac --- /dev/null +++ b/vendor/git.zero-knowledge.org/gibheer/pki/rsa.go @@ -0,0 +1,115 @@ +package pki + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" + "io" +) + +const ( + PemLabelRsa = "RSA PRIVATE KEY" +) + +type ( + RsaPrivateKey struct { + private_key *rsa.PrivateKey + } + + RsaPublicKey struct { + public_key *rsa.PublicKey + } +) + +// generate a new rsa private key +func NewPrivateKeyRsa(size int) (*RsaPrivateKey, error) { + key, err := rsa.GenerateKey(rand.Reader, size) + if err != nil { + return nil, err + } + return &RsaPrivateKey{key}, nil +} + +// load a rsa private key its ASN.1 presentation +func LoadPrivateKeyRsa(raw []byte) (*RsaPrivateKey, error) { + key, err := x509.ParsePKCS1PrivateKey(raw) + if err != nil { + return nil, err + } + return &RsaPrivateKey{key}, nil +} + +func (pr *RsaPrivateKey) Public() PublicKey { + return &RsaPublicKey{pr.private_key.Public().(*rsa.PublicKey)} +} + +func (pr RsaPrivateKey) Sign(message []byte, hash crypto.Hash) ([]byte, error) { + if !hash.Available() { + return make([]byte, 0), errors.New("Hash method is not available!") + } + hashed_message := hash.New() + hashed_message.Write(message) + return rsa.SignPKCS1v15(rand.Reader, pr.private_key, hash, hashed_message.Sum(nil)) +} + +// get the private key +func (pr RsaPrivateKey) PrivateKey() crypto.PrivateKey { + return pr.private_key +} + +func (pr RsaPrivateKey) MarshalPem() (io.WriterTo, error) { + 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{} + if pub_raw, err := x509.ParsePKIXPublicKey(raw); err != nil { + return nil, err + } else { + pub.public_key = pub_raw.(*rsa.PublicKey) + } + return pub, nil +} + +// ToPem returns the pem encoded public key. +func (pu *RsaPublicKey) ToPem() (pem.Block, error) { + asn1, err := x509.MarshalPKIXPublicKey(pu.public_key) + if err != nil { + return pem.Block{}, err + } + return pem.Block{Type: PemLabelPublic, Bytes: asn1}, nil +} + +// marshal a rsa public key into pem format +func (pu *RsaPublicKey) MarshalPem() (io.WriterTo, error) { + pem_block, err := pu.ToPem() + if err != nil { + return nil, err + } + return marshalledPemBlock(pem.EncodeToMemory(&pem_block)), nil +} + +// verify a message with a signature using the public key +func (pu *RsaPublicKey) Verify(message []byte, signature []byte, hash crypto.Hash) (bool, error) { + hashed_message := hash.New() + hashed_message.Write(message) + if err := rsa.VerifyPKCS1v15(pu.public_key, hash, hashed_message.Sum(nil), signature); err != nil { + return false, err + } + return true, nil +} diff --git a/vendor/git.zero-knowledge.org/gibheer/pki/types.go b/vendor/git.zero-knowledge.org/gibheer/pki/types.go new file mode 100644 index 0000000..f2c6902 --- /dev/null +++ b/vendor/git.zero-knowledge.org/gibheer/pki/types.go @@ -0,0 +1,66 @@ +// Package pki provides an easier way to create crypto related structures +// with the intent of making the management of these structures easier for +// other programs. +// Currently it provides mechanisms to create private keys in ECDSA and RSA, +// create public keys, create certificate sign requests and certificates. +// +// To create a new private key, there are two ways +// for an ecdsa key +// private_key, err := NewPrivateKeyEcdsa(elliptic.P521()) +// or for a RSA key +// private_key, err := NewPrivateKeyRSA(4096) +// +// Getting a private key from the private key can be done with +// public_key := private_key.Public() +package pki + +import ( + "crypto" + "encoding/pem" + "io" +) + +// This label is used as the type in the pem encoding of public keys. +const PemLabelPublic = "PUBLIC KEY" + +type ( + // PrivateKey is a common interface for all crypto implementations to provide + // the same functions, like deriving a public key or signing a message. + PrivateKey interface { + // Derive a new public key from the private key. + Public() PublicKey + // Sign a message using the public key and the given hash method. + // To use a hash method, include the package + // import _ "crypto/sha512" + Sign(message []byte, hash crypto.Hash) ([]byte, error) + + // 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 + // same functionality like verifying a message against a signature. + PublicKey interface { + Pemmer + PemOutput + // This function can be used to verify a message against a provided signature + // using the given hash function. + Verify(message []byte, signature []byte, hash crypto.Hash) (bool, error) + } + + // Pemmer is used by all crypto structures which need to be available + // in the pem format. The result can then be written to any structure + // implementing the io.Writer interface. + 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) + } +) |