Feature/keyvault - GetKey + KeyVaultCommon (#1383)
* add cmake project for keyvault keys (#1081)
This commit is contained in:
parent
c564c02544
commit
80357ab69d
@ -67,3 +67,4 @@ add_subdirectory(sdk/identity/azure-identity)
|
||||
|
||||
add_subdirectory(sdk/storage)
|
||||
add_subdirectory(sdk/template/azure-template)
|
||||
add_subdirectory(sdk/keyvault)
|
||||
|
||||
11
sdk/keyvault/CMakeLists.txt
Normal file
11
sdk/keyvault/CMakeLists.txt
Normal file
@ -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)
|
||||
48
sdk/keyvault/README.md
Normal file
48
sdk/keyvault/README.md
Normal file
@ -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
|
||||
4
sdk/keyvault/azure-security-keyvault-common/CHANGELOG.md
Normal file
4
sdk/keyvault/azure-security-keyvault-common/CHANGELOG.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Release History
|
||||
|
||||
## 4.0.0-beta.1 (Unreleased)
|
||||
|
||||
70
sdk/keyvault/azure-security-keyvault-common/CMakeLists.txt
Normal file
70
sdk/keyvault/azure-security-keyvault-common/CMakeLists.txt
Normal file
@ -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
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
|
||||
$<INSTALL_INTERFACE:include/azure-security-keyvault-common>
|
||||
${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)
|
||||
32
sdk/keyvault/azure-security-keyvault-common/NOTICE.txt
Normal file
32
sdk/keyvault/azure-security-keyvault-common/NOTICE.txt
Normal 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.
|
||||
|
||||
5
sdk/keyvault/azure-security-keyvault-common/README.md
Normal file
5
sdk/keyvault/azure-security-keyvault-common/README.md
Normal file
@ -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.
|
||||
36
sdk/keyvault/azure-security-keyvault-common/cgmanifest.json
Normal file
36
sdk/keyvault/azure-security-keyvault-common/cgmanifest.json
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -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
|
||||
@ -0,0 +1,29 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <azure/core/http/http.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
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<Azure::Core::Http::RawResponse> RawResponse;
|
||||
|
||||
static KeyVaultException CreateFromResponse(
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse> response);
|
||||
};
|
||||
}}}} // namespace Azure::Security::KeyVault::Common
|
||||
@ -0,0 +1,79 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <azure/core/context.hpp>
|
||||
#include <azure/core/http/http.hpp>
|
||||
#include <azure/core/http/pipeline.hpp>
|
||||
#include <azure/core/response.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
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<std::string> const& path) const;
|
||||
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse> 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<std::unique_ptr<Azure::Core::Http::HttpPolicy>> 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<TResult>
|
||||
*/
|
||||
template <class T>
|
||||
Azure::Core::Response<T> SendRequest(
|
||||
Azure::Core::Context const& context,
|
||||
Azure::Core::Http::HttpMethod method,
|
||||
std::function<T(Azure::Core::Http::RawResponse const& rawResponse)> factoryFn,
|
||||
std::vector<std::string> const& path)
|
||||
{
|
||||
auto request = CreateRequest(method, path);
|
||||
auto response = SendRequest(context, request);
|
||||
return Azure::Core::Response<T>(factoryFn(*response), std::move(response));
|
||||
}
|
||||
};
|
||||
}}}}} // namespace Azure::Security::KeyVault::Common::Internal
|
||||
@ -0,0 +1,33 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#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
|
||||
@ -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 <azure/core/http/policy.hpp>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
using namespace Azure::Security::KeyVault::Common;
|
||||
|
||||
namespace {
|
||||
|
||||
inline std::string GetHeaderOrEmptyString(
|
||||
std::map<std::string, std::string> 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<Azure::Core::Http::RawResponse> response)
|
||||
{
|
||||
std::vector<uint8_t> 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<std::string>();
|
||||
message = error["message"].get<std::string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
message = std::string(bodyBuffer.begin(), bodyBuffer.end());
|
||||
}
|
||||
|
||||
KeyVaultException result = KeyVaultException(
|
||||
std::to_string(static_cast<std::underlying_type<Azure::Core::Http::HttpStatusCode>::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;
|
||||
}
|
||||
@ -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<std::string> 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<Azure::Core::Http::RawResponse> 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;
|
||||
}
|
||||
@ -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.)
|
||||
11
sdk/keyvault/azure-security-keyvault-common/test/main.cpp
Normal file
11
sdk/keyvault/azure-security-keyvault-common/test/main.cpp
Normal file
@ -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;
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <azure/core/http/http.hpp>
|
||||
#include <azure/core/http/policy.hpp>
|
||||
#include <azure/keyvault/common/keyvault_pipeline.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace Azure::Security::KeyVault::Common::Internal;
|
||||
|
||||
TEST(KeyVaultPipeline, initPipeline)
|
||||
{
|
||||
std::vector<std::unique_ptr<Azure::Core::Http::HttpPolicy>> policies;
|
||||
policies.emplace_back(std::make_unique<Azure::Core::Http::TransportPolicy>());
|
||||
Azure::Core::Http::Url url("urlTest");
|
||||
EXPECT_NO_THROW(KeyVaultPipeline p(url, "version", policies));
|
||||
}
|
||||
@ -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
|
||||
@ -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")
|
||||
@ -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()
|
||||
4
sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md
Normal file
4
sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Release History
|
||||
|
||||
## 4.0.0-beta.1 (Unreleased)
|
||||
|
||||
78
sdk/keyvault/azure-security-keyvault-keys/CMakeLists.txt
Normal file
78
sdk/keyvault/azure-security-keyvault-keys/CMakeLists.txt
Normal file
@ -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
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
|
||||
$<INSTALL_INTERFACE:include/azure-security-keyvault-keys>
|
||||
${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)
|
||||
32
sdk/keyvault/azure-security-keyvault-keys/NOTICE.txt
Normal file
32
sdk/keyvault/azure-security-keyvault-keys/NOTICE.txt
Normal 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.
|
||||
|
||||
5
sdk/keyvault/azure-security-keyvault-keys/README.md
Normal file
5
sdk/keyvault/azure-security-keyvault-keys/README.md
Normal file
@ -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.
|
||||
36
sdk/keyvault/azure-security-keyvault-keys/cgmanifest.json
Normal file
36
sdk/keyvault/azure-security-keyvault-keys/cgmanifest.json
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "azure/keyvault/keys/key_client.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 <string>
|
||||
#include <vector>
|
||||
|
||||
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<KeyOperation> const& keyOperations)
|
||||
{
|
||||
m_keyOps = keyOperations;
|
||||
}
|
||||
std::vector<KeyOperation> const& KeyOperations() const { return m_keyOps; }
|
||||
|
||||
private:
|
||||
std::vector<KeyOperation> m_keyOps;
|
||||
};
|
||||
|
||||
}}}} // namespace Azure::Security::KeyVault::Keys
|
||||
@ -0,0 +1,87 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <azure/core/credentials.hpp>
|
||||
#include <azure/core/http/http.hpp>
|
||||
#include <azure/core/response.hpp>
|
||||
#include <azure/keyvault/common/keyvault_pipeline.hpp>
|
||||
|
||||
#include "azure/keyvault/keys/key_client_options.hpp"
|
||||
#include "azure/keyvault/keys/key_vault_key.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
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<Azure::Security::KeyVault::Common::Internal::KeyVaultPipeline> 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<Core::TokenCredential const> 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<KeyVaultKey> GetKey(
|
||||
std::string const& name,
|
||||
GetKeyOptions const& options = GetKeyOptions()) const
|
||||
{
|
||||
return m_pipeline->SendRequest<KeyVaultKey>(
|
||||
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
|
||||
@ -0,0 +1,43 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <azure/core/http/http.hpp>
|
||||
#include <azure/core/response.hpp>
|
||||
#include <azure/keyvault/common/keyvault_pipeline.hpp>
|
||||
|
||||
#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
|
||||
@ -0,0 +1,28 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
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
|
||||
@ -0,0 +1,45 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <azure/core/datetime.hpp>
|
||||
#include <azure/core/nullable.hpp>
|
||||
|
||||
#include "azure/keyvault/keys/key_release_policy.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
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<std::string, std::string> Tags;
|
||||
Azure::Core::Nullable<bool> Enabled;
|
||||
Azure::Core::Nullable<Azure::Core::DateTime> NotBefore;
|
||||
Azure::Core::Nullable<Azure::Core::DateTime> ExpiresOn;
|
||||
Azure::Core::Nullable<Azure::Core::DateTime> CreatedOn;
|
||||
Azure::Core::Nullable<Azure::Core::DateTime> UpdatedOn;
|
||||
Azure::Core::Nullable<int> RecoverableDays;
|
||||
std::string RecoveryLevel;
|
||||
Azure::Core::Nullable<bool> Exportable;
|
||||
KeyReleasePolicy ReleasePolicy;
|
||||
|
||||
KeyProperties() {}
|
||||
KeyProperties(std::string name) : Name(std::move(name)) {}
|
||||
};
|
||||
|
||||
}}}} // namespace Azure::Security::KeyVault::Keys
|
||||
@ -0,0 +1,26 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
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<uint8_t> Data;
|
||||
|
||||
KeyReleasePolicy() {}
|
||||
|
||||
KeyReleasePolicy(std::vector<uint8_t> data) : Data(std::move(data)) {}
|
||||
};
|
||||
|
||||
}}}} // namespace Azure::Security::KeyVault::Keys
|
||||
@ -0,0 +1,34 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
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
|
||||
@ -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 <azure/core/http/http.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
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<KeyOperation> 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
|
||||
@ -0,0 +1,33 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#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
|
||||
@ -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)
|
||||
@ -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)
|
||||
@ -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 <azure/core/http/http.hpp>
|
||||
#include <azure/core/logging/logging.hpp>
|
||||
#include <azure/identity/client_secret_credential.hpp>
|
||||
#include <azure/keyvault/common/keyvault_exception.hpp>
|
||||
#include <azure/keyvault/key_vault.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
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<Azure::Identity::ClientSecretCredential>(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;
|
||||
}
|
||||
38
sdk/keyvault/azure-security-keyvault-keys/src/key_client.cpp
Normal file
38
sdk/keyvault/azure-security-keyvault-keys/src/key_client.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <azure/core/credentials.hpp>
|
||||
#include <azure/core/http/http.hpp>
|
||||
#include <azure/core/http/policy.hpp>
|
||||
|
||||
#include "azure/keyvault/keys/key_client.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace Azure::Security::KeyVault::Keys;
|
||||
using namespace Azure::Core::Http;
|
||||
|
||||
KeyClient::KeyClient(
|
||||
std::string const& vaultUrl,
|
||||
std::shared_ptr<Core::TokenCredential const> credential,
|
||||
KeyClientOptions options)
|
||||
{
|
||||
auto apiVersion = options.GetVersionString();
|
||||
|
||||
// Base Pipeline
|
||||
std::vector<std::unique_ptr<HttpPolicy>> policies;
|
||||
policies.emplace_back(std::make_unique<TelemetryPolicy>("KeyVault", apiVersion));
|
||||
policies.emplace_back(std::make_unique<RequestIdPolicy>());
|
||||
policies.emplace_back(std::make_unique<RetryPolicy>(options.RetryOptions));
|
||||
policies.emplace_back(std::make_unique<BearerTokenAuthenticationPolicy>(
|
||||
credential, "https://vault.azure.net/.default"));
|
||||
policies.emplace_back(std::make_unique<LoggingPolicy>());
|
||||
policies.emplace_back(
|
||||
std::make_unique<Azure::Core::Http::TransportPolicy>(options.TransportPolicyOptions));
|
||||
Azure::Core::Http::Url url(vaultUrl);
|
||||
|
||||
m_pipeline = std::make_unique<Azure::Security::KeyVault::Common::Internal::KeyVaultPipeline>(
|
||||
url, apiVersion, std::move(policies));
|
||||
}
|
||||
66
sdk/keyvault/azure-security-keyvault-keys/src/key_type.cpp
Normal file
66
sdk/keyvault/azure-security-keyvault-keys/src/key_type.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "azure/keyvault/keys/key_type.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
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();
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "azure/keyvault/keys/key_vault_key.hpp"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace Azure::Security::KeyVault::Keys;
|
||||
|
||||
namespace {
|
||||
void ParseStringOperationsToKeyOperations(
|
||||
std::vector<KeyOperation>& keyOperations,
|
||||
std::vector<std::string> 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<std::string>>();
|
||||
std::vector<KeyOperation> keyOperations;
|
||||
ParseStringOperationsToKeyOperations(keyOperations, keyOperationVector);
|
||||
key.Key.SetKeyOperations(keyOperations);
|
||||
}
|
||||
|
||||
key.Key.Id = jsonKey["kid"].get<std::string>();
|
||||
key.Key.KeyType = Details::KeyTypeFromString(jsonKey["kty"].get<std::string>());
|
||||
|
||||
return key;
|
||||
}
|
||||
@ -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.)
|
||||
@ -0,0 +1,31 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <azure/core/context.hpp>
|
||||
#include <azure/identity/client_secret_credential.hpp>
|
||||
#include <azure/keyvault/key_vault.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace Azure::Security::KeyVault::Keys;
|
||||
|
||||
TEST(KeyClient, initClient)
|
||||
{
|
||||
auto credential
|
||||
= std::make_shared<Azure::Identity::ClientSecretCredential>("tenantID", "AppId", "SecretId");
|
||||
EXPECT_NO_THROW(KeyClient keyClient("vaultUrl", credential));
|
||||
}
|
||||
|
||||
TEST(KeyClient, DISABLED_SendRequestDefault)
|
||||
{
|
||||
auto credential
|
||||
= std::make_shared<Azure::Identity::ClientSecretCredential>("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");
|
||||
}
|
||||
11
sdk/keyvault/azure-security-keyvault-keys/test/main.cpp
Normal file
11
sdk/keyvault/azure-security-keyvault-keys/test/main.cpp
Normal file
@ -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;
|
||||
}
|
||||
7
sdk/keyvault/azure-security-keyvault-keys/vcpkg/CONTROL
Normal file
7
sdk/keyvault/azure-security-keyvault-keys/vcpkg/CONTROL
Normal file
@ -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
|
||||
@ -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")
|
||||
@ -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()
|
||||
41
sdk/keyvault/ci.yml
Normal file
41
sdk/keyvault/ci.yml
Normal file
@ -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
|
||||
Loading…
Reference in New Issue
Block a user