0
0
Fork 0

vendor all dependencies

This commit is contained in:
Gibheer 2022-09-10 18:45:00 +02:00
parent 31b081c06e
commit 07a71d7b77
12 changed files with 672 additions and 0 deletions

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module git.zero-knowledge.org/gibheer/pkictl
go 1.19
require git.zero-knowledge.org/gibheer/pki v0.0.0-20220815203810-d34a8ab26ec7

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
git.zero-knowledge.org/gibheer/pki v0.0.0-20220815203810-d34a8ab26ec7 h1:SFuERGJkxqBaWO+eNl4OuTsMNOoQjsC9OWKnTbOUkD4=
git.zero-knowledge.org/gibheer/pki v0.0.0-20220815203810-d34a8ab26ec7/go.mod h1:N0SOjUNlgYkDYBadg/Q5NjyA0Ee2w0rLf8bfsX3kzyE=

3
vendor/git.zero-knowledge.org/gibheer/pki/AUTHORS generated vendored Normal file
View File

@ -0,0 +1,3 @@
This is the list of contributors to this project:
* Stefan Radomski

13
vendor/git.zero-knowledge.org/gibheer/pki/LICENSE generated vendored Normal file
View File

@ -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.

7
vendor/git.zero-knowledge.org/gibheer/pki/README.md generated vendored Normal file
View File

@ -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)

View File

@ -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
}

142
vendor/git.zero-knowledge.org/gibheer/pki/ecdsa.go generated vendored Normal file
View File

@ -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
}

119
vendor/git.zero-knowledge.org/gibheer/pki/ed25519.go generated vendored Normal file
View File

@ -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
}

View File

@ -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
}

115
vendor/git.zero-knowledge.org/gibheer/pki/rsa.go generated vendored Normal file
View File

@ -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
}

66
vendor/git.zero-knowledge.org/gibheer/pki/types.go generated vendored Normal file
View File

@ -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)
}
)

3
vendor/modules.txt vendored Normal file
View File

@ -0,0 +1,3 @@
# git.zero-knowledge.org/gibheer/pki v0.0.0-20220815203810-d34a8ab26ec7
## explicit; go 1.19
git.zero-knowledge.org/gibheer/pki