Split out RSA/ECDSA functions.
This commit is contained in:
parent
34a6e1511d
commit
ea457f7167
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue