...
1
16
17 package utils
18
19 import (
20 "crypto"
21 cryptorand "crypto/rand"
22 "crypto/rsa"
23 "crypto/x509"
24 "crypto/x509/pkix"
25 "encoding/pem"
26 "fmt"
27 "math"
28 "math/big"
29 "time"
30
31 certutil "k8s.io/client-go/util/cert"
32 )
33
34 const (
35 certificateBlockType = "CERTIFICATE"
36 rsaKeySize = 2048
37 duration365d = time.Hour * 24 * 365
38 )
39
40
41 func NewPrivateKey() (*rsa.PrivateKey, error) {
42 return rsa.GenerateKey(cryptorand.Reader, rsaKeySize)
43 }
44
45
46 func EncodeCertPEM(cert *x509.Certificate) []byte {
47 block := pem.Block{
48 Type: certificateBlockType,
49 Bytes: cert.Raw,
50 }
51 return pem.EncodeToMemory(&block)
52 }
53
54
55 func NewSignedCert(cfg *certutil.Config, key crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer) (*x509.Certificate, error) {
56
57 serial, err := cryptorand.Int(cryptorand.Reader, new(big.Int).SetInt64(math.MaxInt64-1))
58 if err != nil {
59 return nil, err
60 }
61 serial = new(big.Int).Add(serial, big.NewInt(1))
62 if len(cfg.CommonName) == 0 {
63 return nil, fmt.Errorf("must specify a CommonName")
64 }
65 if len(cfg.Usages) == 0 {
66 return nil, fmt.Errorf("must specify at least one ExtKeyUsage")
67 }
68
69 certTmpl := x509.Certificate{
70 Subject: pkix.Name{
71 CommonName: cfg.CommonName,
72 Organization: cfg.Organization,
73 },
74 DNSNames: cfg.AltNames.DNSNames,
75 IPAddresses: cfg.AltNames.IPs,
76 SerialNumber: serial,
77 NotBefore: caCert.NotBefore,
78 NotAfter: time.Now().Add(duration365d).UTC(),
79 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
80 ExtKeyUsage: cfg.Usages,
81 }
82 certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &certTmpl, caCert, key.Public(), caKey)
83 if err != nil {
84 return nil, err
85 }
86 return x509.ParseCertificate(certDERBytes)
87 }
88
View as plain text