Split out RSA/ECDSA functions.

This commit is contained in:
Jacob Hoffman-Andrews 2015-05-09 11:34:13 -07:00
parent 34a6e1511d
commit ea457f7167
2 changed files with 84 additions and 15 deletions

View File

@ -7,8 +7,10 @@ package core
import (
"crypto"
"crypto/ecdsa"
"crypto/rsa"
"fmt"
"reflect"
blog "github.com/letsencrypt/boulder/log"
)
@ -17,22 +19,40 @@ import (
// strength and algorithm checking.
func GoodKey(key crypto.PublicKey) bool {
log := blog.GetAuditLogger()
rsaKey, ok := key.(rsa.PublicKey)
if !ok {
log.Debug("Non-RSA keys not yet supported.")
return false
switch t := key.(type) {
case rsa.PublicKey:
return GoodKeyRSA(t)
case *rsa.PublicKey:
return GoodKeyRSA(*t)
case ecdsa.PublicKey:
return GoodKeyECDSA(t)
case *ecdsa.PublicKey:
return GoodKeyECDSA(*t)
default:
log.Debug(fmt.Sprintf("Unknown key type %s", reflect.TypeOf(key)))
return false
}
}
func GoodKeyECDSA(key ecdsa.PublicKey) bool {
log := blog.GetAuditLogger()
log.Debug(fmt.Sprintf("ECDSA keys not yet supported."))
return false
}
func GoodKeyRSA(key rsa.PublicKey) bool {
log := blog.GetAuditLogger()
// Baseline Requirements Appendix A
// Modulus must be >= 2048 bits
modulus := rsaKey.N
modulus := key.N
if modulus.BitLen() < 2048 {
log.Debug(fmt.Sprintf("Key too small: %d", modulus.BitLen()))
return false
}
// The CA SHALL confirm that the value of the public exponent
// is an odd number equal to 3 or more
if rsaKey.E % 2 == 0 {
log.Debug(fmt.Sprintf("Key exponent is an even number: %d", rsaKey.E))
if key.E % 2 == 0 {
log.Debug(fmt.Sprintf("Key exponent is an even number: %d", key.E))
return false
}
// Additionally, the public exponent SHOULD be in the range between
@ -40,8 +60,8 @@ func GoodKey(key crypto.PublicKey) bool {
// NOTE: rsa.PublicKey cannot represent an exponent part greater than
// 2^256 - 1, because it stores E as an integer. So we don't check the upper
// bound.
if rsaKey.E < ((1 << 6) + 1) {
log.Debug(fmt.Sprintf("Key exponent is too small: %d", rsaKey.E))
if key.E < ((1 << 6) + 1) {
log.Debug(fmt.Sprintf("Key exponent is too small: %d", key.E))
return false
}
// TODO: The modulus SHOULD also have the following

View File

@ -6,18 +6,67 @@
package core
import (
"testing"
"crypto/ecdsa"
"crypto/rand"
"crypto/rsa"
"math/big"
"testing"
"github.com/letsencrypt/boulder/test"
//"crypto/rsa"
)
func TestWrongKeyType(t *testing.T) {
ecdsaKey := ecdsa.PublicKey{}
test.Assert(t, !GoodKey(ecdsaKey), "Should have rejected ECDSA key.")
test.Assert(t, !GoodKey(&ecdsaKey), "Should have rejected ECDSA key.")
}
func TestWrongKeyType(t *testing.T) {
ecdsaKey := ecdsa.PublicKey{}
test.Assert(t, !GoodKey(ecdsaKey), "Should have rejected ECDSA key.")
func TestSmallModulus(t *testing.T) {
private, err := rsa.GenerateKey(rand.Reader, 2040)
test.AssertNotError(t, err, "Error generating key")
test.Assert(t, !GoodKey(&private.PublicKey), "Should have rejected too-short key.")
}
func TestSmallExponent(t *testing.T) {
bigOne := big.NewInt(1)
key := rsa.PublicKey{
N: bigOne.Lsh(bigOne, 2048),
E: 5,
}
test.Assert(t, !GoodKey(&key), "Should have rejected small exponent.")
}
func TestEvenExponent(t *testing.T) {
bigOne := big.NewInt(1)
key := rsa.PublicKey{
N: bigOne.Lsh(bigOne, 2048),
E: 1 << 17,
}
test.Assert(t, !GoodKey(&key), "Should have rejected even exponent.")
}
func TestEvenModulus(t *testing.T) {
bigOne := big.NewInt(1)
key := rsa.PublicKey{
N: bigOne.Lsh(bigOne, 2048),
E: (1 << 17) + 1,
}
test.Assert(t, !GoodKey(&key), "Should have rejected even modulus.")
}
func TestModulusDivisibleBy752(t *testing.T) {
N := big.NewInt(1)
N.Lsh(N, 2048)
N.Add(N, big.NewInt(1))
N.Mul(N, big.NewInt(751))
key := rsa.PublicKey{
N: N,
E: (1 << 17) + 1,
}
test.Assert(t, !GoodKey(&key), "Should have rejected modulus divisible by 751.")
}
func TestGoodKey(t *testing.T) {
private, err := rsa.GenerateKey(rand.Reader, 2048)
test.AssertNotError(t, err, "Error generating key")
test.Assert(t, GoodKey(&private.PublicKey), "Should have accepted good key.")
}