Skip to content

Commit

Permalink
Add support for (legacy) KeySpec key creation configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
hslatman committed Jul 6, 2023
1 parent 7d32ce2 commit 6c46a30
Showing 1 changed file with 28 additions and 2 deletions.
30 changes: 28 additions & 2 deletions kms/capi/capi.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const (
KeyIDArg = "key-id"
SerialNumberArg = "serial"
IssuerNameArg = "issuer"
KeySpec = "key-spec" // 0, 1, 2; none/NONE, at_keyexchange/AT_KEYEXCHANGE, at_signature/AT_SIGNATURE
)

var signatureAlgorithmMapping = map[apiv1.SignatureAlgorithm]string{
Expand Down Expand Up @@ -79,6 +80,7 @@ var signatureAlgorithmMapping = map[apiv1.SignatureAlgorithm]string{
// "key-id" X509v3 Subject Key Identifier of the certificate to load in hex format
// "serial" serial number of the certificate to load in hex format
// "issuer" Common Name of the certificate issuer
// "key-spec" the (legacy) KeySpec to use - 0, 1 or 2 (or none, at_keyexchange, at_signature)
type CAPIKMS struct {
providerName string
providerHandle uintptr
Expand Down Expand Up @@ -285,7 +287,7 @@ func (k *CAPIKMS) Close() error {
return nil
}

// CreateSigner returns a nce crypto.Signer that will sign using the key passed in via the URI.
// CreateSigner returns a crypto.Signer that will sign using the key passed in via the URI.
func (k *CAPIKMS) CreateSigner(req *apiv1.CreateSignerRequest) (crypto.Signer, error) {
u, err := uri.ParseWithScheme(Scheme, req.SigningKey)
if err != nil {
Expand Down Expand Up @@ -333,6 +335,25 @@ func (k *CAPIKMS) CreateSigner(req *apiv1.CreateSignerRequest) (crypto.Signer, e
return newCAPISigner(kh, containerName, pinOrPass)
}

func setKeySpec(u *uri.URI) (uint32, error) {
keySpec := uint32(0) // default KeySpec value is NONE
value := u.Get(KeySpec)
if v := strings.ReplaceAll(strings.ToLower(value), "_", ""); v != "" {
switch v {
case "0", "none", "null":
break // already set as the default
case "1", "atkeyexchange":
keySpec = uint32(1) // AT_KEYEXCHANGE
case "2", "atsignature":
keySpec = uint32(2) // AT_SIGNATURE
default:
return 0, fmt.Errorf("invalid value set for key-spec: %q", value)
}
}

return keySpec, nil
}

// CreateKey generates a new key in the storage provider using nCryptCreatePersistedKey
func (k *CAPIKMS) CreateKey(req *apiv1.CreateKeyRequest) (*apiv1.CreateKeyResponse, error) {
if req.Name == "" {
Expand Down Expand Up @@ -364,8 +385,13 @@ func (k *CAPIKMS) CreateKey(req *apiv1.CreateKeyRequest) (*apiv1.CreateKeyRespon
return nil, fmt.Errorf("unsupported algorithm %v", req.SignatureAlgorithm)
}

keySpec, err := setKeySpec(u)
if err != nil {
return nil, fmt.Errorf("failed determinging KeySpec to use: %w", err)
}

//TODO: check whether RSA keys require legacyKeySpec set to AT_KEYEXCHANGE
kh, err := nCryptCreatePersistedKey(k.providerHandle, containerName, alg, 0, 0)
kh, err := nCryptCreatePersistedKey(k.providerHandle, containerName, alg, keySpec, 0)
if err != nil {
return nil, fmt.Errorf("unable to create persisted key: %w", err)
}
Expand Down

0 comments on commit 6c46a30

Please sign in to comment.