mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +00: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:
		| @@ -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(), | ||||
| 	} | ||||
|  | ||||
| 	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 | ||||
| 	} | ||||
|  | ||||
| 	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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Rachel Culpepper
					Rachel Culpepper