Code Sample
- *Gets a number of bytes containing random values from a managed HSM. Prints out details of the response + *
Gets a number of bytes containing random values from a managed HSM. Prints out details of the response * returned by the service and the retrieved bytes as a base64URL-encoded string.
* *@@ -1989,12 +1845,8 @@ public byte[] getRandomBytes(int count) { */ @ServiceMethod(returns = ReturnType.SINGLE) public ResponsegetRandomBytesWithResponse(int count, RequestContext requestContext) { - try { - return mapResponse(clientImpl.getRandomBytesWithResponse(new GetRandomBytesRequest(count), requestContext), - RandomBytes::getValue); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } + return mapResponse(clientImpl.getRandomBytesWithResponse(new GetRandomBytesRequest(count), requestContext), + RandomBytes::getValue); } /** @@ -2023,14 +1875,10 @@ public Response getRandomBytesWithResponse(int count, RequestContext req @ServiceMethod(returns = ReturnType.SINGLE) public ReleaseKeyResult releaseKey(String name, String targetAttestationToken) { if (isNullOrEmpty(name)) { - throw LOGGER.logThrowableAsError(new IllegalArgumentException("'name' cannot be null or empty.")); + throw LOGGER.throwableAtError().log("'name' cannot be null or empty.", IllegalArgumentException::new); } - try { - return clientImpl.release(name, "", new KeyReleaseParameters(targetAttestationToken)); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } + return clientImpl.release(name, "", new KeyReleaseParameters(targetAttestationToken)); } /** @@ -2063,14 +1911,10 @@ public ReleaseKeyResult releaseKey(String name, String targetAttestationToken) { @ServiceMethod(returns = ReturnType.SINGLE) public ReleaseKeyResult releaseKey(String name, String version, String targetAttestationToken) { if (isNullOrEmpty(name)) { - throw LOGGER.logThrowableAsError(new IllegalArgumentException("'name' cannot be null or empty.")); + throw LOGGER.throwableAtError().log("'name' cannot be null or empty.", IllegalArgumentException::new); } - try { - return clientImpl.release(name, version, new KeyReleaseParameters(targetAttestationToken)); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } + return clientImpl.release(name, version, new KeyReleaseParameters(targetAttestationToken)); } /** @@ -2116,18 +1960,14 @@ public Response releaseKeyWithResponse(String name, String ver ReleaseKeyOptions releaseKeyOptions, RequestContext requestContext) { if (isNullOrEmpty(name)) { - throw LOGGER.logThrowableAsError(new IllegalArgumentException("'name' cannot be null or empty.")); + throw LOGGER.throwableAtError().log("'name' cannot be null or empty.", IllegalArgumentException::new); } - try { - KeyReleaseParameters keyReleaseParameters = new KeyReleaseParameters(targetAttestationToken) - .setEnc(releaseKeyOptions == null ? null : releaseKeyOptions.getAlgorithm()) - .setNonce(releaseKeyOptions == null ? null : releaseKeyOptions.getNonce()); + KeyReleaseParameters keyReleaseParameters = new KeyReleaseParameters(targetAttestationToken) + .setEnc(releaseKeyOptions == null ? null : releaseKeyOptions.getAlgorithm()) + .setNonce(releaseKeyOptions == null ? null : releaseKeyOptions.getNonce()); - return clientImpl.releaseWithResponse(name, version, keyReleaseParameters, requestContext); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } + return clientImpl.releaseWithResponse(name, version, keyReleaseParameters, requestContext); } /** @@ -2154,14 +1994,10 @@ public Response releaseKeyWithResponse(String name, String ver @ServiceMethod(returns = ReturnType.SINGLE) public KeyVaultKey rotateKey(String name) { if (isNullOrEmpty(name)) { - throw LOGGER.logThrowableAsError(new IllegalArgumentException("'name' cannot be null or empty.")); + throw LOGGER.throwableAtError().log("'name' cannot be null or empty.", IllegalArgumentException::new); } - try { - return createKeyVaultKey(clientImpl.rotateKey(name)); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } + return createKeyVaultKey(clientImpl.rotateKey(name)); } /** @@ -2193,15 +2029,11 @@ public KeyVaultKey rotateKey(String name) { @ServiceMethod(returns = ReturnType.SINGLE) public Response rotateKeyWithResponse(String name, RequestContext requestContext) { if (isNullOrEmpty(name)) { - throw LOGGER.logThrowableAsError(new IllegalArgumentException("'name' cannot be null or empty.")); + throw LOGGER.throwableAtError().log("'name' cannot be null or empty.", IllegalArgumentException::new); } - try { - return mapResponse(clientImpl.rotateKeyWithResponse(name, requestContext), - KeyVaultKeysModelsUtils::createKeyVaultKey); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } + return mapResponse(clientImpl.rotateKeyWithResponse(name, requestContext), + KeyVaultKeysModelsUtils::createKeyVaultKey); } /** @@ -2226,14 +2058,10 @@ public Response rotateKeyWithResponse(String name, RequestContext r @ServiceMethod(returns = ReturnType.SINGLE) public KeyRotationPolicy getKeyRotationPolicy(String keyName) { if (isNullOrEmpty(keyName)) { - throw LOGGER.logThrowableAsError(new IllegalArgumentException("'keyName' cannot be null or empty.")); + throw LOGGER.throwableAtError().log("'keyName' cannot be null or empty.", IllegalArgumentException::new); } - try { - return mapKeyRotationPolicyImpl(clientImpl.getKeyRotationPolicy(keyName)); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } + return mapKeyRotationPolicyImpl(clientImpl.getKeyRotationPolicy(keyName)); } /** @@ -2266,15 +2094,11 @@ public KeyRotationPolicy getKeyRotationPolicy(String keyName) { @ServiceMethod(returns = ReturnType.SINGLE) public Response getKeyRotationPolicyWithResponse(String keyName, RequestContext requestContext) { if (isNullOrEmpty(keyName)) { - throw LOGGER.logThrowableAsError(new IllegalArgumentException("'keyName' cannot be null or empty.")); + throw LOGGER.throwableAtError().log("'keyName' cannot be null or empty.", IllegalArgumentException::new); } - try { - return mapResponse(clientImpl.getKeyRotationPolicyWithResponse(keyName, requestContext), - KeyVaultKeysModelsUtils::mapKeyRotationPolicyImpl); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } + return mapResponse(clientImpl.getKeyRotationPolicyWithResponse(keyName, requestContext), + KeyVaultKeysModelsUtils::mapKeyRotationPolicyImpl); } /** @@ -2314,15 +2138,11 @@ public Response getKeyRotationPolicyWithResponse(String keyNa @ServiceMethod(returns = ReturnType.SINGLE) public KeyRotationPolicy updateKeyRotationPolicy(String keyName, KeyRotationPolicy keyRotationPolicy) { if (isNullOrEmpty(keyName)) { - throw LOGGER.logThrowableAsError(new IllegalArgumentException("'keyName' cannot be null or empty.")); + throw LOGGER.throwableAtError().log("'keyName' cannot be null or empty.", IllegalArgumentException::new); } - try { - return mapKeyRotationPolicyImpl( - clientImpl.updateKeyRotationPolicy(keyName, mapKeyRotationPolicy(keyRotationPolicy))); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } + return mapKeyRotationPolicyImpl( + clientImpl.updateKeyRotationPolicy(keyName, mapKeyRotationPolicy(keyRotationPolicy))); } /** @@ -2370,16 +2190,12 @@ public Response updateKeyRotationPolicyWithResponse(String ke KeyRotationPolicy keyRotationPolicy, RequestContext requestContext) { if (isNullOrEmpty(keyName)) { - throw LOGGER.logThrowableAsError(new IllegalArgumentException("'keyName' cannot be null or empty.")); + throw LOGGER.throwableAtError().log("'keyName' cannot be null or empty.", IllegalArgumentException::new); } - try { - return mapResponse(clientImpl.updateKeyRotationPolicyWithResponse(keyName, - mapKeyRotationPolicy(keyRotationPolicy), requestContext), - KeyVaultKeysModelsUtils::mapKeyRotationPolicyImpl); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } + return mapResponse(clientImpl.updateKeyRotationPolicyWithResponse(keyName, + mapKeyRotationPolicy(keyRotationPolicy), requestContext), + KeyVaultKeysModelsUtils::mapKeyRotationPolicyImpl); } private static Response mapResponse(Responseresponse, Function mapper) { diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/KeyClientBuilder.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/KeyClientBuilder.java index d848833ffd98..2379bd6a417c 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/KeyClientBuilder.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/KeyClientBuilder.java @@ -35,6 +35,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import static io.clientcore.core.utils.CoreUtils.isNullOrEmpty; @@ -129,17 +130,19 @@ public KeyClient buildClient() { String endpoint = getEndpoint(configuration); if (endpoint == null) { - throw LOGGER.logThrowableAsError(new IllegalStateException( - "An Azure Key Vault or Managed HSM endpoint is required. You can set one by using the" + throw LOGGER.throwableAtError() + .log("An Azure Key Vault or Managed HSM endpoint is required. You can set one by using the" + " KeyClientBuilder.endpoint() method or by setting the environment variable" - + " 'AZURE_KEYVAULT_ENDPOINT'.")); + + " 'AZURE_KEYVAULT_ENDPOINT'.", IllegalStateException::new); } KeyServiceVersion version = this.version == null ? KeyServiceVersion.getLatest() : this.version; if (credential == null) { - throw LOGGER.logThrowableAsError(new IllegalStateException( - "A credential object is required. You can set one by using the KeyClientBuilder.credential() method.")); + throw LOGGER.throwableAtError() + .log( + "A credential object is required. You can set one by using the KeyClientBuilder.credential() method.", + IllegalStateException::new); } // Closest to API goes first, closest to wire goes last. @@ -186,16 +189,14 @@ public KeyClient buildClient() { */ @Override public KeyClientBuilder endpoint(String endpoint) { - if (endpoint == null) { - throw LOGGER.logThrowableAsError(new NullPointerException("'endpoint' cannot be null.")); - } + Objects.requireNonNull(endpoint, "'endpoint' cannot be null."); try { URI uri = new URI(endpoint); this.endpoint = uri.toString(); } catch (URISyntaxException e) { - throw LOGGER - .logThrowableAsError(new IllegalArgumentException("The Azure Key Vault endpoint is malformed.", e)); + throw LOGGER.throwableAtError() + .log("The Azure Key Vault endpoint is malformed.", e, IllegalArgumentException::new); } return this; @@ -213,9 +214,7 @@ public KeyClientBuilder endpoint(String endpoint) { */ @Override public KeyClientBuilder credential(TokenCredential credential) { - if (credential == null) { - throw LOGGER.logThrowableAsError(new NullPointerException("'credential' cannot be null.")); - } + Objects.requireNonNull(credential, "'credential' cannot be null."); this.credential = credential; @@ -260,10 +259,7 @@ public KeyClientBuilder httpInstrumentationOptions(HttpInstrumentationOptions in */ @Override public KeyClientBuilder addHttpPipelinePolicy(HttpPipelinePolicy pipelinePolicy) { - if (pipelinePolicy == null) { - throw LOGGER.logThrowableAsError(new NullPointerException("'pipelinePolicy' cannot be null.")); - } - + Objects.requireNonNull(pipelinePolicy, "'pipelinePolicy' cannot be null."); pipelinePolicies.add(pipelinePolicy); return this; diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/CryptographyClient.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/CryptographyClient.java index e8065b88b406..6ab28bf1f67a 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/CryptographyClient.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/CryptographyClient.java @@ -27,15 +27,12 @@ import io.clientcore.core.http.models.HttpResponseException; import io.clientcore.core.http.models.RequestContext; import io.clientcore.core.http.models.Response; +import io.clientcore.core.implementation.http.RetryUtils; import io.clientcore.core.instrumentation.logging.ClientLogger; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.security.NoSuchAlgorithmException; import java.util.Objects; import static com.azure.v2.security.keyvault.keys.cryptography.implementation.CryptographyUtils.createLocalClient; -import static com.azure.v2.security.keyvault.keys.cryptography.implementation.CryptographyUtils.isThrowableRetryable; import static com.azure.v2.security.keyvault.keys.cryptography.implementation.CryptographyUtils.retrieveJwkAndCreateLocalClient; /** @@ -163,27 +160,25 @@ public class CryptographyClient { * operations or key type properties is not configured. */ CryptographyClient(JsonWebKey jsonWebKey) { - try { - Objects.requireNonNull(jsonWebKey, "The JSON Web Key is required."); + Objects.requireNonNull(jsonWebKey, "The JSON Web Key is required."); - if (!jsonWebKey.isValid()) { - throw new IllegalArgumentException("The JSON Web Key is not valid."); - } - - if (jsonWebKey.getKeyOps() == null) { - throw new IllegalArgumentException("The JSON Web Key's key operations property is not configured."); - } + if (!jsonWebKey.isValid()) { + throw LOGGER.throwableAtError().log("The JSON Web Key is not valid.", IllegalArgumentException::new); + } - if (jsonWebKey.getKeyType() == null) { - throw new IllegalArgumentException("The JSON Web Key's key type property is not configured."); - } + if (jsonWebKey.getKeyOps() == null) { + throw LOGGER.throwableAtError() + .log("The JSON Web Key's key operations property is not configured.", IllegalArgumentException::new); + } - this.clientImpl = null; - this.keyId = jsonWebKey.getId(); - this.localKeyCryptographyClient = createLocalClient(jsonWebKey, null); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); + if (jsonWebKey.getKeyType() == null) { + throw LOGGER.throwableAtError() + .log("The JSON Web Key's key type property is not configured.", IllegalArgumentException::new); } + + this.clientImpl = null; + this.keyId = jsonWebKey.getId(); + this.localKeyCryptographyClient = createLocalClient(jsonWebKey, null, LOGGER); } /** @@ -241,14 +236,10 @@ public KeyVaultKey getKey() { @ServiceMethod(returns = ReturnType.SINGLE) public Response getKeyWithResponse(RequestContext requestContext) { if (clientImpl != null) { - try { - return clientImpl.getKeyWithResponse(requestContext); - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } + return clientImpl.getKeyWithResponse(requestContext); } else { - throw LOGGER.logThrowableAsError( - new UnsupportedOperationException("Operation not supported when operating in local-only mode.")); + throw LOGGER.throwableAtError() + .log("Operation not supported when operating in local-only mode.", UnsupportedOperationException::new); } } @@ -308,16 +299,10 @@ public Response getKeyWithResponse(RequestContext requestContext) { */ @ServiceMethod(returns = ReturnType.SINGLE) public EncryptResult encrypt(EncryptionAlgorithm algorithm, byte[] plaintext) { - try { - if (isLocalClientAvailable()) { - return localKeyCryptographyClient.encrypt(algorithm, plaintext, RequestContext.none()); - } else { - return clientImpl.encrypt(algorithm, plaintext); - } - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } catch (IOException e) { - throw LOGGER.logThrowableAsError(new UncheckedIOException(e)); + if (isLocalClientAvailable()) { + return localKeyCryptographyClient.encrypt(algorithm, plaintext, RequestContext.none()); + } else { + return clientImpl.encrypt(algorithm, plaintext); } } @@ -387,16 +372,10 @@ public EncryptResult encrypt(EncryptionAlgorithm algorithm, byte[] plaintext) { */ @ServiceMethod(returns = ReturnType.SINGLE) public EncryptResult encrypt(EncryptParameters encryptParameters, RequestContext requestContext) { - try { - if (isLocalClientAvailable()) { - return localKeyCryptographyClient.encrypt(encryptParameters, requestContext); - } else { - return clientImpl.encrypt(encryptParameters, requestContext); - } - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } catch (IOException e) { - throw LOGGER.logThrowableAsError(new UncheckedIOException(e)); + if (isLocalClientAvailable()) { + return localKeyCryptographyClient.encrypt(encryptParameters, requestContext); + } else { + return clientImpl.encrypt(encryptParameters, requestContext); } } @@ -457,16 +436,10 @@ public EncryptResult encrypt(EncryptParameters encryptParameters, RequestContext */ @ServiceMethod(returns = ReturnType.SINGLE) public DecryptResult decrypt(EncryptionAlgorithm algorithm, byte[] ciphertext) { - try { - if (isLocalClientAvailable()) { - return localKeyCryptographyClient.decrypt(algorithm, ciphertext, RequestContext.none()); - } else { - return clientImpl.decrypt(algorithm, ciphertext, RequestContext.none()); - } - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } catch (IOException e) { - throw LOGGER.logThrowableAsError(new UncheckedIOException(e)); + if (isLocalClientAvailable()) { + return localKeyCryptographyClient.decrypt(algorithm, ciphertext, RequestContext.none()); + } else { + return clientImpl.decrypt(algorithm, ciphertext, RequestContext.none()); } } @@ -537,16 +510,10 @@ public DecryptResult decrypt(EncryptionAlgorithm algorithm, byte[] ciphertext) { */ @ServiceMethod(returns = ReturnType.SINGLE) public DecryptResult decrypt(DecryptParameters decryptParameters, RequestContext requestContext) { - try { - if (isLocalClientAvailable()) { - return localKeyCryptographyClient.decrypt(decryptParameters, requestContext); - } else { - return clientImpl.decrypt(decryptParameters, requestContext); - } - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } catch (IOException e) { - throw LOGGER.logThrowableAsError(new UncheckedIOException(e)); + if (isLocalClientAvailable()) { + return localKeyCryptographyClient.decrypt(decryptParameters, requestContext); + } else { + return clientImpl.decrypt(decryptParameters, requestContext); } } @@ -598,16 +565,10 @@ public DecryptResult decrypt(DecryptParameters decryptParameters, RequestContext */ @ServiceMethod(returns = ReturnType.SINGLE) public SignResult sign(SignatureAlgorithm algorithm, byte[] digest) { - try { - if (isLocalClientAvailable()) { - return localKeyCryptographyClient.sign(algorithm, digest, RequestContext.none()); - } else { - return clientImpl.sign(algorithm, digest, RequestContext.none()); - } - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } catch (IOException e) { - throw LOGGER.logThrowableAsError(new UncheckedIOException(e)); + if (isLocalClientAvailable()) { + return localKeyCryptographyClient.sign(algorithm, digest, RequestContext.none()); + } else { + return clientImpl.sign(algorithm, digest, RequestContext.none()); } } @@ -665,16 +626,10 @@ public SignResult sign(SignatureAlgorithm algorithm, byte[] digest) { */ @ServiceMethod(returns = ReturnType.SINGLE) public SignResult sign(SignatureAlgorithm algorithm, byte[] digest, RequestContext requestContext) { - try { - if (isLocalClientAvailable()) { - return localKeyCryptographyClient.sign(algorithm, digest, requestContext); - } else { - return clientImpl.sign(algorithm, digest, requestContext); - } - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } catch (IOException e) { - throw LOGGER.logThrowableAsError(new UncheckedIOException(e)); + if (isLocalClientAvailable()) { + return localKeyCryptographyClient.sign(algorithm, digest, requestContext); + } else { + return clientImpl.sign(algorithm, digest, requestContext); } } @@ -786,16 +741,10 @@ public VerifyResult verify(SignatureAlgorithm algorithm, byte[] digest, byte[] s @ServiceMethod(returns = ReturnType.SINGLE) public VerifyResult verify(SignatureAlgorithm algorithm, byte[] digest, byte[] signature, RequestContext requestContext) { - try { - if (isLocalClientAvailable()) { - return localKeyCryptographyClient.verify(algorithm, digest, signature, requestContext); - } else { - return clientImpl.verify(algorithm, digest, signature, requestContext); - } - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } catch (IOException e) { - throw LOGGER.logThrowableAsError(new UncheckedIOException(e)); + if (isLocalClientAvailable()) { + return localKeyCryptographyClient.verify(algorithm, digest, signature, requestContext); + } else { + return clientImpl.verify(algorithm, digest, signature, requestContext); } } @@ -899,16 +848,10 @@ public WrapResult wrapKey(KeyWrapAlgorithm algorithm, byte[] key) { */ @ServiceMethod(returns = ReturnType.SINGLE) public WrapResult wrapKey(KeyWrapAlgorithm algorithm, byte[] key, RequestContext requestContext) { - try { - if (isLocalClientAvailable()) { - return localKeyCryptographyClient.wrapKey(algorithm, key, requestContext); - } else { - return clientImpl.wrapKey(algorithm, key, requestContext); - } - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } catch (IOException e) { - throw LOGGER.logThrowableAsError(new UncheckedIOException(e)); + if (isLocalClientAvailable()) { + return localKeyCryptographyClient.wrapKey(algorithm, key, requestContext); + } else { + return clientImpl.wrapKey(algorithm, key, requestContext); } } @@ -1015,16 +958,10 @@ public UnwrapResult unwrapKey(KeyWrapAlgorithm algorithm, byte[] encryptedKey) { */ @ServiceMethod(returns = ReturnType.SINGLE) public UnwrapResult unwrapKey(KeyWrapAlgorithm algorithm, byte[] encryptedKey, RequestContext requestContext) { - try { - if (isLocalClientAvailable()) { - return localKeyCryptographyClient.unwrapKey(algorithm, encryptedKey, requestContext); - } else { - return clientImpl.unwrapKey(algorithm, encryptedKey, requestContext); - } - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } catch (IOException e) { - throw LOGGER.logThrowableAsError(new UncheckedIOException(e)); + if (isLocalClientAvailable()) { + return localKeyCryptographyClient.unwrapKey(algorithm, encryptedKey, requestContext); + } else { + return clientImpl.unwrapKey(algorithm, encryptedKey, requestContext); } } @@ -1126,18 +1063,10 @@ public SignResult signData(SignatureAlgorithm algorithm, byte[] data) { */ @ServiceMethod(returns = ReturnType.SINGLE) public SignResult signData(SignatureAlgorithm algorithm, byte[] data, RequestContext requestContext) { - try { - if (isLocalClientAvailable()) { - return localKeyCryptographyClient.signData(algorithm, data, requestContext); - } else { - return clientImpl.signData(algorithm, data, requestContext); - } - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } catch (IOException e) { - throw LOGGER.logThrowableAsError(new UncheckedIOException(e)); - } catch (NoSuchAlgorithmException e) { - throw LOGGER.logThrowableAsError(new RuntimeException(e)); + if (isLocalClientAvailable()) { + return localKeyCryptographyClient.signData(algorithm, data, requestContext); + } else { + return clientImpl.signData(algorithm, data, requestContext); } } @@ -1241,27 +1170,19 @@ public VerifyResult verifyData(SignatureAlgorithm algorithm, byte[] data, byte[] @ServiceMethod(returns = ReturnType.SINGLE) public VerifyResult verifyData(SignatureAlgorithm algorithm, byte[] data, byte[] signature, RequestContext requestContext) { - try { - if (isLocalClientAvailable()) { - return localKeyCryptographyClient.verifyData(algorithm, data, signature, requestContext); - } else { - return clientImpl.verifyData(algorithm, data, signature, requestContext); - } - } catch (RuntimeException e) { - throw LOGGER.logThrowableAsError(e); - } catch (IOException e) { - throw LOGGER.logThrowableAsError(new UncheckedIOException(e)); - } catch (NoSuchAlgorithmException e) { - throw LOGGER.logThrowableAsError(new RuntimeException(e)); + if (isLocalClientAvailable()) { + return localKeyCryptographyClient.verifyData(algorithm, data, signature, requestContext); + } else { + return clientImpl.verifyData(algorithm, data, signature, requestContext); } } private boolean isLocalClientAvailable() { if (!skipLocalClientCreation && localKeyCryptographyClient == null) { try { - localKeyCryptographyClient = retrieveJwkAndCreateLocalClient(clientImpl); - } catch (Throwable t) { - if (isThrowableRetryable(t)) { + localKeyCryptographyClient = retrieveJwkAndCreateLocalClient(clientImpl, LOGGER); + } catch (RuntimeException t) { + if (RetryUtils.isRetryable(t)) { LOGGER.atVerbose() .setThrowable(t) .log("Could not set up local cryptography for this operation. Defaulting to service-side " diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/CryptographyClientBuilder.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/CryptographyClientBuilder.java index 8973a5de96b2..4fb746442b27 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/CryptographyClientBuilder.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/CryptographyClientBuilder.java @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import static io.clientcore.core.utils.CoreUtils.isNullOrEmpty; @@ -148,25 +149,27 @@ public CryptographyClientBuilder() { public CryptographyClient buildClient() { if (jsonWebKey != null) { if (isKeyCachingDisabled) { - throw LOGGER.logThrowableAsError( - new IllegalStateException("Key caching cannot be disabled when using a JSON Web Key.")); + throw LOGGER.throwableAtError() + .log("Key caching cannot be disabled when using a JSON Web Key.", IllegalStateException::new); } return new CryptographyClient(jsonWebKey); } if (isNullOrEmpty(keyId)) { - throw LOGGER.logThrowableAsError(new IllegalStateException( - "An Azure Key Vault or Managed HSM key identifier is required to build the cryptography client if a" - + " JSON Web Key is not provided.")); + throw LOGGER.throwableAtError() + .log( + "An Azure Key Vault or Managed HSM key identifier is required to build the cryptography client if a" + + " JSON Web Key is not provided.", + IllegalStateException::new); } CryptographyServiceVersion serviceVersion = version != null ? version : CryptographyServiceVersion.getLatest(); if (credential == null) { - throw LOGGER.logThrowableAsError( - new IllegalStateException("A credential object is required. You can set one by using the" - + " CryptographyClientBuilder.credential() method.")); + throw LOGGER.throwableAtError() + .log("A credential object is required. You can set one by using the" + + " CryptographyClientBuilder.credential() method.", IllegalArgumentException::new); } // Closest to API goes first, closest to wire goes last. @@ -225,7 +228,7 @@ CryptographyServiceVersion getServiceVersion() { */ public CryptographyClientBuilder keyIdentifier(String keyId) { if (isNullOrEmpty(keyId)) { - throw LOGGER.logThrowableAsError(new IllegalArgumentException("'keyId' cannot be null or empty.")); + throw LOGGER.throwableAtError().log("'keyId' cannot be null or empty.", IllegalArgumentException::new); } this.keyId = keyId; @@ -245,10 +248,7 @@ public CryptographyClientBuilder keyIdentifier(String keyId) { */ @Override public CryptographyClientBuilder credential(TokenCredential credential) { - if (credential == null) { - throw LOGGER.logThrowableAsError(new NullPointerException("'credential' cannot be null.")); - } - + Objects.requireNonNull(credential, "'credential' cannot be null."); this.credential = credential; return this; @@ -266,10 +266,7 @@ public CryptographyClientBuilder credential(TokenCredential credential) { * @throws NullPointerException If {@code jsonWebKey} is {@code null}. */ public CryptographyClientBuilder jsonWebKey(JsonWebKey jsonWebKey) { - if (jsonWebKey == null) { - throw LOGGER.logThrowableAsError(new NullPointerException("'jsonWebKey' must not be null.")); - } - + Objects.requireNonNull(jsonWebKey, "'jsonWebKey' cannot be null."); this.jsonWebKey = jsonWebKey; return this; @@ -313,10 +310,7 @@ public CryptographyClientBuilder httpInstrumentationOptions(HttpInstrumentationO */ @Override public CryptographyClientBuilder addHttpPipelinePolicy(HttpPipelinePolicy pipelinePolicy) { - if (pipelinePolicy == null) { - throw LOGGER.logThrowableAsError(new NullPointerException("'pipelinePolicy' cannot be null.")); - } - + Objects.requireNonNull(pipelinePolicy, "'pipelinePolicy' cannot be null."); pipelinePolicies.add(pipelinePolicy); return this; diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes128Kw.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes128Kw.java index b7c08efec85b..48d689f3d99c 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes128Kw.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes128Kw.java @@ -3,6 +3,8 @@ package com.azure.v2.security.keyvault.keys.cryptography.implementation; +import io.clientcore.core.instrumentation.logging.ClientLogger; + import javax.crypto.NoSuchPaddingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -11,6 +13,7 @@ import java.util.Arrays; class Aes128Kw extends AesKw { + private static final ClientLogger LOGGER = new ClientLogger(Aes128Kw.class); public static final String ALGORITHM_NAME = "A128KW"; static final int KEY_SIZE_IN_BYTES = 128 >> 3; @@ -23,7 +26,7 @@ class Aes128Kw extends AesKw { public ICryptoTransform createEncryptor(byte[] key, byte[] iv, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException { - CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES); + CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES, LOGGER); return super.createEncryptor(Arrays.copyOfRange(key, 0, KEY_SIZE_IN_BYTES), iv, provider); } @@ -32,7 +35,7 @@ public ICryptoTransform createEncryptor(byte[] key, byte[] iv, Provider provider public ICryptoTransform createDecryptor(byte[] key, byte[] iv, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException { - CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES); + CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES, LOGGER); return super.createDecryptor(Arrays.copyOfRange(key, 0, KEY_SIZE_IN_BYTES), iv, provider); } diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes192Kw.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes192Kw.java index 7c3635adb763..909250236e79 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes192Kw.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes192Kw.java @@ -3,6 +3,8 @@ package com.azure.v2.security.keyvault.keys.cryptography.implementation; +import io.clientcore.core.instrumentation.logging.ClientLogger; + import javax.crypto.NoSuchPaddingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -11,6 +13,7 @@ import java.util.Arrays; class Aes192Kw extends AesKw { + private static final ClientLogger LOGGER = new ClientLogger(Aes192Kw.class); public static final String ALGORITHM_NAME = "A192KW"; static final int KEY_SIZE_IN_BYTES = 192 >> 3; @@ -23,7 +26,7 @@ class Aes192Kw extends AesKw { public ICryptoTransform createEncryptor(byte[] key, byte[] iv, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException { - CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES); + CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES, LOGGER); return super.createEncryptor(Arrays.copyOfRange(key, 0, KEY_SIZE_IN_BYTES), iv, provider); } @@ -32,7 +35,7 @@ public ICryptoTransform createEncryptor(byte[] key, byte[] iv, Provider provider public ICryptoTransform createDecryptor(byte[] key, byte[] iv, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException { - CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES); + CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES, LOGGER); return super.createDecryptor(Arrays.copyOfRange(key, 0, KEY_SIZE_IN_BYTES), iv, provider); } diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes256Kw.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes256Kw.java index c724743de6c7..b76ef6f58e10 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes256Kw.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Aes256Kw.java @@ -3,6 +3,8 @@ package com.azure.v2.security.keyvault.keys.cryptography.implementation; +import io.clientcore.core.instrumentation.logging.ClientLogger; + import javax.crypto.NoSuchPaddingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -11,6 +13,7 @@ import java.util.Arrays; class Aes256Kw extends AesKw { + private static final ClientLogger LOGGER = new ClientLogger(Aes256Kw.class); public static final String ALGORITHM_NAME = "A256KW"; static final int KEY_SIZE_IN_BYTES = 256 >> 3; @@ -23,7 +26,7 @@ class Aes256Kw extends AesKw { public ICryptoTransform createEncryptor(byte[] key, byte[] iv, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException { - CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES); + CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES, LOGGER); return super.createEncryptor(Arrays.copyOfRange(key, 0, KEY_SIZE_IN_BYTES), iv, provider); } @@ -32,7 +35,7 @@ public ICryptoTransform createEncryptor(byte[] key, byte[] iv, Provider provider public ICryptoTransform createDecryptor(byte[] key, byte[] iv, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException { - CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES); + CryptographyUtils.validate(key, KEY_SIZE_IN_BYTES, LOGGER); return super.createDecryptor(Arrays.copyOfRange(key, 0, KEY_SIZE_IN_BYTES), iv, provider); } diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbc.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbc.java index 4cbe5186afae..0e9870decd71 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbc.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbc.java @@ -3,6 +3,8 @@ package com.azure.v2.security.keyvault.keys.cryptography.implementation; +import io.clientcore.core.instrumentation.logging.ClientLogger; + import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; @@ -16,6 +18,7 @@ import java.util.Arrays; abstract class AesCbc extends SymmetricEncryptionAlgorithm { + private static final ClientLogger LOGGER = new ClientLogger(AesCbc.class); final int keySizeInBytes; final int keySize; @@ -40,7 +43,10 @@ public ICryptoTransform createEncryptor(byte[] key, byte[] iv, byte[] additional NoSuchPaddingException, InvalidAlgorithmParameterException { if (key == null || key.length < keySizeInBytes) { - throw new InvalidKeyException("Key must be at least " + keySize + " bits in length."); + throw LOGGER.throwableAtError() + .addKeyValue("actualSize", key == null ? 0 : key.length) + .addKeyValue("expectedSize", keySizeInBytes) + .log("Key is too short.", InvalidKeyException::new); } return new AesCbcEncryptor(Arrays.copyOfRange(key, 0, keySizeInBytes), iv, provider); @@ -60,7 +66,10 @@ public ICryptoTransform createDecryptor(byte[] key, byte[] iv, byte[] additional NoSuchPaddingException, InvalidAlgorithmParameterException { if (key == null || key.length < keySizeInBytes) { - throw new InvalidKeyException("Key must be at least " + keySize + " bits in length."); + throw LOGGER.throwableAtError() + .addKeyValue("actualSize", key == null ? 0 : key.length) + .addKeyValue("expectedSize", keySizeInBytes) + .log("Key is too short.", InvalidKeyException::new); } return new AesCbcDecryptor(Arrays.copyOfRange(key, 0, keySizeInBytes), iv, provider); diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbcHmacSha2.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbcHmacSha2.java index 996d19e7597b..1eb765501884 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbcHmacSha2.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbcHmacSha2.java @@ -4,6 +4,7 @@ package com.azure.v2.security.keyvault.keys.cryptography.implementation; import io.clientcore.core.instrumentation.logging.ClientLogger; +import io.clientcore.core.models.CoreException; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; @@ -18,6 +19,7 @@ abstract class AesCbcHmacSha2 extends SymmetricEncryptionAlgorithm { private static final long BYTE_TO_BITS = 8L; + private static final ClientLogger LOGGER = new ClientLogger(AesCbcHmacSha2.class); abstract static class AbstractAesCbcHmacSha2CryptoTransform implements IAuthenticatedCryptoTransform { byte[] tag; @@ -63,8 +65,10 @@ private Triplet getAlgorithmParameters(String algorithm, by if (algorithm.equalsIgnoreCase(Aes128CbcHmacSha256.ALGORITHM_NAME)) { if ((key.length << 3) < 256) { - throw new IllegalArgumentException( - String.format("%s key length in bits %d < 256", algorithm, key.length << 3)); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm) + .addKeyValue("keyLengthInBits", key.length << 3) + .log("Key is too short, must be at least 256.", IllegalArgumentException::new); } hmacKey = new byte[128 >> 3]; @@ -78,8 +82,10 @@ private Triplet getAlgorithmParameters(String algorithm, by hmac.init(new SecretKeySpec(hmacKey, "HmacSHA256")); } else if (algorithm.equalsIgnoreCase(Aes192CbcHmacSha384.ALGORITHM_NAME)) { if ((key.length << 3) < 384) { - throw new IllegalArgumentException( - String.format("%s key length in bits %d < 384", algorithm, key.length << 3)); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm) + .addKeyValue("keyLengthInBits", key.length << 3) + .log("Key is too short, must be at least 384.", IllegalArgumentException::new); } hmacKey = new byte[192 >> 3]; @@ -93,8 +99,10 @@ private Triplet getAlgorithmParameters(String algorithm, by hmac.init(new SecretKeySpec(hmacKey, "HmacSHA384")); } else if (algorithm.equalsIgnoreCase(Aes256CbcHmacSha512.ALGORITHM_NAME)) { if ((key.length << 3) < 512) { - throw new IllegalArgumentException( - String.format("%s key length in bits %d < 512", algorithm, key.length << 3)); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm) + .addKeyValue("keyLengthInBits", key.length << 3) + .log("Key is too short, must be at least 512.", IllegalArgumentException::new); } hmacKey = new byte[256 >> 3]; @@ -107,7 +115,9 @@ private Triplet getAlgorithmParameters(String algorithm, by hmac = Mac.getInstance("HmacSHA512"); hmac.init(new SecretKeySpec(hmacKey, "HmacSHA512")); } else { - throw new IllegalArgumentException(String.format("Unsupported algorithm: %s", algorithm)); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm) + .log("Unsupported algorithm.", IllegalArgumentException::new); } return new Triplet<>(aesKey, hmacKey, hmac); @@ -143,13 +153,30 @@ public byte[] doFinal(byte[] input) System.arraycopy(hash, 0, tag, 0, hmacKey.length); // Check the tag before performing the final decrypt - if (!CryptographyUtils.sequenceEqualConstantTime(tag, tag)) { - throw LOGGER.logThrowableAsWarning(new IllegalArgumentException("Data is not authentic")); + if (!sequenceEqualConstantTime(tag, tag)) { + throw LOGGER.throwableAtError().log("Data is not authentic", CoreException::from); } return inner.doFinal(input); } + /** + * Compares two byte arrays in constant time. + * + * @param self The first byte array to compare. + * @param other The second byte array to compare. + * @return True if the two byte arrays are equal. + */ + static boolean sequenceEqualConstantTime(byte[] self, byte[] other) { + // Constant time comparison of two byte arrays + long difference = (self.length & 0xffffffffL) ^ (other.length & 0xffffffffL); + + for (int i = 0; i < self.length && i < other.length; i++) { + difference |= (self[i] ^ other[i]) & 0xffffffffL; + } + + return difference == 0; + } } static class AesCbcHmacSha2Encryptor extends AbstractAesCbcHmacSha2CryptoTransform { @@ -199,19 +226,19 @@ public ICryptoTransform createDecryptor(byte[] key, byte[] iv, byte[] additional byte[] authenticationTag, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException { if (key == null) { - throw new IllegalArgumentException("No key material."); + throw LOGGER.throwableAtError().log("No key material.", IllegalArgumentException::new); } if (iv == null) { - throw new IllegalArgumentException("No initialization vector."); + throw LOGGER.throwableAtError().log("No initialization vector.", IllegalArgumentException::new); } if (additionalAuthenticatedData == null) { - throw new IllegalArgumentException("No authentication data."); + throw LOGGER.throwableAtError().log("No authentication data.", IllegalArgumentException::new); } if (authenticationTag == null) { - throw new IllegalArgumentException("No authentication tag."); + throw LOGGER.throwableAtError().log("No authentication tag.", IllegalArgumentException::new); } // Create the Decryptor. @@ -233,15 +260,15 @@ public ICryptoTransform createEncryptor(byte[] key, byte[] iv, byte[] additional NoSuchPaddingException, InvalidAlgorithmParameterException { if (key == null) { - throw new IllegalArgumentException("No key material"); + throw LOGGER.throwableAtError().log("No key material.", IllegalArgumentException::new); } if (iv == null) { - throw new IllegalArgumentException("No initialization vector"); + throw LOGGER.throwableAtError().log("No initialization vector.", IllegalArgumentException::new); } if (additionalAuthenticatedData == null) { - throw new IllegalArgumentException("No authentication data"); + throw LOGGER.throwableAtError().log("No authentication data.", IllegalArgumentException::new); } // Create the Encryptor. diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbcPad.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbcPad.java index 3ffdeebbbcb3..d004faefe56e 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbcPad.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesCbcPad.java @@ -3,6 +3,8 @@ package com.azure.v2.security.keyvault.keys.cryptography.implementation; +import io.clientcore.core.instrumentation.logging.ClientLogger; + import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; @@ -16,6 +18,7 @@ import java.util.Arrays; abstract class AesCbcPad extends SymmetricEncryptionAlgorithm { + private static final ClientLogger LOGGER = new ClientLogger(AesCbcPad.class); final int keySizeInBytes; final int keySize; @@ -40,7 +43,10 @@ public ICryptoTransform createEncryptor(byte[] key, byte[] iv, byte[] additional NoSuchPaddingException, InvalidAlgorithmParameterException { if (key == null || key.length < keySizeInBytes) { - throw new InvalidKeyException("key must be at least " + keySize + " bits in length"); + throw LOGGER.throwableAtError() + .addKeyValue("actualSize", key == null ? 0 : key.length) + .addKeyValue("expectedSize", keySizeInBytes) + .log("Key is too short.", InvalidKeyException::new); } return new AesCbcPadEncryptor(Arrays.copyOfRange(key, 0, keySizeInBytes), iv, provider); @@ -60,7 +66,10 @@ public ICryptoTransform createDecryptor(byte[] key, byte[] iv, byte[] additional NoSuchPaddingException, InvalidAlgorithmParameterException { if (key == null || key.length < keySizeInBytes) { - throw new InvalidKeyException("key must be at least " + keySize + " bits in length"); + throw LOGGER.throwableAtError() + .addKeyValue("actualSize", key == null ? 0 : key.length) + .addKeyValue("expectedSize", keySizeInBytes) + .log("Key is too short.", InvalidKeyException::new); } return new AesCbcPadDecryptor(Arrays.copyOfRange(key, 0, keySizeInBytes), iv, provider); diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesKeyCryptographyClient.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesKeyCryptographyClient.java index b141d9b1eb11..ef981031c929 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesKeyCryptographyClient.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesKeyCryptographyClient.java @@ -17,12 +17,12 @@ import com.azure.v2.security.keyvault.keys.models.JsonWebKey; import com.azure.v2.security.keyvault.keys.models.KeyOperation; import io.clientcore.core.http.models.RequestContext; +import io.clientcore.core.instrumentation.logging.ClientLogger; +import io.clientcore.core.models.CoreException; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; -import java.io.IOException; -import java.io.UncheckedIOException; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -33,6 +33,7 @@ import static com.azure.v2.security.keyvault.keys.cryptography.implementation.CryptographyUtils.verifyKeyPermissions; class AesKeyCryptographyClient extends LocalKeyCryptographyClient { + private static final ClientLogger LOGGER = new ClientLogger(AesKeyCryptographyClient.class); static final int AES_BLOCK_SIZE = 16; private final byte[] aesKey; @@ -42,27 +43,38 @@ class AesKeyCryptographyClient extends LocalKeyCryptographyClient { aesKey = jsonWebKey.toAes().getEncoded(); if (aesKey == null || aesKey.length == 0) { - throw new IllegalArgumentException("The provided JSON Web Key cannot be null or empty."); + throw LOGGER.throwableAtError() + .log("The provided JSON Web Key cannot be null or empty.", IllegalArgumentException::new); } } private static void validateEncryptionAlgorithm(EncryptionAlgorithm algorithm) { if (isGcm(algorithm)) { - throw new UnsupportedOperationException("AES-GCM is not supported for local cryptography operations."); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("AES-GCM is not supported for local cryptography operations.", IllegalArgumentException::new); } if (!isAes(algorithm)) { - throw new IllegalArgumentException("Encryption algorithm provided is not supported: " + algorithm); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Encryption algorithm provided is not supported.", IllegalArgumentException::new); } } - private static byte[] generateIv(int sizeInBytes) throws NoSuchAlgorithmException { - SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG"); - byte[] iv = new byte[sizeInBytes]; + private static byte[] generateIv(int sizeInBytes) { + try { + SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG"); + byte[] iv = new byte[sizeInBytes]; - randomSecureRandom.nextBytes(iv); + randomSecureRandom.nextBytes(iv); - return iv; + return iv; + } catch (NoSuchAlgorithmException e) { + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", "SHA1PRNG") + .log("Could not generate iv for this local operation.", e, CoreException::from); + } } private static boolean isAes(EncryptionAlgorithm encryptionAlgorithm) { @@ -82,29 +94,19 @@ private static boolean isGcm(EncryptionAlgorithm encryptionAlgorithm) { @Override public EncryptResult encrypt(EncryptionAlgorithm algorithm, byte[] plaintext, RequestContext requestContext) { - try { - return encryptInternal(algorithm, plaintext, null, null, requestContext); - } catch (Exception e) { - throw new RuntimeException(e); - } + return encryptInternal(algorithm, plaintext, null, null, requestContext); } @Override public EncryptResult encrypt(EncryptParameters encryptParameters, RequestContext requestContext) { Objects.requireNonNull(encryptParameters, "Encrypt parameters cannot be null."); - try { - return encryptInternal(encryptParameters.getAlgorithm(), encryptParameters.getPlainText(), - encryptParameters.getIv(), encryptParameters.getAdditionalAuthenticatedData(), requestContext); - } catch (Exception e) { - throw new RuntimeException(e); - } + return encryptInternal(encryptParameters.getAlgorithm(), encryptParameters.getPlainText(), + encryptParameters.getIv(), encryptParameters.getAdditionalAuthenticatedData(), requestContext); } private EncryptResult encryptInternal(EncryptionAlgorithm algorithm, byte[] plaintext, byte[] iv, - byte[] additionalAuthenticatedData, RequestContext requestContext) - throws BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException, - NoSuchAlgorithmException, NoSuchPaddingException, IOException { + byte[] additionalAuthenticatedData, RequestContext requestContext) { Objects.requireNonNull(algorithm, "Encryption algorithm cannot be null."); Objects.requireNonNull(plaintext, "Plaintext cannot be null."); @@ -117,58 +119,54 @@ private EncryptResult encryptInternal(EncryptionAlgorithm algorithm, byte[] plai return implClient.encrypt(algorithm, plaintext, null, null, requestContext); } - throw new NoSuchAlgorithmException(algorithm.toString()); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Unsupported encryption algorithm.", CoreException::from); } - verifyKeyPermissions(jsonWebKey, KeyOperation.ENCRYPT); + verifyKeyPermissions(jsonWebKey, KeyOperation.ENCRYPT, LOGGER); validateEncryptionAlgorithm(algorithm); SymmetricEncryptionAlgorithm symmetricEncryptionAlgorithm = (SymmetricEncryptionAlgorithm) baseAlgorithm; if (iv == null) { if (isAes(algorithm)) { - try { - iv = generateIv(AES_BLOCK_SIZE); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException("Could not generate iv for this local operation.", e); - } + iv = generateIv(AES_BLOCK_SIZE); } else { - throw new IllegalArgumentException("Encryption algorithm provided is not supported: " + algorithm); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Unsupported encryption algorithm provided.", CoreException::from); } } - byte[] ciphertext = symmetricEncryptionAlgorithm.createEncryptor(aesKey, iv, additionalAuthenticatedData, null) - .doFinal(plaintext); + byte[] ciphertext; + try { + ciphertext = symmetricEncryptionAlgorithm.createEncryptor(aesKey, iv, additionalAuthenticatedData, null) + .doFinal(plaintext); + } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException + | BadPaddingException | InvalidAlgorithmParameterException ex) { + throw LOGGER.throwableAtError().log(ex, CoreException::from); + } return new EncryptResult(ciphertext, algorithm, jsonWebKey.getId(), iv, null, additionalAuthenticatedData); } @Override public DecryptResult decrypt(EncryptionAlgorithm algorithm, byte[] ciphertext, RequestContext requestContext) { - try { - return decryptInternal(algorithm, ciphertext, null, null, null, requestContext); - } catch (Exception e) { - throw new RuntimeException(e); - } + return decryptInternal(algorithm, ciphertext, null, null, null, requestContext); } @Override public DecryptResult decrypt(DecryptParameters decryptParameters, RequestContext requestContext) { Objects.requireNonNull(decryptParameters, "Decrypt parameters cannot be null."); - try { - return decryptInternal(decryptParameters.getAlgorithm(), decryptParameters.getCipherText(), - decryptParameters.getIv(), decryptParameters.getAdditionalAuthenticatedData(), - decryptParameters.getAuthenticationTag(), requestContext); - } catch (Exception e) { - throw new RuntimeException(e); - } + return decryptInternal(decryptParameters.getAlgorithm(), decryptParameters.getCipherText(), + decryptParameters.getIv(), decryptParameters.getAdditionalAuthenticatedData(), + decryptParameters.getAuthenticationTag(), requestContext); } private DecryptResult decryptInternal(EncryptionAlgorithm algorithm, byte[] ciphertext, byte[] iv, - byte[] additionalAuthenticatedData, byte[] authenticationTag, RequestContext requestContext) - throws BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException, - NoSuchAlgorithmException, NoSuchPaddingException, IOException { + byte[] additionalAuthenticatedData, byte[] authenticationTag, RequestContext requestContext) { Objects.requireNonNull(algorithm, "Encryption algorithm cannot be null."); Objects.requireNonNull(ciphertext, "Ciphertext cannot be null."); @@ -181,33 +179,44 @@ private DecryptResult decryptInternal(EncryptionAlgorithm algorithm, byte[] ciph return implClient.decrypt(algorithm, ciphertext, requestContext); } - throw new NoSuchAlgorithmException(algorithm.toString()); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Unsupported encryption algorithm.", CoreException::from); } - verifyKeyPermissions(jsonWebKey, KeyOperation.DECRYPT); + verifyKeyPermissions(jsonWebKey, KeyOperation.DECRYPT, LOGGER); validateEncryptionAlgorithm(algorithm); SymmetricEncryptionAlgorithm symmetricEncryptionAlgorithm = (SymmetricEncryptionAlgorithm) baseAlgorithm; Objects.requireNonNull(iv, "'iv' cannot be null in local decryption operations."); - byte[] plaintext - = symmetricEncryptionAlgorithm.createDecryptor(aesKey, iv, additionalAuthenticatedData, authenticationTag) + byte[] plaintext; + + try { + plaintext = symmetricEncryptionAlgorithm + .createDecryptor(aesKey, iv, additionalAuthenticatedData, authenticationTag) .doFinal(ciphertext); + } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException + | BadPaddingException | InvalidAlgorithmParameterException ex) { + throw LOGGER.throwableAtError().log(ex, CoreException::from); + } return new DecryptResult(plaintext, algorithm, jsonWebKey.getId()); } @Override public SignResult sign(SignatureAlgorithm algorithm, byte[] digest, RequestContext requestContext) { - throw new UnsupportedOperationException("The sign operation not supported for OCT/symmetric keys."); + throw LOGGER.throwableAtError() + .log("The sign operation not supported for OCT/symmetric keys.", UnsupportedOperationException::new); } @Override public VerifyResult verify(SignatureAlgorithm algorithm, byte[] digest, byte[] signature, RequestContext requestContext) { - throw new UnsupportedOperationException("The verify operation is not supported for OCT/symmetric keys."); + throw LOGGER.throwableAtError() + .log("The verify operation not supported for OCT/symmetric keys.", UnsupportedOperationException::new); } @Override @@ -220,17 +229,15 @@ public WrapResult wrapKey(KeyWrapAlgorithm algorithm, byte[] keyToWrap, RequestC if (!(baseAlgorithm instanceof LocalKeyWrapAlgorithm)) { if (implClient != null) { - try { - return implClient.wrapKey(algorithm, keyToWrap, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.wrapKey(algorithm, keyToWrap, requestContext); } - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } - verifyKeyPermissions(jsonWebKey, KeyOperation.WRAP_KEY); + verifyKeyPermissions(jsonWebKey, KeyOperation.WRAP_KEY, LOGGER); LocalKeyWrapAlgorithm localKeyWrapAlgorithm = (LocalKeyWrapAlgorithm) baseAlgorithm; @@ -239,19 +246,15 @@ public WrapResult wrapKey(KeyWrapAlgorithm algorithm, byte[] keyToWrap, RequestC try { transform = localKeyWrapAlgorithm.createEncryptor(aesKey, null, null); } catch (GeneralSecurityException e) { - throw new RuntimeException(e); + throw LOGGER.throwableAtError().log(e, CoreException::from); } byte[] encrypted; try { encrypted = transform.doFinal(keyToWrap); - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new RuntimeException(e); - } + } catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException | NoSuchAlgorithmException e) { + throw LOGGER.throwableAtError().log(e, CoreException::from); } return new WrapResult(encrypted, algorithm, jsonWebKey.getId()); @@ -262,23 +265,21 @@ public UnwrapResult unwrapKey(KeyWrapAlgorithm algorithm, byte[] encryptedKey, R Objects.requireNonNull(algorithm, "Key wrap algorithm cannot be null."); Objects.requireNonNull(encryptedKey, "Encrypted key content to be unwrapped cannot be null."); - verifyKeyPermissions(jsonWebKey, KeyOperation.UNWRAP_KEY); + verifyKeyPermissions(jsonWebKey, KeyOperation.UNWRAP_KEY, LOGGER); Algorithm baseAlgorithm = AlgorithmResolver.DEFAULT.get(algorithm.toString()); if (!(baseAlgorithm instanceof LocalKeyWrapAlgorithm)) { if (implClient != null) { - try { - return implClient.unwrapKey(algorithm, encryptedKey, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.unwrapKey(algorithm, encryptedKey, requestContext); } - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } - verifyKeyPermissions(jsonWebKey, KeyOperation.UNWRAP_KEY); + verifyKeyPermissions(jsonWebKey, KeyOperation.UNWRAP_KEY, LOGGER); LocalKeyWrapAlgorithm localKeyWrapAlgorithm = (LocalKeyWrapAlgorithm) baseAlgorithm; @@ -287,7 +288,7 @@ public UnwrapResult unwrapKey(KeyWrapAlgorithm algorithm, byte[] encryptedKey, R return new UnwrapResult(decrypted, algorithm, jsonWebKey.getId()); } catch (GeneralSecurityException e) { - throw new RuntimeException(e); + throw LOGGER.throwableAtError().log(e, CoreException::from); } } diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesKw.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesKw.java index 2441ca0d0700..aaad642e88d2 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesKw.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/AesKw.java @@ -3,6 +3,8 @@ package com.azure.v2.security.keyvault.keys.cryptography.implementation; +import io.clientcore.core.instrumentation.logging.ClientLogger; + import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; @@ -14,6 +16,7 @@ import java.security.Provider; abstract class AesKw extends LocalKeyWrapAlgorithm { + private static final ClientLogger LOGGER = new ClientLogger(AesKw.class); static final int BLOCK_SIZE_IN_BITS = 64; static final String CIPHER_NAME = "AESWrap"; static final byte[] DEFAULT_IV = new byte[] { @@ -114,21 +117,28 @@ public ICryptoTransform createEncryptor(byte[] key, byte[] iv, Provider provider NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { if (key == null) { - throw new IllegalArgumentException("key"); + throw LOGGER.throwableAtError().log("key cannot be null.", IllegalArgumentException::new); } if (key.length != 128 >> 3 && key.length != 192 >> 3 && key.length != 256 >> 3) { - throw new IllegalArgumentException("key length must be 128, 192 or 256 bits"); + throw LOGGER.throwableAtError() + .addKeyValue("length", key.length) + .log("key length must be 128, 192 or 256 bits.", IllegalArgumentException::new); } if (iv != null) { // iv length must be 64 bits if (iv.length != BLOCK_SIZE_IN_BITS >> 3) { - throw new IllegalArgumentException(String.format("iv length must be %s bits", BLOCK_SIZE_IN_BITS)); + throw LOGGER.throwableAtError() + .addKeyValue("length", iv.length) + .addKeyValue("expectedLength", BLOCK_SIZE_IN_BITS >> 3) + .log("Invalid iv length.", IllegalArgumentException::new); } // iv cannot be specified with the default provider if (provider == null) { - throw new IllegalArgumentException("user specified iv is not supported with the default provider"); + throw LOGGER.throwableAtError() + .log("user specified iv is not supported with the default provider.", + IllegalArgumentException::new); } } @@ -162,21 +172,28 @@ public ICryptoTransform createDecryptor(byte[] key, byte[] iv, Provider provider NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { if (key == null) { - throw new IllegalArgumentException("key"); + throw LOGGER.throwableAtError().log("key cannot be null.", IllegalArgumentException::new); } if (key.length != 128 >> 3 && key.length != 192 >> 3 && key.length != 256 >> 3) { - throw new IllegalArgumentException("key length must be 128, 192 or 256 bits"); + throw LOGGER.throwableAtError() + .addKeyValue("length", key.length) + .log("key length must be 128, 192 or 256 bits.", IllegalArgumentException::new); } if (iv != null) { // iv length must be 64 bits if (iv.length != BLOCK_SIZE_IN_BITS >> 3) { - throw new IllegalArgumentException(String.format("iv length must be %s bits", BLOCK_SIZE_IN_BITS)); + throw LOGGER.throwableAtError() + .addKeyValue("length", iv.length) + .addKeyValue("expectedLength", BLOCK_SIZE_IN_BITS >> 3) + .log("Invalid iv length.", IllegalArgumentException::new); } // iv cannot be specified with the default provider if (provider == null) { - throw new IllegalArgumentException("user specified iv is not supported with the default provider"); + throw LOGGER.throwableAtError() + .log("user specified iv is not supported with the default provider.", + IllegalArgumentException::new); } } diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Algorithm.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Algorithm.java index faae580624eb..ad844e2332ea 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Algorithm.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Algorithm.java @@ -3,6 +3,8 @@ package com.azure.v2.security.keyvault.keys.cryptography.implementation; +import io.clientcore.core.instrumentation.logging.ClientLogger; + import static io.clientcore.core.utils.CoreUtils.isNullOrEmpty; /** @@ -10,12 +12,15 @@ * */ abstract class Algorithm { + private static final ClientLogger LOGGER = new ClientLogger(Algorithm.class); private final String name; Algorithm(String name) { if (isNullOrEmpty(name) || name.trim().isEmpty()) { - throw new IllegalArgumentException("name"); + throw LOGGER.throwableAtError() + .addKeyValue("name", name) + .log("Algorithm name cannot be null or empty.", IllegalArgumentException::new); } this.name = name; diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Asn1DerSignatureEncoding.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Asn1DerSignatureEncoding.java index 956cf86a8ee2..2e4fea2c10e2 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Asn1DerSignatureEncoding.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Asn1DerSignatureEncoding.java @@ -2,12 +2,18 @@ // Licensed under the MIT License. package com.azure.v2.security.keyvault.keys.cryptography.implementation; +import io.clientcore.core.instrumentation.logging.ClientLogger; +import io.clientcore.core.models.CoreException; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.util.Arrays; +import static io.clientcore.core.utils.CoreUtils.bytesToHexString; + final class Asn1DerSignatureEncoding { + private static final ClientLogger LOGGER = new ClientLogger(Asn1DerSignatureEncoding.class); // The EDCSA ASN.1 DER signature is in the format: // 0x30 b1 0x02 b2 (vr) 0x02 b3 (vs) // where: @@ -30,7 +36,10 @@ static byte[] encode(byte[] signature, Ecdsa algorithm) { // Verify that the signature is the correct length for the given algorithm. if (signature.length != (coordLength * 2)) { - throw new IllegalArgumentException("Invalid signature."); + throw LOGGER.throwableAtError() + .addKeyValue("signature", bytesToHexString(signature)) + .addKeyValue("len", signature.length) + .log("Invalid signature; invalid length.", CoreException::from); } // r is the first half of the signature. @@ -60,14 +69,19 @@ static byte[] decode(byte[] bytes, Ecdsa algorithm) { // Verify byte 0 is 0x30. if (asn1DerSignature.read() != 0x30) { - throw new IllegalArgumentException("Invalid signature."); + throw LOGGER.throwableAtError() + .addKeyValue("signature", bytesToHexString(bytes)) + .log("Invalid signature.", CoreException::from); } int objLen = readFieldLength(asn1DerSignature); // Verify the object length is equal to the remaining length of the _asn1DerSignature. if (objLen != asn1DerSignature.available()) { - throw new IllegalArgumentException(String.format("Invalid signature; invalid field len %d", objLen)); + throw LOGGER.throwableAtError() + .addKeyValue("signature", bytesToHexString(bytes)) + .addKeyValue("len", objLen) + .log("Invalid signature; invalid field len.", CoreException::from); } byte[] rawSignature = new byte[coordLength * 2]; @@ -120,7 +134,8 @@ static void writeFieldLength(ByteArrayOutputStream field, int len) { static void decodeIntField(ByteArrayInputStream bytes, byte[] dest, int index, int intlen) { // Verify the first byte of field is 0x02. if (bytes.read() != 0x02) { - throw new IllegalArgumentException("Invalid signature."); + throw LOGGER.throwableAtError() + .log("Invalid signature; First byte of field is not 0x02.", CoreException::from); } // Get the length of the field. @@ -131,7 +146,11 @@ static void decodeIntField(ByteArrayInputStream bytes, byte[] dest, int index, i // Validate that len is within the max range and doesn't run past the end of bytes. if (len > intlen + 1 || len > bytes.available()) { - throw new IllegalArgumentException("Invalid signature."); + throw LOGGER.throwableAtError() + .addKeyValue("len", len) + .addKeyValue("intlen", intlen) + .addKeyValue("bytesAvailable", bytes.available()) + .log("Invalid signature; invalid field len.", CoreException::from); } // If len is greater than intlen increment _bytesRead and decrement len. @@ -156,7 +175,10 @@ static int readFieldLength(ByteArrayInputStream bytes) { // If the number of len bytes is greater than the remaining signature the signature is invalid. if (numLenBytes > bytes.available()) { - throw new IllegalArgumentException("Invalid signature."); + throw LOGGER.throwableAtError() + .addKeyValue("numLenBytes", numLenBytes) + .addKeyValue("bytesAvailable", bytes.available()) + .log("Invalid signature; invalid field len.", CoreException::from); } byte[] lenBytes = new byte[numLenBytes]; @@ -165,10 +187,12 @@ static int readFieldLength(ByteArrayInputStream bytes) { BigInteger bigLen = new BigInteger(1, lenBytes); - // For DSA signatures no feilds should be longer than can be expressed in an integer this means that the + // For DSA signatures no fields should be longer than can be expressed in an integer this means that the // bitLength must be 31 or less to account for the leading zero of a positive integer. if (bigLen.bitLength() >= 31) { - throw new IllegalArgumentException("Invalid signature."); + throw LOGGER.throwableAtError() + .addKeyValue("bigLen", bigLen.toString()) + .log("Invalid signature; invalid field len.", CoreException::from); } return bigLen.intValue(); diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/CryptographyClientImpl.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/CryptographyClientImpl.java index f0ba51b8a267..8343f0bb8d3a 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/CryptographyClientImpl.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/CryptographyClientImpl.java @@ -32,8 +32,8 @@ import io.clientcore.core.http.models.Response; import io.clientcore.core.http.pipeline.HttpPipeline; import io.clientcore.core.instrumentation.logging.ClientLogger; +import io.clientcore.core.models.CoreException; -import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.List; @@ -106,15 +106,14 @@ public Response setSecretKey(SecretBundle secret, RequestContext r return secretClient.setSecretWithResponse("", secretSetParameters, requestContext); } - public EncryptResult encrypt(EncryptionAlgorithm algorithm, byte[] plaintext) throws IOException { + public EncryptResult encrypt(EncryptionAlgorithm algorithm, byte[] plaintext) { Objects.requireNonNull(algorithm, "Encryption algorithm cannot be null."); Objects.requireNonNull(plaintext, "Plaintext cannot be null."); return encrypt(algorithm, plaintext, null, null, RequestContext.none()); } - public EncryptResult encrypt(EncryptParameters encryptParameters, RequestContext requestContext) - throws IOException { + public EncryptResult encrypt(EncryptParameters encryptParameters, RequestContext requestContext) { Objects.requireNonNull(encryptParameters, "Encrypt parameters cannot be null."); @@ -123,7 +122,7 @@ public EncryptResult encrypt(EncryptParameters encryptParameters, RequestContext } EncryptResult encrypt(EncryptionAlgorithm algorithm, byte[] plainText, byte[] iv, - byte[] additionalAuthenticatedData, RequestContext requestContext) throws IOException { + byte[] additionalAuthenticatedData, RequestContext requestContext) { KeyOperationsParameters keyOperationsParameters = new KeyOperationsParameters(mapKeyEncryptionAlgorithm(algorithm), plainText).setIv(iv) @@ -139,8 +138,7 @@ EncryptResult encrypt(EncryptionAlgorithm algorithm, byte[] plainText, byte[] iv } } - public DecryptResult decrypt(EncryptionAlgorithm algorithm, byte[] ciphertext, RequestContext requestContext) - throws IOException { + public DecryptResult decrypt(EncryptionAlgorithm algorithm, byte[] ciphertext, RequestContext requestContext) { Objects.requireNonNull(algorithm, "Encryption algorithm cannot be null."); Objects.requireNonNull(ciphertext, "Ciphertext cannot be null."); @@ -148,8 +146,7 @@ public DecryptResult decrypt(EncryptionAlgorithm algorithm, byte[] ciphertext, R return decrypt(algorithm, ciphertext, null, null, null, requestContext); } - public DecryptResult decrypt(DecryptParameters decryptParameters, RequestContext requestContext) - throws IOException { + public DecryptResult decrypt(DecryptParameters decryptParameters, RequestContext requestContext) { Objects.requireNonNull(decryptParameters, "Decrypt parameters cannot be null."); @@ -159,8 +156,7 @@ public DecryptResult decrypt(DecryptParameters decryptParameters, RequestContext } DecryptResult decrypt(EncryptionAlgorithm algorithm, byte[] ciphertext, byte[] iv, - byte[] additionalAuthenticatedData, byte[] authenticationTag, RequestContext requestContext) - throws IOException { + byte[] additionalAuthenticatedData, byte[] authenticationTag, RequestContext requestContext) { KeyOperationsParameters keyOperationsParameters = new KeyOperationsParameters(mapKeyEncryptionAlgorithm(algorithm), ciphertext).setIv(iv) @@ -174,8 +170,7 @@ DecryptResult decrypt(EncryptionAlgorithm algorithm, byte[] ciphertext, byte[] i } } - public SignResult sign(SignatureAlgorithm algorithm, byte[] digest, RequestContext requestContext) - throws IOException { + public SignResult sign(SignatureAlgorithm algorithm, byte[] digest, RequestContext requestContext) { Objects.requireNonNull(algorithm, "Signature algorithm cannot be null."); Objects.requireNonNull(digest, "Digest content cannot be null."); @@ -190,7 +185,7 @@ public SignResult sign(SignatureAlgorithm algorithm, byte[] digest, RequestConte } public VerifyResult verify(SignatureAlgorithm algorithm, byte[] digest, byte[] signature, - RequestContext requestContext) throws IOException { + RequestContext requestContext) { Objects.requireNonNull(algorithm, "Signature algorithm cannot be null."); Objects.requireNonNull(digest, "Digest content cannot be null."); @@ -206,8 +201,7 @@ public VerifyResult verify(SignatureAlgorithm algorithm, byte[] digest, byte[] s } } - public WrapResult wrapKey(KeyWrapAlgorithm algorithm, byte[] key, RequestContext requestContext) - throws IOException { + public WrapResult wrapKey(KeyWrapAlgorithm algorithm, byte[] key, RequestContext requestContext) { Objects.requireNonNull(algorithm, "Key wrap algorithm cannot be null."); Objects.requireNonNull(key, "Key content to be wrapped cannot be null."); @@ -221,9 +215,7 @@ public WrapResult wrapKey(KeyWrapAlgorithm algorithm, byte[] key, RequestContext } } - public UnwrapResult unwrapKey(KeyWrapAlgorithm algorithm, byte[] encryptedKey, RequestContext requestContext) - throws IOException { - + public UnwrapResult unwrapKey(KeyWrapAlgorithm algorithm, byte[] encryptedKey, RequestContext requestContext) { Objects.requireNonNull(algorithm, "Key wrap algorithm cannot be null."); Objects.requireNonNull(encryptedKey, "Encrypted key content to be unwrapped cannot be null."); @@ -237,14 +229,12 @@ public UnwrapResult unwrapKey(KeyWrapAlgorithm algorithm, byte[] encryptedKey, R } } - public SignResult signData(SignatureAlgorithm algorithm, byte[] data, RequestContext requestContext) - throws IOException, NoSuchAlgorithmException { - + public SignResult signData(SignatureAlgorithm algorithm, byte[] data, RequestContext requestContext) { Objects.requireNonNull(algorithm, "Signature algorithm cannot be null."); Objects.requireNonNull(data, "Data to be signed cannot be null."); HashAlgorithm hashAlgorithm = SignatureHashResolver.DEFAULT.get(algorithm); - MessageDigest md = MessageDigest.getInstance(hashAlgorithm.toString()); + MessageDigest md = getMessageDigest(hashAlgorithm); md.update(data); @@ -254,19 +244,28 @@ public SignResult signData(SignatureAlgorithm algorithm, byte[] data, RequestCon } public VerifyResult verifyData(SignatureAlgorithm algorithm, byte[] data, byte[] signature, - RequestContext requestContext) throws IOException, NoSuchAlgorithmException { - + RequestContext requestContext) { Objects.requireNonNull(algorithm, "Signature algorithm cannot be null."); Objects.requireNonNull(data, "Data to verify cannot be null."); Objects.requireNonNull(signature, "Signature to be verified cannot be null."); HashAlgorithm hashAlgorithm = SignatureHashResolver.DEFAULT.get(algorithm); - MessageDigest md = MessageDigest.getInstance(hashAlgorithm.toString()); + MessageDigest md = getMessageDigest(hashAlgorithm); md.update(data); byte[] digest = md.digest(); return verify(algorithm, digest, signature, requestContext); } + + private MessageDigest getMessageDigest(HashAlgorithm hashAlgorithm) { + try { + return MessageDigest.getInstance(hashAlgorithm.toString()); + } catch (NoSuchAlgorithmException e) { + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", hashAlgorithm.toString()) + .log(e, CoreException::from); + } + } } diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/CryptographyUtils.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/CryptographyUtils.java index 992904520b20..5f64b68e7288 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/CryptographyUtils.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/CryptographyUtils.java @@ -53,46 +53,50 @@ private CryptographyUtils() { */ public static List unpackAndValidateId(String keyId, ClientLogger logger) { if (isNullOrEmpty(keyId)) { - throw logger.logThrowableAsError(new IllegalArgumentException("'keyId' cannot be null or empty.")); + throw logger.throwableAtError().log("'keyId' cannot be null or empty.", IllegalArgumentException::new); } + URI uri; try { - URI uri = new URI(keyId); - String[] tokens = uri.getPath().split("/"); - String vaultUrl = uri.getScheme() + "://" + uri.getHost(); + uri = new URI(keyId); + } catch (URISyntaxException e) { + throw logger.throwableAtError().log("The key identifier is malformed.", e, IllegalArgumentException::new); + } - if (uri.getPort() != -1) { - vaultUrl += ":" + uri.getPort(); - } + String[] tokens = uri.getPath().split("/"); + String vaultUrl = uri.getScheme() + "://" + uri.getHost(); - String keyCollection = (tokens.length >= 2 ? tokens[1] : null); - String keyName = (tokens.length >= 3 ? tokens[2] : null); - String keyVersion = (tokens.length >= 4 ? tokens[3] : null); + if (uri.getPort() != -1) { + vaultUrl += ":" + uri.getPort(); + } - if (isNullOrEmpty(vaultUrl)) { - throw logger - .logThrowableAsError(new IllegalArgumentException("Key endpoint in key identifier is invalid.")); - } else if (isNullOrEmpty(keyName)) { - throw logger - .logThrowableAsError(new IllegalArgumentException("Key name in key identifier is invalid.")); - } + String keyCollection = (tokens.length >= 2 ? tokens[1] : null); + String keyName = (tokens.length >= 3 ? tokens[2] : null); + String keyVersion = (tokens.length >= 4 ? tokens[3] : null); - return Arrays.asList(vaultUrl, keyCollection, keyName, keyVersion); - } catch (URISyntaxException e) { - throw logger.logThrowableAsError(new IllegalArgumentException("The key identifier is malformed.", e)); + if (isNullOrEmpty(vaultUrl)) { + throw logger.throwableAtError() + .log("Key endpoint in key identifier is invalid.", IllegalArgumentException::new); + } else if (isNullOrEmpty(keyName)) { + throw logger.throwableAtError() + .log("Key name in key identifier is invalid.", IllegalArgumentException::new); } + + return Arrays.asList(vaultUrl, keyCollection, keyName, keyVersion); } /** * Creates a local cryptography client using the provided key identifier and cryptography client implementation. * * @param implClient The cryptography client implementation. + * @param logger The logger to use for logging errors. * @return A local cryptography client. * * @throws IllegalStateException If either of the key identifier or JSON Web Key is invalid or if the latter cannot * be retrieved. */ - public static LocalKeyCryptographyClient retrieveJwkAndCreateLocalClient(CryptographyClientImpl implClient) { + public static LocalKeyCryptographyClient retrieveJwkAndCreateLocalClient(CryptographyClientImpl implClient, + ClientLogger logger) { // Technically the collection portion of a key identifier should never be null/empty, but we still check for it. if (!isNullOrEmpty(implClient.getKeyCollection())) { // Get the JWK from the service and validate it. Then attempt to create a local cryptography client or @@ -102,16 +106,20 @@ public static LocalKeyCryptographyClient retrieveJwkAndCreateLocalClient(Cryptog : implClient.getKeyWithResponse(RequestContext.none()).getValue().getKey(); if (jsonWebKey == null) { - throw new IllegalStateException( - "Could not retrieve JSON Web Key to perform local cryptographic operations."); + throw logger.throwableAtError() + .log("Could not retrieve JSON Web Key to perform local cryptographic operations.", + IllegalStateException::new); } else if (!jsonWebKey.isValid()) { - throw new IllegalStateException("The retrieved JSON Web Key is not valid."); + throw logger.throwableAtError() + .log("The retrieved JSON Web Key is not valid.", IllegalStateException::new); } else { - return createLocalClient(jsonWebKey, implClient); + return createLocalClient(jsonWebKey, implClient, logger); } } else { // Couldn't/didn't create a local cryptography client. - throw new IllegalStateException("Could not create a local cryptography client."); + throw logger.throwableAtError() + .log("Could not create a local cryptography client, key collection is invalid", + IllegalStateException::new); } } @@ -120,18 +128,14 @@ public static LocalKeyCryptographyClient retrieveJwkAndCreateLocalClient(Cryptog * * @param jsonWebKey The JSON Web Key to use for local cryptographic operations. * @param implClient The cryptography client implementation. + * @param logger The logger to use for logging errors. * @return A local cryptography client. * * @throws IllegalArgumentException If the JSON Web Key type is not supported. * @throws IllegalStateException If the local cryptography client cannot be created. */ - public static LocalKeyCryptographyClient createLocalClient(JsonWebKey jsonWebKey, - CryptographyClientImpl implClient) { - - if (!KeyType.values().contains(jsonWebKey.getKeyType())) { - throw new IllegalArgumentException( - String.format("The JSON Web Key type: %s is not supported.", jsonWebKey.getKeyType().toString())); - } + public static LocalKeyCryptographyClient createLocalClient(JsonWebKey jsonWebKey, CryptographyClientImpl implClient, + ClientLogger logger) { if (jsonWebKey.getKeyType().equals(RSA) || jsonWebKey.getKeyType().equals(RSA_HSM)) { return new RsaKeyCryptographyClient(jsonWebKey, implClient); @@ -142,7 +146,9 @@ public static LocalKeyCryptographyClient createLocalClient(JsonWebKey jsonWebKey } // Should never reach this point. - throw new IllegalStateException("Could not create local cryptography client."); + throw logger.throwableAtError() + .addKeyValue("keyType", jsonWebKey.getKeyType().getValue()) + .log("The JSON Web Key type is not supported.", IllegalArgumentException::new); } /** @@ -150,15 +156,18 @@ public static LocalKeyCryptographyClient createLocalClient(JsonWebKey jsonWebKey * * @param jsonWebKey The JSON Web Key to verify. * @param keyOperation The key operation to verify. + * @param logger The logger to use for logging errors. * * @throws UnsupportedOperationException If the key operation is not supported by the key. */ - public static void verifyKeyPermissions(JsonWebKey jsonWebKey, KeyOperation keyOperation) { + public static void verifyKeyPermissions(JsonWebKey jsonWebKey, KeyOperation keyOperation, ClientLogger logger) { if (!jsonWebKey.getKeyOps().contains(keyOperation)) { String keyOperationName = keyOperation == null ? null : keyOperation.toString().toLowerCase(Locale.ROOT); - throw new UnsupportedOperationException(String.format("The %s operation is not allowed for key with id: %s", - keyOperationName, jsonWebKey.getId())); + throw logger.throwableAtError() + .addKeyValue("keyOperationName", keyOperationName) + .addKeyValue("keyId", jsonWebKey.getId()) + .log("The operation is not allowed for key", UnsupportedOperationException::new); } } @@ -188,42 +197,19 @@ public static boolean isThrowableRetryable(Throwable e) { * @param key The key to be checked. * @param keySizeInBytes The minimum size required for the key. */ - static void validate(byte[] key, int keySizeInBytes) { + static void validate(byte[] key, int keySizeInBytes, ClientLogger logger) { if (key == null) { - throw new IllegalArgumentException("key must not be null"); + throw logger.throwableAtError().log("key must not be null", NullPointerException::new); } if (key.length < keySizeInBytes) { - throw new IllegalArgumentException(String.format("key must be at least %d bits long", keySizeInBytes << 3)); + throw logger.throwableAtError() + .addKeyValue("expectedLengthInBytes", keySizeInBytes) + .addKeyValue("keyLength", key.length) + .log("Key is too short", IllegalArgumentException::new); } } - /** - * Compares two byte arrays in constant time. - * - * @param self The first byte array to compare. - * @param other The second byte array to compare. - * @return True if the two byte arrays are equal. - */ - static boolean sequenceEqualConstantTime(byte[] self, byte[] other) { - if (self == null) { - throw new IllegalArgumentException("self"); - } - - if (other == null) { - throw new IllegalArgumentException("other"); - } - - // Constant time comparison of two byte arrays - long difference = (self.length & 0xffffffffL) ^ (other.length & 0xffffffffL); - - for (int i = 0; i < self.length && i < other.length; i++) { - difference |= (self[i] ^ other[i]) & 0xffffffffL; - } - - return difference == 0; - } - static JsonWebKey transformSecretBundle(SecretBundle secretKey) { return new JsonWebKey().setId(secretKey.getId()) .setK(Base64.getUrlDecoder().decode(secretKey.getValue())) diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/EcKeyCryptographyClient.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/EcKeyCryptographyClient.java index 397c2ca39961..6476867b0c04 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/EcKeyCryptographyClient.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/EcKeyCryptographyClient.java @@ -17,9 +17,10 @@ import com.azure.v2.security.keyvault.keys.models.JsonWebKey; import com.azure.v2.security.keyvault.keys.models.KeyOperation; import io.clientcore.core.http.models.RequestContext; +import io.clientcore.core.instrumentation.logging.ClientLogger; +import io.clientcore.core.models.CoreException; -import java.io.IOException; -import java.io.UncheckedIOException; +import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -30,6 +31,7 @@ import static com.azure.v2.security.keyvault.keys.cryptography.implementation.CryptographyUtils.verifyKeyPermissions; class EcKeyCryptographyClient extends LocalKeyCryptographyClient { + private static final ClientLogger LOGGER = new ClientLogger(EcKeyCryptographyClient.class); private final KeyPair ecKeyPair; private final Provider provider; @@ -42,22 +44,26 @@ class EcKeyCryptographyClient extends LocalKeyCryptographyClient { @Override public EncryptResult encrypt(EncryptionAlgorithm algorithm, byte[] plaintext, RequestContext requestContext) { - throw new UnsupportedOperationException("The encrypt operation is not supported for EC keys."); + throw LOGGER.throwableAtError() + .log("The encrypt operation is not supported for EC keys.", UnsupportedOperationException::new); } @Override public EncryptResult encrypt(EncryptParameters options, RequestContext requestContext) { - throw new UnsupportedOperationException("The encrypt operation is not supported for EC keys."); + throw LOGGER.throwableAtError() + .log("The encrypt operation is not supported for EC keys.", UnsupportedOperationException::new); } @Override public DecryptResult decrypt(EncryptionAlgorithm algorithm, byte[] plaintext, RequestContext requestContext) { - throw new UnsupportedOperationException("The decrypt operation is not supported for EC keys."); + throw LOGGER.throwableAtError() + .log("The decrypt operation is not supported for EC keys.", UnsupportedOperationException::new); } @Override public DecryptResult decrypt(DecryptParameters options, RequestContext requestContext) { - throw new UnsupportedOperationException("The decrypt operation is not supported for EC keys."); + throw LOGGER.throwableAtError() + .log("The decrypt operation is not supported for EC keys.", UnsupportedOperationException::new); } @Override @@ -70,51 +76,46 @@ public SignResult sign(SignatureAlgorithm algorithm, byte[] digest, RequestConte if (baseAlgorithm == null) { if (implClient != null) { - try { - return implClient.sign(algorithm, digest, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.sign(algorithm, digest, requestContext); } - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } else if (!(baseAlgorithm instanceof AsymmetricSignatureAlgorithm)) { - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } if (ecKeyPair.getPrivate() == null) { if (implClient != null) { - try { - return implClient.sign(algorithm, digest, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.sign(algorithm, digest, requestContext); } - throw new IllegalArgumentException( - "The private portion of the key is not locally available to perform the sign operation."); + throw LOGGER.throwableAtError() + .log("The private portion of the key is not locally available to perform the sign operation.", + IllegalArgumentException::new); } - verifyKeyPermissions(jsonWebKey, KeyOperation.SIGN); + verifyKeyPermissions(jsonWebKey, KeyOperation.SIGN, LOGGER); Ecdsa algo; if (baseAlgorithm instanceof Ecdsa) { algo = (Ecdsa) baseAlgorithm; } else { - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } ISignatureTransform signer = algo.createSignatureTransform(ecKeyPair, provider); try { return new SignResult(signer.sign(digest), algorithm, jsonWebKey.getId()); - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new RuntimeException(e); - } + } catch (GeneralSecurityException e) { + throw LOGGER.throwableAtError().log(e, CoreException::from); } } @@ -131,87 +132,82 @@ public VerifyResult verify(SignatureAlgorithm algorithm, byte[] digest, byte[] s if (baseAlgorithm == null) { if (implClient != null) { - try { - return implClient.verify(algorithm, digest, signature, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.verify(algorithm, digest, signature, requestContext); } - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } else if (!(baseAlgorithm instanceof AsymmetricSignatureAlgorithm)) { - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } if (ecKeyPair.getPublic() == null) { if (implClient != null) { - try { - return implClient.verify(algorithm, digest, signature, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.verify(algorithm, digest, signature, requestContext); } - throw new IllegalArgumentException( - "The public portion of the key is not locally available to perform the verify operation."); + throw LOGGER.throwableAtError() + .log("The public portion of the key is not locally available to perform the verify operation.", + IllegalArgumentException::new); } - verifyKeyPermissions(jsonWebKey, KeyOperation.VERIFY); + verifyKeyPermissions(jsonWebKey, KeyOperation.VERIFY, LOGGER); Ecdsa algo; if (baseAlgorithm instanceof Ecdsa) { algo = (Ecdsa) baseAlgorithm; } else { - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } ISignatureTransform signer = algo.createSignatureTransform(ecKeyPair, provider); try { return new VerifyResult(signer.verify(digest, signature), algorithm, jsonWebKey.getId()); - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new RuntimeException(e); - } + } catch (GeneralSecurityException e) { + throw LOGGER.throwableAtError().log(e, CoreException::from); } } @Override public WrapResult wrapKey(KeyWrapAlgorithm algorithm, byte[] keyToWrap, RequestContext requestContext) { - throw new UnsupportedOperationException("The key wrap operation is not supported for EC keys."); + throw LOGGER.throwableAtError() + .log("The key wrap operation is not supported for EC keys.", UnsupportedOperationException::new); } @Override public UnwrapResult unwrapKey(KeyWrapAlgorithm algorithm, byte[] encryptedKey, RequestContext requestContext) { - throw new UnsupportedOperationException("The key unwrap operation is not supported for EC keys."); + throw LOGGER.throwableAtError() + .log("The key wrap operation is not supported for EC keys.", UnsupportedOperationException::new); } @Override public SignResult signData(SignatureAlgorithm algorithm, byte[] data, RequestContext requestContext) { - try { - return sign(algorithm, calculateDigest(algorithm, data), requestContext); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } + return sign(algorithm, calculateDigest(algorithm, data), requestContext); } @Override public VerifyResult verifyData(SignatureAlgorithm algorithm, byte[] data, byte[] signature, RequestContext requestContext) { - try { - return verify(algorithm, calculateDigest(algorithm, data), signature, requestContext); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } + return verify(algorithm, calculateDigest(algorithm, data), signature, requestContext); } - private static byte[] calculateDigest(SignatureAlgorithm algorithm, byte[] data) throws NoSuchAlgorithmException { + private static byte[] calculateDigest(SignatureAlgorithm algorithm, byte[] data) { HashAlgorithm hashAlgorithm = SignatureHashResolver.DEFAULT.get(algorithm); - MessageDigest md = MessageDigest.getInstance(Objects.toString(hashAlgorithm, null)); + + MessageDigest md; + try { + md = MessageDigest.getInstance(Objects.toString(hashAlgorithm, null)); + } catch (NoSuchAlgorithmException e) { + throw LOGGER.throwableAtError().addKeyValue("algorithm", algorithm.getValue()).log(e, CoreException::from); + } md.update(data); diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Ecdsa.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Ecdsa.java index 927b3c14c721..6468d85bff78 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Ecdsa.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/Ecdsa.java @@ -3,12 +3,16 @@ package com.azure.v2.security.keyvault.keys.cryptography.implementation; +import io.clientcore.core.instrumentation.logging.ClientLogger; + import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.Provider; import java.security.Signature; abstract class Ecdsa extends AsymmetricSignatureAlgorithm { + private static final ClientLogger LOGGER = new ClientLogger(Ecdsa.class); + protected Ecdsa() { super("NONEwithECDSA"); } @@ -59,7 +63,9 @@ public boolean verify(byte[] digest, byte[] signature) throws GeneralSecurityExc private void checkDigestLength(byte[] digest) { if (digest.length != getDigestLength()) { - throw new IllegalArgumentException("Invalid digest length."); + throw LOGGER.throwableAtError() + .addKeyValue("length", digest.length) + .log("Invalid digest length.", IllegalArgumentException::new); } } } diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/RsaKeyCryptographyClient.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/RsaKeyCryptographyClient.java index 6460f295c801..5124d52e08c2 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/RsaKeyCryptographyClient.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/RsaKeyCryptographyClient.java @@ -17,9 +17,9 @@ import com.azure.v2.security.keyvault.keys.models.JsonWebKey; import com.azure.v2.security.keyvault.keys.models.KeyOperation; import io.clientcore.core.http.models.RequestContext; +import io.clientcore.core.instrumentation.logging.ClientLogger; +import io.clientcore.core.models.CoreException; -import java.io.IOException; -import java.io.UncheckedIOException; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.MessageDigest; @@ -29,6 +29,7 @@ import static com.azure.v2.security.keyvault.keys.cryptography.implementation.CryptographyUtils.verifyKeyPermissions; class RsaKeyCryptographyClient extends LocalKeyCryptographyClient { + private static final ClientLogger LOGGER = new ClientLogger(RsaKeyCryptographyClient.class); private final KeyPair rsaKeyPair; RsaKeyCryptographyClient(JsonWebKey jsonWebKey, CryptographyClientImpl implClient) { @@ -47,32 +48,29 @@ public EncryptResult encrypt(EncryptionAlgorithm algorithm, byte[] plaintext, Re if (baseAlgorithm == null) { if (implClient != null) { - try { - return implClient.encrypt(algorithm, plaintext, null, null, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.encrypt(algorithm, plaintext, null, null, requestContext); } - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } else if (!(baseAlgorithm instanceof AsymmetricEncryptionAlgorithm)) { - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } if (rsaKeyPair.getPublic() == null) { if (implClient != null) { - try { - return implClient.encrypt(algorithm, plaintext, null, null, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.encrypt(algorithm, plaintext, null, null, requestContext); } - throw new IllegalArgumentException( - "The public portion of the key is not available to perform the encrypt operation."); + throw LOGGER.throwableAtError() + .log("The public portion of the key is not available to perform the encrypt operation.", + IllegalArgumentException::new); } - verifyKeyPermissions(jsonWebKey, KeyOperation.ENCRYPT); + verifyKeyPermissions(jsonWebKey, KeyOperation.ENCRYPT, LOGGER); AsymmetricEncryptionAlgorithm algo = (AsymmetricEncryptionAlgorithm) baseAlgorithm; @@ -81,7 +79,7 @@ public EncryptResult encrypt(EncryptionAlgorithm algorithm, byte[] plaintext, Re return new EncryptResult(transform.doFinal(plaintext), algorithm, jsonWebKey.getId()); } catch (GeneralSecurityException e) { - throw new RuntimeException(e); + throw LOGGER.throwableAtError().log(e, CoreException::from); } } @@ -102,32 +100,29 @@ public DecryptResult decrypt(EncryptionAlgorithm algorithm, byte[] ciphertext, R if (baseAlgorithm == null) { if (implClient != null) { - try { - return implClient.decrypt(algorithm, ciphertext, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.decrypt(algorithm, ciphertext, requestContext); } - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } else if (!(baseAlgorithm instanceof AsymmetricEncryptionAlgorithm)) { - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } if (rsaKeyPair.getPrivate() == null) { if (implClient != null) { - try { - return implClient.decrypt(algorithm, ciphertext, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.decrypt(algorithm, ciphertext, requestContext); } - throw new IllegalArgumentException( - "The private portion of the key is not available to perform the decrypt operation."); + throw LOGGER.throwableAtError() + .log("The private portion of the key is not available to perform the decrypt operation.", + IllegalArgumentException::new); } - verifyKeyPermissions(jsonWebKey, KeyOperation.DECRYPT); + verifyKeyPermissions(jsonWebKey, KeyOperation.DECRYPT, LOGGER); AsymmetricEncryptionAlgorithm algo = (AsymmetricEncryptionAlgorithm) baseAlgorithm; @@ -136,7 +131,7 @@ public DecryptResult decrypt(EncryptionAlgorithm algorithm, byte[] ciphertext, R return new DecryptResult(transform.doFinal(ciphertext), algorithm, jsonWebKey.getId()); } catch (GeneralSecurityException e) { - throw new RuntimeException(e); + throw LOGGER.throwableAtError().log(e, CoreException::from); } } @@ -150,13 +145,11 @@ public DecryptResult decrypt(DecryptParameters decryptParameters, RequestContext @Override public SignResult sign(SignatureAlgorithm algorithm, byte[] digest, RequestContext requestContext) { if (implClient != null) { - try { - return implClient.sign(algorithm, digest, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.sign(algorithm, digest, requestContext); } else { - throw new UnsupportedOperationException("The sign operation on local RSA key is not currently supported."); + throw LOGGER.throwableAtError() + .log("The sign operation on a local RSA key is not currently supported.", + UnsupportedOperationException::new); } } @@ -164,14 +157,11 @@ public SignResult sign(SignatureAlgorithm algorithm, byte[] digest, RequestConte public VerifyResult verify(SignatureAlgorithm algorithm, byte[] digest, byte[] signature, RequestContext requestContext) { if (implClient != null) { - try { - return implClient.verify(algorithm, digest, signature, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.verify(algorithm, digest, signature, requestContext); } else { - throw new UnsupportedOperationException( - "The verify operation on a local RSA key is not currently supported."); + throw LOGGER.throwableAtError() + .log("The verify operation on a local RSA key is not currently supported.", + UnsupportedOperationException::new); } } @@ -184,32 +174,29 @@ public WrapResult wrapKey(KeyWrapAlgorithm algorithm, byte[] keyToWrap, RequestC if (baseAlgorithm == null) { if (implClient != null) { - try { - return implClient.wrapKey(algorithm, keyToWrap, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.wrapKey(algorithm, keyToWrap, requestContext); } - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", IllegalArgumentException::new); } else if (!(baseAlgorithm instanceof AsymmetricEncryptionAlgorithm)) { - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", IllegalArgumentException::new); } if (rsaKeyPair.getPublic() == null) { if (implClient != null) { - try { - return implClient.wrapKey(algorithm, keyToWrap, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.wrapKey(algorithm, keyToWrap, requestContext); } - throw new IllegalArgumentException( - "The public portion of the key is not available to perform the key wrap operation."); + throw LOGGER.throwableAtError() + .log("The public portion of the key is not available to perform the key wrap operation.", + IllegalArgumentException::new); } - verifyKeyPermissions(jsonWebKey, KeyOperation.WRAP_KEY); + verifyKeyPermissions(jsonWebKey, KeyOperation.WRAP_KEY, LOGGER); AsymmetricEncryptionAlgorithm algo = (AsymmetricEncryptionAlgorithm) baseAlgorithm; @@ -218,7 +205,7 @@ public WrapResult wrapKey(KeyWrapAlgorithm algorithm, byte[] keyToWrap, RequestC return new WrapResult(transform.doFinal(keyToWrap), algorithm, jsonWebKey.getId()); } catch (GeneralSecurityException e) { - throw new RuntimeException(e); + throw LOGGER.throwableAtError().log(e, CoreException::from); } } @@ -232,32 +219,29 @@ public UnwrapResult unwrapKey(KeyWrapAlgorithm algorithm, byte[] encryptedKey, R if (baseAlgorithm == null) { if (implClient != null) { - try { - return implClient.unwrapKey(algorithm, encryptedKey, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.unwrapKey(algorithm, encryptedKey, requestContext); } - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } else if (!(baseAlgorithm instanceof AsymmetricEncryptionAlgorithm)) { - throw new RuntimeException(new NoSuchAlgorithmException(algorithm.toString())); + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log("Algorithm not supported.", CoreException::from); } if (rsaKeyPair.getPrivate() == null) { if (implClient != null) { - try { - return implClient.unwrapKey(algorithm, encryptedKey, requestContext); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + return implClient.unwrapKey(algorithm, encryptedKey, requestContext); } - throw new IllegalArgumentException( - "The private portion of the key is not available to perform the key unwrap operation."); + throw LOGGER.throwableAtError() + .log("The public portion of the key is not available to perform the key wrap operation.", + IllegalArgumentException::new); } - verifyKeyPermissions(jsonWebKey, KeyOperation.UNWRAP_KEY); + verifyKeyPermissions(jsonWebKey, KeyOperation.UNWRAP_KEY, LOGGER); AsymmetricEncryptionAlgorithm algo = (AsymmetricEncryptionAlgorithm) baseAlgorithm; @@ -266,33 +250,33 @@ public UnwrapResult unwrapKey(KeyWrapAlgorithm algorithm, byte[] encryptedKey, R return new UnwrapResult(transform.doFinal(encryptedKey), algorithm, jsonWebKey.getId()); } catch (GeneralSecurityException e) { - throw new RuntimeException(e); + throw LOGGER.throwableAtError().log(e, CoreException::from); } } @Override public SignResult signData(SignatureAlgorithm algorithm, byte[] data, RequestContext requestContext) { - try { - return sign(algorithm, calculateDigest(algorithm, data), requestContext); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } + return sign(algorithm, calculateDigest(algorithm, data), requestContext); } @Override public VerifyResult verifyData(SignatureAlgorithm algorithm, byte[] data, byte[] signature, RequestContext requestContext) { - try { - return verify(algorithm, calculateDigest(algorithm, data), signature, requestContext); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } + return verify(algorithm, calculateDigest(algorithm, data), signature, requestContext); } - private static byte[] calculateDigest(SignatureAlgorithm algorithm, byte[] data) throws NoSuchAlgorithmException { + private static byte[] calculateDigest(SignatureAlgorithm algorithm, byte[] data) { HashAlgorithm hashAlgorithm = SignatureHashResolver.DEFAULT.get(algorithm); - MessageDigest md = MessageDigest.getInstance(Objects.toString(hashAlgorithm, null)); + MessageDigest md; + + try { + md = MessageDigest.getInstance(Objects.toString(hashAlgorithm, null)); + } catch (NoSuchAlgorithmException e) { + throw LOGGER.throwableAtError() + .addKeyValue("algorithm", algorithm.getValue()) + .log(e, IllegalArgumentException::new); + } md.update(data); diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/SignatureEncoding.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/SignatureEncoding.java index 611081bd1625..a298376d4d58 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/SignatureEncoding.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/cryptography/implementation/SignatureEncoding.java @@ -3,8 +3,6 @@ package com.azure.v2.security.keyvault.keys.cryptography.implementation; -import static io.clientcore.core.utils.CoreUtils.bytesToHexString; - final class SignatureEncoding { private SignatureEncoding() { } @@ -17,11 +15,7 @@ private SignatureEncoding() { * @return The raw format of the given ASN.1 DER encoded signature in the form R|S. */ static byte[] fromAsn1Der(byte[] asn1DerSignature, Ecdsa algorithm) { - try { - return Asn1DerSignatureEncoding.decode(asn1DerSignature, algorithm); - } catch (IllegalArgumentException ex) { - throw new IllegalArgumentException(ex.getMessage() + " " + bytesToHexString(asn1DerSignature), ex); - } + return Asn1DerSignatureEncoding.decode(asn1DerSignature, algorithm); } /** @@ -32,10 +26,6 @@ static byte[] fromAsn1Der(byte[] asn1DerSignature, Ecdsa algorithm) { * @return The ASN.1 DER encoded signature of the given signature. */ static byte[] toAsn1Der(byte[] signature, Ecdsa algorithm) { - try { - return Asn1DerSignatureEncoding.encode(signature, algorithm); - } catch (IllegalArgumentException ex) { - throw new IllegalArgumentException(ex.getMessage() + " " + bytesToHexString(signature), ex); - } + return Asn1DerSignatureEncoding.encode(signature, algorithm); } } diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/implementation/KeyVaultCredentialPolicy.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/implementation/KeyVaultCredentialPolicy.java index cf242001c130..d2ce5caeb24a 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/implementation/KeyVaultCredentialPolicy.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/implementation/KeyVaultCredentialPolicy.java @@ -10,6 +10,7 @@ import io.clientcore.core.http.models.Response; import io.clientcore.core.http.pipeline.HttpPipelineNextPolicy; import io.clientcore.core.instrumentation.logging.ClientLogger; +import io.clientcore.core.models.CoreException; import io.clientcore.core.models.binarydata.BinaryData; import io.clientcore.core.utils.Base64Uri; @@ -169,12 +170,12 @@ private boolean authorizeRequestOnChallengeInternal(HttpRequest request, Respons } else { if (!disableChallengeResourceVerification) { if (!isChallengeResourceValid(request, scope)) { - throw LOGGER.logThrowableAsError(new RuntimeException(String.format( - "The challenge resource '%s' does not match the requested domain. If you wish to disable " + throw LOGGER.throwableAtError() + .addKeyValue("scope", scope) + .log("The challenge resource does not match the requested domain. If you wish to disable " + "this check for your client, pass 'true' to the SecretClientBuilder" + ".disableChallengeResourceVerification() method when building it. See " - + "https://aka.ms/azsdk/blog/vault-uri for more information.", - scope))); + + "https://aka.ms/azsdk/blog/vault-uri for more information.", CoreException::from); } } @@ -189,8 +190,9 @@ private boolean authorizeRequestOnChallengeInternal(HttpRequest request, Respons try { authorizationUri = new URI(authorization); } catch (URISyntaxException e) { - throw LOGGER.logThrowableAsError(new RuntimeException( - String.format("The challenge authorization URI '%s' is invalid.", authorization), e)); + throw LOGGER.throwableAtError() + .addKeyValue("authorization", authorization) + .log("The challenge authorization URI is not a valid URI.", e, CoreException::from); } this.challenge = new ChallengeParameters(authorizationUri, new String[] { scope }); @@ -205,7 +207,7 @@ private boolean authorizeRequestOnChallengeInternal(HttpRequest request, Respons String error = challengeAttributes.get("error"); if (error != null) { - LOGGER.atVerbose().log("The challenge response contained an error: " + error); + LOGGER.atVerbose().addKeyValue("error", error).log("The challenge response contained an error"); if ("insufficient_claims".equalsIgnoreCase(error)) { String claims = challengeAttributes.get("claims"); @@ -224,8 +226,9 @@ private boolean authorizeRequestOnChallengeInternal(HttpRequest request, Respons @Override public Response process(HttpRequest request, HttpPipelineNextPolicy next) { if (!"https".equals(request.getUri().getScheme())) { - throw LOGGER.logThrowableAsError( - new RuntimeException("Token credentials require a URL using the HTTPS protocol scheme.")); + throw LOGGER.throwableAtError() + .addKeyValue("scheme", request.getUri().getScheme()) + .log("Token credentials require a URL using the HTTPS protocol scheme.", IllegalStateException::new); } HttpPipelineNextPolicy nextPolicy = next.copy(); @@ -349,8 +352,9 @@ private static boolean isChallengeResourceValid(HttpRequest request, String scop try { scopeUri = new URI(scope); } catch (URISyntaxException e) { - throw LOGGER.logThrowableAsError( - new RuntimeException(String.format("The challenge resource '%s' is not a valid URI.", scope), e)); + throw LOGGER.throwableAtError() + .addKeyValue("scope", scope) + .log("The challenge resource is not a valid URI.", e, IllegalArgumentException::new); } // Returns false if the host specified in the scope does not match the requested domain. diff --git a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/implementation/KeyVaultKeysUtils.java b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/implementation/KeyVaultKeysUtils.java index e5b68990b84b..e7afbba13ebd 100644 --- a/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/implementation/KeyVaultKeysUtils.java +++ b/sdk/keyvault-v2/azure-security-keyvault-keys/src/main/java/com/azure/v2/security/keyvault/keys/implementation/KeyVaultKeysUtils.java @@ -120,7 +120,7 @@ public static void unpackId(String id, Consumer nameConsumer, Consumer io.clientcore core -1.0.0-beta.9 +1.0.0-beta.10