mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-11 00:57:00 +02:00
vault-24597: add key types and key creation for CMAC (#25967)
* add key types for cmac for transit key creation * add test for key creation * fix test logic and add cases * fix logic for hmac * add go doc * fix key size and add check for HMAC key
This commit is contained in:
parent
244b4998a0
commit
9ebcbf6a0c
@ -222,6 +222,10 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d *
|
||||
polReq.KeyType = keysutil.KeyType_HMAC
|
||||
case "managed_key":
|
||||
polReq.KeyType = keysutil.KeyType_MANAGED_KEY
|
||||
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
|
||||
}
|
||||
|
@ -195,3 +195,113 @@ func TestTransit_CreateKeyWithAutorotation(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestTransit_CreateKey validates transit key creation functionality
|
||||
func TestTransit_CreateKey(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
creationParams map[string]interface{}
|
||||
shouldError bool
|
||||
}{
|
||||
"AES-128": {
|
||||
creationParams: map[string]interface{}{"type": "aes128-gcm96"},
|
||||
shouldError: false,
|
||||
},
|
||||
"AES-256": {
|
||||
creationParams: map[string]interface{}{"type": "aes256-gcm96"},
|
||||
shouldError: false,
|
||||
},
|
||||
"CHACHA20": {
|
||||
creationParams: map[string]interface{}{"type": "chacha20-poly1305"},
|
||||
shouldError: false,
|
||||
},
|
||||
"ECDSA-P256": {
|
||||
creationParams: map[string]interface{}{"type": "ecdsa-p256"},
|
||||
shouldError: false,
|
||||
},
|
||||
"ECDSA-P384": {
|
||||
creationParams: map[string]interface{}{"type": "ecdsa-p384"},
|
||||
shouldError: false,
|
||||
},
|
||||
"ECDSA-P521": {
|
||||
creationParams: map[string]interface{}{"type": "ecdsa-p521"},
|
||||
shouldError: false,
|
||||
},
|
||||
"RSA_2048": {
|
||||
creationParams: map[string]interface{}{"type": "rsa-2048"},
|
||||
shouldError: false,
|
||||
},
|
||||
"RSA_3072": {
|
||||
creationParams: map[string]interface{}{"type": "rsa-3072"},
|
||||
shouldError: false,
|
||||
},
|
||||
"RSA_4096": {
|
||||
creationParams: map[string]interface{}{"type": "rsa-4096"},
|
||||
shouldError: false,
|
||||
},
|
||||
"HMAC": {
|
||||
creationParams: map[string]interface{}{"type": "hmac", "key_size": 128},
|
||||
shouldError: false,
|
||||
},
|
||||
"AES-128 CMAC": {
|
||||
creationParams: map[string]interface{}{"type": "aes128-cmac"},
|
||||
shouldError: false,
|
||||
},
|
||||
"AES-256 CMAC": {
|
||||
creationParams: map[string]interface{}{"type": "aes256-cmac"},
|
||||
shouldError: false,
|
||||
},
|
||||
"bad key type": {
|
||||
creationParams: map[string]interface{}{"type": "fake-key-type"},
|
||||
shouldError: true,
|
||||
},
|
||||
}
|
||||
|
||||
coreConfig := &vault.CoreConfig{
|
||||
LogicalBackends: map[string]logical.Factory{
|
||||
"transit": transit.Factory,
|
||||
},
|
||||
}
|
||||
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
|
||||
HandlerFunc: vaulthttp.Handler,
|
||||
})
|
||||
cluster.Start()
|
||||
defer cluster.Cleanup()
|
||||
cores := cluster.Cores
|
||||
vault.TestWaitActive(t, cores[0].Core)
|
||||
client := cores[0].Client
|
||||
err := client.Sys().Mount("transit", &api.MountInput{
|
||||
Type: "transit",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for name, tt := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
keyName, err := uuid.GenerateUUID()
|
||||
if err != nil {
|
||||
t.Fatalf("error generating key name: %s", err)
|
||||
}
|
||||
|
||||
resp, err := client.Logical().Write(fmt.Sprintf("transit/keys/%s", keyName), tt.creationParams)
|
||||
if err != nil && !tt.shouldError {
|
||||
t.Fatalf("unexpected error creating key: %s", err)
|
||||
}
|
||||
|
||||
if err == nil && tt.shouldError {
|
||||
t.Fatal("expected error but got nil")
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
keyType, ok := resp.Data["type"]
|
||||
if !ok {
|
||||
t.Fatal("missing key type in response")
|
||||
}
|
||||
|
||||
if keyType != tt.creationParams["type"] {
|
||||
t.Fatalf("incorrect key type: expected %s, got %s", tt.creationParams["type"], keyType)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -397,6 +397,12 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest, rand io
|
||||
return nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %v", req.KeyType)
|
||||
}
|
||||
|
||||
case KeyType_AES128_CMAC, KeyType_AES256_CMAC:
|
||||
if req.Derived || req.Convergent {
|
||||
cleanup()
|
||||
return nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %v", req.KeyType)
|
||||
}
|
||||
|
||||
default:
|
||||
cleanup()
|
||||
return nil, false, fmt.Errorf("unsupported key type %v", req.KeyType)
|
||||
|
@ -68,6 +68,8 @@ const (
|
||||
KeyType_RSA3072
|
||||
KeyType_MANAGED_KEY
|
||||
KeyType_HMAC
|
||||
KeyType_AES128_CMAC
|
||||
KeyType_AES256_CMAC
|
||||
)
|
||||
|
||||
const (
|
||||
@ -202,6 +204,10 @@ func (kt KeyType) String() string {
|
||||
return "hmac"
|
||||
case KeyType_MANAGED_KEY:
|
||||
return "managed_key"
|
||||
case KeyType_AES128_CMAC:
|
||||
return "aes128-cmac"
|
||||
case KeyType_AES256_CMAC:
|
||||
return "aes256-cmac"
|
||||
}
|
||||
|
||||
return "[unknown]"
|
||||
@ -1611,17 +1617,20 @@ func (p *Policy) RotateInMemory(randReader io.Reader) (retErr error) {
|
||||
DeprecatedCreationTime: now.Unix(),
|
||||
}
|
||||
|
||||
hmacKey, err := uuid.GenerateRandomBytesWithReader(32, randReader)
|
||||
if err != nil {
|
||||
return err
|
||||
if p.Type != KeyType_AES128_CMAC && p.Type != KeyType_AES256_CMAC && p.Type != KeyType_HMAC {
|
||||
hmacKey, err := uuid.GenerateRandomBytesWithReader(32, randReader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
entry.HMACKey = hmacKey
|
||||
}
|
||||
entry.HMACKey = hmacKey
|
||||
|
||||
var err error
|
||||
switch p.Type {
|
||||
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:
|
||||
// Default to 256 bit key
|
||||
numBytes := 32
|
||||
if p.Type == KeyType_AES128_GCM96 {
|
||||
if p.Type == KeyType_AES128_GCM96 || p.Type == KeyType_AES128_CMAC {
|
||||
numBytes = 16
|
||||
} else if p.Type == KeyType_HMAC {
|
||||
numBytes = p.KeySize
|
||||
|
Loading…
Reference in New Issue
Block a user