AJ ONeal
4 years ago
5 changed files with 88 additions and 107 deletions
@ -0,0 +1,61 @@ |
|||
package xkeypairs |
|||
|
|||
import ( |
|||
"crypto/ecdsa" |
|||
"crypto/elliptic" |
|||
"crypto/rsa" |
|||
"io" |
|||
"log" |
|||
"math/rand" |
|||
|
|||
"git.rootprojects.org/root/keypairs" |
|||
) |
|||
|
|||
// 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"` |
|||
Seed int64 `json:"-"` |
|||
SeedStr string `json:"seed"` |
|||
Claims Object `json:"claims"` |
|||
Header Object `json:"header"` |
|||
} |
|||
|
|||
// this shananigans is only for testing and debug API stuff
|
|||
func (o *KeyOptions) MyFooNextReader() io.Reader { |
|||
if 0 == o.Seed { |
|||
return RandomReader |
|||
} |
|||
return rand.New(rand.NewSource(o.Seed)) |
|||
} |
|||
|
|||
// GenPrivKey generates a 256-bit entropy RSA or ECDSA private key
|
|||
func GenPrivKey(opts *KeyOptions) keypairs.PrivateKey { |
|||
var privkey keypairs.PrivateKey |
|||
|
|||
if "RSA" == opts.KeyType { |
|||
keylen := 2048 |
|||
privkey, _ = rsa.GenerateKey(opts.MyFooNextReader(), keylen) |
|||
if 0 != opts.Seed { |
|||
for i := 0; i < maxRetry; i++ { |
|||
otherkey, _ := rsa.GenerateKey(opts.MyFooNextReader(), keylen) |
|||
otherCmp := otherkey.D.Cmp(privkey.(*rsa.PrivateKey).D) |
|||
if 0 != otherCmp { |
|||
// There are two possible keys, choose the lesser D value
|
|||
// See https://github.com/square/go-jose/issues/189
|
|||
if otherCmp < 0 { |
|||
privkey = otherkey |
|||
} |
|||
break |
|||
} |
|||
if maxRetry == i-1 { |
|||
log.Printf("error: coinflip landed on heads %d times", maxRetry) |
|||
} |
|||
} |
|||
} |
|||
} else { |
|||
// TODO: EC keys may also suffer the same random problems in the future
|
|||
privkey, _ = ecdsa.GenerateKey(elliptic.P256(), opts.MyFooNextReader()) |
|||
} |
|||
return privkey |
|||
} |
Loading…
Reference in new issue