aboutsummaryrefslogtreecommitdiff
path: root/vendor/git.zero-knowledge.org
diff options
context:
space:
mode:
authorGibheer <gibheer+git@zero-knowledge.org>2022-09-10 18:45:00 +0200
committerGibheer <gibheer+git@zero-knowledge.org>2022-09-10 18:45:00 +0200
commit07a71d7b77dad8754205483dfc069fc136a26854 (patch)
tree16d59e0d7c212b4c041314d8599c40da1ad3bbff /vendor/git.zero-knowledge.org
parent31b081c06e4fb6b33d2e48bb87443509f7b2f98e (diff)
vendor all dependencies
Diffstat (limited to 'vendor/git.zero-knowledge.org')
-rw-r--r--vendor/git.zero-knowledge.org/gibheer/pki/AUTHORS3
-rw-r--r--vendor/git.zero-knowledge.org/gibheer/pki/LICENSE13
-rw-r--r--vendor/git.zero-knowledge.org/gibheer/pki/README.md7
-rw-r--r--vendor/git.zero-knowledge.org/gibheer/pki/certificate.go181
-rw-r--r--vendor/git.zero-knowledge.org/gibheer/pki/ecdsa.go142
-rw-r--r--vendor/git.zero-knowledge.org/gibheer/pki/ed25519.go119
-rw-r--r--vendor/git.zero-knowledge.org/gibheer/pki/pem_marshal.go16
-rw-r--r--vendor/git.zero-knowledge.org/gibheer/pki/rsa.go115
-rw-r--r--vendor/git.zero-knowledge.org/gibheer/pki/types.go66
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)
+ }
+)