Switch to btcutil for certificate generation.

This commit is contained in:
Josh Rickmar 2014-01-10 15:51:54 -05:00
parent eca8914254
commit 467d976f0a

View file

@ -18,26 +18,22 @@ package main
import (
"code.google.com/p/go.net/websocket"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
_ "crypto/sha512" // for cert generation
"crypto/subtle"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/base64"
"encoding/hex"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"github.com/conformal/btcjson"
"github.com/conformal/btcutil"
"github.com/conformal/btcwallet/wallet"
"github.com/conformal/btcws"
"github.com/conformal/go-socks"
"math/big"
"io/ioutil"
"net"
"net/http"
"os"
@ -124,7 +120,7 @@ func newServer(listenAddrs []string) (*server, error) {
// Check for existence of cert file and key file
if !fileExists(cfg.RPCKey) && !fileExists(cfg.RPCCert) {
// if both files do not exist, we generate them.
err := genKey(cfg.RPCKey, cfg.RPCCert)
err := genCertPair(cfg.RPCKey, cfg.RPCCert)
if err != nil {
return nil, err
}
@ -169,94 +165,27 @@ func newServer(listenAddrs []string) (*server, error) {
return &s, nil
}
// genkey generates a key/cert pair to the paths provided.
// TODO(oga) wrap errors with fmt.Errorf for more context?
func genKey(key, cert string) error {
// genCertPair generates a key/cert pair to the paths provided.
func genCertPair(certFile, keyFile string) error {
log.Infof("Generating TLS certificates...")
priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
org := "btcwallet autogenerated cert"
validUntil := time.Now().Add(10 * 365 * 24 * time.Hour)
cert, key, err := btcutil.NewTLSCertPair(org, validUntil, nil)
if err != nil {
return err
}
notBefore := time.Now()
notAfter := notBefore.Add(10 * 365 * 24 * time.Hour)
// end of ASN.1 time
endOfTime := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC)
if notAfter.After(endOfTime) {
notAfter = endOfTime
}
template := x509.Certificate{
SerialNumber: new(big.Int).SetInt64(0),
Subject: pkix.Name{
Organization: []string{"btcwallet autogenerated cert"},
},
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
IsCA: true, // so can sign self.
BasicConstraintsValid: true,
}
host, err := os.Hostname()
if err != nil {
// Write cert and key files.
if err = ioutil.WriteFile(certFile, cert, 0666); err != nil {
return err
}
template.DNSNames = append(template.DNSNames, host, "localhost")
needLocalhost := true
addrs, err := net.InterfaceAddrs()
if err != nil {
if err = ioutil.WriteFile(keyFile, key, 0600); err != nil {
os.Remove(certFile)
return err
}
for _, a := range addrs {
ip, _, err := net.ParseCIDR(a.String())
if err == nil {
if ip.String() == "127.0.0.1" {
needLocalhost = false
}
template.IPAddresses = append(template.IPAddresses, ip)
}
}
if needLocalhost {
localHost := net.ParseIP("127.0.0.1")
template.IPAddresses = append(template.IPAddresses, localHost)
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template,
&template, &priv.PublicKey, priv)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create certificate: %v\n", err)
os.Exit(-1)
}
certOut, err := os.Create(cert)
if err != nil {
return err
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
certOut.Close()
keyOut, err := os.OpenFile(key, os.O_WRONLY|os.O_CREATE|os.O_TRUNC,
0600)
if err != nil {
os.Remove(cert)
return err
}
keybytes, err := x509.MarshalECPrivateKey(priv)
if err != nil {
os.Remove(key)
os.Remove(cert)
return err
}
pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: keybytes})
keyOut.Close()
log.Info("Done generating TLS certificates")
log.Infof("Done generating TLS certificates")
return nil
}