Skip to content

Commit

Permalink
Add CreateEcKeyOptions class (#18272)
Browse files Browse the repository at this point in the history
Resolves #16853
  • Loading branch information
heaths authored Jan 29, 2021
1 parent f1bfb3a commit edc83b1
Show file tree
Hide file tree
Showing 11 changed files with 715 additions and 6 deletions.
5 changes: 5 additions & 0 deletions sdk/keyvault/Azure.Security.KeyVault.Keys/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## 4.2.0-beta.4 (Unreleased)

### Added

- Added `CreateEcKeyOptions` class.
- Added `CreateEcKey` and `CreateEcKeyAsync` methods to the `KeyClient` class.

### Removed

- Removed local cryptographic support for AES-GCM.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ public CreateKeyOptions() { }
public System.DateTimeOffset? NotBefore { get { throw null; } set { } }
public System.Collections.Generic.IDictionary<string, string> Tags { get { throw null; } }
}
public partial class CreateOctKeyOptions : Azure.Security.KeyVault.Keys.CreateKeyOptions
{
public CreateOctKeyOptions(string name, bool hardwareProtected = false) { }
public bool HardwareProtected { get { throw null; } }
public int? KeySize { get { throw null; } set { } }
public Azure.Security.KeyVault.Keys.KeyType KeyType { get { throw null; } }
public string Name { get { throw null; } }
}
public partial class CreateRsaKeyOptions : Azure.Security.KeyVault.Keys.CreateKeyOptions
{
public CreateRsaKeyOptions(string name, bool hardwareProtected = false) { }
Expand Down Expand Up @@ -105,6 +113,8 @@ public KeyClient(System.Uri vaultUri, Azure.Core.TokenCredential credential, Azu
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Security.KeyVault.Keys.KeyVaultKey>> CreateEcKeyAsync(Azure.Security.KeyVault.Keys.CreateEcKeyOptions ecKeyOptions, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Security.KeyVault.Keys.KeyVaultKey> CreateKey(string name, Azure.Security.KeyVault.Keys.KeyType keyType, Azure.Security.KeyVault.Keys.CreateKeyOptions keyOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Security.KeyVault.Keys.KeyVaultKey>> CreateKeyAsync(string name, Azure.Security.KeyVault.Keys.KeyType keyType, Azure.Security.KeyVault.Keys.CreateKeyOptions keyOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Security.KeyVault.Keys.KeyVaultKey> CreateOctKey(Azure.Security.KeyVault.Keys.CreateOctKeyOptions octKeyOptions, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Security.KeyVault.Keys.KeyVaultKey>> CreateOctKeyAsync(Azure.Security.KeyVault.Keys.CreateOctKeyOptions octKeyOptions, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Security.KeyVault.Keys.KeyVaultKey> CreateRsaKey(Azure.Security.KeyVault.Keys.CreateRsaKeyOptions rsaKeyOptions, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Security.KeyVault.Keys.KeyVaultKey>> CreateRsaKeyAsync(Azure.Security.KeyVault.Keys.CreateRsaKeyOptions rsaKeyOptions, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Security.KeyVault.Keys.DeletedKey> GetDeletedKey(string name, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using Azure.Core;

namespace Azure.Security.KeyVault.Keys
{
/// <summary>
/// The properties needed to create an AES key using the <see cref="KeyClient"/>.
/// </summary>
public class CreateOctKeyOptions : CreateKeyOptions
{
/// <summary>
/// Gets the name of the key to create.
/// </summary>
public string Name { get; }

/// <summary>
/// Gets the key type of the <see cref="JsonWebKey"/> to create, including <see cref="KeyType.Oct"/> and <see cref="KeyType.OctHsm"/>.
/// </summary>
public KeyType KeyType { get; }

/// <summary>
/// Gets or sets the key size in bits, such as 128, 192, or 256. If null, the service default is used.
/// </summary>
public int? KeySize { get; set; }

/// <summary>
/// Gets a value indicating whether to create a hardware-protected key in a hardware security module (HSM).
/// </summary>
/// <value><c>true</c> to create a hardware-protected key; otherwise, <c>false</c> to create a software key.</value>
public bool HardwareProtected { get; }

/// <summary>
/// Initializes a new instance of the <see cref="CreateOctKeyOptions"/> class.
/// </summary>
/// <param name="name">The name of the key to create.</param>
/// <param name="hardwareProtected">True to create a hardware-protected key in a hardware security module (HSM). The default is false to create a software key.</param>
/// <exception cref="ArgumentException"><paramref name="name"/> is empty.</exception>
/// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
public CreateOctKeyOptions(string name, bool hardwareProtected = false)
{
Argument.AssertNotNullOrEmpty(name, nameof(name));

Name = name;
HardwareProtected = hardwareProtected;
if (hardwareProtected)
{
KeyType = KeyType.OctHsm;
}
else
{
KeyType = KeyType.Oct;
}
}
}
}
70 changes: 64 additions & 6 deletions sdk/keyvault/Azure.Security.KeyVault.Keys/src/KeyClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public KeyClient(Uri vaultUri, TokenCredential credential, KeyClientOptions opti

/// <summary>
/// Creates and stores a new key in Key Vault. The create key operation can be used to create any key type in Azure Key Vault.
/// If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
/// If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/create permission.
/// </summary>
/// <param name="name">The name of the key.</param>
/// <param name="keyType">The type of key to create. See <see cref="KeyType"/> for valid values.</param>
Expand Down Expand Up @@ -111,7 +111,7 @@ public virtual Response<KeyVaultKey> CreateKey(string name, KeyType keyType, Cre

/// <summary>
/// Creates and stores a new key in Key Vault. The create key operation can be used to create any key type in Azure Key Vault.
/// If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
/// If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/create permission.
/// </summary>
/// <param name="name">The name of the key.</param>
/// <param name="keyType">The type of key to create. See <see cref="KeyType"/> for valid values.</param>
Expand Down Expand Up @@ -144,7 +144,7 @@ public virtual async Task<Response<KeyVaultKey>> CreateKeyAsync(string name, Key

/// <summary>
/// Creates and stores a new Elliptic Curve key in Key Vault. If the named key already exists,
/// Azure Key Vault creates a new version of the key. It requires the keys/create permission.
/// Azure Key Vault creates a new version of the key. This operation requires the keys/create permission.
/// </summary>
/// <param name="ecKeyOptions">The key options object containing information about the Elliptic Curve key being created.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
Expand Down Expand Up @@ -173,7 +173,7 @@ public virtual Response<KeyVaultKey> CreateEcKey(CreateEcKeyOptions ecKeyOptions

/// <summary>
/// Creates and stores a new Elliptic Curve key in Key Vault. If the named key already exists,
/// Azure Key Vault creates a new version of the key. It requires the keys/create permission.
/// Azure Key Vault creates a new version of the key. This operation requires the keys/create permission.
/// </summary>
/// <param name="ecKeyOptions">The key options object containing information about the Elliptic Curve key being created.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
Expand Down Expand Up @@ -202,7 +202,7 @@ public virtual async Task<Response<KeyVaultKey>> CreateEcKeyAsync(CreateEcKeyOpt

/// <summary>
/// Creates and stores a new RSA key in Key Vault. If the named key already exists, Azure Key Vault creates a new
/// version of the key. It requires the keys/create permission.
/// version of the key. This operation requires the keys/create permission.
/// </summary>
/// <param name="rsaKeyOptions">The key options object containing information about the RSA key being created.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
Expand Down Expand Up @@ -231,7 +231,7 @@ public virtual Response<KeyVaultKey> CreateRsaKey(CreateRsaKeyOptions rsaKeyOpti

/// <summary>
/// Creates and stores a new RSA key in Key Vault. If the named key already exists, Azure Key Vault creates a new
/// version of the key. It requires the keys/create permission.
/// version of the key. This operation requires the keys/create permission.
/// </summary>
/// <param name="rsaKeyOptions">The key options object containing information about the RSA key being created.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
Expand All @@ -258,6 +258,64 @@ public virtual async Task<Response<KeyVaultKey>> CreateRsaKeyAsync(CreateRsaKeyO
}
}

/// <summary>
/// Creates and stores a new AES key in Key Vault. If the named key already exists, Azure Key Vault creates a new
/// version of the key. This operation requires the keys/create permission.
/// </summary>
/// <param name="octKeyOptions">The key options object containing information about the AES key being created.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
/// <exception cref="ArgumentNullException"><paramref name="octKeyOptions"/> is null.</exception>
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
public virtual Response<KeyVaultKey> CreateOctKey(CreateOctKeyOptions octKeyOptions, CancellationToken cancellationToken = default)
{
Argument.AssertNotNull(octKeyOptions, nameof(octKeyOptions));

var parameters = new KeyRequestParameters(octKeyOptions);

using DiagnosticScope scope = _pipeline.CreateScope($"{nameof(KeyClient)}.{nameof(CreateOctKey)}");
scope.AddAttribute("key", octKeyOptions.Name);
scope.Start();

try
{
return _pipeline.SendRequest(RequestMethod.Post, parameters, () => new KeyVaultKey(octKeyOptions.Name), cancellationToken, KeysPath, octKeyOptions.Name, "/create");
}
catch (Exception e)
{
scope.Failed(e);
throw;
}
}

/// <summary>
/// Creates and stores a new AES key in Key Vault. If the named key already exists, Azure Key Vault creates a new
/// version of the key. This operation requires the keys/create permission.
/// </summary>
/// <param name="octKeyOptions">The key options object containing information about the AES key being created.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
/// <exception cref="ArgumentNullException"><paramref name="octKeyOptions"/> is null.</exception>
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
public virtual async Task<Response<KeyVaultKey>> CreateOctKeyAsync(CreateOctKeyOptions octKeyOptions, CancellationToken cancellationToken = default)
{
Argument.AssertNotNull(octKeyOptions, nameof(octKeyOptions));

var parameters = new KeyRequestParameters(octKeyOptions);

using DiagnosticScope scope = _pipeline.CreateScope($"{nameof(KeyClient)}.{nameof(CreateOctKey)}");
scope.AddAttribute("key", octKeyOptions.Name);
scope.Start();

try
{
return await _pipeline.SendRequestAsync(RequestMethod.Post, parameters, () => new KeyVaultKey(octKeyOptions.Name), cancellationToken, KeysPath, octKeyOptions.Name, "/create").ConfigureAwait(false);
}
catch (Exception e)
{
scope.Failed(e);
throw;
}
}

/// <summary>
/// The update key operation changes specified attributes of a stored key and
/// can be applied to any key type and key version stored in Azure Key Vault.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ internal KeyRequestParameters(CreateRsaKeyOptions rsaKey)
}
}

internal KeyRequestParameters(CreateOctKeyOptions octKey)
: this(octKey.KeyType, octKey)
{
if (octKey.KeySize.HasValue)
{
KeySize = octKey.KeySize.Value;
}
}

void IJsonSerializable.WriteProperties(Utf8JsonWriter json)
{
if (KeyType != default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public void CreateKeyArgumentValidation()
Assert.ThrowsAsync<ArgumentException>(() => Client.CreateKeyAsync(string.Empty, KeyType.Ec));
Assert.ThrowsAsync<ArgumentNullException>(() => Client.CreateEcKeyAsync(null));
Assert.ThrowsAsync<ArgumentNullException>(() => Client.CreateRsaKeyAsync(null));
Assert.ThrowsAsync<ArgumentNullException>(() => Client.CreateOctKeyAsync(null));
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,33 @@ public async Task CreateRsaWithPublicExponent()
int publicExponent = rsaParams.Exponent.ToInt32();
Assert.AreEqual(3, publicExponent);
}

[Test]
public async Task CreateOctHsmKey()
{
string keyName = Recording.GenerateId();

CreateOctKeyOptions options = new CreateOctKeyOptions(keyName, hardwareProtected: true);
KeyVaultKey ecHsmkey = await Client.CreateOctKeyAsync(options);
RegisterForCleanup(keyName);

KeyVaultKey keyReturned = await Client.GetKeyAsync(keyName);

AssertKeyVaultKeysEqual(ecHsmkey, keyReturned);
}

[Test]
public async Task CreateOctKey()
{
string keyName = Recording.GenerateId();

CreateOctKeyOptions ecKey = new CreateOctKeyOptions(keyName, hardwareProtected: false);
KeyVaultKey keyNoHsm = await Client.CreateOctKeyAsync(ecKey);
RegisterForCleanup(keyNoHsm.Name);

KeyVaultKey keyReturned = await Client.GetKeyAsync(keyNoHsm.Name);

AssertKeyVaultKeysEqual(keyNoHsm, keyReturned);
}
}
}
Loading

0 comments on commit edc83b1

Please sign in to comment.