Accept base64 (PEM) encoded certificate as std::string instead of vector<uint8_t> (#5991)
* Accept base64 (PEM) encoded certificate as std::string instead of vector<uint8_t> * Fix unix implementation and remove use of privacy enhance mail in comments, in favor of PEM
This commit is contained in:
parent
639fc9f594
commit
e7420dfd04
@ -99,8 +99,8 @@ namespace Azure { namespace Identity {
|
||||
explicit ClientCertificateCredential(
|
||||
std::string tenantId,
|
||||
std::string const& clientId,
|
||||
std::vector<uint8_t> clientCertificate,
|
||||
std::vector<uint8_t> privateKey,
|
||||
std::string clientCertificate,
|
||||
std::string privateKey,
|
||||
std::string const& authorityHost,
|
||||
std::vector<std::string> additionallyAllowedTenants,
|
||||
bool sendCertificateChain,
|
||||
@ -112,8 +112,8 @@ namespace Azure { namespace Identity {
|
||||
*
|
||||
* @param tenantId Tenant ID.
|
||||
* @param clientId Client ID.
|
||||
* @param clientCertificatePath The path to a Privacy Enhanced Mail (PEM) file containing
|
||||
* exactly one certificate which is used for signing along with its corresponding private key.
|
||||
* @param clientCertificatePath The path to a PEM file containing exactly one certificate which
|
||||
* is used for signing along with its corresponding private key.
|
||||
* @param options Options for token retrieval.
|
||||
*/
|
||||
explicit ClientCertificateCredential(
|
||||
@ -128,17 +128,17 @@ namespace Azure { namespace Identity {
|
||||
*
|
||||
* @param tenantId Tenant ID.
|
||||
* @param clientId Client ID.
|
||||
* @param clientCertificate The x509 certificate which is used for signing, in base64 string
|
||||
* format, including the begin and end headers.
|
||||
* @param privateKey The binary representation of the corresponding RSA private key of the
|
||||
* certificate.
|
||||
* @param clientCertificate The PEM encoded x509 certificate which is used for signing, in
|
||||
* base64 string format, including the begin and end headers.
|
||||
* @param privateKey The PEM encoded representation of the corresponding
|
||||
* RSA private key of the certificate.
|
||||
* @param options Options for token retrieval.
|
||||
*/
|
||||
explicit ClientCertificateCredential(
|
||||
std::string tenantId,
|
||||
std::string const& clientId,
|
||||
std::vector<uint8_t> clientCertificate,
|
||||
std::vector<uint8_t> privateKey,
|
||||
std::string clientCertificate,
|
||||
std::string privateKey,
|
||||
ClientCertificateCredentialOptions const& options = {});
|
||||
|
||||
/**
|
||||
@ -146,8 +146,8 @@ namespace Azure { namespace Identity {
|
||||
*
|
||||
* @param tenantId Tenant ID.
|
||||
* @param clientId Client ID.
|
||||
* @param clientCertificatePath The path to a Privacy Enhanced Mail (PEM) file containing
|
||||
* exactly one certificate which is used for signing along with its corresponding private key.
|
||||
* @param clientCertificatePath The path to a PEM file containing exactly one certificate which
|
||||
* is used for signing along with its corresponding private key.
|
||||
* @param options Options for token retrieval.
|
||||
*/
|
||||
explicit ClientCertificateCredential(
|
||||
|
||||
@ -77,21 +77,15 @@ template <typename T> std::vector<uint8_t> ToUInt8Vector(T const& in)
|
||||
return outVec;
|
||||
}
|
||||
|
||||
std::string FindPemCertificateContent(
|
||||
std::string const& path,
|
||||
std::vector<uint8_t> clientCertificate)
|
||||
std::string FindPemCertificateContent(std::string const& path, std::string clientCertificate)
|
||||
{
|
||||
std::string pem{};
|
||||
std::string pem = clientCertificate;
|
||||
if (clientCertificate.empty())
|
||||
{
|
||||
auto pemContent{FileBodyStream(path).ReadToEnd()};
|
||||
pem = std::string{pemContent.begin(), pemContent.end()};
|
||||
pemContent = {};
|
||||
}
|
||||
else
|
||||
{
|
||||
pem = std::string{clientCertificate.begin(), clientCertificate.end()};
|
||||
}
|
||||
|
||||
const std::string beginHeader = std::string("-----BEGIN CERTIFICATE-----");
|
||||
auto headerStart = pem.find(beginHeader);
|
||||
@ -127,7 +121,7 @@ std::string GetJwtToken(
|
||||
CertificateThumbprint mdVec,
|
||||
bool sendCertificateChain,
|
||||
std::string const& clientCertificatePath,
|
||||
std::vector<uint8_t> clientCertificate = {})
|
||||
std::string clientCertificate = {})
|
||||
{
|
||||
std::string thumbprintHexStr;
|
||||
std::string thumbprintBase64Str;
|
||||
@ -328,15 +322,13 @@ UniquePrivateKey ImportPemPrivateKey(std::string const& pem)
|
||||
}
|
||||
|
||||
std::tuple<CertificateThumbprint, UniquePrivateKey> ReadPemCertificate(
|
||||
std::vector<uint8_t> clientCertificate,
|
||||
std::vector<uint8_t> privateKey)
|
||||
std::string clientCertificate,
|
||||
std::string privateKey)
|
||||
{
|
||||
auto certContext = ImportPemCertificate(clientCertificate);
|
||||
|
||||
// We only support the RSA private key type.
|
||||
return std::make_tuple(
|
||||
GetThumbprint(certContext.get()),
|
||||
ImportRsaPrivateKey(privateKey.data(), static_cast<DWORD>(privateKey.size())));
|
||||
return std::make_tuple(GetThumbprint(certContext.get()), ImportPemPrivateKey(privateKey));
|
||||
}
|
||||
|
||||
std::tuple<CertificateThumbprint, UniquePrivateKey> ReadPemCertificate(std::string const& path)
|
||||
@ -430,20 +422,21 @@ std::tuple<CertificateThumbprint, UniquePrivateKey> GetThumbprintAndKey(
|
||||
}
|
||||
|
||||
std::tuple<CertificateThumbprint, UniquePrivateKey> ReadPemCertificate(
|
||||
std::vector<uint8_t> clientCertificate,
|
||||
std::vector<uint8_t> privateKey)
|
||||
std::string clientCertificate,
|
||||
std::string privateKey)
|
||||
{
|
||||
// Create a BIO from the private key vector data in memory.
|
||||
UniqueHandle<BIO> bioKey(BIO_new_mem_buf(privateKey.data(), static_cast<int>(privateKey.size())));
|
||||
if (!bioKey)
|
||||
{
|
||||
throw AuthenticationException("Failed to create BIO for the binary private key.");
|
||||
throw AuthenticationException("Failed to create BIO for the PEM encoded private key.");
|
||||
}
|
||||
|
||||
UniquePrivateKey pkey{d2i_PrivateKey_bio(bioKey.get(), nullptr)};
|
||||
UniquePrivateKey pkey{PEM_read_bio_PrivateKey(bioKey.get(), nullptr, nullptr, nullptr)};
|
||||
if (!pkey)
|
||||
{
|
||||
throw AuthenticationException("Failed to read the binary private key for the certificate.");
|
||||
throw AuthenticationException(
|
||||
"Failed to read the PEM encoded private key for the certificate.");
|
||||
}
|
||||
|
||||
// Create a BIO from the client certificate vector data in memory.
|
||||
@ -592,8 +585,8 @@ ClientCertificateCredential::ClientCertificateCredential(
|
||||
ClientCertificateCredential::ClientCertificateCredential(
|
||||
std::string tenantId,
|
||||
std::string const& clientId,
|
||||
std::vector<uint8_t> clientCertificate,
|
||||
std::vector<uint8_t> privateKey,
|
||||
std::string clientCertificate,
|
||||
std::string privateKey,
|
||||
std::string const& authorityHost,
|
||||
std::vector<std::string> additionallyAllowedTenants,
|
||||
bool sendCertificateChain,
|
||||
@ -662,8 +655,8 @@ ClientCertificateCredential::ClientCertificateCredential(
|
||||
ClientCertificateCredential::ClientCertificateCredential(
|
||||
std::string tenantId,
|
||||
std::string const& clientId,
|
||||
std::vector<uint8_t> clientCertificate,
|
||||
std::vector<uint8_t> privateKey,
|
||||
std::string clientCertificate,
|
||||
std::string privateKey,
|
||||
ClientCertificateCredentialOptions const& options)
|
||||
: ClientCertificateCredential(
|
||||
tenantId,
|
||||
|
||||
@ -95,71 +95,6 @@ std::string ExampleValidPrivateKeyString
|
||||
"qxxMaq+sv5e9c56EJtctxNnAK27JsoadD+b+NjysZgMeKUdBIzSrHQ==\n"
|
||||
"-----END RSA PRIVATE KEY-----\n";
|
||||
// cspell:enable
|
||||
|
||||
std::vector<uint8_t> ExampleValidPrivateKey{
|
||||
48, 130, 4, 164, 2, 1, 0, 2, 130, 1, 1, 0, 207, 118, 110, 41, 186, 67, 187,
|
||||
186, 1, 49, 243, 5, 235, 154, 142, 21, 32, 74, 34, 114, 158, 240, 221, 11, 4, 36,
|
||||
96, 54, 108, 204, 125, 156, 115, 47, 194, 232, 6, 231, 139, 117, 225, 10, 95, 168, 20,
|
||||
24, 65, 98, 222, 47, 81, 230, 165, 192, 222, 138, 245, 67, 251, 94, 89, 93, 225, 139,
|
||||
8, 245, 89, 4, 120, 104, 99, 198, 86, 26, 38, 223, 132, 0, 51, 169, 13, 15, 244,
|
||||
38, 181, 147, 39, 99, 188, 30, 46, 37, 193, 39, 23, 244, 88, 181, 11, 250, 159, 163,
|
||||
176, 153, 211, 181, 192, 157, 182, 36, 215, 17, 148, 203, 89, 170, 105, 219, 253, 13, 8,
|
||||
159, 103, 227, 92, 70, 221, 151, 206, 127, 25, 153, 88, 204, 196, 17, 119, 39, 200, 211,
|
||||
42, 226, 73, 16, 92, 97, 93, 164, 131, 76, 222, 92, 44, 95, 152, 43, 193, 222, 182,
|
||||
250, 35, 82, 169, 161, 65, 71, 150, 71, 135, 182, 71, 131, 194, 109, 21, 29, 65, 45,
|
||||
224, 124, 252, 130, 23, 1, 211, 75, 72, 229, 228, 182, 124, 125, 171, 62, 66, 13, 64,
|
||||
167, 58, 251, 68, 20, 11, 98, 136, 9, 0, 190, 27, 50, 108, 96, 54, 240, 64, 230,
|
||||
168, 229, 88, 100, 243, 65, 249, 45, 27, 140, 244, 215, 115, 191, 231, 212, 222, 82, 231,
|
||||
146, 214, 2, 129, 120, 11, 244, 5, 248, 47, 244, 125, 103, 131, 243, 182, 230, 168, 254,
|
||||
166, 209, 2, 3, 1, 0, 1, 2, 130, 1, 1, 0, 196, 25, 34, 186, 40, 137, 59,
|
||||
153, 238, 229, 66, 220, 150, 189, 233, 141, 72, 143, 42, 142, 131, 116, 18, 204, 5, 231,
|
||||
72, 86, 73, 114, 229, 76, 139, 136, 90, 200, 45, 54, 146, 25, 35, 85, 69, 227, 190,
|
||||
210, 202, 131, 100, 150, 255, 232, 111, 70, 166, 84, 92, 207, 28, 124, 43, 38, 213, 57,
|
||||
49, 135, 143, 211, 236, 232, 103, 95, 35, 37, 231, 22, 161, 83, 251, 128, 208, 139, 2,
|
||||
241, 207, 241, 191, 106, 195, 119, 23, 145, 178, 72, 124, 153, 7, 124, 98, 77, 76, 182,
|
||||
82, 8, 165, 24, 8, 112, 74, 169, 249, 236, 113, 99, 225, 102, 118, 87, 109, 146, 243,
|
||||
82, 145, 197, 84, 4, 220, 16, 157, 120, 190, 161, 99, 225, 19, 104, 46, 163, 104, 53,
|
||||
4, 249, 54, 129, 177, 116, 251, 113, 111, 74, 180, 60, 67, 1, 135, 131, 235, 144, 39,
|
||||
10, 208, 164, 159, 146, 7, 212, 242, 185, 1, 90, 184, 100, 121, 255, 4, 170, 31, 221,
|
||||
220, 20, 126, 88, 11, 255, 175, 228, 142, 234, 91, 166, 80, 123, 71, 251, 172, 66, 144,
|
||||
15, 38, 198, 87, 57, 1, 148, 162, 114, 24, 37, 88, 152, 249, 251, 93, 175, 240, 38,
|
||||
184, 176, 179, 225, 89, 33, 241, 243, 127, 121, 180, 144, 152, 160, 196, 151, 127, 31, 4,
|
||||
235, 156, 164, 160, 248, 127, 40, 6, 9, 224, 238, 86, 75, 116, 22, 22, 28, 193, 137,
|
||||
132, 13, 2, 129, 129, 0, 227, 201, 168, 91, 187, 51, 122, 11, 223, 46, 229, 5, 107,
|
||||
75, 7, 127, 34, 174, 55, 43, 206, 191, 181, 174, 119, 139, 26, 210, 92, 29, 40, 241,
|
||||
210, 249, 171, 112, 47, 164, 205, 81, 96, 128, 26, 74, 38, 96, 0, 196, 123, 122, 162,
|
||||
98, 3, 23, 13, 127, 84, 222, 25, 86, 235, 57, 45, 96, 88, 244, 222, 217, 209, 131,
|
||||
136, 129, 142, 159, 39, 114, 18, 193, 84, 183, 247, 89, 222, 83, 61, 28, 53, 84, 171,
|
||||
184, 101, 110, 55, 203, 192, 81, 133, 133, 149, 251, 118, 120, 179, 89, 242, 48, 64, 192,
|
||||
52, 86, 202, 70, 98, 251, 44, 48, 116, 230, 133, 135, 116, 147, 35, 20, 175, 203, 233,
|
||||
135, 2, 129, 129, 0, 233, 40, 85, 226, 253, 145, 66, 37, 243, 145, 110, 134, 29, 32,
|
||||
89, 12, 133, 71, 9, 229, 176, 188, 137, 93, 58, 81, 31, 27, 188, 51, 101, 110, 30,
|
||||
243, 3, 67, 133, 244, 140, 181, 124, 137, 175, 55, 219, 19, 37, 193, 181, 82, 168, 17,
|
||||
39, 79, 232, 217, 230, 245, 110, 223, 181, 204, 167, 91, 222, 185, 75, 222, 19, 30, 236,
|
||||
187, 250, 135, 239, 30, 142, 137, 2, 111, 32, 255, 75, 151, 239, 76, 25, 219, 162, 212,
|
||||
242, 168, 100, 36, 196, 214, 154, 195, 141, 4, 210, 139, 193, 76, 228, 21, 62, 213, 26,
|
||||
199, 90, 6, 88, 154, 155, 84, 75, 190, 55, 147, 81, 23, 80, 130, 119, 237, 34, 231,
|
||||
2, 129, 129, 0, 224, 86, 26, 153, 61, 36, 213, 110, 27, 191, 243, 142, 2, 189, 66,
|
||||
4, 212, 3, 0, 19, 4, 235, 137, 226, 233, 152, 246, 49, 118, 198, 193, 44, 104, 187,
|
||||
187, 60, 33, 176, 13, 5, 184, 36, 113, 191, 213, 75, 119, 118, 10, 166, 28, 134, 170,
|
||||
196, 105, 102, 158, 14, 158, 166, 27, 195, 148, 12, 239, 143, 58, 107, 11, 12, 159, 195,
|
||||
248, 210, 133, 230, 178, 209, 244, 189, 185, 189, 168, 88, 18, 55, 85, 206, 173, 208, 77,
|
||||
20, 223, 158, 171, 41, 158, 118, 145, 223, 182, 45, 233, 117, 12, 48, 185, 148, 145, 247,
|
||||
103, 255, 42, 60, 116, 168, 196, 120, 195, 201, 67, 230, 37, 6, 154, 156, 24, 193, 2,
|
||||
129, 128, 89, 174, 98, 26, 197, 93, 178, 11, 214, 252, 1, 127, 36, 132, 228, 187, 164,
|
||||
40, 6, 238, 138, 100, 122, 145, 153, 116, 202, 122, 104, 145, 124, 90, 55, 29, 82, 12,
|
||||
14, 226, 89, 157, 21, 34, 0, 123, 131, 144, 129, 221, 88, 89, 74, 188, 14, 90, 246,
|
||||
61, 154, 80, 157, 44, 255, 72, 144, 183, 13, 156, 72, 74, 75, 32, 129, 254, 108, 7,
|
||||
13, 58, 187, 168, 135, 127, 39, 58, 11, 97, 141, 113, 192, 32, 115, 41, 101, 140, 207,
|
||||
184, 52, 222, 54, 249, 48, 172, 194, 47, 111, 82, 156, 8, 111, 250, 152, 42, 69, 190,
|
||||
91, 38, 92, 200, 183, 185, 154, 182, 215, 98, 24, 93, 150, 179, 103, 209, 2, 129, 128,
|
||||
55, 188, 105, 17, 190, 48, 228, 148, 77, 53, 227, 1, 91, 44, 108, 54, 52, 82, 207,
|
||||
120, 220, 83, 125, 214, 160, 102, 106, 3, 106, 15, 42, 51, 40, 0, 42, 14, 130, 175,
|
||||
117, 28, 76, 208, 137, 72, 14, 115, 169, 182, 62, 0, 125, 186, 73, 212, 148, 225, 52,
|
||||
226, 67, 96, 26, 84, 248, 12, 232, 241, 74, 30, 116, 3, 96, 157, 219, 89, 218, 125,
|
||||
117, 69, 40, 230, 149, 14, 147, 19, 245, 134, 150, 200, 171, 28, 76, 106, 175, 172, 191,
|
||||
151, 189, 115, 158, 132, 38, 215, 45, 196, 217, 192, 43, 110, 201, 178, 134, 157, 15, 230,
|
||||
254, 54, 60, 172, 102, 3, 30, 41, 71, 65, 35, 52, 171, 29, 171};
|
||||
} // namespace
|
||||
|
||||
class GetCredentialName : public ::testing::TestWithParam<CertFormat> {
|
||||
@ -504,6 +439,7 @@ TEST(ClientCertificateCredential, InvalidContentInFile)
|
||||
|
||||
TEST(ClientCertificateCredential, InvalidContentInMemory)
|
||||
{
|
||||
// Empty string parameters.
|
||||
EXPECT_THROW(
|
||||
ClientCertificateCredential const cred(
|
||||
"01234567-89ab-cdef-fedc-ba8976543210",
|
||||
@ -513,13 +449,29 @@ TEST(ClientCertificateCredential, InvalidContentInMemory)
|
||||
{}),
|
||||
Azure::Core::Credentials::AuthenticationException);
|
||||
|
||||
EXPECT_THROW(
|
||||
ClientCertificateCredential const cred(
|
||||
"01234567-89ab-cdef-fedc-ba8976543210",
|
||||
"fedcba98-7654-3210-0123-456789abcdef",
|
||||
ExampleValidCertString,
|
||||
{},
|
||||
{}),
|
||||
Azure::Core::Credentials::AuthenticationException);
|
||||
|
||||
EXPECT_THROW(
|
||||
ClientCertificateCredential const cred(
|
||||
"01234567-89ab-cdef-fedc-ba8976543210",
|
||||
"fedcba98-7654-3210-0123-456789abcdef",
|
||||
{},
|
||||
ExampleValidPrivateKeyString),
|
||||
Azure::Core::Credentials::AuthenticationException);
|
||||
|
||||
// cspell:disable
|
||||
std::string invalidContents[]
|
||||
= {"a",
|
||||
"-----BEGIN CERTIFICATE-----\na",
|
||||
"-----BEGIN RSA PRIVATE KEY-----\na",
|
||||
"-----BEGIN RSA PRIVATE KEY-----\na-----BEGIN CERTIFICATE-----\na",
|
||||
ExampleValidPrivateKeyString,
|
||||
"-----BEGIN RSA PRIVATE "
|
||||
"KEY-----\nqxxMaq+sv5e9c56EJtctxNnAK27JsoadD+b+NjysZgMeKUdBIzSrHQ==\n-----END RSA "
|
||||
"PRIVATE KEY-----\n-----BEGIN "
|
||||
@ -527,18 +479,14 @@ TEST(ClientCertificateCredential, InvalidContentInMemory)
|
||||
"-END CERTIFICATE-----"};
|
||||
// cspell:enable
|
||||
|
||||
std::vector<uint8_t> validCert(ExampleValidCertString.begin(), ExampleValidCertString.end());
|
||||
|
||||
for (std::string invalidContent : invalidContents)
|
||||
{
|
||||
std::vector<uint8_t> invalid(invalidContent.begin(), invalidContent.end());
|
||||
|
||||
EXPECT_THROW(
|
||||
ClientCertificateCredential const cred(
|
||||
"01234567-89ab-cdef-fedc-ba8976543210",
|
||||
"fedcba98-7654-3210-0123-456789abcdef",
|
||||
validCert,
|
||||
invalid,
|
||||
ExampleValidCertString,
|
||||
invalidContent,
|
||||
{}),
|
||||
Azure::Core::Credentials::AuthenticationException);
|
||||
|
||||
@ -546,8 +494,8 @@ TEST(ClientCertificateCredential, InvalidContentInMemory)
|
||||
ClientCertificateCredential const cred(
|
||||
"01234567-89ab-cdef-fedc-ba8976543210",
|
||||
"fedcba98-7654-3210-0123-456789abcdef",
|
||||
invalid,
|
||||
ExampleValidPrivateKey,
|
||||
invalidContent,
|
||||
ExampleValidPrivateKeyString,
|
||||
{}),
|
||||
Azure::Core::Credentials::AuthenticationException);
|
||||
|
||||
@ -555,8 +503,8 @@ TEST(ClientCertificateCredential, InvalidContentInMemory)
|
||||
ClientCertificateCredential const cred(
|
||||
"01234567-89ab-cdef-fedc-ba8976543210",
|
||||
"fedcba98-7654-3210-0123-456789abcdef",
|
||||
invalid,
|
||||
invalid,
|
||||
invalidContent,
|
||||
invalidContent,
|
||||
{}),
|
||||
Azure::Core::Credentials::AuthenticationException);
|
||||
}
|
||||
@ -590,13 +538,11 @@ TEST_P(GetTokenFromCertInMemory, )
|
||||
options.Transport.Transport = transport;
|
||||
options.SendCertificateChain = GetSendCertChain();
|
||||
|
||||
std::vector<uint8_t> cert(ExampleValidCertString.begin(), ExampleValidCertString.end());
|
||||
|
||||
return std::make_unique<ClientCertificateCredential>(
|
||||
"01234567-89ab-cdef-fedc-ba8976543210",
|
||||
"fedcba98-7654-3210-0123-456789abcdef",
|
||||
cert,
|
||||
ExampleValidPrivateKey,
|
||||
ExampleValidCertString,
|
||||
ExampleValidPrivateKeyString,
|
||||
options);
|
||||
},
|
||||
{{{"https://azure.com/.default"}}, {{}}},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user