From 80357ab69d6db24877340796622546c5eca27c95 Mon Sep 17 00:00:00 2001 From: Victor Vazquez Date: Sat, 16 Jan 2021 00:50:44 +0000 Subject: [PATCH] Feature/keyvault - GetKey + KeyVaultCommon (#1383) * add cmake project for keyvault keys (#1081) --- CMakeLists.txt | 1 + sdk/keyvault/CMakeLists.txt | 11 +++ sdk/keyvault/README.md | 48 ++++++++++ .../CHANGELOG.md | 4 + .../CMakeLists.txt | 70 +++++++++++++++ .../azure-security-keyvault-common/NOTICE.txt | 32 +++++++ .../azure-security-keyvault-common/README.md | 5 ++ .../cgmanifest.json | 36 ++++++++ .../keyvault/common/keyvault_constants.hpp | 16 ++++ .../keyvault/common/keyvault_exception.hpp | 29 +++++++ .../keyvault/common/keyvault_pipeline.hpp | 79 +++++++++++++++++ .../inc/azure/keyvault/common/version.hpp | 33 +++++++ .../src/keyvault_exception.cpp | 67 ++++++++++++++ .../src/keyvault_pipeline.cpp | 49 +++++++++++ .../test/CMakeLists.txt | 27 ++++++ .../test/main.cpp | 11 +++ .../test/pipeline_test.cpp | 20 +++++ .../vcpkg/CONTROL | 7 ++ .../vcpkg/Config.cmake.in | 15 ++++ .../vcpkg/portfile.cmake | 24 +++++ .../azure-security-keyvault-keys/CHANGELOG.md | 4 + .../CMakeLists.txt | 78 +++++++++++++++++ .../azure-security-keyvault-keys/NOTICE.txt | 32 +++++++ .../azure-security-keyvault-keys/README.md | 5 ++ .../cgmanifest.json | 36 ++++++++ .../inc/azure/keyvault/key_vault.hpp | 6 ++ .../inc/azure/keyvault/keys/json_web_key.hpp | 54 ++++++++++++ .../inc/azure/keyvault/keys/key_client.hpp | 87 +++++++++++++++++++ .../keyvault/keys/key_client_options.hpp | 43 +++++++++ .../inc/azure/keyvault/keys/key_operation.hpp | 28 ++++++ .../azure/keyvault/keys/key_properties.hpp | 45 ++++++++++ .../keyvault/keys/key_release_policy.hpp | 26 ++++++ .../inc/azure/keyvault/keys/key_type.hpp | 34 ++++++++ .../inc/azure/keyvault/keys/key_vault_key.hpp | 40 +++++++++ .../inc/azure/keyvault/keys/version.hpp | 33 +++++++ .../sample/CMakeLists.txt | 6 ++ .../sample/get-key/CMakeLists.txt | 15 ++++ .../sample/get-key/main.cpp | 76 ++++++++++++++++ .../src/key_client.cpp | 38 ++++++++ .../src/key_type.cpp | 66 ++++++++++++++ .../src/key_vault_key.cpp | 42 +++++++++ .../test/CMakeLists.txt | 27 ++++++ .../test/key_client_test.cpp | 31 +++++++ .../test/main.cpp | 11 +++ .../vcpkg/CONTROL | 7 ++ .../vcpkg/Config.cmake.in | 11 +++ .../vcpkg/portfile.cmake | 24 +++++ sdk/keyvault/ci.yml | 41 +++++++++ 48 files changed, 1530 insertions(+) create mode 100644 sdk/keyvault/CMakeLists.txt create mode 100644 sdk/keyvault/README.md create mode 100644 sdk/keyvault/azure-security-keyvault-common/CHANGELOG.md create mode 100644 sdk/keyvault/azure-security-keyvault-common/CMakeLists.txt create mode 100644 sdk/keyvault/azure-security-keyvault-common/NOTICE.txt create mode 100644 sdk/keyvault/azure-security-keyvault-common/README.md create mode 100644 sdk/keyvault/azure-security-keyvault-common/cgmanifest.json create mode 100644 sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_constants.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_exception.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_pipeline.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/version.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-common/src/keyvault_exception.cpp create mode 100644 sdk/keyvault/azure-security-keyvault-common/src/keyvault_pipeline.cpp create mode 100644 sdk/keyvault/azure-security-keyvault-common/test/CMakeLists.txt create mode 100644 sdk/keyvault/azure-security-keyvault-common/test/main.cpp create mode 100644 sdk/keyvault/azure-security-keyvault-common/test/pipeline_test.cpp create mode 100644 sdk/keyvault/azure-security-keyvault-common/vcpkg/CONTROL create mode 100644 sdk/keyvault/azure-security-keyvault-common/vcpkg/Config.cmake.in create mode 100644 sdk/keyvault/azure-security-keyvault-common/vcpkg/portfile.cmake create mode 100644 sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md create mode 100644 sdk/keyvault/azure-security-keyvault-keys/CMakeLists.txt create mode 100644 sdk/keyvault/azure-security-keyvault-keys/NOTICE.txt create mode 100644 sdk/keyvault/azure-security-keyvault-keys/README.md create mode 100644 sdk/keyvault/azure-security-keyvault-keys/cgmanifest.json create mode 100644 sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/key_vault.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/json_web_key.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client_options.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_operation.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_properties.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_release_policy.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_type.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_vault_key.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/version.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/sample/CMakeLists.txt create mode 100644 sdk/keyvault/azure-security-keyvault-keys/sample/get-key/CMakeLists.txt create mode 100644 sdk/keyvault/azure-security-keyvault-keys/sample/get-key/main.cpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/src/key_client.cpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/src/key_type.cpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/src/key_vault_key.cpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/test/CMakeLists.txt create mode 100644 sdk/keyvault/azure-security-keyvault-keys/test/key_client_test.cpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/test/main.cpp create mode 100644 sdk/keyvault/azure-security-keyvault-keys/vcpkg/CONTROL create mode 100644 sdk/keyvault/azure-security-keyvault-keys/vcpkg/Config.cmake.in create mode 100644 sdk/keyvault/azure-security-keyvault-keys/vcpkg/portfile.cmake create mode 100644 sdk/keyvault/ci.yml diff --git a/CMakeLists.txt b/CMakeLists.txt index b584b3f08..d93535378 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,3 +67,4 @@ add_subdirectory(sdk/identity/azure-identity) add_subdirectory(sdk/storage) add_subdirectory(sdk/template/azure-template) +add_subdirectory(sdk/keyvault) diff --git a/sdk/keyvault/CMakeLists.txt b/sdk/keyvault/CMakeLists.txt new file mode 100644 index 000000000..01de74a7b --- /dev/null +++ b/sdk/keyvault/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +cmake_minimum_required (VERSION 3.13) + +project (azure-security-keyvault LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +add_subdirectory(azure-security-keyvault-common) +add_subdirectory(azure-security-keyvault-keys) diff --git a/sdk/keyvault/README.md b/sdk/keyvault/README.md new file mode 100644 index 000000000..c40b9d965 --- /dev/null +++ b/sdk/keyvault/README.md @@ -0,0 +1,48 @@ +# Azure Key Vault Client Library for C++ + +The Azure Key Vault Client Library for C++ allows you to build applications against Microsoft Azure Key Vault. For an overview of Azure Key Vault, see [Introduction to Microsoft Azure Key Vault](https://docs.microsoft.com/azure/key-vault). + +# Features + +- Keys + - Get/Create/Delete Keys + +# Getting started + +... + +## Requirements + +To call Azure services, you must first have an Azure subscription. Sign up for a [free trial](https://azure.microsoft.com/pricing/free-trial/) or use your [MSDN subscriber benefits](https://azure.microsoft.com/pricing/member-offers/msdn-benefits-details/). + +## Need Help? + +Be sure to check out the [Azure Key Vault Forum](https://social.msdn.microsoft.com/Forums/azure/home?forum=keyvault) on MSDN if you need help, or use [StackOverflow](https://stackoverflow.com/questions/tagged/azure). + +## Collaborate & Contribute + +We gladly accept community contributions. + +- **Issues:** Report bugs on the [Issues page](https://github.com/Azure/azure-sdk-for-cpp/issues) in GitHub. Ideally, please add an "[Key Vault]" prefix to the title for easier categorizing. +- **Forums:** Communicate with the Azure Key Vault development team on the [Azure Key Vault Forum](https://social.msdn.microsoft.com/Forums/azure/home?forum=keyvaulthome) or [StackOverflow](https://stackoverflow.com/questions/tagged/azure). +- **Source Code Contributions:** Please follow the [contribution guidelines for Azure open source](https://azure.github.io/azure-sdk/cpp_introduction.html) for instructions about contributing to the source project. + +For general suggestions about Azure, use our [Azure feedback forum](https://feedback.azure.com/forums/34192--general-feedback). + +## Download & Install + +### Install Dependencies + +#### Windows + +#### Unix Platforms + +### Build from Source + +#### Windows + +## Dependencies + + - [Azure Core SDK](https://github.com/Azure/azure-sdk-for-cpp/blob/master/README.md) + +## Code Samples diff --git a/sdk/keyvault/azure-security-keyvault-common/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-common/CHANGELOG.md new file mode 100644 index 000000000..2fcc5787f --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/CHANGELOG.md @@ -0,0 +1,4 @@ +# Release History + +## 4.0.0-beta.1 (Unreleased) + diff --git a/sdk/keyvault/azure-security-keyvault-common/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-common/CMakeLists.txt new file mode 100644 index 000000000..15e8592e6 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/CMakeLists.txt @@ -0,0 +1,70 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +cmake_minimum_required (VERSION 3.13) +project(azure-security-keyvault-common 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(az_vcpkg) +include(az_version) +include(CodeCoverage) +include(DefineTransportAdapter) +include(doxygen_common) +include(global_compile_options) + +az_vcpkg_integrate() + +if(NOT AZ_ALL_LIBRARIES) + find_package(azure-core-cpp CONFIG QUIET) + if(NOT azure-core-cpp_FOUND) + find_package(azure-core-cpp REQUIRED) + endif() +endif() + +set( + AZURE_KEYVAULT_COMMON_HEADER + inc/azure/keyvault/common/keyvault_constants.hpp + inc/azure/keyvault/common/keyvault_exception.hpp + inc/azure/keyvault/common/keyvault_pipeline.hpp + inc/azure/keyvault/common/version.hpp +) + +set( + AZURE_KEYVAULT_COMMON_SOURCE + src/keyvault_exception.cpp + src/keyvault_pipeline.cpp +) + +add_library( + azure-security-keyvault-common + ${AZURE_KEYVAULT_COMMON_HEADER} ${AZURE_KEYVAULT_COMMON_SOURCE} +) +add_library(Azure::keyvault::common ALIAS azure-security-keyvault-common) + +target_include_directories( + azure-security-keyvault-common + PUBLIC + $ + $ + ${azure-core-cpp_INCLUDE_DIRS} +) + +target_link_libraries(azure-security-keyvault-common PUBLIC Azure::azure-core) + +# coverage. Has no effect if BUILD_CODE_COVERAGE is OFF +create_code_coverage(keyvault azure-security-keyvault-common azure-security-keyvault-common-test) + +get_az_version("${CMAKE_CURRENT_SOURCE_DIR}/inc/azure/keyvault/common/version.hpp") +generate_documentation(azure-security-keyvault-common ${AZ_LIBRARY_VERSION}) + +if(BUILD_TESTING) + # tests + add_subdirectory(test) +endif() + +az_vcpkg_export(azure-security-keyvault-common) diff --git a/sdk/keyvault/azure-security-keyvault-common/NOTICE.txt b/sdk/keyvault/azure-security-keyvault-common/NOTICE.txt new file mode 100644 index 000000000..6e1bceb63 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/NOTICE.txt @@ -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. + diff --git a/sdk/keyvault/azure-security-keyvault-common/README.md b/sdk/keyvault/azure-security-keyvault-common/README.md new file mode 100644 index 000000000..6b152e923 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/README.md @@ -0,0 +1,5 @@ +# Azure Key Vault Common Package client library for C++ + +### License + +Azure SDK for C++ is licensed under the [MIT](https://github.com/Azure/azure-sdk-for-cpp/blob/master/LICENSE.txt) license. \ No newline at end of file diff --git a/sdk/keyvault/azure-security-keyvault-common/cgmanifest.json b/sdk/keyvault/azure-security-keyvault-common/cgmanifest.json new file mode 100644 index 000000000..7f2901e70 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/cgmanifest.json @@ -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 + } + ] +} diff --git a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_constants.hpp b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_constants.hpp new file mode 100644 index 000000000..718fca54b --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_constants.hpp @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +namespace Azure { namespace Security { namespace KeyVault { namespace Common { namespace Details { + /***************** KeyVault headers *****************/ + static constexpr char const ContentType[] = "Content-Type"; + static constexpr char const ApplicationJson[] = "application/json"; + static constexpr char const Accept[] = "Accept"; + static constexpr char const MsRequestId[] = "x-ms-request-id"; + static constexpr char const MsClientRequestId[] = "x-ms-client-request-id"; + + /**************** KeyVault QueryParameters *********/ + static constexpr char const ApiVersion[] = "api-version"; +}}}}} // namespace Azure::Security::KeyVault::Common::Details diff --git a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_exception.hpp b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_exception.hpp new file mode 100644 index 000000000..a72c8dcf0 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_exception.hpp @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include +#include +#include + +namespace Azure { namespace Security { namespace KeyVault { namespace Common { + + struct KeyVaultException : public std::runtime_error + { + explicit KeyVaultException(const std::string& message) : std::runtime_error(message) {} + + Azure::Core::Http::HttpStatusCode StatusCode = Azure::Core::Http::HttpStatusCode::None; + std::string ReasonPhrase; + std::string ClientRequestId; + std::string RequestId; + std::string ErrorCode; + std::string Message; + std::unique_ptr RawResponse; + + static KeyVaultException CreateFromResponse( + std::unique_ptr response); + }; +}}}} // namespace Azure::Security::KeyVault::Common diff --git a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_pipeline.hpp b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_pipeline.hpp new file mode 100644 index 000000000..6a140d9c8 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_pipeline.hpp @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace Azure { namespace Security { namespace KeyVault { namespace Common { namespace Internal { + + /** + * @brief The HTTP pipeline used by KeyVault clients. + */ + class KeyVaultPipeline { + Azure::Core::Http::Url m_vaultUrl; + Azure::Core::Http::HttpPipeline m_pipeline; + std::string m_apiVersion; + + /** + * @brief Create a Request to be sent. + * + * @param method Represent an HTTP method. + * @param path The path for the HTTP request. + * @return A constructed request. + */ + Azure::Core::Http::Request CreateRequest( + Azure::Core::Http::HttpMethod method, + std::vector const& path) const; + + std::unique_ptr SendRequest( + Azure::Core::Context const& context, + Azure::Core::Http::Request& request) const; + + public: + /** + * @brief Construct a new Key Vault Pipeline. + * + * @param vaultUrl The url address for the Key Vault. + * @param policies The policies to use for building the KeyVaultPipeline. + */ + explicit KeyVaultPipeline( + Azure::Core::Http::Url vaultUrl, + std::string apiVersion, + std::vector> const& policies) + : m_vaultUrl(std::move(vaultUrl)), m_pipeline(policies), m_apiVersion(std::move(apiVersion)) + { + } + + /** + * @brief Create and send the HTTP request using. Uses the result factory function to create + * the response type. + * + * + * @param context The context for per-operation options or cancellation. + * @param method The method for the request. + * @param factoryFn The function to deserialize and produce T from the raw response. + * @param path A path for the request represented as a vector of strings. + * @return Azure::Core::Response + */ + template + Azure::Core::Response SendRequest( + Azure::Core::Context const& context, + Azure::Core::Http::HttpMethod method, + std::function factoryFn, + std::vector const& path) + { + auto request = CreateRequest(method, path); + auto response = SendRequest(context, request); + return Azure::Core::Response(factoryFn(*response), std::move(response)); + } + }; +}}}}} // namespace Azure::Security::KeyVault::Common::Internal diff --git a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/version.hpp b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/version.hpp new file mode 100644 index 000000000..d727202d3 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/version.hpp @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#define AZURE_SECURITY_KEYVAULT_COMMON_VERSION_MAJOR 4 +#define AZURE_SECURITY_KEYVAULT_COMMON_VERSION_MINOR 0 +#define AZURE_SECURITY_KEYVAULT_COMMON_VERSION_PATCH 0 +#define AZURE_SECURITY_KEYVAULT_COMMON_VERSION_PRERELEASE "beta.1" + +namespace Azure { namespace Security { namespace KeyVault { namespace Common { + + class Version { + public: + static constexpr int Major = AZURE_SECURITY_KEYVAULT_COMMON_VERSION_MAJOR; + static constexpr int Minor = AZURE_SECURITY_KEYVAULT_COMMON_VERSION_MINOR; + static constexpr int Patch = AZURE_SECURITY_KEYVAULT_COMMON_VERSION_PATCH; + static std::string const PreRelease; + static std::string VersionString(); + + private: + // To avoid leaking out the #define values we smuggle out the value + // which will later be used to initialize the PreRelease std::string + static constexpr const char* secret = AZURE_SECURITY_KEYVAULT_COMMON_VERSION_PRERELEASE; + }; +}}}} // namespace Azure::Security::KeyVault::Common + +#undef AZURE_SECURITY_KEYVAULT_COMMON_VERSION_MAJOR +#undef AZURE_SECURITY_KEYVAULT_COMMON_VERSION_MINOR +#undef AZURE_SECURITY_KEYVAULT_COMMON_VERSION_PATCH +#undef AZURE_SECURITY_KEYVAULT_COMMON_VERSION_PRERELEASE diff --git a/sdk/keyvault/azure-security-keyvault-common/src/keyvault_exception.cpp b/sdk/keyvault/azure-security-keyvault-common/src/keyvault_exception.cpp new file mode 100644 index 000000000..adfe7d769 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/src/keyvault_exception.cpp @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include "azure/keyvault/common/keyvault_exception.hpp" +#include "azure/keyvault/common/keyvault_constants.hpp" + +#include + +#include +#include + +using namespace Azure::Security::KeyVault::Common; + +namespace { + +inline std::string GetHeaderOrEmptyString( + std::map const& headers, + std::string const& headerName) +{ + auto header = headers.find(headerName); + if (header != headers.end()) + { + return header->second; // second is the header value. + } + return {}; // empty string +} + +} // namespace + +KeyVaultException KeyVaultException::CreateFromResponse( + std::unique_ptr response) +{ + std::vector bodyBuffer = std::move(response->GetBody()); + + auto httpStatusCode = response->GetStatusCode(); + std::string reasonPhrase = response->GetReasonPhrase(); + auto& headers = response->GetHeaders(); + std::string requestId = GetHeaderOrEmptyString(headers, Details::MsRequestId); + std::string clientRequestId = GetHeaderOrEmptyString(headers, Details::MsClientRequestId); + std::string contentType = GetHeaderOrEmptyString(headers, Details::ContentType); + std::string errorCode; + std::string message; + + if (contentType.find("json") != std::string::npos) + { + auto jsonParser = nlohmann::json::parse(bodyBuffer); + auto& error = jsonParser["error"]; + errorCode = error["code"].get(); + message = error["message"].get(); + } + else + { + message = std::string(bodyBuffer.begin(), bodyBuffer.end()); + } + + KeyVaultException result = KeyVaultException( + std::to_string(static_cast::type>( + httpStatusCode)) + + " " + reasonPhrase + "\n" + message + "\nRequest ID: " + requestId); + result.StatusCode = httpStatusCode; + result.ReasonPhrase = std::move(reasonPhrase); + result.RequestId = std::move(requestId); + result.ErrorCode = std::move(errorCode); + result.Message = std::move(message); + result.RawResponse = std::move(response); + return result; +} diff --git a/sdk/keyvault/azure-security-keyvault-common/src/keyvault_pipeline.cpp b/sdk/keyvault/azure-security-keyvault-common/src/keyvault_pipeline.cpp new file mode 100644 index 000000000..5b22b1bc9 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/src/keyvault_pipeline.cpp @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include "azure/keyvault/common/keyvault_pipeline.hpp" +#include "azure/keyvault/common/keyvault_constants.hpp" +#include "azure/keyvault/common/keyvault_exception.hpp" + +using namespace Azure::Security::KeyVault::Common; + +Azure::Core::Http::Request Internal::KeyVaultPipeline::CreateRequest( + Azure::Core::Http::HttpMethod method, + std::vector const& path) const +{ + Azure::Core::Http::Request request(method, m_vaultUrl); + + request.AddHeader(Details::ContentType, Details::ApplicationJson); + request.AddHeader(Details::Accept, Details::ApplicationJson); + + request.GetUrl().AppendQueryParameter(Details::ApiVersion, m_apiVersion); + + for (std::string const& p : path) + { + if (!p.empty()) + { + request.GetUrl().AppendPath(p); + } + } + return request; +} + +std::unique_ptr Internal::KeyVaultPipeline::SendRequest( + Azure::Core::Context const& context, + Azure::Core::Http::Request& request) const +{ + auto response = m_pipeline.Send(context, request); + 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 KeyVaultException::CreateFromResponse(std::move(response)); + } + return response; +} diff --git a/sdk/keyvault/azure-security-keyvault-common/test/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-common/test/CMakeLists.txt new file mode 100644 index 000000000..ed9e174a2 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/test/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +cmake_minimum_required (VERSION 3.13) + +project (azure-security-keyvault-common-test LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +include(GoogleTest) + +add_executable ( + azure-security-keyvault-common-test + pipeline_test.cpp + main.cpp +) + +if (MSVC) + target_compile_options(azure-security-keyvault-common-test PUBLIC /wd6326 /wd26495 /wd26812) +endif() + +target_link_libraries(azure-security-keyvault-common-test PUBLIC azure-security-keyvault-common gtest gmock) + +# 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_add_tests(TARGET azure-security-keyvault-common-test + TEST_PREFIX azure-security-keyvault-common-test.) diff --git a/sdk/keyvault/azure-security-keyvault-common/test/main.cpp b/sdk/keyvault/azure-security-keyvault-common/test/main.cpp new file mode 100644 index 000000000..3d0b851aa --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/test/main.cpp @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include "gtest/gtest.h" + +int main(int argc, char** argv) +{ + testing::InitGoogleTest(&argc, argv); + auto r = RUN_ALL_TESTS(); + return r; +} diff --git a/sdk/keyvault/azure-security-keyvault-common/test/pipeline_test.cpp b/sdk/keyvault/azure-security-keyvault-common/test/pipeline_test.cpp new file mode 100644 index 000000000..6c06515b3 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/test/pipeline_test.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include "gtest/gtest.h" + +#include +#include +#include + +#include + +using namespace Azure::Security::KeyVault::Common::Internal; + +TEST(KeyVaultPipeline, initPipeline) +{ + std::vector> policies; + policies.emplace_back(std::make_unique()); + Azure::Core::Http::Url url("urlTest"); + EXPECT_NO_THROW(KeyVaultPipeline p(url, "version", policies)); +} diff --git a/sdk/keyvault/azure-security-keyvault-common/vcpkg/CONTROL b/sdk/keyvault/azure-security-keyvault-common/vcpkg/CONTROL new file mode 100644 index 000000000..5553d6c6d --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/vcpkg/CONTROL @@ -0,0 +1,7 @@ +Source: azure-security-keyvault-common-cpp +Version: @AZ_LIBRARY_VERSION@ +Build-Depends: azure-core-cpp, openssl (!windows) +Description: Microsoft Azure Common Key Vault SDK for C++ + This library provides common Azure KeyVault-related abstractions for Azure SDK. +Homepage: https://github.com/Azure/azure-sdk-for-cpp/tree/master/sdk/keyvault/azure-security-keyvault-common +Supports: !uwp diff --git a/sdk/keyvault/azure-security-keyvault-common/vcpkg/Config.cmake.in b/sdk/keyvault/azure-security-keyvault-common/vcpkg/Config.cmake.in new file mode 100644 index 000000000..e21df0e77 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/vcpkg/Config.cmake.in @@ -0,0 +1,15 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(azure-core-cpp) + +if(NOT MSVC) + find_dependency(OpenSSL) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/azure-security-keyvault-common-cppTargets.cmake") + +check_required_components("azure-security-keyvault-common-cpp") diff --git a/sdk/keyvault/azure-security-keyvault-common/vcpkg/portfile.cmake b/sdk/keyvault/azure-security-keyvault-common/vcpkg/portfile.cmake new file mode 100644 index 000000000..d03a7c5b9 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-common/vcpkg/portfile.cmake @@ -0,0 +1,24 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +vcpkg_fail_port_install(ON_TARGET "UWP") + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO Azure/azure-sdk-for-cpp + REF azure-security-keyvault-common_@AZ_LIBRARY_VERSION@ + SHA512 1 +) + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH}/sdk/keyvault/azure-security-keyvault-common/ + PREFER_NINJA + OPTIONS + -DWARNINGS_AS_ERRORS=OFF +) + +vcpkg_install_cmake() +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") +vcpkg_fixup_cmake_targets() +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share") +vcpkg_copy_pdbs() diff --git a/sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md new file mode 100644 index 000000000..2fcc5787f --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md @@ -0,0 +1,4 @@ +# Release History + +## 4.0.0-beta.1 (Unreleased) + diff --git a/sdk/keyvault/azure-security-keyvault-keys/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-keys/CMakeLists.txt new file mode 100644 index 000000000..b7e0ac67b --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/CMakeLists.txt @@ -0,0 +1,78 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +cmake_minimum_required (VERSION 3.13) +project(azure-security-keyvault-keys 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(az_vcpkg) +include(az_version) +include(CodeCoverage) +include(DefineTransportAdapter) +include(doxygen_common) +include(global_compile_options) + +az_vcpkg_integrate() + +if(NOT AZ_ALL_LIBRARIES) + find_package(azure-security-keyvault-common-cpp CONFIG QUIET) + if(NOT azure-security-keyvault-common-cpp_FOUND) + find_package(azure-security-keyvault-common-cpp REQUIRED) + endif() +endif() + +set( + AZURE_KEYVAULT_KEYS_HEADER + inc/azure/keyvault/keys/json_web_key.hpp + inc/azure/keyvault/keys/key_client.hpp + inc/azure/keyvault/keys/key_client_options.hpp + inc/azure/keyvault/keys/key_operation.hpp + inc/azure/keyvault/keys/key_properties.hpp + inc/azure/keyvault/keys/key_release_policy.hpp + inc/azure/keyvault/keys/key_type.hpp + inc/azure/keyvault/keys/key_vault_key.hpp + inc/azure/keyvault/keys/version.hpp +) + +set( + AZURE_KEYVAULT_KEYS_SOURCE + src/key_client.cpp + src/key_type.cpp + src/key_vault_key.cpp +) + +add_library(azure-security-keyvault-keys + ${AZURE_KEYVAULT_KEYS_HEADER} ${AZURE_KEYVAULT_KEYS_SOURCE} +) +add_library(Azure::keyvault::keys ALIAS azure-security-keyvault-keys) + +target_include_directories( + azure-security-keyvault-keys + PUBLIC + $ + $ + ${azure-core-cpp_INCLUDE_DIRS} +) + +target_link_libraries(azure-security-keyvault-keys PUBLIC Azure::keyvault::common) + +# coverage. Has no effect if BUILD_CODE_COVERAGE is OFF +create_code_coverage(keyvault azure-security-keyvault-keys azure-security-keyvault-keys-test) + +get_az_version("${CMAKE_CURRENT_SOURCE_DIR}/inc/azure/keyvault/keys/version.hpp") +generate_documentation(azure-security-keyvault-keys ${AZ_LIBRARY_VERSION}) + +if(BUILD_TESTING) + add_subdirectory(test) +endif() + +if(BUILD_SAMPLES) + add_subdirectory(sample) +endif() + +az_vcpkg_export(azure-security-keyvault-keys) diff --git a/sdk/keyvault/azure-security-keyvault-keys/NOTICE.txt b/sdk/keyvault/azure-security-keyvault-keys/NOTICE.txt new file mode 100644 index 000000000..6e1bceb63 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/NOTICE.txt @@ -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. + diff --git a/sdk/keyvault/azure-security-keyvault-keys/README.md b/sdk/keyvault/azure-security-keyvault-keys/README.md new file mode 100644 index 000000000..7cb459e95 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/README.md @@ -0,0 +1,5 @@ +# Azure Key Vault Keys Package client library for C++ + +### License + +Azure SDK for C++ is licensed under the [MIT](https://github.com/Azure/azure-sdk-for-cpp/blob/master/LICENSE.txt) license. \ No newline at end of file diff --git a/sdk/keyvault/azure-security-keyvault-keys/cgmanifest.json b/sdk/keyvault/azure-security-keyvault-keys/cgmanifest.json new file mode 100644 index 000000000..7f2901e70 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/cgmanifest.json @@ -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 + } + ] +} diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/key_vault.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/key_vault.hpp new file mode 100644 index 000000000..c2c44af1b --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/key_vault.hpp @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include "azure/keyvault/keys/key_client.hpp" diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/json_web_key.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/json_web_key.hpp new file mode 100644 index 000000000..e7f1cccf5 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/json_web_key.hpp @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include "azure/keyvault/keys/key_operation.hpp" +#include "azure/keyvault/keys/key_type.hpp" + +#include +#include + +namespace Azure { namespace Security { namespace KeyVault { namespace Keys { + + namespace Details { + constexpr static const char* KeyIdPropertyName = "kid"; + constexpr static const char* KeyTypePropertyName = "kty"; + constexpr static const char* KeyOpsPropertyName = "key_ops"; + constexpr static const char* CurveNamePropertyName = "crv"; + constexpr static const char* NPropertyName = "n"; + constexpr static const char* EPropertyName = "e"; + constexpr static const char* DPPropertyName = "dp"; + constexpr static const char* DQPropertyName = "dq"; + constexpr static const char* QIPropertyName = "qi"; + constexpr static const char* PPropertyName = "p"; + constexpr static const char* QPropertyName = "q"; + constexpr static const char* XPropertyName = "x"; + constexpr static const char* YPropertyName = "y"; + constexpr static const char* DPropertyName = "d"; + constexpr static const char* KPropertyName = "k"; + constexpr static const char* TPropertyName = "key_hsm"; + } // namespace Details + + struct JsonWebKey + { + /** + * @brief The Identifier of the key. This is not limited to a Url. + * + */ + std::string Id; + KeyTypeEnum KeyType; + + JsonWebKey() {} + + void SetKeyOperations(std::vector const& keyOperations) + { + m_keyOps = keyOperations; + } + std::vector const& KeyOperations() const { return m_keyOps; } + + private: + std::vector m_keyOps; + }; + +}}}} // namespace Azure::Security::KeyVault::Keys diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client.hpp new file mode 100644 index 000000000..97dbcc11d --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client.hpp @@ -0,0 +1,87 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include +#include + +#include "azure/keyvault/keys/key_client_options.hpp" +#include "azure/keyvault/keys/key_vault_key.hpp" + +#include +#include + +namespace Azure { namespace Security { namespace KeyVault { namespace Keys { + + namespace Details { + constexpr static const char* KeysPath = "keys"; + constexpr static const char* DeletedKeysPath = "deletedkeys"; + } // namespace Details + + /** + * @brief The KeyClient provides synchronous methods to manage a KeyVaultKe in the Azure Key + * Vault. The client supports creating, retrieving, updating, deleting, purging, backing up, + * restoring, and listing the KeyVaultKey. + */ + class KeyClient { + protected: + std::unique_ptr m_pipeline; + + public: + /** + * @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 KeyClient( + std::string const& vaultUrl, + std::shared_ptr credential, + KeyClientOptions options = KeyClientOptions()); + + /** + * @brief Optional parameters for KeyVaultClient::GetKey + * + */ + struct GetKeyOptions + { + /** + * @brief Context for cancelling long running operations. + */ + Azure::Core::Context context; + /** + * @brief Specify the key version to get. + */ + std::string version; + }; + + /** + * @brief Gets the public part of a stored key. + * + * @remark The get key operation is applicable to all key types. If the requested key is + * symmetric, then no key is released in the response. This operation requires the keys/get + * permission. + * + * @param name The name of the key. + * @param options Optional parameters for this operation. + * @return The Key wrapped in the Response. + */ + Azure::Core::Response GetKey( + std::string const& name, + GetKeyOptions const& options = GetKeyOptions()) const + { + return m_pipeline->SendRequest( + options.context, + Azure::Core::Http::HttpMethod::Get, + [name](Azure::Core::Http::RawResponse const& rawResponse) { + return Details::KeyVaultKeyDeserialize(name, rawResponse); + }, + {Details::KeysPath, name, options.version}); + } + }; + +}}}} // namespace Azure::Security::KeyVault::Keys diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client_options.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client_options.hpp new file mode 100644 index 000000000..54bbc53b7 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client_options.hpp @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include + +#include "azure/keyvault/keys/key_vault_key.hpp" + +namespace Azure { namespace Security { namespace KeyVault { namespace Keys { + + enum class ServiceVersion + { + V7_0, + V7_1, + V7_2 + }; + + struct KeyClientOptions + { + ServiceVersion Version; + Azure::Core::Http::RetryOptions RetryOptions; + Azure::Core::Http::TransportPolicyOptions TransportPolicyOptions; + + KeyClientOptions(ServiceVersion version = ServiceVersion::V7_1) : Version(version) {} + + std::string GetVersionString() + { + switch (Version) + { + case ServiceVersion::V7_0: + return "7.0"; + case ServiceVersion::V7_1: + return "7.1"; + default: + throw std::runtime_error("Version not found"); + } + } + }; + +}}}} // namespace Azure::Security::KeyVault::Keys diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_operation.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_operation.hpp new file mode 100644 index 000000000..0a20e46a6 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_operation.hpp @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +namespace Azure { namespace Security { namespace KeyVault { namespace Keys { + + class KeyOperation { + std::string m_operation; + + public: + KeyOperation(std::string const& operation) : m_operation(operation) {} + + std::string const& ToString() const { return m_operation; } + + static KeyOperation Encrypt() { return KeyOperation("encrypt"); } + static KeyOperation Decrypt() { return KeyOperation("decrypt"); } + static KeyOperation Sign() { return KeyOperation("sign"); } + static KeyOperation Verify() { return KeyOperation("verify"); } + static KeyOperation WrapKey() { return KeyOperation("wrapKey"); } + static KeyOperation UnwrapKey() { return KeyOperation("unwrapKey"); } + static KeyOperation Import() { return KeyOperation("import"); } + static KeyOperation Export() { return KeyOperation("export"); } + }; + +}}}} // namespace Azure::Security::KeyVault::Keys diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_properties.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_properties.hpp new file mode 100644 index 000000000..4c68d6f1e --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_properties.hpp @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "azure/keyvault/keys/key_release_policy.hpp" + +#include +#include + +namespace Azure { namespace Security { namespace KeyVault { namespace Keys { + + namespace Details { + constexpr static const char* ManagedPropertyName = "managed"; + constexpr static const char* AttributesPropertyName = "attributes"; + constexpr static const char* TagsPropertyName = "tags"; + constexpr static const char* ReleasePolicyPropertyName = "release_policy"; + } // namespace Details + + struct KeyProperties + { + std::string Name; + std::string Id; + std::string VaultUrl; + std::string Version; + bool Managed; + std::unordered_map Tags; + Azure::Core::Nullable Enabled; + Azure::Core::Nullable NotBefore; + Azure::Core::Nullable ExpiresOn; + Azure::Core::Nullable CreatedOn; + Azure::Core::Nullable UpdatedOn; + Azure::Core::Nullable RecoverableDays; + std::string RecoveryLevel; + Azure::Core::Nullable Exportable; + KeyReleasePolicy ReleasePolicy; + + KeyProperties() {} + KeyProperties(std::string name) : Name(std::move(name)) {} + }; + +}}}} // namespace Azure::Security::KeyVault::Keys diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_release_policy.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_release_policy.hpp new file mode 100644 index 000000000..b6644a1d7 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_release_policy.hpp @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +namespace Azure { namespace Security { namespace KeyVault { namespace Keys { + + namespace Details { + constexpr static const char* ContentTypePropertyName = "contentType"; + constexpr static const char* DataPropertyName = "data"; + } // namespace Details + + struct KeyReleasePolicy + { + std::string ContentType; + std::vector Data; + + KeyReleasePolicy() {} + + KeyReleasePolicy(std::vector data) : Data(std::move(data)) {} + }; + +}}}} // namespace Azure::Security::KeyVault::Keys diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_type.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_type.hpp new file mode 100644 index 000000000..33f7e6982 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_type.hpp @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +namespace Azure { namespace Security { namespace KeyVault { namespace Keys { + + namespace Details { + 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"; + constexpr static const char* OctValue = "oct"; + constexpr static const char* OctHsmValue = "oct-HSM"; + } // namespace Details + + enum class KeyTypeEnum + { + Ec, + EcHsm, + Rsa, + RsaHsm, + Oct, + OctHsm, + }; + + namespace Details { + KeyTypeEnum KeyTypeFromString(std::string const& name); + std::string KeyTypeToString(KeyTypeEnum kty); + } // namespace Details + +}}}} // namespace Azure::Security::KeyVault::Keys diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_vault_key.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_vault_key.hpp new file mode 100644 index 000000000..8ccf01878 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_vault_key.hpp @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include "azure/keyvault/keys/json_web_key.hpp" +#include "azure/keyvault/keys/key_operation.hpp" +#include "azure/keyvault/keys/key_properties.hpp" + +#include + +#include + +namespace Azure { namespace Security { namespace KeyVault { namespace Keys { + + namespace Details { + constexpr static const char* KeyPropertyName = "key"; + } // namespace Details + + struct KeyVaultKey + { + JsonWebKey Key; + KeyProperties Properties; + + KeyVaultKey(std::string name) : Properties(std::move(name)) {} + + std::string const& Id() const { return Key.Id; } + std::string const& Name() const { return Properties.Name; } + KeyTypeEnum const& GetKeyType() const { return Key.KeyType; } + std::vector const& KeyOperations() const { return Key.KeyOperations(); } + }; + + /*********************** Deserializer / Serializer ******************************/ + namespace Details { + KeyVaultKey KeyVaultKeyDeserialize( + std::string const& name, + Azure::Core::Http::RawResponse const& rawResponse); + } // namespace Details + +}}}} // namespace Azure::Security::KeyVault::Keys diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/version.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/version.hpp new file mode 100644 index 000000000..efd757a4b --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/version.hpp @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#define AZURE_SECURITY_KEYVAULT_KEYS_VERSION_MAJOR 4 +#define AZURE_SECURITY_KEYVAULT_KEYS_VERSION_MINOR 0 +#define AZURE_SECURITY_KEYVAULT_KEYS_VERSION_PATCH 0 +#define AZURE_SECURITY_KEYVAULT_KEYS_VERSION_PRERELEASE "beta.1" + +namespace Azure { namespace Security { namespace KeyVault { namespace Keys { + + class Version { + public: + static constexpr int Major = AZURE_SECURITY_KEYVAULT_KEYS_VERSION_MAJOR; + static constexpr int Minor = AZURE_SECURITY_KEYVAULT_KEYS_VERSION_MINOR; + static constexpr int Patch = AZURE_SECURITY_KEYVAULT_KEYS_VERSION_PATCH; + static std::string const PreRelease; + static std::string VersionString(); + + private: + // To avoid leaking out the #define values we smuggle out the value + // which will later be used to initialize the PreRelease std::string + static constexpr const char* secret = AZURE_SECURITY_KEYVAULT_KEYS_VERSION_PRERELEASE; + }; +}}}} // namespace Azure::Security::KeyVault::Keys + +#undef AZURE_SECURITY_KEYVAULT_KEYS_VERSION_MAJOR +#undef AZURE_SECURITY_KEYVAULT_KEYS_VERSION_MINOR +#undef AZURE_SECURITY_KEYVAULT_KEYS_VERSION_PATCH +#undef AZURE_SECURITY_KEYVAULT_KEYS_VERSION_PRERELEASE diff --git a/sdk/keyvault/azure-security-keyvault-keys/sample/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-keys/sample/CMakeLists.txt new file mode 100644 index 000000000..018539c7f --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/sample/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +cmake_minimum_required (VERSION 3.13) + +add_subdirectory(get-key) diff --git a/sdk/keyvault/azure-security-keyvault-keys/sample/get-key/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-keys/sample/get-key/CMakeLists.txt new file mode 100644 index 000000000..1fe426a82 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/sample/get-key/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +cmake_minimum_required (VERSION 3.13) + +project (azure-security-keyvault-keys-sample-get-key LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +add_executable ( + azure-security-keyvault-keys-sample-get-key + main.cpp +) + +target_link_libraries(azure-security-keyvault-keys-sample-get-key PRIVATE azure-security-keyvault-keys azure-identity) diff --git a/sdk/keyvault/azure-security-keyvault-keys/sample/get-key/main.cpp b/sdk/keyvault/azure-security-keyvault-keys/sample/get-key/main.cpp new file mode 100644 index 000000000..1b1000649 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/sample/get-key/main.cpp @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +/** + * @brief The next sample provides the code implementation to use the Key Vault SDK client for C++ + * to create a key client and get a key from Key Vault service. + * + * @remark Make sure to set the next environment variables before running the sample. + * - AZURE_KEYVAULT_URL: To the KeyVault account url. + * - AZURE_KEYVAULT_TENANT_ID: Tenant id for the Azure account. + * - AZURE_KEYVAULT_CLIENT_ID: The client id to authenticate the request. + * - AZURE_KEYVAULT_CLIENT_SECRET: The secret id from the client id. + * + * Also, make sure the key is already created. Then set the key name as `KEY_VAULT_KEY_NAME` before + * the main() method below. + * + * @remark The sample has logging enabled and will log the HTTP response into the standard output. + * + */ + +#if defined(_MSC_VER) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include +#include +#include + +#include +#include + +using namespace Azure::Security::KeyVault::Keys; + +// Define the name of the key to get +#define KEY_VAULT_KEY_NAME "keyName" + +int main() +{ + Azure::Core::Logging::SetLogListener( + [](Azure::Core::Logging::LogClassification const&, std::string const& message) { + std::cout << message << std::endl; + }); + Azure::Core::Logging::SetLogClassifications({Azure::Core::Http::LogClassification::Response}); + + auto tenantId = std::getenv("AZURE_KEYVAULT_TENANT_ID"); + auto clientId = std::getenv("AZURE_KEYVAULT_CLIENT_ID"); + auto clientSecret = std::getenv("AZURE_KEYVAULT_CLIENT_SECRET"); + auto credential + = std::make_shared(tenantId, clientId, clientSecret); + + KeyClient keyClient(std::getenv("AZURE_KEYVAULT_URL"), credential); + + try + { + auto responseT = keyClient.GetKey(KEY_VAULT_KEY_NAME); + auto key = responseT.ExtractValue(); + std::cout << "KeyId: " << key.Key.Id << std::endl; + std::cout << "Operations:" << std::endl; + for (KeyOperation operation : key.KeyOperations()) + { + std::cout << " - " << operation.ToString() << std::endl; + } + } + catch (Azure::Core::AuthenticationException const& e) + { + std::cout << "Authentication Exception happened:" << std::endl << e.what() << std::endl; + } + catch (Azure::Security::KeyVault::Common::KeyVaultException const& e) + { + std::cout << "KeyVault Client Exception happened:" << std::endl << e.Message << std::endl; + } + + return 0; +} diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/key_client.cpp b/sdk/keyvault/azure-security-keyvault-keys/src/key_client.cpp new file mode 100644 index 000000000..e054215ff --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/src/key_client.cpp @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include +#include +#include + +#include "azure/keyvault/keys/key_client.hpp" + +#include +#include +#include + +using namespace Azure::Security::KeyVault::Keys; +using namespace Azure::Core::Http; + +KeyClient::KeyClient( + std::string const& vaultUrl, + std::shared_ptr credential, + KeyClientOptions options) +{ + auto apiVersion = options.GetVersionString(); + + // Base Pipeline + std::vector> policies; + policies.emplace_back(std::make_unique("KeyVault", apiVersion)); + policies.emplace_back(std::make_unique()); + policies.emplace_back(std::make_unique(options.RetryOptions)); + policies.emplace_back(std::make_unique( + credential, "https://vault.azure.net/.default")); + policies.emplace_back(std::make_unique()); + policies.emplace_back( + std::make_unique(options.TransportPolicyOptions)); + Azure::Core::Http::Url url(vaultUrl); + + m_pipeline = std::make_unique( + url, apiVersion, std::move(policies)); +} diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/key_type.cpp b/sdk/keyvault/azure-security-keyvault-keys/src/key_type.cpp new file mode 100644 index 000000000..8af3924f9 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/src/key_type.cpp @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include "azure/keyvault/keys/key_type.hpp" + +#include + +using namespace Azure::Security::KeyVault::Keys; + +KeyTypeEnum Details::KeyTypeFromString(std::string const& name) +{ + if (name == EcValue) + { + return KeyTypeEnum::Ec; + } + if (name == EcHsmValue) + { + return KeyTypeEnum::EcHsm; + } + if (name == OctValue) + { + return KeyTypeEnum::Oct; + } + if (name == OctHsmValue) + { + return KeyTypeEnum::OctHsm; + } + if (name == RsaValue) + { + return KeyTypeEnum::Rsa; + } + if (name == RsaHsmValue) + { + return KeyTypeEnum::RsaHsm; + } + throw std::runtime_error("cannot convert " + name + " to key type (kty)"); +} + +std::string Details::KeyTypeToString(KeyTypeEnum kty) +{ + if (kty == KeyTypeEnum::Ec) + { + return EcValue; + } + if (kty == KeyTypeEnum::EcHsm) + { + return EcHsmValue; + } + if (kty == KeyTypeEnum::Oct) + { + return OctValue; + } + if (kty == KeyTypeEnum::OctHsm) + { + return OctHsmValue; + } + if (kty == KeyTypeEnum::Rsa) + { + return RsaValue; + } + if (kty == KeyTypeEnum::RsaHsm) + { + return RsaHsmValue; + } + return std::string(); +} diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/key_vault_key.cpp b/sdk/keyvault/azure-security-keyvault-keys/src/key_vault_key.cpp new file mode 100644 index 000000000..ea16a79b8 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/src/key_vault_key.cpp @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include "azure/keyvault/keys/key_vault_key.hpp" + +#include + +using namespace Azure::Security::KeyVault::Keys; + +namespace { +void ParseStringOperationsToKeyOperations( + std::vector& keyOperations, + std::vector const& stringOperations) +{ + for (std::string const& operation : stringOperations) + { + keyOperations.emplace_back(KeyOperation(operation)); + } +} +} // namespace + +KeyVaultKey Details::KeyVaultKeyDeserialize( + std::string const& name, + Azure::Core::Http::RawResponse const& rawResponse) +{ + auto body = rawResponse.GetBody(); + auto jsonParser = nlohmann::json::parse(body); + + KeyVaultKey key(name); + auto const& jsonKey = jsonParser["key"]; + { + auto keyOperationVector = jsonKey["key_ops"].get>(); + std::vector keyOperations; + ParseStringOperationsToKeyOperations(keyOperations, keyOperationVector); + key.Key.SetKeyOperations(keyOperations); + } + + key.Key.Id = jsonKey["kid"].get(); + key.Key.KeyType = Details::KeyTypeFromString(jsonKey["kty"].get()); + + return key; +} diff --git a/sdk/keyvault/azure-security-keyvault-keys/test/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-keys/test/CMakeLists.txt new file mode 100644 index 000000000..f038e2f37 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/test/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +cmake_minimum_required (VERSION 3.13) + +project (azure-security-keyvault-keys-test LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +include(GoogleTest) + +add_executable ( + azure-security-keyvault-keys-test + key_client_test.cpp + main.cpp +) + +if (MSVC) + target_compile_options(azure-security-keyvault-keys-test PUBLIC /wd6326 /wd26495 /wd26812) +endif() + +target_link_libraries(azure-security-keyvault-keys-test PRIVATE azure-security-keyvault-keys azure-identity gtest gmock) + +# 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_add_tests(TARGET azure-security-keyvault-keys-test + TEST_PREFIX azure-security-keyvault-keys-test.) diff --git a/sdk/keyvault/azure-security-keyvault-keys/test/key_client_test.cpp b/sdk/keyvault/azure-security-keyvault-keys/test/key_client_test.cpp new file mode 100644 index 000000000..c33a62d1b --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/test/key_client_test.cpp @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include "gtest/gtest.h" + +#include +#include +#include + +#include + +using namespace Azure::Security::KeyVault::Keys; + +TEST(KeyClient, initClient) +{ + auto credential + = std::make_shared("tenantID", "AppId", "SecretId"); + EXPECT_NO_THROW(KeyClient keyClient("vaultUrl", credential)); +} + +TEST(KeyClient, DISABLED_SendRequestDefault) +{ + auto credential + = std::make_shared("tenantID", "AppId", "SecretId"); + KeyClient keyClient("vaultUrl", credential); + auto r = keyClient.GetKey("KeyName"); + auto t = r.ExtractValue(); + auto rr = r.ExtractRawResponse(); + + EXPECT_EQ(t.Name(), "KeyName"); +} diff --git a/sdk/keyvault/azure-security-keyvault-keys/test/main.cpp b/sdk/keyvault/azure-security-keyvault-keys/test/main.cpp new file mode 100644 index 000000000..3d0b851aa --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/test/main.cpp @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include "gtest/gtest.h" + +int main(int argc, char** argv) +{ + testing::InitGoogleTest(&argc, argv); + auto r = RUN_ALL_TESTS(); + return r; +} diff --git a/sdk/keyvault/azure-security-keyvault-keys/vcpkg/CONTROL b/sdk/keyvault/azure-security-keyvault-keys/vcpkg/CONTROL new file mode 100644 index 000000000..7772eea77 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/vcpkg/CONTROL @@ -0,0 +1,7 @@ +Source: azure-security-keyvault-keys-cpp +Version: @AZ_LIBRARY_VERSION@ +Build-Depends: azure-security-keyvault-common-cpp +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/master/sdk/keyvault/azure-security-keyvault-keys +Supports: !uwp diff --git a/sdk/keyvault/azure-security-keyvault-keys/vcpkg/Config.cmake.in b/sdk/keyvault/azure-security-keyvault-keys/vcpkg/Config.cmake.in new file mode 100644 index 000000000..3c65c60a0 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/vcpkg/Config.cmake.in @@ -0,0 +1,11 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(azure-security-keyvault-common-cpp) + +include("${CMAKE_CURRENT_LIST_DIR}/azure-security-keyvault-keys-cppTargets.cmake") + +check_required_components("azure-security-keyvault-keys-cpp") diff --git a/sdk/keyvault/azure-security-keyvault-keys/vcpkg/portfile.cmake b/sdk/keyvault/azure-security-keyvault-keys/vcpkg/portfile.cmake new file mode 100644 index 000000000..8e84837e7 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/vcpkg/portfile.cmake @@ -0,0 +1,24 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +vcpkg_fail_port_install(ON_TARGET "UWP") + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO Azure/azure-sdk-for-cpp + REF azure-security-keyvault-keys_@AZ_LIBRARY_VERSION@ + SHA512 1 +) + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH}/sdk/keyvault/azure-security-keyvault-keys/ + PREFER_NINJA + OPTIONS + -DWARNINGS_AS_ERRORS=OFF +) + +vcpkg_install_cmake() +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") +vcpkg_fixup_cmake_targets() +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share") +vcpkg_copy_pdbs() diff --git a/sdk/keyvault/ci.yml b/sdk/keyvault/ci.yml new file mode 100644 index 000000000..25a976c5c --- /dev/null +++ b/sdk/keyvault/ci.yml @@ -0,0 +1,41 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. +trigger: + branches: + include: + - master + - feature/* + - release/* + - hotfix/* + paths: + include: + - cmake-modules/ + - eng/ + - CMakeLists.txt + - sdk/core + - sdk/keyvault + +pr: + branches: + include: + - master + - feature/* + - release/* + - hotfix/* + paths: + include: + - cmake-modules/ + - eng/ + - CMakeLists.txt + - sdk/core/ + - sdk/keyvault + +stages: + - template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml + parameters: + ServiceDirectory: keyvault + CtestRegex: azure-security-keyvault + Artifacts: + - Name: azure-security-keyvault-common + Path: azure-security-keyvault-common + - Name: azure-security-keyvault-keys + Path: azure-security-keyvault-keys