Merge pull request #322 from letsencrypt/good-key-err

Return errors from core.GoodKey
This commit is contained in:
James 'J.C.' Jones 2015-06-07 09:00:58 -07:00
commit cf0b2e9cc2
4 changed files with 38 additions and 32 deletions

View File

@ -257,8 +257,8 @@ func (ca *CertificateAuthorityImpl) IssueCertificate(csr x509.CertificateRequest
ca.log.AuditErr(err) ca.log.AuditErr(err)
return emptyCert, err return emptyCert, err
} }
if !core.GoodKey(key, ca.MaxKeySize) { if err = core.GoodKey(key, ca.MaxKeySize); err != nil {
err = fmt.Errorf("Invalid public key in CSR.") err = fmt.Errorf("Invalid public key in CSR: %s", err.Error())
// AUDIT[ Certificate Requests ] 11917fa4-10ef-4e0d-9105-bacbe7836a3c // AUDIT[ Certificate Requests ] 11917fa4-10ef-4e0d-9105-bacbe7836a3c
ca.log.AuditErr(err) ca.log.AuditErr(err)
return emptyCert, err return emptyCert, err

View File

@ -42,7 +42,7 @@ var (
// key use (our requirements are the same for either one), according to basic // key use (our requirements are the same for either one), according to basic
// strength and algorithm checking. // strength and algorithm checking.
// TODO: Support JsonWebKeys once go-jose migration is done. // TODO: Support JsonWebKeys once go-jose migration is done.
func GoodKey(key crypto.PublicKey, maxKeySize int) bool { func GoodKey(key crypto.PublicKey, maxKeySize int) error {
log := blog.GetAuditLogger() log := blog.GetAuditLogger()
switch t := key.(type) { switch t := key.(type) {
case rsa.PublicKey: case rsa.PublicKey:
@ -54,30 +54,34 @@ func GoodKey(key crypto.PublicKey, maxKeySize int) bool {
case *ecdsa.PublicKey: case *ecdsa.PublicKey:
return GoodKeyECDSA(*t, maxKeySize) return GoodKeyECDSA(*t, maxKeySize)
default: default:
log.Debug(fmt.Sprintf("Unknown key type %s", reflect.TypeOf(key))) err := fmt.Errorf("Unknown key type %s", reflect.TypeOf(key))
return false log.Debug(err.Error())
return err
} }
} }
func GoodKeyECDSA(key ecdsa.PublicKey, maxKeySize int) bool { func GoodKeyECDSA(key ecdsa.PublicKey, maxKeySize int) (err error) {
log := blog.GetAuditLogger() log := blog.GetAuditLogger()
log.Debug(fmt.Sprintf("ECDSA keys not yet supported.")) err = fmt.Errorf("ECDSA keys not yet supported")
return false log.Debug(err.Error())
return
} }
func GoodKeyRSA(key rsa.PublicKey, maxKeySize int) bool { func GoodKeyRSA(key rsa.PublicKey, maxKeySize int) (err error) {
log := blog.GetAuditLogger() log := blog.GetAuditLogger()
// Baseline Requirements Appendix A // Baseline Requirements Appendix A
// Modulus must be >= 2048 bits and < maxKeySize // Modulus must be >= 2048 bits and < maxKeySize
modulus := key.N modulus := key.N
modulusBitLen := modulus.BitLen() modulusBitLen := modulus.BitLen()
if modulusBitLen < 2048 { if modulusBitLen < 2048 {
log.Debug(fmt.Sprintf("Key too small: %d", modulusBitLen)) err = fmt.Errorf("Key too small: %d", modulusBitLen)
return false log.Debug(err.Error())
return err
} }
if modulusBitLen > maxKeySize { if modulusBitLen > maxKeySize {
log.Debug(fmt.Sprintf("Key too large: %d > %d", modulusBitLen, maxKeySize)) err = fmt.Errorf("Key too large: %d > %d", modulusBitLen, maxKeySize)
return false log.Debug(err.Error())
return err
} }
// The CA SHALL confirm that the value of the public exponent is an // The CA SHALL confirm that the value of the public exponent is an
// odd number equal to 3 or more. Additionally, the public exponent // odd number equal to 3 or more. Additionally, the public exponent
@ -86,8 +90,9 @@ func GoodKeyRSA(key rsa.PublicKey, maxKeySize int) bool {
// 2^32 - 1 or 2^64 - 1, because it stores E as an integer. So we // 2^32 - 1 or 2^64 - 1, because it stores E as an integer. So we
// don't need to check the upper bound. // don't need to check the upper bound.
if (key.E%2) == 0 || key.E < ((1<<16)+1) { if (key.E%2) == 0 || key.E < ((1<<16)+1) {
log.Debug(fmt.Sprintf("Key exponent should be odd and >2^16: %d", key.E)) err = fmt.Errorf("Key exponent should be odd and >2^16: %d", key.E)
return false log.Debug(err.Error())
return err
} }
// The modulus SHOULD also have the following characteristics: an odd // The modulus SHOULD also have the following characteristics: an odd
// number, not the power of a prime, and have no factors smaller than 752. // number, not the power of a prime, and have no factors smaller than 752.
@ -101,9 +106,10 @@ func GoodKeyRSA(key rsa.PublicKey, maxKeySize int) bool {
var result big.Int var result big.Int
result.Mod(modulus, prime) result.Mod(modulus, prime)
if result.Sign() == 0 { if result.Sign() == 0 {
log.Debug(fmt.Sprintf("Key divisible by small prime: %d", prime)) err = fmt.Errorf("Key divisible by small prime: %d", prime)
return false log.Debug(err.Error())
return err
} }
} }
return true return nil
} }

View File

@ -19,27 +19,27 @@ var maxKeySize int = 2048
func TestUnknownKeyType(t *testing.T) { func TestUnknownKeyType(t *testing.T) {
notAKey := struct{}{} notAKey := struct{}{}
test.Assert(t, !GoodKey(notAKey, maxKeySize), "Should have rejected a key of unknown type") test.AssertError(t, GoodKey(notAKey, maxKeySize), "Should have rejected a key of unknown type")
} }
func TestWrongKeyType(t *testing.T) { func TestWrongKeyType(t *testing.T) {
ecdsaKey := ecdsa.PublicKey{} ecdsaKey := ecdsa.PublicKey{}
test.Assert(t, !GoodKey(&ecdsaKey, maxKeySize), "Should have rejected ECDSA key.") test.AssertError(t, GoodKey(&ecdsaKey, maxKeySize), "Should have rejected ECDSA key.")
test.Assert(t, !GoodKey(ecdsaKey, maxKeySize), "Should have rejected ECDSA key.") test.AssertError(t, GoodKey(ecdsaKey, maxKeySize), "Should have rejected ECDSA key.")
} }
func TestSmallModulus(t *testing.T) { func TestSmallModulus(t *testing.T) {
private, err := rsa.GenerateKey(rand.Reader, 2040) private, err := rsa.GenerateKey(rand.Reader, 2040)
test.AssertNotError(t, err, "Error generating key") test.AssertNotError(t, err, "Error generating key")
test.Assert(t, !GoodKey(&private.PublicKey, maxKeySize), "Should have rejected too-short key.") test.AssertError(t, GoodKey(&private.PublicKey, maxKeySize), "Should have rejected too-short key.")
test.Assert(t, !GoodKey(private.PublicKey, maxKeySize), "Should have rejected too-short key.") test.AssertError(t, GoodKey(private.PublicKey, maxKeySize), "Should have rejected too-short key.")
} }
func TestLargeModulus(t *testing.T) { func TestLargeModulus(t *testing.T) {
private, err := rsa.GenerateKey(rand.Reader, maxKeySize+1) private, err := rsa.GenerateKey(rand.Reader, maxKeySize+1)
test.AssertNotError(t, err, "Error generating key") test.AssertNotError(t, err, "Error generating key")
test.Assert(t, !GoodKey(&private.PublicKey, maxKeySize), "Should have rejected too-long key.") test.AssertError(t, GoodKey(&private.PublicKey, maxKeySize), "Should have rejected too-long key.")
test.Assert(t, !GoodKey(private.PublicKey, maxKeySize), "Should have rejected too-long key.") test.AssertError(t, GoodKey(private.PublicKey, maxKeySize), "Should have rejected too-long key.")
} }
func TestSmallExponent(t *testing.T) { func TestSmallExponent(t *testing.T) {
@ -48,7 +48,7 @@ func TestSmallExponent(t *testing.T) {
N: bigOne.Lsh(bigOne, 2048), N: bigOne.Lsh(bigOne, 2048),
E: 5, E: 5,
} }
test.Assert(t, !GoodKey(&key, maxKeySize), "Should have rejected small exponent.") test.AssertError(t, GoodKey(&key, maxKeySize), "Should have rejected small exponent.")
} }
func TestEvenExponent(t *testing.T) { func TestEvenExponent(t *testing.T) {
@ -57,7 +57,7 @@ func TestEvenExponent(t *testing.T) {
N: bigOne.Lsh(bigOne, 2048), N: bigOne.Lsh(bigOne, 2048),
E: 1 << 17, E: 1 << 17,
} }
test.Assert(t, !GoodKey(&key, maxKeySize), "Should have rejected even exponent.") test.AssertError(t, GoodKey(&key, maxKeySize), "Should have rejected even exponent.")
} }
func TestEvenModulus(t *testing.T) { func TestEvenModulus(t *testing.T) {
@ -66,7 +66,7 @@ func TestEvenModulus(t *testing.T) {
N: bigOne.Lsh(bigOne, 2048), N: bigOne.Lsh(bigOne, 2048),
E: (1 << 17) + 1, E: (1 << 17) + 1,
} }
test.Assert(t, !GoodKey(&key, maxKeySize), "Should have rejected even modulus.") test.AssertError(t, GoodKey(&key, maxKeySize), "Should have rejected even modulus.")
} }
func TestModulusDivisibleBy752(t *testing.T) { func TestModulusDivisibleBy752(t *testing.T) {
@ -78,11 +78,11 @@ func TestModulusDivisibleBy752(t *testing.T) {
N: N, N: N,
E: (1 << 17) + 1, E: (1 << 17) + 1,
} }
test.Assert(t, !GoodKey(&key, maxKeySize), "Should have rejected modulus divisible by 751.") test.AssertError(t, GoodKey(&key, maxKeySize), "Should have rejected modulus divisible by 751.")
} }
func TestGoodKey(t *testing.T) { func TestGoodKey(t *testing.T) {
private, err := rsa.GenerateKey(rand.Reader, 2048) private, err := rsa.GenerateKey(rand.Reader, 2048)
test.AssertNotError(t, err, "Error generating key") test.AssertNotError(t, err, "Error generating key")
test.Assert(t, GoodKey(&private.PublicKey, maxKeySize), "Should have accepted good key.") test.AssertNotError(t, GoodKey(&private.PublicKey, maxKeySize), "Should have accepted good key.")
} }

View File

@ -88,8 +88,8 @@ type certificateRequestEvent struct {
} }
func (ra *RegistrationAuthorityImpl) NewRegistration(init core.Registration) (reg core.Registration, err error) { func (ra *RegistrationAuthorityImpl) NewRegistration(init core.Registration) (reg core.Registration, err error) {
if !core.GoodKey(init.Key.Key, ra.MaxKeySize) { if err = core.GoodKey(init.Key.Key, ra.MaxKeySize); err != nil {
return core.Registration{}, core.UnauthorizedError("Invalid public key") return core.Registration{}, core.MalformedRequestError(fmt.Sprintf("Invalid public key: %s", err.Error()))
} }
reg = core.Registration{ reg = core.Registration{
RecoveryToken: core.NewToken(), RecoveryToken: core.NewToken(),