diff --git a/kms/azurekms/key_vault.go b/kms/azurekms/key_vault.go index 77b3f610..c752676b 100644 --- a/kms/azurekms/key_vault.go +++ b/kms/azurekms/key_vault.go @@ -120,7 +120,8 @@ type KeyVaultClient interface { // "public" or "AzurePublicCloud", "usgov" or "AzureUSGovernmentCloud", "china" // or "AzureChinaCloud", "german" or "AzureGermanCloud", it will default to the // public cloud if not specified; "hsm" defines if a key will be generated by an -// HSM by default. +// HSM by default; "managedhsm" defines if a key will be generated on a Azure +// Key Vault Managed HSM. // // The URI format for a key in Azure Key Vault is the following: // @@ -128,6 +129,7 @@ type KeyVaultClient interface { // - azurekms:name=key-name;vault=vault-name?version=key-version // - azurekms:name=key-name;vault=vault-name?hsm=true // - azurekms:name=key-name;vault=vault-name +// - azurekms:name=key-name;vault=vault-name;managedhsm=true // // The "name" is the key name inside the "vault"; "version" is an optional // parameter that defines the version of they key, if version is not given, the @@ -160,7 +162,7 @@ var createCredentials = func(ctx context.Context, opts apiv1.Options) (azcore.To // The 'environment' parameter in the URI defines the Cloud environment to // be used. By default Azure Public Cloud is used. - cloudConf, err := getCloudConfiguration(u.Get("environment")) + cloudConf, err := getCloudConfiguration(u.Get("environment"), u.GetBool("managedhsm")) if err != nil { return nil, err } @@ -238,7 +240,7 @@ func New(ctx context.Context, opts apiv1.Options) (*KeyVault, error) { if err != nil { return nil, err } - cloudConf, err := getCloudConfiguration(u.Get("environment")) + cloudConf, err := getCloudConfiguration(u.Get("environment"), u.GetBool("managedhsm")) if err != nil { return nil, err } @@ -394,9 +396,15 @@ type cloudConfiguration struct { // // Note that the German configuration does not appear on the SDK. It might not // work. -func getCloudConfiguration(cloudName string) (cloudConfiguration, error) { +func getCloudConfiguration(cloudName string, managed bool) (cloudConfiguration, error) { switch strings.ToUpper(cloudName) { case "", "PUBLIC", "AZURECLOUD", "AZUREPUBLICCLOUD": + if managed { + return cloudConfiguration{ + Configuration: cloud.AzurePublic, + DNSSuffix: "managedhsm.azure.net", + }, nil + } return cloudConfiguration{ Configuration: cloud.AzurePublic, DNSSuffix: "vault.azure.net", diff --git a/kms/azurekms/key_vault_test.go b/kms/azurekms/key_vault_test.go index 7cb22934..4e441598 100644 --- a/kms/azurekms/key_vault_test.go +++ b/kms/azurekms/key_vault_test.go @@ -143,6 +143,20 @@ func TestNew(t *testing.T) { ProtectionLevel: apiv1.HSM, }, }, false}, + {"ok with vault + managedhsm", func() { + createCredentials = func(ctx context.Context, opts apiv1.Options) (azcore.TokenCredential, error) { + return fakeTokenCredential{}, nil + } + }, args{context.Background(), apiv1.Options{ + URI: "azurekms:vault=my-vault;hsm=true;managedhsm=true", + }}, &KeyVault{ + client: newLazyClient("managedhsm.azure.net", lazyClientCreator(fakeTokenCredential{})), + defaults: defaultOptions{ + Vault: "my-vault", + DNSSuffix: "managedhsm.azure.net", + ProtectionLevel: apiv1.HSM, + }, + }, false}, {"ok with vault + environment", func() { createCredentials = func(ctx context.Context, opts apiv1.Options) (azcore.TokenCredential, error) { return fakeTokenCredential{}, nil @@ -753,7 +767,8 @@ func Test_getCloudConfiguration(t *testing.T) { } type args struct { - name string + name string + managed bool } tests := []struct { name string @@ -761,20 +776,22 @@ func Test_getCloudConfiguration(t *testing.T) { want cloudConfiguration wantErr bool }{ - {"empty", args{""}, cloudConfiguration{Configuration: cloud.AzurePublic, DNSSuffix: "vault.azure.net"}, false}, - {"public", args{"public"}, cloudConfiguration{Configuration: cloud.AzurePublic, DNSSuffix: "vault.azure.net"}, false}, - {"USGov", args{"USGov"}, cloudConfiguration{Configuration: cloud.AzureGovernment, DNSSuffix: "vault.usgovcloudapi.net"}, false}, - {"China", args{"China"}, cloudConfiguration{Configuration: cloud.AzureChina, DNSSuffix: "vault.azure.cn"}, false}, - {"GERMAN", args{"GERMAN"}, cloudConfiguration{Configuration: germanCloud, DNSSuffix: "vault.microsoftazure.de"}, false}, - {"AzurePublicCloud", args{"AzurePublicCloud"}, cloudConfiguration{Configuration: cloud.AzurePublic, DNSSuffix: "vault.azure.net"}, false}, - {"AzureUSGovernmentCloud", args{"AzureUSGovernmentCloud"}, cloudConfiguration{Configuration: cloud.AzureGovernment, DNSSuffix: "vault.usgovcloudapi.net"}, false}, - {"AzureChinaCloud", args{"AzureChinaCloud"}, cloudConfiguration{Configuration: cloud.AzureChina, DNSSuffix: "vault.azure.cn"}, false}, - {"AzureGermanCloud", args{"AzureGermanCloud"}, cloudConfiguration{Configuration: germanCloud, DNSSuffix: "vault.microsoftazure.de"}, false}, - {"fake", args{"fake"}, cloudConfiguration{}, true}, + {"empty", args{"", false}, cloudConfiguration{Configuration: cloud.AzurePublic, DNSSuffix: "vault.azure.net"}, false}, + {"public", args{"public", false}, cloudConfiguration{Configuration: cloud.AzurePublic, DNSSuffix: "vault.azure.net"}, false}, + {"empty managed", args{"", true}, cloudConfiguration{Configuration: cloud.AzurePublic, DNSSuffix: "managedhsm.azure.net"}, false}, + {"managed", args{"public", true}, cloudConfiguration{Configuration: cloud.AzurePublic, DNSSuffix: "managedhsm.azure.net"}, false}, + {"USGov", args{"USGov", false}, cloudConfiguration{Configuration: cloud.AzureGovernment, DNSSuffix: "vault.usgovcloudapi.net"}, false}, + {"China", args{"China", false}, cloudConfiguration{Configuration: cloud.AzureChina, DNSSuffix: "vault.azure.cn"}, false}, + {"GERMAN", args{"GERMAN", false}, cloudConfiguration{Configuration: germanCloud, DNSSuffix: "vault.microsoftazure.de"}, false}, + {"AzurePublicCloud", args{"AzurePublicCloud", false}, cloudConfiguration{Configuration: cloud.AzurePublic, DNSSuffix: "vault.azure.net"}, false}, + {"AzureUSGovernmentCloud", args{"AzureUSGovernmentCloud", false}, cloudConfiguration{Configuration: cloud.AzureGovernment, DNSSuffix: "vault.usgovcloudapi.net"}, false}, + {"AzureChinaCloud", args{"AzureChinaCloud", false}, cloudConfiguration{Configuration: cloud.AzureChina, DNSSuffix: "vault.azure.cn"}, false}, + {"AzureGermanCloud", args{"AzureGermanCloud", false}, cloudConfiguration{Configuration: germanCloud, DNSSuffix: "vault.microsoftazure.de"}, false}, + {"fake", args{"fake", false}, cloudConfiguration{}, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := getCloudConfiguration(tt.args.name) + got, err := getCloudConfiguration(tt.args.name, tt.args.managed) if (err != nil) != tt.wantErr { t.Errorf("getCloudConfiguration() error = %v, wantErr %v", err, tt.wantErr) return