ClientCertificateCredential: better exception message for unsupported file extensions (#5197)

* Cert Cred: better exception message for unsupported file extensions

* fix spelling

* Make it better

* Empty path case

* adfs

---------

Co-authored-by: Anton Kolesnyk <antkmsft@users.noreply.github.com>
This commit is contained in:
Anton Kolesnyk 2023-11-28 12:19:05 -08:00 committed by GitHub
parent bce301a841
commit b997e76e0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 6 deletions

1
.vscode/cspell.json vendored
View File

@ -52,6 +52,7 @@
"ABFS",
"ABNF",
"adamdebreceni",
"adfs",
"Adls",
"ahojnnes",
"ahsonkhan",

View File

@ -9,6 +9,7 @@
#include <azure/core/base64.hpp>
#include <azure/core/datetime.hpp>
#include <azure/core/internal/cryptography/sha_hash.hpp>
#include <azure/core/internal/strings.hpp>
#include <azure/core/io/body_stream.hpp>
#include <azure/core/platform.hpp>
#include <azure/core/uuid.hpp>
@ -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:

View File

@ -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)
{
{