This repository has been archived by the owner on Jun 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
certificate.go
103 lines (90 loc) · 2.48 KB
/
certificate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package certificates
import (
cryptorand "crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"errors"
"fmt"
"net"
"time"
)
func GetValidNotAfter(certPEM []byte) (*time.Time, error) {
block, _ := pem.Decode(certPEM)
if block == nil {
return nil, errors.New("failed to parse certificate PEM")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, err
}
return &cert.NotAfter, nil
}
func GetCSR(serviceNames []string, namespace *string, key *rsa.PrivateKey) ([]byte, error) {
subject := pkix.Name{
Organization: []string{"system:nodes"},
CommonName: fmt.Sprintf("system:node:%s.%s.svc", serviceNames[0], *namespace),
}
altNames := []string{}
for i := range serviceNames {
altNames = append(altNames,
serviceNames[i],
fmt.Sprintf("%s.%s", serviceNames[i], *namespace),
fmt.Sprintf("%s.%s.svc", serviceNames[i], *namespace),
fmt.Sprintf("%s.%s.svc.cluster", serviceNames[i], *namespace),
fmt.Sprintf("%s.%s.svc.cluster.local", serviceNames[i], *namespace))
}
ipAddresses := []net.IP{}
csr, err := generateCSR(key, &subject, altNames, ipAddresses)
if err != nil {
return nil, err
}
return csr, nil
}
func generateCSR(privateKey *rsa.PrivateKey, subject *pkix.Name, dnsSANs []string, ipSANs []net.IP) (csr []byte, err error) {
// Customize the signature for RSA keys, depending on the key size
var sigType x509.SignatureAlgorithm
keySize := privateKey.N.BitLen()
switch {
case keySize >= 4096:
sigType = x509.SHA512WithRSA
case keySize >= 3072:
sigType = x509.SHA384WithRSA
default:
sigType = x509.SHA256WithRSA
}
keyUsage, err := marshalKeyUsage(x509.KeyUsage(x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment))
if err != nil {
return nil, err
}
extKeyUsage, err := marshalExtKeyUsage([]x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, []asn1.ObjectIdentifier{})
if err != nil {
return nil, err
}
bc, err := marshalBasicConstraints(false, 0, false)
if err != nil {
return nil, err
}
template := &x509.CertificateRequest{
Subject: *subject,
SignatureAlgorithm: sigType,
DNSNames: dnsSANs,
IPAddresses: ipSANs,
ExtraExtensions: []pkix.Extension{
bc,
keyUsage,
extKeyUsage,
},
}
csr, err = x509.CreateCertificateRequest(cryptorand.Reader, template, privateKey)
if err != nil {
return nil, err
}
csrPemBlock := &pem.Block{
Type: "CERTIFICATE REQUEST",
Bytes: csr,
}
return pem.EncodeToMemory(csrPemBlock), nil
}