Check for existing objects before generating a key. (#4981)
We only expect to want one key per slot/token. Refactor key_test somewhat to split up cases, and add a new test case.
This commit is contained in:
parent
91ba1730dc
commit
62eae60711
|
@ -54,9 +54,13 @@ type keyInfo struct {
|
|||
}
|
||||
|
||||
func generateKey(ctx pkcs11helpers.PKCtx, session pkcs11.SessionHandle, label string, outputPath string, config keyGenConfig) (*keyInfo, error) {
|
||||
_, err := pkcs11helpers.FindObject(ctx, session, []*pkcs11.Attribute{})
|
||||
if err != pkcs11helpers.ErrNoObject {
|
||||
return nil, fmt.Errorf("expected no objects in slot for key storage. got error: %s", err)
|
||||
}
|
||||
|
||||
var pubKey crypto.PublicKey
|
||||
var keyID []byte
|
||||
var err error
|
||||
switch config.Type {
|
||||
case "rsa":
|
||||
pubKey, keyID, err = rsaGenerate(ctx, session, label, config.RSAModLength, rsaExp)
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"math/big"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/letsencrypt/boulder/pkcs11helpers"
|
||||
|
@ -19,30 +20,43 @@ import (
|
|||
"github.com/miekg/pkcs11"
|
||||
)
|
||||
|
||||
func TestGenerateKey(t *testing.T) {
|
||||
tmp, err := ioutil.TempDir("", "ceremony-testing")
|
||||
func setupCtx() pkcs11helpers.MockCtx {
|
||||
return pkcs11helpers.MockCtx{
|
||||
GenerateKeyPairFunc: func(pkcs11.SessionHandle, []*pkcs11.Mechanism, []*pkcs11.Attribute, []*pkcs11.Attribute) (pkcs11.ObjectHandle, pkcs11.ObjectHandle, error) {
|
||||
return 0, 0, nil
|
||||
},
|
||||
SignInitFunc: func(pkcs11.SessionHandle, []*pkcs11.Mechanism, pkcs11.ObjectHandle) error {
|
||||
return nil
|
||||
},
|
||||
GenerateRandomFunc: func(pkcs11.SessionHandle, int) ([]byte, error) {
|
||||
return []byte{1, 2, 3}, nil
|
||||
},
|
||||
FindObjectsInitFunc: func(pkcs11.SessionHandle, []*pkcs11.Attribute) error {
|
||||
return nil
|
||||
},
|
||||
FindObjectsFunc: func(pkcs11.SessionHandle, int) ([]pkcs11.ObjectHandle, bool, error) {
|
||||
return nil, false, nil
|
||||
},
|
||||
FindObjectsFinalFunc: func(pkcs11.SessionHandle) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateKeyRSA(t *testing.T) {
|
||||
tmp, err := ioutil.TempDir("", "ceremony-testing-rsa")
|
||||
test.AssertNotError(t, err, "Failed to create temporary directory")
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
// RSA
|
||||
ctx := pkcs11helpers.MockCtx{}
|
||||
ctx := setupCtx()
|
||||
rsaPriv, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
test.AssertNotError(t, err, "Failed to generate a test RSA key")
|
||||
ctx.GenerateKeyPairFunc = func(pkcs11.SessionHandle, []*pkcs11.Mechanism, []*pkcs11.Attribute, []*pkcs11.Attribute) (pkcs11.ObjectHandle, pkcs11.ObjectHandle, error) {
|
||||
return 0, 0, nil
|
||||
}
|
||||
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
|
||||
return []*pkcs11.Attribute{
|
||||
pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, big.NewInt(int64(rsaPriv.E)).Bytes()),
|
||||
pkcs11.NewAttribute(pkcs11.CKA_MODULUS, rsaPriv.N.Bytes()),
|
||||
}, nil
|
||||
}
|
||||
ctx.SignInitFunc = func(pkcs11.SessionHandle, []*pkcs11.Mechanism, pkcs11.ObjectHandle) error {
|
||||
return nil
|
||||
}
|
||||
ctx.GenerateRandomFunc = func(pkcs11.SessionHandle, int) ([]byte, error) {
|
||||
return []byte{1, 2, 3}, nil
|
||||
}
|
||||
ctx.SignFunc = func(_ pkcs11.SessionHandle, msg []byte) ([]byte, error) {
|
||||
// Chop of the hash identifier and feed back into rsa.SignPKCS1v15
|
||||
return rsa.SignPKCS1v15(rand.Reader, rsaPriv, crypto.SHA256, msg[19:])
|
||||
|
@ -59,8 +73,14 @@ func TestGenerateKey(t *testing.T) {
|
|||
diskKey, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
test.AssertNotError(t, err, "Failed to parse disk key")
|
||||
test.AssertDeepEquals(t, diskKey, keyInfo.key)
|
||||
}
|
||||
|
||||
// EC
|
||||
func TestGenerateKeyEC(t *testing.T) {
|
||||
tmp, err := ioutil.TempDir("", "ceremony-testing-ec")
|
||||
test.AssertNotError(t, err, "Failed to create temporary directory")
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
ctx := setupCtx()
|
||||
ecPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
test.AssertNotError(t, err, "Failed to generate a ECDSA test key")
|
||||
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
|
||||
|
@ -72,16 +92,34 @@ func TestGenerateKey(t *testing.T) {
|
|||
ctx.SignFunc = func(_ pkcs11.SessionHandle, msg []byte) ([]byte, error) {
|
||||
return ecPKCS11Sign(ecPriv, msg)
|
||||
}
|
||||
keyPath = path.Join(tmp, "test-ecdsa-key.pem")
|
||||
keyInfo, err = generateKey(ctx, 0, "", keyPath, keyGenConfig{
|
||||
keyPath := path.Join(tmp, "test-ecdsa-key.pem")
|
||||
keyInfo, err := generateKey(ctx, 0, "", keyPath, keyGenConfig{
|
||||
Type: "ecdsa",
|
||||
ECDSACurve: "P-256",
|
||||
})
|
||||
test.AssertNotError(t, err, "Failed to generate ECDSA key")
|
||||
diskKeyBytes, err = ioutil.ReadFile(keyPath)
|
||||
diskKeyBytes, err := ioutil.ReadFile(keyPath)
|
||||
test.AssertNotError(t, err, "Failed to load key from disk")
|
||||
block, _ = pem.Decode(diskKeyBytes)
|
||||
diskKey, err = x509.ParsePKIXPublicKey(block.Bytes)
|
||||
block, _ := pem.Decode(diskKeyBytes)
|
||||
diskKey, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
test.AssertNotError(t, err, "Failed to parse disk key")
|
||||
test.AssertDeepEquals(t, diskKey, keyInfo.key)
|
||||
}
|
||||
|
||||
func TestGenerateKeySlotHasSomething(t *testing.T) {
|
||||
tmp, err := ioutil.TempDir("", "ceremony-testing-slot-has-something")
|
||||
test.AssertNotError(t, err, "Failed to create temporary directory")
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
ctx := setupCtx()
|
||||
ctx.FindObjectsFunc = func(pkcs11.SessionHandle, int) ([]pkcs11.ObjectHandle, bool, error) {
|
||||
return []pkcs11.ObjectHandle{1}, false, nil
|
||||
}
|
||||
keyPath := path.Join(tmp, "should-not-exist.pem")
|
||||
_, err = generateKey(ctx, 0, "", keyPath, keyGenConfig{
|
||||
Type: "ecdsa",
|
||||
ECDSACurve: "P-256",
|
||||
})
|
||||
test.AssertError(t, err, "expected failure for a slot with an object already in it")
|
||||
test.Assert(t, strings.HasPrefix(err.Error(), "expected no objects"), "wrong error")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue