mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 19:17:58 +00:00
vault-24958: add cmac key types for import and export (#26610)
* add cmac key types to export * set rsa public key and add cmac key types for wrapping * add cmac types to import and export * add cmac export key type * fix import key type * add cmac to policy import * add enterprise checks * fix imports
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/vault/helper/constants"
|
||||
"github.com/hashicorp/vault/sdk/framework"
|
||||
"github.com/hashicorp/vault/sdk/helper/keysutil"
|
||||
"github.com/hashicorp/vault/sdk/logical"
|
||||
@@ -97,6 +98,10 @@ func (b *backend) pathPolicyBYOKExportRead(ctx context.Context, req *logical.Req
|
||||
return logical.ErrorResponse("key is not exportable"), nil
|
||||
}
|
||||
|
||||
if srcP.Type.CMACSupported() && !constants.IsEnterprise {
|
||||
return logical.ErrorResponse(ErrCmacEntOnly.Error()), logical.ErrInvalidRequest
|
||||
}
|
||||
|
||||
retKeys := map[string]string{}
|
||||
switch version {
|
||||
case "":
|
||||
@@ -154,7 +159,7 @@ func getBYOKExportKey(dstP *keysutil.Policy, srcP *keysutil.Policy, key *keysuti
|
||||
|
||||
var targetKey interface{}
|
||||
switch srcP.Type {
|
||||
case keysutil.KeyType_AES128_GCM96, keysutil.KeyType_AES256_GCM96, keysutil.KeyType_ChaCha20_Poly1305, keysutil.KeyType_HMAC:
|
||||
case keysutil.KeyType_AES128_GCM96, keysutil.KeyType_AES256_GCM96, keysutil.KeyType_ChaCha20_Poly1305, keysutil.KeyType_HMAC, keysutil.KeyType_AES128_CMAC, keysutil.KeyType_AES256_CMAC:
|
||||
targetKey = key.Key
|
||||
case keysutil.KeyType_RSA2048, keysutil.KeyType_RSA3072, keysutil.KeyType_RSA4096:
|
||||
targetKey = key.RSAKey
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/vault/helper/constants"
|
||||
"github.com/hashicorp/vault/sdk/framework"
|
||||
"github.com/hashicorp/vault/sdk/helper/keysutil"
|
||||
"github.com/hashicorp/vault/sdk/logical"
|
||||
@@ -27,6 +28,7 @@ const (
|
||||
exportTypeHMACKey = "hmac-key"
|
||||
exportTypePublicKey = "public-key"
|
||||
exportTypeCertificateChain = "certificate-chain"
|
||||
exportTypeCMACKey = "cmac-key"
|
||||
)
|
||||
|
||||
func (b *backend) pathExportKeys() *framework.Path {
|
||||
@@ -42,7 +44,7 @@ func (b *backend) pathExportKeys() *framework.Path {
|
||||
Fields: map[string]*framework.FieldSchema{
|
||||
"type": {
|
||||
Type: framework.TypeString,
|
||||
Description: "Type of key to export (encryption-key, signing-key, hmac-key, public-key)",
|
||||
Description: "Type of key to export (encryption-key, signing-key, hmac-key, public-key, cmac-key)",
|
||||
},
|
||||
"name": {
|
||||
Type: framework.TypeString,
|
||||
@@ -74,6 +76,10 @@ func (b *backend) pathPolicyExportRead(ctx context.Context, req *logical.Request
|
||||
case exportTypeHMACKey:
|
||||
case exportTypePublicKey:
|
||||
case exportTypeCertificateChain:
|
||||
case exportTypeCMACKey:
|
||||
if !constants.IsEnterprise {
|
||||
return logical.ErrorResponse(ErrCmacEntOnly.Error()), logical.ErrInvalidRequest
|
||||
}
|
||||
default:
|
||||
return logical.ErrorResponse(fmt.Sprintf("invalid export type: %s", exportType)), logical.ErrInvalidRequest
|
||||
}
|
||||
@@ -265,6 +271,11 @@ func getExportKey(policy *keysutil.Policy, key *keysutil.KeyEntry, exportType st
|
||||
certChain := strings.Join(pemCerts, "\n")
|
||||
|
||||
return certChain, nil
|
||||
case exportTypeCMACKey:
|
||||
switch policy.Type {
|
||||
case keysutil.KeyType_AES128_CMAC, keysutil.KeyType_AES256_CMAC:
|
||||
return strings.TrimSpace(base64.StdEncoding.EncodeToString(key.Key)), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("unknown key type %v for export type %v", policy.Type, exportType)
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/tink/go/kwp/subtle"
|
||||
"github.com/hashicorp/vault/helper/constants"
|
||||
"github.com/hashicorp/vault/sdk/framework"
|
||||
"github.com/hashicorp/vault/sdk/helper/keysutil"
|
||||
"github.com/hashicorp/vault/sdk/logical"
|
||||
@@ -45,7 +46,7 @@ func (b *backend) pathImport() *framework.Path {
|
||||
Default: "aes256-gcm96",
|
||||
Description: `The type of key being imported. Currently, "aes128-gcm96" (symmetric), "aes256-gcm96" (symmetric), "ecdsa-p256"
|
||||
(asymmetric), "ecdsa-p384" (asymmetric), "ecdsa-p521" (asymmetric), "ed25519" (asymmetric), "rsa-2048" (asymmetric), "rsa-3072"
|
||||
(asymmetric), "rsa-4096" (asymmetric) are supported. Defaults to "aes256-gcm96".
|
||||
(asymmetric), "rsa-4096" (asymmetric), "hmac", "aes128-cmac", "aes256-cmac" are supported. Defaults to "aes256-gcm96".
|
||||
`,
|
||||
},
|
||||
"hash_function": {
|
||||
@@ -214,10 +215,18 @@ func (b *backend) pathImportWrite(ctx context.Context, req *logical.Request, d *
|
||||
polReq.KeyType = keysutil.KeyType_RSA4096
|
||||
case "hmac":
|
||||
polReq.KeyType = keysutil.KeyType_HMAC
|
||||
case "aes128-cmac":
|
||||
polReq.KeyType = keysutil.KeyType_AES128_CMAC
|
||||
case "aes256-cmac":
|
||||
polReq.KeyType = keysutil.KeyType_AES256_CMAC
|
||||
default:
|
||||
return logical.ErrorResponse(fmt.Sprintf("unknown key type: %v", keyType)), logical.ErrInvalidRequest
|
||||
}
|
||||
|
||||
if polReq.KeyType.CMACSupported() && !constants.IsEnterprise {
|
||||
return logical.ErrorResponse(ErrCmacEntOnly.Error()), logical.ErrInvalidRequest
|
||||
}
|
||||
|
||||
p, _, err := b.GetPolicy(ctx, polReq, b.GetRandomReader())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1527,13 +1527,13 @@ func (p *Policy) ImportPublicOrPrivate(ctx context.Context, storage logical.Stor
|
||||
return fmt.Errorf("unable to import only public key for derived Ed25519 key: imported key should not be an Ed25519 key pair but is instead an HKDF key")
|
||||
}
|
||||
|
||||
if (p.Type == KeyType_AES128_GCM96 && len(key) != 16) ||
|
||||
((p.Type == KeyType_AES256_GCM96 || p.Type == KeyType_ChaCha20_Poly1305) && len(key) != 32) ||
|
||||
if ((p.Type == KeyType_AES128_GCM96 || p.Type == KeyType_AES128_CMAC) && len(key) != 16) ||
|
||||
((p.Type == KeyType_AES256_GCM96 || p.Type == KeyType_ChaCha20_Poly1305 || p.Type == KeyType_AES256_CMAC) && len(key) != 32) ||
|
||||
(p.Type == KeyType_HMAC && (len(key) < HmacMinKeySize || len(key) > HmacMaxKeySize)) {
|
||||
return fmt.Errorf("invalid key size %d bytes for key type %s", len(key), p.Type)
|
||||
}
|
||||
|
||||
if p.Type == KeyType_AES128_GCM96 || p.Type == KeyType_AES256_GCM96 || p.Type == KeyType_ChaCha20_Poly1305 || p.Type == KeyType_HMAC {
|
||||
if p.Type == KeyType_AES128_GCM96 || p.Type == KeyType_AES256_GCM96 || p.Type == KeyType_ChaCha20_Poly1305 || p.Type == KeyType_HMAC || p.Type == KeyType_AES128_CMAC || p.Type == KeyType_AES256_CMAC {
|
||||
entry.Key = key
|
||||
if p.Type == KeyType_HMAC {
|
||||
p.KeySize = len(key)
|
||||
@@ -1736,6 +1736,8 @@ func (p *Policy) RotateInMemory(randReader io.Reader) (retErr error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
entry.RSAPublicKey = entry.RSAKey.Public().(*rsa.PublicKey)
|
||||
}
|
||||
|
||||
if p.ConvergentEncryption {
|
||||
@@ -2394,7 +2396,7 @@ func (ke *KeyEntry) WrapKey(targetKey interface{}, targetKeyType KeyType, hash h
|
||||
|
||||
var preppedTargetKey []byte
|
||||
switch targetKeyType {
|
||||
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_HMAC:
|
||||
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_HMAC, KeyType_AES128_CMAC, KeyType_AES256_CMAC:
|
||||
var ok bool
|
||||
preppedTargetKey, ok = targetKey.([]byte)
|
||||
if !ok {
|
||||
|
||||
Reference in New Issue
Block a user