dockerfiles/anylink/dtls-2.0.9/pkg/crypto/selfsign/selfsign.go

104 lines
2.6 KiB
Go

// Package selfsign is a test helper that generates self signed certificate.
package selfsign
import (
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/hex"
"errors"
"math/big"
"time"
)
var errInvalidPrivateKey = errors.New("selfsign: invalid private key type")
// GenerateSelfSigned creates a self-signed certificate
func GenerateSelfSigned() (tls.Certificate, error) {
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return tls.Certificate{}, err
}
return SelfSign(priv)
}
// GenerateSelfSignedWithDNS creates a self-signed certificate
func GenerateSelfSignedWithDNS(cn string, sans ...string) (tls.Certificate, error) {
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return tls.Certificate{}, err
}
return WithDNS(priv, cn, sans...)
}
// SelfSign creates a self-signed certificate from a elliptic curve key
func SelfSign(key crypto.PrivateKey) (tls.Certificate, error) {
return WithDNS(key, hex.EncodeToString(make([]byte, 16)))
}
// WithDNS creates a self-signed certificate from a elliptic curve key
func WithDNS(key crypto.PrivateKey, cn string, sans ...string) (tls.Certificate, error) {
var (
pubKey crypto.PublicKey
maxBigInt = new(big.Int) // Max random value, a 130-bits integer, i.e 2^130 - 1
)
switch k := key.(type) {
case ed25519.PrivateKey:
pubKey = k.Public()
case *ecdsa.PrivateKey:
pubKey = k.Public()
default:
return tls.Certificate{}, errInvalidPrivateKey
}
/* #nosec */
maxBigInt.Exp(big.NewInt(2), big.NewInt(130), nil).Sub(maxBigInt, big.NewInt(1))
/* #nosec */
serialNumber, err := rand.Int(rand.Reader, maxBigInt)
if err != nil {
return tls.Certificate{}, err
}
names := []string{cn}
names = append(names, sans...)
template := x509.Certificate{
Subject: pkix.Name{
// TODO anylink
Organization: []string{cn},
OrganizationalUnit: names,
},
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageClientAuth,
x509.ExtKeyUsageServerAuth,
},
BasicConstraintsValid: true,
NotBefore: time.Now(),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
NotAfter: time.Now().AddDate(0, 1, 0),
SerialNumber: serialNumber,
Version: 2,
IsCA: true,
DNSNames: names,
}
raw, err := x509.CreateCertificate(rand.Reader, &template, &template, pubKey, key)
if err != nil {
return tls.Certificate{}, err
}
return tls.Certificate{
Certificate: [][]byte{raw},
PrivateKey: key,
Leaf: &template,
}, nil
}