Adding Key Vault Certificates - GetCertificateWithPolicy API (#2818)

* certs one api checkpoint
This commit is contained in:
Victor Vazquez 2021-09-07 13:44:15 -07:00 committed by GitHub
parent 841675b622
commit 8f0d6728c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 2385 additions and 0 deletions

View File

@ -14,3 +14,4 @@ endif()
add_subdirectory(azure-security-keyvault-keys)
add_subdirectory(azure-security-keyvault-secrets)
add_subdirectory(azure-security-keyvault-certificates)

View File

@ -0,0 +1,7 @@
# Release History
## 4.0.0-beta.1 (Unreleased)
### New Features
- Added `CertificateClient` with `GetCertificate()` and `GetCertificateVersion()` APIs.

View File

@ -0,0 +1,85 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required (VERSION 3.13)
project(azure-security-keyvault-certificates LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake-modules")
include(AzureVcpkg)
include(AzureVersion)
include(AzureCodeCoverage)
include(AzureTransportAdapters)
include(AzureDoxygen)
include(AzureGlobalCompileOptions)
az_vcpkg_integrate()
if(NOT AZ_ALL_LIBRARIES)
find_package(azure-core-cpp "1.2.0" CONFIG QUIET)
if(NOT azure-core-cpp_FOUND)
find_package(azure-core-cpp "1.2.0" REQUIRED)
endif()
endif()
set(
AZURE_KEYVAULT_CERTIFICATES_HEADER
inc/azure/keyvault/certificates/certificate_client.hpp
inc/azure/keyvault/certificates/certificate_client_models.hpp
inc/azure/keyvault/certificates/certificate_client_options.hpp
)
set(
AZURE_KEYVAULT_CERTIFICATES_SOURCE
src/certificate_client.cpp
src/keyvault_certificate.cpp
src/keyvault_certificates_common_request.cpp
)
add_library(azure-security-keyvault-certificates
${AZURE_KEYVAULT_CERTIFICATES_HEADER} ${AZURE_KEYVAULT_CERTIFICATES_SOURCE}
)
add_library(Azure::azure-security-keyvault-certificates ALIAS azure-security-keyvault-certificates)
target_include_directories(
azure-security-keyvault-certificates
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
$<INSTALL_INTERFACE:include>
)
target_link_libraries(azure-security-keyvault-certificates PUBLIC Azure::azure-core)
# coverage. Has no effect if BUILD_CODE_COVERAGE is OFF
create_code_coverage(keyvault azure-security-keyvault-certificates azure-security-keyvault-certificates-test)
get_az_version("${CMAKE_CURRENT_SOURCE_DIR}/src/private/package_version.hpp")
generate_documentation(azure-security-keyvault-certificates ${AZ_LIBRARY_VERSION})
if(BUILD_TESTING)
if (NOT AZ_ALL_LIBRARIES)
include(AddGoogleTest)
enable_testing ()
endif()
add_subdirectory(test/ut)
endif()
# if (BUILD_PERFORMANCE_TESTS)
# add_subdirectory(test/perf)
# endif()
# if(BUILD_SAMPLES)
# add_subdirectory(test/samples)
# endif()
az_vcpkg_export(
azure-security-keyvault-certificates
SECURITY_KEYVAULT_CERTIFICATES
"azure/keyvault/certificates/dll_import_export.hpp"
)

View File

@ -0,0 +1,32 @@
azure-sdk-for-cpp
NOTICES AND INFORMATION
Do Not Translate or Localize
This software incorporates material from third parties. Microsoft makes certain
open source code available at https://3rdpartysource.microsoft.com, or you may
send a check or money order for US $5.00, including the product name, the open
source component name, and version number, to:
Source Code Compliance Team
Microsoft Corporation
One Microsoft Way
Redmond, WA 98052
USA
Notwithstanding any other terms, you may reverse engineer this software to the
extent required to debug changes to any libraries licensed under the GNU Lesser
General Public License.
------------------------------------------------------------------------------
Azure SDK for C++ uses third-party libraries or other resources that may be
distributed under licenses different than the Azure SDK for C++ software.
In the event that we accidentally failed to list a required notice, please
bring it to our attention. Post an issue or email us:
azcppsdkhelp@microsoft.com
The attached notices are provided for information only.

View File

@ -0,0 +1,39 @@
# Azure Key Vault Certificates client library for C++
Azure Key Vault is a cloud service that provides secure storage and automated management of certificates used throughout a cloud application. Multiple certificates, and multiple versions of the same certificate, can be kept in the Azure Key Vault. Each certificate in the vault has a policy associated with it which controls the issuance and lifetime of the certificate, along with actions to be taken as certificates near expiry.
The Azure Key Vault certificates client library enables programmatically managing certificates, offering methods to get certificates, policies, issuers, and contacts.
[Source code][certificate_client_src] | [API reference documentation][api_reference] | [Product documentation][keyvault_docs]
### Additional concepts
<!-- CLIENT COMMON BAR -->
[Replaceable HTTP transport adapter](https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/core/azure-core#http-transport-adapter) |
[Long-running operations](https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/core/azure-core#long-running-operations) |
### Additional Documentation
- For more extensive documentation on Azure Key Vault, see the [API reference documentation][keyvault_rest].
## Contributing
See the [CONTRIBUTING.md][contributing] for details on building, testing, and contributing to these libraries.
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA)
declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment).
Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct][code_of_conduct].
For more information see the [Code of Conduct FAQ][coc_faq] or contact opencode@microsoft.com with any additional questions or comments.
<!-- LINKS -->
[api_reference]: https://azure.github.io/azure-sdk-for-cpp/keyvault.html
[code_of_conduct]: https://opensource.microsoft.com/codeofconduct/
[keyvault_docs]: https://docs.microsoft.com/azure/key-vault/
[keyvault_rest]: https://docs.microsoft.com/rest/api/keyvault/
[contributing]: https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md
[coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/

View File

@ -0,0 +1,36 @@
{
"Registrations": [
{
"Component": {
"Type": "git",
"git": {
"RepositoryUrl": "https://github.com/google/googletest",
"CommitHash": "703bd9caab50b139428cea1aaff9974ebee5742e"
}
},
"DevelopmentDependency": true
},
{
"Component": {
"Type": "other",
"Other": {
"Name": "clang-format",
"Version": "9.0.0-2",
"DownloadUrl": "https://ubuntu.pkgs.org/18.04/ubuntu-updates-universe-amd64/clang-format-9_9-2~ubuntu18.04.2_amd64.deb.html"
}
},
"DevelopmentDependency": true
},
{
"Component": {
"Type": "other",
"Other": {
"Name": "doxygen",
"Version": "1.8.20",
"DownloadUrl": "http://doxygen.nl/files/doxygen-1.8.20-setup.exe"
}
},
"DevelopmentDependency": true
}
]
}

View File

@ -0,0 +1,112 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
* @brief Defines the Key Vault Certificates client.
*
*/
#pragma once
#include "azure/keyvault/certificates/certificate_client_models.hpp"
#include "azure/keyvault/certificates/certificate_client_options.hpp"
#include <azure/core/context.hpp>
#include <azure/core/credentials/credentials.hpp>
#include <azure/core/http/http.hpp>
#include <azure/core/internal/http/pipeline.hpp>
#include <azure/core/response.hpp>
#include <memory>
#include <string>
namespace Azure { namespace Security { namespace KeyVault { namespace Certificates {
/**
* @brief The CertificateClient provides synchronous methods to manage KeyVaultCertificate in
* Azure Key Vault.
*
* @details The client supports retrieving KeyVaultCertificate.
*/
class CertificateClient
#if !defined(TESTING_BUILD)
final
#endif
{
protected:
// Using a shared pipeline for a client to share it with LRO (like delete key)
Azure::Core::Url m_vaultUrl;
std::string m_apiVersion;
std::shared_ptr<Azure::Core::Http::_internal::HttpPipeline> m_pipeline;
public:
/**
* @brief Destructor.
*
*/
virtual ~CertificateClient() = default;
/**
* @brief Construct a new Key Client object
*
* @param vaultUrl The URL address where the client will send the requests to.
* @param credential The authentication method to use.
* @param options The options to customize the client behavior.
*/
explicit CertificateClient(
std::string const& vaultUrl,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
CertificateClientOptions options = CertificateClientOptions());
/**
* @brief Construct a new Key Client object from another key client.
*
* @param keyClient An existing key vault key client.
*/
explicit CertificateClient(CertificateClient const& keyClient) = default;
/**
* @brief Returns the latest version of the KeyVaultCertificate along with its
* CertificatePolicy.
*
* @remark This operation requires the certificates/get permission.
*
* @param name The name of the certificate.
* @param context The context for the operation can be used for request cancellation.
* @return A response containing the certificate and policy as a KeyVaultCertificateWithPolicy
* instance.
*/
Azure::Response<KeyVaultCertificateWithPolicy> GetCertificate(
std::string const& name,
Azure::Core::Context const& context = Azure::Core::Context()) const;
/**
* @brief Returns a specific version of the certificate without its CertificatePolicy.
*
* @details If the version is not set in the options, the latest version is returned.
*
* @remark This operation requires the certificates/get permission.
*
* @param name The name of the certificate.
* @param options Optional parameters for this operation.
* @param context The context for the operation can be used for request cancellation.
* @return A response containing the certificate and policy as a KeyVaultCertificateWithPolicy
* instance.
*/
Azure::Response<KeyVaultCertificate> GetCertificateVersion(
std::string const& name,
GetCertificateOptions const& options = GetCertificateOptions(),
Azure::Core::Context const& context = Azure::Core::Context()) const;
private:
std::unique_ptr<Azure::Core::Http::RawResponse> SendRequest(
Azure::Core::Http::Request& request,
Azure::Core::Context const& context) const;
Azure::Core::Http::Request CreateRequest(
Azure::Core::Http::HttpMethod method,
std::vector<std::string> const& path = {},
Azure::Core::IO::BodyStream* content = nullptr) const;
};
}}}} // namespace Azure::Security::KeyVault::Certificates

View File

@ -0,0 +1,805 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
* @brief Defines the Key Vault Certificates types.
*
*/
#pragma once
#include "azure/keyvault/certificates/dll_import_export.hpp"
#include <azure/core/context.hpp>
#include <azure/core/http/http.hpp>
#include <azure/core/nullable.hpp>
#include <azure/core/response.hpp>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
namespace Azure { namespace Security { namespace KeyVault { namespace Certificates {
/**
* @brief Contains identity and other basic properties of a Certificate.
*
*/
struct CertificateProperties final
{
// Attributes
/**
* @brief Indicate when the certificate will be valid and can be used for cryptographic
* operations.
*
*/
Azure::Nullable<Azure::DateTime> NotBefore;
/**
* @brief Indicate when the certificate will expire and cannot be used for cryptographic
* operations.
*
*/
Azure::Nullable<Azure::DateTime> ExpiresOn;
/**
* @brief Indicate when the certificate was created.
*
*/
Azure::Nullable<Azure::DateTime> CreatedOn;
/**
* @brief Indicate when the certificate was updated.
*
*/
Azure::Nullable<Azure::DateTime> UpdatedOn;
/**
* @brief The number of days a certificate is retained before being deleted for a soft
* delete-enabled Key Vault.
*
*/
Azure::Nullable<int32_t> RecoverableDays;
/**
* @brief The recovery level currently in effect for keys in the Key Vault.
*
* @remark If Purgeable, the certificate can be permanently deleted by an authorized user;
* otherwise, only the service can purge the keys at the end of the retention interval.
*
*/
Azure::Nullable<std::string> RecoveryLevel;
// Properties
/**
* @brief Dictionary of tags with specific metadata about the certificate.
*
*/
std::unordered_map<std::string, std::string> Tags;
/**
* @brief The name of the certificate.
*
*/
std::string Name;
/**
* @brief The certificate identifier.
*
*/
std::string Id;
/**
* @brief The Key Vault base Url.
*
*/
std::string VaultUrl;
/**
* @brief The version of the certificate.
*
*/
std::string Version;
/**
* @brief Get the digital thumbprint of the certificate which can be used to uniquely identify
* it.
*
*/
std::vector<uint8_t> X509Thumbprint;
/**
* @brief Indicate whether the certificate is enabled and useable for cryptographic operations.
*
*/
Azure::Nullable<bool> Enabled;
/**
* @brief Construct a new Certificate Properties object
*
*/
CertificateProperties() = default;
/**
* @brief Construct a new Certificate Properties object
*
* @param name The name of the certificate.
*/
CertificateProperties(std::string const& name) : Name(name) {}
};
/**
* @brief An Azure Key Vault certificate.
*
*/
class KeyVaultCertificate {
public:
/**
* @brief Get the identifier of the certificate.
*
*/
std::string KeyId;
/**
* @brief Get the identifier of the Key Vault Secret which contains the PEM of PFX formatted
* content of the certificate and its private key.
*
*/
std::string SecretId;
/**
* @brief Additional fields for the certificate.
*
*/
CertificateProperties Properties;
/**
* @brief Get the CER formatted public X509 certificate.
*
* @remarks This property contains only the public key.
*
*/
std::vector<uint8_t> Cer;
/**
* @brief Get the name of the certificate.
*
* @return The name of the certificate.
*/
std::string const& Name() const { return Properties.Name; }
/**
* @brief Get the certificate Id,
*
* @return The id of the certificate.
*/
std::string const& Id() const { return Properties.Id; }
/**
* @brief Construct a new Key Vault Certificate object
*
* @param properties The properties to create a new certificate.
*/
KeyVaultCertificate(CertificateProperties const& properties) : Properties(properties) {}
/**
* @brief Construct a new Key Vault Certificate object
*
*/
KeyVaultCertificate() = default;
/**
* @brief Destroy the Key Vault Certificate object
*
*/
virtual ~KeyVaultCertificate() = default;
};
/**
* @brief Supported JsonWebKey key types (kty).
*
*/
class CertificateKeyType final {
private:
std::string m_value;
public:
/**
* @brief Construct a new Certificate Key Type object
*
* @param keyType The type of the certificate.
*/
explicit CertificateKeyType(std::string keyType) : m_value(std::move(keyType)) {}
/**
* @brief Construct a new Certificate Key Type object
*
*/
CertificateKeyType() = default;
/**
* @brief Enables using the equal operator for JWT.
*
* @param other A JWT to be compared.
*/
bool operator==(const CertificateKeyType& other) const noexcept
{
return m_value == other.m_value;
}
/**
* @brief Return the JSON Web Token (JWT) as a string.
*
* @return The JWT represented as string.
*/
std::string const& ToString() const { return m_value; }
/**
* @brief An Elliptic Curve Cryptographic (ECC) algorithm.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyType Ec;
/**
* @brief An Elliptic Curve Cryptographic (ECC) algorithm backed by a Hardware Security Module
* (HSM).
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyType EcHsm;
/**
* @brief An RSA cryptographic algorithm.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyType Rsa;
/**
* @brief An RSA cryptographic algorithm backed by a Hardware Security Module (HSM).
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyType RsaHsm;
};
/**
* @brief Elliptic Curve Cryptography (ECC) curve names.
*
*/
class CertificateKeyCurveName final {
private:
std::string m_value;
public:
/**
* @brief Construct a new Key Curve Name object.
*
* @param value The string value of the instance.
*/
explicit CertificateKeyCurveName(std::string value)
{
if (value.empty())
{
throw std::invalid_argument("The value for the curve name can not be empty");
}
m_value = std::move(value);
}
/**
* @brief Construct a default key curve.
*
*/
CertificateKeyCurveName() = default;
/**
* @brief Enables using the equal operator for key curve.
*
* @param other A key curve to be compared.
*/
bool operator==(const CertificateKeyCurveName& other) const noexcept
{
return m_value == other.m_value;
}
/**
* @brief Get the string value of the key curve.
*
*/
std::string const& ToString() const { return m_value; }
/**
* @brief Get the NIST P-256 elliptic curve, AKA SECG curve SECP256R1.
*
* @remark For more information, see
* <a href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve
* types</a>.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyCurveName P256;
/**
* @brief Get the SECG SECP256K1 elliptic curve.
*
* @remark For more information, see
* <a href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve
* types</a>.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyCurveName P256K;
/**
* @brief Get the NIST P-384 elliptic curve, AKA SECG curve SECP384R1.
*
* @remark For more information, see
* <a href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve
* types</a>.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyCurveName P384;
/**
* @brief Get the NIST P-521 elliptic curve, AKA SECG curve SECP521R1.
*
* @remark For more information, see
* <a href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve
* types</a>.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyCurveName P521;
};
/**
* @brief A collection of subject alternative names (SANs) for a X.509 certificate. SANs can be
* DNS entries, emails, or unique principal names.
*
*/
struct SubjectAlternativeNames final
{
/**
* @brief Get a collection of DNS names.
*
*/
std::vector<std::string> DnsNames;
/**
* @brief Get a collection of email addresses.
*
*/
std::vector<std::string> Emails;
/**
* @brief Get a collection of user principal names (UPNs).
*
*/
std::vector<std::string> UserPrincipalNames;
};
/**
* @brief Content type of the certificate when downloaded from getecret.
*
*/
class CertificateContentType final {
private:
std::string m_value;
public:
/**
* @brief Construct a new Key Curve Name object.
*
* @param value The string value of the instance.
*/
explicit CertificateContentType(std::string value)
{
if (value.empty())
{
throw std::invalid_argument("The value for the curve name can not be empty");
}
m_value = std::move(value);
}
/**
* @brief Construct a default key curve.
*
*/
CertificateContentType() = default;
/**
* @brief Enables using the equal operator for key curve.
*
* @param other A key curve to be compared.
*/
bool operator==(const CertificateContentType& other) const noexcept
{
return m_value == other.m_value;
}
/**
* @brief Get the string value of the key curve.
*
*/
std::string const& ToString() const { return m_value; }
/**
* @brief Get the NIST P-256 elliptic curve, AKA SECG curve SECP256R1.
*
* @remark For more information, see
* <a href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve
* types</a>.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateContentType Pkcs12;
/**
* @brief Get the SECG SECP256K1 elliptic curve.
*
* @remark For more information, see
* <a href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve
* types</a>.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateContentType Pem;
};
/**
* @brief Supported usages of a certificate key.
*
*/
class CertificateKeyUsage final {
private:
std::string m_value;
public:
/**
* @brief Construct a new Key Curve Name object.
*
* @param value The string value of the instance.
*/
explicit CertificateKeyUsage(std::string value)
{
if (value.empty())
{
throw std::invalid_argument("The value for the curve name can not be empty");
}
m_value = std::move(value);
}
/**
* @brief Construct a default key curve.
*
*/
CertificateKeyUsage() = default;
/**
* @brief Enables using the equal operator for key curve.
*
* @param other A key curve to be compared.
*/
bool operator==(const CertificateKeyUsage& other) const noexcept
{
return m_value == other.m_value;
}
/**
* @brief Get the string value of the key curve.
*
*/
std::string const& ToString() const { return m_value; }
/**
* @brief Get a CertificateKeyUsage indicating that the certificate key can be
* used as a digital signatures.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyUsage DigitalSignature;
/**
* @brief Get a CertificateKeyUsage indicating that the certificate key can be used for
* authentication.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyUsage NonRepudiation;
/**
* @brief Get a CertificateKeyUsage indicating that the certificate key can be used for key
* encryption.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyUsage KeyEncipherment;
/**
* @brief Get a CertificateKeyUsage indicating that the certificate key can be used for data
* encryption.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyUsage DataEncipherment;
/**
* @brief Get a CertificateKeyUsage indicating that the certificate key can be used to determine
* key agreement, such as a key created using the Diffie-Hellman key agreement algorithm.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyUsage KeyAgreement;
/**
* @brief Get a CertificateKeyUsage indicating that the certificate key can be used to sign
* certificates.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyUsage KeyCertSign;
/**
* @brief Get a CertificateKeyUsage indicating that the certificate key can be used to sign a
* certificate revocation list.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyUsage CrlSign;
/**
* @brief Get a CertificateKeyUsage indicating that the certificate key can be used for
* encryption only.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyUsage EncipherOnly;
/**
* @brief Get a CertificateKeyUsage indicating that the certificate key can be used for
* decryption only.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificateKeyUsage DecipherOnly;
};
/**
* @brief An action that will be executed.
*
*/
class CertificatePolicyAction final {
private:
std::string m_value;
public:
/**
* @brief Construct a new Key Curve Name object.
*
* @param value The string value of the instance.
*/
explicit CertificatePolicyAction(std::string value)
{
if (value.empty())
{
throw std::invalid_argument("The value for the curve name can not be empty");
}
m_value = std::move(value);
}
/**
* @brief Construct a default key curve.
*
*/
CertificatePolicyAction() = default;
/**
* @brief Enables using the equal operator for key curve.
*
* @param other A key curve to be compared.
*/
bool operator==(const CertificatePolicyAction& other) const noexcept
{
return m_value == other.m_value;
}
/**
* @brief Get the string value of the key curve.
*
*/
std::string const& ToString() const { return m_value; }
/**
* @brief Get the NIST P-256 elliptic curve, AKA SECG curve SECP256R1.
*
* @remark For more information, see
* <a href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve
* types</a>.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificatePolicyAction
DigitalSignature;
/**
* @brief Gets a CertificatePolicyAction that will auto-renew a certificate.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificatePolicyAction AutoRenew;
/**
* @brief Get a CertificatePolicyAction action that will email certificate contacts.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const CertificatePolicyAction EmailContacts;
};
/**
* @brief An action to be executed at a prescribed time in a certificates lifecycle.
*
*/
struct LifetimeAction final
{
/**
* @brief Get the CertificatePolicyAction to be performed.
*
*/
CertificatePolicyAction Action;
/**
* @brief Get the action should be performed the specified number of days before the certificate
* will expire.
*
*/
Azure::Nullable<int32_t> DaysBeforeExpiry;
/**
* @brief Get the action should be performed when the certificate reaches the specified
* percentage of its lifetime. Valid values include 1-99.
*
*/
Azure::Nullable<int32_t> LifetimePercentage;
};
/**
* @brief A policy which governs the lifecycle a properties of a certificate managed by Azure Key
* Vault.
*
*/
struct CertificatePolicy final
{
/**
* @brief Get the type of backing key to be generated when issuing new certificates.
*
*/
Azure::Nullable<CertificateKeyType> KeyType;
/**
* @brief Get a value indicating whether the certificate key should be reused when rotating the
* certificate.
*
*/
Azure::Nullable<bool> ReuseKey;
/**
* @brief Get a value indicating whether the certificate key is exportable from the vault or
* secure certificate store.
*
*/
Azure::Nullable<bool> Exportable;
/**
* @brief Get the curve which back an Elliptic Curve (EC) key.
*
*/
Azure::Nullable<CertificateKeyCurveName> KeyCurveName;
/**
* @brief Get the size of the RSA key. The value must be a valid RSA key length such as 2048 or
* 4092.
*
*/
Azure::Nullable<int32_t> KeySize;
/**
* @brief Get the subject name of a certificate.
*
*/
std::string Subject;
/**
* @brief Get the subject alternative names (SANs) of a certificate.
*
*/
struct SubjectAlternativeNames SubjectAlternativeNames;
/**
* @brief Indicates if the certificates generated under this policy should be published to
* certificate transparency logs.
*
*/
Azure::Nullable<bool> CertificateTransparency;
/**
* @brief Certificate type as supported by the provider (optional); for example 'OV-SSL',
* 'EV-SSL'.
*
*/
Azure::Nullable<std::string> CertificateType;
/**
* @brief Name of the referenced issuer object or reserved names; for example, 'Self' or
'Unknown'.
*
*/
Azure::Nullable<std::string> IssuerName;
/**
* @brief Get the CertificateContentType of the certificate.
*
*/
Azure::Nullable<CertificateContentType> ContentType;
/**
* @brief Get the validity period for a certificate in months.
*
*/
Azure::Nullable<int32_t> ValidityInMonths;
/**
* @brief Get a value indicating whether the certificate is currently enabled. If null, the
* server default will be used.
*
*/
Azure::Nullable<bool> Enabled;
/**
* @brief Get a DateTime indicating when the certificate was updated.
*
*/
Azure::Nullable<Azure::DateTime> UpdatedOn;
/**
* @brief Get a DateTime indicating when the certificate was created.
*
*/
Azure::Nullable<Azure::DateTime> CreatedOn;
/**
* @brief Gets the allowed usages for the key of the certificate.
*
*/
std::vector<CertificateKeyUsage> KeyUsage;
/**
* @brief Get the allowed enhanced key usages (EKUs) of the certificate.
*
*/
std::vector<std::string> EnhancedKeyUsage;
/**
* @brief Get the actions to be executed at specified times in the certificates lifetime.
*
*/
std::vector<LifetimeAction> LifetimeActions;
};
/**
* @brief A KeyVaultCertificate along with its CertificatePolicy.
*
*/
struct KeyVaultCertificateWithPolicy final : public KeyVaultCertificate
{
/**
* @brief Gets the current policy for the certificate.
*
*/
CertificatePolicy Policy;
/**
* @brief Construct a new Key Vault Certificate With Policy object
*
* @param properties The properties to create a new certificate.
*/
KeyVaultCertificateWithPolicy(CertificateProperties const& properties)
: KeyVaultCertificate(properties)
{
}
};
/**
* @brief The options for calling GetCertificate.
*
*/
struct GetCertificateOptions final
{
std::string Version;
};
}}}} // namespace Azure::Security::KeyVault::Certificates

View File

@ -0,0 +1,74 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
* @brief Defines the supported options to create a Key Vault Keys client.
*
*/
#pragma once
#include <azure/core/internal/client_options.hpp>
#include "azure/keyvault/certificates/certificate_client_models.hpp"
#include "azure/keyvault/certificates/dll_import_export.hpp"
namespace Azure { namespace Security { namespace KeyVault { namespace Certificates {
/**
* @brief The API version to use from Key Vault.
*
*/
class ServiceVersion final {
private:
std::string m_version;
public:
/**
* @brief Construct a new Service Version object
*
* @param version The string version for the Key Vault keys service.
*/
ServiceVersion(std::string version) : m_version(std::move(version)) {}
/**
* @brief Enable comparing the ext enum.
*
* @param other Another #ServiceVersion to be compared.
*/
bool operator==(ServiceVersion const& other) const { return m_version == other.m_version; }
/**
* @brief Return the #ServiceVersion string representation.
*
*/
std::string const& ToString() const { return m_version; }
/**
* @brief Use to send request to the 7.2 version of Key Vault service.
*
*/
AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT static const ServiceVersion V7_2;
};
/**
* @brief Define the options to create an SDK Keys client.
*
*/
struct CertificateClientOptions final : public Azure::Core::_internal::ClientOptions
{
ServiceVersion Version;
/**
* @brief Construct a new Key Client Options object.
*
* @param version Optional version for the client.
*/
CertificateClientOptions(ServiceVersion version = ServiceVersion::V7_2)
: Azure::Core::_internal::ClientOptions(), Version(version)
{
}
};
}}}} // namespace Azure::Security::KeyVault::Certificates

View File

@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
* @brief DLL export macro.
*/
// For explanation, see the comment in azure/core/dll_import_export.hpp
#pragma once
/**
* @def AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT
* @brief Applies DLL export attribute, when applicable.
* @note See https://docs.microsoft.com/cpp/cpp/dllexport-dllimport?view=msvc-160.
*/
#if defined(AZ_SECURITY_KEYVAULT_CERTIFICATES_DLL) \
|| (0 /*@AZ_SECURITY_KEYVAULT_CERTIFICATES_DLL_INSTALLED_AS_PACKAGE@*/)
#define AZ_SECURITY_KEYVAULT_CERTIFICATES_BUILT_AS_DLL 1
#else
#define AZ_SECURITY_KEYVAULT_CERTIFICATES_BUILT_AS_DLL 0
#endif
#if AZ_SECURITY_KEYVAULT_CERTIFICATES_BUILT_AS_DLL
#if defined(_MSC_VER)
#if defined(AZ_SECURITY_KEYVAULT_CERTIFICATES_BEING_BUILT)
#define AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT __declspec(dllexport)
#else // !defined(AZ_SECURITY_KEYVAULT_CERTIFICATES_BEING_BUILT)
#define AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT __declspec(dllimport)
#endif // AZ_SECURITY_KEYVAULT_CERTIFICATES_BEING_BUILT
#else // !defined(_MSC_VER)
#define AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT
#endif // _MSC_VER
#else // !AZ_SECURITY_KEYVAULT_CERTIFICATES_BUILT_AS_DLL
#define AZ_SECURITY_KEYVAULT_CERTIFICATES_DLLEXPORT
#endif // AZ_SECURITY_KEYVAULT_CERTIFICATES_BUILT_AS_DLL
#undef AZ_SECURITY_KEYVAULT_CERTIFICATES_BUILT_AS_DLL

View File

@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Includes all public headers from Azure Key Vault Certificates SDK library.
*
*/
#pragma once
#include "azure/keyvault/certificates/dll_import_export.hpp"
#include "azure/keyvault/certificates/certificate_client.hpp"
#include "azure/keyvault/certificates/certificate_client_models.hpp"
#include "azure/keyvault/certificates/certificate_client_options.hpp"

View File

@ -0,0 +1,130 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include "azure/keyvault/certificates/certificate_client.hpp"
#include "private/certificate_serializers.hpp"
#include "private/keyvault_certificates_common_request.hpp"
#include "private/package_version.hpp"
#include <azure/core/credentials/credentials.hpp>
#include <azure/core/http/http.hpp>
#include <azure/core/http/policies/policy.hpp>
#include <azure/core/internal/http/pipeline.hpp>
#include <memory>
#include <string>
#include <vector>
using namespace Azure::Security::KeyVault::Certificates;
using namespace Azure::Security::KeyVault::Certificates::_detail;
using namespace Azure;
using namespace Azure::Core;
using namespace Azure::Core::Http;
using namespace Azure::Core::Http::Policies;
using namespace Azure::Core::Http::Policies::_internal;
using namespace Azure::Core::Http::_internal;
using namespace Azure::Security::KeyVault::_detail;
namespace {
constexpr static const char KeyVaultServicePackageName[] = "keyvault-certificates";
constexpr static const char CertificatesPath[] = "certificates";
// This is a Key-Vault only patch to calculate token scope/audience
std::string GetScopeFromUrl(Azure::Core::Url const& url)
{
std::string calculatedScope(url.GetScheme() + "://");
auto const& hostWithAccount = url.GetHost();
auto hostNoAccountStart = std::find(hostWithAccount.begin(), hostWithAccount.end(), '.');
// Insert the calculated scope only when then host in the url contains at least a `.`
// Otherwise, only the default scope will be there.
// We don't want to throw/validate input but just leave the values go to azure to decide what to
// do.
if (hostNoAccountStart != hostWithAccount.end())
{
calculatedScope.append(hostNoAccountStart + 1, hostWithAccount.end());
calculatedScope.append("/.default");
}
return calculatedScope;
}
} // namespace
std::unique_ptr<RawResponse> CertificateClient::SendRequest(
Azure::Core::Http::Request& request,
Azure::Core::Context const& context) const
{
return KeyVaultCertificatesCommonRequest::SendRequest(*m_pipeline, request, context);
}
Request CertificateClient::CreateRequest(
HttpMethod method,
std::vector<std::string> const& path,
Azure::Core::IO::BodyStream* content) const
{
return KeyVaultCertificatesCommonRequest::CreateRequest(
m_vaultUrl, m_apiVersion, method, path, content);
}
CertificateClient::CertificateClient(
std::string const& vaultUrl,
std::shared_ptr<Core::Credentials::TokenCredential const> credential,
CertificateClientOptions options)
: m_vaultUrl(vaultUrl), m_apiVersion(options.Version.ToString())
{
auto apiVersion = options.Version.ToString();
std::vector<std::unique_ptr<HttpPolicy>> perRetrypolicies;
{
Azure::Core::Credentials::TokenRequestContext const tokenContext
= {{::GetScopeFromUrl(m_vaultUrl)}};
perRetrypolicies.emplace_back(
std::make_unique<BearerTokenAuthenticationPolicy>(credential, std::move(tokenContext)));
}
std::vector<std::unique_ptr<HttpPolicy>> perCallpolicies;
m_pipeline = std::make_shared<Azure::Core::Http::_internal::HttpPipeline>(
options,
KeyVaultServicePackageName,
PackageVersion::ToString(),
std::move(perRetrypolicies),
std::move(perCallpolicies));
}
Response<KeyVaultCertificateWithPolicy> CertificateClient::GetCertificate(
std::string const& name,
Context const& context) const
{
auto request = CreateRequest(HttpMethod::Get, {CertificatesPath, name});
// Send and parse respone
auto rawResponse = SendRequest(request, context);
auto value
= _detail::KeyVaultCertificateSerializer::KeyVaultCertificateDeserialize(name, *rawResponse);
return Azure::Response<KeyVaultCertificateWithPolicy>(std::move(value), std::move(rawResponse));
}
Response<KeyVaultCertificate> CertificateClient::GetCertificateVersion(
std::string const& name,
GetCertificateOptions const& options,
Context const& context) const
{
// Request with no payload
std::vector<std::string> path{{CertificatesPath, name}};
if (!options.Version.empty())
{
path.emplace_back(options.Version);
}
auto request = CreateRequest(HttpMethod::Get, std::move(path));
// Send and parse respone
auto rawResponse = SendRequest(request, context);
auto value
= _detail::KeyVaultCertificateSerializer::KeyVaultCertificateDeserialize(name, *rawResponse);
return Azure::Response<KeyVaultCertificate>(std::move(value), std::move(rawResponse));
}
const ServiceVersion ServiceVersion::V7_2("7.2");

View File

@ -0,0 +1,227 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include <azure/core/base64.hpp>
#include <azure/core/internal/json/json.hpp>
#include <azure/core/internal/json/json_optional.hpp>
#include <azure/core/internal/json/json_serializable.hpp>
#include <azure/core/url.hpp>
#include "azure/keyvault/certificates/certificate_client_models.hpp"
#include "private/certificate_constants.hpp"
#include "private/certificate_serializers.hpp"
using namespace Azure::Security::KeyVault::Certificates;
using namespace Azure::Core::Json::_internal;
using namespace Azure::Core::_internal;
using Azure::Core::_internal::PosixTimeConverter;
KeyVaultCertificateWithPolicy
_detail::KeyVaultCertificateSerializer::KeyVaultCertificateDeserialize(
std::string const& name,
Azure::Core::Http::RawResponse const& rawResponse)
{
CertificateProperties properties(name);
auto const& body = rawResponse.GetBody();
auto jsonResponse = json::parse(body);
using Azure::Core::_internal::PosixTimeConverter;
// Parse URL for the name, vaultUrl and version
_detail::KeyVaultCertificateSerializer::ParseKeyUrl(
properties, jsonResponse[IdName].get<std::string>());
// x5t
properties.X509Thumbprint = Base64Url::Base64UrlDecode(jsonResponse[X5tName].get<std::string>());
// "Tags"
if (jsonResponse.contains(TagsName))
{
properties.Tags = jsonResponse[TagsName].get<std::unordered_map<std::string, std::string>>();
}
// "Attributes"
if (jsonResponse.contains(AttributesPropertyName))
{
auto attributes = jsonResponse[AttributesPropertyName];
JsonOptional::SetIfExists(properties.Enabled, attributes, EnabledPropertyName);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
properties.NotBefore, attributes, NbfPropertyName, PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
properties.ExpiresOn, attributes, ExpPropertyName, PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
properties.CreatedOn,
attributes,
CreatedPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
properties.UpdatedOn,
attributes,
UpdatedPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists(properties.RecoveryLevel, attributes, RecoveryLevelPropertyName);
JsonOptional::SetIfExists(properties.RecoverableDays, attributes, RecoverableDaysPropertyName);
}
KeyVaultCertificateWithPolicy certificate(std::move(properties));
// kid
certificate.KeyId = jsonResponse[KidPropertyName].get<std::string>();
// sid
certificate.SecretId = jsonResponse[SidPropertyName].get<std::string>();
// cer
certificate.Cer = Base64Url::Base64UrlDecode(jsonResponse[CerPropertyName].get<std::string>());
// policy
if (jsonResponse.contains(PolicyPropertyName))
{
auto const policyJson = jsonResponse[PolicyPropertyName];
// key_props
{
auto const keyPropsJson = policyJson[KeyPropsPropertyName];
JsonOptional::SetIfExists<std::string, CertificateKeyType>(
certificate.Policy.KeyType, keyPropsJson, KeyTypePropertyName, [](std::string value) {
return CertificateKeyType(value);
});
JsonOptional::SetIfExists(certificate.Policy.ReuseKey, keyPropsJson, ReuseKeyPropertyName);
JsonOptional::SetIfExists(
certificate.Policy.Exportable, keyPropsJson, ExportablePropertyName);
JsonOptional::SetIfExists<std::string, CertificateKeyCurveName>(
certificate.Policy.KeyCurveName,
keyPropsJson,
CurveNamePropertyName,
[](std::string value) { return CertificateKeyCurveName(value); });
JsonOptional::SetIfExists(certificate.Policy.KeySize, keyPropsJson, KeySizePropertyName);
}
// secret_props
{
auto const secretPropsJson = policyJson[SecretPropsPropertyName];
JsonOptional::SetIfExists<std::string, CertificateContentType>(
certificate.Policy.ContentType,
secretPropsJson,
ContentTypePropertyName,
[](std::string value) { return CertificateContentType(value); });
}
// x509_props
{
auto const x509PropsJson = policyJson[X509PropsPropertyName];
certificate.Policy.Subject = x509PropsJson[SubjectPropertyName].get<std::string>();
JsonOptional::SetIfExists<std::vector<std::string>, std::vector<std::string>>(
certificate.Policy.SubjectAlternativeNames.DnsNames,
x509PropsJson,
DnsPropertyName,
[](std::vector<std::string> const& values) { return values; });
JsonOptional::SetIfExists<std::vector<std::string>, std::vector<std::string>>(
certificate.Policy.SubjectAlternativeNames.Emails,
x509PropsJson,
EmailsPropertyName,
[](std::vector<std::string> const& values) { return values; });
JsonOptional::SetIfExists<std::vector<std::string>, std::vector<std::string>>(
certificate.Policy.SubjectAlternativeNames.UserPrincipalNames,
x509PropsJson,
UserPrincipalNamesPropertyName,
[](std::vector<std::string> const& values) { return values; });
JsonOptional::SetIfExists<std::vector<std::string>, std::vector<CertificateKeyUsage>>(
certificate.Policy.KeyUsage,
x509PropsJson,
UserPrincipalNamesPropertyName,
[](std::vector<std::string> const& values) {
std::vector<CertificateKeyUsage> keyUsage;
for (auto const& item : values)
{
keyUsage.emplace_back(CertificateKeyUsage(item));
}
return keyUsage;
});
JsonOptional::SetIfExists<std::vector<std::string>, std::vector<std::string>>(
certificate.Policy.EnhancedKeyUsage,
x509PropsJson,
EkusPropertyName,
[](std::vector<std::string> const& values) { return values; });
JsonOptional::SetIfExists(
certificate.Policy.ValidityInMonths, x509PropsJson, ValidityMonthsPropertyName);
}
// issuer
{
auto const issuerJson = policyJson[IssuerPropertyName];
JsonOptional::SetIfExists(certificate.Policy.IssuerName, issuerJson, IssuerNamePropertyName);
JsonOptional::SetIfExists(
certificate.Policy.CertificateTransparency, issuerJson, CertTransparencyPropertyName);
JsonOptional::SetIfExists(certificate.Policy.CertificateType, issuerJson, CtyPropertyName);
}
// attributes
{
auto const policyAttributesJson = policyJson[AttributesPropertyName];
JsonOptional::SetIfExists(
certificate.Policy.Enabled, policyAttributesJson, EnabledPropertyName);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
certificate.Policy.CreatedOn,
policyAttributesJson,
CreatedPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
JsonOptional::SetIfExists<int64_t, Azure::DateTime>(
certificate.Policy.UpdatedOn,
policyAttributesJson,
UpdatedPropertyName,
PosixTimeConverter::PosixTimeToDateTime);
}
// lifetime_actions
{
auto const policyAttributesJson = policyJson[LifetimeActionsPropertyName];
for (auto const& attributeItem : policyAttributesJson)
{
LifetimeAction action;
JsonOptional::SetIfExists<json, CertificatePolicyAction>(
action.Action, attributeItem, ActionPropertyName, [](json const& value) {
return CertificatePolicyAction(value[ActionTypePropertyName].get<std::string>());
});
if (attributeItem.contains(TriggerPropertyName))
{
auto const triggerPropertyJson = attributeItem[TriggerPropertyName];
JsonOptional::SetIfExists(
action.DaysBeforeExpiry, triggerPropertyJson, DaysBeforeExpiryPropertyName);
JsonOptional::SetIfExists(
action.LifetimePercentage, triggerPropertyJson, LifetimePercentagePropertyName);
}
// At this point the action is parsed from json and can be added to the LifeTimeActions from
// the policy.
certificate.Policy.LifetimeActions.emplace_back(action);
}
}
}
return certificate;
}
namespace Azure { namespace Security { namespace KeyVault { namespace Certificates {
const CertificateKeyUsage CertificateKeyUsage::DigitalSignature(_detail::DigitalSignatureValue);
const CertificateKeyUsage CertificateKeyUsage::NonRepudiation(_detail::NonRepudiationValue);
const CertificateKeyUsage CertificateKeyUsage::KeyEncipherment(_detail::KeyEnciphermentValue);
const CertificateKeyUsage CertificateKeyUsage::DataEncipherment(_detail::DataEnciphermentValue);
const CertificateKeyUsage CertificateKeyUsage::KeyAgreement(_detail::KeyAgreementValue);
const CertificateKeyUsage CertificateKeyUsage::KeyCertSign(_detail::KeyCertSignValue);
const CertificateKeyUsage CertificateKeyUsage::CrlSign(_detail::CrlSignValue);
const CertificateKeyUsage CertificateKeyUsage::EncipherOnly(_detail::EncipherOnlyValue);
const CertificateKeyUsage CertificateKeyUsage::DecipherOnly(_detail::DecipherOnlyValue);
const CertificateKeyType CertificateKeyType::Ec(_detail::EcValue);
const CertificateKeyType CertificateKeyType::EcHsm(_detail::EcHsmValue);
const CertificateKeyType CertificateKeyType::Rsa(_detail::RsaValue);
const CertificateKeyType CertificateKeyType::RsaHsm(_detail::RsaHsmValue);
const CertificateKeyCurveName CertificateKeyCurveName::P256(_detail::P256Value);
const CertificateKeyCurveName CertificateKeyCurveName::P256K(_detail::P256KValue);
const CertificateKeyCurveName CertificateKeyCurveName::P384(_detail::P384Value);
const CertificateKeyCurveName CertificateKeyCurveName::P521(_detail::P521Value);
const CertificateContentType CertificateContentType::Pkcs12(_detail::Pkc12Value);
const CertificateContentType CertificateContentType::Pem(_detail::PemValue);
const CertificatePolicyAction CertificatePolicyAction::AutoRenew(_detail::AutoRenewValue);
const CertificatePolicyAction CertificatePolicyAction::EmailContacts(_detail::EmailContactsValue);
}}}} // namespace Azure::Security::KeyVault::Certificates

View File

@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include "private/keyvault_certificates_common_request.hpp"
#include <azure/core/exception.hpp>
#include <azure/core/http/http.hpp>
#include <memory>
using namespace Azure::Security::KeyVault;
using namespace Azure::Core::Http::_internal;
std::unique_ptr<Azure::Core::Http::RawResponse>
_detail::KeyVaultCertificatesCommonRequest::SendRequest(
Azure::Core::Http::_internal::HttpPipeline const& pipeline,
Azure::Core::Http::Request& request,
Azure::Core::Context const& context)
{
auto response = pipeline.Send(request, context);
auto responseCode = response->GetStatusCode();
switch (responseCode)
{
// 200, 2001, 202, 204 are accepted responses
case Azure::Core::Http::HttpStatusCode::Ok:
case Azure::Core::Http::HttpStatusCode::Created:
case Azure::Core::Http::HttpStatusCode::Accepted:
case Azure::Core::Http::HttpStatusCode::NoContent:
break;
default:
throw Azure::Core::RequestFailedException(response);
}
return response;
}
Azure::Core::Http::Request _detail::KeyVaultCertificatesCommonRequest::CreateRequest(
Azure::Core::Url url,
std::string const& apiVersion,
Azure::Core::Http::HttpMethod method,
std::vector<std::string> const& path,
Azure::Core::IO::BodyStream* content)
{
using namespace Azure::Core::Http;
Request request = content == nullptr ? Request(method, url) : Request(method, url, content);
request.GetUrl().AppendQueryParameter("api-version", apiVersion);
for (std::string const& p : path)
{
if (!p.empty())
{
request.GetUrl().AppendPath(p);
}
}
return request;
}

View File

@ -0,0 +1,91 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
* @brief Centralize the string constants used by Key Vault Certificates Client.
*
*/
#pragma once
namespace Azure { namespace Security { namespace KeyVault { namespace Certificates {
namespace _detail {
/***************** Certificates Properties *****************/
constexpr static const char IdName[] = "id";
constexpr static const char X5tName[] = "x5t";
constexpr static const char TagsName[] = "tags";
constexpr static const char AttributesPropertyName[] = "attributes";
constexpr static const char EnabledPropertyName[] = "enabled";
constexpr static const char NbfPropertyName[] = "nbf";
constexpr static const char ExpPropertyName[] = "exp";
constexpr static const char CreatedPropertyName[] = "created";
constexpr static const char UpdatedPropertyName[] = "updated";
constexpr static const char RecoverableDaysPropertyName[] = "recoverableDays";
constexpr static const char RecoveryLevelPropertyName[] = "recoveryLevel";
constexpr static const char KidPropertyName[] = "kid";
constexpr static const char SidPropertyName[] = "sid";
constexpr static const char CerPropertyName[] = "cer";
/***************** Certificates Policy *****************/
constexpr static const char PolicyPropertyName[] = "policy";
constexpr static const char KeyPropsPropertyName[] = "key_props";
constexpr static const char KeyTypePropertyName[] = "kty";
constexpr static const char ReuseKeyPropertyName[] = "reuse_key";
constexpr static const char ExportablePropertyName[] = "exportable";
constexpr static const char CurveNamePropertyName[] = "crv";
constexpr static const char KeySizePropertyName[] = "key_size";
constexpr static const char SecretPropsPropertyName[] = "secret_props";
constexpr static const char ContentTypePropertyName[] = "contentType";
constexpr static const char X509PropsPropertyName[] = "x509_props";
constexpr static const char SubjectPropertyName[] = "subject";
constexpr static const char SansPropertyName[] = "sans";
constexpr static const char DnsPropertyName[] = "dns_names";
constexpr static const char EmailsPropertyName[] = "emails";
constexpr static const char UserPrincipalNamesPropertyName[] = "upns";
constexpr static const char KeyUsagePropertyName[] = "key_usage";
constexpr static const char EkusPropertyName[] = "ekus";
constexpr static const char ValidityMonthsPropertyName[] = "validity_months";
constexpr static const char IssuerPropertyName[] = "issuer";
constexpr static const char CertTransparencyPropertyName[] = "cert_transparency";
constexpr static const char CtyPropertyName[] = "cty";
constexpr static const char IssuerNamePropertyName[] = "name";
constexpr static const char LifetimeActionsPropertyName[] = "lifetime_actions";
constexpr static const char TriggerPropertyName[] = "trigger";
constexpr static const char ActionPropertyName[] = "action";
constexpr static const char LifetimePercentagePropertyName[] = "lifetime_percentage";
constexpr static const char DaysBeforeExpiryPropertyName[] = "days_before_expiry";
constexpr static const char ActionTypePropertyName[] = "action_type";
/***************** Certificates Key Usage *****************/
constexpr static const char DigitalSignatureValue[] = "digitalSignature";
constexpr static const char NonRepudiationValue[] = "nonRepudiation";
constexpr static const char KeyEnciphermentValue[] = "keyEncipherment";
constexpr static const char DataEnciphermentValue[] = "dataEncipherment";
constexpr static const char KeyAgreementValue[] = "keyAgreement";
constexpr static const char KeyCertSignValue[] = "keyCertSign";
constexpr static const char CrlSignValue[] = "crlSign";
constexpr static const char EncipherOnlyValue[] = "encipherOnly";
constexpr static const char DecipherOnlyValue[] = "decipherOnly";
/***************** Certificates Key Type *****************/
constexpr static const char EcValue[] = "EC";
constexpr static const char EcHsmValue[] = "EC-HSM";
constexpr static const char RsaValue[] = "RSA";
constexpr static const char RsaHsmValue[] = "RSA-HSM";
/***************** Certificates Curve Name *****************/
constexpr static const char P256Value[] = "P-256";
constexpr static const char P256KValue[] = "P-256K";
constexpr static const char P384Value[] = "P-384";
constexpr static const char P521Value[] = "P-521";
/***************** Certificates Content Type *****************/
constexpr static const char Pkc12Value[] = "application/x-pkcs12";
constexpr static const char PemValue[] = "application/x-pem-file";
/***************** Certificates Policy Action *****************/
constexpr static const char AutoRenewValue[] = "AutoRenew";
constexpr static const char EmailContactsValue[] = "EmailContacts";
}}}}} // namespace Azure::Security::KeyVault::Certificates::_detail

View File

@ -0,0 +1,73 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
* @brief Centralize the serialize and de-serialize methods for the key vault keys models.
*
*/
#pragma once
#include <azure/core/internal/json/json.hpp>
#include "azure/keyvault/certificates/certificate_client_models.hpp"
#include "azure/keyvault/certificates/certificate_client_options.hpp"
#include <string>
namespace Azure { namespace Security { namespace KeyVault { namespace Certificates {
namespace _detail {
/***************** Certificate *****************/
class KeyVaultCertificateSerializer final {
public:
// Creates a new key based on a name and an HTTP raw response.
static KeyVaultCertificateWithPolicy KeyVaultCertificateDeserialize(
std::string const& name,
Azure::Core::Http::RawResponse const& rawResponse);
static std::string GetUrlAuthorityWithScheme(Azure::Core::Url const& url)
{
std::string urlString;
if (!url.GetScheme().empty())
{
urlString += url.GetScheme() + "://";
}
urlString += url.GetHost();
if (url.GetPort() != 0)
{
urlString += ":" + std::to_string(url.GetPort());
}
return urlString;
}
void static inline ParseKeyUrl(
CertificateProperties& certificateProperties,
std::string const& url)
{
Azure::Core::Url kid(url);
certificateProperties.Id = url;
certificateProperties.VaultUrl = GetUrlAuthorityWithScheme(kid);
auto const& path = kid.GetPath();
// path is in the form of `verb/keyName{/keyVersion}`
auto const separatorChar = '/';
auto pathEnd = path.end();
auto start = path.begin();
start = std::find(start, pathEnd, separatorChar);
start += 1;
auto separator = std::find(start, pathEnd, separatorChar);
if (separator != pathEnd)
{
certificateProperties.Name = std::string(start, separator);
start = separator + 1;
certificateProperties.Version = std::string(start, pathEnd);
}
else
{
// Nothing but the name+
certificateProperties.Name = std::string(start, pathEnd);
}
}
};
}}}}} // namespace Azure::Security::KeyVault::Certificates::_detail

View File

@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Provides a wrapper class for the Azure Core Pipeline for all Key Vault services where
* common functionality is set up.
*
*/
#pragma once
#include <azure/core/context.hpp>
#include <azure/core/http/http.hpp>
#include <azure/core/internal/http/pipeline.hpp>
#include <azure/core/internal/json/json.hpp>
#include <azure/core/internal/json/json_serializable.hpp>
#include <azure/core/response.hpp>
#include <memory>
#include <string>
#include <vector>
namespace Azure { namespace Security { namespace KeyVault { namespace _detail {
struct KeyVaultCertificatesCommonRequest final
{
static Azure::Core::Http::Request CreateRequest(
Azure::Core::Url url,
std::string const& apiVersion,
Azure::Core::Http::HttpMethod method,
std::vector<std::string> const& path,
Azure::Core::IO::BodyStream* content);
static std::unique_ptr<Azure::Core::Http::RawResponse> SendRequest(
Azure::Core::Http::_internal::HttpPipeline const& pipeline,
Azure::Core::Http::Request& request,
Azure::Core::Context const& context);
};
}}}} // namespace Azure::Security::KeyVault::_detail

View File

@ -0,0 +1,64 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
* @brief Provides version information.
*/
#pragma once
#include <cstdint>
#define AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_MAJOR 4
#define AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_MINOR 0
#define AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_PATCH 0
#define AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_PRERELEASE "beta.1"
#define AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_ITOA_HELPER(i) #i
#define AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_ITOA(i) \
AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_ITOA_HELPER(i)
namespace Azure { namespace Security { namespace KeyVault { namespace Certificates {
namespace _detail {
/**
* @brief Provides version information.
*
*/
class PackageVersion final {
public:
/// Major numeric identifier.
static constexpr int32_t Major = AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_MAJOR;
/// Minor numeric identifier.
static constexpr int32_t Minor = AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_MINOR;
/// Patch numeric identifier.
static constexpr int32_t Patch = AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_PATCH;
/// Indicates whether the SDK is in a pre-release state.
static constexpr bool IsPreRelease
= sizeof(AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_PRERELEASE) != sizeof("");
/**
* @brief The version in string format used for telemetry following the `semver.org` standard
* (https://semver.org).
*/
static constexpr const char* ToString()
{
return IsPreRelease
? AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_ITOA(AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_MAJOR) "." AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_ITOA(
AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_MINOR) "." AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_ITOA(AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_PATCH) "-" AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_PRERELEASE
: AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_ITOA(AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_MAJOR) "." AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_ITOA(
AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_MINOR) "." AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_ITOA(AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_PATCH);
}
};
}}}}} // namespace Azure::Security::KeyVault::Certificates::_detail
#undef AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_ITOA_HELPER
#undef AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_ITOA
#undef AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_MAJOR
#undef AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_MINOR
#undef AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_PATCH
#undef AZURE_SECURITY_KEYVAULT_CERTIFICATES_VERSION_PRERELEASE

View File

@ -0,0 +1,36 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required (VERSION 3.13)
project (azure-security-keyvault-certificates-test LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
include(GoogleTest)
# Export the test folder for recordings access.
add_compile_definitions(AZURE_TEST_RECORDING_DIR="${CMAKE_CURRENT_LIST_DIR}")
add_executable (
azure-security-keyvault-certificates-test
macro_guard.cpp
certificate_client_test.cpp
certificate_client_base_test.hpp)
if (MSVC)
target_compile_options(azure-security-keyvault-certificates-test PUBLIC /wd6326 /wd26495 /wd26812 /wd4389)
endif()
target_link_libraries(azure-security-keyvault-certificates-test PRIVATE azure-security-keyvault-certificates azure-identity azure-core-test-fw gtest gtest_main gmock)
# Adding private headers so we can test the private APIs with no relative paths include.
target_include_directories (azure-security-keyvault-certificates-test PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../src>)
# gtest_add_tests will scan the test from azure-core-test and call add_test
# for each test to ctest. This enables `ctest -r` to run specific tests directly.
gtest_discover_tests(azure-security-keyvault-certificates-test
TEST_PREFIX azure-security-keyvault-certificates.
NO_PRETTY_TYPES
NO_PRETTY_VALUES
)

View File

@ -0,0 +1,163 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
* @brief The base class to construct and init a Key Vault client.
*
*/
#include <gtest/gtest.h>
#include <azure/core/test/test_base.hpp>
#include <azure/identity/client_secret_credential.hpp>
#include <azure/keyvault/keyvault_certificates.hpp>
#include <thread>
using namespace std::chrono_literals;
namespace Azure {
namespace Security {
namespace KeyVault {
namespace Certificates {
namespace Test {
/**
* @brief Client Certificate Credential authenticates with the Azure services using a Tenant ID,
* Client ID and a client secret.
*
*/
class TestClientSecretCredential final : public Core::Credentials::TokenCredential {
public:
Core::Credentials::AccessToken GetToken(
Core::Credentials::TokenRequestContext const& tokenRequestContext,
Core::Context const& context) const override
{
Core::Credentials::AccessToken accessToken;
accessToken.Token = "magicToken";
accessToken.ExpiresOn = DateTime::max();
if (context.IsCancelled() || tokenRequestContext.Scopes.size() == 0)
{
accessToken.ExpiresOn = DateTime::min();
}
return accessToken;
}
};
class KeyVaultCertificateClientTest : public Azure::Core::Test::TestBase,
public ::testing::WithParamInterface<int> {
private:
std::unique_ptr<Azure::Security::KeyVault::Certificates::CertificateClient> m_client;
std::string GetEnv(const std::string& name, std::string const& defaultValue = std::string())
{
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4996)
const char* ret = std::getenv(name.data());
#pragma warning(pop)
#else
const char* ret = std::getenv(name.data());
#endif
if (!ret)
{
if (!defaultValue.empty())
{
return defaultValue;
}
throw std::runtime_error(
name + " is required to run the tests but not set as an environment variable.");
}
return std::string(ret);
}
protected:
std::shared_ptr<Azure::Identity::ClientSecretCredential> m_credential;
std::shared_ptr<TestClientSecretCredential> m_testCredential;
std::string m_keyVaultUrl;
std::chrono::milliseconds m_defaultWait;
Azure::Security::KeyVault::Certificates::CertificateClient const& GetClientForTest(
std::string const& testName)
{
InitializeClient();
// set the interceptor for the current test
m_testContext.RenameTest(testName);
return *m_client;
}
// Create
void InitializeClient()
{
// Init interceptor from PlayBackRecorder
std::string recordingPath(AZURE_TEST_RECORDING_DIR);
recordingPath.append("/recordings");
Azure::Core::Test::TestBase::SetUpBase(recordingPath);
std::string tenantId = GetEnv("AZURE_TENANT_ID", "tenant");
std::string clientId = GetEnv("AZURE_CLIENT_ID", "client");
std::string secretId = GetEnv("AZURE_CLIENT_SECRET", "secret");
m_keyVaultUrl = GetEnv("AZURE_KEYVAULT_URL", "https://REDACTED.vault.azure.net/");
// Create default client for the test
CertificateClientOptions options;
// Replace default transport adapter for playback
if (m_testContext.IsPlaybackMode())
{
options.Transport.Transport = m_interceptor->GetPlaybackClient();
}
// Insert Recording policy when Record mode is on (non playback and non LiveMode)
else if (!m_testContext.IsLiveMode())
{
// AZURE_TEST_RECORDING_DIR is exported by CMAKE
options.PerRetryPolicies.push_back(m_interceptor->GetRecordPolicy());
}
if (m_testContext.IsPlaybackMode())
{ // inject fake token client here if it's test
m_testCredential = std::make_shared<TestClientSecretCredential>();
m_client = std::make_unique<CertificateClient>(m_keyVaultUrl, m_testCredential, options);
// we really dont need to wait for results
m_defaultWait = 1ms;
}
else
{
m_credential = std::make_shared<Azure::Identity::ClientSecretCredential>(
tenantId, clientId, secretId);
m_client = std::make_unique<CertificateClient>(m_keyVaultUrl, m_credential, options);
m_defaultWait = 30s;
}
// When running live tests, service can return 429 error response if the client is sending
// multiple requests per second. This can happen if the network is fast and tests are running
// without any delay between them.
auto avoidTestThrottled = GetEnv("AZURE_KEYVAULT_AVOID_THROTTLED", "0");
if (avoidTestThrottled != "0")
{
std::cout << "- Wait to avoid server throttled..." << std::endl;
// 10 sec should be enough to prevent from 429 error
std::this_thread::sleep_for(std::chrono::seconds(10));
}
}
public:
template <class T>
static inline void CheckValidResponse(
Azure::Response<T>& response,
Azure::Core::Http::HttpStatusCode expectedCode = Azure::Core::Http::HttpStatusCode::Ok)
{
auto const& rawResponse = response.RawResponse;
EXPECT_EQ(
static_cast<typename std::underlying_type<Azure::Core::Http::HttpStatusCode>::type>(
rawResponse->GetStatusCode()),
static_cast<typename std::underlying_type<Azure::Core::Http::HttpStatusCode>::type>(
expectedCode));
}
};
}}}}} // namespace Azure::Security::KeyVault::Certificates::Test

View File

@ -0,0 +1,122 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include <azure/identity/client_secret_credential.hpp>
#include "certificate_client_base_test.hpp"
#include <cstddef>
#include <gtest/gtest.h>
#include <string>
using namespace std::chrono_literals;
using namespace Azure::Security::KeyVault::Certificates;
using namespace Azure::Security::KeyVault::Certificates::Test;
TEST_F(KeyVaultCertificateClientTest, GetCertificate)
{
// cspell: disable-next-line
std::string const certificateName("vivazqu");
auto const& client
= GetClientForTest(::testing::UnitTest::GetInstance()->current_test_info()->name());
{
auto response = client.GetCertificate(certificateName);
CheckValidResponse(response);
auto cert = response.Value;
EXPECT_EQ(cert.Name(), cert.Properties.Name);
EXPECT_EQ(cert.Properties.Name, certificateName);
EXPECT_EQ(cert.Properties.VaultUrl, m_keyVaultUrl);
// There should be a version
EXPECT_NE(cert.Properties.Version, "");
// x5t
EXPECT_NE(cert.Properties.X509Thumbprint.size(), 0);
EXPECT_EQ(cert.Properties.Tags.size(), 0);
// attributes
EXPECT_TRUE(cert.Properties.Enabled.HasValue());
EXPECT_TRUE(cert.Properties.NotBefore.HasValue());
EXPECT_TRUE(cert.Properties.ExpiresOn.HasValue());
EXPECT_TRUE(cert.Properties.CreatedOn.HasValue());
EXPECT_TRUE(cert.Properties.UpdatedOn.HasValue());
EXPECT_TRUE(cert.Properties.RecoverableDays.HasValue());
EXPECT_TRUE(cert.Properties.RecoveryLevel.HasValue());
// kid, sid, cer
EXPECT_NE(cert.KeyId, "");
EXPECT_NE(cert.SecretId, "");
EXPECT_NE(cert.Cer.size(), 0);
// policy
{
auto const& policy = cert.Policy;
// Key props
EXPECT_TRUE(policy.Exportable.HasValue());
EXPECT_TRUE(policy.KeyType.HasValue());
EXPECT_TRUE(policy.ReuseKey.HasValue());
// Recording uses RSA with no curve-name. Use RSA key when running LIVE
EXPECT_FALSE(policy.KeyCurveName.HasValue());
EXPECT_TRUE(policy.KeySize.HasValue());
// Secret props
EXPECT_TRUE(policy.ContentType.HasValue());
// x509_props
EXPECT_TRUE(policy.Subject.size() > 0);
// issuer
EXPECT_TRUE(policy.IssuerName.HasValue());
// attributes
EXPECT_TRUE(policy.CreatedOn.HasValue());
// lifetime_actions
EXPECT_TRUE(policy.LifetimeActions.size() > 0);
EXPECT_NE(policy.LifetimeActions[0].Action.ToString(), "");
}
}
}
TEST_F(KeyVaultCertificateClientTest, GetCertificateVersion)
{
// cspell: disable-next-line
std::string const certificateName("vivazqu");
std::string const certificateVersion("8d532937fea74df58d9b18fca036ad51");
auto const& client
= GetClientForTest(::testing::UnitTest::GetInstance()->current_test_info()->name());
{
GetCertificateOptions options;
options.Version = certificateVersion;
auto response = client.GetCertificateVersion(certificateName, options);
CheckValidResponse(response);
auto cert = response.Value;
EXPECT_EQ(cert.Name(), cert.Properties.Name);
EXPECT_EQ(cert.Properties.Name, certificateName);
EXPECT_EQ(cert.Properties.VaultUrl, m_keyVaultUrl);
// There should be a version
EXPECT_NE(cert.Properties.Version, "");
// x5t
EXPECT_NE(cert.Properties.X509Thumbprint.size(), 0);
EXPECT_EQ(cert.Properties.Tags.size(), 0);
// attributes
EXPECT_TRUE(cert.Properties.Enabled.HasValue());
EXPECT_TRUE(cert.Properties.NotBefore.HasValue());
EXPECT_TRUE(cert.Properties.ExpiresOn.HasValue());
EXPECT_TRUE(cert.Properties.CreatedOn.HasValue());
EXPECT_TRUE(cert.Properties.UpdatedOn.HasValue());
EXPECT_TRUE(cert.Properties.RecoverableDays.HasValue());
EXPECT_TRUE(cert.Properties.RecoveryLevel.HasValue());
// kid, sid, cer
EXPECT_NE(cert.KeyId, "");
EXPECT_NE(cert.SecretId, "");
EXPECT_NE(cert.Cer.size(), 0);
}
}

View File

@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
// Define `min` and `max` as function-like macros before including all public
// headers to ensure that uses of those identifiers are defended against
// expansion as function-like macros. Define `small` as an object-like macro to
// ensure that identifier isn't used at all. Windows.h is badly behaved and
// defines similar macros with these names and we want to ensure the SDK headers
// function even when a naive user includes Windows.h first.
//
#define small FAIL><TO][COMPILE)(VERY{{{LOUDLY!!!
#define max(x, y) small
#define min(x, y) small
#include "azure/keyvault/keyvault_certificates.hpp"

View File

@ -0,0 +1,30 @@
{
"networkCallRecords": [
{
"Headers": {
"user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Linux 5.4.0-1056-azure x86_64 #58~18.04.1-Ubuntu SMP Wed Jul 28 23:14:18 UTC 2021)",
"x-ms-client-request-id": "932e1149-d496-4cb2-51d4-1ba1aa13b5d8"
},
"Method": "GET",
"Response": {
"BODY": "{\"id\":\"https://vivaz.vault.azure.net/certificates/vivazqu/8d532937fea74df58d9b18fca036ad51\",\"kid\":\"https://vivaz.vault.azure.net/keys/vivazqu/8d532937fea74df58d9b18fca036ad51\",\"sid\":\"https://vivaz.vault.azure.net/secrets/vivazqu/8d532937fea74df58d9b18fca036ad51\",\"x5t\":\"7ojjp5dyU2lDF0UkU5ekmfrHGUc\",\"cer\":\"MIIDLDCCAhSgAwIBAgIQAxd2DfDpSUWO55wIK3plrzANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwh2aHZiMTk4OTAeFw0yMTA4MzEyMDM2NTJaFw0yMjA4MzEyMDQ2NTJaMBMxETAPBgNVBAMTCHZodmIxOTg5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5pMgw+hP76Hu+ZXkjfrQTw04jUPTfpXPCw4AIjLNo3g4mUmqTDXd3yNIUOpmibfPcDhGotyPiE3UO0hsQCBTf18iHYM108BhO3shVR2sILKw5CBKhqMr4U+g4o9iUsXgiLRO58SUFvJlj9aio7tgS1Z8gcBkYpmJKDrVvZb65SbewkTC6iohhornU3q5ju3fEKtvVllmOgMxlGESYOEkONxAjQccqVWvbElhT0py2pkwDxiIxkFWMnBdtblIuoimKS+UujcSvrrxXFoTT47MzxjuFTTCYvaqHTmmSnEdR7SBansGVyaoW+Pyqm4SNvToa8JzFnf2+0lpwv/f3C52QIDAQABo3wwejAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHwYDVR0jBBgwFoAUDkHLOHieUJ6WfzBMcn6iiJ3FqS4wHQYDVR0OBBYEFA5Byzh4nlCeln8wTHJ+ooidxakuMA0GCSqGSIb3DQEBCwUAA4IBAQAN52HqsZTL9psVFbbvnI8DeO+/oRBkUJhEyk5zgkWkQYBMqCOfULxuG5kIvJkmR83TZOwN0Ki6cVg6pw16zh8IHyE4KgoVEO+3n2pbldJY7RuQDGcmE7kd+B+uOpU5yW6vHCsfGnRBid05uf3+y618B9mUiJ0NjpGoITCelkMiqe5ISDUpx6g4uI/PGyKQzFCddO9Kzy3uGdilcuSfEOlZdgHzmvuqrhdWjx+tFjCGDeWP6WW4BTJBXS14dJ3n+oNWpnTVxyybB5K95O8MWh1ASnw3XA3Zgq6jfTLwQHth9BPSR7iy5CfHLr6l7ZBXLiOlyZCTU1IHpTK56EYE4DpC\",\"attributes\":{\"enabled\":true,\"nbf\":1630442212,\"exp\":1661978812,\"created\":1630442812,\"updated\":1630442812,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"policy\":{\"id\":\"https://vivaz.vault.azure.net/certificates/vivazqu/policy\",\"key_props\":{\"exportable\":true,\"kty\":\"RSA\",\"key_size\":2048,\"reuse_key\":false},\"secret_props\":{\"contentType\":\"application/x-pkcs12\"},\"x509_props\":{\"subject\":\"CN=vhvb1989\",\"sans\":{\"dns_names\":[]},\"ekus\":[\"1.3.6.1.5.5.7.3.1\",\"1.3.6.1.5.5.7.3.2\"],\"key_usage\":[\"digitalSignature\",\"keyEncipherment\"],\"validity_months\":12,\"basic_constraints\":{\"ca\":false}},\"lifetime_actions\":[{\"trigger\":{\"lifetime_percentage\":80},\"action\":{\"action_type\":\"AutoRenew\"}}],\"issuer\":{\"name\":\"Self\"},\"attributes\":{\"enabled\":true,\"created\":1630442797,\"updated\":1630442797}},\"pending\":{\"id\":\"https://vivaz.vault.azure.net/certificates/vivazqu/pending\"}}",
"STATUS_CODE": "200",
"cache-control": "no-cache",
"content-length": "2270",
"content-type": "application/json; charset=utf-8",
"date": "Wed, 01 Sep 2021 21:21:03 GMT",
"expires": "-1",
"pragma": "no-cache",
"strict-transport-security": "max-age=31536000;includeSubDomains",
"x-content-type-options": "nosniff",
"x-ms-client-request-id": "932e1149-d496-4cb2-51d4-1ba1aa13b5d8",
"x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;",
"x-ms-keyvault-region": "eastus",
"x-ms-keyvault-service-version": "1.9.79.1",
"x-ms-request-id": "4a1a7eb3-7736-4da9-b3df-173b5782e208",
"x-powered-by": "ASP.NET"
},
"Url": "https://REDACTED.vault.azure.net/certificates/vivazqu?api-version=7.2"
}
]
}

View File

@ -0,0 +1,30 @@
{
"networkCallRecords": [
{
"Headers": {
"user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Linux 5.4.0-1056-azure x86_64 #58~18.04.1-Ubuntu SMP Wed Jul 28 23:14:18 UTC 2021)",
"x-ms-client-request-id": "fd08ec44-e0b4-4568-7a4b-7f778c59e81a"
},
"Method": "GET",
"Response": {
"BODY": "{\"id\":\"https://vivaz.vault.azure.net/certificates/vivazqu/8d532937fea74df58d9b18fca036ad51\",\"kid\":\"https://vivaz.vault.azure.net/keys/vivazqu/8d532937fea74df58d9b18fca036ad51\",\"sid\":\"https://vivaz.vault.azure.net/secrets/vivazqu/8d532937fea74df58d9b18fca036ad51\",\"x5t\":\"7ojjp5dyU2lDF0UkU5ekmfrHGUc\",\"cer\":\"MIIDLDCCAhSgAwIBAgIQAxd2DfDpSUWO55wIK3plrzANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwh2aHZiMTk4OTAeFw0yMTA4MzEyMDM2NTJaFw0yMjA4MzEyMDQ2NTJaMBMxETAPBgNVBAMTCHZodmIxOTg5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5pMgw+hP76Hu+ZXkjfrQTw04jUPTfpXPCw4AIjLNo3g4mUmqTDXd3yNIUOpmibfPcDhGotyPiE3UO0hsQCBTf18iHYM108BhO3shVR2sILKw5CBKhqMr4U+g4o9iUsXgiLRO58SUFvJlj9aio7tgS1Z8gcBkYpmJKDrVvZb65SbewkTC6iohhornU3q5ju3fEKtvVllmOgMxlGESYOEkONxAjQccqVWvbElhT0py2pkwDxiIxkFWMnBdtblIuoimKS+UujcSvrrxXFoTT47MzxjuFTTCYvaqHTmmSnEdR7SBansGVyaoW+Pyqm4SNvToa8JzFnf2+0lpwv/f3C52QIDAQABo3wwejAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHwYDVR0jBBgwFoAUDkHLOHieUJ6WfzBMcn6iiJ3FqS4wHQYDVR0OBBYEFA5Byzh4nlCeln8wTHJ+ooidxakuMA0GCSqGSIb3DQEBCwUAA4IBAQAN52HqsZTL9psVFbbvnI8DeO+/oRBkUJhEyk5zgkWkQYBMqCOfULxuG5kIvJkmR83TZOwN0Ki6cVg6pw16zh8IHyE4KgoVEO+3n2pbldJY7RuQDGcmE7kd+B+uOpU5yW6vHCsfGnRBid05uf3+y618B9mUiJ0NjpGoITCelkMiqe5ISDUpx6g4uI/PGyKQzFCddO9Kzy3uGdilcuSfEOlZdgHzmvuqrhdWjx+tFjCGDeWP6WW4BTJBXS14dJ3n+oNWpnTVxyybB5K95O8MWh1ASnw3XA3Zgq6jfTLwQHth9BPSR7iy5CfHLr6l7ZBXLiOlyZCTU1IHpTK56EYE4DpC\",\"attributes\":{\"enabled\":true,\"nbf\":1630442212,\"exp\":1661978812,\"created\":1630442812,\"updated\":1630442812,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"subject\":\"CN=vhvb1989\",\"issuer\":\"CN=vhvb1989\",\"sans\":{\"dns_names\":[]},\"serialnumber\":\"0317760DF0E949458EE79C082B7A65AF\"}",
"STATUS_CODE": "200",
"cache-control": "no-cache",
"content-length": "1694",
"content-type": "application/json; charset=utf-8",
"date": "Wed, 01 Sep 2021 21:21:03 GMT",
"expires": "-1",
"pragma": "no-cache",
"strict-transport-security": "max-age=31536000;includeSubDomains",
"x-content-type-options": "nosniff",
"x-ms-client-request-id": "fd08ec44-e0b4-4568-7a4b-7f778c59e81a",
"x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;",
"x-ms-keyvault-region": "eastus",
"x-ms-keyvault-service-version": "1.9.79.1",
"x-ms-request-id": "b9720337-3e1b-468b-ada0-a8c3f0f53c04",
"x-powered-by": "ASP.NET"
},
"Url": "https://REDACTED.vault.azure.net/certificates/vivazqu/8d532937fea74df58d9b18fca036ad51?api-version=7.2"
}
]
}

View File

@ -0,0 +1,11 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(azure-core-cpp "1.2.0")
include("${CMAKE_CURRENT_LIST_DIR}/azure-security-keyvault-certificates-cppTargets.cmake")
check_required_components("azure-security-keyvault-certificates-cpp")

View File

@ -0,0 +1,21 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO Azure/azure-sdk-for-cpp
REF azure-security-keyvault-certificates_@AZ_LIBRARY_VERSION@
SHA512 0
)
vcpkg_cmake_configure(
SOURCE_PATH ${SOURCE_PATH}/sdk/keyvault/azure-security-keyvault-certificates/
OPTIONS
-DWARNINGS_AS_ERRORS=OFF
)
vcpkg_cmake_install()
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
vcpkg_cmake_config_fixup()
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share")
vcpkg_copy_pdbs()

View File

@ -0,0 +1,29 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
{
"name": "azure-security-keyvault-keys-cpp",
"version-semver": "@AZ_LIBRARY_VERSION@",
"description": [
"Microsoft Azure Key Vault Keys SDK for C++",
"This library provides Azure Key Vault Keys SDK."
],
"homepage": "https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/keyvault/azure-security-keyvault-keys",
"license": "MIT",
"builtin-baseline": "14c54c49b56a964ac7f2f701a6857adb02ae1bec",
"dependencies": [
{
"name": "azure-core-cpp",
"default-features": false,
"version>=": "1.1.0"
},
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
]
}