Updates certificate signing code

This seems to have fixed the SEC_ERROR_REUSED_ISSUER_AND_SERIAL error I
was getting in firefox.

I have taken the code from the goproxy project.

https://github.com/elazarl/goproxy/issues/311
master
Jonathan Hodgson 5 years ago
parent bdb2d4db79
commit aa1517a820
  1. 57
      signer.go

@ -36,8 +36,11 @@ https://github.com/elazarl/goproxy
*/ */
import ( import (
"crypto"
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rsa" "crypto/rsa"
"crypto/sha1" "crypto/sha1"
"crypto/sha256" "crypto/sha256"
@ -45,7 +48,9 @@ import (
"crypto/x509" "crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
"errors" "errors"
"fmt"
"math/big" "math/big"
"math/rand"
"net" "net"
"runtime" "runtime"
"sort" "sort"
@ -56,20 +61,24 @@ import (
counterecryptor.go counterecryptor.go
*/ */
type counterEncryptorRand struct { type CounterEncryptorRand struct {
cipher cipher.Block cipher cipher.Block
counter []byte counter []byte
rand []byte rand []byte
ix int ix int
} }
func newCounterEncryptorRandFromKey(key interface{}, seed []byte) (r counterEncryptorRand, err error) { func NewCounterEncryptorRandFromKey(key interface{}, seed []byte) (r CounterEncryptorRand, err error) {
var keyBytes []byte var keyBytes []byte
switch key := key.(type) { switch key := key.(type) {
case *rsa.PrivateKey: case *rsa.PrivateKey:
keyBytes = x509.MarshalPKCS1PrivateKey(key) keyBytes = x509.MarshalPKCS1PrivateKey(key)
case *ecdsa.PrivateKey:
if keyBytes, err = x509.MarshalECPrivateKey(key); err != nil {
return
}
default: default:
err = errors.New("only RSA keys supported") err = errors.New("only RSA and ECDSA keys supported")
return return
} }
h := sha256.New() h := sha256.New()
@ -85,14 +94,14 @@ func newCounterEncryptorRandFromKey(key interface{}, seed []byte) (r counterEncr
return return
} }
func (c *counterEncryptorRand) Seed(b []byte) { func (c *CounterEncryptorRand) Seed(b []byte) {
if len(b) != len(c.counter) { if len(b) != len(c.counter) {
panic("SetCounter: wrong counter size") panic("SetCounter: wrong counter size")
} }
copy(c.counter, b) copy(c.counter, b)
} }
func (c *counterEncryptorRand) refill() { func (c *CounterEncryptorRand) refill() {
c.cipher.Encrypt(c.rand, c.counter) c.cipher.Encrypt(c.rand, c.counter)
for i := 0; i < len(c.counter); i++ { for i := 0; i < len(c.counter); i++ {
if c.counter[i]++; c.counter[i] != 0 { if c.counter[i]++; c.counter[i] != 0 {
@ -102,7 +111,7 @@ func (c *counterEncryptorRand) refill() {
c.ix = 0 c.ix = 0
} }
func (c *counterEncryptorRand) Read(b []byte) (n int, err error) { func (c *CounterEncryptorRand) Read(b []byte) (n int, err error) {
if c.ix == len(c.rand) { if c.ix == len(c.rand) {
c.refill() c.refill()
} }
@ -149,9 +158,8 @@ func signHost(ca tls.Certificate, hosts []string) (cert tls.Certificate, err err
if err != nil { if err != nil {
panic(err) panic(err)
} }
hash := hashSorted(append(hosts, goproxySignerVersion, ":"+runtime.Version()))
serial := new(big.Int) serial := big.NewInt(rand.Int63())
serial.SetBytes(hash)
template := x509.Certificate{ template := x509.Certificate{
// TODO(elazar): instead of this ugly hack, just encode the certificate and hash the binary form. // TODO(elazar): instead of this ugly hack, just encode the certificate and hash the binary form.
SerialNumber: serial, SerialNumber: serial,
@ -171,18 +179,32 @@ func signHost(ca tls.Certificate, hosts []string) (cert tls.Certificate, err err
template.IPAddresses = append(template.IPAddresses, ip) template.IPAddresses = append(template.IPAddresses, ip)
} else { } else {
template.DNSNames = append(template.DNSNames, h) template.DNSNames = append(template.DNSNames, h)
template.Subject.CommonName = h
} }
} }
var csprng counterEncryptorRand
if csprng, err = newCounterEncryptorRandFromKey(ca.PrivateKey, hash); err != nil { hash := hashSorted(append(hosts, goproxySignerVersion, ":"+runtime.Version()))
var csprng CounterEncryptorRand
if csprng, err = NewCounterEncryptorRandFromKey(ca.PrivateKey, hash); err != nil {
return return
} }
var certpriv *rsa.PrivateKey
if certpriv, err = rsa.GenerateKey(&csprng, 1024); err != nil { var certpriv crypto.Signer
return switch ca.PrivateKey.(type) {
case *rsa.PrivateKey:
if certpriv, err = rsa.GenerateKey(&csprng, 2048); err != nil {
return
}
case *ecdsa.PrivateKey:
if certpriv, err = ecdsa.GenerateKey(elliptic.P256(), &csprng); err != nil {
return
}
default:
err = fmt.Errorf("unsupported key type %T", ca.PrivateKey)
} }
var derBytes []byte var derBytes []byte
if derBytes, err = x509.CreateCertificate(&csprng, &template, x509ca, &certpriv.PublicKey, ca.PrivateKey); err != nil { if derBytes, err = x509.CreateCertificate(&csprng, &template, x509ca, certpriv.Public(), ca.PrivateKey); err != nil {
return return
} }
return tls.Certificate{ return tls.Certificate{
@ -190,3 +212,8 @@ func signHost(ca tls.Certificate, hosts []string) (cert tls.Certificate, err err
PrivateKey: certpriv, PrivateKey: certpriv,
}, nil }, nil
} }
func init() {
// Avoid deterministic random numbers
rand.Seed(time.Now().UnixNano())
}

Loading…
Cancel
Save