-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
cert.go
140 lines (124 loc) · 4.51 KB
/
cert.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
package tls
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"os"
"strconv"
"time"
"github.com/bettercap/bettercap/session"
)
type CertConfig struct {
Bits int
Country string
Locality string
Organization string
OrganizationalUnit string
CommonName string
}
var (
DefaultLegitConfig = CertConfig{
Bits: 4096,
Country: "US",
Locality: "",
Organization: "bettercap devteam",
OrganizationalUnit: "https://bettercap.org/",
CommonName: "bettercap",
}
DefaultSpoofConfig = CertConfig{
Bits: 4096,
Country: "US",
Locality: "Scottsdale",
Organization: "GoDaddy.com, Inc.",
OrganizationalUnit: "https://certs.godaddy.com/repository/",
CommonName: "Go Daddy Secure Certificate Authority - G2",
}
)
func CertConfigToModule(prefix string, m *session.SessionModule, defaults CertConfig) {
m.AddParam(session.NewIntParameter(prefix+".certificate.bits", strconv.Itoa(defaults.Bits),
"Number of bits of the RSA private key of the generated HTTPS certificate."))
m.AddParam(session.NewStringParameter(prefix+".certificate.country", defaults.Country, ".*",
"Country field of the generated HTTPS certificate."))
m.AddParam(session.NewStringParameter(prefix+".certificate.locality", defaults.Locality, ".*",
"Locality field of the generated HTTPS certificate."))
m.AddParam(session.NewStringParameter(prefix+".certificate.organization", defaults.Organization, ".*",
"Organization field of the generated HTTPS certificate."))
m.AddParam(session.NewStringParameter(prefix+".certificate.organizationalunit", defaults.OrganizationalUnit, ".*",
"Organizational Unit field of the generated HTTPS certificate."))
m.AddParam(session.NewStringParameter(prefix+".certificate.commonname", defaults.CommonName, ".*",
"Common Name field of the generated HTTPS certificate."))
}
func CertConfigFromModule(prefix string, m session.SessionModule) (err error, cfg CertConfig) {
if err, cfg.Bits = m.IntParam(prefix + ".certificate.bits"); err != nil {
return err, cfg
} else if err, cfg.Country = m.StringParam(prefix + ".certificate.country"); err != nil {
return err, cfg
} else if err, cfg.Locality = m.StringParam(prefix + ".certificate.locality"); err != nil {
return err, cfg
} else if err, cfg.Organization = m.StringParam(prefix + ".certificate.organization"); err != nil {
return err, cfg
} else if err, cfg.OrganizationalUnit = m.StringParam(prefix + ".certificate.organizationalunit"); err != nil {
return err, cfg
} else if err, cfg.CommonName = m.StringParam(prefix + ".certificate.commonname"); err != nil {
return err, cfg
}
return nil, cfg
}
func CreateCertificate(cfg CertConfig) (error, *rsa.PrivateKey, []byte) {
priv, err := rsa.GenerateKey(rand.Reader, cfg.Bits)
if err != nil {
return err, nil, nil
}
notBefore := time.Now()
aYear := time.Duration(365*24) * time.Hour
notAfter := notBefore.Add(aYear)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return err, nil, nil
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Country: []string{cfg.Country},
Locality: []string{cfg.Locality},
Organization: []string{cfg.Organization},
OrganizationalUnit: []string{cfg.OrganizationalUnit},
CommonName: cfg.CommonName,
},
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
IsCA: true,
}
cert, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
return err, nil, nil
}
return nil, priv, cert
}
func Generate(cfg CertConfig, certPath string, keyPath string) error {
keyFile, err := os.Create(keyPath)
if err != nil {
return err
}
defer keyFile.Close()
certFile, err := os.Create(certPath)
if err != nil {
return err
}
defer certFile.Close()
err, priv, cert := CreateCertificate(cfg)
if err != nil {
return err
}
if err := pem.Encode(keyFile, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}); err != nil {
return err
}
return pem.Encode(certFile, &pem.Block{Type: "CERTIFICATE", Bytes: cert})
}