-
Notifications
You must be signed in to change notification settings - Fork 7
/
x509.go
131 lines (108 loc) · 3.48 KB
/
x509.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Package utiltest provides testing helpers, for generating valid mock data like
// X509 certificates etc.
package utiltest
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"testing"
"time"
)
const (
// certValidityDuration is how long certificate is valid from the moment of generation.
certValidityDuration = 1 * time.Hour
)
// PKI struct holds X509 certificate and belonging RSA private key in PEM format.
type PKI struct {
Certificate string
PrivateKey string
}
// GenerateX509Certificate generates random X.509 certificate and
// returns it as string in PEM format.
func GenerateX509Certificate(t *testing.T) string {
return GeneratePKI(t).Certificate
}
// GenerateRSAPrivateKey generates RSA private key and returns it
// as string in PEM format.
func GenerateRSAPrivateKey(t *testing.T) string {
return GeneratePKI(t).PrivateKey
}
// GeneratePKCS1PrivateKey generates RSA private key in PKCS1 format,
// PEM encoded.
func GeneratePKCS1PrivateKey(t *testing.T) string {
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatalf("Failed to generate RSA key: %v", err)
}
privBytes := x509.MarshalPKCS1PrivateKey(priv)
var key bytes.Buffer
if err := pem.Encode(&key, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: privBytes}); err != nil {
t.Fatalf("Failed to write data to key.pem: %s", err)
}
return key.String()
}
// GenerateECPrivateKey generates EC private key, PEM encoded.
func GenerateECPrivateKey(t *testing.T) string {
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatalf("Failed generating ECDSA key: %v", err)
}
privBytes, err := x509.MarshalECPrivateKey(priv)
if err != nil {
t.Fatalf("Failed serializing EC private key: %v", err)
}
var key bytes.Buffer
if err := pem.Encode(&key, &pem.Block{Type: "EC PRIVATE KEY", Bytes: privBytes}); err != nil {
t.Fatalf("Failed to write data to key.pem: %s", err)
}
return key.String()
}
// GeneratePKI generates PKI struct
func GeneratePKI(t *testing.T) *PKI {
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatalf("Failed to generate RSA key: %v", err)
}
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) //nolint:gomnd
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
t.Fatalf("Failed to generate serial number: %v", err)
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"example"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(certValidityDuration),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
t.Fatalf("Failed to create certificate: %v", err)
}
var cert bytes.Buffer
if err := pem.Encode(&cert, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
t.Fatalf("Failed to write data to cert.pem: %s", err)
}
privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
if err != nil {
t.Fatalf("Unable to marshal private key: %v", err)
}
var key bytes.Buffer
if err := pem.Encode(&key, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
t.Fatalf("Failed to write data to key.pem: %s", err)
}
return &PKI{
Certificate: cert.String(),
PrivateKey: key.String(),
}
}