diff --git a/cmd/step-pkcs11-init/main.go b/cmd/step-pkcs11-init/main.go index b190c261..c7ac9b0f 100644 --- a/cmd/step-pkcs11-init/main.go +++ b/cmd/step-pkcs11-init/main.go @@ -328,6 +328,7 @@ func createPKI(k kms.KeyManager, c Config) error { if err = cm.StoreCertificate(&apiv1.StoreCertificateRequest{ Name: c.RootObject, Certificate: root, + Extractable: c.Extractable, }); err != nil { return err } @@ -406,6 +407,7 @@ func createPKI(k kms.KeyManager, c Config) error { if err = cm.StoreCertificate(&apiv1.StoreCertificateRequest{ Name: c.CrtObject, Certificate: intermediate, + Extractable: c.Extractable, }); err != nil { return err } diff --git a/kms/apiv1/requests.go b/kms/apiv1/requests.go index 321b308b..94d832f9 100644 --- a/kms/apiv1/requests.go +++ b/kms/apiv1/requests.go @@ -156,4 +156,8 @@ type LoadCertificateRequest struct { type StoreCertificateRequest struct { Name string Certificate *x509.Certificate + + // Whether the key may be exported from the HSM under a wrap key. + // Sets the CKA_EXTRACTABLE bit. + Extractable bool } diff --git a/kms/pkcs11/pkcs11.go b/kms/pkcs11/pkcs11.go index f6a86a0d..98b08c58 100644 --- a/kms/pkcs11/pkcs11.go +++ b/kms/pkcs11/pkcs11.go @@ -33,6 +33,7 @@ type P11 interface { FindKeyPair(id, label []byte) (crypto11.Signer, error) FindCertificate(id, label []byte, serial *big.Int) (*x509.Certificate, error) ImportCertificateWithLabel(id, label []byte, cert *x509.Certificate) error + ImportCertificateWithAttributes(template crypto11.AttributeSet, certificate *x509.Certificate) error DeleteCertificate(id, label []byte, serial *big.Int) error GenerateRSAKeyPairWithLabel(id, label []byte, bits int) (crypto11.SignerDecrypter, error) GenerateECDSAKeyPairWithLabel(id, label []byte, curve elliptic.Curve) (crypto11.Signer, error) @@ -197,13 +198,31 @@ func (k *PKCS11) StoreCertificate(req *apiv1.StoreCertificateRequest) error { }, "storeCertificate failed") } - if err := k.p11.ImportCertificateWithLabel(id, object, req.Certificate); err != nil { + if err := ImportCertificateWithLabel(k.p11, id, object, req.Certificate, req.Extractable); err != nil { return errors.Wrap(err, "storeCertificate failed") } return nil } +func ImportCertificateWithLabel(ctx P11, id []byte, label []byte, certificate *x509.Certificate, extractable bool) error { + if id == nil { + return errors.New("id cannot be nil") + } + if label == nil { + return errors.New("label cannot be nil") + } + + template, err := crypto11.NewAttributeSetWithIDAndLabel(id, label) + if err != nil { + return err + } + template.AddIfNotPresent([]*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, extractable), + }) + return ctx.ImportCertificateWithAttributes(template, certificate) +} + // DeleteKey is a utility function to delete a key given an uri. func (k *PKCS11) DeleteKey(uri string) error { id, object, err := parseObject(uri)