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