diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 9f399c9e77..48993be3b7 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -52,6 +52,7 @@ "ABFS", "ABNF", "adamdebreceni", + "adfs", "Adls", "ahojnnes", "ahsonkhan", diff --git a/sdk/identity/azure-identity/src/client_certificate_credential.cpp b/sdk/identity/azure-identity/src/client_certificate_credential.cpp index 1599bd4560..b257130fd3 100644 --- a/sdk/identity/azure-identity/src/client_certificate_credential.cpp +++ b/sdk/identity/azure-identity/src/client_certificate_credential.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -399,16 +400,33 @@ ClientCertificateCredential::ClientCertificateCredential( CertificateThumbprint mdVec; try { + if (clientCertificatePath.empty()) + { + throw AuthenticationException("Certificate file path is empty."); + } + + using Azure::Core::_internal::StringExtensions; + std::string const PemExtension = ".pem"; + auto const certFileExtensionStart = clientCertificatePath.find_last_of('.'); + auto const certFileExtension = certFileExtensionStart != std::string::npos + ? clientCertificatePath.substr(certFileExtensionStart) + : std::string{}; + + if (!StringExtensions::LocaleInvariantCaseInsensitiveEqual(certFileExtension, PemExtension)) + { + throw AuthenticationException( + "Certificate format" + + (certFileExtension.empty() ? " " : " ('" + certFileExtension + "') ") + + "is not supported. Please convert your certificate to '" + PemExtension + "'."); + } + std::tie(mdVec, m_pkey) = ReadPemCertificate(clientCertificatePath); } - catch (AuthenticationException&) - { - throw; - } - catch (std::exception& e) + catch (std::exception const& e) { // WIL does not throw AuthenticationException. - throw AuthenticationException(e.what()); + throw AuthenticationException( + std::string("Identity: ClientCertificateCredential: ") + e.what()); } // Get thumbprint as hex string: diff --git a/sdk/identity/azure-identity/test/ut/client_certificate_credential_test.cpp b/sdk/identity/azure-identity/test/ut/client_certificate_credential_test.cpp index 6103da8183..511b733934 100644 --- a/sdk/identity/azure-identity/test/ut/client_certificate_credential_test.cpp +++ b/sdk/identity/azure-identity/test/ut/client_certificate_credential_test.cpp @@ -148,6 +148,77 @@ TEST_P(GetCredentialName, ) EXPECT_EQ(cred.GetCredentialName(), "ClientCertificateCredential"); } +TEST(ClientCertificateCredential, UnsupportedExtension) +{ + try + { + ClientCertificateCredential const cred( + "01234567-89ab-cdef-fedc-ba8976543210", "fedcba98-7654-3210-0123-456789abcdef", "file.pfx"); + + EXPECT_TRUE( + !"ClientCertificateCredential with unsupported extension (.pfx) is supposed to throw."); + } + catch (Azure::Core::Credentials::AuthenticationException const& ex) + { + EXPECT_EQ( + ex.what(), + std::string("Identity: ClientCertificateCredential: " + "Certificate format ('.pfx') is not supported. " + "Please convert your certificate to '.pem'.")); + } + + try + { + ClientCertificateCredential const cred( + "01234567-89ab-cdef-fedc-ba8976543210", + "fedcba98-7654-3210-0123-456789abcdef", + "file.cert"); + + EXPECT_TRUE( + !"ClientCertificateCredential with unsupported extension (.cert) is supposed to throw."); + } + catch (Azure::Core::Credentials::AuthenticationException const& ex) + { + EXPECT_EQ( + ex.what(), + std::string("Identity: ClientCertificateCredential: " + "Certificate format ('.cert') is not supported. " + "Please convert your certificate to '.pem'.")); + } + + try + { + ClientCertificateCredential const cred( + "01234567-89ab-cdef-fedc-ba8976543210", + "fedcba98-7654-3210-0123-456789abcdef", + "noextension"); + + EXPECT_TRUE(!"ClientCertificateCredential without an extension is supposed to throw."); + } + catch (Azure::Core::Credentials::AuthenticationException const& ex) + { + EXPECT_EQ( + ex.what(), + std::string("Identity: ClientCertificateCredential: " + "Certificate format is not supported. " + "Please convert your certificate to '.pem'.")); + } + + try + { + ClientCertificateCredential const cred( + "01234567-89ab-cdef-fedc-ba8976543210", "fedcba98-7654-3210-0123-456789abcdef", ""); + + EXPECT_TRUE(!"ClientCertificateCredential with an empty path is supposed to throw."); + } + catch (Azure::Core::Credentials::AuthenticationException const& ex) + { + EXPECT_EQ( + ex.what(), + std::string("Identity: ClientCertificateCredential: Certificate file path is empty.")); + } +} + TEST(ClientCertificateCredential, GetOptionsFromEnvironment) { {