11/**
22* Copyright (c) 2020 Ameya Lokare
33*/
4- package main
4+ package certutil
55
66import (
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