@@ -16,22 +16,21 @@ import (
16
16
"crypto/x509/pkix"
17
17
"encoding/pem"
18
18
"fmt"
19
- log "github.com/Sirupsen/logrus"
20
19
"io/ioutil"
21
20
"math/big"
22
21
"net"
23
22
"os"
24
23
"strings"
25
24
"time"
25
+
26
+ log "github.com/Sirupsen/logrus"
26
27
)
27
28
28
29
var (
29
- host = "localhost"
30
- validFrom = ""
31
- validFor = 365 * 24 * time .Hour * 2 // 2 years
32
- isCA = true
33
- rsaBits = 2048
34
- ecdsaCurve = ""
30
+ host = "localhost"
31
+ validFrom = ""
32
+ validFor = 365 * 24 * time .Hour * 2 // 2 years
33
+ rsaBits = 2048
35
34
)
36
35
37
36
func publicKey (priv interface {}) interface {} {
@@ -61,37 +60,32 @@ func pemBlockForKey(priv interface{}) *pem.Block {
61
60
}
62
61
}
63
62
64
- func generateCertificates () {
65
-
66
- var priv interface {}
67
- var err error
63
+ func generateKey (ecdsaCurve string ) (interface {}, error ) {
68
64
switch ecdsaCurve {
69
65
case "" :
70
- priv , err = rsa .GenerateKey (rand .Reader , rsaBits )
66
+ return rsa .GenerateKey (rand .Reader , rsaBits )
71
67
case "P224" :
72
- priv , err = ecdsa .GenerateKey (elliptic .P224 (), rand .Reader )
68
+ return ecdsa .GenerateKey (elliptic .P224 (), rand .Reader )
73
69
case "P256" :
74
- priv , err = ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
70
+ return ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
75
71
case "P384" :
76
- priv , err = ecdsa .GenerateKey (elliptic .P384 (), rand .Reader )
72
+ return ecdsa .GenerateKey (elliptic .P384 (), rand .Reader )
77
73
case "P521" :
78
- priv , err = ecdsa .GenerateKey (elliptic .P521 (), rand .Reader )
74
+ return ecdsa .GenerateKey (elliptic .P521 (), rand .Reader )
79
75
default :
80
- fmt .Fprintf (os .Stderr , "Unrecognized elliptic curve: %q" , ecdsaCurve )
81
- os .Exit (1 )
82
- }
83
- if err != nil {
84
- log .Fatalf ("failed to generate private key: %s" , err )
76
+ return nil , fmt .Errorf ("Unrecognized elliptic curve: %q" , ecdsaCurve )
85
77
}
78
+ }
86
79
80
+ func generateSingleCertificate (isCa bool ) (* x509.Certificate , error ) {
87
81
var notBefore time.Time
82
+ var err error
88
83
if len (validFrom ) == 0 {
89
84
notBefore = time .Now ()
90
85
} else {
91
86
notBefore , err = time .Parse ("Jan 2 15:04:05 2006" , validFrom )
92
87
if err != nil {
93
- fmt .Fprintf (os .Stderr , "Failed to parse creation date: %s\n " , err )
94
- os .Exit (1 )
88
+ return nil , fmt .Errorf ("Failed to parse creation date: %s\n " , err .Error ())
95
89
}
96
90
}
97
91
@@ -100,7 +94,7 @@ func generateCertificates() {
100
94
serialNumberLimit := new (big.Int ).Lsh (big .NewInt (1 ), 128 )
101
95
serialNumber , err := rand .Int (rand .Reader , serialNumberLimit )
102
96
if err != nil {
103
- log . Fatalf ("failed to generate serial number: %s" , err )
97
+ return nil , fmt . Errorf ("failed to generate serial number: %s\n " , err . Error () )
104
98
}
105
99
106
100
template := x509.Certificate {
@@ -128,37 +122,91 @@ func generateCertificates() {
128
122
}
129
123
}
130
124
131
- if isCA {
125
+ if isCa {
132
126
template .IsCA = true
133
127
template .KeyUsage |= x509 .KeyUsageCertSign
134
128
}
135
129
136
- derBytes , err := x509 . CreateCertificate ( rand . Reader , & template , & template , publicKey ( priv ), priv )
137
- if err != nil {
138
- log . Fatalf ( "Failed to create certificate: %s" , err )
139
- }
130
+ return & template , nil
131
+ }
132
+
133
+ func generateCertificates () {
140
134
141
- // remove old certificates
135
+ os .Remove ("ca.cert.pem" )
136
+ os .Remove ("ca.key.pem" )
142
137
os .Remove ("cert.pem" )
143
138
os .Remove ("key.pem" )
144
- os .Remove ("cert.cer" )
145
139
146
- certOut , err := os .Create ("cert.pem" )
140
+ // Create the key for the certification authority
141
+ caKey , err := generateKey ("" )
142
+ if err != nil {
143
+ log .Error (err .Error ())
144
+ os .Exit (1 )
145
+ }
146
+
147
+ keyOut , err := os .OpenFile ("ca.key.pem" , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , 0600 )
147
148
if err != nil {
148
- log .Fatalf ("failed to open cert.pem for writing: %s" , err )
149
+ log .Error (err .Error ())
150
+ os .Exit (1 )
151
+ }
152
+ pem .Encode (keyOut , pemBlockForKey (caKey ))
153
+ keyOut .Close ()
154
+ log .Println ("written ca.key.pem" )
155
+
156
+ // Create the certification authority
157
+ caTemplate , err := generateSingleCertificate (true )
158
+
159
+ if err != nil {
160
+ log .Error (err .Error ())
161
+ os .Exit (1 )
162
+ }
163
+
164
+ derBytes , err := x509 .CreateCertificate (rand .Reader , caTemplate , caTemplate , publicKey (caKey ), caKey )
165
+
166
+ certOut , err := os .Create ("ca.cert.pem" )
167
+ if err != nil {
168
+ log .Error (err .Error ())
169
+ os .Exit (1 )
149
170
}
150
171
pem .Encode (certOut , & pem.Block {Type : "CERTIFICATE" , Bytes : derBytes })
151
172
certOut .Close ()
152
- log .Print ("written cert.pem\n " )
173
+ log .Print ("written ca.cert.pem" )
174
+
175
+ ioutil .WriteFile ("ca.cert.cer" , derBytes , 0644 )
176
+ log .Print ("written ca.cert.cer" )
153
177
154
- ioutil .WriteFile ("cert.cer" , derBytes , 0644 )
178
+ // Create the key for the final certificate
179
+ key , err := generateKey ("" )
180
+ if err != nil {
181
+ log .Error (err .Error ())
182
+ os .Exit (1 )
183
+ }
155
184
156
- keyOut , err : = os .OpenFile ("key.pem" , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , 0600 )
185
+ keyOut , err = os .OpenFile ("key.pem" , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , 0600 )
157
186
if err != nil {
158
- log .Print ( "failed to open key.pem for writing:" , err )
159
- return
187
+ log .Error ( err . Error () )
188
+ os . Exit ( 1 )
160
189
}
161
- pem .Encode (keyOut , pemBlockForKey (priv ))
190
+ pem .Encode (keyOut , pemBlockForKey (key ))
162
191
keyOut .Close ()
163
- log .Print ("written key.pem\n " )
192
+ log .Println ("written key.pem" )
193
+
194
+ // Create the final certificate
195
+ template , err := generateSingleCertificate (false )
196
+
197
+ if err != nil {
198
+ log .Error (err .Error ())
199
+ os .Exit (1 )
200
+ }
201
+
202
+ derBytes , err = x509 .CreateCertificate (rand .Reader , template , caTemplate , publicKey (key ), caKey )
203
+
204
+ certOut , err = os .Create ("cert.pem" )
205
+ if err != nil {
206
+ log .Error (err .Error ())
207
+ os .Exit (1 )
208
+ }
209
+ pem .Encode (certOut , & pem.Block {Type : "CERTIFICATE" , Bytes : derBytes })
210
+ certOut .Close ()
211
+ log .Print ("written cert.pem" )
164
212
}
0 commit comments