keypairs/generate.go

70 lines
1.7 KiB
Go

package keypairs
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"io"
mathrand "math/rand"
"time"
)
var randReader io.Reader = rand.Reader
var allowMocking = false
// KeyOptions are the things that we may need to know about a request to fulfill it properly
type keyOptions struct {
//Key string `json:"key"`
KeyType string `json:"kty"`
mockSeed int64 //`json:"-"`
//SeedStr string `json:"seed"`
//Claims Object `json:"claims"`
//Header Object `json:"header"`
}
func (o *keyOptions) nextReader() io.Reader {
if allowMocking {
return o.maybeMockReader()
}
return randReader
}
// NewDefaultPrivateKey generates a key with reasonable strength.
// Today that means a 256-bit equivalent - either RSA 2048 or EC P-256.
func NewDefaultPrivateKey() PrivateKey {
// insecure random is okay here,
// it's just used for a coin toss
mathrand.Seed(time.Now().UnixNano())
coin := mathrand.Int()
// the idea here is that we want to make
// it dead simple to support RSA and EC
// so it shouldn't matter which is used
if 0 == coin%2 {
return newPrivateKey(&keyOptions{
KeyType: "RSA",
})
}
return newPrivateKey(&keyOptions{
KeyType: "EC",
})
}
// newPrivateKey generates a 256-bit entropy RSA or ECDSA private key
func newPrivateKey(opts *keyOptions) PrivateKey {
var privkey PrivateKey
if "RSA" == opts.KeyType {
keylen := 2048
privkey, _ = rsa.GenerateKey(opts.nextReader(), keylen)
if allowMocking {
privkey = maybeDerandomizeMockKey(privkey, keylen, opts)
}
} else {
// TODO: EC keys may also suffer the same random problems in the future
privkey, _ = ecdsa.GenerateKey(elliptic.P256(), opts.nextReader())
}
return privkey
}