...

Source file src/edge-infra.dev/pkg/lib/crypto/certs/x509/x509.go

Documentation: edge-infra.dev/pkg/lib/crypto/certs/x509

     1  package x509
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/rand"
     6  	"crypto/rsa"
     7  	"crypto/x509"
     8  	"crypto/x509/pkix"
     9  	"math"
    10  	"math/big"
    11  	"net"
    12  	"time"
    13  
    14  	"k8s.io/client-go/util/keyutil"
    15  
    16  	pem "edge-infra.dev/pkg/lib/crypto/certs/pem"
    17  )
    18  
    19  type CertInfo struct {
    20  	Name         string
    21  	CommonName   string
    22  	Organization []string
    23  	DNSNames     []string
    24  	IPs          []net.IP
    25  	Usages       []x509.ExtKeyUsage
    26  }
    27  
    28  type EncodedKeyPair struct {
    29  	Key  []byte
    30  	Cert []byte
    31  }
    32  
    33  // Utility for abstracting private key creation, public cert generation, cert and key encoding and return
    34  func GenerateCertAndKey(certInfo CertInfo, caCert *x509.Certificate, caKeySigner crypto.Signer) (encodedKeyPair EncodedKeyPair, err error) {
    35  	key, err := GenPrivateKey()
    36  	if err != nil {
    37  		return
    38  	}
    39  	x509CertBytes, err := GenPublicCert(certInfo, key, caCert, caKeySigner)
    40  	if err != nil {
    41  		return
    42  	}
    43  
    44  	encodedKey, _ := keyutil.MarshalPrivateKeyToPEM(key)
    45  	encodedCert := pem.Encodex509CertAsPem(x509CertBytes)
    46  
    47  	encodedKeyPair = EncodedKeyPair{
    48  		Key:  encodedKey,
    49  		Cert: encodedCert,
    50  	}
    51  
    52  	return
    53  }
    54  
    55  // Creates RSA private key
    56  func GenPrivateKey() (crypto.Signer, error) {
    57  	return rsa.GenerateKey(rand.Reader, 2048)
    58  }
    59  
    60  // Abstracts serial number generation, x509 cert struct declaration and creation with one year expiry
    61  // Returns bytes of the x509 cert
    62  func GenPublicCert(ci CertInfo, key crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer) ([]byte, error) {
    63  	serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	notAfter := time.Now().Add(time.Hour * 24 * 365).UTC()
    69  	certTmpl := x509.Certificate{
    70  		Subject: pkix.Name{
    71  			CommonName:   ci.CommonName,
    72  			Organization: ci.Organization,
    73  		},
    74  		DNSNames:              ci.DNSNames,
    75  		IPAddresses:           ci.IPs,
    76  		SerialNumber:          serial,
    77  		NotBefore:             caCert.NotBefore,
    78  		NotAfter:              notAfter,
    79  		KeyUsage:              3,
    80  		ExtKeyUsage:           ci.Usages,
    81  		BasicConstraintsValid: true,
    82  		IsCA:                  false,
    83  	}
    84  
    85  	certDERBytes, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, key.Public(), caKey)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  	return certDERBytes, nil
    90  }
    91  

View as plain text