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

View File

@ -6,18 +6,67 @@
package core package core
import ( import (
"testing"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/rand"
"crypto/rsa"
"math/big"
"testing"
"github.com/letsencrypt/boulder/test" "github.com/letsencrypt/boulder/test"
//"crypto/rsa"
) )
func TestWrongKeyType(t *testing.T) { func TestWrongKeyType(t *testing.T) {
ecdsaKey := ecdsa.PublicKey{} 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) { func TestSmallModulus(t *testing.T) {
ecdsaKey := ecdsa.PublicKey{} private, err := rsa.GenerateKey(rand.Reader, 2040)
test.Assert(t, !GoodKey(ecdsaKey), "Should have rejected ECDSA key.") 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.")
} }