From a32823ace3910332da4fb81d57b87b1866661bc9 Mon Sep 17 00:00:00 2001 From: magodo Date: Fri, 18 Feb 2022 10:35:20 +0800 Subject: [PATCH 1/2] azidentity: environmnet credential add supports for the cert password --- sdk/azidentity/README.md | 3 ++- sdk/azidentity/environment_credential.go | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/sdk/azidentity/README.md b/sdk/azidentity/README.md index 498b3b55d45b..0904dd65347e 100644 --- a/sdk/azidentity/README.md +++ b/sdk/azidentity/README.md @@ -170,7 +170,8 @@ client := armresources.NewResourceGroupsClient("subscription ID", chain, nil) |-|- |`AZURE_CLIENT_ID`|id of an Azure Active Directory application |`AZURE_TENANT_ID`|id of the application's Azure Active Directory tenant -|`AZURE_CLIENT_CERTIFICATE_PATH`|path to a PEM-encoded certificate file including private key (without password protection) +|`AZURE_CLIENT_CERTIFICATE_PATH`|path to a PEM-encoded certificate file including private key +|`AZURE_CLIENT_CERTIFICATE_PASSWORD`|password of the certificate file #### Username and password diff --git a/sdk/azidentity/environment_credential.go b/sdk/azidentity/environment_credential.go index cb12c45e0ea1..5b24f4e5855e 100644 --- a/sdk/azidentity/environment_credential.go +++ b/sdk/azidentity/environment_credential.go @@ -37,8 +37,8 @@ type EnvironmentCredentialOptions struct { // Service principal with certificate: // - AZURE_TENANT_ID: ID of the service principal's tenant. Also called its "directory" ID. // - AZURE_CLIENT_ID: the service principal's client ID -// - AZURE_CLIENT_CERTIFICATE_PATH: path to a PEM or PKCS12 certificate file including the private key. The -// certificate must not be password-protected. +// - AZURE_CLIENT_CERTIFICATE_PATH: path to a PEM or PKCS12 certificate file including the private key. +// - AZURE_CLIENT_CERTIFICATE_PASSWORD: password of the certificate file. // // User with username and password: // - AZURE_CLIENT_ID: the application's client ID @@ -79,7 +79,11 @@ func NewEnvironmentCredential(options *EnvironmentCredentialOptions) (*Environme if err != nil { return nil, fmt.Errorf(`failed to read certificate file "%s": %v`, certPath, err) } - certs, key, err := ParseCertificates(certData, nil) + var password []byte + if v := os.Getenv("AZURE_CLIENT_CERTIFICATE_PASSWORD"); v != "" { + password = []byte(v) + } + certs, key, err := ParseCertificates(certData, password) if err != nil { return nil, fmt.Errorf(`failed to load certificate from "%s": %v`, certPath, err) } From c91b7d9f9b5c731229f1c2d5c9faaa55769e77ee Mon Sep 17 00:00:00 2001 From: Charles Lowell <10964656+chlowell@users.noreply.github.com> Date: Fri, 3 Jun 2022 15:50:14 -0700 Subject: [PATCH 2/2] add test --- sdk/azidentity/environment_credential_test.go | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/sdk/azidentity/environment_credential_test.go b/sdk/azidentity/environment_credential_test.go index 85f67a40572d..4d3b475a03e0 100644 --- a/sdk/azidentity/environment_credential_test.go +++ b/sdk/azidentity/environment_credential_test.go @@ -9,8 +9,10 @@ package azidentity import ( "context" "errors" + "fmt" "os" "reflect" + "strings" "testing" "github.com/Azure/azure-sdk-for-go/sdk/azcore" @@ -116,6 +118,36 @@ func TestEnvironmentCredential_ClientCertificatePathSet(t *testing.T) { } } +func TestEnvironmentCredential_ClientCertificatePassword(t *testing.T) { + for key, value := range map[string]string{ + "AZURE_TENANT_ID": fakeTenantID, + azureClientID: fakeClientID, + "AZURE_CLIENT_CERTIFICATE_PATH": "testdata/certificate_encrypted_key.pfx", + } { + t.Setenv(key, value) + } + for _, correctPassword := range []bool{true, false} { + t.Run(fmt.Sprintf("%v", correctPassword), func(t *testing.T) { + password := "wrong password" + if correctPassword { + password = "password" + } + t.Setenv("AZURE_CLIENT_CERTIFICATE_PASSWORD", password) + cred, err := NewEnvironmentCredential(nil) + if correctPassword { + if err != nil { + t.Fatal(err) + } + if _, ok := cred.cred.(*ClientCertificateCredential); !ok { + t.Fatalf("expected *azidentity.ClientCertificateCredential, got %t", cred) + } + } else if err == nil || !strings.Contains(err.Error(), "password") { + t.Fatal("expected an error about the password") + } + }) + } +} + func TestEnvironmentCredential_UsernameOnlySet(t *testing.T) { resetEnvironmentVarsForTest() err := os.Setenv("AZURE_TENANT_ID", fakeTenantID)