Skip to content

Commit

Permalink
Supports Encrypt/Decrypt/Wrap/Unwrap using keys (#15816)
Browse files Browse the repository at this point in the history
* add encrypt and decrypt by key

* add test cases and examples

* add change log

* add online version

* remove position number
  • Loading branch information
BethanyZhou committed Sep 7, 2021
1 parent 8b4f2c8 commit 24f497c
Show file tree
Hide file tree
Showing 20 changed files with 1,705 additions and 892 deletions.
14 changes: 14 additions & 0 deletions src/KeyVault/KeyVault.Test/PesterTests/Key.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,18 @@ Describe "Import key" {
Add-AzKeyVaultKey -VaultName veakkine-kv -Name PSECImportedKey -KeyFilePath E:\targetBlob.byok -CurveName P-256 -ErrorAction Stop
} | Should -Throw "KeyType"
}
}

Describe "Invoke key operation" {
It "Encrypt and Decrypt a sequence using key" {
$encryptedResult = Invoke-AzKeyVaultKeyOperation -Operation Encrypt -Algorithm RSA1_5 -HsmName bez-hsm -Name bez-k -Value (ConvertTo-SecureString -String "test" -AsPlainText -Force)
$decryptedResult = Invoke-AzKeyVaultKeyOperation -Operation Decrypt -Algorithm RSA1_5 -HsmName bez-hsm -Name bez-k -Value (ConvertTo-SecureString -String $$encryptedResult.result -AsPlainText -Force)
$decryptedResult.result | Should -Be "test"
}

It "Wrap and Unwrap a sequence using key" {
$wrappedResult = Invoke-AzKeyVaultKeyOperation -Operation Wrap -Algorithm RSA1_5 -HsmName bez-hsm -Name bez-k -Value (ConvertTo-SecureString -String "test" -AsPlainText -Force)
$unwrappedResult = Invoke-AzKeyVaultKeyOperation -Operation Unwrap -Algorithm RSA1_5 -HsmName bez-hsm -Name bez-k -Value (ConvertTo-SecureString -String $wrappedResult.result -AsPlainText -Force)
$unwrappedResult.result | Should -Be "test"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ $here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"

. $PSScriptRoot/ManagedHsmDatePlaneTests.ps1
. $PSScriptRoot/ManagedHsmDataPlaneTests.ps1
# ImportModules
$hsmName = 'bezmhsm'
$signInName = 'yeliu@microsoft.com'
Expand Down
1 change: 1 addition & 0 deletions src/KeyVault/KeyVault/Az.KeyVault.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ CmdletsToExport = 'Add-AzKeyVaultCertificate', 'Update-AzKeyVaultCertificate',
'Add-AzKeyVaultKey', 'Remove-AzKeyVaultKey', 'Update-AzKeyVault',
'New-AzKeyVaultNetworkRuleSetObject', 'Remove-AzKeyVaultSecret',
'Restore-AzKeyVaultKey', 'Update-AzKeyVaultKey',
'Invoke-AzKeyVaultKeyOperation',
'Set-AzKeyVaultSecret', 'Update-AzKeyVaultSecret',
'Get-AzKeyVaultCertificatePolicy',
'New-AzKeyVaultCertificateAdministratorDetail',
Expand Down
1 change: 1 addition & 0 deletions src/KeyVault/KeyVault/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- Additional information about change #1
-->
## Upcoming Release
* Supports Encrypt/Decrypt/Wrap/Unwrap using keys [#15679]
* Enabled managing resources in other subscriptions without switching the context by adding `-Subscription <String>`.

## Version 3.5.0
Expand Down
119 changes: 119 additions & 0 deletions src/KeyVault/KeyVault/Commands/Key/InvokeAzureKeyVaultOperation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using Microsoft.Azure.Commands.KeyVault.Models;
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;

using System;
using System.Management.Automation;
using System.Security;
using System.Text;

namespace Microsoft.Azure.Commands.KeyVault.Commands.Key
{
/// <summary>
/// 1. Encrypts an arbitrary sequence of bytes using an encryption key that is stored in a key vault.
/// 2. Decrypts a single block of encrypted data.
/// 3. Wraps a symmetric key using a specified key.
/// 4. Unwraps a symmetric key using the specified key that was initially used for wrapping that key.
/// </summary>
[Cmdlet(VerbsLifecycle.Invoke, ResourceManager.Common.AzureRMConstants.AzurePrefix + "KeyVaultKeyOperation", SupportsShouldProcess = true, DefaultParameterSetName = ByVaultNameParameterSet)]
[OutputType(typeof(PSKeyOperationResult))]
public class InvokeAzureKeyVaultKeyOperation : KeyVaultKeyCmdletBase
{
#region Supported Operation
enum Operations
{
Unknown,
Encrypt,
Decrypt,
Wrap,
Unwrap
}
#endregion

#region Input Parameter Definitions

[Parameter(Mandatory = true,
HelpMessage = "Algorithm identifier")]
[ValidateNotNullOrEmpty]
[PSArgumentCompleter("Encrypt", "Decrypt", "Wrap", "Unwrap")]
public string Operation { get; set; }

[Parameter(Mandatory = true,
HelpMessage = "Algorithm identifier")]
[ValidateNotNullOrEmpty]
[PSArgumentCompleter("RSA-OAEP", "RSA-OAEP-256", "RSA1_5")]
[Alias("EncryptionAlgorithm", "WrapAlgorithm")]
public string Algorithm { get; set; }

[Parameter(Mandatory = true,
HelpMessage = "The value to be operated")]
[ValidateNotNullOrEmpty]
public SecureString Value { get; set; }
#endregion Input Parameter Definitions

public override void ExecuteCmdlet()
{
NormalizeParameterSets();

Operations opt = Operations.Unknown;
Enum.TryParse(Operation, out opt);

if (string.IsNullOrEmpty(HsmName))
{
switch (opt)
{
case Operations.Encrypt:
this.WriteObject(
this.Track2DataClient.Encrypt(VaultName, Name, Version,
Encoding.ASCII.GetBytes(Value.ConvertToString()), Algorithm));
break;
case Operations.Decrypt:
this.WriteObject(
this.Track2DataClient.Decrypt(VaultName, Name, Version,
Convert.FromBase64String(Value.ConvertToString()), Algorithm));
break;
case Operations.Wrap:
this.WriteObject(
this.Track2DataClient.WrapKey(VaultName, Name, Version,
Encoding.ASCII.GetBytes(Value.ConvertToString()), Algorithm));
break;
case Operations.Unwrap:
this.WriteObject(
this.Track2DataClient.UnwrapKey(VaultName, Name, Version,
Convert.FromBase64String(Value.ConvertToString()), Algorithm));
break;
case Operations.Unknown:
throw new NotSupportedException("Not supported ${Operation} yet");
}
}
else
{
switch (opt)
{
case Operations.Encrypt:
this.WriteObject(
this.Track2DataClient.ManagedHsmKeyEncrypt(HsmName, Name, Version,
Encoding.ASCII.GetBytes(Value.ConvertToString()), Algorithm));
break;
case Operations.Decrypt:
this.WriteObject(
this.Track2DataClient.ManagedHsmKeyDecrypt(HsmName, Name, Version,
Convert.FromBase64String(Value.ConvertToString()), Algorithm));
break;
case Operations.Wrap:
this.WriteObject(
this.Track2DataClient.ManagedHsmWrapKey(HsmName, Name, Version,
Encoding.ASCII.GetBytes(Value.ConvertToString()), Algorithm));
break;
case Operations.Unwrap:
this.WriteObject(
this.Track2DataClient.ManagedHsmUnwrapKey(HsmName, Name, Version,
Convert.FromBase64String(Value.ConvertToString()), Algorithm));
break;
case Operations.Unknown:
throw new NotSupportedException("Not supported ${Operation} yet");
}

}
}
}
}
94 changes: 94 additions & 0 deletions src/KeyVault/KeyVault/Commands/Key/KeyVaultKeyCmdletBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using Microsoft.Azure.Commands.KeyVault.Models;
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;

using System.Management.Automation;

namespace Microsoft.Azure.Commands.KeyVault.Commands.Key
{
public class KeyVaultKeyCmdletBase : KeyVaultCmdletBase
{
#region Parameter Set Names

internal const string ByVaultNameParameterSet = "ByVaultName";
internal const string ByHsmNameParameterSet = "ByHsmName";
internal const string ByKeyInputObjectParameterSet = "ByKeyInputObject";

#endregion

#region Input Parameter Definitions

/// <summary>
/// Vault name
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ParameterSetName = ByVaultNameParameterSet,
HelpMessage = "Vault name.")]
[ResourceNameCompleter("Microsoft.KeyVault/vaults", "FakeResourceGroupName")]
[ValidateNotNullOrEmpty]
public string VaultName { get; set; }

[Parameter(Mandatory = true,
Position = 0,
ParameterSetName = ByHsmNameParameterSet,
HelpMessage = "HSM name.")]
[ResourceNameCompleter("Microsoft.KeyVault/managedHSMs", "FakeResourceGroupName")]
[ValidateNotNullOrEmpty]
public string HsmName { get; set; }

/// <summary>
/// Key name.
/// </summary>
[Parameter(Mandatory = true,
Position = 1,
ParameterSetName = ByVaultNameParameterSet,
HelpMessage = "Key name.")]
[Parameter(Mandatory = true,
Position = 1,
ParameterSetName = ByHsmNameParameterSet,
HelpMessage = "Key name.")]
[ValidateNotNullOrEmpty]
[Alias(Constants.KeyName)]
public string Name { get; set; }

/// <summary>
/// Key object
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ParameterSetName = ByKeyInputObjectParameterSet,
ValueFromPipeline = true,
HelpMessage = "Key object")]
[ValidateNotNullOrEmpty]
[Alias("Key")]
public PSKeyVaultKeyIdentityItem InputObject { get; set; }

/// <summary>
/// Key version.
/// </summary>
[Parameter(Mandatory = false,
HelpMessage = "Key version.")]
[Alias("KeyVersion")]
public string Version { get; set; }

#endregion Input Parameter Definitions

internal void NormalizeParameterSets()
{
if (InputObject != null) {
Name = InputObject.Name;
Version = Version ?? InputObject.Version;

if (InputObject.IsHsm)
{
HsmName = InputObject.VaultName;
}
else
{
VaultName = InputObject.VaultName;
}
}
}
}
}
67 changes: 43 additions & 24 deletions src/KeyVault/KeyVault/Models/IKeyVaultDataServiceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,56 +25,75 @@ namespace Microsoft.Azure.Commands.KeyVault.Models
{
public interface IKeyVaultDataServiceClient
{
#region Key actions
PSKeyVaultKey CreateKey(string vaultName, string keyName, PSKeyVaultKeyAttributes keyAttributes, int? size, string curveName);

PSKeyVaultKey CreateManagedHsmKey(string managedHsmName, string keyName, PSKeyVaultKeyAttributes keyAttributes, int? size, string curveName);
#region KeyVault key actions
string BackupKey(string vaultName, string keyName, string outputBlobPath);

PSKeyVaultKey ImportKey(string vaultName, string keyName, PSKeyVaultKeyAttributes keyAttributes, JsonWebKey webKey, bool? importToHsm);
PSKeyVaultKey CreateKey(string vaultName, string keyName, PSKeyVaultKeyAttributes keyAttributes, int? size, string curveName);

PSKeyVaultKey ImportManagedHsmKey(string managedHsmName, string keyName, Track2Sdk.JsonWebKey webKey);
PSKeyOperationResult Decrypt(string vaultName, string keyName, string version, byte[] value, string encryptAlgorithm);

PSKeyVaultKey UpdateKey(string vaultName, string keyName, string keyVersion, PSKeyVaultKeyAttributes keyAttributes);
PSDeletedKeyVaultKey DeleteKey(string vaultName, string keyName);

PSKeyVaultKey UpdateManagedHsmKey(string managedHsmName, string keyName, string keyVersion, PSKeyVaultKeyAttributes keyAttributes);
PSKeyOperationResult Encrypt(string vaultName, string keyName, string version, byte[] value, string encryptAlgorithm);

PSKeyVaultKey GetKey(string vaultName, string keyName, string keyVersion);

PSKeyVaultKey GetManagedHsmKey(string managedHsmName, string keyName, string keyVersion);

PSDeletedKeyVaultKey GetDeletedKey(string managedHsmName, string keyName);

PSDeletedKeyVaultKey GetManagedHsmDeletedKey(string managedHsmName, string keyName);

IEnumerable<PSKeyVaultKeyIdentityItem> GetKeys(KeyVaultObjectFilterOptions options);

IEnumerable<PSKeyVaultKeyIdentityItem> GetManagedHsmKeys(string managedHsmName);

IEnumerable<PSKeyVaultKeyIdentityItem> GetKeyVersions(KeyVaultObjectFilterOptions options);

IEnumerable<PSKeyVaultKeyIdentityItem> GetManagedHsmKeyAllVersions(string managedHsmName, string keyName);

IEnumerable<PSDeletedKeyVaultKeyIdentityItem> GetDeletedKeys(KeyVaultObjectFilterOptions options);

IEnumerable<PSDeletedKeyVaultKeyIdentityItem> GetManagedHsmDeletedKeys(string managedHsmName);
PSKeyVaultKey ImportKey(string vaultName, string keyName, PSKeyVaultKeyAttributes keyAttributes, JsonWebKey webKey, bool? importToHsm);

PSDeletedKeyVaultKey DeleteKey(string vaultName, string keyName);
PSKeyOperationResult UnwrapKey(string vaultName, string keyName, string keyVersion, byte[] value, string wrapAlgorithm);

PSDeletedKeyVaultKey DeleteManagedHsmKey(string ManagedHsm, string keyName);
PSKeyVaultKey UpdateKey(string vaultName, string keyName, string keyVersion, PSKeyVaultKeyAttributes keyAttributes);

void PurgeKey(string vaultName, string name);
PSKeyOperationResult WrapKey(string vaultName, string keyName, string keyVersion, byte[] wrapKey, string wrapAlgorithm);

void PurgeManagedHsmKey(string managedHsmName, string keyName);
void PurgeKey(string vaultName, string name);

PSKeyVaultKey RecoverKey(string vaultName, string keyName);

PSKeyVaultKey RecoverManagedHsmKey(string managedHsmName, string keyName);
PSKeyVaultKey RestoreKey(string vaultName, string inputBlobPath);
#endregion

string BackupKey(string vaultName, string keyName, string outputBlobPath);
#region Managed Hsm key actions

string BackupManagedHsmKey(string managedHsmName, string keyName, string outputBlobPath);

PSKeyVaultKey RestoreKey(string vaultName, string inputBlobPath);
PSKeyVaultKey CreateManagedHsmKey(string managedHsmName, string keyName, PSKeyVaultKeyAttributes keyAttributes, int? size, string curveName);

PSDeletedKeyVaultKey DeleteManagedHsmKey(string ManagedHsm, string keyName);

PSKeyVaultKey GetManagedHsmKey(string managedHsmName, string keyName, string keyVersion);

PSDeletedKeyVaultKey GetManagedHsmDeletedKey(string managedHsmName, string keyName);

IEnumerable<PSKeyVaultKeyIdentityItem> GetManagedHsmKeys(string managedHsmName);

IEnumerable<PSKeyVaultKeyIdentityItem> GetManagedHsmKeyAllVersions(string managedHsmName, string keyName);

IEnumerable<PSDeletedKeyVaultKeyIdentityItem> GetManagedHsmDeletedKeys(string managedHsmName);

PSKeyVaultKey ImportManagedHsmKey(string managedHsmName, string keyName, Track2Sdk.JsonWebKey webKey);

PSKeyOperationResult ManagedHsmKeyDecrypt(string vaultName, string keyName, string version, byte[] value, string encryptAlgorithm);

PSKeyOperationResult ManagedHsmKeyEncrypt(string vaultName, string keyName, string version, byte[] value, string encryptAlgorithm);

PSKeyOperationResult ManagedHsmUnwrapKey(string vaultName, string keyName, string keyVersion, byte[] value, string wrapAlgorithm);

PSKeyOperationResult ManagedHsmWrapKey(string vaultName, string keyName, string keyVersion, byte[] wrapKey, string wrapAlgorithm);

PSKeyVaultKey UpdateManagedHsmKey(string managedHsmName, string keyName, string keyVersion, PSKeyVaultKeyAttributes keyAttributes);

void PurgeManagedHsmKey(string managedHsmName, string keyName);

PSKeyVaultKey RecoverManagedHsmKey(string managedHsmName, string keyName);

PSKeyVaultKey RestoreManagedHsmKey(string managedHsmName, string inputBlobPath);
#endregion
Expand Down
Loading

0 comments on commit 24f497c

Please sign in to comment.