Skip to content

Commit edc83b1

Browse files
authored
Add CreateEcKeyOptions class (Azure#18272)
Resolves Azure#16853
1 parent f1bfb3a commit edc83b1

File tree

11 files changed

+715
-6
lines changed

11 files changed

+715
-6
lines changed

sdk/keyvault/Azure.Security.KeyVault.Keys/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## 4.2.0-beta.4 (Unreleased)
44

5+
### Added
6+
7+
- Added `CreateEcKeyOptions` class.
8+
- Added `CreateEcKey` and `CreateEcKeyAsync` methods to the `KeyClient` class.
9+
510
### Removed
611

712
- Removed local cryptographic support for AES-GCM.

sdk/keyvault/Azure.Security.KeyVault.Keys/api/Azure.Security.KeyVault.Keys.netstandard2.0.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ public CreateKeyOptions() { }
1717
public System.DateTimeOffset? NotBefore { get { throw null; } set { } }
1818
public System.Collections.Generic.IDictionary<string, string> Tags { get { throw null; } }
1919
}
20+
public partial class CreateOctKeyOptions : Azure.Security.KeyVault.Keys.CreateKeyOptions
21+
{
22+
public CreateOctKeyOptions(string name, bool hardwareProtected = false) { }
23+
public bool HardwareProtected { get { throw null; } }
24+
public int? KeySize { get { throw null; } set { } }
25+
public Azure.Security.KeyVault.Keys.KeyType KeyType { get { throw null; } }
26+
public string Name { get { throw null; } }
27+
}
2028
public partial class CreateRsaKeyOptions : Azure.Security.KeyVault.Keys.CreateKeyOptions
2129
{
2230
public CreateRsaKeyOptions(string name, bool hardwareProtected = false) { }
@@ -105,6 +113,8 @@ public KeyClient(System.Uri vaultUri, Azure.Core.TokenCredential credential, Azu
105113
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; }
106114
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; }
107115
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; }
116+
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; }
117+
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; }
108118
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; }
109119
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; }
110120
public virtual Azure.Response<Azure.Security.KeyVault.Keys.DeletedKey> GetDeletedKey(string name, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using Azure.Core;
6+
7+
namespace Azure.Security.KeyVault.Keys
8+
{
9+
/// <summary>
10+
/// The properties needed to create an AES key using the <see cref="KeyClient"/>.
11+
/// </summary>
12+
public class CreateOctKeyOptions : CreateKeyOptions
13+
{
14+
/// <summary>
15+
/// Gets the name of the key to create.
16+
/// </summary>
17+
public string Name { get; }
18+
19+
/// <summary>
20+
/// Gets the key type of the <see cref="JsonWebKey"/> to create, including <see cref="KeyType.Oct"/> and <see cref="KeyType.OctHsm"/>.
21+
/// </summary>
22+
public KeyType KeyType { get; }
23+
24+
/// <summary>
25+
/// Gets or sets the key size in bits, such as 128, 192, or 256. If null, the service default is used.
26+
/// </summary>
27+
public int? KeySize { get; set; }
28+
29+
/// <summary>
30+
/// Gets a value indicating whether to create a hardware-protected key in a hardware security module (HSM).
31+
/// </summary>
32+
/// <value><c>true</c> to create a hardware-protected key; otherwise, <c>false</c> to create a software key.</value>
33+
public bool HardwareProtected { get; }
34+
35+
/// <summary>
36+
/// Initializes a new instance of the <see cref="CreateOctKeyOptions"/> class.
37+
/// </summary>
38+
/// <param name="name">The name of the key to create.</param>
39+
/// <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>
40+
/// <exception cref="ArgumentException"><paramref name="name"/> is empty.</exception>
41+
/// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
42+
public CreateOctKeyOptions(string name, bool hardwareProtected = false)
43+
{
44+
Argument.AssertNotNullOrEmpty(name, nameof(name));
45+
46+
Name = name;
47+
HardwareProtected = hardwareProtected;
48+
if (hardwareProtected)
49+
{
50+
KeyType = KeyType.OctHsm;
51+
}
52+
else
53+
{
54+
KeyType = KeyType.Oct;
55+
}
56+
}
57+
}
58+
}

sdk/keyvault/Azure.Security.KeyVault.Keys/src/KeyClient.cs

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public KeyClient(Uri vaultUri, TokenCredential credential, KeyClientOptions opti
7878

7979
/// <summary>
8080
/// 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.
81-
/// If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
81+
/// If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/create permission.
8282
/// </summary>
8383
/// <param name="name">The name of the key.</param>
8484
/// <param name="keyType">The type of key to create. See <see cref="KeyType"/> for valid values.</param>
@@ -111,7 +111,7 @@ public virtual Response<KeyVaultKey> CreateKey(string name, KeyType keyType, Cre
111111

112112
/// <summary>
113113
/// 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.
114-
/// If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
114+
/// If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/create permission.
115115
/// </summary>
116116
/// <param name="name">The name of the key.</param>
117117
/// <param name="keyType">The type of key to create. See <see cref="KeyType"/> for valid values.</param>
@@ -144,7 +144,7 @@ public virtual async Task<Response<KeyVaultKey>> CreateKeyAsync(string name, Key
144144

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

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

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

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

261+
/// <summary>
262+
/// Creates and stores a new AES key in Key Vault. If the named key already exists, Azure Key Vault creates a new
263+
/// version of the key. This operation requires the keys/create permission.
264+
/// </summary>
265+
/// <param name="octKeyOptions">The key options object containing information about the AES key being created.</param>
266+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
267+
/// <exception cref="ArgumentNullException"><paramref name="octKeyOptions"/> is null.</exception>
268+
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
269+
public virtual Response<KeyVaultKey> CreateOctKey(CreateOctKeyOptions octKeyOptions, CancellationToken cancellationToken = default)
270+
{
271+
Argument.AssertNotNull(octKeyOptions, nameof(octKeyOptions));
272+
273+
var parameters = new KeyRequestParameters(octKeyOptions);
274+
275+
using DiagnosticScope scope = _pipeline.CreateScope($"{nameof(KeyClient)}.{nameof(CreateOctKey)}");
276+
scope.AddAttribute("key", octKeyOptions.Name);
277+
scope.Start();
278+
279+
try
280+
{
281+
return _pipeline.SendRequest(RequestMethod.Post, parameters, () => new KeyVaultKey(octKeyOptions.Name), cancellationToken, KeysPath, octKeyOptions.Name, "/create");
282+
}
283+
catch (Exception e)
284+
{
285+
scope.Failed(e);
286+
throw;
287+
}
288+
}
289+
290+
/// <summary>
291+
/// Creates and stores a new AES key in Key Vault. If the named key already exists, Azure Key Vault creates a new
292+
/// version of the key. This operation requires the keys/create permission.
293+
/// </summary>
294+
/// <param name="octKeyOptions">The key options object containing information about the AES key being created.</param>
295+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
296+
/// <exception cref="ArgumentNullException"><paramref name="octKeyOptions"/> is null.</exception>
297+
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
298+
public virtual async Task<Response<KeyVaultKey>> CreateOctKeyAsync(CreateOctKeyOptions octKeyOptions, CancellationToken cancellationToken = default)
299+
{
300+
Argument.AssertNotNull(octKeyOptions, nameof(octKeyOptions));
301+
302+
var parameters = new KeyRequestParameters(octKeyOptions);
303+
304+
using DiagnosticScope scope = _pipeline.CreateScope($"{nameof(KeyClient)}.{nameof(CreateOctKey)}");
305+
scope.AddAttribute("key", octKeyOptions.Name);
306+
scope.Start();
307+
308+
try
309+
{
310+
return await _pipeline.SendRequestAsync(RequestMethod.Post, parameters, () => new KeyVaultKey(octKeyOptions.Name), cancellationToken, KeysPath, octKeyOptions.Name, "/create").ConfigureAwait(false);
311+
}
312+
catch (Exception e)
313+
{
314+
scope.Failed(e);
315+
throw;
316+
}
317+
}
318+
261319
/// <summary>
262320
/// The update key operation changes specified attributes of a stored key and
263321
/// can be applied to any key type and key version stored in Azure Key Vault.

sdk/keyvault/Azure.Security.KeyVault.Keys/src/KeyRequestParameters.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,15 @@ internal KeyRequestParameters(CreateRsaKeyOptions rsaKey)
112112
}
113113
}
114114

115+
internal KeyRequestParameters(CreateOctKeyOptions octKey)
116+
: this(octKey.KeyType, octKey)
117+
{
118+
if (octKey.KeySize.HasValue)
119+
{
120+
KeySize = octKey.KeySize.Value;
121+
}
122+
}
123+
115124
void IJsonSerializable.WriteProperties(Utf8JsonWriter json)
116125
{
117126
if (KeyType != default)

sdk/keyvault/Azure.Security.KeyVault.Keys/tests/KeyClientTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public void CreateKeyArgumentValidation()
3131
Assert.ThrowsAsync<ArgumentException>(() => Client.CreateKeyAsync(string.Empty, KeyType.Ec));
3232
Assert.ThrowsAsync<ArgumentNullException>(() => Client.CreateEcKeyAsync(null));
3333
Assert.ThrowsAsync<ArgumentNullException>(() => Client.CreateRsaKeyAsync(null));
34+
Assert.ThrowsAsync<ArgumentNullException>(() => Client.CreateOctKeyAsync(null));
3435
}
3536

3637
[Test]

sdk/keyvault/Azure.Security.KeyVault.Keys/tests/ManagedHsmLiveTests.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,33 @@ public async Task CreateRsaWithPublicExponent()
4343
int publicExponent = rsaParams.Exponent.ToInt32();
4444
Assert.AreEqual(3, publicExponent);
4545
}
46+
47+
[Test]
48+
public async Task CreateOctHsmKey()
49+
{
50+
string keyName = Recording.GenerateId();
51+
52+
CreateOctKeyOptions options = new CreateOctKeyOptions(keyName, hardwareProtected: true);
53+
KeyVaultKey ecHsmkey = await Client.CreateOctKeyAsync(options);
54+
RegisterForCleanup(keyName);
55+
56+
KeyVaultKey keyReturned = await Client.GetKeyAsync(keyName);
57+
58+
AssertKeyVaultKeysEqual(ecHsmkey, keyReturned);
59+
}
60+
61+
[Test]
62+
public async Task CreateOctKey()
63+
{
64+
string keyName = Recording.GenerateId();
65+
66+
CreateOctKeyOptions ecKey = new CreateOctKeyOptions(keyName, hardwareProtected: false);
67+
KeyVaultKey keyNoHsm = await Client.CreateOctKeyAsync(ecKey);
68+
RegisterForCleanup(keyNoHsm.Name);
69+
70+
KeyVaultKey keyReturned = await Client.GetKeyAsync(keyNoHsm.Name);
71+
72+
AssertKeyVaultKeysEqual(keyNoHsm, keyReturned);
73+
}
4674
}
4775
}

0 commit comments

Comments
 (0)