Skip to content

Commit 75e74c7

Browse files
committed
Merge pull request #42 from arduino/certificates
Certificates
2 parents 6e1d110 + 647db95 commit 75e74c7

File tree

2 files changed

+96
-47
lines changed

2 files changed

+96
-47
lines changed

certificates.go

+88-40
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,21 @@ import (
1616
"crypto/x509/pkix"
1717
"encoding/pem"
1818
"fmt"
19-
log "github.com/Sirupsen/logrus"
2019
"io/ioutil"
2120
"math/big"
2221
"net"
2322
"os"
2423
"strings"
2524
"time"
25+
26+
log "github.com/Sirupsen/logrus"
2627
)
2728

2829
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
3534
)
3635

3736
func publicKey(priv interface{}) interface{} {
@@ -61,37 +60,32 @@ func pemBlockForKey(priv interface{}) *pem.Block {
6160
}
6261
}
6362

64-
func generateCertificates() {
65-
66-
var priv interface{}
67-
var err error
63+
func generateKey(ecdsaCurve string) (interface{}, error) {
6864
switch ecdsaCurve {
6965
case "":
70-
priv, err = rsa.GenerateKey(rand.Reader, rsaBits)
66+
return rsa.GenerateKey(rand.Reader, rsaBits)
7167
case "P224":
72-
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
68+
return ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
7369
case "P256":
74-
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
70+
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
7571
case "P384":
76-
priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
72+
return ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
7773
case "P521":
78-
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
74+
return ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
7975
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)
8577
}
78+
}
8679

80+
func generateSingleCertificate(isCa bool) (*x509.Certificate, error) {
8781
var notBefore time.Time
82+
var err error
8883
if len(validFrom) == 0 {
8984
notBefore = time.Now()
9085
} else {
9186
notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom)
9287
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())
9589
}
9690
}
9791

@@ -100,7 +94,7 @@ func generateCertificates() {
10094
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
10195
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
10296
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())
10498
}
10599

106100
template := x509.Certificate{
@@ -128,37 +122,91 @@ func generateCertificates() {
128122
}
129123
}
130124

131-
if isCA {
125+
if isCa {
132126
template.IsCA = true
133127
template.KeyUsage |= x509.KeyUsageCertSign
134128
}
135129

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() {
140134

141-
// remove old certificates
135+
os.Remove("ca.cert.pem")
136+
os.Remove("ca.key.pem")
142137
os.Remove("cert.pem")
143138
os.Remove("key.pem")
144-
os.Remove("cert.cer")
145139

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)
147148
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)
149170
}
150171
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
151172
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")
153177

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+
}
155184

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)
157186
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)
160189
}
161-
pem.Encode(keyOut, pemBlockForKey(priv))
190+
pem.Encode(keyOut, pemBlockForKey(key))
162191
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")
164212
}

main.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@ package main
55

66
import (
77
"flag"
8-
log "github.com/Sirupsen/logrus"
9-
"github.com/carlescere/scheduler"
10-
"github.com/gin-gonic/gin"
11-
"github.com/itsjamie/gin-cors"
12-
"github.com/kardianos/osext"
13-
"github.com/vharitonsky/iniflags"
148
"os"
159
"os/user"
1610
"path/filepath"
1711
"runtime/debug"
1812
"strconv"
1913
"text/template"
2014
"time"
15+
16+
log "github.com/Sirupsen/logrus"
17+
"github.com/carlescere/scheduler"
18+
"github.com/gin-gonic/gin"
19+
"github.com/itsjamie/gin-cors"
20+
"github.com/kardianos/osext"
21+
"github.com/vharitonsky/iniflags"
2122
//"github.com/sanbornm/go-selfupdate/selfupdate" #included in update.go to change heavily
2223
)
2324

@@ -399,7 +400,7 @@ body {
399400
<input type="submit" value="Send" />
400401
<input type="text" id="msg" size="64"/>
401402
<input name="pause" type="checkbox" value="pause" id="myCheck"/> Pause
402-
<input type="button" value="Install Certificate" onclick="window.open('http://localhost:8991/certificate.crt')" />
403+
<!--<input type="button" value="Install Certificate" onclick="window.open('http://localhost:8991/certificate.crt')" />-->
403404
</form>
404405
</form>
405406
</body>

0 commit comments

Comments
 (0)