Okp (#4239)
* first pass * part2 * part3 * part 5 * pre PR * updated tests * fix test * clangs * updated changelog
This commit is contained in:
parent
41e3e89cf8
commit
275f6f8077
@ -2,5 +2,5 @@
|
||||
"AssetsRepo": "Azure/azure-sdk-assets",
|
||||
"AssetsRepoPrefixPath": "cpp",
|
||||
"TagPrefix": "cpp/keyvault",
|
||||
"Tag": "cpp/keyvault_ea82152bd3"
|
||||
"Tag": "cpp/keyvault_fd91dfe00e"
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
|
||||
### Features Added
|
||||
|
||||
- Support for OKP keys.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
@ -39,6 +39,9 @@ namespace Azure {
|
||||
* @brief Construct a new Key Client Options object.
|
||||
*
|
||||
*/
|
||||
CryptographyClientOptions() : Azure::Core::_internal::ClientOptions() { Version = "7.3"; }
|
||||
CryptographyClientOptions() : Azure::Core::_internal::ClientOptions()
|
||||
{
|
||||
Version = "7.4-preview.1";
|
||||
}
|
||||
};
|
||||
}}}}} // namespace Azure::Security::KeyVault::Keys::Cryptography
|
||||
|
||||
@ -173,6 +173,23 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
|
||||
CreateOctKeyOptions const& octKeyOptions,
|
||||
Azure::Core::Context const& context = Azure::Core::Context()) const;
|
||||
|
||||
/**
|
||||
* @brief Creates and stores a new OKP key in Key Vault.
|
||||
*
|
||||
* @remark If the named key already exists, Azure Key Vault creates a new version of the
|
||||
* key.
|
||||
*
|
||||
* @remark This operation requires the keys/create permission.
|
||||
*
|
||||
* @param okpKeyOptions The key options object containing information about the OKP key
|
||||
* being created.
|
||||
* @param context A #Azure::Core::Context controlling the request lifetime.
|
||||
* @return The Key wrapped in the Response.
|
||||
*/
|
||||
Azure::Response<KeyVaultKey> CreateOkpKey(
|
||||
CreateOkpKeyOptions const& okpKeyOptions,
|
||||
Azure::Core::Context const& context = Azure::Core::Context()) const;
|
||||
|
||||
/**
|
||||
* @brief Get a single page with the properties of all keys in the specified vault. You can
|
||||
* use the returned #KeyProperties.Name in subsequent calls to #GetKey.
|
||||
|
||||
@ -214,6 +214,18 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
|
||||
*
|
||||
*/
|
||||
AZ_SECURITY_KEYVAULT_KEYS_DLLEXPORT static const KeyVaultKeyType OctHsm;
|
||||
|
||||
/**
|
||||
* @brief An OKP cryptographic algorithm.
|
||||
*
|
||||
*/
|
||||
AZ_SECURITY_KEYVAULT_KEYS_DLLEXPORT static const KeyVaultKeyType Okp;
|
||||
|
||||
/**
|
||||
* @brief An OKP cryptographic algorithm backed by a Hardware Security Module (HSM).
|
||||
*
|
||||
*/
|
||||
AZ_SECURITY_KEYVAULT_KEYS_DLLEXPORT static const KeyVaultKeyType OkpHsm;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -297,6 +309,16 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
|
||||
*
|
||||
*/
|
||||
AZ_SECURITY_KEYVAULT_KEYS_DLLEXPORT static const KeyCurveName P521;
|
||||
|
||||
/**
|
||||
* @brief Gets the Ed25519 Edwards curve.
|
||||
*
|
||||
* @remark For more information, see
|
||||
* <a href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve
|
||||
* types</a>.
|
||||
*
|
||||
*/
|
||||
AZ_SECURITY_KEYVAULT_KEYS_DLLEXPORT static const KeyCurveName Ed25519;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -400,14 +422,14 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
|
||||
/// The RSA secret prime.
|
||||
std::vector<uint8_t> Q;
|
||||
|
||||
/// The RSA private exponent or EC private key.
|
||||
/// The RSA private exponent or EC private key, or OKP private key.
|
||||
std::vector<uint8_t> D;
|
||||
|
||||
/// Gets the symmetric key.
|
||||
std::vector<uint8_t> K;
|
||||
/// Gets the protected key used with "Bring Your Own Key".
|
||||
std::vector<uint8_t> T;
|
||||
/// Gets the X coordinate of the elliptic curve point.
|
||||
/// Gets the X coordinate of the elliptic curve point, or OKP public key.
|
||||
std::vector<uint8_t> X;
|
||||
/// Gets the Y coordinate for the elliptic curve point.
|
||||
std::vector<uint8_t> Y;
|
||||
|
||||
@ -53,7 +53,7 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
|
||||
* @brief Service Version used.
|
||||
*
|
||||
*/
|
||||
const std::string ApiVersion{"7.3"};
|
||||
const std::string ApiVersion{"7.4-preview.1"};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -326,6 +326,80 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
|
||||
bool GetHardwareProtected() const { return m_hardwareProtected; }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The properties needed to create an OKP key.
|
||||
*
|
||||
*/
|
||||
class CreateOkpKeyOptions final : public CreateKeyOptions {
|
||||
private:
|
||||
std::string m_name;
|
||||
bool m_hardwareProtected;
|
||||
KeyVaultKeyType m_keyType;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Gets or sets the key size in bits, such as 2048, 3072, or 4096.
|
||||
*
|
||||
* @remark If null, the service default is used.
|
||||
*
|
||||
*/
|
||||
Azure::Nullable<int64_t> KeySize;
|
||||
|
||||
/**
|
||||
* @brief Gets or sets the elliptic curve name.
|
||||
*
|
||||
* @remark See #KeyCurveName for possible values.
|
||||
*
|
||||
* @remark If null, the service default is used.
|
||||
*
|
||||
*/
|
||||
Azure::Nullable<KeyCurveName> CurveName;
|
||||
|
||||
/**
|
||||
* @brief Create a OKP Key Options object.
|
||||
*
|
||||
* @param name Name of the key to create.
|
||||
* @param hardwareProtected `true` to create hardware-protected key in a hardware security
|
||||
* module (HSM). The default is false to create a software key.
|
||||
*/
|
||||
explicit CreateOkpKeyOptions(std::string const& name, bool hardwareProtected = false)
|
||||
: m_hardwareProtected(hardwareProtected)
|
||||
{
|
||||
if (name.empty())
|
||||
{
|
||||
throw std::invalid_argument("The name can't be empty");
|
||||
}
|
||||
m_name = name;
|
||||
if (hardwareProtected)
|
||||
{
|
||||
m_keyType = KeyVaultKeyType::OkpHsm;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_keyType = KeyVaultKeyType::Okp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the name of the key to create.
|
||||
*
|
||||
*/
|
||||
std::string const& GetName() const { return m_name; }
|
||||
|
||||
/**
|
||||
* @brief Gets the key type to create, including Okp and OkpHsm.
|
||||
*
|
||||
*/
|
||||
KeyVaultKeyType GetKeyType() const { return m_keyType; }
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether to create a hardware-protected key in a hardware
|
||||
* security module (HSM).
|
||||
*
|
||||
*/
|
||||
bool GetHardwareProtected() const { return m_hardwareProtected; }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A key resource and its properties.
|
||||
*
|
||||
|
||||
@ -167,6 +167,27 @@ Azure::Response<KeyVaultKey> KeyClient::CreateRsaKey(
|
||||
return Azure::Response<KeyVaultKey>(std::move(value), std::move(rawResponse));
|
||||
}
|
||||
|
||||
Azure::Response<KeyVaultKey> KeyClient::CreateOkpKey(
|
||||
CreateOkpKeyOptions const& okpKeyOptions,
|
||||
Azure::Core::Context const& context) const
|
||||
{
|
||||
// Payload for the request
|
||||
std::string const& keyName = okpKeyOptions.GetName();
|
||||
std::string payload = _detail ::KeyRequestParameters(okpKeyOptions).Serialize();
|
||||
Azure::Core::IO::MemoryBodyStream payloadStream(
|
||||
reinterpret_cast<const uint8_t*>(payload.data()), payload.size());
|
||||
|
||||
// Request and settings
|
||||
auto request
|
||||
= CreateRequest(HttpMethod::Post, {_detail::KeysPath, keyName, CreateValue}, &payloadStream);
|
||||
request.SetHeader(HttpShared::ContentType, HttpShared::ApplicationJson);
|
||||
|
||||
// Send and parse respone
|
||||
auto rawResponse = SendRequest(request, context);
|
||||
auto value = _detail::KeyVaultKeySerializer::KeyVaultKeyDeserialize(keyName, *rawResponse);
|
||||
return Azure::Response<KeyVaultKey>(std::move(value), std::move(rawResponse));
|
||||
}
|
||||
|
||||
Azure::Response<KeyVaultKey> KeyClient::CreateOctKey(
|
||||
CreateOctKeyOptions const& octKeyOptions,
|
||||
Azure::Core::Context const& context) const
|
||||
|
||||
@ -14,4 +14,6 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
|
||||
|
||||
const KeyCurveName KeyCurveName::P521(_detail::P521Value);
|
||||
|
||||
const KeyCurveName KeyCurveName::Ed25519(_detail::Ed25519Value);
|
||||
|
||||
}}}} // namespace Azure::Security::KeyVault::Keys
|
||||
|
||||
@ -24,15 +24,12 @@ std::string KeyRequestParameters::Serialize() const
|
||||
return type.ToString();
|
||||
});
|
||||
|
||||
json attributes;
|
||||
// attributes
|
||||
JsonOptional::SetFromNullable(
|
||||
m_options.Enabled, payload[_detail::AttributesPropertyName], _detail::EnabledPropertyName);
|
||||
JsonOptional::SetFromNullable(m_options.Enabled, attributes, _detail::EnabledPropertyName);
|
||||
|
||||
// exportable attribute
|
||||
JsonOptional::SetFromNullable(
|
||||
m_options.Exportable,
|
||||
payload[_detail::AttributesPropertyName],
|
||||
_detail::ExportablePropertyName);
|
||||
JsonOptional::SetFromNullable(m_options.Exportable, attributes, _detail::ExportablePropertyName);
|
||||
|
||||
/* Optional */
|
||||
// key_size
|
||||
@ -46,16 +43,23 @@ std::string KeyRequestParameters::Serialize() const
|
||||
// attributes
|
||||
JsonOptional::SetFromNullable<Azure::DateTime, int64_t>(
|
||||
m_options.ExpiresOn,
|
||||
payload[_detail::AttributesPropertyName],
|
||||
attributes,
|
||||
_detail::ExpPropertyName,
|
||||
PosixTimeConverter::DateTimeToPosixTime);
|
||||
|
||||
JsonOptional::SetFromNullable<Azure::DateTime, int64_t>(
|
||||
m_options.NotBefore,
|
||||
payload[_detail::AttributesPropertyName],
|
||||
attributes,
|
||||
_detail::NbfPropertyName,
|
||||
PosixTimeConverter::DateTimeToPosixTime);
|
||||
|
||||
// in order to avoid creating the "attributes":null json field.
|
||||
// The service deserializer on HSM really does not like that
|
||||
if (!attributes.empty())
|
||||
{
|
||||
payload[_detail::AttributesPropertyName] = attributes;
|
||||
}
|
||||
|
||||
// tags
|
||||
for (auto tag : m_options.Tags)
|
||||
{
|
||||
|
||||
@ -14,3 +14,5 @@ const KeyVaultKeyType KeyVaultKeyType::Rsa(_detail::RsaValue);
|
||||
const KeyVaultKeyType KeyVaultKeyType::RsaHsm(_detail::RsaHsmValue);
|
||||
const KeyVaultKeyType KeyVaultKeyType::Oct(_detail::OctValue);
|
||||
const KeyVaultKeyType KeyVaultKeyType::OctHsm(_detail::OctHsmValue);
|
||||
const KeyVaultKeyType KeyVaultKeyType::Okp(_detail::OkpValue);
|
||||
const KeyVaultKeyType KeyVaultKeyType::OkpHsm(_detail::OkpHsmValue);
|
||||
|
||||
@ -19,9 +19,9 @@ std::unique_ptr<Azure::Core::Http::RawResponse> _detail::KeyVaultKeysCommonReque
|
||||
{
|
||||
auto response = pipeline.Send(request, context);
|
||||
auto responseCode = response->GetStatusCode();
|
||||
|
||||
switch (responseCode)
|
||||
{
|
||||
|
||||
// 200, 2001, 202, 204 are accepted responses
|
||||
case Azure::Core::Http::HttpStatusCode::Ok:
|
||||
case Azure::Core::Http::HttpStatusCode::Created:
|
||||
|
||||
@ -60,6 +60,8 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys { nam
|
||||
constexpr static const char RsaHsmValue[] = "RSA-HSM";
|
||||
constexpr static const char OctValue[] = "oct";
|
||||
constexpr static const char OctHsmValue[] = "oct-HSM";
|
||||
constexpr static const char OkpValue[] = "OKP";
|
||||
constexpr static const char OkpHsmValue[] = "OKP-HSM";
|
||||
|
||||
/***************** Deleted Key *****************/
|
||||
constexpr static const char RecoveryIdPropertyName[] = "recoveryId";
|
||||
@ -71,6 +73,7 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys { nam
|
||||
constexpr static const char P256KValue[] = "P-256K";
|
||||
constexpr static const char P384Value[] = "P-384";
|
||||
constexpr static const char P521Value[] = "P-521";
|
||||
constexpr static const char Ed25519Value[] = "Ed25519";
|
||||
|
||||
constexpr static const char P256OidValue[] = "1.2.840.10045.3.1.7";
|
||||
constexpr static const char P256KOidValue[] = "1.3.132.0.10";
|
||||
|
||||
@ -104,6 +104,15 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys { nam
|
||||
}
|
||||
}
|
||||
|
||||
explicit KeyRequestParameters(CreateOkpKeyOptions const& okpKey)
|
||||
: KeyRequestParameters(okpKey.GetKeyType(), okpKey)
|
||||
{
|
||||
if (okpKey.CurveName.HasValue())
|
||||
{
|
||||
Curve = okpKey.CurveName.Value();
|
||||
}
|
||||
}
|
||||
|
||||
std::string Serialize() const override;
|
||||
};
|
||||
}}}}} // namespace Azure::Security::KeyVault::Keys::_detail
|
||||
|
||||
@ -130,6 +130,54 @@ TEST_F(KeyVaultKeyClient, CreateEcKey)
|
||||
}
|
||||
}
|
||||
|
||||
/********************************* Create key overloads *********************************/
|
||||
TEST_F(KeyVaultKeyClient, CreateOkpKey)
|
||||
{
|
||||
auto const keyName = GetTestName();
|
||||
// This client requires an HSM client
|
||||
CreateHsmClient();
|
||||
auto const& client = GetClientForTest(keyName);
|
||||
|
||||
{
|
||||
auto okpKey = Azure::Security::KeyVault::Keys::CreateOkpKeyOptions(keyName);
|
||||
auto keyResponse = client.CreateOkpKey(okpKey);
|
||||
CheckValidResponse(keyResponse);
|
||||
auto keyVaultKey = keyResponse.Value;
|
||||
EXPECT_EQ(keyVaultKey.Name(), keyName);
|
||||
}
|
||||
{
|
||||
// Now get the key
|
||||
auto keyResponse = client.GetKey(keyName);
|
||||
CheckValidResponse(keyResponse);
|
||||
auto keyVaultKey = keyResponse.Value;
|
||||
EXPECT_EQ(keyVaultKey.Name(), keyName);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(KeyVaultKeyClient, CreateOkpHSMKey)
|
||||
{
|
||||
auto const keyName = GetTestName();
|
||||
// This client requires an HSM client
|
||||
CreateHsmClient();
|
||||
auto const& client = GetClientForTest(keyName);
|
||||
|
||||
{
|
||||
auto okpKey = Azure::Security::KeyVault::Keys::CreateOkpKeyOptions(keyName, true);
|
||||
auto keyResponse = client.CreateOkpKey(okpKey);
|
||||
CheckValidResponse(keyResponse);
|
||||
auto keyVaultKey = keyResponse.Value;
|
||||
EXPECT_EQ(keyVaultKey.Name(), keyName);
|
||||
EXPECT_EQ(keyVaultKey.GetKeyType(), KeyVaultKeyType::OkpHsm);
|
||||
EXPECT_EQ(keyVaultKey.Key.CurveName.Value(), KeyCurveName::Ed25519);
|
||||
}
|
||||
{
|
||||
// Now get the key
|
||||
auto keyResponse = client.GetKey(keyName);
|
||||
CheckValidResponse(keyResponse);
|
||||
auto keyVaultKey = keyResponse.Value;
|
||||
EXPECT_EQ(keyVaultKey.Name(), keyName);
|
||||
}
|
||||
}
|
||||
TEST_F(KeyVaultKeyClient, CreateEcKeyWithCurve)
|
||||
{
|
||||
auto const keyName = GetTestName();
|
||||
|
||||
@ -35,7 +35,7 @@ TEST(KeyVaultKeyClientUnitTest, ServiceVersion)
|
||||
// 7.3
|
||||
EXPECT_NO_THROW(auto options = KeyClientOptions();
|
||||
KeyClient keyClient("http://account.vault.azure.net", credential, options);
|
||||
EXPECT_EQ(options.ApiVersion, "7.3"););
|
||||
EXPECT_EQ(options.ApiVersion, "7.4-preview.1"););
|
||||
}
|
||||
|
||||
TEST(KeyVaultKeyClientUnitTest, GetUrl)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user