Skip to content

Commit a380d47

Browse files
authored
Added a convenience method to key clients to create a cryptography client. (Azure#24503)
* Added a new convenience method to KeyClient and KeyAsyncClient to obtain a CryptographyClient and CryptographyAsyncClient (respectively) for a given key. * Added tests. * Updated crypto code snippets. * Updated CHANGELOG. * Added test recordings. * Applied PR feedback. * Fixed CheckStyle issues. * Fixed test issues. * Fixed test and samples issues, updated test-resources.json template and re-recorded tests. * Updated documentation. * Fixed yet another CheckStyle issue.
1 parent ebc71be commit a380d47

File tree

103 files changed

+3082
-9061
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+3082
-9061
lines changed

sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,27 @@
33
## 4.4.0-beta.4 (Unreleased)
44

55
### Features Added
6-
7-
### Breaking Changes
8-
9-
### Bugs Fixed
6+
- Added new functions to key clients to enable key rotation:
7+
- `KeyClient`
8+
- `rotateKey(String name)`
9+
- `rotateKeyWithResponse(String name, Context context)`
10+
- `getKeyRotationPolicy(String name)`
11+
- `getKeyRotationPolicyWithResponse(String name, Context context)`
12+
- `updateKeyRotationPolicy(String name, KeyRotationPolicyProperties keyRotationPolicyProperties)`
13+
- `updateKeyRotationPolicyWithResponse(String name, KeyRotationPolicyProperties keyRotationPolicyProperties, Context context)`
14+
- `KeyAsyncClient`
15+
- `rotateKey(String name)`
16+
- `rotateKeyWithResponse(String name)`
17+
- `getKeyRotationPolicy(String name)`
18+
- `getKeyRotationPolicyWithResponse(String name)`
19+
- `updateKeyRotationPolicy(String name, KeyRotationPolicyProperties keyRotationPolicyProperties)`
20+
- `updateKeyRotationPolicyWithResponse(String name, KeyRotationPolicyProperties keyRotationPolicyProperties)`
21+
- Added convenience methods to create cryptography clients using key clients:
22+
- `KeyClient.getCryptographyClient(String keyName)`
23+
- `KeyClient.getCryptographyClient(String keyName, String keyVersion)`
24+
- `KeyAsyncClient.getCryptographyAsyncClient(String keyName)`
25+
- `KeyAsyncClient.getCryptographyAsyncClient(String keyName, String keyVersion)`
26+
- `CryptographyClientBuilder` does not require `keyIdentifier` to a include a key version. If no version is provided, cryptographic operations will be made using the latest version of the key.
1027

1128
### Other Changes
1229

sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/KeyAsyncClient.java

Lines changed: 170 additions & 76 deletions
Large diffs are not rendered by default.

sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/KeyClient.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import com.azure.core.http.rest.Response;
1515
import com.azure.core.util.Context;
1616
import com.azure.core.util.polling.SyncPoller;
17+
import com.azure.security.keyvault.keys.cryptography.CryptographyClient;
18+
import com.azure.security.keyvault.keys.cryptography.CryptographyClientBuilder;
1719
import com.azure.security.keyvault.keys.models.CreateEcKeyOptions;
1820
import com.azure.security.keyvault.keys.models.CreateKeyOptions;
1921
import com.azure.security.keyvault.keys.models.CreateOctKeyOptions;
@@ -66,6 +68,44 @@ public String getVaultUrl() {
6668
return client.getVaultUrl();
6769
}
6870

71+
/**
72+
* Creates a {@link CryptographyClient} for the latest version of a given key.
73+
*
74+
* <p>To ensure correct behavior when performing operations such as {@code Decrypt}, {@code Unwrap} and
75+
* {@code Verify}, it is recommended to use a {@link CryptographyClient} created for the specific key
76+
* version that was used for the corresponding inverse operation: {@code Encrypt}, {@code Wrap}, or
77+
* {@code Sign}, respectively.</p>
78+
*
79+
* <p>You can provide a key version either via {@link KeyClient#getCryptographyClient(String, String)} or by
80+
* ensuring it is included in the {@code keyIdentifier} passed to
81+
* {@link CryptographyClientBuilder#keyIdentifier(String)} before building a client.</p>
82+
*
83+
* @param keyName The name of the key.
84+
*
85+
* @return An instance of {@link CryptographyClient} associated with the latest version of a key with the
86+
* provided name.
87+
*
88+
* @throws IllegalArgumentException If {@code keyName} is {@code null} or empty.
89+
*/
90+
public CryptographyClient getCryptographyClient(String keyName) {
91+
return client.getCryptographyClientBuilder(keyName, null).buildClient();
92+
}
93+
94+
/**
95+
* Creates a {@link CryptographyClient} for a given key version.
96+
*
97+
* @param keyName The name of the key.
98+
* @param keyVersion The key version.
99+
*
100+
* @return An instance of {@link CryptographyClient} associated with a key with the provided name and version.
101+
* If {@code keyVersion} is {@code null} or empty, the client will use the latest version of the key.
102+
*
103+
* @throws IllegalArgumentException If {@code keyName} is {@code null} or empty.
104+
*/
105+
public CryptographyClient getCryptographyClient(String keyName, String keyVersion) {
106+
return client.getCryptographyClientBuilder(keyName, keyVersion).buildClient();
107+
}
108+
69109
/**
70110
* Creates a new {@link KeyVaultKey key} and stores it in the key vault. The create key operation can be used to
71111
* create any {@link KeyType keyType} in Azure Key Vault. If a {@link KeyVaultKey key} with the provided name

sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/cryptography/CryptographyAsyncClient.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,15 @@
5353
*
5454
* {@codesnippet com.azure.security.keyvault.keys.cryptography.CryptographyAsyncClient.instantiation}
5555
* {@codesnippet com.azure.security.keyvault.keys.cryptography.CryptographyAsyncClient.withJsonWebKey.instantiation}
56-
* {@codesnippet com.azure.security.keyvault.keys.cryptography.CryptographyAsyncClient.withHttpClient.instantiation}
57-
* {@codesnippet com.azure.security.keyvault.keys.cryptography.CryptographyAsyncClient.withPipeline.instantiation}
5856
*
5957
* @see CryptographyClientBuilder
6058
*/
6159
@ServiceClient(builder = CryptographyClientBuilder.class, isAsync = true, serviceInterfaces = CryptographyService.class)
6260
public class CryptographyAsyncClient {
63-
static final String SECRETS_COLLECTION = "secrets";
6461
// Please see <a href=https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/azure-services-resource-providers>here</a>
6562
// for more information on Azure resource provider namespaces.
6663
static final String KEYVAULT_TRACING_NAMESPACE_VALUE = "Microsoft.KeyVault";
64+
static final String SECRETS_COLLECTION = "secrets";
6765

6866
JsonWebKey key;
6967

@@ -792,15 +790,14 @@ Mono<VerifyResult> verifyData(SignatureAlgorithm algorithm, byte[] data, byte[]
792790

793791
private void unpackAndValidateId(String keyId) {
794792
if (CoreUtils.isNullOrEmpty(keyId)) {
795-
throw logger.logExceptionAsError(new IllegalArgumentException("Key Id is invalid"));
793+
throw logger.logExceptionAsError(new IllegalArgumentException("'keyId' cannot be null or empty."));
796794
}
797795

798796
try {
799797
URL url = new URL(keyId);
800798
String[] tokens = url.getPath().split("/");
801799
String endpoint = url.getProtocol() + "://" + url.getHost();
802800
String keyName = (tokens.length >= 3 ? tokens[2] : null);
803-
String version = (tokens.length >= 4 ? tokens[3] : null);
804801
this.keyCollection = (tokens.length >= 2 ? tokens[1] : null);
805802

806803
if (Strings.isNullOrEmpty(endpoint)) {
@@ -809,9 +806,6 @@ private void unpackAndValidateId(String keyId) {
809806
} else if (Strings.isNullOrEmpty(keyName)) {
810807
throw logger.logExceptionAsError(
811808
new IllegalArgumentException("Key name in key identifier is invalid."));
812-
} else if (Strings.isNullOrEmpty(version)) {
813-
throw logger.logExceptionAsError(
814-
new IllegalArgumentException("Key version in key identifier is invalid."));
815809
}
816810
} catch (MalformedURLException e) {
817811
throw logger.logExceptionAsError(new IllegalArgumentException("The key identifier is malformed.", e));

sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/cryptography/CryptographyClientBuilder.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,13 @@
3737
* It constructs an instance of the desired client.
3838
*
3939
* <p>The minimal configuration options required by {@link CryptographyClientBuilder cryptographyClientBuilder} to build
40-
* {@link CryptographyAsyncClient} are {@link JsonWebKey jsonWebKey} or {@link String Azure Key Vault key identifier}
41-
* and {@link TokenCredential credential}.</p>
40+
* a {@link CryptographyAsyncClient} or a {@link CryptographyClient} are a {@link TokenCredential credential} and either
41+
* a {@link JsonWebKey JSON Web Key} or a {@code Azure Key Vault key identifier}.</p>
42+
*
43+
* <p>To ensure correct behavior when performing operations such as {@code Decrypt}, {@code Unwrap} and
44+
* {@code Verify}, it is recommended to use a {@link CryptographyAsyncClient} or {@link CryptographyClient} created
45+
* for the specific key version that was used for the corresponding inverse operation: {@code Encrypt},
46+
* {@code Wrap}, or {@code Sign}, respectively.</p>
4247
*
4348
* {@codesnippet com.azure.security.keyvault.keys.cryptography.CryptographyAsyncClient.instantiation}
4449
* {@codesnippet com.azure.security.keyvault.keys.cryptography.CryptographyAsyncClient.withJsonWebKey.instantiation}
@@ -227,6 +232,11 @@ CryptographyServiceVersion getServiceVersion() {
227232
/**
228233
* Sets the Azure Key Vault key identifier of the JSON Web Key to be used for cryptography operations.
229234
*
235+
* <p>To ensure correct behavior when performing operations such as {@code Decrypt}, {@code Unwrap} and
236+
* {@code Verify}, it is recommended to use a {@link CryptographyAsyncClient} or {@link CryptographyClient} created
237+
* for the specific key version that was used for the corresponding inverse operation: {@code Encrypt}
238+
* {@code Wrap}, or {@code Sign}, respectively.</p>
239+
*
230240
* @param keyId The Azure Key Vault key identifier of the JSON Web Key stored in the key vault.
231241
*
232242
* @return The updated {@link CryptographyClientBuilder} object.

0 commit comments

Comments
 (0)