-
Notifications
You must be signed in to change notification settings - Fork 43
/
tlshelp.go
145 lines (124 loc) · 3.68 KB
/
tlshelp.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"log"
"math/big"
"time"
)
import "crypto/tls"
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
// RandString generates random string of n size
// It returns the generated random string.and any write error encountered.
func RandString(n int) string {
r := make([]byte, n)
_, err := rand.Read(r)
if err != nil {
return ""
}
b := make([]byte, n)
l := len(letters)
for i := range b {
b[i] = letters[int(r[i])%l]
}
return string(b)
}
// RandBytes generates random bytes of n size
// It returns the generated random bytes
func RandBytes(n int) []byte {
r := make([]byte, n)
_, err := rand.Read(r)
if err != nil {
}
return r
}
// RandBigInt generates random big integer with max number
// It returns the generated random big integer
func RandBigInt(max *big.Int) *big.Int {
r, _ := rand.Int(rand.Reader, max)
return r
}
func genPair(keysize int) (cacert []byte, cakey []byte, cert []byte, certkey []byte) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
ca := &x509.Certificate{
SerialNumber: RandBigInt(serialNumberLimit),
Subject: pkix.Name{
Country: []string{RandString(16)},
Organization: []string{RandString(16)},
OrganizationalUnit: []string{RandString(16)},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
SubjectKeyId: RandBytes(5),
BasicConstraintsValid: true,
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
}
priv, _ := rsa.GenerateKey(rand.Reader, keysize)
pub := &priv.PublicKey
caBin, err := x509.CreateCertificate(rand.Reader, ca, ca, pub, priv)
if err != nil {
log.Println("create ca failed", err)
return
}
cert2 := &x509.Certificate{
SerialNumber: RandBigInt(serialNumberLimit),
Subject: pkix.Name{
Country: []string{RandString(16)},
Organization: []string{RandString(16)},
OrganizationalUnit: []string{RandString(16)},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
SubjectKeyId: RandBytes(6),
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
}
priv2, _ := rsa.GenerateKey(rand.Reader, keysize)
pub2 := &priv2.PublicKey
cert2Bin, err2 := x509.CreateCertificate(rand.Reader, cert2, ca, pub2, priv)
if err2 != nil {
log.Println("create cert2 failed", err2)
return
}
privBin := x509.MarshalPKCS1PrivateKey(priv)
priv2Bin := x509.MarshalPKCS1PrivateKey(priv2)
return caBin, privBin, cert2Bin, priv2Bin
}
func verifyCert(cacert []byte, cert []byte) bool {
caBin, _ := x509.ParseCertificate(cacert)
cert2Bin, _ := x509.ParseCertificate(cert)
err3 := cert2Bin.CheckSignatureFrom(caBin)
if err3 != nil {
return false
}
return true
}
func getPEMs(cert []byte, key []byte) (pemcert []byte, pemkey []byte) {
certPem := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: cert,
})
keyPem := pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: key,
})
return certPem, keyPem
}
func getTLSPair(certPem []byte, keyPem []byte) (tls.Certificate, error) {
tlspair, errt := tls.X509KeyPair(certPem, keyPem)
if errt != nil {
return tlspair, errt
}
return tlspair, nil
}
func getRandomTLS(keysize int) (tls.Certificate, error) {
_, _, cert, certkey := genPair(keysize)
certPem, keyPem := getPEMs(cert, certkey)
tlspair, err := getTLSPair(certPem, keyPem)
return tlspair, err
}