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) {
|
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 pubKey crypto.PublicKey
|
||||||
var keyID []byte
|
var keyID []byte
|
||||||
var err error
|
|
||||||
switch config.Type {
|
switch config.Type {
|
||||||
case "rsa":
|
case "rsa":
|
||||||
pubKey, keyID, err = rsaGenerate(ctx, session, label, config.RSAModLength, rsaExp)
|
pubKey, keyID, err = rsaGenerate(ctx, session, label, config.RSAModLength, rsaExp)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/letsencrypt/boulder/pkcs11helpers"
|
"github.com/letsencrypt/boulder/pkcs11helpers"
|
||||||
|
|
@ -19,30 +20,43 @@ import (
|
||||||
"github.com/miekg/pkcs11"
|
"github.com/miekg/pkcs11"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGenerateKey(t *testing.T) {
|
func setupCtx() pkcs11helpers.MockCtx {
|
||||||
tmp, err := ioutil.TempDir("", "ceremony-testing")
|
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")
|
test.AssertNotError(t, err, "Failed to create temporary directory")
|
||||||
defer os.RemoveAll(tmp)
|
defer os.RemoveAll(tmp)
|
||||||
|
|
||||||
// RSA
|
ctx := setupCtx()
|
||||||
ctx := pkcs11helpers.MockCtx{}
|
|
||||||
rsaPriv, err := rsa.GenerateKey(rand.Reader, 1024)
|
rsaPriv, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||||
test.AssertNotError(t, err, "Failed to generate a test RSA key")
|
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) {
|
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
|
||||||
return []*pkcs11.Attribute{
|
return []*pkcs11.Attribute{
|
||||||
pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, big.NewInt(int64(rsaPriv.E)).Bytes()),
|
pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, big.NewInt(int64(rsaPriv.E)).Bytes()),
|
||||||
pkcs11.NewAttribute(pkcs11.CKA_MODULUS, rsaPriv.N.Bytes()),
|
pkcs11.NewAttribute(pkcs11.CKA_MODULUS, rsaPriv.N.Bytes()),
|
||||||
}, nil
|
}, 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) {
|
ctx.SignFunc = func(_ pkcs11.SessionHandle, msg []byte) ([]byte, error) {
|
||||||
// Chop of the hash identifier and feed back into rsa.SignPKCS1v15
|
// Chop of the hash identifier and feed back into rsa.SignPKCS1v15
|
||||||
return rsa.SignPKCS1v15(rand.Reader, rsaPriv, crypto.SHA256, msg[19:])
|
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)
|
diskKey, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||||
test.AssertNotError(t, err, "Failed to parse disk key")
|
test.AssertNotError(t, err, "Failed to parse disk key")
|
||||||
test.AssertDeepEquals(t, diskKey, keyInfo.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)
|
ecPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
test.AssertNotError(t, err, "Failed to generate a ECDSA test key")
|
test.AssertNotError(t, err, "Failed to generate a ECDSA test key")
|
||||||
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
|
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) {
|
ctx.SignFunc = func(_ pkcs11.SessionHandle, msg []byte) ([]byte, error) {
|
||||||
return ecPKCS11Sign(ecPriv, msg)
|
return ecPKCS11Sign(ecPriv, msg)
|
||||||
}
|
}
|
||||||
keyPath = path.Join(tmp, "test-ecdsa-key.pem")
|
keyPath := path.Join(tmp, "test-ecdsa-key.pem")
|
||||||
keyInfo, err = generateKey(ctx, 0, "", keyPath, keyGenConfig{
|
keyInfo, err := generateKey(ctx, 0, "", keyPath, keyGenConfig{
|
||||||
Type: "ecdsa",
|
Type: "ecdsa",
|
||||||
ECDSACurve: "P-256",
|
ECDSACurve: "P-256",
|
||||||
})
|
})
|
||||||
test.AssertNotError(t, err, "Failed to generate ECDSA key")
|
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")
|
test.AssertNotError(t, err, "Failed to load key from disk")
|
||||||
block, _ = pem.Decode(diskKeyBytes)
|
block, _ := pem.Decode(diskKeyBytes)
|
||||||
diskKey, err = x509.ParsePKIXPublicKey(block.Bytes)
|
diskKey, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||||
test.AssertNotError(t, err, "Failed to parse disk key")
|
test.AssertNotError(t, err, "Failed to parse disk key")
|
||||||
test.AssertDeepEquals(t, diskKey, keyInfo.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