Skip to content

Commit 32c9876

Browse files
committed
Move certificate generation code into its own package
1 parent 40a6d51 commit 32c9876

File tree

2 files changed

+106
-104
lines changed

2 files changed

+106
-104
lines changed
Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* Copyright (c) 2020 Ameya Lokare
33
*/
4-
package main
4+
package certutil
55

66
import (
77
"crypto"
@@ -16,14 +16,15 @@ import (
1616
"github.com/juggernaut/webhook-sentry/proxy"
1717
"math/big"
1818
"net"
19+
"testing"
1920
"time"
2021
)
2122

22-
func generateKeyPair() (crypto.PrivateKey, error) {
23+
func GenerateKeyPair() (crypto.PrivateKey, error) {
2324
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
2425
}
2526

26-
func generateCertificate(hostname string, organizationName string, key crypto.PrivateKey, notBefore time.Time, notAfter time.Time, issuerCertificate *x509.Certificate, issuerPrivateKey crypto.PrivateKey, isClientCert bool, isCA bool) ([]byte, error) {
27+
func GenerateCertificate(hostname string, organizationName string, key crypto.PrivateKey, notBefore time.Time, notAfter time.Time, issuerCertificate *x509.Certificate, issuerPrivateKey crypto.PrivateKey, isClientCert bool, isCA bool) ([]byte, error) {
2728

2829
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
2930
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
@@ -86,14 +87,14 @@ func generateCertificate(hostname string, organizationName string, key crypto.Pr
8687
return x509.CreateCertificate(rand.Reader, &template, issuerTemplate, proxy.PublicKey(key), issuerPrivateKey)
8788
}
8889

89-
func generateRootCACert() (crypto.PrivateKey, *x509.Certificate, error) {
90-
key, err := generateKeyPair()
90+
func GenerateRootCACert() (crypto.PrivateKey, *x509.Certificate, error) {
91+
key, err := GenerateKeyPair()
9192
if err != nil {
9293
return nil, nil, err
9394
}
9495
notBefore := time.Now().Add(time.Duration(-1) * time.Hour)
9596
notAfter := time.Now().Add(time.Duration(1) * time.Hour)
96-
certBytes, err := generateCertificate("wh-sentry-root.com", "WH Sentry Root", key, notBefore, notAfter, nil, nil, true, true)
97+
certBytes, err := GenerateCertificate("wh-sentry-root.com", "WH Sentry Root", key, notBefore, notAfter, nil, nil, true, true)
9798
if err != nil {
9899
return nil, nil, err
99100
}
@@ -104,15 +105,15 @@ func generateRootCACert() (crypto.PrivateKey, *x509.Certificate, error) {
104105
return key, cert, nil
105106
}
106107

107-
func generateLeafCert(hostname string, organizationName string, issuerCert *x509.Certificate, issuerKey crypto.PrivateKey, isClient bool) (*tls.Certificate, error) {
108-
key, err := generateKeyPair()
108+
func GenerateLeafCert(hostname string, organizationName string, issuerCert *x509.Certificate, issuerKey crypto.PrivateKey, isClient bool) (*tls.Certificate, error) {
109+
key, err := GenerateKeyPair()
109110
if err != nil {
110111
return nil, err
111112
}
112113
notBefore := time.Now().Add(time.Duration(-1) * time.Minute)
113114
notAfter := time.Now().Add(time.Duration(30) * time.Minute)
114115

115-
derBytes, err := generateCertificate(hostname, organizationName, key, notBefore, notAfter, issuerCert, issuerKey, isClient, false)
116+
derBytes, err := GenerateCertificate(hostname, organizationName, key, notBefore, notAfter, issuerCert, issuerKey, isClient, false)
116117
if err != nil {
117118
return nil, err
118119
}
@@ -128,7 +129,7 @@ func generateLeafCert(hostname string, organizationName string, issuerCert *x509
128129
return &cert, err
129130
}
130131

131-
func x509ToTLSCertificate(x509Cert *x509.Certificate, privateKey crypto.PrivateKey) (*tls.Certificate, error) {
132+
func X509ToTLSCertificate(x509Cert *x509.Certificate, privateKey crypto.PrivateKey) (*tls.Certificate, error) {
132133
certPemBytes := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: x509Cert.Raw})
133134

134135
privKeyBytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
@@ -139,3 +140,57 @@ func x509ToTLSCertificate(x509Cert *x509.Certificate, privateKey crypto.PrivateK
139140
cert, err := tls.X509KeyPair(certPemBytes, privKeyPemBytes)
140141
return &cert, err
141142
}
143+
144+
type CertificateFixtures struct {
145+
RootCAs *x509.CertPool
146+
RootCAPrivateKey crypto.PrivateKey
147+
RootCACert *tls.Certificate
148+
ProxyCert *tls.Certificate
149+
ServerCert *tls.Certificate
150+
InvalidHostnameServerCert *tls.Certificate
151+
ClientCert *tls.Certificate
152+
}
153+
154+
func NewCertificateFixtures(t *testing.T) *CertificateFixtures {
155+
rootCertKey, rootCert, err := GenerateRootCACert()
156+
if err != nil {
157+
t.Fatalf("Error generating root CA cert: %s", err)
158+
}
159+
certPool := x509.NewCertPool()
160+
certPool.AddCert(rootCert)
161+
162+
rootCACert, err := X509ToTLSCertificate(rootCert, rootCertKey)
163+
if err != nil {
164+
t.Fatalf("Error converting x509 to TLS certificate: %s", err)
165+
}
166+
167+
serverCert, err := GenerateLeafCert("localhost", "WH Sentry Test Server", rootCert, rootCertKey, false)
168+
if err != nil {
169+
t.Fatalf("Error generating server cert: %s", err)
170+
}
171+
172+
invalidHostnameServerCert, err := GenerateLeafCert("wh-target-server.com", "WH Sentry Test Server", rootCert, rootCertKey, false)
173+
if err != nil {
174+
t.Fatalf("Error generating server cert: %s", err)
175+
}
176+
177+
proxyCert, err := GenerateLeafCert("127.0.0.1", "WH Sentry Proxy", rootCert, rootCertKey, false)
178+
if err != nil {
179+
t.Fatalf("Error generating server cert: %s", err)
180+
}
181+
182+
clientCert, err := GenerateLeafCert("wh-client.com", "WH Sentry Client", rootCert, rootCertKey, true)
183+
if err != nil {
184+
t.Fatalf("Error generating client cert: %s", err)
185+
}
186+
return &CertificateFixtures{
187+
RootCAs: certPool,
188+
RootCAPrivateKey: rootCertKey,
189+
RootCACert: rootCACert,
190+
ServerCert: serverCert,
191+
InvalidHostnameServerCert: invalidHostnameServerCert,
192+
ProxyCert: proxyCert,
193+
ClientCert: clientCert,
194+
}
195+
}
196+

0 commit comments

Comments
 (0)