From 9011247ff09367559d9d560811805d4c59e3a735 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 16 Sep 2020 08:24:23 -0600 Subject: [PATCH 01/92] Add JCA provider for Azure KeyVault --- .gitignore | 4 + .../azure-security-keyvault-jca/CHANGELOG.md | 1 + .../azure-security-keyvault-jca/README.md | 1 + .../azure-security-keyvault-jca/pom.xml | 178 +++++++++ .../security/keyvault/jca/AuthClient.java | 84 ++++ .../keyvault/jca/DelegateRestClient.java | 44 +++ .../keyvault/jca/JacksonJsonConverter.java | 53 +++ .../security/keyvault/jca/JsonConverter.java | 28 ++ .../keyvault/jca/JsonConverterFactory.java | 26 ++ .../keyvault/jca/KeyVaultCertificate.java | 249 ++++++++++++ .../security/keyvault/jca/KeyVaultClient.java | 234 +++++++++++ .../keyvault/jca/KeyVaultJcaProvider.java | 67 ++++ .../keyvault/jca/KeyVaultKeyManager.java | 104 +++++ .../jca/KeyVaultKeyManagerFactory.java | 42 ++ .../keyvault/jca/KeyVaultKeyStore.java | 205 ++++++++++ .../jca/KeyVaultLoadStoreParameter.java | 94 +++++ .../keyvault/jca/LegacyRestClient.java | 80 ++++ .../security/keyvault/jca/RestClient.java | 31 ++ .../keyvault/jca/RestClientFactory.java | 26 ++ .../security/keyvault/jca/package-info.java | 7 + .../keyvault/jca/rest/CertificateBundle.java | 105 +++++ .../keyvault/jca/rest/CertificateItem.java | 36 ++ .../jca/rest/CertificateListResult.java | 37 ++ .../keyvault/jca/rest/CertificatePolicy.java | 36 ++ .../keyvault/jca/rest/KeyProperties.java | 36 ++ .../keyvault/jca/rest/OAuthToken.java | 36 ++ .../keyvault/jca/rest/SecretBundle.java | 36 ++ .../security/keyvault/jca/AuthClientTest.java | 30 ++ .../keyvault/jca/DelegateRestClientTest.java | 23 ++ .../jca/JacksonJsonConverterTest.java | 44 +++ .../keyvault/jca/KeyVaultCertificateTest.java | 366 ++++++++++++++++++ .../keyvault/jca/KeyVaultClientTest.java | 37 ++ .../keyvault/jca/KeyVaultJcaProviderTest.java | 39 ++ .../keyvault/jca/KeyVaultKeyStoreTest.java | 237 ++++++++++++ .../jca/KeyVaultLoadStoreParameterTest.java | 24 ++ .../keyvault/jca/LegacyRestClientTest.java | 23 ++ .../keyvault/jca/RestClientFactoryTest.java | 22 ++ .../keyvault/jca/ServerSocketTest.java | 144 +++++++ sdk/keyvault/pom.xml | 1 + .../CHANGELOG.md | 16 + .../README.md | 1 + .../pom.xml | 173 +++++++++ 42 files changed, 3060 insertions(+) create mode 100644 sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md create mode 100644 sdk/keyvault/azure-security-keyvault-jca/README.md create mode 100644 sdk/keyvault/azure-security-keyvault-jca/pom.xml create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/package-info.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultClientTest.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java create mode 100644 sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md create mode 100644 sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md create mode 100644 sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml diff --git a/.gitignore b/.gitignore index 08f1238124660..72b02a4735c3f 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,7 @@ ClientAggregatePom.xml # Anaconda virtual venv + +# NetBeans +nbproject +nb-configuration.xml \ No newline at end of file diff --git a/sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md @@ -0,0 +1 @@ + diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -0,0 +1 @@ + diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml new file mode 100644 index 0000000000000..943b66bcdc21e --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -0,0 +1,178 @@ + + + + 4.0.0 + com.azure + azure-security-keyvault-jca + 1.0.0 + Microsoft Azure JCA Provider for KeyVault + The Java Crypto Architecture (JCA) Provider for Azure KeyVault + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-resources-plugin + 3.2.0 + + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + + shade + + + + + com.fasterxml.jackson + com.azure.keyvault.jca.com.fasterxml.jackson + + + org.apache.commons + com.azure.keyvault.jca.org.apache.commons + + + org.apache.hc + com.azure.keyvault.jca.org.apache.hc + + + mozilla + com.azure.keyvault.jca.mozilla + + + org.slf4j + com.azure.keyvault.jca.org.slf4j + + + + + + true + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + true + + + + org.jacoco + jacoco-maven-plugin + 0.8.5 + + + default-prepare-agent + + prepare-agent + + + + default-report + prepare-package + + report + + + + + + + + + + org.apache.httpcomponents.client5 + httpclient5 + 5.0.1 + true + + + + com.fasterxml.jackson.core + jackson-databind + 2.11.2 + true + + + + org.junit.jupiter + junit-jupiter-api + 5.6.0 + test + + + org.junit.jupiter + junit-jupiter-params + 5.6.0 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.0 + test + + + + + it + + + + azure.keyvault.uri + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + false + + ${azure.keyvault.uri} + ${azure.tenant.id} + ${azure.client.id} + ${azure.client.secret} + + + + + + + + + UTF-8 + + diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java new file mode 100644 index 0000000000000..ef37ce523600d --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License./ +package com.azure.security.keyvault.jca; + +import com.azure.security.keyvault.jca.rest.OAuthToken; + +/** + * The REST client specific to getting an access token for Azure REST APIs. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +class AuthClient extends DelegateRestClient { + + /** + * Stores the Client ID fragment. + */ + private static final String CLIENT_ID_FRAGMENT = "&client_id="; + + /** + * Stores the Client Secret fragment. + */ + private static final String CLIENT_SECRET_FRAGMENT = "&client_secret="; + + /** + * Stores the Grant Type fragment. + */ + private static final String GRANT_TYPE_FRAGMENT = "grant_type=client_credentials"; + + /** + * Stores the Resource fragment. + */ + private static final String RESOURCE_FRAGMENT = "&resource="; + + /** + * Stores the OAuth2 token base URL. + */ + private static final String OAUTH2_TOKEN_BASE_URL = "https://login.microsoftonline.com/"; + + /** + * Stores the OAuth2 token postfix. + */ + private static final String OAUTH2_TOKEN_POSTFIX = "/oauth2/token"; + + /** + * Constructor. + */ + public AuthClient() { + super(RestClientFactory.createClient()); + } + + /** + * Get an access token. + * + * @param resource the resource. + * @param tenantId the tenant ID. + * @param clientId the client ID. + * @param clientSecret the client secret. + * @return the access token. + */ + public String getAuthorizationToken(String resource, String tenantId, + String clientId, String clientSecret) { + + String result = null; + + StringBuilder oauth2Url = new StringBuilder(); + oauth2Url.append(OAUTH2_TOKEN_BASE_URL) + .append(tenantId) + .append(OAUTH2_TOKEN_POSTFIX); + + StringBuilder requestBody = new StringBuilder(); + requestBody.append(GRANT_TYPE_FRAGMENT) + .append(CLIENT_ID_FRAGMENT).append(clientId) + .append(CLIENT_SECRET_FRAGMENT).append(clientSecret) + .append(RESOURCE_FRAGMENT).append(resource); + + String body = post(oauth2Url.toString(), requestBody.toString(), "application/x-www-form-urlencoded"); + if (body != null) { + JsonConverter converter = JsonConverterFactory.createJsonConverter(); + OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); + result = token.getAccess_token(); + } + return result; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java new file mode 100644 index 0000000000000..7da2879c16461 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.util.Map; + +/** + * A RestClient that delegates to another RestClient. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +class DelegateRestClient implements RestClient { + + /** + * Stores the delegate. + */ + private final RestClient delegate; + + /** + * Constructor. + */ + public DelegateRestClient(RestClient delegate) { + this.delegate = delegate; + } + + @Override + public String get(String url, Map headers) { + return delegate.get(url, headers); + } + + /** + * Get the delegate. + * + * @return the delegate. + */ + public RestClient getDelegate() { + return delegate; + } + + @Override + public String post(String url, String body, String contentType) { + return delegate.post(url, body, contentType); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java new file mode 100644 index 0000000000000..c8105299b4a70 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * The JSON-B JsonConverter. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +class JacksonJsonConverter implements JsonConverter { + + /** + * From JSON. + * + * @param string the string. + * @param resultClass the result class. + * @return the object, or null if the conversion failed. + */ + @Override + public Object fromJson(String string, Class resultClass) { + Object result = null; + try { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + result = objectMapper.readValue(string, resultClass); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return result; + } + + /** + * To JSON. + * + * @param object the object. + * @return the JSON string. + */ + @Override + public String toJson(Object object) { + String result = null; + try { + ObjectMapper mapper = new ObjectMapper(); + result = mapper.writeValueAsString(object); + } catch (JsonProcessingException e) { + // consider logging. + } + return result; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java new file mode 100644 index 0000000000000..008dd3979e79b --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +/** + * The JSON converter API. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +interface JsonConverter { + + /** + * To JSON. + * + * @param object the object to transform. + * @return the JSON string. + */ + String toJson(Object object); + + /** + * From JSON. + * + * @param string the JSON string to transform. + * @param resultClass the result class. + * @return the object, or null if the conversion failed. + */ + Object fromJson(String string, Class resultClass); +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java new file mode 100644 index 0000000000000..3214bf38cda6b --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +/** + * The JsonConverterFactory. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +class JsonConverterFactory { + + /** + * Constructor. + */ + private JsonConverterFactory() { + } + + /** + * Static helper method to create a JsonConverter. + * + * @return the JsonConverter. + */ + static JsonConverter createJsonConverter() { + return new JacksonJsonConverter(); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java new file mode 100644 index 0000000000000..3238c4b11cbf6 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java @@ -0,0 +1,249 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Principal; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.Set; + +/** + * The KeyVault certificate. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +class KeyVaultCertificate extends X509Certificate { + + /** + * Stores the delegate. + */ + private final X509Certificate delegate; + + /** + * Constructor. + * + * @param delegate the delegate. + */ + KeyVaultCertificate(X509Certificate delegate) { + super(); + this.delegate = delegate; + } + + /** + * @see X509Certificate#checkValidity() + */ + @Override + public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { + delegate.checkValidity(); + } + + /** + * @see X509Certificate#checkValidity(java.util.Date) + */ + @Override + public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException { + delegate.checkValidity(date); + } + + /** + * @see X509Certificate#getBasicConstraints() + */ + @Override + public int getBasicConstraints() { + return delegate.getBasicConstraints(); + } + + /** + * @see X509Certificate#getCriticalExtensionOIDs() + */ + @Override + public Set getCriticalExtensionOIDs() { + return delegate.getCriticalExtensionOIDs(); + } + + /** + * @see X509Certificate#getEncoded() + */ + @Override + public byte[] getEncoded() throws CertificateEncodingException { + return delegate.getEncoded(); + } + + /** + * @see X509Certificate#getExtensionValue(java.lang.String) + */ + @Override + public byte[] getExtensionValue(String oid) { + return delegate.getExtensionValue(oid); + } + + /** + * @see X509Certificate#getIssuerDN() + */ + @Override + public Principal getIssuerDN() { + return delegate.getIssuerDN(); + } + + /** + * @see X509Certificate#getIssuerUniqueID() + */ + @Override + public boolean[] getIssuerUniqueID() { + return delegate.getIssuerUniqueID(); + } + + /** + * @see X509Certificate#getKeyUsage() + */ + @Override + public boolean[] getKeyUsage() { + return delegate.getKeyUsage(); + } + + /** + * @see X509Certificate#getNonCriticalExtensionOIDs() + */ + @Override + public Set getNonCriticalExtensionOIDs() { + return delegate.getNonCriticalExtensionOIDs(); + } + + /** + * @see X509Certificate#getNotAfter() + */ + @Override + public Date getNotAfter() { + return delegate.getNotAfter(); + } + + /** + * @see X509Certificate#getNotBefore() + */ + @Override + public Date getNotBefore() { + return delegate.getNotBefore(); + } + + /** + * @see X509Certificate#getPublicKey() + */ + @Override + public PublicKey getPublicKey() { + return delegate.getPublicKey(); + } + + /** + * @see X509Certificate#getSerialNumber() + */ + @Override + public BigInteger getSerialNumber() { + return delegate.getSerialNumber(); + } + + /** + * @see X509Certificate#getSigAlgName() + */ + @Override + public String getSigAlgName() { + return delegate.getSigAlgName(); + } + + /** + * @see X509Certificate#getSigAlgOID() + */ + @Override + public String getSigAlgOID() { + return delegate.getSigAlgOID(); + } + + /** + * @see X509Certificate#getSigAlgParams() + */ + @Override + public byte[] getSigAlgParams() { + return delegate.getSigAlgParams(); + } + + /** + * @see X509Certificate#getSignature() + */ + @Override + public byte[] getSignature() { + return delegate.getSignature(); + } + + /** + * @see X509Certificate#getSubjectDN() + */ + @Override + public Principal getSubjectDN() { + return delegate.getSubjectDN(); + } + + /** + * @see X509Certificate#getSubjectUniqueID() + */ + @Override + public boolean[] getSubjectUniqueID() { + return delegate.getSubjectUniqueID(); + } + + /** + * @see X509Certificate#getTBSCertificate() + */ + @Override + public byte[] getTBSCertificate() throws CertificateEncodingException { + return delegate.getTBSCertificate(); + } + + /** + * @see X509Certificate#getVersion() + */ + @Override + public int getVersion() { + return delegate.getVersion(); + } + + /** + * @see X509Certificate#hasUnsupportedCriticalExtension() + */ + @Override + public boolean hasUnsupportedCriticalExtension() { + return delegate.hasUnsupportedCriticalExtension(); + } + + /** + * @see X509Certificate#toString() + */ + @Override + public String toString() { + return delegate.toString(); + } + + /** + * @see X509Certificate#verify(java.security.PublicKey) + */ + @Override + public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { + delegate.verify(key); + } + + /** + * @see X509Certificate#verify(java.security.PublicKey, java.security.Provider) + */ + @Override + public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { + delegate.verify(key, sigProvider); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java new file mode 100644 index 0000000000000..4a1b928941b30 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java @@ -0,0 +1,234 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import com.azure.security.keyvault.jca.rest.CertificateListResult; +import com.azure.security.keyvault.jca.rest.CertificateItem; +import com.azure.security.keyvault.jca.rest.CertificateBundle; +import com.azure.security.keyvault.jca.rest.SecretBundle; +import java.io.ByteArrayInputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.security.Key; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; + +/** + * The REST client specific to Azure KeyVault. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +class KeyVaultClient extends DelegateRestClient { + + /** + * Stores the API version postfix. + */ + private static final String API_VERSION_POSTFIX = "?api-version=7.1"; + + /** + * Stores the KeyVault URI. + */ + private String keyVaultUri; + + /** + * Stores the tenant ID. + */ + private String tenantId; + + /** + * Stores the client ID. + */ + private String clientId; + + /** + * Stores the client secret. + */ + private String clientSecret; + + /** + * Constructor. + * + * @param keyVaultUri the KeyVault URI. + */ + public KeyVaultClient(String keyVaultUri) { + super(RestClientFactory.createClient()); + if (!keyVaultUri.endsWith("/")) { + keyVaultUri = keyVaultUri + "/"; + } + this.keyVaultUri = keyVaultUri; + } + + /** + * Constructor. + * + * @param keyVaultUri the KeyVault URI. + * @param tenantId the tenant ID. + * @param clientId the client ID. + * @param clientSecret the client secret. + */ + public KeyVaultClient(String keyVaultUri, String tenantId, String clientId, String clientSecret) { + this(keyVaultUri); + this.tenantId = tenantId; + this.clientId = clientId; + this.clientSecret = clientSecret; + } + + /** + * Get the access token. + * + * @return the access token. + */ + private String getAccessToken() { + String accessToken = null; + try { + AuthClient authClient = new AuthClient(); + String resource = URLEncoder.encode("https://vault.azure.net", "UTF-8"); + accessToken = authClient.getAuthorizationToken(resource, tenantId, clientId, clientSecret); + } catch (UnsupportedEncodingException uee) { + uee.printStackTrace(); + } + return accessToken; + } + + /** + * Get the list of aliases. + * + * @return the list of aliases. + */ + public List getAliases() { + ArrayList result = new ArrayList<>(); + + StringBuilder url = new StringBuilder(); + url.append(keyVaultUri) + .append("certificates") + .append(API_VERSION_POSTFIX); + + HashMap headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + getAccessToken()); + + String body = get(url.toString(), headers); + + CertificateListResult certificateListResult = null; + if (body != null) { + JsonConverter converter = JsonConverterFactory.createJsonConverter(); + certificateListResult = (CertificateListResult) converter.fromJson(body, CertificateListResult.class); + } + if (certificateListResult != null && certificateListResult.getValue().size() > 0) { + for (CertificateItem certificateItem : certificateListResult.getValue()) { + String alias = certificateItem.getId(); + alias = alias.substring(alias.indexOf("certificates") + "certificates".length() + 1); + result.add(alias); + } + } + + return result; + } + + /** + * Get the certificate bundle. + * + * @param alias the alias. + * @return the certificate bundle. + */ + private CertificateBundle getCertificateBundle(String alias) { + CertificateBundle result = null; + + StringBuilder url = new StringBuilder(); + url.append(keyVaultUri) + .append("certificates/") + .append(alias) + .append(API_VERSION_POSTFIX); + + HashMap headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + getAccessToken()); + + String body = get(url.toString(), headers); + + if (body != null) { + JsonConverter converter = JsonConverterFactory.createJsonConverter(); + result = (CertificateBundle) converter.fromJson(body, CertificateBundle.class); + } + + return result; + } + + /** + * Get the certificate. + * + * @param alias the alias. + * @return the certificate, or null if not found. + */ + public Certificate getCertificate(String alias) { + X509Certificate certificate = null; + CertificateBundle certificateBundle = getCertificateBundle(alias); + if (certificateBundle != null) { + String certificateString = certificateBundle.getCer(); + if (certificateString != null) { + try { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + certificate = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(Base64.getDecoder() + .decode(certificateBundle.getCer()))); + } catch (CertificateException ce) { + ce.printStackTrace(); + } + } + } + return certificate; + } + + /** + * Get the key. + * + * @param alias the alias. + * @param password the password. + * @return the key. + */ + public Key getKey(String alias, char[] password) { + Key key = null; + CertificateBundle certificateBundle = getCertificateBundle(alias); + if (certificateBundle != null + && certificateBundle.getPolicy() != null + && certificateBundle.getPolicy().getKey_props() != null + && certificateBundle.getPolicy().getKey_props().isExportable()) { + + // + // Because the certificate is exportable the private key is + // available. So we'll use the KeyVault Secrets API to get the + // private key. + // + String certificateSecretUri = certificateBundle.getSid(); + HashMap headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + getAccessToken()); + String body = get(certificateSecretUri + API_VERSION_POSTFIX, headers); + if (body != null) { + JsonConverter converter = JsonConverterFactory.createJsonConverter(); + SecretBundle secretBundle = (SecretBundle) converter.fromJson(body, SecretBundle.class); + + try { + KeyStore keyStore = KeyStore.getInstance("PKCS12"); + keyStore.load(new ByteArrayInputStream( + Base64.getDecoder().decode(secretBundle.getValue())), "".toCharArray()); + alias = keyStore.aliases().nextElement(); + key = keyStore.getKey(alias, "".toCharArray()); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } else { + // + // The private key is not available so the certificate cannot be + // used for server side certificates or mTLS. Since we do not know + // the intent of the usage at this stage we skip this key. + // + } + return key; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java new file mode 100644 index 0000000000000..58102abfad059 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.Provider; +import java.util.Arrays; + +/** + * The Azure KeyVault security provider. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultJcaProvider extends Provider { + + /** + * Stores the serial version UID. + */ + private static final long serialVersionUID = 1L; + + /** + * Stores the information. + */ + private static final String INFO = "Azure KeyVault Security Provider"; + + /** + * Stores the name. + */ + private static final String NAME = "AzureKeyVault"; + + /** + * Stores the version. + */ + private static final Double VERSION = 1.0; + + /** + * Constructor. + */ + public KeyVaultJcaProvider() { + super(NAME, VERSION, INFO); + initialize(); + } + + /** + * Initialize the provider. + */ + private void initialize() { + AccessController.doPrivileged((PrivilegedAction) () -> { + putService(new Provider.Service(this, "KeyManagerFactory", "SunX509", + KeyVaultKeyManagerFactory.class.getName(), + Arrays.asList("SunX509", "IbmX509"), null)); + + /* + * Note for Tomcat we needed to add "DKS" as an algorithm so it does + * not use an in-memory key store and later on can wrap the + * KeyManager using its JSSEKeyManager so the key alias is known. + * + * See SSLUtilBase.getKeyManagers and look for the + * "DKS".equalsIgnoreCase(certificate.getCertificateKeystoreType() + */ + putService(new Provider.Service(this, "KeyStore", "AzureKeyVault", + KeyVaultKeyStore.class.getName(), Arrays.asList("AzureKeyVault", "DKS"), null)); + return null; + }); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java new file mode 100644 index 0000000000000..95e0a4a3a19d2 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java @@ -0,0 +1,104 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.net.Socket; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.Principal; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.X509ExtendedKeyManager; + +/** + * The KeyVault variant of the X509ExtendedKeyManager. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultKeyManager extends X509ExtendedKeyManager { + + /** + * Stores the keystore. + */ + private KeyStore keystore; + + /** + * Stores the password. + */ + private char[] password; + + /** + * Constructor. + * + * @param keystore the keystore. + */ + public KeyVaultKeyManager(KeyStore keystore, char[] password) { + this.keystore = keystore; + this.password = password; + } + + @Override + public String[] getClientAliases(String keyType, Principal[] issuers) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String[] getServerAliases(String keyType, Principal[] issuers) { + String[] serverAliases = new String[0]; + try { + serverAliases = Collections.list(keystore.aliases()).toArray(new String[0]); + } catch (KeyStoreException kse) { + kse.printStackTrace(); + } + return serverAliases; + } + + @Override + public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public X509Certificate[] getCertificateChain(String alias) { + List chain = new ArrayList<>(); + try { + Certificate[] keystoreChain = keystore.getCertificateChain(alias); + if (keystoreChain.length > 0) { + for(int i=0; i keyManagers = new ArrayList<>(); + + @Override + protected void engineInit(KeyStore ks, char[] password) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { + KeyVaultKeyManager manager = new KeyVaultKeyManager(ks, password); + keyManagers.add(manager); + } + + @Override + protected void engineInit(ManagerFactoryParameters spec) throws InvalidAlgorithmParameterException { + } + + @Override + protected KeyManager[] engineGetKeyManagers() { + return keyManagers.toArray(new KeyManager[0]); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java new file mode 100644 index 0000000000000..b74f0e932ef78 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java @@ -0,0 +1,205 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.Key; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.KeyStoreSpi; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableEntryException; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; + +/** + * The Azure KeyVault implementation of the KeyStoreSpi. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultKeyStore extends KeyStoreSpi { + + /** + * Stores the list of aliases. + */ + private List certificateAliases; + + /** + * Stores the certificates by alias. + */ + private final HashMap certificates = new HashMap<>(); + + /** + * Stores the certificate keys by alias. + */ + private final HashMap certificateKeys = new HashMap<>(); + + /** + * Stores the creation date. + */ + private final Date creationDate; + + /** + * Stores the key vault. + */ + private KeyVaultClient keyVault; + + /** + * Constructor. + */ + public KeyVaultKeyStore() { + creationDate = new Date(); + String keyVaultUri = System.getProperty("azure.keyvault.uri"); + String tenantId = System.getProperty("azure.keyvault.tenantId"); + String clientId = System.getProperty("azure.keyvault.clientId", null); + String clientSecret = System.getProperty("azure.keyvault.clientSecret", null); + keyVault = new KeyVaultClient(keyVaultUri, tenantId, clientId, clientSecret); + } + + @Override + public Enumeration engineAliases() { + if (certificateAliases == null) { + certificateAliases = keyVault.getAliases(); + } + return Collections.enumeration(certificateAliases); + } + + @Override + public boolean engineContainsAlias(String alias) { + return engineIsCertificateEntry(alias); + } + + @Override + public void engineDeleteEntry(String alias) throws KeyStoreException { + } + + @Override + public boolean engineEntryInstanceOf(String alias, Class entryClass) { + return super.engineEntryInstanceOf(alias, entryClass); + } + + @Override + public Certificate engineGetCertificate(String alias) { + Certificate certificate; + if (certificates.containsKey(alias)) { + certificate = certificates.get(alias); + } else { + certificate = keyVault.getCertificate(alias); + if (certificate != null) { + certificates.put(alias, certificate); + if (!certificateAliases.contains(alias)) { + certificateAliases.add(alias); + } + } + } + return certificate; + } + + @Override + public String engineGetCertificateAlias(Certificate cert) { + String alias = null; + if (certificates.containsValue(cert)) { + for (String candidate : certificates.keySet()) { + if (certificates.get(candidate).equals(cert)) { + alias = candidate; + break; + } + } + } + return alias; + } + + @Override + public Certificate[] engineGetCertificateChain(String alias) { + Certificate[] chain = null; + Certificate certificate = engineGetCertificate(alias); + if (certificate != null) { + chain = new Certificate[1]; + chain[0] = certificate; + } + return chain; + } + + @Override + public Date engineGetCreationDate(String alias) { + return creationDate; + } + + @Override + public KeyStore.Entry engineGetEntry(String alias, KeyStore.ProtectionParameter protParam) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException { + return super.engineGetEntry(alias, protParam); + } + + @Override + public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { + Key key; + if (certificateKeys.containsKey(alias)) { + key = certificateKeys.get(alias); + } else { + key = keyVault.getKey(alias, password); + if (key != null) { + certificateKeys.put(alias, key); + if (!certificateAliases.contains(alias)) { + certificateAliases.add(alias); + } + } + } + return key; + } + + @Override + public boolean engineIsCertificateEntry(String alias) { + if (certificateAliases == null) { + certificateAliases = keyVault.getAliases(); + } + return certificateAliases.contains(alias); + } + + @Override + public boolean engineIsKeyEntry(String alias) { + return engineIsCertificateEntry(alias); + } + + @Override + public void engineLoad(KeyStore.LoadStoreParameter param) throws IOException, NoSuchAlgorithmException, CertificateException { + if (param instanceof KeyVaultLoadStoreParameter) { + KeyVaultLoadStoreParameter parameter = (KeyVaultLoadStoreParameter) param; + keyVault = new KeyVaultClient( + parameter.getUri(), parameter.getTenantId(), + parameter.getClientId(), parameter.getClientSecret()); + } + } + + @Override + public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { + } + + @Override + public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException { + } + + @Override + public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { + } + + @Override + public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException { + } + + @Override + public int engineSize() { + return certificateAliases != null ? certificateAliases.size() : 0; + } + + @Override + public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java new file mode 100644 index 0000000000000..bedcbb4f9d674 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java @@ -0,0 +1,94 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.security.KeyStore; + +/** + * The Azure KeyVault LoadStoreParameter of the KeyStoreSpi. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultLoadStoreParameter implements KeyStore.LoadStoreParameter { + + /** + * Stores the URI. + */ + private final String uri; + + /** + * Stores the tenant id. + */ + private final String tenantId; + + /** + * Stores the client ID. + */ + private final String clientId; + + /** + * Stores the client secret. + */ + private final String clientSecret; + + /** + * Constructor. + * + * @param uri the KeyVault URI. + * @param tenantId the tenant ID. + * @param clientId the client ID. + * @param clientSecret the client secret. + */ + public KeyVaultLoadStoreParameter(String uri, String tenantId, String clientId, String clientSecret) { + this.uri = uri; + this.tenantId = tenantId; + this.clientId = clientId; + this.clientSecret = clientSecret; + } + + /** + * Get the protection parameter. + * + * @return null + */ + @Override + public KeyStore.ProtectionParameter getProtectionParameter() { + return null; + } + + /** + * Get the client id. + * + * @return the client id. + */ + public String getClientId() { + return clientId; + } + + /** + * Get the client secret. + * + * @return the client secret. + */ + public String getClientSecret() { + return clientSecret; + } + + /** + * Get the tenant id. + * + * @return the tenant id. + */ + public String getTenantId() { + return tenantId; + } + + /** + * Get the uri. + * + * @return the URI. + */ + public String getUri() { + return uri; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java new file mode 100644 index 0000000000000..e2525413b43c4 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java @@ -0,0 +1,80 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.io.IOException; +import java.util.Map; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.ClassicHttpResponse; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.io.HttpClientResponseHandler; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.io.entity.HttpEntities; + +/** + * The RestClient that uses the Apache HttpClient class. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +class LegacyRestClient implements RestClient { + + /** + * Constructor. + */ + public LegacyRestClient() { + } + + @Override + public String get(String url, Map headers) { + String result = null; + try (CloseableHttpClient client = HttpClients.createDefault()) { + HttpGet httpGet = new HttpGet(url); + if (headers != null) { + headers.entrySet().forEach(entry -> { + String key = entry.getKey(); + String value = entry.getValue(); + httpGet.addHeader(key, value); + }); + } + HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { + int status = response.getCode(); + String result1 = null; + if (status >= 200 && status < 300) { + HttpEntity entity = response.getEntity(); + result1 = entity != null ? EntityUtils.toString(entity) : null; + } + return result1; + }; + result = client.execute(httpGet, responseHandler); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return result; + } + + @Override + public String post(String url, String body, String contentType) { + String result = null; + try (CloseableHttpClient client = HttpClients.createDefault()) { + HttpPost httpPost = new HttpPost(url); + httpPost.setEntity(HttpEntities.create(body, ContentType.create(contentType))); + HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { + int status = response.getCode(); + String result1 = null; + if (status >= 200 && status < 300) { + HttpEntity entity = response.getEntity(); + result1 = entity != null ? EntityUtils.toString(entity) : null; + } + return result1; + }; + result = client.execute(httpPost, responseHandler); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return result; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java new file mode 100644 index 0000000000000..d3e46e8d2b5f7 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.util.Map; + +/** + * The REST client API. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +interface RestClient { + + /** + * Issue a GET request. + * + * @param url the URL. + * @param headers the request headers map. + * @return the response body as a string. + */ + String get(String url, Map headers); + + /** + * Issue a POST request. + * + * @param url the URL. + * @param body the request body. + * @return the response body as a string. + */ + String post(String url, String body, String contentType); +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java new file mode 100644 index 0000000000000..77e7f3308bae5 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +/** + * The RestClientFactory. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +class RestClientFactory { + + /** + * Constructor. + */ + private RestClientFactory() { + } + + /** + * Static helper method to create a RestClient. + * + * @return the RestClient. + */ + static RestClient createClient() { + return new LegacyRestClient(); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/package-info.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/package-info.java new file mode 100644 index 0000000000000..e40cd274cf580 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/package-info.java @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +/** + * The Azure KeyVault JCA Provider package. + */ +package com.azure.security.keyvault.jca; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java new file mode 100644 index 0000000000000..7a99b5ec6e94f --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java @@ -0,0 +1,105 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca.rest; + +import java.io.Serializable; + +/** + * The CertificateBundle REST model. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class CertificateBundle implements Serializable { + + /** + * Stores the CER bytes. + */ + private String cer; + + /** + * Stores the Key ID. + */ + private String kid; + + /** + * Stores the policy. + */ + private CertificatePolicy policy; + + /** + * Stores the Secret ID. + */ + private String sid; + + /** + * Get the CER string. + * + * @return the CER string. + */ + public String getCer() { + return cer; + } + + /** + * Get the Key ID. + * + * @return the Key ID. + */ + public String getKid() { + return kid; + } + + /** + * Get the policy. + * + * @return the policy. + */ + public CertificatePolicy getPolicy() { + return policy; + } + + /** + * Get the Secret ID. + * + * @return the Secret ID. + */ + public String getSid() { + return sid; + } + + /** + * Set the CER string. + * + * @param cer the CER string. + */ + public void setCer(String cer) { + this.cer = cer; + } + + /** + * Set the Key ID. + * + * @param kid the Key ID. + */ + public void setKid(String kid) { + this.kid = kid; + } + + /** + * Set the policy. + * + * @param policy the policy. + */ + public void setPolicy(CertificatePolicy policy) { + this.policy = policy; + } + + /** + * Set the Secret ID. + * + * @param sid the Secret ID. + */ + public void setSid(String sid) { + this.sid = sid; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java new file mode 100644 index 0000000000000..6fa8174d1af6b --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca.rest; + +import java.io.Serializable; + +/** + * The CertificateItem REST model. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class CertificateItem implements Serializable { + + /** + * Stores the id. + */ + private String id; + + /** + * Get the id. + * + * @return the id. + */ + public String getId() { + return id; + } + + /** + * Set the id. + * + * @param id the id. + */ + public void setId(String id) { + this.id = id; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java new file mode 100644 index 0000000000000..4af24481edd00 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca.rest; + +import java.io.Serializable; +import java.util.List; + +/** + * The CertificateItem REST model. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class CertificateListResult implements Serializable { + + /** + * Stores the value. + */ + private List value; + + /** + * Get the value. + * + * @return the id. + */ + public List getValue() { + return value; + } + + /** + * Set the value. + * + * @param value the value. + */ + public void setValue(List value) { + this.value = value; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java new file mode 100644 index 0000000000000..2c4f0cb78afa2 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca.rest; + +import java.io.Serializable; + +/** + * The CertificatePolicy REST model. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class CertificatePolicy implements Serializable { + + /** + * Stores the key properties. + */ + private KeyProperties keyProperties; + + /** + * Get the key properties. + * + * @return the key properties. + */ + public KeyProperties getKey_props() { + return keyProperties; + } + + /** + * Set the key properties. + * + * @param keyProperties the key properties. + */ + public void setKey_props(KeyProperties keyProperties) { + this.keyProperties = keyProperties; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java new file mode 100644 index 0000000000000..1411fa858c8c1 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca.rest; + +import java.io.Serializable; + +/** + * The KeyProperties REST model. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyProperties implements Serializable { + + /** + * Stores if the key is exportable. + */ + private boolean exportable; + + /** + * Is the key exportable. + * + * @return true if exportable, false otherwise. + */ + public boolean isExportable() { + return exportable; + } + + /** + * Set the key to be exportable. + * + * @param exportable the exportable flag. + */ + public void setExportable(boolean exportable) { + this.exportable = exportable; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java new file mode 100644 index 0000000000000..ec310f9b9163f --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca.rest; + +import java.io.Serializable; + +/** + * An OAuth2 token. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class OAuthToken implements Serializable { + + /** + * Stores the access token. + */ + private String access_token; + + /** + * Get the access token. + * + * @return the access token. + */ + public String getAccess_token() { + return access_token; + } + + /** + * Set the access token. + * + * @param accessToken the access token. + */ + public void setAccess_token(String accessToken) { + this.access_token = accessToken; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java new file mode 100644 index 0000000000000..4d9de1a0e0007 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca.rest; + +import java.io.Serializable; + +/** + * The SecretBundle REST model. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class SecretBundle implements Serializable { + + /** + * Stores the value. + */ + private String value; + + /** + * Get the value. + * + * @return the value. + */ + public String getValue() { + return value; + } + + /** + * Set the value. + * + * @param value the value. + */ + public void setValue(String value) { + this.value = value; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java new file mode 100644 index 0000000000000..6821b5405a72b --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.net.URLEncoder; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import org.junit.jupiter.api.Test; + +/** + * The JUnit test for the AuthClient. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class AuthClientTest { + + /** + * Test getAuthorizationToken method. + */ + @Test + public void testGetAuthorizationToken() throws Exception { + String tenantId = "72f988bf-86f1-41af-91ab-2d7cd011db47"; + String clientId = "2b8f123b-b18a-4077-bce0-42e10ce8bbab"; + String clientSecret = "72-~tZ9~cG~rimDI0EkQSMQ1D9DYmGmI_I"; + AuthClient authClient = new AuthClient(); + String result = authClient.getAuthorizationToken( + "https://management.azure.com/", tenantId, clientId, + URLEncoder.encode(clientSecret, "UTF-8")); + assertNotNull(result); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java new file mode 100644 index 0000000000000..578e36fe4b30c --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +/** + * The JUnit tests for the DelegateRestClient class. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class DelegateRestClientTest { + + /** + * Test of getDelegate method, of class DelegateRestClient. + */ + @Test + public void testGetDelegate() { + DelegateRestClient client = new DelegateRestClient(RestClientFactory.createClient()); + assertNotNull(client.getDelegate()); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java new file mode 100644 index 0000000000000..72098f4af9253 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import com.azure.security.keyvault.jca.rest.CertificateBundle; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + +/** + * The JUnit tests for the JsonbJsonConverter class. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class JacksonJsonConverterTest { + + /** + * Test fromJson method. + */ + @Test + public void testFromJson() { + String string = "{ \"cer\": \"cer\" }"; + JacksonJsonConverter converter = new JacksonJsonConverter(); + CertificateBundle bundle = (CertificateBundle) converter.fromJson(string, CertificateBundle.class); + assertNotNull(bundle); + assertEquals("cer", bundle.getCer()); + } + + /** + * Test toJson method. + * + * @throws Exception when a serious error occurs. + */ + @Test + public void testToJson() throws Exception { + JacksonJsonConverter converter = new JacksonJsonConverter(); + CertificateBundle bundle = new CertificateBundle(); + bundle.setCer("value"); + String string = converter.toJson(bundle); + assertTrue(string.contains("cer")); + assertTrue(string.contains("\"value\"")); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java new file mode 100644 index 0000000000000..d8f4001f02065 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java @@ -0,0 +1,366 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.io.ByteArrayInputStream; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.ProviderException; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateFactory; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.X509Certificate; +import java.util.Base64; +import java.util.Date; +import java.util.Set; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * The JUnit tests for the KeyVaultCertificate class. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultCertificateTest { + + /** + * Stores the CER test certificate (which is valid til 2120). + */ + private static final String TEST_CERTIFICATE + = "MIIDeDCCAmCgAwIBAgIQGghBu97rQJKNnUHPWU7xjDANBgkqhkiG9w0BAQsFADAk" + + "MSIwIAYDVQQDExlodW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMCAXDTIwMDkwMjE3" + + "NDUyNFoYDzIxMjAwOTAyMTc1NTI0WjAkMSIwIAYDVQQDExlodW5kcmVkLXllYXJz" + + "LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuU14" + + "btkN5wmcO2WKXqm1NUKXzi79EtqiFFkrLgPAwj5NNwMw2Akm3GpdEpwkJ8/q3l7d" + + "frDEVOO9gwZbz7xppyqutjxjllw8CCgjFdfK02btz56CGgh3X25ZZtzPbuMZJM0j" + + "o4mVEdaFNJ0eUeMppS0DcbbuTWCF7Jf1gvr8GVqx+E0IJUFkE+D4kdTbnJSaeK0A" + + "KEt94z88MPX18h8ud14uRVmUCYVZrZeswdE2tO1BpazrXELHuXCtrjGxsDDjDzeP" + + "98aFI9kblkqoJS4TsmloLEjwZLm80cyJDEmpXXMtR7C0FFXFI1BAtIa4mxSgBLsT" + + "L4GVPEGNANR8COYkHQIDAQABo4GjMIGgMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRME" + + "AjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAkBgNVHREEHTAbghlo" + + "dW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMB8GA1UdIwQYMBaAFOGTt4H3ho30O4e+" + + "hebwJjm2VMvIMB0GA1UdDgQWBBThk7eB94aN9DuHvoXm8CY5tlTLyDANBgkqhkiG" + + "9w0BAQsFAAOCAQEAGp8mCioVCmM+kZv6r+K2j2uog1k4HBwN1NfRoSsibDB8+QXF" + + "bmNf3M0imiuR/KJgODyuROwaa/AalxNFMOP8XTL2YmP7XsddBs9ONHHQXKjY/Ojl" + + "PsIPR7vZjwYPfEB+XEKl2fOIxDQQ921POBV7M6DdTC49T5X+FsLR1AIIfinVetT9" + + "QmNuvzulBX0T0rea/qpcPK4HTj7ToyImOaf8sXRv2s2ODLUrKWu5hhTNH2l6RIkQ" + + "U/aIAdQRfDaSE9jhtcVu5d5kCgBs7nz5AzeCisDPo5zIt4Mxej3iVaAJ79oEbHOE" + + "p192KLXLV/pscA4Wgb+PJ8AAEa5B6xq8p9JO+Q=="; + + /** + * Stores the X.509 certificate. + */ + private X509Certificate x509Certificate; + + /** + * Setup before each test. + * + * @throws Exception when an exception occurs. + */ + @BeforeEach + public void setUp() throws Exception { + try { + byte[] certificateBytes = Base64.getDecoder().decode(TEST_CERTIFICATE); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + x509Certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certificateBytes)); + } catch (CertificateException e) { + throw new ProviderException(e); + } + } + + /** + * Test checkValidity method. + */ + @Test + public void testCheckValidity() { + try { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + certificate.checkValidity(); + } catch (CertificateExpiredException | CertificateNotYetValidException cnyve) { + fail(); + } + } + + /** + * Test checkValidity method. + */ + @Test + public void testCheckValidity2() { + try { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + certificate.checkValidity(new Date(100, 1, 1)); + fail(); + } catch (CertificateExpiredException ex) { + fail(); + } catch (CertificateNotYetValidException cnyve) { + // expecting this as the TEST_CERTIFICATE is not valid against given date. + } + } + + /** + * Test checkValidity method. + */ + @Test + public void testCheckValidity3() { + try { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + certificate.checkValidity(new Date(200, 1, 1)); + } catch (CertificateExpiredException | CertificateNotYetValidException cnyve) { + fail(); + } + } + + /** + * Test getBasicConstraints method. + */ + @Test + public void testGetBasicConstraints() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertEquals(-1, certificate.getBasicConstraints()); + } + + /** + * Test getCriticalExtensionOIDs method. + */ + @Test + public void testGetCriticalExtensionOIDs() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + Set criticalExtensions = certificate.getCriticalExtensionOIDs(); + assertFalse(criticalExtensions.isEmpty()); + assertTrue(criticalExtensions.contains("2.5.29.15")); + } + + /** + * Test getEncoded method. + */ + @Test + public void testGetEncoded() { + try { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertNotNull(certificate.getEncoded()); + } catch (CertificateEncodingException cee) { + fail(); + } + } + + /** + * Test getExtensionValue method. + */ + @Test + public void testGetExtensionValue() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertNotNull(certificate.getExtensionValue("2.5.29.15")); + } + + /** + * Test getIssuerDN method. + */ + @Test + public void testGetIssuerDN() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertEquals("CN=hundred-years.example.com", certificate.getIssuerDN().getName()); + } + + /** + * Test getIssuerUniqueID method. + */ + @Test + public void testGetIssuerUniqueID() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertNull(certificate.getIssuerUniqueID()); + } + + /** + * Test getKeyUsage method. + */ + @Test + public void testGetKeyUsage() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertNotNull(certificate.getKeyUsage()); + } + + /** + * Test getNonCriticalExtensionOIDs method. + */ + @Test + public void testGetNonCriticalExtensionOIDs() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + Set nonCriticalExtensions = certificate.getNonCriticalExtensionOIDs(); + assertFalse(nonCriticalExtensions.isEmpty()); + } + + /** + * Test getNotAfter method. + */ + @Test + public void testGetNotAfter() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + Date notAfter = certificate.getNotAfter(); + assertTrue(new Date().before(notAfter)); + } + + /** + * Test getNotBefore method. + */ + @Test + public void testGetNotBefore() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + Date notBefore = certificate.getNotBefore(); + assertTrue(new Date().after(notBefore)); + } + + /** + * Test getPublicKey method. + */ + @Test + public void testGetPublicKey() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertNotNull(certificate.getPublicKey()); + } + + /** + * Test getSerialNumber method. + */ + @Test + public void testGetSerialNumber() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertNotNull(certificate.getSerialNumber()); + } + + /** + * Test getSigAlgName method. + */ + @Test + public void testGetSigAlgName() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertEquals("SHA256withRSA", certificate.getSigAlgName()); + } + + /** + * Test getSigAlgOID method. + */ + @Test + public void testGetSigAlgOID() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertEquals("1.2.840.113549.1.1.11", certificate.getSigAlgOID()); + } + + /** + * Test getSigAlgParams method. + */ + @Test + public void testGetSigAlgParams() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertNull(certificate.getSigAlgParams()); + } + + /** + * Test getSignature method. + */ + @Test + public void testGetSignature() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertNotNull(certificate.getSignature()); + } + + /** + * Test getSubjectDN method. + */ + @Test + public void testGetSubjectDN() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertEquals("CN=hundred-years.example.com", certificate.getSubjectDN().getName()); + } + + /** + * Test getSubjectUniqueID method. + */ + @Test + public void testGetSubjectUniqueID() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertNull(certificate.getSubjectUniqueID()); + } + + /** + * Test getTBSCertificate method. + */ + @Test + public void testGetTBSCertificate() { + try { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertNotNull(certificate.getTBSCertificate()); + } catch (CertificateEncodingException cee) { + fail(); + } + } + + /** + * Test getVersion method. + */ + @Test + public void testGetVersion() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertEquals(3, certificate.getVersion()); + } + + /** + * Test hasUnsupportedCriticalExtension method. + */ + @Test + public void testHasUnsupportedCriticalExtension() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertFalse(certificate.hasUnsupportedCriticalExtension()); + } + + /** + * Test toString method. + */ + @Test + public void testToString() { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + assertNotNull(certificate.toString()); + } + + /** + * Test verify method. + */ + @Test + public void testVerify() { + try { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + PublicKey publicKey = certificate.getPublicKey(); + certificate.verify(publicKey); + } catch (CertificateException | NoSuchAlgorithmException + | InvalidKeyException | NoSuchProviderException + | SignatureException e) { + fail(); + } + } + + /** + * Test verify method. + */ + @Test + public void testVerify2() { + try { + KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); + PublicKey publicKey = certificate.getPublicKey(); + certificate.verify(publicKey, "SunRsaSign"); + } catch (CertificateException | NoSuchAlgorithmException + | InvalidKeyException | NoSuchProviderException + | SignatureException e) { + fail(); + } + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultClientTest.java new file mode 100644 index 0000000000000..26cdddf4a46c3 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultClientTest.java @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +/** + * The JUnit tests for the KeyVaultClient class. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultClientTest { + + /** + * Stores the KeyVault URI. + */ + private static String keyVaultURI; + + /** + * Setup before any test. + */ + @BeforeAll + public static void setUpClass() { + keyVaultURI = System.getProperty("azure.keyvault.uri"); + } + + /** + * Test getCertificate method. + */ + @Test + public void testGetCertificate() { + KeyVaultClient client = new KeyVaultClient(keyVaultURI); + assertNull(client.getCertificate("myalias")); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java new file mode 100644 index 0000000000000..1cdf0484c865f --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.security.KeyStore; +import java.security.Security; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; + +/** + * The JUnit tests for the KeyVaultProvider class. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultJcaProviderTest { + + /** + * Test the constructor. + */ + @Test + public void testConstructor() { + KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); + assertNotNull(provider); + } + + /** + * Test getting a certificate using the Provider. + * + * @throws Exception when an error occurs. + */ + @Test + public void testGetCertificate() throws Exception { + Security.addProvider(new KeyVaultJcaProvider()); + KeyStore keyStore = KeyStore.getInstance("AzureKeyVault"); + keyStore.load(null, null); + assertNull(keyStore.getCertificate("myalias")); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java new file mode 100644 index 0000000000000..5a5f218d27760 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java @@ -0,0 +1,237 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + +/** + * The JUnit tests for the KeyVaultKeyStore class. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultKeyStoreTest { + + /** + * Test engineGetCertificate method. + * + * @throws Exception when a serious error occurs. + */ + @Test + public void testEngineGetCertificate() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + keystore.engineLoad(null, null); + assertNull(keystore.engineGetCertificate("myalias")); + } + + /** + * Test engineGetCertificate method. + * + * @throws Exception when a serious error occurs. + */ + @Test + public void testEngineGetCertificate2() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + keystore.engineLoad(null, null); + assertNull(keystore.engineGetCertificate("myalias")); + } + + /** + * Test engineGetCertificate method. + * + * @throws Exception when a serious error occurs. + */ + @Test + public void testEngineGetCertificate3() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), null, null, null); + keystore.engineLoad(parameter); + assertNull(keystore.engineGetCertificate("myalias")); + } + + /** + * Test engineGetCertificateAlias method. + */ + @Test + public void testEngineGetCertificateAlias() { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + assertNull(keystore.engineGetCertificateAlias(null)); + } + + /** + * Test engineGetCertificateChain method. + * + * @throws Exception when an error occurs. + */ + @Test + public void testEngineGetCertificateChain() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), null, null, null); + keystore.engineLoad(parameter); + assertNull(keystore.engineGetCertificateChain("myalias")); + } + + /** + * Test engineIsCertificateEntry method. + * + * @throws Exception when an error occurs. + */ + @Test + public void testEngineIsCertificateEntry() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + keystore.engineLoad(parameter); + + assertFalse(keystore.engineIsCertificateEntry("myalias")); + } + + /** + * Test engineSetCertificateEntry method. + * + * @throws Exception when a serious error occurs. + */ + @Test + public void testEngineSetCertificateEntry() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + keystore.engineSetCertificateEntry("myalias", null); + } + + /** + * Test engineGetKey method. + * + * @throws Exception when an error occurs. + */ + @Test + public void testEngineGetKey() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + keystore.engineLoad(parameter); + assertNull(keystore.engineGetKey("myalias", null)); + } + + /** + * Test engineIsKeyEntry method. + * + * @throws Exception when an error occurs. + */ + @Test + public void testEngineIsKeyEntry() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + keystore.engineLoad(parameter); + assertFalse(keystore.engineIsKeyEntry("myalias")); + } + + /** + * Test engineSetKeyEntry method. + * + * @throws Exception when a serious error occurs. + */ + @Test + public void testEngineSetKeyEntry() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + keystore.engineSetKeyEntry("myalias", null, null); + } + + /** + * Test engineSetKeyEntry method. + * + * @throws Exception when an error occurs. + */ + @Test + public void testEngineSetKeyEntry2() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + keystore.engineSetKeyEntry("myalias", null, null, null); + } + + /** + * Test engineAliases method. + * + * @throws Exception when a serious error occurs. + */ + @Test + public void testEngineAliases() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + keystore.engineLoad(parameter); + assertTrue(keystore.engineAliases().hasMoreElements()); + } + + /** + * Test engineContainsAlias method. + * + * @throws Exception when an error occurs. + */ + @Test + public void testEngineContainsAlias() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + keystore.engineLoad(parameter); + assertFalse(keystore.engineContainsAlias("myalias")); + } + + /** + * Test engineGetCretionDate method. + */ + @Test + public void testEngineGetCreationDate() { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + assertNotNull(keystore.engineGetCreationDate("myalias")); + } + + /** + * Test engineDeleteEntry method. + * + * @throws Exception when a serious error occurs. + */ + @Test + public void testEngineDeleteEntry() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + keystore.engineDeleteEntry("myalias"); + } + + /** + * Test engineSize method. + */ + @Test + public void testEngineSize() { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + assertTrue(keystore.engineSize() >= 0); + } + + /** + * Test engineStore method. + * + * @throws Exception when an error occurs. + */ + @Test + public void testEngineStore() throws Exception { + KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + keystore.engineStore(null, null); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java new file mode 100644 index 0000000000000..7ace46bb5b2fb --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; + +/** + * The JUnit tests for the KeyVaultLoadStoreParameter class. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultLoadStoreParameterTest { + + /** + * Test getProtectionParameter method. + */ + @Test + public void testGetProtectionParameter() { + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), null, null, null); + assertNull(parameter.getProtectionParameter()); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java new file mode 100644 index 0000000000000..ab74cbd983b8a --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import org.junit.jupiter.api.Test; + +/** + * The JUnit tests for the LegacyRestClient class. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class LegacyRestClientTest { + + /** + * Test constructor. + */ + @Test + public void testConstructor() { + LegacyRestClient client = new LegacyRestClient(); + assertNotNull(client); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java new file mode 100644 index 0000000000000..8b740e400b4f3 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import org.junit.jupiter.api.Test; + +/** + * The JUnit tests for the RestClientFactory class. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class RestClientFactoryTest { + + /** + * Test createClient method. + */ + @Test + public void testCreateClient() { + assertNotNull(RestClientFactory.createClient()); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java new file mode 100644 index 0000000000000..5a1a75ce63972 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java @@ -0,0 +1,144 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.security.KeyStore; +import java.security.Security; +import java.security.cert.X509Certificate; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLServerSocketFactory; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder; +import org.apache.hc.core5.http.ClassicHttpResponse; +import org.apache.hc.core5.http.io.HttpClientResponseHandler; +import org.apache.hc.core5.ssl.SSLContexts; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +/** + * The unit test validating the ServerSocket is created using a certificate from + * Azure KeyVault. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class ServerSocketTest { + + /** + * Test SSLServerSocket without client trust. + * + * @throws Exception when a serious error occurs. + */ + @Test + public void testServerSocket() throws Exception { + + /* + * Add JCA provider. + */ + KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); + Security.addProvider(provider); + + /* + * Setup server side. + * + * - Create an Azure KeyVault specific instance of a KeyStore. + * - Set the KeyManagerFactory to use that KeyStore. + * - Set the SSL context to use the KeyManagerFactory. + * - Create the SSLServerSocket using th SSL context. + */ + KeyStore ks = KeyStore.getInstance("AzureKeyVault"); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + ks.load(parameter); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(ks, "".toCharArray()); + + SSLContext context = SSLContext.getInstance("TLS"); + context.init(kmf.getKeyManagers(), null, null); + + SSLServerSocketFactory factory = (SSLServerSocketFactory) context.getServerSocketFactory(); + SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(8765); + + Thread server = new Thread(() -> { + while (true) { + try { + Socket socket = serverSocket.accept(); + try (OutputStream outputStream = socket.getOutputStream()) { + outputStream.write("HTTP/1.1 204\r\n".getBytes()); + outputStream.flush(); + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + }); + server.start(); + + /* + * Setup client side + * + * - Create an SSL context. + * - Set SSL context to trust any certificate. + * - Create SSL connection factory. + * - Set hostname verifier to trust any hostname. + */ + + SSLContext sslContext = SSLContexts + .custom() + .loadTrustMaterial((final X509Certificate[] chain, final String authType) -> { + return true; + }) + .build(); + + SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder + .create() + .setSslContext(sslContext) + .setHostnameVerifier((hostname, session) -> { + return true; + }) + .build(); + + PoolingHttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder + .create() + .setSSLSocketFactory(sslSocketFactory) + .build(); + + /* + * And now execute the test. + */ + String result = null; + + try ( CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build()) { + HttpGet httpGet = new HttpGet("https://localhost:8765"); + HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { + int status = response.getCode(); + String result1 = null; + if (status == 204) { + result1 = "Success"; + } + return result1; + }; + result = client.execute(httpGet, responseHandler); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + + /* + * And verify all went well. + */ + assertEquals("Success", result); + } +} diff --git a/sdk/keyvault/pom.xml b/sdk/keyvault/pom.xml index 5f620284c6a4a..06d693f5939db 100644 --- a/sdk/keyvault/pom.xml +++ b/sdk/keyvault/pom.xml @@ -17,6 +17,7 @@ microsoft-azure-keyvault-extensions microsoft-azure-keyvault-test azure-security-keyvault-certificates + azure-security-keyvault-jca azure-security-keyvault-keys azure-security-keyvault-secrets diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md new file mode 100644 index 0000000000000..6456f7f08de9c --- /dev/null +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md @@ -0,0 +1,16 @@ +# Release History + +## 2.4.0-beta.1 (Unreleased) + + +## 2.3.3 (2020-08-13) +_New Features_ +- Support connection to multiple Key Vault from a single application configuration file +- Support case sensitive keys in Key Vault +- Key Vault Spring Boot Actuator + +_Improved_ +- Revamp KeyVault refreshing logic to avoid unnecessary updates. + +_Bug Fixes_ +- Address CVEs and cleaned up all warnings at build time. diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md new file mode 100644 index 0000000000000..d05145ae5fe4e --- /dev/null +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -0,0 +1 @@ +# Azure Key Vault Certificates Spring Boot starter diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml new file mode 100644 index 0000000000000..0a575a282be58 --- /dev/null +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -0,0 +1,173 @@ + + + 4.0.0 + + com.azure + azure-client-sdk-parent + 1.7.0 + ../../parents/azure-client-sdk-parent + + com.microsoft.azure + azure-keyvault-certificates-spring-boot-starter + 2.4.0-beta.1 + + Azure Key Vault Certificates Spring Boot Starter + Spring Boot Starter supporting Azure Key Vault Certificates + https://github.com/Azure/azure-sdk-for-java + + + + org.springframework.boot + spring-boot-starter + 2.3.3.RELEASE + + + org.springframework.boot + spring-boot-starter-validation + 2.3.3.RELEASE + + + com.azure + azure-security-keyvault-jca + 1.0.0 + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + + com.microsoft.azure:azure-spring-boot:[2.4.0-beta.1] + com.azure:azure-security-keyvault-secrets:[1.0.0] + org.springframework.boot:spring-boot-starter:[2.3.3.RELEASE] + org.springframework.boot:spring-boot-starter-validation:[2.3.3.RELEASE] + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.1.1 + + + attach-javadocs + + jar + + + true + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.2 + + + + empty-javadoc-jar-with-readme + package + + jar + + + javadoc + ${project.basedir}/javadocTemp + + + + + + empty-sources-jar-with-readme + package + + jar + + + sources + ${project.basedir}/sourceTemp + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + copy-readme-to-javadocTemp + prepare-package + + + Deleting existing ${project.basedir}/javadocTemp + + + + Copying ${project.basedir}/README.md to + ${project.basedir}/javadocTemp/README.md + + + + + + run + + + + copy-readme-to-sourceTemp + prepare-package + + + Deleting existing ${project.basedir}/sourceTemp + + + + Copying ${project.basedir}/README.md to + ${project.basedir}/sourceTemp/README.md + + + + + + run + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + none + + + + + + + From 366021aeb4f0e0ec7b464172128d93e487de0c57 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 29 Sep 2020 15:16:18 -0600 Subject: [PATCH 02/92] Added the starter --- .../keyvault/jca/KeyVaultJcaProvider.java | 6 +- .../keyvault/jca/ServerSocketTest.java | 108 ++++++++++++++++++ .../pom.xml | 6 + ...tCertificatesEnvironmentPostProcessor.java | 46 ++++++++ .../main/resources/META-INF/spring.factories | 2 + .../resources/config/application.properties | 5 + .../src/main/resources/keyvault.dummy | 1 + 7 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java create mode 100644 sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/META-INF/spring.factories create mode 100644 sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/config/application.properties create mode 100644 sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/keyvault.dummy diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java index 58102abfad059..8443812066dd5 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java @@ -22,7 +22,7 @@ public class KeyVaultJcaProvider extends Provider { /** * Stores the information. */ - private static final String INFO = "Azure KeyVault Security Provider"; + private static final String INFO = "Azure KeyVault JCA Provider"; /** * Stores the name. @@ -59,8 +59,10 @@ private void initialize() { * See SSLUtilBase.getKeyManagers and look for the * "DKS".equalsIgnoreCase(certificate.getCertificateKeystoreType() */ + putService(new Provider.Service(this, "KeyStore", "DKS", + KeyVaultKeyStore.class.getName(), Arrays.asList("DKS"), null)); putService(new Provider.Service(this, "KeyStore", "AzureKeyVault", - KeyVaultKeyStore.class.getName(), Arrays.asList("AzureKeyVault", "DKS"), null)); + KeyVaultKeyStore.class.getName(), Arrays.asList("AzureKeyVault"), null)); return null; }); } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java index 5a1a75ce63972..140708f3b7fc6 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java @@ -19,6 +19,7 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder; +import org.apache.hc.client5.http.ssl.TrustSelfSignedStrategy; import org.apache.hc.core5.http.ClassicHttpResponse; import org.apache.hc.core5.http.io.HttpClientResponseHandler; import org.apache.hc.core5.ssl.SSLContexts; @@ -136,6 +137,113 @@ public void testServerSocket() throws Exception { ioe.printStackTrace(); } + /* + * And verify all went well. + */ + assertEquals("Success", result); + } + + /** + * Test SSLServerSocket WITH self-signed client trust. + * + * @throws Exception when a serious error occurs. + */ + @Test + public void testServerSocketWithSelfSignedClientTrust() throws Exception { + + /* + * Add JCA provider. + */ + KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); + Security.addProvider(provider); + + /* + * Setup server side. + * + * - Create an Azure KeyVault specific instance of a KeyStore. + * - Set the KeyManagerFactory to use that KeyStore. + * - Set the SSL context to use the KeyManagerFactory. + * - Create the SSLServerSocket using th SSL context. + */ + KeyStore ks = KeyStore.getInstance("AzureKeyVault"); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + ks.load(parameter); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(ks, "".toCharArray()); + + SSLContext context = SSLContext.getInstance("TLS"); + context.init(kmf.getKeyManagers(), null, null); + + SSLServerSocketFactory factory = (SSLServerSocketFactory) context.getServerSocketFactory(); + SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(8766); + + Thread server = new Thread(() -> { + while (true) { + try { + Socket socket = serverSocket.accept(); + try (OutputStream outputStream = socket.getOutputStream()) { + outputStream.write("HTTP/1.1 204\r\n".getBytes()); + outputStream.flush(); + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + }); + server.start(); + + /* + * Setup client side + * + * - Create an SSL context. + * - Set SSL context to trust any certificate. + * - Create SSL connection factory. + * - Set hostname verifier to trust any hostname. + */ + + SSLContext sslContext = SSLContexts + .custom() + .loadTrustMaterial(ks, new TrustSelfSignedStrategy()) + .build(); + + SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder + .create() + .setSslContext(sslContext) + .setHostnameVerifier((hostname, session) -> { + return true; + }) + .build(); + + PoolingHttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder + .create() + .setSSLSocketFactory(sslSocketFactory) + .build(); + + /* + * And now execute the test. + */ + String result = null; + + try ( CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build()) { + HttpGet httpGet = new HttpGet("https://localhost:8766"); + HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { + int status = response.getCode(); + String result1 = null; + if (status == 204) { + result1 = "Success"; + } + return result1; + }; + result = client.execute(httpGet, responseHandler); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + /* * And verify all went well. */ diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index 0a575a282be58..ff8710755baae 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -3,12 +3,14 @@ xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + com.microsoft.azure azure-keyvault-certificates-spring-boot-starter 2.4.0-beta.1 @@ -170,4 +172,8 @@ + + 1.8 + 1.8 + diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java new file mode 100644 index 0000000000000..95ee3e079b472 --- /dev/null +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.keyvault.certificates.starter; + +import com.azure.security.keyvault.jca.KeyVaultJcaProvider; +import java.security.Security; +import java.util.Properties; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.env.EnvironmentPostProcessor; +import static org.springframework.core.Ordered.LOWEST_PRECEDENCE; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.ConfigurableEnvironment; + +@Order(LOWEST_PRECEDENCE) +public class KeyVaultCertificatesEnvironmentPostProcessor implements EnvironmentPostProcessor { + + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, + SpringApplication application) { + + Properties properties = System.getProperties(); + + String uri = environment.getProperty("azure.keyvault.uri"); + if (uri != null) { + properties.put("azure.keyvault.uri", uri); + } + + String tenantId = environment.getProperty("azure.keyvault.tenantId"); + if (tenantId != null) { + properties.put("azure.keyvault.tenantId", tenantId); + } + + String clientId = environment.getProperty("azure.keyvault.clientId"); + if (clientId != null) { + properties.put("azure.keyvault.clientId", clientId); + } + + String clientSecret = environment.getProperty("azure.keyvault.clientSecret"); + if (clientSecret != null) { + properties.put("azure.keyvault.clientSecret", clientSecret); + } + + KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); + Security.insertProviderAt(provider, 1); + } +} diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/META-INF/spring.factories b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000000..d48e60ced4b01 --- /dev/null +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.env.EnvironmentPostProcessor=com.azure.keyvault.certificates.starter.KeyVaultCertificatesEnvironmentPostProcessor + diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/config/application.properties b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/config/application.properties new file mode 100644 index 0000000000000..6365a99bb5466 --- /dev/null +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/config/application.properties @@ -0,0 +1,5 @@ +server.ssl.key-store=classpath:keyvault.dummy +server.ssl.key-store-password=doesnotmatter +server.ssl.key-password=doesnotmatter +server.ssl.trust-store=classpath:keyvault.dummy +server.ssl.trust-store-password=doesnotmatter diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/keyvault.dummy b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/keyvault.dummy new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/keyvault.dummy @@ -0,0 +1 @@ + From 4229ad580682118919f8e647e9cd5b9b326850c8 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 30 Sep 2020 08:43:58 -0600 Subject: [PATCH 03/92] Added sample --- .../.gitignore | 33 ++ .../.mvn/wrapper/MavenWrapperDownloader.java | 117 +++++++ .../.mvn/wrapper/maven-wrapper.jar | Bin 0 -> 50710 bytes .../.mvn/wrapper/maven-wrapper.properties | 2 + .../Dockerfile | 3 + .../deployment.yml | 43 +++ .../mvnw | 310 ++++++++++++++++++ .../mvnw.cmd | 182 ++++++++++ .../pom.xml | 110 +++++++ .../certificates/sample/DemoApplication.java | 12 + .../src/main/resources/application.properties | 54 +++ 11 files changed, 866 insertions(+) create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.gitignore create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.jar create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.properties create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/deployment.yml create mode 100755 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw.cmd create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/DemoApplication.java create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.gitignore b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.gitignore new file mode 100644 index 0000000000000..549e00a2a96fa --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000000000..e76d1f3241d38 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,117 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.jar b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054 GIT binary patch literal 50710 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 EfAhh=DF6Tf literal 0 HcmV?d00001 diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000000..642d572ce90e5 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile new file mode 100644 index 0000000000000..152c475c7bca4 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile @@ -0,0 +1,3 @@ +FROM mcr.microsoft.com/java/jre:8-zulu-alpine +ADD target/app.jar . +CMD java -jar app.jar diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/deployment.yml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/deployment.yml new file mode 100644 index 0000000000000..2b2efb3e2cc2f --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/deployment.yml @@ -0,0 +1,43 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: springboot + labels: + app: springboot +spec: + replicas: 1 + selector: + matchLabels: + app: springboot + template: + metadata: + labels: + app: springboot + spec: + nodeSelector: + "beta.kubernetes.io/os": linux + containers: + - name: springboot + image: keyvaultssl.azurecr.io/demo:latest + ports: + - containerPort: 8443 + name: https + resources: + requests: + cpu: 250m + limits: + cpu: 500m +--- +apiVersion: v1 +kind: Service +metadata: + name: springboot +spec: + type: LoadBalancer + ports: + - port: 443 + targetPort: 8443 + selector: + app: springboot + diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw new file mode 100755 index 0000000000000..a16b5431b4c3c --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw.cmd b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw.cmd new file mode 100644 index 0000000000000..c8d43372c986d --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml new file mode 100644 index 0000000000000..662613a99abe4 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml @@ -0,0 +1,110 @@ + + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.3.4.RELEASE + + + + + com.azure + azure-spring-boot-sample-keyvault-certificates + 1.0.0 + jar + + Azure Spring Boot Starter Sample - Key Vault Certificates + Sample project for Azure Key Vault Certificates Starter + https://github.com/Azure/azure-sdk-for-java + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + com.microsoft.azure + azure-keyvault-certificates-spring-boot-starter + 2.4.0-beta.1 + + + org.springframework.boot + spring-boot-starter-actuator + + + + app + + + org.springframework.boot + spring-boot-maven-plugin + + + ${azure.keyvault.uri} + ${azure.tenant.id} + ${azure.client.id} + ${azure.client.secret} + ${server.ssl.key-alias} + + + + + + diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/DemoApplication.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/DemoApplication.java new file mode 100644 index 0000000000000..745967dd0c69e --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/DemoApplication.java @@ -0,0 +1,12 @@ +package com.azure.keyvault.certificates.sample; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } +} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties new file mode 100644 index 0000000000000..cfe9c9fa7fe0c --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties @@ -0,0 +1,54 @@ +# +# The URI to the Azure KeyVault used +# +azure.keyvault.uri=${AZURE_KEYVAULT_URI} + +# +# The alias corresponding to the certificate in Azure KeyVault. +# +server.ssl.key-alias=${SERVER_SSL_KEY_ALIAS} + +# +# The keystore type that enables the use of Azure KeyVault for your server-side +# SSL certificate (note for embedded Tomcat it needs to be DKS, for all others +# it needs to be AzureKeyVault). +# +server.ssl.key-store-type=DKS +# server.ssl.key-store-type=AzureKeyVault + +# +# The truststore type that enables the use of Azure KeyVault for trusted +# certificates, a.k.a the ones you trust when making an outbound SSL connection +# (note for embedded Tomcat it needs to be DKS, for all others it needs to be +# AzureKeyVault). +# +# server.ssl.key-store-type=DKS +# server.ssl.trust-store-type=AzureKeyVault + +# +# The Tenant ID for your Azure KeyVault (needed if you are not using managed +# identity). +# +azure.keyvault.tenantId=${AZURE_KEYVAULT_TENTANT_ID} + +# +# The Client ID that has been setup with access to your Azure KeyVault (needed +# if you are not using managed identity). +# +azure.keyvault.clientId=${AZURE_KEYVAULT_CLIENT_ID} + +# +# The Client Secret that will be used for accessing your Azure KeyVault (needed +# if you are not using managed identity). +# +azure.keyvault.clientSecret=${AZURE_KEYVAULT_CLIENT_SECRET} + +# +# The server port. +# +server.port=8443 + +# +# Just for debugging purposes. +# +management.endpoints.web.exposure.include=* From 7720e9c3a85af9ebbef866874c536482b2edadaa Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 30 Sep 2020 09:00:18 -0600 Subject: [PATCH 04/92] Cleaned up sample --- ...emoApplication.java => SampleApplication.java} | 6 ++++-- .../certificates/sample/SampleController.java | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) rename sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/{DemoApplication.java => SampleApplication.java} (56%) create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleController.java diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/DemoApplication.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleApplication.java similarity index 56% rename from sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/DemoApplication.java rename to sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleApplication.java index 745967dd0c69e..2c48356bbea15 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/DemoApplication.java +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleApplication.java @@ -1,12 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. package com.azure.keyvault.certificates.sample; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class DemoApplication { +public class SampleApplication { public static void main(String[] args) { - SpringApplication.run(DemoApplication.class, args); + SpringApplication.run(SampleApplication.class, args); } } diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleController.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleController.java new file mode 100644 index 0000000000000..9af77488f4d58 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleController.java @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.keyvault.certificates.sample; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class SampleController { + + @GetMapping("/") + public String helloWorld() { + return "Hello World"; + } +} From f4294f9fe29522ffdd548d0e892591a2ac4e3840 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 30 Sep 2020 09:36:28 -0600 Subject: [PATCH 05/92] Remove unncessary deployment.yml --- .../deployment.yml | 43 ------------------- 1 file changed, 43 deletions(-) delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/deployment.yml diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/deployment.yml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/deployment.yml deleted file mode 100644 index 2b2efb3e2cc2f..0000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/deployment.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: springboot - labels: - app: springboot -spec: - replicas: 1 - selector: - matchLabels: - app: springboot - template: - metadata: - labels: - app: springboot - spec: - nodeSelector: - "beta.kubernetes.io/os": linux - containers: - - name: springboot - image: keyvaultssl.azurecr.io/demo:latest - ports: - - containerPort: 8443 - name: https - resources: - requests: - cpu: 250m - limits: - cpu: 500m ---- -apiVersion: v1 -kind: Service -metadata: - name: springboot -spec: - type: LoadBalancer - ports: - - port: 443 - targetPort: 8443 - selector: - app: springboot - From 49239ee2e3cb96a8d9a22e89872317abd911f1b8 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 1 Oct 2020 16:20:00 -0600 Subject: [PATCH 06/92] Add system assigned identity support step #1 --- .../security/keyvault/jca/AuthClient.java | 73 +++++++++++++++++-- .../security/keyvault/jca/KeyVaultClient.java | 6 +- .../Dockerfile | 2 +- 3 files changed, 73 insertions(+), 8 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java index ef37ce523600d..5a379f64b926b 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -3,6 +3,7 @@ package com.azure.security.keyvault.jca; import com.azure.security.keyvault.jca.rest.OAuthToken; +import java.util.HashMap; /** * The REST client specific to getting an access token for Azure REST APIs. @@ -15,12 +16,12 @@ class AuthClient extends DelegateRestClient { * Stores the Client ID fragment. */ private static final String CLIENT_ID_FRAGMENT = "&client_id="; - + /** * Stores the Client Secret fragment. */ private static final String CLIENT_SECRET_FRAGMENT = "&client_secret="; - + /** * Stores the Grant Type fragment. */ @@ -41,6 +42,12 @@ class AuthClient extends DelegateRestClient { */ private static final String OAUTH2_TOKEN_POSTFIX = "/oauth2/token"; + /** + * Stores the OAuth2 managed identity URL. + */ + private static final String OAUTH2_MANAGED_IDENTITY_TOKEN_URL + = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01"; + /** * Constructor. */ @@ -49,17 +56,36 @@ public AuthClient() { } /** - * Get an access token. + * Get an authorization token for a managed identity. + * + * @param resource the resource. + * @return the authorization token. + */ + public String getAuthorizationToken(String resource) { + String result; + + if (System.getenv("WEBSITE_SITE_NAME") != null && + !System.getenv("WEBSITE_SITE_NAME").isEmpty()) { + result = getAuthorizationTokenOnAppService(resource); + } else { + result = getAuthorizationTokenOnOthers(resource); + } + + return result; + } + + /** + * Get an authorization token. * * @param resource the resource. * @param tenantId the tenant ID. * @param clientId the client ID. * @param clientSecret the client secret. - * @return the access token. + * @return the authorization token. */ - public String getAuthorizationToken(String resource, String tenantId, + public String getAuthorizationToken(String resource, String tenantId, String clientId, String clientSecret) { - + String result = null; StringBuilder oauth2Url = new StringBuilder(); @@ -81,4 +107,39 @@ public String getAuthorizationToken(String resource, String tenantId, } return result; } + + /** + * Get the authorization token on Azure App Service. + * + * @param resource the resource. + * @return the authorization token. + */ + private String getAuthorizationTokenOnAppService(String resource) { + return null; + } + + /** + * Get the authorization token on everything else but Azure App Service. + * + * @param resource the resource. + * @return the authorization token. + */ + private String getAuthorizationTokenOnOthers(String resource) { + String result = null; + + StringBuilder url = new StringBuilder(); + url.append(OAUTH2_MANAGED_IDENTITY_TOKEN_URL) + .append(RESOURCE_FRAGMENT).append(resource); + + HashMap headers = new HashMap<>(); + headers.put("Metadata", "true"); + String body = get(url.toString(), headers); + + if (body != null) { + JsonConverter converter = JsonConverterFactory.createJsonConverter(); + OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); + result = token.getAccess_token(); + } + return result; + } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java index 4a1b928941b30..772528c263a16 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java @@ -90,7 +90,11 @@ private String getAccessToken() { try { AuthClient authClient = new AuthClient(); String resource = URLEncoder.encode("https://vault.azure.net", "UTF-8"); - accessToken = authClient.getAuthorizationToken(resource, tenantId, clientId, clientSecret); + if (tenantId != null && clientId != null && clientSecret != null) { + accessToken = authClient.getAuthorizationToken(resource, tenantId, clientId, clientSecret); + } else { + accessToken = authClient.getAuthorizationToken(resource); + } } catch (UnsupportedEncodingException uee) { uee.printStackTrace(); } diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile index 152c475c7bca4..091170acf8810 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile @@ -1,3 +1,3 @@ -FROM mcr.microsoft.com/java/jre:8-zulu-alpine +FROM mcr.microsoft.com/java/jdk:8-zulu-centos ADD target/app.jar . CMD java -jar app.jar From 502bd8724d382e35bf731213433c651b3f41774d Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 2 Oct 2020 12:28:28 -0600 Subject: [PATCH 07/92] Added system managed identity support for App Service --- .../security/keyvault/jca/AuthClient.java | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java index 5a379f64b926b..8c04992ce7593 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -64,8 +64,8 @@ public AuthClient() { public String getAuthorizationToken(String resource) { String result; - if (System.getenv("WEBSITE_SITE_NAME") != null && - !System.getenv("WEBSITE_SITE_NAME").isEmpty()) { + if (System.getenv("WEBSITE_SITE_NAME") != null + && !System.getenv("WEBSITE_SITE_NAME").isEmpty()) { result = getAuthorizationTokenOnAppService(resource); } else { result = getAuthorizationTokenOnOthers(resource); @@ -115,7 +115,26 @@ public String getAuthorizationToken(String resource, String tenantId, * @return the authorization token. */ private String getAuthorizationTokenOnAppService(String resource) { - return null; + String result = null; + + System.out.println("Using MSI_ENDPOINT: " + System.getenv("MSI_ENDPOINT")); + + StringBuilder url = new StringBuilder(); + url.append(System.getenv("MSI_ENDPOINT")) + .append("?api-version=2017-09-01") + .append(RESOURCE_FRAGMENT).append(resource); + + HashMap headers = new HashMap<>(); + headers.put("Metadata", "true"); + headers.put("Secret", System.getenv("MSI_SECRET")); + String body = get(url.toString(), headers); + + if (body != null) { + JsonConverter converter = JsonConverterFactory.createJsonConverter(); + OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); + result = token.getAccess_token(); + } + return result; } /** @@ -134,7 +153,7 @@ private String getAuthorizationTokenOnOthers(String resource) { HashMap headers = new HashMap<>(); headers.put("Metadata", "true"); String body = get(url.toString(), headers); - + if (body != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); From 599b7ed42da34deeee1ffa2bf86bac3a327b5f07 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 6 Oct 2020 11:28:35 -0600 Subject: [PATCH 08/92] Added README for JCA provider --- .../azure-security-keyvault-jca/README.md | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index 8b137891791fe..1ded2855725fc 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -1 +1,99 @@ +# Microsoft Azure JCA Provider for KeyVault +If you want to test the current version under development you will have to +build and install it into your local Maven repository. To do so use the +following command line: + +``` + mvn clean install -DskipTests=true +``` + +## Server side SSL + +If you are looking to integrate the JCA provider to create a SSLServerSocket +see the example below. + +``` + KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); + Security.addProvider(provider); + + KeyStore ks = KeyStore.getInstance("AzureKeyVault"); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + ks.load(parameter); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(ks, "".toCharArray()); + + SSLContext context = SSLContext.getInstance("TLS"); + context.init(kmf.getKeyManagers(), null, null); + + SSLServerSocketFactory factory = (SSLServerSocketFactory) context.getServerSocketFactory(); + SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(8765); +``` + +Note if you want to use a Azure managed identity you would only pass the value +of the `azure.keyvault.uri` and the rest of the parameters would be `null`. + +## Client side SSL + +If you are looking to integrate the JCA provider for client side socket +connections, see the Apache HTTP client example below. + +``` + KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); + Security.addProvider(provider); + + KeyStore ks = KeyStore.getInstance("AzureKeyVault"); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + ks.load(parameter); + + SSLContext sslContext = SSLContexts + .custom() + .loadTrustMaterial(ks, new TrustSelfSignedStrategy()) + .build(); + + SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder + .create() + .setSslContext(sslContext) + .setHostnameVerifier((hostname, session) -> { + return true; + }) + .build(); + + PoolingHttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder + .create() + .setSSLSocketFactory(sslSocketFactory) + .build(); + + String result = null; + + try ( CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build()) { + HttpGet httpGet = new HttpGet("https://localhost:8766"); + HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { + int status = response.getCode(); + String result1 = null; + if (status == 204) { + result1 = "Success"; + } + return result1; + }; + result = client.execute(httpGet, responseHandler); + } catch (IOException ioe) { + ioe.printStackTrace(); + } +``` + +Note if you want to use a Azure managed identity you would only pass the value +of the `azure.keyvault.uri` and the rest of the parameters would be `null`. + +## Spring Boot + +For Spring Boot applications see our Spring Boot starter. \ No newline at end of file From d8d0bc0e7fc1d3eedaadab0429ddc40a28c303aa Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 6 Oct 2020 11:48:49 -0600 Subject: [PATCH 09/92] Added README for JCA provider --- sdk/keyvault/azure-security-keyvault-jca/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index 1ded2855725fc..23152c347c768 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -13,7 +13,7 @@ following command line: If you are looking to integrate the JCA provider to create a SSLServerSocket see the example below. -``` +```java KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); Security.addProvider(provider); @@ -43,7 +43,7 @@ of the `azure.keyvault.uri` and the rest of the parameters would be `null`. If you are looking to integrate the JCA provider for client side socket connections, see the Apache HTTP client example below. -``` +```java KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); Security.addProvider(provider); From 316bd9507b53434d22e0d7b5ca3eccdb0e87baa3 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 6 Oct 2020 12:13:56 -0600 Subject: [PATCH 10/92] Add instructions to build starter --- .../README.md | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index d05145ae5fe4e..1b32cd5487f9a 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -1 +1,120 @@ # Azure Key Vault Certificates Spring Boot starter + +If you want to test the current version under development you will have to + +1. Build and install the Microsoft Azure JCA Provider for KeyVault +1. Build and install this Starter. + +To build and install the starter use the following command line: + +``` + mvn clean install -DskipTests=true +``` + +## Server side SSL + +### Using a managed identity + +To use the starter for server side SSL you will need to add the following to +your application.properties + +``` +azure.keyvault.uri= + +server.ssl.key-alias= +server.ssl.key-store-type=< DKS when running on Tomcat, AzureKeyVault otherwise> +``` + +Note make sure the managed identity has access to the Azure KeyVault to access +keys, secrets and certificates. + +### Using a client ID and client secret + +To use the starter for server side SSL you will need to add the following to +your application.properties + +``` +azure.keyvault.uri= +azure.keyvault.tenantId= +azure.keyvault.clientId= +azure.keyvault.clientSecret= + +server.ssl.key-alias= +server.ssl.key-store-type=< DKS when running on Tomcat, AzureKeyVault otherwise> +``` + +Note make sure the client ID has access to the Azure KeyVault to access +keys, secrets and certificates. + +## Client side SSL + +### Using a managed identity + +To use the starter for client side SSL you will need to add the following to +your application.properties + +``` +azure.keyvault.uri= +``` + +And then if you are using RestTemplate use code similar to the example below. + +```java + @Bean + public RestTemplate restTemplate() throws Exception { + KeyStore ks = KeyStore.getInstance("AzureKeyVault"); + SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(ks, new TrustSelfSignedStrategy()) + .build(); + + SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); + + CloseableHttpClient httpClient = HttpClients.custom() + .setSSLSocketFactory(csf) + .build(); + + HttpComponentsClientHttpRequestFactory requestFactory = + new HttpComponentsClientHttpRequestFactory(); + + requestFactory.setHttpClient(httpClient); + RestTemplate restTemplate = new RestTemplate(requestFactory); + return restTemplate; + } +``` + +### Using a client ID and client secret + +To use the starter for client side SSL you will need to add the following to +your application.properties + +``` +azure.keyvault.uri= +azure.keyvault.tenantId= +azure.keyvault.clientId= +azure.keyvault.clientSecret= +``` + +And then if you are using RestTemplate use code similar to the example below. + +```java + @Bean + public RestTemplate restTemplate() throws Exception { + KeyStore ks = KeyStore.getInstance("AzureKeyVault"); + SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(ks, new TrustSelfSignedStrategy()) + .build(); + + SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); + + CloseableHttpClient httpClient = HttpClients.custom() + .setSSLSocketFactory(csf) + .build(); + + HttpComponentsClientHttpRequestFactory requestFactory = + new HttpComponentsClientHttpRequestFactory(); + + requestFactory.setHttpClient(httpClient); + RestTemplate restTemplate = new RestTemplate(requestFactory); + return restTemplate; + } +``` From 0c0c67a5debd73cbdbda1f1e2756d35120b54536 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 6 Oct 2020 12:17:13 -0600 Subject: [PATCH 11/92] Add instructions to build starter --- .../README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 1b32cd5487f9a..42f4a4ab9caea 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -11,6 +11,17 @@ To build and install the starter use the following command line: mvn clean install -DskipTests=true ``` +## Maven dependency + +All usage requires you to add the following dependency to your Maven POM file. + +```xml + + com.microsoft.azure + azure-keyvault-certificates-spring-boot-starter + +``` + ## Server side SSL ### Using a managed identity From d4a5a1fb5161da287dc2fc12b9ec927ffd05b6bc Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 6 Oct 2020 12:20:40 -0600 Subject: [PATCH 12/92] Add instructions to build starter --- .../README.md | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 42f4a4ab9caea..0c4cb14920e82 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -11,17 +11,6 @@ To build and install the starter use the following command line: mvn clean install -DskipTests=true ``` -## Maven dependency - -All usage requires you to add the following dependency to your Maven POM file. - -```xml - - com.microsoft.azure - azure-keyvault-certificates-spring-boot-starter - -``` - ## Server side SSL ### Using a managed identity @@ -39,6 +28,15 @@ server.ssl.key-store-type=< DKS when running on Tomcat, AzureKeyVault otherwise> Note make sure the managed identity has access to the Azure KeyVault to access keys, secrets and certificates. +Add then add the following Maven dependency to your POM file. + +```xml + + com.microsoft.azure + azure-keyvault-certificates-spring-boot-starter + +``` + ### Using a client ID and client secret To use the starter for server side SSL you will need to add the following to @@ -57,6 +55,15 @@ server.ssl.key-store-type=< DKS when running on Tomcat, AzureKeyVault otherwise> Note make sure the client ID has access to the Azure KeyVault to access keys, secrets and certificates. +Add then add the following Maven dependency to your POM file. + +```xml + + com.microsoft.azure + azure-keyvault-certificates-spring-boot-starter + +``` + ## Client side SSL ### Using a managed identity @@ -67,8 +74,19 @@ your application.properties ``` azure.keyvault.uri= ``` +Note make sure the managed identity has access to the Azure KeyVault to access +keys, secrets and certificates. -And then if you are using RestTemplate use code similar to the example below. +Add then add the following Maven dependency to your POM file. + +```xml + + com.microsoft.azure + azure-keyvault-certificates-spring-boot-starter + +``` + +And if you are using RestTemplate use code similar to the example below. ```java @Bean @@ -105,6 +123,18 @@ azure.keyvault.clientId= azure.keyvault.clientSecret= ``` +Note make sure the client ID has access to the Azure KeyVault to access +keys, secrets and certificates. + +Add then add the following Maven dependency to your POM file. + +```xml + + com.microsoft.azure + azure-keyvault-certificates-spring-boot-starter + +``` + And then if you are using RestTemplate use code similar to the example below. ```java From 95aea0e56c3859922d4ed467093a67fb2ce55a58 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 6 Oct 2020 12:22:19 -0600 Subject: [PATCH 13/92] Add instructions to build starter --- .../azure-spring-boot-starter-keyvault-certificates/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 0c4cb14920e82..a700ef6d409ac 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -22,7 +22,7 @@ your application.properties azure.keyvault.uri= server.ssl.key-alias= -server.ssl.key-store-type=< DKS when running on Tomcat, AzureKeyVault otherwise> +server.ssl.key-store-type= ``` Note make sure the managed identity has access to the Azure KeyVault to access @@ -49,7 +49,7 @@ azure.keyvault.clientId= azure.keyvault.clientSecret= server.ssl.key-alias= -server.ssl.key-store-type=< DKS when running on Tomcat, AzureKeyVault otherwise> +server.ssl.key-store-type= ``` Note make sure the client ID has access to the Azure KeyVault to access From 7fc29460aedef752bbb58f6fb04363b7460e272d Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 6 Oct 2020 12:25:52 -0600 Subject: [PATCH 14/92] Add instructions to build starter --- .../azure-spring-boot-starter-keyvault-certificates/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index a700ef6d409ac..6f321193afdcc 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -20,7 +20,6 @@ your application.properties ``` azure.keyvault.uri= - server.ssl.key-alias= server.ssl.key-store-type= ``` @@ -47,7 +46,6 @@ azure.keyvault.uri= azure.keyvault.tenantId= azure.keyvault.clientId= azure.keyvault.clientSecret= - server.ssl.key-alias= server.ssl.key-store-type= ``` From b7dcb077e3fd6a02d9525c23f7f7396bcf7dc089 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 6 Oct 2020 13:42:48 -0600 Subject: [PATCH 15/92] Minor fixes --- sdk/keyvault/azure-security-keyvault-jca/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index 23152c347c768..b44c9f3ec5ff2 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -79,7 +79,7 @@ connections, see the Apache HTTP client example below. HttpGet httpGet = new HttpGet("https://localhost:8766"); HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { int status = response.getCode(); - String result1 = null; + String result1 = "Not success"; if (status == 204) { result1 = "Success"; } @@ -91,9 +91,9 @@ connections, see the Apache HTTP client example below. } ``` -Note if you want to use a Azure managed identity you would only pass the value -of the `azure.keyvault.uri` and the rest of the parameters would be `null`. +Note if you want to use an Azure managed identity you only need to pass the value +of the `azure.keyvault.uri` and let the remaining parameters be `null`. ## Spring Boot -For Spring Boot applications see our Spring Boot starter. \ No newline at end of file +For Spring Boot applications see our Spring Boot starter. From 8da02d29665be3376b4991f8fce8afaf5012fcc8 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 6 Oct 2020 13:54:27 -0600 Subject: [PATCH 16/92] Added setDelegate --- .../com/azure/security/keyvault/jca/AuthClient.java | 6 ++++-- .../security/keyvault/jca/DelegateRestClient.java | 11 ++++++++++- .../azure/security/keyvault/jca/KeyVaultKeyStore.java | 10 +++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java index 8c04992ce7593..e9cdcf6f0dec6 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -50,6 +50,10 @@ class AuthClient extends DelegateRestClient { /** * Constructor. + * + *

+ * The constructor creates a default RestClient. + *

*/ public AuthClient() { super(RestClientFactory.createClient()); @@ -117,8 +121,6 @@ public String getAuthorizationToken(String resource, String tenantId, private String getAuthorizationTokenOnAppService(String resource) { String result = null; - System.out.println("Using MSI_ENDPOINT: " + System.getenv("MSI_ENDPOINT")); - StringBuilder url = new StringBuilder(); url.append(System.getenv("MSI_ENDPOINT")) .append("?api-version=2017-09-01") diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java index 7da2879c16461..fd33d0a54a18f 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java @@ -14,7 +14,7 @@ class DelegateRestClient implements RestClient { /** * Stores the delegate. */ - private final RestClient delegate; + private RestClient delegate; /** * Constructor. @@ -41,4 +41,13 @@ public RestClient getDelegate() { public String post(String url, String body, String contentType) { return delegate.post(url, body, contentType); } + + /** + * Set the delegate. + * + * @param delegate the delegate. + */ + public void setDelegate(RestClient delegate) { + this.delegate = delegate; + } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java index b74f0e932ef78..cf18871855690 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java @@ -54,6 +54,14 @@ public class KeyVaultKeyStore extends KeyStoreSpi { /** * Constructor. + * + *

+ * The constructor uses System.getProperty for + * azure.keyvault.uri, azure.keyvault.tenantId, + * azure.keyvault.clientId, + * azure.keyvault.clientSecret to initialize the keyvault + * client. + *

*/ public KeyVaultKeyStore() { creationDate = new Date(); @@ -61,7 +69,7 @@ public KeyVaultKeyStore() { String tenantId = System.getProperty("azure.keyvault.tenantId"); String clientId = System.getProperty("azure.keyvault.clientId", null); String clientSecret = System.getProperty("azure.keyvault.clientSecret", null); - keyVault = new KeyVaultClient(keyVaultUri, tenantId, clientId, clientSecret); + keyVault = new KeyVaultClient(keyVaultUri, tenantId, clientId, clientSecret); } @Override From 8bece1fc97b81c3926dddee0b6d702857f92f195 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 7 Oct 2020 09:19:08 -0600 Subject: [PATCH 17/92] Added logging --- .../security/keyvault/jca/AuthClient.java | 36 +++++++++---- .../keyvault/jca/JacksonJsonConverter.java | 18 +++++-- .../security/keyvault/jca/KeyVaultClient.java | 29 ++++++++--- .../keyvault/jca/KeyVaultKeyManager.java | 22 ++++++-- .../keyvault/jca/KeyVaultKeyStore.java | 45 ++++++++++------- .../security/keyvault/jca/AuthClientTest.java | 2 +- .../keyvault/jca/KeyVaultClientTest.java | 37 -------------- .../keyvault/jca/KeyVaultJcaProviderTest.java | 11 ++-- .../keyvault/jca/KeyVaultKeyStoreTest.java | 50 ++++++++----------- 9 files changed, 139 insertions(+), 111 deletions(-) delete mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultClientTest.java diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java index e9cdcf6f0dec6..d668999da97f2 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -4,6 +4,8 @@ import com.azure.security.keyvault.jca.rest.OAuthToken; import java.util.HashMap; +import static java.util.logging.Level.FINER; +import java.util.logging.Logger; /** * The REST client specific to getting an access token for Azure REST APIs. @@ -48,6 +50,11 @@ class AuthClient extends DelegateRestClient { private static final String OAUTH2_MANAGED_IDENTITY_TOKEN_URL = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01"; + /** + * Stores our logger. + */ + private static final Logger LOGGER = Logger.getLogger(AuthClient.class.getName()); + /** * Constructor. * @@ -60,26 +67,27 @@ public AuthClient() { } /** - * Get an authorization token for a managed identity. + * Get an access token for a managed identity. * * @param resource the resource. * @return the authorization token. */ - public String getAuthorizationToken(String resource) { + public String getAccessToken(String resource) { + LOGGER.log(FINER, "Resource: {0}", resource); String result; if (System.getenv("WEBSITE_SITE_NAME") != null && !System.getenv("WEBSITE_SITE_NAME").isEmpty()) { - result = getAuthorizationTokenOnAppService(resource); + result = getAccessTokenOnAppService(resource); } else { - result = getAuthorizationTokenOnOthers(resource); + result = getAccessTokenOnOthers(resource); } - + LOGGER.log(FINER, "Access token: {0}", result); return result; } /** - * Get an authorization token. + * Get an access token. * * @param resource the resource. * @param tenantId the tenant ID. @@ -87,9 +95,10 @@ public String getAuthorizationToken(String resource) { * @param clientSecret the client secret. * @return the authorization token. */ - public String getAuthorizationToken(String resource, String tenantId, + public String getAccessToken(String resource, String tenantId, String clientId, String clientSecret) { - + LOGGER.log(FINER, "\nResource: {0}\nTenant ID: {1}\nClient ID: {2}\nClient secret: {3}", + new Object[] {resource, tenantId, clientId, clientSecret}); String result = null; StringBuilder oauth2Url = new StringBuilder(); @@ -109,16 +118,18 @@ public String getAuthorizationToken(String resource, String tenantId, OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); result = token.getAccess_token(); } + LOGGER.log(FINER, "Access token: {0}", result); return result; } /** - * Get the authorization token on Azure App Service. + * Get the access token on Azure App Service. * * @param resource the resource. * @return the authorization token. */ - private String getAuthorizationTokenOnAppService(String resource) { + private String getAccessTokenOnAppService(String resource) { + LOGGER.log(FINER, "Resource: {0}", resource); String result = null; StringBuilder url = new StringBuilder(); @@ -136,6 +147,7 @@ private String getAuthorizationTokenOnAppService(String resource) { OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); result = token.getAccess_token(); } + LOGGER.log(FINER, "Access Token: {0}", result); return result; } @@ -145,7 +157,8 @@ private String getAuthorizationTokenOnAppService(String resource) { * @param resource the resource. * @return the authorization token. */ - private String getAuthorizationTokenOnOthers(String resource) { + private String getAccessTokenOnOthers(String resource) { + LOGGER.log(FINER, "Resource: {0}", resource); String result = null; StringBuilder url = new StringBuilder(); @@ -161,6 +174,7 @@ private String getAuthorizationTokenOnOthers(String resource) { OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); result = token.getAccess_token(); } + LOGGER.log(FINER, "Access token: {0}", result); return result; } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java index c8105299b4a70..b49d0a862f92b 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java @@ -5,14 +5,22 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import static java.util.logging.Level.FINEST; +import static java.util.logging.Level.WARNING; +import java.util.logging.Logger; /** - * The JSON-B JsonConverter. + * The Jackson JsonConverter. * * @author Manfred Riem (manfred.riem@microsoft.com) */ class JacksonJsonConverter implements JsonConverter { + /** + * Stores the logger. + */ + private static final Logger LOGGER = Logger.getLogger(JacksonJsonConverter.class.getName()); + /** * From JSON. * @@ -22,14 +30,16 @@ class JacksonJsonConverter implements JsonConverter { */ @Override public Object fromJson(String string, Class resultClass) { + LOGGER.log(FINEST, "Result Class: {1}, Json:\n {0}", new Object[] {string, resultClass}); Object result = null; try { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); result = objectMapper.readValue(string, resultClass); } catch (JsonProcessingException e) { - e.printStackTrace(); + LOGGER.log(WARNING, "Unable to convert from JSON", e); } + LOGGER.log(FINEST, "Object: {0}", result); return result; } @@ -41,13 +51,15 @@ public Object fromJson(String string, Class resultClass) { */ @Override public String toJson(Object object) { + LOGGER.log(FINEST, "Object: {0}", object); String result = null; try { ObjectMapper mapper = new ObjectMapper(); result = mapper.writeValueAsString(object); } catch (JsonProcessingException e) { - // consider logging. + LOGGER.log(WARNING, "Unable to convert to JSON", e); } + LOGGER.log(FINEST, "Json:\n {0}", result); return result; } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java index 772528c263a16..7643f52d8bffa 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java @@ -7,10 +7,14 @@ import com.azure.security.keyvault.jca.rest.CertificateBundle; import com.azure.security.keyvault.jca.rest.SecretBundle; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.Key; import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; @@ -19,6 +23,10 @@ import java.util.Base64; import java.util.HashMap; import java.util.List; +import static java.util.logging.Level.FINE; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; +import java.util.logging.Logger; /** * The REST client specific to Azure KeyVault. @@ -26,6 +34,11 @@ * @author Manfred Riem (manfred.riem@microsoft.com) */ class KeyVaultClient extends DelegateRestClient { + + /** + * Stores the logger. + */ + private static final Logger LOGGER = Logger.getLogger(KeyVaultClient.class.getName()); /** * Stores the API version postfix. @@ -59,6 +72,7 @@ class KeyVaultClient extends DelegateRestClient { */ public KeyVaultClient(String keyVaultUri) { super(RestClientFactory.createClient()); + LOGGER.log(FINE, "KeyVault URI: {0}", keyVaultUri); if (!keyVaultUri.endsWith("/")) { keyVaultUri = keyVaultUri + "/"; } @@ -75,6 +89,8 @@ public KeyVaultClient(String keyVaultUri) { */ public KeyVaultClient(String keyVaultUri, String tenantId, String clientId, String clientSecret) { this(keyVaultUri); + LOGGER.log(FINE, "\nKeyVault URI: {0}\nTenant ID: {1}\nClient ID: {2}\nClient Secret: {3}", + new Object[] {keyVaultUri, tenantId, clientId, clientSecret}); this.tenantId = tenantId; this.clientId = clientId; this.clientSecret = clientSecret; @@ -91,13 +107,14 @@ private String getAccessToken() { AuthClient authClient = new AuthClient(); String resource = URLEncoder.encode("https://vault.azure.net", "UTF-8"); if (tenantId != null && clientId != null && clientSecret != null) { - accessToken = authClient.getAuthorizationToken(resource, tenantId, clientId, clientSecret); + accessToken = authClient.getAccessToken(resource, tenantId, clientId, clientSecret); } else { - accessToken = authClient.getAuthorizationToken(resource); + accessToken = authClient.getAccessToken(resource); } } catch (UnsupportedEncodingException uee) { - uee.printStackTrace(); + LOGGER.log(WARNING, "Unsupported encoding", uee); } + LOGGER.log(FINE, "Access token: {0}", accessToken); return accessToken; } @@ -181,7 +198,7 @@ public Certificate getCertificate(String alias) { new ByteArrayInputStream(Base64.getDecoder() .decode(certificateBundle.getCer()))); } catch (CertificateException ce) { - ce.printStackTrace(); + LOGGER.log(WARNING, "Certificate error", ce); } } } @@ -222,8 +239,8 @@ public Key getKey(String alias, char[] password) { Base64.getDecoder().decode(secretBundle.getValue())), "".toCharArray()); alias = keyStore.aliases().nextElement(); key = keyStore.getKey(alias, "".toCharArray()); - } catch (Exception ex) { - ex.printStackTrace(); + } catch (IOException | KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException ex) { + LOGGER.log(WARNING, "Unable to decode key", ex); } } } else { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java index 95e0a4a3a19d2..a53c52c30a396 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java @@ -12,6 +12,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static java.util.logging.Level.FINEST; +import java.util.logging.Logger; import javax.net.ssl.SSLEngine; import javax.net.ssl.X509ExtendedKeyManager; @@ -22,11 +24,16 @@ */ public class KeyVaultKeyManager extends X509ExtendedKeyManager { + /** + * Stores the logger. + */ + private static final Logger LOGGER = Logger.getLogger(KeyVaultKeyManager.class.getName()); + /** * Stores the keystore. */ private KeyStore keystore; - + /** * Stores the password. */ @@ -44,12 +51,15 @@ public KeyVaultKeyManager(KeyStore keystore, char[] password) { @Override public String[] getClientAliases(String keyType, Principal[] issuers) { - throw new UnsupportedOperationException("Not supported yet."); + LOGGER.log(FINEST, "Key type: {0}, issuers: {1}", new Object[]{keyType, issuers}); + return null; } @Override public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { - throw new UnsupportedOperationException("Not supported yet."); + LOGGER.log(FINEST, "Key type: {0}, issuers: {1}, socket: {2}", + new Object[]{keyType, issuers, socket}); + return null; } @Override @@ -65,7 +75,9 @@ public String[] getServerAliases(String keyType, Principal[] issuers) { @Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { - throw new UnsupportedOperationException("Not supported yet."); + LOGGER.log(FINEST, "Key type: {0}, issuers: {1}, socket: {2}", + new Object[]{keyType, issuers, socket}); + return null; } @Override @@ -74,7 +86,7 @@ public X509Certificate[] getCertificateChain(String alias) { try { Certificate[] keystoreChain = keystore.getCertificateChain(alias); if (keystoreChain.length > 0) { - for(int i=0; i certificateAliases; + private List aliases; /** * Stores the certificates by alias. @@ -48,7 +48,7 @@ public class KeyVaultKeyStore extends KeyStoreSpi { private final Date creationDate; /** - * Stores the key vault. + * Stores the key vault client. */ private KeyVaultClient keyVault; @@ -67,17 +67,17 @@ public KeyVaultKeyStore() { creationDate = new Date(); String keyVaultUri = System.getProperty("azure.keyvault.uri"); String tenantId = System.getProperty("azure.keyvault.tenantId"); - String clientId = System.getProperty("azure.keyvault.clientId", null); - String clientSecret = System.getProperty("azure.keyvault.clientSecret", null); + String clientId = System.getProperty("azure.keyvault.clientId"); + String clientSecret = System.getProperty("azure.keyvault.clientSecret"); keyVault = new KeyVaultClient(keyVaultUri, tenantId, clientId, clientSecret); } @Override public Enumeration engineAliases() { - if (certificateAliases == null) { - certificateAliases = keyVault.getAliases(); + if (aliases == null) { + aliases = keyVault.getAliases(); } - return Collections.enumeration(certificateAliases); + return Collections.enumeration(aliases); } @Override @@ -103,8 +103,8 @@ public Certificate engineGetCertificate(String alias) { certificate = keyVault.getCertificate(alias); if (certificate != null) { certificates.put(alias, certificate); - if (!certificateAliases.contains(alias)) { - certificateAliases.add(alias); + if (!aliases.contains(alias)) { + aliases.add(alias); } } } @@ -155,8 +155,8 @@ public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmExc key = keyVault.getKey(alias, password); if (key != null) { certificateKeys.put(alias, key); - if (!certificateAliases.contains(alias)) { - certificateAliases.add(alias); + if (!aliases.contains(alias)) { + aliases.add(alias); } } } @@ -165,10 +165,10 @@ public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmExc @Override public boolean engineIsCertificateEntry(String alias) { - if (certificateAliases == null) { - certificateAliases = keyVault.getAliases(); + if (aliases == null) { + aliases = keyVault.getAliases(); } - return certificateAliases.contains(alias); + return aliases.contains(alias); } @Override @@ -181,8 +181,10 @@ public void engineLoad(KeyStore.LoadStoreParameter param) throws IOException, No if (param instanceof KeyVaultLoadStoreParameter) { KeyVaultLoadStoreParameter parameter = (KeyVaultLoadStoreParameter) param; keyVault = new KeyVaultClient( - parameter.getUri(), parameter.getTenantId(), - parameter.getClientId(), parameter.getClientSecret()); + parameter.getUri(), + parameter.getTenantId(), + parameter.getClientId(), + parameter.getClientSecret()); } } @@ -194,6 +196,11 @@ public void engineLoad(InputStream stream, char[] password) throws IOException, public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException { } + @Override + public void engineSetEntry(String alias, KeyStore.Entry entry, KeyStore.ProtectionParameter protParam) throws KeyStoreException { + super.engineSetEntry(alias, entry, protParam); + } + @Override public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { } @@ -204,10 +211,14 @@ public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) thr @Override public int engineSize() { - return certificateAliases != null ? certificateAliases.size() : 0; + return aliases != null ? aliases.size() : 0; } @Override public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { } + + @Override + public void engineStore(KeyStore.LoadStoreParameter param) throws IOException, NoSuchAlgorithmException, CertificateException { + } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java index 6821b5405a72b..8b0fb320048e7 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java @@ -22,7 +22,7 @@ public void testGetAuthorizationToken() throws Exception { String clientId = "2b8f123b-b18a-4077-bce0-42e10ce8bbab"; String clientSecret = "72-~tZ9~cG~rimDI0EkQSMQ1D9DYmGmI_I"; AuthClient authClient = new AuthClient(); - String result = authClient.getAuthorizationToken( + String result = authClient.getAccessToken( "https://management.azure.com/", tenantId, clientId, URLEncoder.encode(clientSecret, "UTF-8")); assertNotNull(result); diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultClientTest.java deleted file mode 100644 index 26cdddf4a46c3..0000000000000 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultClientTest.java +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -package com.azure.security.keyvault.jca; - -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * The JUnit tests for the KeyVaultClient class. - * - * @author Manfred Riem (manfred.riem@microsoft.com) - */ -public class KeyVaultClientTest { - - /** - * Stores the KeyVault URI. - */ - private static String keyVaultURI; - - /** - * Setup before any test. - */ - @BeforeAll - public static void setUpClass() { - keyVaultURI = System.getProperty("azure.keyvault.uri"); - } - - /** - * Test getCertificate method. - */ - @Test - public void testGetCertificate() { - KeyVaultClient client = new KeyVaultClient(keyVaultURI); - assertNull(client.getCertificate("myalias")); - } -} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java index 1cdf0484c865f..f0a11b6578d39 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java @@ -32,8 +32,13 @@ public void testConstructor() { @Test public void testGetCertificate() throws Exception { Security.addProvider(new KeyVaultJcaProvider()); - KeyStore keyStore = KeyStore.getInstance("AzureKeyVault"); - keyStore.load(null, null); - assertNull(keyStore.getCertificate("myalias")); + KeyStore keystore = KeyStore.getInstance("AzureKeyVault"); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + keystore.load(parameter); + assertNull(keystore.getCertificate("myalias")); } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java index 5a5f218d27760..7e0b2b7d0b306 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java @@ -2,10 +2,15 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; +import java.util.logging.ConsoleHandler; +import java.util.logging.Handler; +import static java.util.logging.Level.ALL; +import java.util.logging.Logger; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; /** @@ -22,43 +27,30 @@ public class KeyVaultKeyStoreTest { */ @Test public void testEngineGetCertificate() throws Exception { - KeyVaultKeyStore keystore = new KeyVaultKeyStore(); - keystore.engineLoad(null, null); - assertNull(keystore.engineGetCertificate("myalias")); - } - - /** - * Test engineGetCertificate method. - * - * @throws Exception when a serious error occurs. - */ - @Test - public void testEngineGetCertificate2() throws Exception { - KeyVaultKeyStore keystore = new KeyVaultKeyStore(); - keystore.engineLoad(null, null); - assertNull(keystore.engineGetCertificate("myalias")); - } - - /** - * Test engineGetCertificate method. - * - * @throws Exception when a serious error occurs. - */ - @Test - public void testEngineGetCertificate3() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), null, null, null); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); assertNull(keystore.engineGetCertificate("myalias")); } /** * Test engineGetCertificateAlias method. + * + * @throws Exception when an error occurs. */ @Test - public void testEngineGetCertificateAlias() { + public void testEngineGetCertificateAlias() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + keystore.engineLoad(parameter); assertNull(keystore.engineGetCertificateAlias(null)); } @@ -71,7 +63,10 @@ public void testEngineGetCertificateAlias() { public void testEngineGetCertificateChain() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), null, null, null); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); assertNull(keystore.engineGetCertificateChain("myalias")); } @@ -90,7 +85,6 @@ public void testEngineIsCertificateEntry() throws Exception { System.getProperty("azure.client.id"), System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); - assertFalse(keystore.engineIsCertificateEntry("myalias")); } From 0c3e63f9b7aed69b0715c82fc92bfc11adbe9731 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 8 Oct 2020 08:49:14 -0600 Subject: [PATCH 18/92] Added more logging --- .../keyvault/jca/KeyVaultKeyManager.java | 77 ++++++++++++------- .../jca/KeyVaultKeyManagerFactory.java | 6 +- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java index a53c52c30a396..1d871b57ddbf1 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java @@ -5,16 +5,18 @@ import java.net.Socket; import java.security.KeyStore; import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.PrivateKey; +import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import static java.util.logging.Level.FINEST; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; import java.util.logging.Logger; -import javax.net.ssl.SSLEngine; import javax.net.ssl.X509ExtendedKeyManager; /** @@ -43,41 +45,58 @@ public class KeyVaultKeyManager extends X509ExtendedKeyManager { * Constructor. * * @param keystore the keystore. + * @param password the password. */ public KeyVaultKeyManager(KeyStore keystore, char[] password) { this.keystore = keystore; this.password = password; } - @Override - public String[] getClientAliases(String keyType, Principal[] issuers) { - LOGGER.log(FINEST, "Key type: {0}, issuers: {1}", new Object[]{keyType, issuers}); - return null; - } - @Override public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { - LOGGER.log(FINEST, "Key type: {0}, issuers: {1}, socket: {2}", - new Object[]{keyType, issuers, socket}); - return null; + String alias = null; + try { + /* + * If we only have one alias and the keystore type is not 'AzureKeyVault' + * return that alias as a match. + */ + if (!keystore.getProvider().getName().equals("AzureKeyVault") + && keystore.size() == 1) { + alias = keystore.aliases().nextElement(); + } + } catch (KeyStoreException kse) { + LOGGER.log(WARNING, "Unable to choose client alias", kse); + } + return alias; } @Override - public String[] getServerAliases(String keyType, Principal[] issuers) { - String[] serverAliases = new String[0]; + public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { + String alias = null; try { - serverAliases = Collections.list(keystore.aliases()).toArray(new String[0]); + /* + * If we only have one alias and the keystore type is not 'AzureKeyVault' + * return that alias as a match. + */ + if (!keystore.getProvider().getName().equals("AzureKeyVault") + && keystore.size() == 1) { + alias = keystore.aliases().nextElement(); + } } catch (KeyStoreException kse) { - kse.printStackTrace(); + LOGGER.log(WARNING, "Unable to choose server alias", kse); } - return serverAliases; + return alias; } @Override - public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { - LOGGER.log(FINEST, "Key type: {0}, issuers: {1}, socket: {2}", - new Object[]{keyType, issuers, socket}); - return null; + public String[] getClientAliases(String keyType, Principal[] issuers) { + String[] aliases = null; + try { + aliases = Collections.list(keystore.aliases()).toArray(new String[0]); + } catch (KeyStoreException kse) { + LOGGER.log(WARNING, "Unable to get client aliases", kse); + } + return aliases; } @Override @@ -92,8 +111,8 @@ public X509Certificate[] getCertificateChain(String alias) { } } } - } catch (Exception ex) { - ex.printStackTrace(); + } catch (KeyStoreException kse) { + LOGGER.log(WARNING, "Unable to get certificate chain for alias: " + alias, kse); } return chain.toArray(new X509Certificate[0]); } @@ -103,14 +122,20 @@ public PrivateKey getPrivateKey(String alias) { PrivateKey privateKey = null; try { privateKey = (PrivateKey) keystore.getKey(alias, password); - } catch (Exception ex) { - ex.printStackTrace(); + } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException ex) { + LOGGER.log(WARNING, "Unable to get private key for alias: " + alias, ex); } return privateKey; } @Override - public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) { - return super.chooseEngineServerAlias(keyType, issuers, engine); + public String[] getServerAliases(String keyType, Principal[] issuers) { + String[] serverAliases = new String[0]; + try { + serverAliases = Collections.list(keystore.aliases()).toArray(new String[0]); + } catch (KeyStoreException kse) { + LOGGER.log(WARNING, "Unable to get server aliases", kse); + } + return serverAliases; } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java index 1fe250092fa6c..4709f93aefb5e 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java @@ -15,16 +15,16 @@ /** * The KeyVault variant of the KeyManagerFactory. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ public class KeyVaultKeyManagerFactory extends KeyManagerFactorySpi { - + /** * Stores the key managers. */ private List keyManagers = new ArrayList<>(); - + @Override protected void engineInit(KeyStore ks, char[] password) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { KeyVaultKeyManager manager = new KeyVaultKeyManager(ks, password); From f0624cfffca6fc3dc78f8e6c301c55abceb1796d Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 8 Oct 2020 08:49:53 -0600 Subject: [PATCH 19/92] Added more logging --- .../java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java index 1d871b57ddbf1..b2d668427bb5a 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java @@ -14,7 +14,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import java.util.logging.Logger; import javax.net.ssl.X509ExtendedKeyManager; From 8ec0bc7df4035f2a2e71a094d89e96d4e9e966b9 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 8 Oct 2020 12:02:51 -0600 Subject: [PATCH 20/92] Added configuration for Spring Cloud gateway --- .../README.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 6f321193afdcc..004bcfae57e01 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -157,3 +157,29 @@ And then if you are using RestTemplate use code similar to the example below. return restTemplate; } ``` + +## Using Azure KeyVault with Spring Cloud Gateway + +To use Azure KeyVault with Spring Cloud Gateway for outbound SSL you will need +to add the following configuration: + +```yaml +azure: + keyvault: + uri: +spring: + cloud: + gateway: + httpclient: + ssl: + trust-store-type: AzureKeyVault +``` + +Add then add the following Maven dependency to your POM file. + +```xml + + com.microsoft.azure + azure-keyvault-certificates-spring-boot-starter + +``` From 8dbd7ace724ac5d5caec744d09f27d092cb33432 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 8 Oct 2020 12:58:48 -0600 Subject: [PATCH 21/92] Added creating an Azure KeyVault section --- .../README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 004bcfae57e01..93695a61c0bb3 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -183,3 +183,14 @@ Add then add the following Maven dependency to your POM file. azure-keyvault-certificates-spring-boot-starter ``` + +## Creating an Azure Key Vault + +To create an Azure KeyVault use the command line below: + +```shell + export KEYVAULT=mykeyvault + export RESOURCE_GROUP=myresourcegroup + az keyvault create --name ${KEY_VAULT} -g ${RESOURCE_GROUP} +``` + From 132ec369267fe682dd8e1e93801be79d60a74624 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 8 Oct 2020 13:07:39 -0600 Subject: [PATCH 22/92] Add instructions to create a self-signed certificate --- .../README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 93695a61c0bb3..b47b7f83d24d9 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -194,3 +194,12 @@ To create an Azure KeyVault use the command line below: az keyvault create --name ${KEY_VAULT} -g ${RESOURCE_GROUP} ``` +## Create a self-signed certificate + +To create a self-signed certificate use the command line below: + +```shell + export CERTIFICATE_ALIAS=self-signed + az keyvault certificate create --vault-name ${KEY_VAULT} \ + -n ${CERTIFICATE_ALIAS} -p "$(az keyvault certificate get-default-policy)" +``` From bec1cf67b63b8220a3bfd9d652348f8b312e3e80 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 8 Oct 2020 13:18:26 -0600 Subject: [PATCH 23/92] Add 'assign a managed identity' --- .../README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index b47b7f83d24d9..c6fa5442c97c0 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -203,3 +203,14 @@ To create a self-signed certificate use the command line below: az keyvault certificate create --vault-name ${KEY_VAULT} \ -n ${CERTIFICATE_ALIAS} -p "$(az keyvault certificate get-default-policy)" ``` + +## Assign a managed identity to an Azure Spring Cloud application + +To assign a managed identity use the command line below: + +```shell + export SPRING_CLOUD_APP=myspringcloudapp + az spring-cloud app identity assign --name ${SPRING_CLOUD_APP} + export SPRING_CLOUD_APP_IDENTITY=$(az spring-cloud app show \ + --name ${SPRING_CLOUD_APP} --query identity.principalId --output tsv) +``` From da1774b8199f067e025548b80e3fd2276886cde0 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 8 Oct 2020 13:29:33 -0600 Subject: [PATCH 24/92] Add instructions to grant a managed identity access to keyvault --- .../README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index c6fa5442c97c0..f696158250c4f 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -189,7 +189,7 @@ Add then add the following Maven dependency to your POM file. To create an Azure KeyVault use the command line below: ```shell - export KEYVAULT=mykeyvault + export KEY_VAULT=mykeyvault export RESOURCE_GROUP=myresourcegroup az keyvault create --name ${KEY_VAULT} -g ${RESOURCE_GROUP} ``` @@ -204,13 +204,25 @@ To create a self-signed certificate use the command line below: -n ${CERTIFICATE_ALIAS} -p "$(az keyvault certificate get-default-policy)" ``` -## Assign a managed identity to an Azure Spring Cloud application +## Assign a managed identity (to an Azure Spring Cloud application) To assign a managed identity use the command line below: ```shell export SPRING_CLOUD_APP=myspringcloudapp az spring-cloud app identity assign --name ${SPRING_CLOUD_APP} - export SPRING_CLOUD_APP_IDENTITY=$(az spring-cloud app show \ + export MANAGED_IDENTITY=$(az spring-cloud app show \ --name ${SPRING_CLOUD_APP} --query identity.principalId --output tsv) ``` + +## Grant a managed identity with access to Azure Key Vault + +To grant access use the command line below: + +```shell + az keyvault set-policy --name ${KEY_VAULT} \ + --object-id ${MANAGED_IDENTITY} \ + --key-permisssions get list \ + --secret-permissions get list \ + --certificate-permissions get list +``` From c89d604786124ea2879e8a3aa0b9acb4a5958fbc Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 8 Oct 2020 16:16:54 -0600 Subject: [PATCH 25/92] Add link to JCA provider --- .../keyvault/jca/KeyVaultKeyManager.java | 18 ++++++++++++++++++ .../jca/KeyVaultKeyManagerFactory.java | 14 ++++++++++++-- .../README.md | 4 ++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java index b2d668427bb5a..714f66b972b91 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import java.util.logging.Logger; import javax.net.ssl.X509ExtendedKeyManager; @@ -47,12 +48,16 @@ public class KeyVaultKeyManager extends X509ExtendedKeyManager { * @param password the password. */ public KeyVaultKeyManager(KeyStore keystore, char[] password) { + LOGGER.log(INFO, "KeyVaultKeyManager.: {0}, {1}", + new Object[] {keystore, new String(password)}); this.keystore = keystore; this.password = password; } @Override public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { + LOGGER.log(INFO, "KeyVaultKeyManager.chooseClientAlias: {0}, {1}, {2}", + new Object[] {keyType, issuers, socket}); String alias = null; try { /* @@ -66,11 +71,14 @@ public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket so } catch (KeyStoreException kse) { LOGGER.log(WARNING, "Unable to choose client alias", kse); } + LOGGER.log(INFO, "KeyVaultKeyManager.chooseClientAlias: {0}", alias); return alias; } @Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { + LOGGER.log(INFO, "KeyVaultKeyManager.chooseServerAlias: {0}, {1}, {2}", + new Object[] {keyType, issuers, socket}); String alias = null; try { /* @@ -84,22 +92,27 @@ public String chooseServerAlias(String keyType, Principal[] issuers, Socket sock } catch (KeyStoreException kse) { LOGGER.log(WARNING, "Unable to choose server alias", kse); } + LOGGER.log(INFO, "KeyVaultKeyManager.chooseServerAlias: {0}", alias); return alias; } @Override public String[] getClientAliases(String keyType, Principal[] issuers) { + LOGGER.log(INFO, "KeyVaultKeyManager.getClientAliases: {0}, {1}", + new Object[] {keyType, issuers}); String[] aliases = null; try { aliases = Collections.list(keystore.aliases()).toArray(new String[0]); } catch (KeyStoreException kse) { LOGGER.log(WARNING, "Unable to get client aliases", kse); } + LOGGER.log(INFO, "KeyVaultKeyManager.getClientAliases: {0}", aliases); return aliases; } @Override public X509Certificate[] getCertificateChain(String alias) { + LOGGER.log(INFO, "KeyVaultKeyManager.getCertificateChain: {0}", alias); List chain = new ArrayList<>(); try { Certificate[] keystoreChain = keystore.getCertificateChain(alias); @@ -113,28 +126,33 @@ public X509Certificate[] getCertificateChain(String alias) { } catch (KeyStoreException kse) { LOGGER.log(WARNING, "Unable to get certificate chain for alias: " + alias, kse); } + LOGGER.log(INFO, "KeyVaultKeyManager.getCertificateChain: {0}", chain); return chain.toArray(new X509Certificate[0]); } @Override public PrivateKey getPrivateKey(String alias) { + LOGGER.log(INFO, "KeyVaultKeyManager.getPrivateKey: {0}", alias); PrivateKey privateKey = null; try { privateKey = (PrivateKey) keystore.getKey(alias, password); } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException ex) { LOGGER.log(WARNING, "Unable to get private key for alias: " + alias, ex); } + LOGGER.log(INFO, "KeyVaultKeyManager.getPrivateKey: {0}", privateKey); return privateKey; } @Override public String[] getServerAliases(String keyType, Principal[] issuers) { + LOGGER.log(INFO, "KeyVaultKeyManager.getServerAliases: {0}, {1}", new Object[] {keyType, issuers}); String[] serverAliases = new String[0]; try { serverAliases = Collections.list(keystore.aliases()).toArray(new String[0]); } catch (KeyStoreException kse) { LOGGER.log(WARNING, "Unable to get server aliases", kse); } + LOGGER.log(INFO, "KeyVaultKeyManager.getServerAliases: {0}", serverAliases); return serverAliases; } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java index 4709f93aefb5e..14c19ecd52dc7 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java @@ -9,6 +9,8 @@ import java.security.UnrecoverableKeyException; import java.util.ArrayList; import java.util.List; +import static java.util.logging.Level.INFO; +import java.util.logging.Logger; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactorySpi; import javax.net.ssl.ManagerFactoryParameters; @@ -20,14 +22,21 @@ */ public class KeyVaultKeyManagerFactory extends KeyManagerFactorySpi { + /** + * Stores the logger. + */ + private static final Logger LOGGER = Logger.getLogger(KeyVaultKeyManagerFactory.class.getName()); + /** * Stores the key managers. */ private List keyManagers = new ArrayList<>(); @Override - protected void engineInit(KeyStore ks, char[] password) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { - KeyVaultKeyManager manager = new KeyVaultKeyManager(ks, password); + protected void engineInit(KeyStore keystore, char[] password) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { + LOGGER.log(INFO, "KeyVaultKeyManagerFactory.engineInit: {0}, {1}", + new Object[] {keystore, new String(password)}); + KeyVaultKeyManager manager = new KeyVaultKeyManager(keystore, password); keyManagers.add(manager); } @@ -37,6 +46,7 @@ protected void engineInit(ManagerFactoryParameters spec) throws InvalidAlgorithm @Override protected KeyManager[] engineGetKeyManagers() { + LOGGER.log(INFO, "KeyVaultKeyManagerFactory.engineGetKeyManagers: {0}", keyManagers); return keyManagers.toArray(new KeyManager[0]); } } diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index f696158250c4f..00c38268105ce 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -2,8 +2,8 @@ If you want to test the current version under development you will have to -1. Build and install the Microsoft Azure JCA Provider for KeyVault -1. Build and install this Starter. +1. Build and install the [Microsoft Azure JCA Provider](../../keyvault/azure-security-keyvault-jca/README.md) for KeyVault +1. Build and install this starter. To build and install the starter use the following command line: From f9d0dd5bf2640a87ba483452b4e36b5abbe86cf7 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 9 Oct 2020 07:40:15 -0600 Subject: [PATCH 26/92] Added link to JCA reference guide --- sdk/keyvault/azure-security-keyvault-jca/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index b44c9f3ec5ff2..638d323def2d1 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -97,3 +97,7 @@ of the `azure.keyvault.uri` and let the remaining parameters be `null`. ## Spring Boot For Spring Boot applications see our Spring Boot starter. + +## Reference + +1. [Java Cryptography Architecture (JCA) Reference Guide](https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html) \ No newline at end of file From 61c8a1980e0257f294161bee33bd2e7a8473cc12 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 9 Oct 2020 08:28:48 -0600 Subject: [PATCH 27/92] Add link to our Spring Boot starter --- sdk/keyvault/azure-security-keyvault-jca/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index 638d323def2d1..59e9b95dc2f8c 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -96,7 +96,7 @@ of the `azure.keyvault.uri` and let the remaining parameters be `null`. ## Spring Boot -For Spring Boot applications see our Spring Boot starter. +For Spring Boot applications see our [Spring Boot starter](../spring/azure-spring-boot-starter-keyvault-certificates/README.md). ## Reference From 53316f374235c924674dfc94fd35f7a6ae31abf7 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 9 Oct 2020 08:50:22 -0600 Subject: [PATCH 28/92] Make sure server.ssl.key-store and server.ssl.trust-store are set automatically when applicable --- ...tCertificatesEnvironmentPostProcessor.java | 59 +++++++++++++------ .../resources/config/application.properties | 2 - 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index 95ee3e079b472..ef40e04cdf6a4 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -10,6 +10,9 @@ import static org.springframework.core.Ordered.LOWEST_PRECEDENCE; import org.springframework.core.annotation.Order; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertiesPropertySource; +import org.springframework.core.env.PropertySource; @Order(LOWEST_PRECEDENCE) public class KeyVaultCertificatesEnvironmentPostProcessor implements EnvironmentPostProcessor { @@ -18,29 +21,49 @@ public class KeyVaultCertificatesEnvironmentPostProcessor implements Environment public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - Properties properties = System.getProperties(); - + Properties systemProperties = System.getProperties(); + String uri = environment.getProperty("azure.keyvault.uri"); if (uri != null) { - properties.put("azure.keyvault.uri", uri); - } + systemProperties.put("azure.keyvault.uri", uri); - String tenantId = environment.getProperty("azure.keyvault.tenantId"); - if (tenantId != null) { - properties.put("azure.keyvault.tenantId", tenantId); - } + String tenantId = environment.getProperty("azure.keyvault.tenantId"); + if (tenantId != null) { + systemProperties.put("azure.keyvault.tenantId", tenantId); + } - String clientId = environment.getProperty("azure.keyvault.clientId"); - if (clientId != null) { - properties.put("azure.keyvault.clientId", clientId); - } + String clientId = environment.getProperty("azure.keyvault.clientId"); + if (clientId != null) { + systemProperties.put("azure.keyvault.clientId", clientId); + } - String clientSecret = environment.getProperty("azure.keyvault.clientSecret"); - if (clientSecret != null) { - properties.put("azure.keyvault.clientSecret", clientSecret); - } + String clientSecret = environment.getProperty("azure.keyvault.clientSecret"); + if (clientSecret != null) { + systemProperties.put("azure.keyvault.clientSecret", clientSecret); + } - KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); - Security.insertProviderAt(provider, 1); + String keyStoreType = environment.getProperty("server.ssl.key-store-type"); + + if (keyStoreType != null && (keyStoreType.equals("DKS") || keyStoreType.equals("AzureKeyVault"))) { + MutablePropertySources sources = environment.getPropertySources(); + Properties properties = new Properties(); + properties.put("server.ssl.key-store", "classpath:keyvault.dummy"); + PropertySource propertySource = new PropertiesPropertySource("KeyStorePropertySource", properties); + sources.addFirst(propertySource); + } + + String trustStoreType = environment.getProperty("server.ssl.trust-store-type"); + + if (trustStoreType != null && (trustStoreType.equals("DKS") || trustStoreType.equals("AzureKeyVault"))) { + MutablePropertySources sources = environment.getPropertySources(); + Properties properties = new Properties(); + properties.put("server.ssl.trust-store", "classpath:keyvault.dummy"); + PropertySource propertySource = new PropertiesPropertySource("TrustStorePropertySource", properties); + sources.addFirst(propertySource); + } + + KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); + Security.insertProviderAt(provider, 1); + } } } diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/config/application.properties b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/config/application.properties index 6365a99bb5466..997ec590954ba 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/config/application.properties +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/config/application.properties @@ -1,5 +1,3 @@ -server.ssl.key-store=classpath:keyvault.dummy server.ssl.key-store-password=doesnotmatter server.ssl.key-password=doesnotmatter -server.ssl.trust-store=classpath:keyvault.dummy server.ssl.trust-store-password=doesnotmatter From ea2eb042c90284240b08ef87e0103faf5df6d23f Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 9 Oct 2020 12:02:13 -0600 Subject: [PATCH 29/92] Fix Spring Boot starter link --- .../azure-security-keyvault-jca/README.md | 2 +- .../README.md | 24 ++++++------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index 59e9b95dc2f8c..3960c88ffe84a 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -96,7 +96,7 @@ of the `azure.keyvault.uri` and let the remaining parameters be `null`. ## Spring Boot -For Spring Boot applications see our [Spring Boot starter](../spring/azure-spring-boot-starter-keyvault-certificates/README.md). +For Spring Boot applications see our [Spring Boot starter](../../spring/azure-spring-boot-starter-keyvault-certificates/README.md). ## Reference diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 00c38268105ce..0ef645e961b8c 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -133,7 +133,8 @@ Add then add the following Maven dependency to your POM file. ``` -And then if you are using RestTemplate use code similar to the example below. +And then if you are using RestTemplate use the code below as a starting +point: ```java @Bean @@ -143,7 +144,8 @@ And then if you are using RestTemplate use code similar to the example below. .loadTrustMaterial(ks, new TrustSelfSignedStrategy()) .build(); - SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); + HostnameVerifier allowAll = (String hostName, SSLSession session) -> true; + SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, allowAll); CloseableHttpClient httpClient = HttpClients.custom() .setSSLSocketFactory(csf) @@ -158,30 +160,18 @@ And then if you are using RestTemplate use code similar to the example below. } ``` -## Using Azure KeyVault with Spring Cloud Gateway +## Configuring Spring Cloud Gateway -To use Azure KeyVault with Spring Cloud Gateway for outbound SSL you will need +To configure Spring Cloud Gateway for outbound SSL you will need to add the following configuration: ```yaml -azure: - keyvault: - uri: spring: cloud: gateway: httpclient: ssl: - trust-store-type: AzureKeyVault -``` - -Add then add the following Maven dependency to your POM file. - -```xml - - com.microsoft.azure - azure-keyvault-certificates-spring-boot-starter - + useInsecureTrustManager: true ``` ## Creating an Azure Key Vault From 716acd7f264d3e2e425a241ddaebeae7bc4a27cc Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 13 Oct 2020 09:54:06 -0600 Subject: [PATCH 30/92] Reworked logging --- .../azure/security/keyvault/jca/AuthClient.java | 17 +++++++++-------- .../security/keyvault/jca/KeyVaultClient.java | 13 ++++++++----- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java index d668999da97f2..8b08c502e4aa5 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -73,7 +73,6 @@ public AuthClient() { * @return the authorization token. */ public String getAccessToken(String resource) { - LOGGER.log(FINER, "Resource: {0}", resource); String result; if (System.getenv("WEBSITE_SITE_NAME") != null @@ -82,7 +81,6 @@ public String getAccessToken(String resource) { } else { result = getAccessTokenOnOthers(resource); } - LOGGER.log(FINER, "Access token: {0}", result); return result; } @@ -97,8 +95,9 @@ public String getAccessToken(String resource) { */ public String getAccessToken(String resource, String tenantId, String clientId, String clientSecret) { - LOGGER.log(FINER, "\nResource: {0}\nTenant ID: {1}\nClient ID: {2}\nClient secret: {3}", - new Object[] {resource, tenantId, clientId, clientSecret}); + LOGGER.entering("AuthClient", "getAccessToken", new Object[] { + resource, tenantId, clientId, clientSecret}); + LOGGER.info("Getting access token using client ID / client secret"); String result = null; StringBuilder oauth2Url = new StringBuilder(); @@ -129,7 +128,8 @@ public String getAccessToken(String resource, String tenantId, * @return the authorization token. */ private String getAccessTokenOnAppService(String resource) { - LOGGER.log(FINER, "Resource: {0}", resource); + LOGGER.entering("AuthClient", "getAccessTokenOnAppService", resource); + LOGGER.info("Getting access token using managed identity based on MSI_SECRET"); String result = null; StringBuilder url = new StringBuilder(); @@ -147,7 +147,7 @@ private String getAccessTokenOnAppService(String resource) { OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); result = token.getAccess_token(); } - LOGGER.log(FINER, "Access Token: {0}", result); + LOGGER.exiting("AuthClient", "getAccessTokenOnAppService", result); return result; } @@ -158,7 +158,8 @@ private String getAccessTokenOnAppService(String resource) { * @return the authorization token. */ private String getAccessTokenOnOthers(String resource) { - LOGGER.log(FINER, "Resource: {0}", resource); + LOGGER.entering("AuthClient", "getAccessTokenOnOthers", resource); + LOGGER.info("Getting access token using managed identity"); String result = null; StringBuilder url = new StringBuilder(); @@ -174,7 +175,7 @@ private String getAccessTokenOnOthers(String resource) { OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); result = token.getAccess_token(); } - LOGGER.log(FINER, "Access token: {0}", result); + LOGGER.exiting("AuthClient", "getAccessTokenOnOthers", result); return result; } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java index 7643f52d8bffa..cda34b9b25e3b 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java @@ -23,7 +23,6 @@ import java.util.Base64; import java.util.HashMap; import java.util.List; -import static java.util.logging.Level.FINE; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import java.util.logging.Logger; @@ -72,7 +71,6 @@ class KeyVaultClient extends DelegateRestClient { */ public KeyVaultClient(String keyVaultUri) { super(RestClientFactory.createClient()); - LOGGER.log(FINE, "KeyVault URI: {0}", keyVaultUri); if (!keyVaultUri.endsWith("/")) { keyVaultUri = keyVaultUri + "/"; } @@ -89,8 +87,6 @@ public KeyVaultClient(String keyVaultUri) { */ public KeyVaultClient(String keyVaultUri, String tenantId, String clientId, String clientSecret) { this(keyVaultUri); - LOGGER.log(FINE, "\nKeyVault URI: {0}\nTenant ID: {1}\nClient ID: {2}\nClient Secret: {3}", - new Object[] {keyVaultUri, tenantId, clientId, clientSecret}); this.tenantId = tenantId; this.clientId = clientId; this.clientSecret = clientSecret; @@ -102,6 +98,7 @@ public KeyVaultClient(String keyVaultUri, String tenantId, String clientId, Stri * @return the access token. */ private String getAccessToken() { + LOGGER.entering("KeyVaultClient", "getAccessToken"); String accessToken = null; try { AuthClient authClient = new AuthClient(); @@ -114,7 +111,7 @@ private String getAccessToken() { } catch (UnsupportedEncodingException uee) { LOGGER.log(WARNING, "Unsupported encoding", uee); } - LOGGER.log(FINE, "Access token: {0}", accessToken); + LOGGER.exiting("KeyVaultClient", "getAccessToken", accessToken); return accessToken; } @@ -187,6 +184,8 @@ private CertificateBundle getCertificateBundle(String alias) { * @return the certificate, or null if not found. */ public Certificate getCertificate(String alias) { + LOGGER.entering("KeyVaultClient", "getCertificate", alias); + LOGGER.log(INFO, "Getting certificate for alias: {0}", alias); X509Certificate certificate = null; CertificateBundle certificateBundle = getCertificateBundle(alias); if (certificateBundle != null) { @@ -202,6 +201,7 @@ public Certificate getCertificate(String alias) { } } } + LOGGER.exiting("KeyVaultClient", "getCertificate", certificate); return certificate; } @@ -213,6 +213,8 @@ public Certificate getCertificate(String alias) { * @return the key. */ public Key getKey(String alias, char[] password) { + LOGGER.entering("KeyVaultClient", "getKey", new Object[] {alias, password}); + LOGGER.log(INFO, "Getting key for alias: {0}", alias); Key key = null; CertificateBundle certificateBundle = getCertificateBundle(alias); if (certificateBundle != null @@ -250,6 +252,7 @@ public Key getKey(String alias, char[] password) { // the intent of the usage at this stage we skip this key. // } + LOGGER.exiting("KeyVaultClient", "getKey", key); return key; } } From 10e00108e663c0d552fca49e59671f72aa8271f8 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 13 Oct 2020 11:31:00 -0600 Subject: [PATCH 31/92] Reworked logging --- .../azure-security-keyvault-jca/pom.xml | 6 +++++ .../keyvault/jca/JacksonJsonConverter.java | 8 +++---- .../keyvault/jca/KeyVaultKeyManager.java | 23 +++++++++---------- .../jca/KeyVaultKeyManagerFactory.java | 4 ++-- .../keyvault/jca/KeyVaultKeyStoreTest.java | 5 ---- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index 943b66bcdc21e..6a1a29b536b4f 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -133,6 +133,12 @@ 5.6.0 test + + + org.slf4j + slf4j-nop + 1.7.25 + diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java index b49d0a862f92b..e6da5fc13ed35 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java @@ -30,7 +30,7 @@ class JacksonJsonConverter implements JsonConverter { */ @Override public Object fromJson(String string, Class resultClass) { - LOGGER.log(FINEST, "Result Class: {1}, Json:\n {0}", new Object[] {string, resultClass}); + LOGGER.entering("JacksonJsonConverter", "fromJson", new Object[] {string, resultClass}); Object result = null; try { ObjectMapper objectMapper = new ObjectMapper(); @@ -39,7 +39,7 @@ public Object fromJson(String string, Class resultClass) { } catch (JsonProcessingException e) { LOGGER.log(WARNING, "Unable to convert from JSON", e); } - LOGGER.log(FINEST, "Object: {0}", result); + LOGGER.exiting("JacksonJsonConverter", "fromJson", result); return result; } @@ -51,7 +51,7 @@ public Object fromJson(String string, Class resultClass) { */ @Override public String toJson(Object object) { - LOGGER.log(FINEST, "Object: {0}", object); + LOGGER.entering("JacksonJsonConverter", "toJson", object); String result = null; try { ObjectMapper mapper = new ObjectMapper(); @@ -59,7 +59,7 @@ public String toJson(Object object) { } catch (JsonProcessingException e) { LOGGER.log(WARNING, "Unable to convert to JSON", e); } - LOGGER.log(FINEST, "Json:\n {0}", result); + LOGGER.exiting("JacksonJsonConverter", "toJson", result); return result; } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java index 714f66b972b91..02386fde6329a 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java @@ -48,15 +48,14 @@ public class KeyVaultKeyManager extends X509ExtendedKeyManager { * @param password the password. */ public KeyVaultKeyManager(KeyStore keystore, char[] password) { - LOGGER.log(INFO, "KeyVaultKeyManager.: {0}, {1}", - new Object[] {keystore, new String(password)}); + LOGGER.entering("KeyVaultKeyManager", "", new Object[] {keystore, password}); this.keystore = keystore; this.password = password; } @Override public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { - LOGGER.log(INFO, "KeyVaultKeyManager.chooseClientAlias: {0}, {1}, {2}", + LOGGER.entering("KeyVaultKeyManager", "chooseClientAlias", new Object[] {keyType, issuers, socket}); String alias = null; try { @@ -71,13 +70,13 @@ public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket so } catch (KeyStoreException kse) { LOGGER.log(WARNING, "Unable to choose client alias", kse); } - LOGGER.log(INFO, "KeyVaultKeyManager.chooseClientAlias: {0}", alias); + LOGGER.exiting("KeyVaultKeyManager", "chooseClientAlias", alias); return alias; } @Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { - LOGGER.log(INFO, "KeyVaultKeyManager.chooseServerAlias: {0}, {1}, {2}", + LOGGER.entering("KeyVaultKeyManager", "chooseServerAlias", new Object[] {keyType, issuers, socket}); String alias = null; try { @@ -92,7 +91,7 @@ public String chooseServerAlias(String keyType, Principal[] issuers, Socket sock } catch (KeyStoreException kse) { LOGGER.log(WARNING, "Unable to choose server alias", kse); } - LOGGER.log(INFO, "KeyVaultKeyManager.chooseServerAlias: {0}", alias); + LOGGER.exiting("KeyVaultKeyManager", "chooseServerAlias", alias); return alias; } @@ -112,7 +111,7 @@ public String[] getClientAliases(String keyType, Principal[] issuers) { @Override public X509Certificate[] getCertificateChain(String alias) { - LOGGER.log(INFO, "KeyVaultKeyManager.getCertificateChain: {0}", alias); + LOGGER.entering("KeyVaultKeyManager", "getCertificateChain", alias); List chain = new ArrayList<>(); try { Certificate[] keystoreChain = keystore.getCertificateChain(alias); @@ -126,33 +125,33 @@ public X509Certificate[] getCertificateChain(String alias) { } catch (KeyStoreException kse) { LOGGER.log(WARNING, "Unable to get certificate chain for alias: " + alias, kse); } - LOGGER.log(INFO, "KeyVaultKeyManager.getCertificateChain: {0}", chain); + LOGGER.exiting("KeyVaultKeyManager", "getCertificateChain", chain); return chain.toArray(new X509Certificate[0]); } @Override public PrivateKey getPrivateKey(String alias) { - LOGGER.log(INFO, "KeyVaultKeyManager.getPrivateKey: {0}", alias); + LOGGER.entering("KeyVaultKeyManager", "getPrivateKey", alias); PrivateKey privateKey = null; try { privateKey = (PrivateKey) keystore.getKey(alias, password); } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException ex) { LOGGER.log(WARNING, "Unable to get private key for alias: " + alias, ex); } - LOGGER.log(INFO, "KeyVaultKeyManager.getPrivateKey: {0}", privateKey); + LOGGER.exiting("KeyVaultKeyManager", "getPrivateKey", privateKey); return privateKey; } @Override public String[] getServerAliases(String keyType, Principal[] issuers) { - LOGGER.log(INFO, "KeyVaultKeyManager.getServerAliases: {0}, {1}", new Object[] {keyType, issuers}); + LOGGER.entering("KeyVaultKeyManager", "getServerAliases", new Object[] {keyType, issuers}); String[] serverAliases = new String[0]; try { serverAliases = Collections.list(keystore.aliases()).toArray(new String[0]); } catch (KeyStoreException kse) { LOGGER.log(WARNING, "Unable to get server aliases", kse); } - LOGGER.log(INFO, "KeyVaultKeyManager.getServerAliases: {0}", serverAliases); + LOGGER.exiting("KeyVaultKeyManager", "getServerAliases", serverAliases); return serverAliases; } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java index 14c19ecd52dc7..dd0692b78e919 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java @@ -34,7 +34,7 @@ public class KeyVaultKeyManagerFactory extends KeyManagerFactorySpi { @Override protected void engineInit(KeyStore keystore, char[] password) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { - LOGGER.log(INFO, "KeyVaultKeyManagerFactory.engineInit: {0}, {1}", + LOGGER.entering("KeyVaultKeyManagerFactory", "engineInit", new Object[] {keystore, new String(password)}); KeyVaultKeyManager manager = new KeyVaultKeyManager(keystore, password); keyManagers.add(manager); @@ -46,7 +46,7 @@ protected void engineInit(ManagerFactoryParameters spec) throws InvalidAlgorithm @Override protected KeyManager[] engineGetKeyManagers() { - LOGGER.log(INFO, "KeyVaultKeyManagerFactory.engineGetKeyManagers: {0}", keyManagers); + LOGGER.exiting("KeyVaultKeyManagerFactory", "engineGetKeyManagers", keyManagers); return keyManagers.toArray(new KeyManager[0]); } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java index 7e0b2b7d0b306..a05e223e356c2 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java @@ -2,15 +2,10 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; -import java.util.logging.ConsoleHandler; -import java.util.logging.Handler; -import static java.util.logging.Level.ALL; -import java.util.logging.Logger; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; /** From 736723184f7e4decd1fc25b913388ef6264fa42c Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 13 Oct 2020 15:10:23 -0600 Subject: [PATCH 32/92] Added certificate side-loading --- .../keyvault/jca/KeyVaultKeyStore.java | 9 +++- .../keyvault/jca/KeyVaultKeyStoreTest.java | 50 ++++++++++++++++- ...tCertificatesEnvironmentPostProcessor.java | 53 ++++++++++++++++++- 3 files changed, 109 insertions(+), 3 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java index 2de431a50a589..5147a11e2b052 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java @@ -193,7 +193,14 @@ public void engineLoad(InputStream stream, char[] password) throws IOException, } @Override - public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException { + public void engineSetCertificateEntry(String alias, Certificate certificate) throws KeyStoreException { + if (aliases == null) { + aliases = keyVault.getAliases(); + } + if (!aliases.contains(alias)) { + aliases.add(alias); + certificates.put(alias, certificate); + } } @Override diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java index a05e223e356c2..97da44bfd4066 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java @@ -2,6 +2,12 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; +import java.io.ByteArrayInputStream; +import java.security.ProviderException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Base64; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -15,6 +21,30 @@ */ public class KeyVaultKeyStoreTest { + /** + * Stores the CER test certificate (which is valid til 2120). + */ + private static final String TEST_CERTIFICATE + = "MIIDeDCCAmCgAwIBAgIQGghBu97rQJKNnUHPWU7xjDANBgkqhkiG9w0BAQsFADAk" + + "MSIwIAYDVQQDExlodW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMCAXDTIwMDkwMjE3" + + "NDUyNFoYDzIxMjAwOTAyMTc1NTI0WjAkMSIwIAYDVQQDExlodW5kcmVkLXllYXJz" + + "LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuU14" + + "btkN5wmcO2WKXqm1NUKXzi79EtqiFFkrLgPAwj5NNwMw2Akm3GpdEpwkJ8/q3l7d" + + "frDEVOO9gwZbz7xppyqutjxjllw8CCgjFdfK02btz56CGgh3X25ZZtzPbuMZJM0j" + + "o4mVEdaFNJ0eUeMppS0DcbbuTWCF7Jf1gvr8GVqx+E0IJUFkE+D4kdTbnJSaeK0A" + + "KEt94z88MPX18h8ud14uRVmUCYVZrZeswdE2tO1BpazrXELHuXCtrjGxsDDjDzeP" + + "98aFI9kblkqoJS4TsmloLEjwZLm80cyJDEmpXXMtR7C0FFXFI1BAtIa4mxSgBLsT" + + "L4GVPEGNANR8COYkHQIDAQABo4GjMIGgMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRME" + + "AjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAkBgNVHREEHTAbghlo" + + "dW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMB8GA1UdIwQYMBaAFOGTt4H3ho30O4e+" + + "hebwJjm2VMvIMB0GA1UdDgQWBBThk7eB94aN9DuHvoXm8CY5tlTLyDANBgkqhkiG" + + "9w0BAQsFAAOCAQEAGp8mCioVCmM+kZv6r+K2j2uog1k4HBwN1NfRoSsibDB8+QXF" + + "bmNf3M0imiuR/KJgODyuROwaa/AalxNFMOP8XTL2YmP7XsddBs9ONHHQXKjY/Ojl" + + "PsIPR7vZjwYPfEB+XEKl2fOIxDQQ921POBV7M6DdTC49T5X+FsLR1AIIfinVetT9" + + "QmNuvzulBX0T0rea/qpcPK4HTj7ToyImOaf8sXRv2s2ODLUrKWu5hhTNH2l6RIkQ" + + "U/aIAdQRfDaSE9jhtcVu5d5kCgBs7nz5AzeCisDPo5zIt4Mxej3iVaAJ79oEbHOE" + + "p192KLXLV/pscA4Wgb+PJ8AAEa5B6xq8p9JO+Q=="; + /** * Test engineGetCertificate method. * @@ -91,7 +121,25 @@ public void testEngineIsCertificateEntry() throws Exception { @Test public void testEngineSetCertificateEntry() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); - keystore.engineSetCertificateEntry("myalias", null); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); + keystore.engineLoad(parameter); + + X509Certificate certificate; + + try { + byte[] certificateBytes = Base64.getDecoder().decode(TEST_CERTIFICATE); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certificateBytes)); + } catch (CertificateException e) { + throw new ProviderException(e); + } + + keystore.engineSetCertificateEntry("setcert", certificate); + assertNotNull(keystore.engineGetCertificate("setcert")); } /** diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index ef40e04cdf6a4..00a0592db3d1e 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -3,8 +3,19 @@ package com.azure.keyvault.certificates.starter; import com.azure.security.keyvault.jca.KeyVaultJcaProvider; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; import java.security.Security; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; import java.util.Properties; +import static java.util.logging.Level.WARNING; +import java.util.logging.Logger; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import static org.springframework.core.Ordered.LOWEST_PRECEDENCE; @@ -13,10 +24,17 @@ import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.env.PropertySource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; @Order(LOWEST_PRECEDENCE) public class KeyVaultCertificatesEnvironmentPostProcessor implements EnvironmentPostProcessor { + /** + * Stores the logger. + */ + private static final Logger LOGGER = Logger.getLogger(KeyVaultCertificatesEnvironmentPostProcessor.class.getName()); + @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { @@ -51,7 +69,7 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, PropertySource propertySource = new PropertiesPropertySource("KeyStorePropertySource", properties); sources.addFirst(propertySource); } - + String trustStoreType = environment.getProperty("server.ssl.trust-store-type"); if (trustStoreType != null && (trustStoreType.equals("DKS") || trustStoreType.equals("AzureKeyVault"))) { @@ -64,6 +82,39 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); Security.insertProviderAt(provider, 1); + + try { + Resource[] resources = new PathMatchingResourcePatternResolver() + .getResources("classpath:keyvault/*"); + if (resources.length > 0) { + try { + KeyStore keystore = KeyStore.getInstance("AzureKeyVault"); + keystore.load(null, null); + + for (Resource resource : resources) { + try (InputStream inputStream = resource.getInputStream()) { + String alias = resource.getFilename(); + if (alias != null) { + alias = alias.substring(0, alias.lastIndexOf('.')); + byte[] bytes = inputStream.readAllBytes(); + try { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate certificate = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(bytes)); + keystore.setCertificateEntry(alias, certificate); + } catch (KeyStoreException | CertificateException e) { + LOGGER.log(WARNING, "Unable to side-load certificate", e); + } + } + } + } + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException e) { + LOGGER.log(WARNING, "Unable to acquire keystore needed for side-loading", e); + } + } + } catch (IOException ioe) { + LOGGER.log(WARNING, "Unable to determine certificates to side-load", ioe); + } } } } From 809cc3466531692f6955d3d89f2bc3fb1892d2bf Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 13 Oct 2020 16:11:51 -0600 Subject: [PATCH 33/92] Add logging for side-loading --- ...eyVaultCertificatesEnvironmentPostProcessor.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index 00a0592db3d1e..07c555f558f04 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -14,6 +14,8 @@ import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Properties; +import java.util.logging.ConsoleHandler; +import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import java.util.logging.Logger; import org.springframework.boot.SpringApplication; @@ -84,6 +86,11 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, Security.insertProviderAt(provider, 1); try { + ConsoleHandler handler = new ConsoleHandler(); + LOGGER.addHandler(handler); + LOGGER.setUseParentHandlers(false); + LOGGER.setLevel(INFO); + Resource[] resources = new PathMatchingResourcePatternResolver() .getResources("classpath:keyvault/*"); if (resources.length > 0) { @@ -95,13 +102,17 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, try (InputStream inputStream = resource.getInputStream()) { String alias = resource.getFilename(); if (alias != null) { - alias = alias.substring(0, alias.lastIndexOf('.')); + if (alias.lastIndexOf('.') != -1) { + alias = alias.substring(0, alias.lastIndexOf('.')); + } byte[] bytes = inputStream.readAllBytes(); try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate certificate = (X509Certificate) cf.generateCertificate( new ByteArrayInputStream(bytes)); keystore.setCertificateEntry(alias, certificate); + LOGGER.log(INFO, "Side loaded certificate: {0} from: {1}", + new Object[] {alias, resource.getFilename()}); } catch (KeyStoreException | CertificateException e) { LOGGER.log(WARNING, "Unable to side-load certificate", e); } From 8078ad456ec578264bbf81a1a6d3f4e80925fb0d Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 13 Oct 2020 16:12:27 -0600 Subject: [PATCH 34/92] Add logging for side-loading --- .../src/main/resources/keyvault/sideload.x509 | Bin 0 -> 892 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/keyvault/sideload.x509 diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/keyvault/sideload.x509 b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/keyvault/sideload.x509 new file mode 100644 index 0000000000000000000000000000000000000000..7c9f48aae658e67dd615b71fcb2bfd1d2a0de14e GIT binary patch literal 892 zcmXqLVy-Y~VoF%R%*4pVBp}7%xclB~he^G29nVMlee5ydW#iOp^Jx3d%gD&h%3z>k zsAQnP#vIDREG(H(nwL_Pnxb2onpjk`2@q*c6QdHc0~lEun41{+84Q{jxtN+585wr^R^;8}ea<<@I<+fqF4zR3f)>H5~;1neBh9suQ{{94NkQ?S+PQMRMgMEx)*o1Zo`p~$9tREqR;QiT&}fl zn@#ex7#j`^Wzp-WE~mXcKd(uOqdYz@GVRX!yvLF%XO$OsP8Gb?YBE1z&NG~4plap{`ZF;2&K7OY)oxN(EQV}A4g@5fq|Z%R+|TA`{ZyeTt7$KylF z&OH~;bn^j_^r&)x!=xE|- zX+aiQ1L-C_aVif|rOYB>Al4xAaPs!X?`^$btlRgsKKr0%xh>@M35YFxEMhF!rBM?S zFdi8hq~@z}X^C(RXA_&aBnW@%6S zvnavBW}V9$sq7C@(}i6P9{-6o`j(XZJMMTa+j&2e!V57gZv1)i)b0?!`|g|lZ2UD2 zbums$Z+`ALVj}Q8*WW_4+IYcTA3adIfIp5>SPegXhNYFMNI literal 0 HcmV?d00001 From 99b94da5cf85ffd29bf5d5cb4d94c976fc9758b0 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 14 Oct 2020 08:54:23 -0600 Subject: [PATCH 35/92] Add README content for side-loading --- .../README.md | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 0ef645e961b8c..b6a1168869a76 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -1,16 +1,5 @@ # Azure Key Vault Certificates Spring Boot starter -If you want to test the current version under development you will have to - -1. Build and install the [Microsoft Azure JCA Provider](../../keyvault/azure-security-keyvault-jca/README.md) for KeyVault -1. Build and install this starter. - -To build and install the starter use the following command line: - -``` - mvn clean install -DskipTests=true -``` - ## Server side SSL ### Using a managed identity @@ -216,3 +205,30 @@ To grant access use the command line below: --secret-permissions get list \ --certificate-permissions get list ``` + +## Side-loading certificates + +This starter allows you to side-load certificates by supplying them as part of +the application. + +To side-load add your certificates to the `src/main/resources/keyvault` folder. + +Note the alias (certificate name) is constructed from the filename of the +certificate (minus the extension). So if your filename is `mycert.x509` the +certificate will be added with the alias of `mycert`. + +Be aware that certificates coming from Azure KeyVault take precendence over +side-loaded certificates. + +## Testing the current version under development + +If you want to test the current version under development you will have to + +1. Build and install the [Microsoft Azure JCA Provider](../../keyvault/azure-security-keyvault-jca/README.md) for KeyVault +1. Build and install this starter. + +To build and install the starter use the following command line: + +``` + mvn clean install -DskipTests=true +``` From 653933b8e01ef4265ce57a0939249668d3d17b22 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 14 Oct 2020 08:55:00 -0600 Subject: [PATCH 36/92] Add README content for side-loading --- .../azure-spring-boot-starter-keyvault-certificates/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index b6a1168869a76..9f0593b208cae 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -217,7 +217,7 @@ Note the alias (certificate name) is constructed from the filename of the certificate (minus the extension). So if your filename is `mycert.x509` the certificate will be added with the alias of `mycert`. -Be aware that certificates coming from Azure KeyVault take precendence over +Be aware that certificates coming from Azure KeyVault take precedence over side-loaded certificates. ## Testing the current version under development From d7f1606d509ea93217fd9251f1d8eaf06fef5991 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 14 Oct 2020 09:02:17 -0600 Subject: [PATCH 37/92] Add statement what to do when Spring Cloud Config server is in the mix --- .../README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 9f0593b208cae..d33b0ab0cd8c1 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -5,7 +5,8 @@ ### Using a managed identity To use the starter for server side SSL you will need to add the following to -your application.properties +your application.properties (if the application is using Spring Cloud Config +Server for its configuration add it to the bootstrap.yml of the application) ``` azure.keyvault.uri= @@ -28,7 +29,8 @@ Add then add the following Maven dependency to your POM file. ### Using a client ID and client secret To use the starter for server side SSL you will need to add the following to -your application.properties +your application.properties (if the application is using Spring Cloud Config +Server for its configuration add it to the bootstrap.yml of the application) ``` azure.keyvault.uri= @@ -56,7 +58,8 @@ Add then add the following Maven dependency to your POM file. ### Using a managed identity To use the starter for client side SSL you will need to add the following to -your application.properties +your application.properties (if the application is using Spring Cloud Config +Server for its configuration add it to the bootstrap.yml of the application) ``` azure.keyvault.uri= @@ -101,7 +104,8 @@ And if you are using RestTemplate use code similar to the example below. ### Using a client ID and client secret To use the starter for client side SSL you will need to add the following to -your application.properties +your application.properties (if the application is using Spring Cloud Config +Server for its configuration add it to the bootstrap.yml of the application) ``` azure.keyvault.uri= From fff173c1817341086e9296f32984cc1e4e339340 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 14 Oct 2020 09:47:22 -0600 Subject: [PATCH 38/92] Add logging of KeyVault URI --- .../security/keyvault/jca/KeyVaultClient.java | 1 + .../jca/KeyVaultKeyManagerFactory.java | 1 - .../keyvault/jca/KeyVaultKeyStore.java | 91 +++++++++++++++++++ ...tCertificatesEnvironmentPostProcessor.java | 56 ------------ 4 files changed, 92 insertions(+), 57 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java index cda34b9b25e3b..ee0a1689f29a8 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java @@ -71,6 +71,7 @@ class KeyVaultClient extends DelegateRestClient { */ public KeyVaultClient(String keyVaultUri) { super(RestClientFactory.createClient()); + LOGGER.log(INFO, "Using KeyVault: {0}", keyVaultUri); if (!keyVaultUri.endsWith("/")) { keyVaultUri = keyVaultUri + "/"; } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java index dd0692b78e919..b455d9b6b3c55 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java @@ -9,7 +9,6 @@ import java.security.UnrecoverableKeyException; import java.util.ArrayList; import java.util.List; -import static java.util.logging.Level.INFO; import java.util.logging.Logger; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactorySpi; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java index 5147a11e2b052..de7a89f9d5219 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java @@ -2,8 +2,12 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; import java.security.Key; import java.security.KeyStore; @@ -14,11 +18,17 @@ import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.List; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; +import java.util.logging.Logger; /** * The Azure KeyVault implementation of the KeyStoreSpi. @@ -27,6 +37,11 @@ */ public class KeyVaultKeyStore extends KeyStoreSpi { + /** + * Stores the logger. + */ + private static final Logger LOGGER = Logger.getLogger(KeyVaultKeyStore.class.getName()); + /** * Stores the list of aliases. */ @@ -186,10 +201,12 @@ public void engineLoad(KeyStore.LoadStoreParameter param) throws IOException, No parameter.getClientId(), parameter.getClientSecret()); } + sideLoad(); } @Override public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { + sideLoad(); } @Override @@ -228,4 +245,78 @@ public void engineStore(OutputStream stream, char[] password) throws IOException @Override public void engineStore(KeyStore.LoadStoreParameter param) throws IOException, NoSuchAlgorithmException, CertificateException { } + + /** + * Get the filenames. + * + * @param path the path. + * @return the filenames. + * @throws IOException when an I/O error occurs. + */ + private String[] getFilenames(String path) throws IOException { + List filenames = new ArrayList<>(); + InputStream in = getClass().getResourceAsStream(path); + if (in != null) { + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + String resource; + while ((resource = br.readLine()) != null) { + filenames.add(resource); + } + } + return filenames.toArray(new String[0]); + } + + /** + * Read all the bytes for a given input stream. + * + * @param inputStream the input stream. + * @return the byte-array. + * @throws IOException when an I/O error occurs. + */ + private byte[] readAllBytes(InputStream inputStream) throws IOException { + ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + while (true) { + int r = inputStream.read(buffer); + if (r == -1) { + break; + } + byteOutput.write(buffer, 0, r); + } + return byteOutput.toByteArray(); + } + + /** + * Side-load certificate from classpath. + */ + private void sideLoad() { + try { + String[] filenames = getFilenames("/keyvault"); + if (filenames.length > 0) { + for (String filename : filenames) { + try (InputStream inputStream = getClass().getResourceAsStream("/keyvault/" + filename)) { + String alias = filename; + if (alias != null) { + if (alias.lastIndexOf('.') != -1) { + alias = alias.substring(0, alias.lastIndexOf('.')); + } + byte[] bytes = readAllBytes(inputStream); + try { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate certificate = (X509Certificate) cf.generateCertificate( + new ByteArrayInputStream(bytes)); + engineSetCertificateEntry(alias, certificate); + LOGGER.log(INFO, "Side loaded certificate: {0} from: {1}", + new Object[]{alias, filename}); + } catch (KeyStoreException | CertificateException e) { + LOGGER.log(WARNING, "Unable to side-load certificate", e); + } + } + } + } + } + } catch (IOException ioe) { + LOGGER.log(WARNING, "Unable to determine certificates to side-load", ioe); + } + } } diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index 07c555f558f04..5a96ef919f25d 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -3,20 +3,8 @@ package com.azure.keyvault.certificates.starter; import com.azure.security.keyvault.jca.KeyVaultJcaProvider; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; import java.security.Security; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; import java.util.Properties; -import java.util.logging.ConsoleHandler; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; import java.util.logging.Logger; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; @@ -26,8 +14,6 @@ import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.env.PropertySource; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; @Order(LOWEST_PRECEDENCE) public class KeyVaultCertificatesEnvironmentPostProcessor implements EnvironmentPostProcessor { @@ -84,48 +70,6 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); Security.insertProviderAt(provider, 1); - - try { - ConsoleHandler handler = new ConsoleHandler(); - LOGGER.addHandler(handler); - LOGGER.setUseParentHandlers(false); - LOGGER.setLevel(INFO); - - Resource[] resources = new PathMatchingResourcePatternResolver() - .getResources("classpath:keyvault/*"); - if (resources.length > 0) { - try { - KeyStore keystore = KeyStore.getInstance("AzureKeyVault"); - keystore.load(null, null); - - for (Resource resource : resources) { - try (InputStream inputStream = resource.getInputStream()) { - String alias = resource.getFilename(); - if (alias != null) { - if (alias.lastIndexOf('.') != -1) { - alias = alias.substring(0, alias.lastIndexOf('.')); - } - byte[] bytes = inputStream.readAllBytes(); - try { - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - X509Certificate certificate = (X509Certificate) cf.generateCertificate( - new ByteArrayInputStream(bytes)); - keystore.setCertificateEntry(alias, certificate); - LOGGER.log(INFO, "Side loaded certificate: {0} from: {1}", - new Object[] {alias, resource.getFilename()}); - } catch (KeyStoreException | CertificateException e) { - LOGGER.log(WARNING, "Unable to side-load certificate", e); - } - } - } - } - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException e) { - LOGGER.log(WARNING, "Unable to acquire keystore needed for side-loading", e); - } - } - } catch (IOException ioe) { - LOGGER.log(WARNING, "Unable to determine certificates to side-load", ioe); - } } } } From bbfdc10a9665cee9814efa222504ad4c4ccadf38 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 14 Oct 2020 11:02:20 -0600 Subject: [PATCH 39/92] Programmatically determine whether or not using Tomcat --- .../src/main/resources/application.properties | 9 ++------ .../README.md | 7 ++++-- ...tCertificatesEnvironmentPostProcessor.java | 22 ++++++++++++++++--- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties index cfe9c9fa7fe0c..0736876521817 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties @@ -10,19 +10,14 @@ server.ssl.key-alias=${SERVER_SSL_KEY_ALIAS} # # The keystore type that enables the use of Azure KeyVault for your server-side -# SSL certificate (note for embedded Tomcat it needs to be DKS, for all others -# it needs to be AzureKeyVault). +# SSL certificate. # -server.ssl.key-store-type=DKS -# server.ssl.key-store-type=AzureKeyVault +server.ssl.key-store-type=AzureKeyVault # # The truststore type that enables the use of Azure KeyVault for trusted # certificates, a.k.a the ones you trust when making an outbound SSL connection -# (note for embedded Tomcat it needs to be DKS, for all others it needs to be -# AzureKeyVault). # -# server.ssl.key-store-type=DKS # server.ssl.trust-store-type=AzureKeyVault # diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index d33b0ab0cd8c1..8401cc4601b33 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -11,7 +11,7 @@ Server for its configuration add it to the bootstrap.yml of the application) ``` azure.keyvault.uri= server.ssl.key-alias= -server.ssl.key-store-type= +server.ssl.key-store-type=AzureKeyVault ``` Note make sure the managed identity has access to the Azure KeyVault to access @@ -38,7 +38,7 @@ azure.keyvault.tenantId= azure.keyvault.clientId= azure.keyvault.clientSecret= server.ssl.key-alias= -server.ssl.key-store-type= +server.ssl.key-store-type=AzureKeyVault ``` Note make sure the client ID has access to the Azure KeyVault to access @@ -167,6 +167,9 @@ spring: useInsecureTrustManager: true ``` +We are in the process of supplying support for Azure KeyVault integration with +Spring Cloud gateway. + ## Creating an Azure Key Vault To create an Azure KeyVault use the command line below: diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index 5a96ef919f25d..f7739f9040b0e 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -5,6 +5,7 @@ import com.azure.security.keyvault.jca.KeyVaultJcaProvider; import java.security.Security; import java.util.Properties; +import java.util.logging.Level; import java.util.logging.Logger; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; @@ -22,7 +23,7 @@ public class KeyVaultCertificatesEnvironmentPostProcessor implements Environment * Stores the logger. */ private static final Logger LOGGER = Logger.getLogger(KeyVaultCertificatesEnvironmentPostProcessor.class.getName()); - + @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { @@ -50,20 +51,35 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, String keyStoreType = environment.getProperty("server.ssl.key-store-type"); - if (keyStoreType != null && (keyStoreType.equals("DKS") || keyStoreType.equals("AzureKeyVault"))) { + if (keyStoreType != null && keyStoreType.equals("AzureKeyVault")) { MutablePropertySources sources = environment.getPropertySources(); Properties properties = new Properties(); properties.put("server.ssl.key-store", "classpath:keyvault.dummy"); + + try { + Class.forName("org.apache.tomcat.InstanceManager"); + properties.put("server.ssl.key-store-type", "DKS"); + } catch (ClassNotFoundException ex) { + } + PropertySource propertySource = new PropertiesPropertySource("KeyStorePropertySource", properties); sources.addFirst(propertySource); + } String trustStoreType = environment.getProperty("server.ssl.trust-store-type"); - if (trustStoreType != null && (trustStoreType.equals("DKS") || trustStoreType.equals("AzureKeyVault"))) { + if (trustStoreType != null && trustStoreType.equals("AzureKeyVault")) { MutablePropertySources sources = environment.getPropertySources(); Properties properties = new Properties(); properties.put("server.ssl.trust-store", "classpath:keyvault.dummy"); + + try { + Class.forName("org.apache.tomcat.InstanceManager"); + properties.put("server.ssl.trust-store-type", "DKS"); + } catch (ClassNotFoundException ex) { + } + PropertySource propertySource = new PropertiesPropertySource("TrustStorePropertySource", properties); sources.addFirst(propertySource); } From f8ee1b0c5e015e3267d162f199dfbb8ba8c8d7ef Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 15 Oct 2020 10:29:24 -0600 Subject: [PATCH 40/92] Added KeyVault TrustManagerFactory --- .../keyvault/jca/KeyVaultKeyStore.java | 12 +- .../keyvault/jca/KeyVaultTrustManager.java | 131 ++++++++++++++++++ .../jca/KeyVaultTrustManagerFactory.java | 47 +++++++ .../KeyVaultTrustManagerFactoryProvider.java | 55 ++++++++ .../README.md | 16 ++- ...tCertificatesEnvironmentPostProcessor.java | 9 +- 6 files changed, 262 insertions(+), 8 deletions(-) create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java create mode 100644 sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java index de7a89f9d5219..e0013b0d7ac11 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java @@ -129,10 +129,14 @@ public Certificate engineGetCertificate(String alias) { @Override public String engineGetCertificateAlias(Certificate cert) { String alias = null; - if (certificates.containsValue(cert)) { - for (String candidate : certificates.keySet()) { - if (certificates.get(candidate).equals(cert)) { - alias = candidate; + if (cert != null) { + if (aliases == null) { + aliases = keyVault.getAliases(); + } + for (String candidateAlias : aliases) { + Certificate certificate = engineGetCertificate(candidateAlias); + if (certificate.equals(cert)) { + alias = candidateAlias; break; } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java new file mode 100644 index 0000000000000..021ff4d951157 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java @@ -0,0 +1,131 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import javax.net.ssl.X509TrustManager; +import javax.net.ssl.TrustManagerFactory; + +/** + * The KeyVault variant of the X509TrustManager. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultTrustManager implements X509TrustManager { + + /** + * Stores the default trust manager. + */ + private X509TrustManager defaultTrustManager; + + /** + * Stores the keystore. + */ + private KeyStore keyStore; + + /** + * Constructor. + * + * @param keyStore the keystore. + */ + public KeyVaultTrustManager(KeyStore keyStore) { + this.keyStore = keyStore; + if (this.keyStore == null) { + try { + this.keyStore = KeyStore.getInstance("AzureKeyVault"); + this.keyStore.load(null, null); + } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException ex) { + ex.printStackTrace(); + } + } + try { + TrustManagerFactory factory = TrustManagerFactory.getInstance("PKIX", "SunJSSE"); + factory.init(keyStore); + defaultTrustManager = (X509TrustManager) factory.getTrustManagers()[0]; + } catch (NoSuchAlgorithmException | NoSuchProviderException | KeyStoreException ex) { + ex.printStackTrace(); + } + if (defaultTrustManager == null) { + try { + TrustManagerFactory factory = TrustManagerFactory.getInstance("PKIX", "IbmJSSE"); + factory.init(keyStore); + defaultTrustManager = (X509TrustManager) factory.getTrustManagers()[0]; + } catch (NoSuchAlgorithmException | NoSuchProviderException | KeyStoreException ex) { + ex.printStackTrace(); + } + } + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + + boolean pass = true; + + /* + * Step 1 - see if the default trust manager passes. + */ + try { + defaultTrustManager.checkClientTrusted(chain, authType); + } catch (CertificateException ce) { + pass = false; + } + + /* + * Step 2 - see if the certificate exists in the keystore. + */ + if (!pass) { + String alias = null; + try { + alias = keyStore.getCertificateAlias(chain[0]); + } catch (KeyStoreException kse) { + kse.printStackTrace(); + } + if (alias == null) { + throw new CertificateException("Unable to verify in keystore"); + } + } + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + + boolean pass = true; + + /* + * Step 1 - see if the default trust manager passes. + */ + try { + defaultTrustManager.checkServerTrusted(chain, authType); + } catch (CertificateException ce) { + pass = false; + } + + /* + * Step 2 - see if the certificate exists in the keystore. + */ + if (!pass) { + String alias = null; + try { + alias = keyStore.getCertificateAlias(chain[0]); + } catch (KeyStoreException kse) { + kse.printStackTrace(); + } + if (alias == null) { + throw new CertificateException("Unable to verify in keystore"); + } + } + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java new file mode 100644 index 0000000000000..7db14dc54625a --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; +import javax.net.ssl.ManagerFactoryParameters; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactorySpi; + +/** + * The KeyVault variant of the TrustManagerFactory. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultTrustManagerFactory extends TrustManagerFactorySpi { + + /** + * Stores the logger. + */ + private static final Logger LOGGER = Logger.getLogger(KeyVaultTrustManagerFactory.class.getName()); + + /** + * Stores the key managers. + */ + private List trustManagers = new ArrayList<>(); + + @Override + protected void engineInit(KeyStore keystore) throws KeyStoreException { + LOGGER.entering("KeyVaultKeyManagerFactory", "engineInit", keystore); + trustManagers.add(new KeyVaultTrustManager(keystore)); + } + + @Override + protected void engineInit(ManagerFactoryParameters spec) throws InvalidAlgorithmParameterException { + LOGGER.entering("KeyVaultKeyManagerFactory", "engineInit", spec); + } + + @Override + protected TrustManager[] engineGetTrustManagers() { + return trustManagers.toArray(new TrustManager[0]); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java new file mode 100644 index 0000000000000..56a42efcba39c --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.security.keyvault.jca; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.Provider; + +/** + * The Azure KeyVault TrustManagerFactory provider. + * + * @author Manfred Riem (manfred.riem@microsoft.com) + */ +public class KeyVaultTrustManagerFactoryProvider extends Provider { + + /** + * Stores the serial version UID. + */ + private static final long serialVersionUID = 1L; + + /** + * Stores the information. + */ + private static final String INFO = "Azure KeyVault TrustManagerFactory Provider"; + + /** + * Stores the name. + */ + private static final String NAME = "AzureKeyVaultTrustManagerFactory"; + + /** + * Stores the version. + */ + private static final Double VERSION = 1.0; + + /** + * Constructor. + */ + public KeyVaultTrustManagerFactoryProvider() { + super(NAME, VERSION, INFO); + initialize(); + } + + /** + * Initialize the provider. + */ + private void initialize() { + AccessController.doPrivileged((PrivilegedAction) () -> { + putService(new Provider.Service(this, "TrustManagerFactory", "PKIX", + KeyVaultTrustManagerFactory.class.getName(), + null, null)); + return null; + }); + } +} diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 8401cc4601b33..659e421339f82 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -158,6 +158,19 @@ point: To configure Spring Cloud Gateway for outbound SSL you will need to add the following configuration: +```yaml +azure: + keyvault: + overrideTrustManagerFactory: true +``` + +Note if your routes point to services with self-signed certificates where the +hostname does not match the certificate you cannot use the solution above. If +you own the self-signed certificate re-issue it with the proper hostname. If you +do not own the self-signed certificate either have the owner to re-issue the +certificate, or apply the configuration below (note the configuration below +blindly trusts any certificate so it is NOT recommended for production use). + ```yaml spring: cloud: @@ -167,9 +180,6 @@ spring: useInsecureTrustManager: true ``` -We are in the process of supplying support for Azure KeyVault integration with -Spring Cloud gateway. - ## Creating an Azure Key Vault To create an Azure KeyVault use the command line below: diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index f7739f9040b0e..171e22fc8450b 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -3,9 +3,9 @@ package com.azure.keyvault.certificates.starter; import com.azure.security.keyvault.jca.KeyVaultJcaProvider; +import com.azure.security.keyvault.jca.KeyVaultTrustManagerFactoryProvider; import java.security.Security; import java.util.Properties; -import java.util.logging.Level; import java.util.logging.Logger; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; @@ -86,6 +86,13 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); Security.insertProviderAt(provider, 1); + + String enabled = environment.getProperty("azure.keyvault.overrideTrustManagerFactory"); + if (Boolean.valueOf(enabled)) { + KeyVaultTrustManagerFactoryProvider factoryProvider = + new KeyVaultTrustManagerFactoryProvider(); + Security.insertProviderAt(factoryProvider, 1); + } } } } From ebccc65463839ce622cb27b6b88692469c1d6ccc Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 15 Oct 2020 10:30:08 -0600 Subject: [PATCH 41/92] Added KeyVault TrustManagerFactory --- .../azure-spring-boot-starter-keyvault-certificates/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 659e421339f82..fbb85c09542ac 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -167,7 +167,7 @@ azure: Note if your routes point to services with self-signed certificates where the hostname does not match the certificate you cannot use the solution above. If you own the self-signed certificate re-issue it with the proper hostname. If you -do not own the self-signed certificate either have the owner to re-issue the +do not own the self-signed certificate either have the owner re-issue the certificate, or apply the configuration below (note the configuration below blindly trusts any certificate so it is NOT recommended for production use). From 4391b3ec64410ccddd74779dfc81d05d38b4fac5 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 16 Oct 2020 08:04:29 -0600 Subject: [PATCH 42/92] Updated groupId --- .../azure-spring-boot-sample-keyvault-certificates/pom.xml | 4 ++-- .../azure-spring-boot-starter-keyvault-certificates/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml index 662613a99abe4..fb2efb51a9825 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml @@ -10,7 +10,7 @@ - com.azure + com.azure.spring azure-spring-boot-sample-keyvault-certificates 1.0.0 jar @@ -80,7 +80,7 @@ - com.microsoft.azure + com.azure.spring azure-keyvault-certificates-spring-boot-starter 2.4.0-beta.1 diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index ff8710755baae..d2cbe28e4793b 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -11,7 +11,7 @@ ../../parents/azure-client-sdk-parent --> - com.microsoft.azure + com.azure.spring azure-keyvault-certificates-spring-boot-starter 2.4.0-beta.1 From afb7883fc4361dacd9645e215e73f6307c38af99 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 16 Oct 2020 08:12:05 -0600 Subject: [PATCH 43/92] Updated artificatId --- .../pom.xml | 2 +- .../README.md | 16 ++++++++-------- .../pom.xml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml index fb2efb51a9825..ecdae1a2e7fbb 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml @@ -81,7 +81,7 @@ com.azure.spring - azure-keyvault-certificates-spring-boot-starter + azure-spring-boot-starter-keyvault-certificates 2.4.0-beta.1 diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index fbb85c09542ac..605d94cfeb419 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -21,8 +21,8 @@ Add then add the following Maven dependency to your POM file. ```xml - com.microsoft.azure - azure-keyvault-certificates-spring-boot-starter + com.azure.spring + azure-spring-boot-starter-keyvault-certificates ``` @@ -48,8 +48,8 @@ Add then add the following Maven dependency to your POM file. ```xml - com.microsoft.azure - azure-keyvault-certificates-spring-boot-starter + com.azure.spring + azure-spring-boot-starter-keyvault-certificates ``` @@ -71,8 +71,8 @@ Add then add the following Maven dependency to your POM file. ```xml - com.microsoft.azure - azure-keyvault-certificates-spring-boot-starter + com.azure.spring + azure-spring-boot-starter-keyvault-certificates ``` @@ -121,8 +121,8 @@ Add then add the following Maven dependency to your POM file. ```xml - com.microsoft.azure - azure-keyvault-certificates-spring-boot-starter + com.azure.spring + azure-spring-boot-starter-keyvault-certificates ``` diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index d2cbe28e4793b..a9648b19d8a27 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -12,7 +12,7 @@ --> com.azure.spring - azure-keyvault-certificates-spring-boot-starter + azure-spring-boot-starter-keyvault-certificates 2.4.0-beta.1 Azure Key Vault Certificates Spring Boot Starter From a96ae4dbbbc3066d8c96ea8f2e3fd403f684db55 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 16 Oct 2020 08:59:16 -0600 Subject: [PATCH 44/92] Updated package names --- .../keyvault/certificates/sample/SampleApplication.java | 2 +- .../keyvault/certificates/sample/SampleController.java | 2 +- .../starter/KeyVaultCertificatesEnvironmentPostProcessor.java | 2 +- .../src/main/resources/META-INF/spring.factories | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/{ => spring/security}/keyvault/certificates/sample/SampleApplication.java (85%) rename sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/{ => spring/security}/keyvault/certificates/sample/SampleController.java (84%) rename sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/{ => spring/security}/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java (98%) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleApplication.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleApplication.java similarity index 85% rename from sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleApplication.java rename to sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleApplication.java index 2c48356bbea15..9affcf1e69155 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleApplication.java +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleApplication.java @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -package com.azure.keyvault.certificates.sample; +package com.azure.spring.security.keyvault.certificates.sample; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleController.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleController.java similarity index 84% rename from sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleController.java rename to sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleController.java index 9af77488f4d58..be05dd5644af7 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/sample/SampleController.java +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleController.java @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -package com.azure.keyvault.certificates.sample; +package com.azure.spring.security.keyvault.certificates.sample; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java similarity index 98% rename from sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java rename to sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index 171e22fc8450b..a12fb1d122aa3 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -package com.azure.keyvault.certificates.starter; +package com.azure.spring.security.keyvault.certificates.starter; import com.azure.security.keyvault.jca.KeyVaultJcaProvider; import com.azure.security.keyvault.jca.KeyVaultTrustManagerFactoryProvider; diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/META-INF/spring.factories b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/META-INF/spring.factories index d48e60ced4b01..001c6d9372582 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/META-INF/spring.factories +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/resources/META-INF/spring.factories @@ -1,2 +1,2 @@ -org.springframework.boot.env.EnvironmentPostProcessor=com.azure.keyvault.certificates.starter.KeyVaultCertificatesEnvironmentPostProcessor +org.springframework.boot.env.EnvironmentPostProcessor=com.azure.spring.security.keyvault.certificates.starter.KeyVaultCertificatesEnvironmentPostProcessor From abbf13d267850b92ec9ac55b5deb780c86bc8ccf Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 16 Oct 2020 09:01:58 -0600 Subject: [PATCH 45/92] Add KeyVault URI to Spring Cloud Gateway snippet --- .../azure-spring-boot-starter-keyvault-certificates/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 605d94cfeb419..90233cf318e6e 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -161,6 +161,7 @@ to add the following configuration: ```yaml azure: keyvault: + uri: overrideTrustManagerFactory: true ``` From 73f25b2f5a45cc00b6173540e153fa6489c5e524 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 16 Oct 2020 09:36:14 -0600 Subject: [PATCH 46/92] Allow for disabling hostname verification --- .../README.md | 21 +++++++++++++------ ...tCertificatesEnvironmentPostProcessor.java | 8 +++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 90233cf318e6e..3f08de1c4eb26 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -165,12 +165,21 @@ azure: overrideTrustManagerFactory: true ``` -Note if your routes point to services with self-signed certificates where the -hostname does not match the certificate you cannot use the solution above. If -you own the self-signed certificate re-issue it with the proper hostname. If you -do not own the self-signed certificate either have the owner re-issue the -certificate, or apply the configuration below (note the configuration below -blindly trusts any certificate so it is NOT recommended for production use). +Note if any of your routes point to a service where the FQDN does not match the +issued certificate you will need to disable hostname verification. This will +be the case if your service is dynamically assigned a hostname by the hosting +platform you use. In this particular case add the configuration below to disable +hostname verification: + +```yaml +azure: + keyvault: + disableHostnameVerification: true +``` + +If you are developing you can completely disable certificate and hostname +validation altogether by using the configuration below. Note this is NOT +recommended for production! ```yaml spring: diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index a12fb1d122aa3..fbad706664edb 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -7,6 +7,7 @@ import java.security.Security; import java.util.Properties; import java.util.logging.Logger; +import javax.net.ssl.HttpsURLConnection; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import static org.springframework.core.Ordered.LOWEST_PRECEDENCE; @@ -93,6 +94,13 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, new KeyVaultTrustManagerFactoryProvider(); Security.insertProviderAt(factoryProvider, 1); } + + enabled = environment.getProperty("azure.keyvault.disableHostnameVerification"); + if (Boolean.valueOf(enabled)) { + HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> { + return true; + }); + } } } } From 4d9d1eeab3406126bafbcc78506968a4690b2b94 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 16 Oct 2020 12:36:00 -0600 Subject: [PATCH 47/92] Change properties to include JCA 'namespace' in it --- .../README.md | 6 ++++-- .../KeyVaultCertificatesEnvironmentPostProcessor.java | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 3f08de1c4eb26..00f85f21c0ad5 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -162,7 +162,8 @@ to add the following configuration: azure: keyvault: uri: - overrideTrustManagerFactory: true + jca: + overrideTrustManagerFactory: true ``` Note if any of your routes point to a service where the FQDN does not match the @@ -174,7 +175,8 @@ hostname verification: ```yaml azure: keyvault: - disableHostnameVerification: true + jca: + disableHostnameVerification: true ``` If you are developing you can completely disable certificate and hostname diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index fbad706664edb..2626fae9bd415 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -88,14 +88,14 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); Security.insertProviderAt(provider, 1); - String enabled = environment.getProperty("azure.keyvault.overrideTrustManagerFactory"); + String enabled = environment.getProperty("azure.keyvault.jca.overrideTrustManagerFactory"); if (Boolean.valueOf(enabled)) { KeyVaultTrustManagerFactoryProvider factoryProvider = new KeyVaultTrustManagerFactoryProvider(); Security.insertProviderAt(factoryProvider, 1); } - enabled = environment.getProperty("azure.keyvault.disableHostnameVerification"); + enabled = environment.getProperty("azure.keyvault.jca.disableHostnameVerification"); if (Boolean.valueOf(enabled)) { HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> { return true; From 0da1ecc9862afa4706d2549d6976d3a27a916827 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 16 Oct 2020 16:13:52 -0600 Subject: [PATCH 48/92] Add core principles --- sdk/keyvault/azure-security-keyvault-jca/README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index 3960c88ffe84a..98b55fbc52882 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -1,4 +1,14 @@ -# Microsoft Azure JCA Provider for KeyVault +# Azure JCA Provider for KeyVault + +The Azure JCA Provider for KeyVault is a JCA provider for certificates in +Azure Key Vault. It is build on four core principles: + +1. Must be extremely thin to run within a JVM +1. Must not introduce any library version conflicts with Java app code dependencies +1. Must not introduce any class loader hierarchy conflicts with Java app code dependencies +1. Must be ready for "never trust, always verify", Zero Trust environments. + +## Testing the version under development If you want to test the current version under development you will have to build and install it into your local Maven repository. To do so use the From 414a7fbd0939e0efadbf2a12814784c10f1b44b3 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 16 Oct 2020 16:17:39 -0600 Subject: [PATCH 49/92] Add core principles --- sdk/keyvault/azure-security-keyvault-jca/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index 98b55fbc52882..09126db4eda83 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -6,7 +6,7 @@ Azure Key Vault. It is build on four core principles: 1. Must be extremely thin to run within a JVM 1. Must not introduce any library version conflicts with Java app code dependencies 1. Must not introduce any class loader hierarchy conflicts with Java app code dependencies -1. Must be ready for "never trust, always verify", Zero Trust environments. +1. Must be ready for "never trust, always verify and credential-free" Zero Trust environments. ## Testing the version under development From 221f65589ca731572e20d82b8a28bbace277dfb4 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 16 Oct 2020 16:19:49 -0600 Subject: [PATCH 50/92] Add core principles --- sdk/keyvault/azure-security-keyvault-jca/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index 09126db4eda83..b55ed344ba8d2 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -1,7 +1,7 @@ # Azure JCA Provider for KeyVault The Azure JCA Provider for KeyVault is a JCA provider for certificates in -Azure Key Vault. It is build on four core principles: +Azure Key Vault. It is built on four core principles: 1. Must be extremely thin to run within a JVM 1. Must not introduce any library version conflicts with Java app code dependencies From 70bab18e1cb98e7b7fba897738c66b7b8d876316 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Fri, 16 Oct 2020 16:22:35 -0600 Subject: [PATCH 51/92] Minor renaming of project to reflect it is a JCA provider for Azure Key Vault --- sdk/keyvault/azure-security-keyvault-jca/README.md | 4 ++-- sdk/keyvault/azure-security-keyvault-jca/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index b55ed344ba8d2..37ca69fb35186 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -1,6 +1,6 @@ -# Azure JCA Provider for KeyVault +# JCA Provider for Azure Key Vault -The Azure JCA Provider for KeyVault is a JCA provider for certificates in +The JCA Provider for Azure Key Vault is a JCA provider for certificates in Azure Key Vault. It is built on four core principles: 1. Must be extremely thin to run within a JVM diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index 6a1a29b536b4f..1bf2408688fa1 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -7,7 +7,7 @@ com.azure azure-security-keyvault-jca 1.0.0 - Microsoft Azure JCA Provider for KeyVault + JCA Provider for Azure Key Vault The Java Crypto Architecture (JCA) Provider for Azure KeyVault From 026d3860ae20ddd1e11008994958f9eee1c4ca67 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 10:42:41 +0800 Subject: [PATCH 52/92] No logic change, just format xml file. --- .../pom.xml | 197 +++++++++--------- 1 file changed, 99 insertions(+), 98 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml index ecdae1a2e7fbb..467ea58580c97 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml @@ -1,110 +1,111 @@ - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.3.4.RELEASE - - - + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.3.4.RELEASE + + + - com.azure.spring - azure-spring-boot-sample-keyvault-certificates - 1.0.0 - jar + com.azure.spring + azure-spring-boot-sample-keyvault-certificates + 1.0.0 + jar - Azure Spring Boot Starter Sample - Key Vault Certificates - Sample project for Azure Key Vault Certificates Starter - https://github.com/Azure/azure-sdk-for-java + Azure Spring Boot Starter Sample - Key Vault Certificates + Sample project for Azure Key Vault Certificates Starter + https://github.com/Azure/azure-sdk-for-java + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + - - org.springframework.boot - spring-boot-starter-web - - - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.vintage - junit-vintage-engine - - - - - com.azure.spring - azure-spring-boot-starter-keyvault-certificates - 2.4.0-beta.1 + spring-boot-starter-jetty + + --> + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + com.azure.spring + azure-spring-boot-starter-keyvault-certificates + 2.4.0-beta.1 + + + org.springframework.boot + spring-boot-starter-actuator + + + + app + + + org.springframework.boot + spring-boot-maven-plugin + + + ${azure.keyvault.uri} + ${azure.tenant.id} + ${azure.client.id} + ${azure.client.secret} + ${server.ssl.key-alias} + + + + + From 92fec34e2939b7cc91535926abaafde1cd007678 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 10:49:20 +0800 Subject: [PATCH 53/92] Fix error reported by pom_file_version_scanner.ps1. --- eng/versioning/version_client.txt | 1 + .../azure-spring-boot-sample-keyvault-certificates/pom.xml | 4 ++-- .../azure-spring-boot-starter-keyvault-certificates/pom.xml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/eng/versioning/version_client.txt b/eng/versioning/version_client.txt index bb0a978659bdc..07959c08a745f 100644 --- a/eng/versioning/version_client.txt +++ b/eng/versioning/version_client.txt @@ -101,6 +101,7 @@ com.azure:azure-spring-boot-starter-active-directory;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter-cosmos;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter-data-gremlin;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter-keyvault-secrets;3.0.0-beta.1;3.0.0-beta.1 +com.azure.spring:azure-spring-boot-starter-keyvault-certificates;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter-metrics;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter-servicebus-jms;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter;3.0.0-beta.1;3.0.0-beta.1 diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml index 467ea58580c97..7937464ffb28f 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.4.RELEASE + 2.3.3.RELEASE @@ -83,7 +83,7 @@ com.azure.spring azure-spring-boot-starter-keyvault-certificates - 2.4.0-beta.1 + 3.0.0-beta.1 org.springframework.boot diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index a9648b19d8a27..7c1f37f984d12 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -13,7 +13,7 @@ --> com.azure.spring azure-spring-boot-starter-keyvault-certificates - 2.4.0-beta.1 + 3.0.0-beta.1 Azure Key Vault Certificates Spring Boot Starter Spring Boot Starter supporting Azure Key Vault Certificates From 309bb8e0c16bae9f5af710dd1b61ee36fc817216 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 10:54:51 +0800 Subject: [PATCH 54/92] Format file in sdk/spring/azure-spring-boot-starter-keyvault-certificates. --- .../pom.xml | 345 +++++++++--------- ...tCertificatesEnvironmentPostProcessor.java | 13 +- 2 files changed, 181 insertions(+), 177 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index 7c1f37f984d12..aa08a980e9d2d 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -2,178 +2,179 @@ - 4.0.0 - - com.azure.spring - azure-spring-boot-starter-keyvault-certificates - 3.0.0-beta.1 + 4.0.0 + + com.azure.spring + azure-spring-boot-starter-keyvault-certificates + 3.0.0-beta.1 - Azure Key Vault Certificates Spring Boot Starter - Spring Boot Starter supporting Azure Key Vault Certificates - https://github.com/Azure/azure-sdk-for-java + Azure Key Vault Certificates Spring Boot Starter + Spring Boot Starter supporting Azure Key Vault Certificates + https://github.com/Azure/azure-sdk-for-java - - - org.springframework.boot - spring-boot-starter - 2.3.3.RELEASE - - - org.springframework.boot - spring-boot-starter-validation - 2.3.3.RELEASE - - - com.azure - azure-security-keyvault-jca - 1.0.0 - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.0.0-M3 - - - - - com.microsoft.azure:azure-spring-boot:[2.4.0-beta.1] - com.azure:azure-security-keyvault-secrets:[1.0.0] - org.springframework.boot:spring-boot-starter:[2.3.3.RELEASE] - org.springframework.boot:spring-boot-starter-validation:[2.3.3.RELEASE] - - - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.1.1 - - - attach-javadocs - - jar - - - true - - - - - - org.apache.maven.plugins - maven-jar-plugin - 3.1.2 - - - - empty-javadoc-jar-with-readme - package - - jar - - - javadoc - ${project.basedir}/javadocTemp - - - - - - empty-sources-jar-with-readme - package - - jar - - - sources - ${project.basedir}/sourceTemp - - - - - - - org.apache.maven.plugins - maven-antrun-plugin - 1.8 - - - copy-readme-to-javadocTemp - prepare-package - - - Deleting existing ${project.basedir}/javadocTemp - - - - Copying ${project.basedir}/README.md to - ${project.basedir}/javadocTemp/README.md - - - - - - run - - - - copy-readme-to-sourceTemp - prepare-package - - - Deleting existing ${project.basedir}/sourceTemp - - - - Copying ${project.basedir}/README.md to - ${project.basedir}/sourceTemp/README.md - - - - - - run - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.0.1 - - - attach-sources - none - - - - - - - - 1.8 - 1.8 - + + + org.springframework.boot + spring-boot-starter + 2.3.3.RELEASE + + + org.springframework.boot + spring-boot-starter-validation + 2.3.3.RELEASE + + + com.azure + azure-security-keyvault-jca + 1.0.0 + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + + com.microsoft.azure:azure-spring-boot:[2.4.0-beta.1] + com.azure:azure-security-keyvault-secrets:[1.0.0] + org.springframework.boot:spring-boot-starter:[2.3.3.RELEASE] + org.springframework.boot:spring-boot-starter-validation:[2.3.3.RELEASE] + + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.1.1 + + + attach-javadocs + + jar + + + true + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.2 + + + + empty-javadoc-jar-with-readme + package + + jar + + + javadoc + ${project.basedir}/javadocTemp + + + + + + empty-sources-jar-with-readme + package + + jar + + + sources + ${project.basedir}/sourceTemp + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + copy-readme-to-javadocTemp + prepare-package + + + Deleting existing ${project.basedir}/javadocTemp + + + + Copying ${project.basedir}/README.md to + ${project.basedir}/javadocTemp/README.md + + + + + + run + + + + copy-readme-to-sourceTemp + prepare-package + + + Deleting existing ${project.basedir}/sourceTemp + + + + Copying ${project.basedir}/README.md to + ${project.basedir}/sourceTemp/README.md + + + + + + run + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + none + + + + + + + + 1.8 + 1.8 + diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index 2626fae9bd415..d046018749834 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -4,19 +4,22 @@ import com.azure.security.keyvault.jca.KeyVaultJcaProvider; import com.azure.security.keyvault.jca.KeyVaultTrustManagerFactoryProvider; + import java.security.Security; import java.util.Properties; import java.util.logging.Logger; import javax.net.ssl.HttpsURLConnection; + import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; -import static org.springframework.core.Ordered.LOWEST_PRECEDENCE; import org.springframework.core.annotation.Order; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.env.PropertySource; +import static org.springframework.core.Ordered.LOWEST_PRECEDENCE; + @Order(LOWEST_PRECEDENCE) public class KeyVaultCertificatesEnvironmentPostProcessor implements EnvironmentPostProcessor { @@ -27,7 +30,7 @@ public class KeyVaultCertificatesEnvironmentPostProcessor implements Environment @Override public void postProcessEnvironment(ConfigurableEnvironment environment, - SpringApplication application) { + SpringApplication application) { Properties systemProperties = System.getProperties(); @@ -87,14 +90,14 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); Security.insertProviderAt(provider, 1); - + String enabled = environment.getProperty("azure.keyvault.jca.overrideTrustManagerFactory"); if (Boolean.valueOf(enabled)) { KeyVaultTrustManagerFactoryProvider factoryProvider = - new KeyVaultTrustManagerFactoryProvider(); + new KeyVaultTrustManagerFactoryProvider(); Security.insertProviderAt(factoryProvider, 1); } - + enabled = environment.getProperty("azure.keyvault.jca.disableHostnameVerification"); if (Boolean.valueOf(enabled)) { HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> { From 309af4f8590c4af6b226b7ec3f106f9f209e6815 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 10:58:21 +0800 Subject: [PATCH 55/92] Format files in sdk/keyvault/azure-security-keyvault-jca. --- .../azure-security-keyvault-jca/pom.xml | 352 +++++++++--------- .../security/keyvault/jca/AuthClient.java | 30 +- .../keyvault/jca/DelegateRestClient.java | 14 +- .../keyvault/jca/JacksonJsonConverter.java | 9 +- .../security/keyvault/jca/JsonConverter.java | 10 +- .../keyvault/jca/JsonConverterFactory.java | 6 +- .../keyvault/jca/KeyVaultCertificate.java | 56 +-- .../security/keyvault/jca/KeyVaultClient.java | 54 +-- .../keyvault/jca/KeyVaultJcaProvider.java | 14 +- .../keyvault/jca/KeyVaultKeyManager.java | 25 +- .../jca/KeyVaultKeyManagerFactory.java | 17 +- .../keyvault/jca/KeyVaultKeyStore.java | 27 +- .../jca/KeyVaultLoadStoreParameter.java | 2 +- .../keyvault/jca/KeyVaultTrustManager.java | 8 +- .../jca/KeyVaultTrustManagerFactory.java | 6 +- .../KeyVaultTrustManagerFactoryProvider.java | 4 +- .../keyvault/jca/LegacyRestClient.java | 5 +- .../security/keyvault/jca/RestClient.java | 8 +- .../keyvault/jca/RestClientFactory.java | 6 +- .../keyvault/jca/rest/CertificateBundle.java | 30 +- .../keyvault/jca/rest/CertificateItem.java | 8 +- .../jca/rest/CertificateListResult.java | 8 +- .../keyvault/jca/rest/CertificatePolicy.java | 8 +- .../keyvault/jca/rest/KeyProperties.java | 8 +- .../keyvault/jca/rest/SecretBundle.java | 10 +- .../security/keyvault/jca/AuthClientTest.java | 12 +- .../keyvault/jca/DelegateRestClientTest.java | 7 +- .../jca/JacksonJsonConverterTest.java | 5 +- .../keyvault/jca/KeyVaultCertificateTest.java | 52 +-- .../keyvault/jca/KeyVaultJcaProviderTest.java | 16 +- .../keyvault/jca/KeyVaultKeyStoreTest.java | 118 +++--- .../jca/KeyVaultLoadStoreParameterTest.java | 5 +- .../keyvault/jca/LegacyRestClientTest.java | 5 +- .../keyvault/jca/RestClientFactoryTest.java | 7 +- .../keyvault/jca/ServerSocketTest.java | 129 +++---- 35 files changed, 555 insertions(+), 526 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index 1bf2408688fa1..c4515fc19a460 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -3,182 +3,182 @@ - 4.0.0 - com.azure - azure-security-keyvault-jca - 1.0.0 - JCA Provider for Azure Key Vault - The Java Crypto Architecture (JCA) Provider for Azure KeyVault - + 4.0.0 + com.azure + azure-security-keyvault-jca + 1.0.0 + JCA Provider for Azure Key Vault + The Java Crypto Architecture (JCA) Provider for Azure KeyVault + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-resources-plugin + 3.2.0 + + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + + shade + + + + + com.fasterxml.jackson + com.azure.keyvault.jca.com.fasterxml.jackson + + + org.apache.commons + com.azure.keyvault.jca.org.apache.commons + + + org.apache.hc + com.azure.keyvault.jca.org.apache.hc + + + mozilla + com.azure.keyvault.jca.mozilla + + + org.slf4j + com.azure.keyvault.jca.org.slf4j + + + + + + true + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + true + + + + org.jacoco + jacoco-maven-plugin + 0.8.5 + + + default-prepare-agent + + prepare-agent + + + + default-report + prepare-package + + report + + + + + + + + + + org.apache.httpcomponents.client5 + httpclient5 + 5.0.1 + true + + + + com.fasterxml.jackson.core + jackson-databind + 2.11.2 + true + + + + org.junit.jupiter + junit-jupiter-api + 5.6.0 + test + + + org.junit.jupiter + junit-jupiter-params + 5.6.0 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.0 + test + + + + org.slf4j + slf4j-nop + 1.7.25 + + + + + it + + + + azure.keyvault.uri + + + - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 1.8 - 1.8 - ${project.build.sourceEncoding} - - - - org.apache.maven.plugins - maven-resources-plugin - 3.2.0 - - ${project.build.sourceEncoding} - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.4 - - - - shade - - - - - com.fasterxml.jackson - com.azure.keyvault.jca.com.fasterxml.jackson - - - org.apache.commons - com.azure.keyvault.jca.org.apache.commons - - - org.apache.hc - com.azure.keyvault.jca.org.apache.hc - - - mozilla - com.azure.keyvault.jca.mozilla - - - org.slf4j - com.azure.keyvault.jca.org.slf4j - - - - - - true - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - true - - - - org.jacoco - jacoco-maven-plugin - 0.8.5 - - - default-prepare-agent - - prepare-agent - - - - default-report - prepare-package - - report - - - - + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + false + + ${azure.keyvault.uri} + ${azure.tenant.id} + ${azure.client.id} + ${azure.client.secret} + + + - - - - - org.apache.httpcomponents.client5 - httpclient5 - 5.0.1 - true - - - - com.fasterxml.jackson.core - jackson-databind - 2.11.2 - true - - - - org.junit.jupiter - junit-jupiter-api - 5.6.0 - test - - - org.junit.jupiter - junit-jupiter-params - 5.6.0 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.6.0 - test - - - - org.slf4j - slf4j-nop - 1.7.25 - - - - - it - - - - azure.keyvault.uri - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - false - - ${azure.keyvault.uri} - ${azure.tenant.id} - ${azure.client.id} - ${azure.client.secret} - - - - - - - - - UTF-8 - + + + + + UTF-8 + diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java index 8b08c502e4aa5..91a5f3c1cf1b1 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -3,10 +3,12 @@ package com.azure.security.keyvault.jca; import com.azure.security.keyvault.jca.rest.OAuthToken; + import java.util.HashMap; -import static java.util.logging.Level.FINER; import java.util.logging.Logger; +import static java.util.logging.Level.FINER; + /** * The REST client specific to getting an access token for Azure REST APIs. * @@ -48,13 +50,13 @@ class AuthClient extends DelegateRestClient { * Stores the OAuth2 managed identity URL. */ private static final String OAUTH2_MANAGED_IDENTITY_TOKEN_URL - = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01"; + = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01"; /** * Stores our logger. */ private static final Logger LOGGER = Logger.getLogger(AuthClient.class.getName()); - + /** * Constructor. * @@ -76,7 +78,7 @@ public String getAccessToken(String resource) { String result; if (System.getenv("WEBSITE_SITE_NAME") != null - && !System.getenv("WEBSITE_SITE_NAME").isEmpty()) { + && !System.getenv("WEBSITE_SITE_NAME").isEmpty()) { result = getAccessTokenOnAppService(resource); } else { result = getAccessTokenOnOthers(resource); @@ -94,22 +96,22 @@ public String getAccessToken(String resource) { * @return the authorization token. */ public String getAccessToken(String resource, String tenantId, - String clientId, String clientSecret) { + String clientId, String clientSecret) { LOGGER.entering("AuthClient", "getAccessToken", new Object[] { - resource, tenantId, clientId, clientSecret}); + resource, tenantId, clientId, clientSecret }); LOGGER.info("Getting access token using client ID / client secret"); String result = null; StringBuilder oauth2Url = new StringBuilder(); oauth2Url.append(OAUTH2_TOKEN_BASE_URL) - .append(tenantId) - .append(OAUTH2_TOKEN_POSTFIX); + .append(tenantId) + .append(OAUTH2_TOKEN_POSTFIX); StringBuilder requestBody = new StringBuilder(); requestBody.append(GRANT_TYPE_FRAGMENT) - .append(CLIENT_ID_FRAGMENT).append(clientId) - .append(CLIENT_SECRET_FRAGMENT).append(clientSecret) - .append(RESOURCE_FRAGMENT).append(resource); + .append(CLIENT_ID_FRAGMENT).append(clientId) + .append(CLIENT_SECRET_FRAGMENT).append(clientSecret) + .append(RESOURCE_FRAGMENT).append(resource); String body = post(oauth2Url.toString(), requestBody.toString(), "application/x-www-form-urlencoded"); if (body != null) { @@ -134,8 +136,8 @@ private String getAccessTokenOnAppService(String resource) { StringBuilder url = new StringBuilder(); url.append(System.getenv("MSI_ENDPOINT")) - .append("?api-version=2017-09-01") - .append(RESOURCE_FRAGMENT).append(resource); + .append("?api-version=2017-09-01") + .append(RESOURCE_FRAGMENT).append(resource); HashMap headers = new HashMap<>(); headers.put("Metadata", "true"); @@ -164,7 +166,7 @@ private String getAccessTokenOnOthers(String resource) { StringBuilder url = new StringBuilder(); url.append(OAUTH2_MANAGED_IDENTITY_TOKEN_URL) - .append(RESOURCE_FRAGMENT).append(resource); + .append(RESOURCE_FRAGMENT).append(resource); HashMap headers = new HashMap<>(); headers.put("Metadata", "true"); diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java index fd33d0a54a18f..4a32d92af623d 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java @@ -6,16 +6,16 @@ /** * A RestClient that delegates to another RestClient. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ class DelegateRestClient implements RestClient { - + /** * Stores the delegate. */ private RestClient delegate; - + /** * Constructor. */ @@ -27,10 +27,10 @@ public DelegateRestClient(RestClient delegate) { public String get(String url, Map headers) { return delegate.get(url, headers); } - + /** * Get the delegate. - * + * * @return the delegate. */ public RestClient getDelegate() { @@ -41,10 +41,10 @@ public RestClient getDelegate() { public String post(String url, String body, String contentType) { return delegate.post(url, body, contentType); } - + /** * Set the delegate. - * + * * @param delegate the delegate. */ public void setDelegate(RestClient delegate) { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java index e6da5fc13ed35..7e96e77209c92 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java @@ -5,10 +5,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import static java.util.logging.Level.FINEST; -import static java.util.logging.Level.WARNING; + import java.util.logging.Logger; +import static java.util.logging.Level.WARNING; + /** * The Jackson JsonConverter. * @@ -20,7 +21,7 @@ class JacksonJsonConverter implements JsonConverter { * Stores the logger. */ private static final Logger LOGGER = Logger.getLogger(JacksonJsonConverter.class.getName()); - + /** * From JSON. * @@ -30,7 +31,7 @@ class JacksonJsonConverter implements JsonConverter { */ @Override public Object fromJson(String string, Class resultClass) { - LOGGER.entering("JacksonJsonConverter", "fromJson", new Object[] {string, resultClass}); + LOGGER.entering("JacksonJsonConverter", "fromJson", new Object[] { string, resultClass }); Object result = null; try { ObjectMapper objectMapper = new ObjectMapper(); diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java index 008dd3979e79b..483481a563bba 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java @@ -4,22 +4,22 @@ /** * The JSON converter API. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ interface JsonConverter { - + /** * To JSON. - * + * * @param object the object to transform. * @return the JSON string. */ String toJson(Object object); - + /** * From JSON. - * + * * @param string the JSON string to transform. * @param resultClass the result class. * @return the object, or null if the conversion failed. diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java index 3214bf38cda6b..78dc09275ca80 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java @@ -4,7 +4,7 @@ /** * The JsonConverterFactory. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ class JsonConverterFactory { @@ -14,10 +14,10 @@ class JsonConverterFactory { */ private JsonConverterFactory() { } - + /** * Static helper method to create a JsonConverter. - * + * * @return the JsonConverter. */ static JsonConverter createJsonConverter() { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java index 3238c4b11cbf6..b42101ed7e43a 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java @@ -31,7 +31,7 @@ class KeyVaultCertificate extends X509Certificate { /** * Constructor. - * + * * @param delegate the delegate. */ KeyVaultCertificate(X509Certificate delegate) { @@ -40,7 +40,7 @@ class KeyVaultCertificate extends X509Certificate { } /** - * @see X509Certificate#checkValidity() + * @see X509Certificate#checkValidity() */ @Override public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { @@ -48,7 +48,7 @@ public void checkValidity() throws CertificateExpiredException, CertificateNotYe } /** - * @see X509Certificate#checkValidity(java.util.Date) + * @see X509Certificate#checkValidity(java.util.Date) */ @Override public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException { @@ -56,7 +56,7 @@ public void checkValidity(Date date) throws CertificateExpiredException, Certifi } /** - * @see X509Certificate#getBasicConstraints() + * @see X509Certificate#getBasicConstraints() */ @Override public int getBasicConstraints() { @@ -64,7 +64,7 @@ public int getBasicConstraints() { } /** - * @see X509Certificate#getCriticalExtensionOIDs() + * @see X509Certificate#getCriticalExtensionOIDs() */ @Override public Set getCriticalExtensionOIDs() { @@ -72,7 +72,7 @@ public Set getCriticalExtensionOIDs() { } /** - * @see X509Certificate#getEncoded() + * @see X509Certificate#getEncoded() */ @Override public byte[] getEncoded() throws CertificateEncodingException { @@ -80,7 +80,7 @@ public byte[] getEncoded() throws CertificateEncodingException { } /** - * @see X509Certificate#getExtensionValue(java.lang.String) + * @see X509Certificate#getExtensionValue(java.lang.String) */ @Override public byte[] getExtensionValue(String oid) { @@ -96,7 +96,7 @@ public Principal getIssuerDN() { } /** - * @see X509Certificate#getIssuerUniqueID() + * @see X509Certificate#getIssuerUniqueID() */ @Override public boolean[] getIssuerUniqueID() { @@ -104,7 +104,7 @@ public boolean[] getIssuerUniqueID() { } /** - * @see X509Certificate#getKeyUsage() + * @see X509Certificate#getKeyUsage() */ @Override public boolean[] getKeyUsage() { @@ -112,7 +112,7 @@ public boolean[] getKeyUsage() { } /** - * @see X509Certificate#getNonCriticalExtensionOIDs() + * @see X509Certificate#getNonCriticalExtensionOIDs() */ @Override public Set getNonCriticalExtensionOIDs() { @@ -120,7 +120,7 @@ public Set getNonCriticalExtensionOIDs() { } /** - * @see X509Certificate#getNotAfter() + * @see X509Certificate#getNotAfter() */ @Override public Date getNotAfter() { @@ -128,7 +128,7 @@ public Date getNotAfter() { } /** - * @see X509Certificate#getNotBefore() + * @see X509Certificate#getNotBefore() */ @Override public Date getNotBefore() { @@ -136,7 +136,7 @@ public Date getNotBefore() { } /** - * @see X509Certificate#getPublicKey() + * @see X509Certificate#getPublicKey() */ @Override public PublicKey getPublicKey() { @@ -144,7 +144,7 @@ public PublicKey getPublicKey() { } /** - * @see X509Certificate#getSerialNumber() + * @see X509Certificate#getSerialNumber() */ @Override public BigInteger getSerialNumber() { @@ -160,7 +160,7 @@ public String getSigAlgName() { } /** - * @see X509Certificate#getSigAlgOID() + * @see X509Certificate#getSigAlgOID() */ @Override public String getSigAlgOID() { @@ -168,7 +168,7 @@ public String getSigAlgOID() { } /** - * @see X509Certificate#getSigAlgParams() + * @see X509Certificate#getSigAlgParams() */ @Override public byte[] getSigAlgParams() { @@ -176,7 +176,7 @@ public byte[] getSigAlgParams() { } /** - * @see X509Certificate#getSignature() + * @see X509Certificate#getSignature() */ @Override public byte[] getSignature() { @@ -184,7 +184,7 @@ public byte[] getSignature() { } /** - * @see X509Certificate#getSubjectDN() + * @see X509Certificate#getSubjectDN() */ @Override public Principal getSubjectDN() { @@ -192,7 +192,7 @@ public Principal getSubjectDN() { } /** - * @see X509Certificate#getSubjectUniqueID() + * @see X509Certificate#getSubjectUniqueID() */ @Override public boolean[] getSubjectUniqueID() { @@ -200,7 +200,7 @@ public boolean[] getSubjectUniqueID() { } /** - * @see X509Certificate#getTBSCertificate() + * @see X509Certificate#getTBSCertificate() */ @Override public byte[] getTBSCertificate() throws CertificateEncodingException { @@ -208,7 +208,7 @@ public byte[] getTBSCertificate() throws CertificateEncodingException { } /** - * @see X509Certificate#getVersion() + * @see X509Certificate#getVersion() */ @Override public int getVersion() { @@ -216,7 +216,7 @@ public int getVersion() { } /** - * @see X509Certificate#hasUnsupportedCriticalExtension() + * @see X509Certificate#hasUnsupportedCriticalExtension() */ @Override public boolean hasUnsupportedCriticalExtension() { @@ -224,7 +224,7 @@ public boolean hasUnsupportedCriticalExtension() { } /** - * @see X509Certificate#toString() + * @see X509Certificate#toString() */ @Override public String toString() { @@ -232,18 +232,20 @@ public String toString() { } /** - * @see X509Certificate#verify(java.security.PublicKey) + * @see X509Certificate#verify(java.security.PublicKey) */ @Override - public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { + public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, + NoSuchProviderException, SignatureException { delegate.verify(key); } /** - * @see X509Certificate#verify(java.security.PublicKey, java.security.Provider) + * @see X509Certificate#verify(java.security.PublicKey, java.security.Provider) */ @Override - public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { + public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException, SignatureException { delegate.verify(key, sigProvider); } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java index ee0a1689f29a8..4b77140aef6a4 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java @@ -2,10 +2,11 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; -import com.azure.security.keyvault.jca.rest.CertificateListResult; -import com.azure.security.keyvault.jca.rest.CertificateItem; import com.azure.security.keyvault.jca.rest.CertificateBundle; +import com.azure.security.keyvault.jca.rest.CertificateItem; +import com.azure.security.keyvault.jca.rest.CertificateListResult; import com.azure.security.keyvault.jca.rest.SecretBundle; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -23,9 +24,10 @@ import java.util.Base64; import java.util.HashMap; import java.util.List; +import java.util.logging.Logger; + import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import java.util.logging.Logger; /** * The REST client specific to Azure KeyVault. @@ -33,7 +35,7 @@ * @author Manfred Riem (manfred.riem@microsoft.com) */ class KeyVaultClient extends DelegateRestClient { - + /** * Stores the logger. */ @@ -123,17 +125,17 @@ private String getAccessToken() { */ public List getAliases() { ArrayList result = new ArrayList<>(); - + StringBuilder url = new StringBuilder(); url.append(keyVaultUri) - .append("certificates") - .append(API_VERSION_POSTFIX); - + .append("certificates") + .append(API_VERSION_POSTFIX); + HashMap headers = new HashMap<>(); headers.put("Authorization", "Bearer " + getAccessToken()); - + String body = get(url.toString(), headers); - + CertificateListResult certificateListResult = null; if (body != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); @@ -146,7 +148,7 @@ public List getAliases() { result.add(alias); } } - + return result; } @@ -158,23 +160,23 @@ public List getAliases() { */ private CertificateBundle getCertificateBundle(String alias) { CertificateBundle result = null; - + StringBuilder url = new StringBuilder(); url.append(keyVaultUri) - .append("certificates/") - .append(alias) - .append(API_VERSION_POSTFIX); - + .append("certificates/") + .append(alias) + .append(API_VERSION_POSTFIX); + HashMap headers = new HashMap<>(); headers.put("Authorization", "Bearer " + getAccessToken()); - + String body = get(url.toString(), headers); - + if (body != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); result = (CertificateBundle) converter.fromJson(body, CertificateBundle.class); } - + return result; } @@ -195,8 +197,8 @@ public Certificate getCertificate(String alias) { try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); certificate = (X509Certificate) cf.generateCertificate( - new ByteArrayInputStream(Base64.getDecoder() - .decode(certificateBundle.getCer()))); + new ByteArrayInputStream(Base64.getDecoder() + .decode(certificateBundle.getCer()))); } catch (CertificateException ce) { LOGGER.log(WARNING, "Certificate error", ce); } @@ -214,14 +216,14 @@ public Certificate getCertificate(String alias) { * @return the key. */ public Key getKey(String alias, char[] password) { - LOGGER.entering("KeyVaultClient", "getKey", new Object[] {alias, password}); + LOGGER.entering("KeyVaultClient", "getKey", new Object[] { alias, password }); LOGGER.log(INFO, "Getting key for alias: {0}", alias); Key key = null; CertificateBundle certificateBundle = getCertificateBundle(alias); if (certificateBundle != null - && certificateBundle.getPolicy() != null - && certificateBundle.getPolicy().getKey_props() != null - && certificateBundle.getPolicy().getKey_props().isExportable()) { + && certificateBundle.getPolicy() != null + && certificateBundle.getPolicy().getKey_props() != null + && certificateBundle.getPolicy().getKey_props().isExportable()) { // // Because the certificate is exportable the private key is @@ -239,7 +241,7 @@ public Key getKey(String alias, char[] password) { try { KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(new ByteArrayInputStream( - Base64.getDecoder().decode(secretBundle.getValue())), "".toCharArray()); + Base64.getDecoder().decode(secretBundle.getValue())), "".toCharArray()); alias = keyStore.aliases().nextElement(); key = keyStore.getKey(alias, "".toCharArray()); } catch (IOException | KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException ex) { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java index 8443812066dd5..ad23f3f19d2ad 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java @@ -48,21 +48,21 @@ public KeyVaultJcaProvider() { private void initialize() { AccessController.doPrivileged((PrivilegedAction) () -> { putService(new Provider.Service(this, "KeyManagerFactory", "SunX509", - KeyVaultKeyManagerFactory.class.getName(), - Arrays.asList("SunX509", "IbmX509"), null)); - + KeyVaultKeyManagerFactory.class.getName(), + Arrays.asList("SunX509", "IbmX509"), null)); + /* * Note for Tomcat we needed to add "DKS" as an algorithm so it does - * not use an in-memory key store and later on can wrap the + * not use an in-memory key store and later on can wrap the * KeyManager using its JSSEKeyManager so the key alias is known. * - * See SSLUtilBase.getKeyManagers and look for the + * See SSLUtilBase.getKeyManagers and look for the * "DKS".equalsIgnoreCase(certificate.getCertificateKeystoreType() */ putService(new Provider.Service(this, "KeyStore", "DKS", - KeyVaultKeyStore.class.getName(), Arrays.asList("DKS"), null)); + KeyVaultKeyStore.class.getName(), Arrays.asList("DKS"), null)); putService(new Provider.Service(this, "KeyStore", "AzureKeyVault", - KeyVaultKeyStore.class.getName(), Arrays.asList("AzureKeyVault"), null)); + KeyVaultKeyStore.class.getName(), Arrays.asList("AzureKeyVault"), null)); return null; }); } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java index 02386fde6329a..26075b6555885 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java @@ -2,6 +2,7 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; +import javax.net.ssl.X509ExtendedKeyManager; import java.net.Socket; import java.security.KeyStore; import java.security.KeyStoreException; @@ -14,10 +15,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.logging.Logger; + import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import java.util.logging.Logger; -import javax.net.ssl.X509ExtendedKeyManager; /** * The KeyVault variant of the X509ExtendedKeyManager. @@ -48,15 +49,15 @@ public class KeyVaultKeyManager extends X509ExtendedKeyManager { * @param password the password. */ public KeyVaultKeyManager(KeyStore keystore, char[] password) { - LOGGER.entering("KeyVaultKeyManager", "", new Object[] {keystore, password}); + LOGGER.entering("KeyVaultKeyManager", "", new Object[] { keystore, password }); this.keystore = keystore; this.password = password; } @Override public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { - LOGGER.entering("KeyVaultKeyManager", "chooseClientAlias", - new Object[] {keyType, issuers, socket}); + LOGGER.entering("KeyVaultKeyManager", "chooseClientAlias", + new Object[] { keyType, issuers, socket }); String alias = null; try { /* @@ -64,7 +65,7 @@ public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket so * return that alias as a match. */ if (!keystore.getProvider().getName().equals("AzureKeyVault") - && keystore.size() == 1) { + && keystore.size() == 1) { alias = keystore.aliases().nextElement(); } } catch (KeyStoreException kse) { @@ -76,8 +77,8 @@ public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket so @Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { - LOGGER.entering("KeyVaultKeyManager", "chooseServerAlias", - new Object[] {keyType, issuers, socket}); + LOGGER.entering("KeyVaultKeyManager", "chooseServerAlias", + new Object[] { keyType, issuers, socket }); String alias = null; try { /* @@ -85,7 +86,7 @@ public String chooseServerAlias(String keyType, Principal[] issuers, Socket sock * return that alias as a match. */ if (!keystore.getProvider().getName().equals("AzureKeyVault") - && keystore.size() == 1) { + && keystore.size() == 1) { alias = keystore.aliases().nextElement(); } } catch (KeyStoreException kse) { @@ -97,8 +98,8 @@ public String chooseServerAlias(String keyType, Principal[] issuers, Socket sock @Override public String[] getClientAliases(String keyType, Principal[] issuers) { - LOGGER.log(INFO, "KeyVaultKeyManager.getClientAliases: {0}, {1}", - new Object[] {keyType, issuers}); + LOGGER.log(INFO, "KeyVaultKeyManager.getClientAliases: {0}, {1}", + new Object[] { keyType, issuers }); String[] aliases = null; try { aliases = Collections.list(keystore.aliases()).toArray(new String[0]); @@ -144,7 +145,7 @@ public PrivateKey getPrivateKey(String alias) { @Override public String[] getServerAliases(String keyType, Principal[] issuers) { - LOGGER.entering("KeyVaultKeyManager", "getServerAliases", new Object[] {keyType, issuers}); + LOGGER.entering("KeyVaultKeyManager", "getServerAliases", new Object[] { keyType, issuers }); String[] serverAliases = new String[0]; try { serverAliases = Collections.list(keystore.aliases()).toArray(new String[0]); diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java index b455d9b6b3c55..21b1ccd888ee1 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java @@ -2,6 +2,9 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactorySpi; +import javax.net.ssl.ManagerFactoryParameters; import java.security.InvalidAlgorithmParameterException; import java.security.KeyStore; import java.security.KeyStoreException; @@ -10,9 +13,6 @@ import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactorySpi; -import javax.net.ssl.ManagerFactoryParameters; /** * The KeyVault variant of the KeyManagerFactory. @@ -30,11 +30,12 @@ public class KeyVaultKeyManagerFactory extends KeyManagerFactorySpi { * Stores the key managers. */ private List keyManagers = new ArrayList<>(); - + @Override - protected void engineInit(KeyStore keystore, char[] password) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { - LOGGER.entering("KeyVaultKeyManagerFactory", "engineInit", - new Object[] {keystore, new String(password)}); + protected void engineInit(KeyStore keystore, char[] password) throws KeyStoreException, NoSuchAlgorithmException, + UnrecoverableKeyException { + LOGGER.entering("KeyVaultKeyManagerFactory", "engineInit", + new Object[] { keystore, new String(password) }); KeyVaultKeyManager manager = new KeyVaultKeyManager(keystore, password); keyManagers.add(manager); } @@ -45,7 +46,7 @@ protected void engineInit(ManagerFactoryParameters spec) throws InvalidAlgorithm @Override protected KeyManager[] engineGetKeyManagers() { - LOGGER.exiting("KeyVaultKeyManagerFactory", "engineGetKeyManagers", keyManagers); + LOGGER.exiting("KeyVaultKeyManagerFactory", "engineGetKeyManagers", keyManagers); return keyManagers.toArray(new KeyManager[0]); } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java index e0013b0d7ac11..56df9f1642901 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java @@ -26,9 +26,10 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.List; +import java.util.logging.Logger; + import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import java.util.logging.Logger; /** * The Azure KeyVault implementation of the KeyStoreSpi. @@ -196,20 +197,22 @@ public boolean engineIsKeyEntry(String alias) { } @Override - public void engineLoad(KeyStore.LoadStoreParameter param) throws IOException, NoSuchAlgorithmException, CertificateException { + public void engineLoad(KeyStore.LoadStoreParameter param) throws IOException, NoSuchAlgorithmException, + CertificateException { if (param instanceof KeyVaultLoadStoreParameter) { KeyVaultLoadStoreParameter parameter = (KeyVaultLoadStoreParameter) param; keyVault = new KeyVaultClient( - parameter.getUri(), - parameter.getTenantId(), - parameter.getClientId(), - parameter.getClientSecret()); + parameter.getUri(), + parameter.getTenantId(), + parameter.getClientId(), + parameter.getClientSecret()); } sideLoad(); } @Override - public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { + public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, + CertificateException { sideLoad(); } @@ -243,11 +246,13 @@ public int engineSize() { } @Override - public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { + public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, + CertificateException { } @Override - public void engineStore(KeyStore.LoadStoreParameter param) throws IOException, NoSuchAlgorithmException, CertificateException { + public void engineStore(KeyStore.LoadStoreParameter param) throws IOException, NoSuchAlgorithmException, + CertificateException { } /** @@ -308,10 +313,10 @@ private void sideLoad() { try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate certificate = (X509Certificate) cf.generateCertificate( - new ByteArrayInputStream(bytes)); + new ByteArrayInputStream(bytes)); engineSetCertificateEntry(alias, certificate); LOGGER.log(INFO, "Side loaded certificate: {0} from: {1}", - new Object[]{alias, filename}); + new Object[] { alias, filename }); } catch (KeyStoreException | CertificateException e) { LOGGER.log(WARNING, "Unable to side-load certificate", e); } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java index bedcbb4f9d674..bb35f082b060d 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java @@ -15,7 +15,7 @@ public class KeyVaultLoadStoreParameter implements KeyStore.LoadStoreParameter { * Stores the URI. */ private final String uri; - + /** * Stores the tenant id. */ diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java index 021ff4d951157..0f8e4f610fb4e 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java @@ -2,6 +2,8 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; import java.io.IOException; import java.security.KeyStore; import java.security.KeyStoreException; @@ -9,8 +11,6 @@ import java.security.NoSuchProviderException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import javax.net.ssl.X509TrustManager; -import javax.net.ssl.TrustManagerFactory; /** * The KeyVault variant of the X509TrustManager. @@ -64,7 +64,7 @@ public KeyVaultTrustManager(KeyStore keyStore) { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) - throws CertificateException { + throws CertificateException { boolean pass = true; @@ -95,7 +95,7 @@ public void checkClientTrusted(X509Certificate[] chain, String authType) @Override public void checkServerTrusted(X509Certificate[] chain, String authType) - throws CertificateException { + throws CertificateException { boolean pass = true; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java index 7db14dc54625a..81cccec5f0932 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java @@ -2,15 +2,15 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; +import javax.net.ssl.ManagerFactoryParameters; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactorySpi; import java.security.InvalidAlgorithmParameterException; import java.security.KeyStore; import java.security.KeyStoreException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; -import javax.net.ssl.ManagerFactoryParameters; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactorySpi; /** * The KeyVault variant of the TrustManagerFactory. diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java index 56a42efcba39c..34a0197d24cbb 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java @@ -47,8 +47,8 @@ public KeyVaultTrustManagerFactoryProvider() { private void initialize() { AccessController.doPrivileged((PrivilegedAction) () -> { putService(new Provider.Service(this, "TrustManagerFactory", "PKIX", - KeyVaultTrustManagerFactory.class.getName(), - null, null)); + KeyVaultTrustManagerFactory.class.getName(), + null, null)); return null; }); } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java index e2525413b43c4..2a21d6831e965 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java @@ -2,8 +2,6 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; -import java.io.IOException; -import java.util.Map; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; @@ -15,6 +13,9 @@ import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.io.entity.HttpEntities; +import java.io.IOException; +import java.util.Map; + /** * The RestClient that uses the Apache HttpClient class. * diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java index d3e46e8d2b5f7..9572247fd8c2f 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java @@ -10,19 +10,19 @@ * @author Manfred Riem (manfred.riem@microsoft.com) */ interface RestClient { - + /** * Issue a GET request. - * + * * @param url the URL. * @param headers the request headers map. * @return the response body as a string. */ String get(String url, Map headers); - + /** * Issue a POST request. - * + * * @param url the URL. * @param body the request body. * @return the response body as a string. diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java index 77e7f3308bae5..24e23e9db6d21 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java @@ -4,7 +4,7 @@ /** * The RestClientFactory. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ class RestClientFactory { @@ -14,10 +14,10 @@ class RestClientFactory { */ private RestClientFactory() { } - + /** * Static helper method to create a RestClient. - * + * * @return the RestClient. */ static RestClient createClient() { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java index 7a99b5ec6e94f..4f69008d363d6 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java @@ -6,26 +6,26 @@ /** * The CertificateBundle REST model. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ public class CertificateBundle implements Serializable { - + /** * Stores the CER bytes. */ private String cer; - + /** * Stores the Key ID. */ private String kid; - + /** * Stores the policy. */ private CertificatePolicy policy; - + /** * Stores the Secret ID. */ @@ -33,7 +33,7 @@ public class CertificateBundle implements Serializable { /** * Get the CER string. - * + * * @return the CER string. */ public String getCer() { @@ -42,7 +42,7 @@ public String getCer() { /** * Get the Key ID. - * + * * @return the Key ID. */ public String getKid() { @@ -51,7 +51,7 @@ public String getKid() { /** * Get the policy. - * + * * @return the policy. */ public CertificatePolicy getPolicy() { @@ -60,16 +60,16 @@ public CertificatePolicy getPolicy() { /** * Get the Secret ID. - * + * * @return the Secret ID. */ public String getSid() { return sid; } - + /** * Set the CER string. - * + * * @param cer the CER string. */ public void setCer(String cer) { @@ -78,16 +78,16 @@ public void setCer(String cer) { /** * Set the Key ID. - * + * * @param kid the Key ID. */ public void setKid(String kid) { this.kid = kid; } - + /** * Set the policy. - * + * * @param policy the policy. */ public void setPolicy(CertificatePolicy policy) { @@ -96,7 +96,7 @@ public void setPolicy(CertificatePolicy policy) { /** * Set the Secret ID. - * + * * @param sid the Secret ID. */ public void setSid(String sid) { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java index 6fa8174d1af6b..92a09a4932106 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java @@ -6,11 +6,11 @@ /** * The CertificateItem REST model. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ public class CertificateItem implements Serializable { - + /** * Stores the id. */ @@ -18,7 +18,7 @@ public class CertificateItem implements Serializable { /** * Get the id. - * + * * @return the id. */ public String getId() { @@ -27,7 +27,7 @@ public String getId() { /** * Set the id. - * + * * @param id the id. */ public void setId(String id) { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java index 4af24481edd00..97210624cfd62 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java @@ -7,11 +7,11 @@ /** * The CertificateItem REST model. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ public class CertificateListResult implements Serializable { - + /** * Stores the value. */ @@ -19,7 +19,7 @@ public class CertificateListResult implements Serializable { /** * Get the value. - * + * * @return the id. */ public List getValue() { @@ -28,7 +28,7 @@ public List getValue() { /** * Set the value. - * + * * @param value the value. */ public void setValue(List value) { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java index 2c4f0cb78afa2..b520cb8f200f6 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java @@ -6,11 +6,11 @@ /** * The CertificatePolicy REST model. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ public class CertificatePolicy implements Serializable { - + /** * Stores the key properties. */ @@ -18,7 +18,7 @@ public class CertificatePolicy implements Serializable { /** * Get the key properties. - * + * * @return the key properties. */ public KeyProperties getKey_props() { @@ -27,7 +27,7 @@ public KeyProperties getKey_props() { /** * Set the key properties. - * + * * @param keyProperties the key properties. */ public void setKey_props(KeyProperties keyProperties) { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java index 1411fa858c8c1..4e0ef2a635ba8 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java @@ -6,11 +6,11 @@ /** * The KeyProperties REST model. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ public class KeyProperties implements Serializable { - + /** * Stores if the key is exportable. */ @@ -18,7 +18,7 @@ public class KeyProperties implements Serializable { /** * Is the key exportable. - * + * * @return true if exportable, false otherwise. */ public boolean isExportable() { @@ -27,7 +27,7 @@ public boolean isExportable() { /** * Set the key to be exportable. - * + * * @param exportable the exportable flag. */ public void setExportable(boolean exportable) { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java index 4d9de1a0e0007..4d88a6d969831 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java @@ -6,11 +6,11 @@ /** * The SecretBundle REST model. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ public class SecretBundle implements Serializable { - + /** * Stores the value. */ @@ -18,16 +18,16 @@ public class SecretBundle implements Serializable { /** * Get the value. - * + * * @return the value. */ public String getValue() { return value; } - + /** * Set the value. - * + * * @param value the value. */ public void setValue(String value) { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java index 8b0fb320048e7..c5cc3c247d942 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java @@ -2,17 +2,19 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; +import org.junit.jupiter.api.Test; + import java.net.URLEncoder; + import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.Test; /** * The JUnit test for the AuthClient. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ public class AuthClientTest { - + /** * Test getAuthorizationToken method. */ @@ -23,8 +25,8 @@ public void testGetAuthorizationToken() throws Exception { String clientSecret = "72-~tZ9~cG~rimDI0EkQSMQ1D9DYmGmI_I"; AuthClient authClient = new AuthClient(); String result = authClient.getAccessToken( - "https://management.azure.com/", tenantId, clientId, - URLEncoder.encode(clientSecret, "UTF-8")); + "https://management.azure.com/", tenantId, clientId, + URLEncoder.encode(clientSecret, "UTF-8")); assertNotNull(result); } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java index 578e36fe4b30c..8e62c8b5355cd 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java @@ -3,15 +3,16 @@ package com.azure.security.keyvault.jca; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; + +import static org.junit.jupiter.api.Assertions.assertNotNull; /** * The JUnit tests for the DelegateRestClient class. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ public class DelegateRestClientTest { - + /** * Test of getDelegate method, of class DelegateRestClient. */ diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java index 72098f4af9253..85189eedb5180 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java @@ -3,10 +3,11 @@ package com.azure.security.keyvault.jca; import com.azure.security.keyvault.jca.rest.CertificateBundle; +import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; /** * The JUnit tests for the JsonbJsonConverter class. @@ -29,7 +30,7 @@ public void testFromJson() { /** * Test toJson method. - * + * * @throws Exception when a serious error occurs. */ @Test diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java index d8f4001f02065..615f361c0ea38 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java @@ -2,6 +2,9 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import java.io.ByteArrayInputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -18,14 +21,13 @@ import java.util.Base64; import java.util.Date; import java.util.Set; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; /** * The JUnit tests for the KeyVaultCertificate class. @@ -38,25 +40,25 @@ public class KeyVaultCertificateTest { * Stores the CER test certificate (which is valid til 2120). */ private static final String TEST_CERTIFICATE - = "MIIDeDCCAmCgAwIBAgIQGghBu97rQJKNnUHPWU7xjDANBgkqhkiG9w0BAQsFADAk" - + "MSIwIAYDVQQDExlodW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMCAXDTIwMDkwMjE3" - + "NDUyNFoYDzIxMjAwOTAyMTc1NTI0WjAkMSIwIAYDVQQDExlodW5kcmVkLXllYXJz" - + "LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuU14" - + "btkN5wmcO2WKXqm1NUKXzi79EtqiFFkrLgPAwj5NNwMw2Akm3GpdEpwkJ8/q3l7d" - + "frDEVOO9gwZbz7xppyqutjxjllw8CCgjFdfK02btz56CGgh3X25ZZtzPbuMZJM0j" - + "o4mVEdaFNJ0eUeMppS0DcbbuTWCF7Jf1gvr8GVqx+E0IJUFkE+D4kdTbnJSaeK0A" - + "KEt94z88MPX18h8ud14uRVmUCYVZrZeswdE2tO1BpazrXELHuXCtrjGxsDDjDzeP" - + "98aFI9kblkqoJS4TsmloLEjwZLm80cyJDEmpXXMtR7C0FFXFI1BAtIa4mxSgBLsT" - + "L4GVPEGNANR8COYkHQIDAQABo4GjMIGgMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRME" - + "AjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAkBgNVHREEHTAbghlo" - + "dW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMB8GA1UdIwQYMBaAFOGTt4H3ho30O4e+" - + "hebwJjm2VMvIMB0GA1UdDgQWBBThk7eB94aN9DuHvoXm8CY5tlTLyDANBgkqhkiG" - + "9w0BAQsFAAOCAQEAGp8mCioVCmM+kZv6r+K2j2uog1k4HBwN1NfRoSsibDB8+QXF" - + "bmNf3M0imiuR/KJgODyuROwaa/AalxNFMOP8XTL2YmP7XsddBs9ONHHQXKjY/Ojl" - + "PsIPR7vZjwYPfEB+XEKl2fOIxDQQ921POBV7M6DdTC49T5X+FsLR1AIIfinVetT9" - + "QmNuvzulBX0T0rea/qpcPK4HTj7ToyImOaf8sXRv2s2ODLUrKWu5hhTNH2l6RIkQ" - + "U/aIAdQRfDaSE9jhtcVu5d5kCgBs7nz5AzeCisDPo5zIt4Mxej3iVaAJ79oEbHOE" - + "p192KLXLV/pscA4Wgb+PJ8AAEa5B6xq8p9JO+Q=="; + = "MIIDeDCCAmCgAwIBAgIQGghBu97rQJKNnUHPWU7xjDANBgkqhkiG9w0BAQsFADAk" + + "MSIwIAYDVQQDExlodW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMCAXDTIwMDkwMjE3" + + "NDUyNFoYDzIxMjAwOTAyMTc1NTI0WjAkMSIwIAYDVQQDExlodW5kcmVkLXllYXJz" + + "LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuU14" + + "btkN5wmcO2WKXqm1NUKXzi79EtqiFFkrLgPAwj5NNwMw2Akm3GpdEpwkJ8/q3l7d" + + "frDEVOO9gwZbz7xppyqutjxjllw8CCgjFdfK02btz56CGgh3X25ZZtzPbuMZJM0j" + + "o4mVEdaFNJ0eUeMppS0DcbbuTWCF7Jf1gvr8GVqx+E0IJUFkE+D4kdTbnJSaeK0A" + + "KEt94z88MPX18h8ud14uRVmUCYVZrZeswdE2tO1BpazrXELHuXCtrjGxsDDjDzeP" + + "98aFI9kblkqoJS4TsmloLEjwZLm80cyJDEmpXXMtR7C0FFXFI1BAtIa4mxSgBLsT" + + "L4GVPEGNANR8COYkHQIDAQABo4GjMIGgMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRME" + + "AjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAkBgNVHREEHTAbghlo" + + "dW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMB8GA1UdIwQYMBaAFOGTt4H3ho30O4e+" + + "hebwJjm2VMvIMB0GA1UdDgQWBBThk7eB94aN9DuHvoXm8CY5tlTLyDANBgkqhkiG" + + "9w0BAQsFAAOCAQEAGp8mCioVCmM+kZv6r+K2j2uog1k4HBwN1NfRoSsibDB8+QXF" + + "bmNf3M0imiuR/KJgODyuROwaa/AalxNFMOP8XTL2YmP7XsddBs9ONHHQXKjY/Ojl" + + "PsIPR7vZjwYPfEB+XEKl2fOIxDQQ921POBV7M6DdTC49T5X+FsLR1AIIfinVetT9" + + "QmNuvzulBX0T0rea/qpcPK4HTj7ToyImOaf8sXRv2s2ODLUrKWu5hhTNH2l6RIkQ" + + "U/aIAdQRfDaSE9jhtcVu5d5kCgBs7nz5AzeCisDPo5zIt4Mxej3iVaAJ79oEbHOE" + + "p192KLXLV/pscA4Wgb+PJ8AAEa5B6xq8p9JO+Q=="; /** * Stores the X.509 certificate. @@ -342,8 +344,8 @@ public void testVerify() { PublicKey publicKey = certificate.getPublicKey(); certificate.verify(publicKey); } catch (CertificateException | NoSuchAlgorithmException - | InvalidKeyException | NoSuchProviderException - | SignatureException e) { + | InvalidKeyException | NoSuchProviderException + | SignatureException e) { fail(); } } @@ -358,8 +360,8 @@ public void testVerify2() { PublicKey publicKey = certificate.getPublicKey(); certificate.verify(publicKey, "SunRsaSign"); } catch (CertificateException | NoSuchAlgorithmException - | InvalidKeyException | NoSuchProviderException - | SignatureException e) { + | InvalidKeyException | NoSuchProviderException + | SignatureException e) { fail(); } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java index f0a11b6578d39..bfa9add11b0d5 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java @@ -2,11 +2,13 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; +import org.junit.jupiter.api.Test; + import java.security.KeyStore; import java.security.Security; + import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.Test; /** * The JUnit tests for the KeyVaultProvider class. @@ -23,10 +25,10 @@ public void testConstructor() { KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); assertNotNull(provider); } - + /** * Test getting a certificate using the Provider. - * + * * @throws Exception when an error occurs. */ @Test @@ -34,10 +36,10 @@ public void testGetCertificate() throws Exception { Security.addProvider(new KeyVaultJcaProvider()); KeyStore keystore = KeyStore.getInstance("AzureKeyVault"); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.load(parameter); assertNull(keystore.getCertificate("myalias")); } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java index 97da44bfd4066..cf0751b3bd034 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java @@ -2,17 +2,19 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; +import org.junit.jupiter.api.Test; + import java.io.ByteArrayInputStream; import java.security.ProviderException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Base64; + import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; /** * The JUnit tests for the KeyVaultKeyStore class. @@ -25,25 +27,25 @@ public class KeyVaultKeyStoreTest { * Stores the CER test certificate (which is valid til 2120). */ private static final String TEST_CERTIFICATE - = "MIIDeDCCAmCgAwIBAgIQGghBu97rQJKNnUHPWU7xjDANBgkqhkiG9w0BAQsFADAk" - + "MSIwIAYDVQQDExlodW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMCAXDTIwMDkwMjE3" - + "NDUyNFoYDzIxMjAwOTAyMTc1NTI0WjAkMSIwIAYDVQQDExlodW5kcmVkLXllYXJz" - + "LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuU14" - + "btkN5wmcO2WKXqm1NUKXzi79EtqiFFkrLgPAwj5NNwMw2Akm3GpdEpwkJ8/q3l7d" - + "frDEVOO9gwZbz7xppyqutjxjllw8CCgjFdfK02btz56CGgh3X25ZZtzPbuMZJM0j" - + "o4mVEdaFNJ0eUeMppS0DcbbuTWCF7Jf1gvr8GVqx+E0IJUFkE+D4kdTbnJSaeK0A" - + "KEt94z88MPX18h8ud14uRVmUCYVZrZeswdE2tO1BpazrXELHuXCtrjGxsDDjDzeP" - + "98aFI9kblkqoJS4TsmloLEjwZLm80cyJDEmpXXMtR7C0FFXFI1BAtIa4mxSgBLsT" - + "L4GVPEGNANR8COYkHQIDAQABo4GjMIGgMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRME" - + "AjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAkBgNVHREEHTAbghlo" - + "dW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMB8GA1UdIwQYMBaAFOGTt4H3ho30O4e+" - + "hebwJjm2VMvIMB0GA1UdDgQWBBThk7eB94aN9DuHvoXm8CY5tlTLyDANBgkqhkiG" - + "9w0BAQsFAAOCAQEAGp8mCioVCmM+kZv6r+K2j2uog1k4HBwN1NfRoSsibDB8+QXF" - + "bmNf3M0imiuR/KJgODyuROwaa/AalxNFMOP8XTL2YmP7XsddBs9ONHHQXKjY/Ojl" - + "PsIPR7vZjwYPfEB+XEKl2fOIxDQQ921POBV7M6DdTC49T5X+FsLR1AIIfinVetT9" - + "QmNuvzulBX0T0rea/qpcPK4HTj7ToyImOaf8sXRv2s2ODLUrKWu5hhTNH2l6RIkQ" - + "U/aIAdQRfDaSE9jhtcVu5d5kCgBs7nz5AzeCisDPo5zIt4Mxej3iVaAJ79oEbHOE" - + "p192KLXLV/pscA4Wgb+PJ8AAEa5B6xq8p9JO+Q=="; + = "MIIDeDCCAmCgAwIBAgIQGghBu97rQJKNnUHPWU7xjDANBgkqhkiG9w0BAQsFADAk" + + "MSIwIAYDVQQDExlodW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMCAXDTIwMDkwMjE3" + + "NDUyNFoYDzIxMjAwOTAyMTc1NTI0WjAkMSIwIAYDVQQDExlodW5kcmVkLXllYXJz" + + "LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuU14" + + "btkN5wmcO2WKXqm1NUKXzi79EtqiFFkrLgPAwj5NNwMw2Akm3GpdEpwkJ8/q3l7d" + + "frDEVOO9gwZbz7xppyqutjxjllw8CCgjFdfK02btz56CGgh3X25ZZtzPbuMZJM0j" + + "o4mVEdaFNJ0eUeMppS0DcbbuTWCF7Jf1gvr8GVqx+E0IJUFkE+D4kdTbnJSaeK0A" + + "KEt94z88MPX18h8ud14uRVmUCYVZrZeswdE2tO1BpazrXELHuXCtrjGxsDDjDzeP" + + "98aFI9kblkqoJS4TsmloLEjwZLm80cyJDEmpXXMtR7C0FFXFI1BAtIa4mxSgBLsT" + + "L4GVPEGNANR8COYkHQIDAQABo4GjMIGgMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRME" + + "AjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAkBgNVHREEHTAbghlo" + + "dW5kcmVkLXllYXJzLmV4YW1wbGUuY29tMB8GA1UdIwQYMBaAFOGTt4H3ho30O4e+" + + "hebwJjm2VMvIMB0GA1UdDgQWBBThk7eB94aN9DuHvoXm8CY5tlTLyDANBgkqhkiG" + + "9w0BAQsFAAOCAQEAGp8mCioVCmM+kZv6r+K2j2uog1k4HBwN1NfRoSsibDB8+QXF" + + "bmNf3M0imiuR/KJgODyuROwaa/AalxNFMOP8XTL2YmP7XsddBs9ONHHQXKjY/Ojl" + + "PsIPR7vZjwYPfEB+XEKl2fOIxDQQ921POBV7M6DdTC49T5X+FsLR1AIIfinVetT9" + + "QmNuvzulBX0T0rea/qpcPK4HTj7ToyImOaf8sXRv2s2ODLUrKWu5hhTNH2l6RIkQ" + + "U/aIAdQRfDaSE9jhtcVu5d5kCgBs7nz5AzeCisDPo5zIt4Mxej3iVaAJ79oEbHOE" + + "p192KLXLV/pscA4Wgb+PJ8AAEa5B6xq8p9JO+Q=="; /** * Test engineGetCertificate method. @@ -54,10 +56,10 @@ public class KeyVaultKeyStoreTest { public void testEngineGetCertificate() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); assertNull(keystore.engineGetCertificate("myalias")); } @@ -71,10 +73,10 @@ public void testEngineGetCertificate() throws Exception { public void testEngineGetCertificateAlias() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); assertNull(keystore.engineGetCertificateAlias(null)); } @@ -88,10 +90,10 @@ public void testEngineGetCertificateAlias() throws Exception { public void testEngineGetCertificateChain() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); assertNull(keystore.engineGetCertificateChain("myalias")); } @@ -105,10 +107,10 @@ public void testEngineGetCertificateChain() throws Exception { public void testEngineIsCertificateEntry() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); assertFalse(keystore.engineIsCertificateEntry("myalias")); } @@ -122,14 +124,14 @@ public void testEngineIsCertificateEntry() throws Exception { public void testEngineSetCertificateEntry() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); - + X509Certificate certificate; - + try { byte[] certificateBytes = Base64.getDecoder().decode(TEST_CERTIFICATE); CertificateFactory cf = CertificateFactory.getInstance("X.509"); @@ -151,10 +153,10 @@ public void testEngineSetCertificateEntry() throws Exception { public void testEngineGetKey() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); assertNull(keystore.engineGetKey("myalias", null)); } @@ -168,10 +170,10 @@ public void testEngineGetKey() throws Exception { public void testEngineIsKeyEntry() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); assertFalse(keystore.engineIsKeyEntry("myalias")); } @@ -207,10 +209,10 @@ public void testEngineSetKeyEntry2() throws Exception { public void testEngineAliases() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); assertTrue(keystore.engineAliases().hasMoreElements()); } @@ -224,10 +226,10 @@ public void testEngineAliases() throws Exception { public void testEngineContainsAlias() throws Exception { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); keystore.engineLoad(parameter); assertFalse(keystore.engineContainsAlias("myalias")); } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java index 7ace46bb5b2fb..49632d092df5d 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java @@ -2,9 +2,10 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; -import static org.junit.jupiter.api.Assertions.assertNull; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertNull; + /** * The JUnit tests for the KeyVaultLoadStoreParameter class. * @@ -18,7 +19,7 @@ public class KeyVaultLoadStoreParameterTest { @Test public void testGetProtectionParameter() { KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), null, null, null); + System.getProperty("azure.keyvault.uri"), null, null, null); assertNull(parameter.getProtectionParameter()); } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java index ab74cbd983b8a..322f41b56cd76 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java @@ -2,12 +2,13 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; -import static org.junit.jupiter.api.Assertions.assertNotNull; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertNotNull; + /** * The JUnit tests for the LegacyRestClient class. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ public class LegacyRestClientTest { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java index 8b740e400b4f3..a9923ced3aad5 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java @@ -2,16 +2,17 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; -import static org.junit.jupiter.api.Assertions.assertNotNull; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertNotNull; + /** * The JUnit tests for the RestClientFactory class. - * + * * @author Manfred Riem (manfred.riem@microsoft.com) */ public class RestClientFactoryTest { - + /** * Test createClient method. */ diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java index 140708f3b7fc6..766be028bff6f 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java @@ -2,16 +2,6 @@ // Licensed under the MIT License. package com.azure.security.keyvault.jca; -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; -import java.security.KeyStore; -import java.security.Security; -import java.security.cert.X509Certificate; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLServerSocket; -import javax.net.ssl.SSLServerSocketFactory; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; @@ -23,12 +13,23 @@ import org.apache.hc.core5.http.ClassicHttpResponse; import org.apache.hc.core5.http.io.HttpClientResponseHandler; import org.apache.hc.core5.ssl.SSLContexts; -import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLServerSocketFactory; +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.security.KeyStore; +import java.security.Security; +import java.security.cert.X509Certificate; + +import static org.junit.jupiter.api.Assertions.assertEquals; + /** - * The unit test validating the ServerSocket is created using a certificate from - * Azure KeyVault. + * The unit test validating the ServerSocket is created using a certificate from Azure KeyVault. * * @author Manfred Riem (manfred.riem@microsoft.com) */ @@ -41,7 +42,7 @@ public class ServerSocketTest { */ @Test public void testServerSocket() throws Exception { - + /* * Add JCA provider. */ @@ -58,10 +59,10 @@ public void testServerSocket() throws Exception { */ KeyStore ks = KeyStore.getInstance("AzureKeyVault"); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); ks.load(parameter); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); @@ -89,7 +90,7 @@ public void testServerSocket() throws Exception { server.start(); /* - * Setup client side + * Setup client side * * - Create an SSL context. * - Set SSL context to trust any certificate. @@ -98,31 +99,31 @@ public void testServerSocket() throws Exception { */ SSLContext sslContext = SSLContexts - .custom() - .loadTrustMaterial((final X509Certificate[] chain, final String authType) -> { - return true; - }) - .build(); - + .custom() + .loadTrustMaterial((final X509Certificate[] chain, final String authType) -> { + return true; + }) + .build(); + SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder - .create() - .setSslContext(sslContext) - .setHostnameVerifier((hostname, session) -> { - return true; - }) - .build(); - + .create() + .setSslContext(sslContext) + .setHostnameVerifier((hostname, session) -> { + return true; + }) + .build(); + PoolingHttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder - .create() - .setSSLSocketFactory(sslSocketFactory) - .build(); + .create() + .setSSLSocketFactory(sslSocketFactory) + .build(); /* * And now execute the test. */ String result = null; - - try ( CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build()) { + + try (CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build()) { HttpGet httpGet = new HttpGet("https://localhost:8765"); HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { int status = response.getCode(); @@ -136,21 +137,21 @@ public void testServerSocket() throws Exception { } catch (IOException ioe) { ioe.printStackTrace(); } - + /* * And verify all went well. */ assertEquals("Success", result); } - - /** + + /** * Test SSLServerSocket WITH self-signed client trust. * * @throws Exception when a serious error occurs. */ @Test public void testServerSocketWithSelfSignedClientTrust() throws Exception { - + /* * Add JCA provider. */ @@ -167,15 +168,15 @@ public void testServerSocketWithSelfSignedClientTrust() throws Exception { */ KeyStore ks = KeyStore.getInstance("AzureKeyVault"); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), - System.getProperty("azure.tenant.id"), - System.getProperty("azure.client.id"), - System.getProperty("azure.client.secret")); + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.tenant.id"), + System.getProperty("azure.client.id"), + System.getProperty("azure.client.secret")); ks.load(parameter); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, "".toCharArray()); - + SSLContext context = SSLContext.getInstance("TLS"); context.init(kmf.getKeyManagers(), null, null); @@ -198,7 +199,7 @@ public void testServerSocketWithSelfSignedClientTrust() throws Exception { server.start(); /* - * Setup client side + * Setup client side * * - Create an SSL context. * - Set SSL context to trust any certificate. @@ -207,29 +208,29 @@ public void testServerSocketWithSelfSignedClientTrust() throws Exception { */ SSLContext sslContext = SSLContexts - .custom() - .loadTrustMaterial(ks, new TrustSelfSignedStrategy()) - .build(); - + .custom() + .loadTrustMaterial(ks, new TrustSelfSignedStrategy()) + .build(); + SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder - .create() - .setSslContext(sslContext) - .setHostnameVerifier((hostname, session) -> { - return true; - }) - .build(); - + .create() + .setSslContext(sslContext) + .setHostnameVerifier((hostname, session) -> { + return true; + }) + .build(); + PoolingHttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder - .create() - .setSSLSocketFactory(sslSocketFactory) - .build(); + .create() + .setSSLSocketFactory(sslSocketFactory) + .build(); /* * And now execute the test. */ String result = null; - - try ( CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build()) { + + try (CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build()) { HttpGet httpGet = new HttpGet("https://localhost:8766"); HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { int status = response.getCode(); @@ -243,7 +244,7 @@ public void testServerSocketWithSelfSignedClientTrust() throws Exception { } catch (IOException ioe) { ioe.printStackTrace(); } - + /* * And verify all went well. */ From ecfe01d1a1da565478a23c2b26791c40b59395e1 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 11:00:01 +0800 Subject: [PATCH 56/92] Format files in sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates. --- .../.mvn/wrapper/MavenWrapperDownloader.java | 19 ++++++++++--------- .../src/main/resources/application.properties | 8 -------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java index e76d1f3241d38..42c7d2138dd2b 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import java.net.*; import java.io.*; import java.nio.channels.*; @@ -28,17 +29,17 @@ public class MavenWrapperDownloader { + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to use instead of the + * default one. */ private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; + ".mvn/wrapper/maven-wrapper.properties"; /** * Path where the maven-wrapper.jar will be saved to. */ private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; + ".mvn/wrapper/maven-wrapper.jar"; /** * Name of the property which should be used to override the default download url for the wrapper. @@ -54,7 +55,7 @@ public static void main(String args[]) { // wrapperUrl parameter. File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { + if (mavenWrapperPropertyFile.exists()) { FileInputStream mavenWrapperPropertyFileInputStream = null; try { mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); @@ -65,7 +66,7 @@ public static void main(String args[]) { System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); } finally { try { - if(mavenWrapperPropertyFileInputStream != null) { + if (mavenWrapperPropertyFileInputStream != null) { mavenWrapperPropertyFileInputStream.close(); } } catch (IOException e) { @@ -76,10 +77,10 @@ public static void main(String args[]) { System.out.println("- Downloading from: " + url); File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { + if (!outputFile.getParentFile().exists()) { + if (!outputFile.getParentFile().mkdirs()) { System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); } } System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties index 0736876521817..aa139496fa7a8 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties @@ -2,47 +2,39 @@ # The URI to the Azure KeyVault used # azure.keyvault.uri=${AZURE_KEYVAULT_URI} - # # The alias corresponding to the certificate in Azure KeyVault. # server.ssl.key-alias=${SERVER_SSL_KEY_ALIAS} - # # The keystore type that enables the use of Azure KeyVault for your server-side # SSL certificate. # server.ssl.key-store-type=AzureKeyVault - # # The truststore type that enables the use of Azure KeyVault for trusted # certificates, a.k.a the ones you trust when making an outbound SSL connection # # server.ssl.trust-store-type=AzureKeyVault - # # The Tenant ID for your Azure KeyVault (needed if you are not using managed # identity). # azure.keyvault.tenantId=${AZURE_KEYVAULT_TENTANT_ID} - # # The Client ID that has been setup with access to your Azure KeyVault (needed # if you are not using managed identity). # azure.keyvault.clientId=${AZURE_KEYVAULT_CLIENT_ID} - # # The Client Secret that will be used for accessing your Azure KeyVault (needed # if you are not using managed identity). # azure.keyvault.clientSecret=${AZURE_KEYVAULT_CLIENT_SECRET} - # # The server port. # server.port=8443 - # # Just for debugging purposes. # From 8653364c9cad4f6aa791aad7e35be049e2a30d48 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 11:08:06 +0800 Subject: [PATCH 57/92] Change groupId from com.azure.spring to com.azure. --- eng/versioning/version_client.txt | 2 +- .../pom.xml | 6 +++--- .../README.md | 8 ++++---- .../pom.xml | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/eng/versioning/version_client.txt b/eng/versioning/version_client.txt index 07959c08a745f..bc09d58710d13 100644 --- a/eng/versioning/version_client.txt +++ b/eng/versioning/version_client.txt @@ -101,7 +101,7 @@ com.azure:azure-spring-boot-starter-active-directory;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter-cosmos;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter-data-gremlin;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter-keyvault-secrets;3.0.0-beta.1;3.0.0-beta.1 -com.azure.spring:azure-spring-boot-starter-keyvault-certificates;3.0.0-beta.1;3.0.0-beta.1 +com.azure:azure-spring-boot-starter-keyvault-certificates;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter-metrics;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter-servicebus-jms;3.0.0-beta.1;3.0.0-beta.1 com.azure:azure-spring-boot-starter;3.0.0-beta.1;3.0.0-beta.1 diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml index 7937464ffb28f..e92be03a9290d 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml @@ -11,7 +11,7 @@ - com.azure.spring + com.azure azure-spring-boot-sample-keyvault-certificates 1.0.0 jar @@ -81,9 +81,9 @@ - com.azure.spring + com.azure azure-spring-boot-starter-keyvault-certificates - 3.0.0-beta.1 + 3.0.0-beta.1 org.springframework.boot diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 00f85f21c0ad5..2a438c1aff837 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -21,7 +21,7 @@ Add then add the following Maven dependency to your POM file. ```xml - com.azure.spring + com.azure azure-spring-boot-starter-keyvault-certificates ``` @@ -48,7 +48,7 @@ Add then add the following Maven dependency to your POM file. ```xml - com.azure.spring + com.azure azure-spring-boot-starter-keyvault-certificates ``` @@ -71,7 +71,7 @@ Add then add the following Maven dependency to your POM file. ```xml - com.azure.spring + com.azure azure-spring-boot-starter-keyvault-certificates ``` @@ -121,7 +121,7 @@ Add then add the following Maven dependency to your POM file. ```xml - com.azure.spring + com.azure azure-spring-boot-starter-keyvault-certificates ``` diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index aa08a980e9d2d..cfa81e01ce92b 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -11,9 +11,9 @@ ../../parents/azure-client-sdk-parent --> - com.azure.spring + com.azure azure-spring-boot-starter-keyvault-certificates - 3.0.0-beta.1 + 3.0.0-beta.1 Azure Key Vault Certificates Spring Boot Starter Spring Boot Starter supporting Azure Key Vault Certificates From 851ae2009ac021db319c479e7e83c7b53fdadef1 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 13:10:51 +0800 Subject: [PATCH 58/92] Add new projects in to root pom modules. --- sdk/spring/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/spring/pom.xml b/sdk/spring/pom.xml index 675419e350d2a..f6c699c7fa172 100644 --- a/sdk/spring/pom.xml +++ b/sdk/spring/pom.xml @@ -15,6 +15,7 @@ azure-spring-boot-starter-active-directory-b2c azure-spring-boot-starter-cosmos azure-spring-boot-starter-data-gremlin + azure-spring-boot-starter-keyvault-certificates azure-spring-boot-starter-keyvault-secrets azure-spring-boot-starter-metrics azure-spring-boot-starter-servicebus-jms @@ -32,6 +33,7 @@ azure-spring-boot-samples/azure-spring-boot-sample-active-directory-stateless azure-spring-boot-samples/azure-spring-boot-sample-cosmos azure-spring-boot-samples/azure-spring-boot-sample-data-gremlin + azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates azure-spring-boot-samples/azure-spring-boot-sample-keyvault-secrets azure-spring-boot-samples/azure-spring-boot-sample-mediaservices azure-spring-boot-samples/azure-spring-boot-sample-servicebus From 5870ffebe39af980da2c5a838fb400c1c6283807 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 13:24:36 +0800 Subject: [PATCH 59/92] Update CHANGELOG.md and README.md. --- sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md | 3 +++ sdk/keyvault/azure-security-keyvault-jca/README.md | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md index 8b137891791fe..025d359b28644 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md +++ b/sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md @@ -1 +1,4 @@ +# Release History + +## 3.0.0-beta.1 (Unreleased) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index 37ca69fb35186..85c418256d61d 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -1,7 +1,7 @@ # JCA Provider for Azure Key Vault The JCA Provider for Azure Key Vault is a JCA provider for certificates in -Azure Key Vault. It is built on four core principles: +Azure Key Vault. It is built on four principles: 1. Must be extremely thin to run within a JVM 1. Must not introduce any library version conflicts with Java app code dependencies @@ -45,8 +45,8 @@ see the example below. SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(8765); ``` -Note if you want to use a Azure managed identity you would only pass the value -of the `azure.keyvault.uri` and the rest of the parameters would be `null`. +Note if you want to use Azure managed identity, you should set the value +of `azure.keyvault.uri`, and the rest of the parameters would be `null`. ## Client side SSL @@ -101,8 +101,8 @@ connections, see the Apache HTTP client example below. } ``` -Note if you want to use an Azure managed identity you only need to pass the value -of the `azure.keyvault.uri` and let the remaining parameters be `null`. +Note if you want to use Azure managed identity, you should set the value +of `azure.keyvault.uri`, and the rest of the parameters would be `null`. ## Spring Boot From 539e5df91c0003b48979ade0b328a987a438cfd4 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 13:36:33 +0800 Subject: [PATCH 60/92] Add version tag in azure-security-keyvault-jca\pom.xml. --- eng/versioning/external_dependencies.txt | 3 ++ .../azure-security-keyvault-jca/pom.xml | 30 +++++++++++-------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/eng/versioning/external_dependencies.txt b/eng/versioning/external_dependencies.txt index 9fada7984de4a..7a0d985c107d8 100644 --- a/eng/versioning/external_dependencies.txt +++ b/eng/versioning/external_dependencies.txt @@ -63,6 +63,7 @@ org.apache.avro:avro-maven-plugin;1.9.2 org.apache.commons:commons-compress;1.20 org.apache.commons:commons-lang3;3.10 org.apache.httpcomponents:httpclient;4.5.12 +org.apache.httpcomponents:httpclient5;5.0.1 org.apache.logging.log4j:log4j-api;2.13.3 org.apache.logging.log4j:log4j-core;2.13.3 org.apache.logging.log4j:log4j-slf4j-impl;2.13.3 @@ -79,6 +80,7 @@ org.powermock:powermock-api-mockito2;2.0.2 org.powermock:powermock-module-junit4;2.0.2 org.postgresql:postgresql;42.2.14 org.slf4j:slf4j-api;1.7.30 +org.slf4j:slf4j-nop;1.7.30 org.slf4j:slf4j-simple;1.7.30 ## Spring boot dependency versions @@ -232,6 +234,7 @@ org.apache.maven.plugins:maven-jxr-plugin;3.0.0 org.apache.maven.plugins:maven-project-info-reports-plugin;3.0.0 org.apache.maven.plugins:maven-release-plugin;2.5.3 org.apache.maven.plugins:maven-resources-plugin;2.4.3 +org.apache.maven.plugins:maven-shade-plugin;3.2.4 org.apache.maven.plugins:maven-site-plugin;3.7.1 org.apache.maven.plugins:maven-source-plugin;3.0.1 org.apache.maven.plugins:maven-surefire-plugin;3.0.0-M3 diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index c4515fc19a460..ac332cfd7629f 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -4,6 +4,12 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + + azure-client-sdk-parent + com.azure + 1.7.0 + ../../parents/azure-client-sdk-parent + com.azure azure-security-keyvault-jca 1.0.0 @@ -14,7 +20,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.8.1 1.8 1.8 @@ -24,7 +30,7 @@ org.apache.maven.plugins maven-resources-plugin - 3.2.0 + 2.4.3 ${project.build.sourceEncoding} @@ -32,7 +38,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 + 3.2.4 @@ -72,7 +78,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M5 + 3.0.0-M3 true @@ -80,7 +86,7 @@ org.jacoco jacoco-maven-plugin - 0.8.5 + 0.8.5 default-prepare-agent @@ -104,40 +110,40 @@ org.apache.httpcomponents.client5 httpclient5 - 5.0.1 + 5.0.1 true com.fasterxml.jackson.core jackson-databind - 2.11.2 + 2.11.2 true org.junit.jupiter junit-jupiter-api - 5.6.0 + 5.6.2 test org.junit.jupiter junit-jupiter-params - 5.6.0 + 5.6.2 test org.junit.jupiter junit-jupiter-engine - 5.6.0 + 5.6.2 test org.slf4j slf4j-nop - 1.7.25 + 1.7.30 @@ -163,7 +169,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M5 + 3.0.0-M3 false From dc057a08e09f65a821606d45673eb53ddea88a14 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 14:04:41 +0800 Subject: [PATCH 61/92] No logic change, just make code easier to read. --- .../security/keyvault/jca/AuthClient.java | 116 +++++++----------- .../keyvault/jca/DelegateRestClient.java | 1 + .../keyvault/jca/LegacyRestClient.java | 38 +++--- .../security/keyvault/jca/RestClient.java | 1 + 4 files changed, 58 insertions(+), 98 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java index 91a5f3c1cf1b1..77e0c8659a8c0 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -1,10 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License./ + package com.azure.security.keyvault.jca; import com.azure.security.keyvault.jca.rest.OAuthToken; import java.util.HashMap; +import java.util.Optional; import java.util.logging.Logger; import static java.util.logging.Level.FINER; @@ -16,42 +18,6 @@ */ class AuthClient extends DelegateRestClient { - /** - * Stores the Client ID fragment. - */ - private static final String CLIENT_ID_FRAGMENT = "&client_id="; - - /** - * Stores the Client Secret fragment. - */ - private static final String CLIENT_SECRET_FRAGMENT = "&client_secret="; - - /** - * Stores the Grant Type fragment. - */ - private static final String GRANT_TYPE_FRAGMENT = "grant_type=client_credentials"; - - /** - * Stores the Resource fragment. - */ - private static final String RESOURCE_FRAGMENT = "&resource="; - - /** - * Stores the OAuth2 token base URL. - */ - private static final String OAUTH2_TOKEN_BASE_URL = "https://login.microsoftonline.com/"; - - /** - * Stores the OAuth2 token postfix. - */ - private static final String OAUTH2_TOKEN_POSTFIX = "/oauth2/token"; - - /** - * Stores the OAuth2 managed identity URL. - */ - private static final String OAUTH2_MANAGED_IDENTITY_TOKEN_URL - = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01"; - /** * Stores our logger. */ @@ -76,9 +42,12 @@ public AuthClient() { */ public String getAccessToken(String resource) { String result; - - if (System.getenv("WEBSITE_SITE_NAME") != null - && !System.getenv("WEBSITE_SITE_NAME").isEmpty()) { + boolean siteNameSet = Optional.of("WEBSITE_SITE_NAME") + .map(System::getenv) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .isPresent(); + if (siteNameSet) { result = getAccessTokenOnAppService(resource); } else { result = getAccessTokenOnOthers(resource); @@ -95,28 +64,33 @@ public String getAccessToken(String resource) { * @param clientSecret the client secret. * @return the authorization token. */ - public String getAccessToken(String resource, String tenantId, - String clientId, String clientSecret) { - LOGGER.entering("AuthClient", "getAccessToken", new Object[] { - resource, tenantId, clientId, clientSecret }); + public String getAccessToken(String resource, + String tenantId, + String clientId, + String clientSecret) { + LOGGER.entering( + "AuthClient", + "getAccessToken", + new Object[] { + resource, + tenantId, + clientId, + clientSecret + } + ); LOGGER.info("Getting access token using client ID / client secret"); String result = null; - - StringBuilder oauth2Url = new StringBuilder(); - oauth2Url.append(OAUTH2_TOKEN_BASE_URL) - .append(tenantId) - .append(OAUTH2_TOKEN_POSTFIX); - - StringBuilder requestBody = new StringBuilder(); - requestBody.append(GRANT_TYPE_FRAGMENT) - .append(CLIENT_ID_FRAGMENT).append(clientId) - .append(CLIENT_SECRET_FRAGMENT).append(clientSecret) - .append(RESOURCE_FRAGMENT).append(resource); - - String body = post(oauth2Url.toString(), requestBody.toString(), "application/x-www-form-urlencoded"); - if (body != null) { + String oauth2Url = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenantId); + String requestBody = String.format( + "grant_type=client_credentials&client_id=%s&client_secret=%s&resource=%s", + clientId, + clientSecret, + resource + ); + String response = post(oauth2Url, requestBody, "application/x-www-form-urlencoded"); + if (response != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); - OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); + OAuthToken token = (OAuthToken) converter.fromJson(response, OAuthToken.class); result = token.getAccess_token(); } LOGGER.log(FINER, "Access token: {0}", result); @@ -133,20 +107,14 @@ private String getAccessTokenOnAppService(String resource) { LOGGER.entering("AuthClient", "getAccessTokenOnAppService", resource); LOGGER.info("Getting access token using managed identity based on MSI_SECRET"); String result = null; - - StringBuilder url = new StringBuilder(); - url.append(System.getenv("MSI_ENDPOINT")) - .append("?api-version=2017-09-01") - .append(RESOURCE_FRAGMENT).append(resource); - HashMap headers = new HashMap<>(); headers.put("Metadata", "true"); headers.put("Secret", System.getenv("MSI_SECRET")); - String body = get(url.toString(), headers); - - if (body != null) { + String url = String.format("%s?api-version=2017-09-01&resource=%s", System.getenv("MSI_ENDPOINT"), resource); + String response = get(url, headers); + if (response != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); - OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); + OAuthToken token = (OAuthToken) converter.fromJson(response, OAuthToken.class); result = token.getAccess_token(); } LOGGER.exiting("AuthClient", "getAccessTokenOnAppService", result); @@ -163,15 +131,13 @@ private String getAccessTokenOnOthers(String resource) { LOGGER.entering("AuthClient", "getAccessTokenOnOthers", resource); LOGGER.info("Getting access token using managed identity"); String result = null; - - StringBuilder url = new StringBuilder(); - url.append(OAUTH2_MANAGED_IDENTITY_TOKEN_URL) - .append(RESOURCE_FRAGMENT).append(resource); - + String url = String.format( + "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=%s", + resource + ); HashMap headers = new HashMap<>(); headers.put("Metadata", "true"); - String body = get(url.toString(), headers); - + String body = get(url, headers); if (body != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java index 4a32d92af623d..b0402d3aea4a0 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import java.util.Map; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java index 2a21d6831e965..c4649d734ce60 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java @@ -35,21 +35,9 @@ public String get(String url, Map headers) { try (CloseableHttpClient client = HttpClients.createDefault()) { HttpGet httpGet = new HttpGet(url); if (headers != null) { - headers.entrySet().forEach(entry -> { - String key = entry.getKey(); - String value = entry.getValue(); - httpGet.addHeader(key, value); - }); + headers.forEach(httpGet::addHeader); } - HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { - int status = response.getCode(); - String result1 = null; - if (status >= 200 && status < 300) { - HttpEntity entity = response.getEntity(); - result1 = entity != null ? EntityUtils.toString(entity) : null; - } - return result1; - }; + HttpClientResponseHandler responseHandler = createHttpClientResponseHandler(); result = client.execute(httpGet, responseHandler); } catch (IOException ioe) { ioe.printStackTrace(); @@ -63,19 +51,23 @@ public String post(String url, String body, String contentType) { try (CloseableHttpClient client = HttpClients.createDefault()) { HttpPost httpPost = new HttpPost(url); httpPost.setEntity(HttpEntities.create(body, ContentType.create(contentType))); - HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { - int status = response.getCode(); - String result1 = null; - if (status >= 200 && status < 300) { - HttpEntity entity = response.getEntity(); - result1 = entity != null ? EntityUtils.toString(entity) : null; - } - return result1; - }; + HttpClientResponseHandler responseHandler = createHttpClientResponseHandler(); result = client.execute(httpPost, responseHandler); } catch (IOException ioe) { ioe.printStackTrace(); } return result; } + + private HttpClientResponseHandler createHttpClientResponseHandler() { + return (ClassicHttpResponse response) -> { + int status = response.getCode(); + String result = null; + if (status >= 200 && status < 300) { + HttpEntity entity = response.getEntity(); + result = entity != null ? EntityUtils.toString(entity) : null; + } + return result; + }; + } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java index 9572247fd8c2f..218558b7d5acf 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import java.util.Map; From 274b2ed08b5ad881c1316b2c2893a5798b0b3d9d Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 14:51:13 +0800 Subject: [PATCH 62/92] No logic change, just make code easier to read. --- .../keyvault/jca/JacksonJsonConverter.java | 1 + .../security/keyvault/jca/JsonConverter.java | 1 + .../keyvault/jca/JsonConverterFactory.java | 1 + .../keyvault/jca/KeyVaultCertificate.java | 1 + .../security/keyvault/jca/KeyVaultClient.java | 71 ++++++++----------- .../keyvault/jca/KeyVaultJcaProvider.java | 39 ++++++++-- .../keyvault/jca/KeyVaultKeyManager.java | 25 ++++--- .../jca/KeyVaultKeyManagerFactory.java | 18 ++--- 8 files changed, 89 insertions(+), 68 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java index 7e96e77209c92..3506f69bc5a6e 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java index 483481a563bba..049b7346881fd 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; /** diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java index 78dc09275ca80..acb43c6aec6ff 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; /** diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java index b42101ed7e43a..68c48dc5bda2a 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import java.math.BigInteger; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java index 4b77140aef6a4..96430e29aa85e 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java @@ -1,10 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import com.azure.security.keyvault.jca.rest.CertificateBundle; import com.azure.security.keyvault.jca.rest.CertificateItem; import com.azure.security.keyvault.jca.rest.CertificateListResult; +import com.azure.security.keyvault.jca.rest.CertificatePolicy; +import com.azure.security.keyvault.jca.rest.KeyProperties; import com.azure.security.keyvault.jca.rest.SecretBundle; import java.io.ByteArrayInputStream; @@ -24,6 +27,7 @@ import java.util.Base64; import java.util.HashMap; import java.util.List; +import java.util.Optional; import java.util.logging.Logger; import static java.util.logging.Level.INFO; @@ -49,7 +53,7 @@ class KeyVaultClient extends DelegateRestClient { /** * Stores the KeyVault URI. */ - private String keyVaultUri; + private final String keyVaultUri; /** * Stores the tenant ID. @@ -125,30 +129,22 @@ private String getAccessToken() { */ public List getAliases() { ArrayList result = new ArrayList<>(); - - StringBuilder url = new StringBuilder(); - url.append(keyVaultUri) - .append("certificates") - .append(API_VERSION_POSTFIX); - HashMap headers = new HashMap<>(); headers.put("Authorization", "Bearer " + getAccessToken()); - - String body = get(url.toString(), headers); - + String url = String.format("%scertificates%s", keyVaultUri, API_VERSION_POSTFIX); + String response = get(url, headers); CertificateListResult certificateListResult = null; - if (body != null) { + if (response != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); - certificateListResult = (CertificateListResult) converter.fromJson(body, CertificateListResult.class); + certificateListResult = (CertificateListResult) converter.fromJson(response, CertificateListResult.class); } if (certificateListResult != null && certificateListResult.getValue().size() > 0) { for (CertificateItem certificateItem : certificateListResult.getValue()) { - String alias = certificateItem.getId(); - alias = alias.substring(alias.indexOf("certificates") + "certificates".length() + 1); + String id = certificateItem.getId(); + String alias = id.substring(id.indexOf("certificates") + "certificates".length() + 1); result.add(alias); } } - return result; } @@ -160,23 +156,14 @@ public List getAliases() { */ private CertificateBundle getCertificateBundle(String alias) { CertificateBundle result = null; - - StringBuilder url = new StringBuilder(); - url.append(keyVaultUri) - .append("certificates/") - .append(alias) - .append(API_VERSION_POSTFIX); - HashMap headers = new HashMap<>(); headers.put("Authorization", "Bearer " + getAccessToken()); - - String body = get(url.toString(), headers); - - if (body != null) { + String url = String.format("%scertificates/%s%s", keyVaultUri, alias, API_VERSION_POSTFIX); + String response = get(url, headers); + if (response != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); - result = (CertificateBundle) converter.fromJson(body, CertificateBundle.class); + result = (CertificateBundle) converter.fromJson(response, CertificateBundle.class); } - return result; } @@ -197,8 +184,8 @@ public Certificate getCertificate(String alias) { try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); certificate = (X509Certificate) cf.generateCertificate( - new ByteArrayInputStream(Base64.getDecoder() - .decode(certificateBundle.getCer()))); + new ByteArrayInputStream(Base64.getDecoder().decode(certificateBundle.getCer())) + ); } catch (CertificateException ce) { LOGGER.log(WARNING, "Certificate error", ce); } @@ -220,16 +207,15 @@ public Key getKey(String alias, char[] password) { LOGGER.log(INFO, "Getting key for alias: {0}", alias); Key key = null; CertificateBundle certificateBundle = getCertificateBundle(alias); - if (certificateBundle != null - && certificateBundle.getPolicy() != null - && certificateBundle.getPolicy().getKey_props() != null - && certificateBundle.getPolicy().getKey_props().isExportable()) { - - // - // Because the certificate is exportable the private key is + boolean isExportable = Optional.ofNullable(certificateBundle) + .map(CertificateBundle::getPolicy) + .map(CertificatePolicy::getKey_props) + .map(KeyProperties::isExportable) + .orElse(false); + if (isExportable) { + // Because the certificate is exportable the private key is // available. So we'll use the KeyVault Secrets API to get the // private key. - // String certificateSecretUri = certificateBundle.getSid(); HashMap headers = new HashMap<>(); headers.put("Authorization", "Bearer " + getAccessToken()); @@ -237,11 +223,12 @@ public Key getKey(String alias, char[] password) { if (body != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); SecretBundle secretBundle = (SecretBundle) converter.fromJson(body, SecretBundle.class); - try { KeyStore keyStore = KeyStore.getInstance("PKCS12"); - keyStore.load(new ByteArrayInputStream( - Base64.getDecoder().decode(secretBundle.getValue())), "".toCharArray()); + keyStore.load( + new ByteArrayInputStream(Base64.getDecoder().decode(secretBundle.getValue())), + "".toCharArray() + ); alias = keyStore.aliases().nextElement(); key = keyStore.getKey(alias, "".toCharArray()); } catch (IOException | KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException ex) { @@ -249,11 +236,9 @@ public Key getKey(String alias, char[] password) { } } } else { - // // The private key is not available so the certificate cannot be // used for server side certificates or mTLS. Since we do not know // the intent of the usage at this stage we skip this key. - // } LOGGER.exiting("KeyVaultClient", "getKey", key); return key; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java index ad23f3f19d2ad..66eba3e4f847d 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java @@ -1,11 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.Provider; import java.util.Arrays; +import java.util.Collections; /** * The Azure KeyVault security provider. @@ -47,9 +49,16 @@ public KeyVaultJcaProvider() { */ private void initialize() { AccessController.doPrivileged((PrivilegedAction) () -> { - putService(new Provider.Service(this, "KeyManagerFactory", "SunX509", - KeyVaultKeyManagerFactory.class.getName(), - Arrays.asList("SunX509", "IbmX509"), null)); + putService( + new Provider.Service( + this, + "KeyManagerFactory", + "SunX509", + KeyVaultKeyManagerFactory.class.getName(), + Arrays.asList("SunX509", "IbmX509"), + null + ) + ); /* * Note for Tomcat we needed to add "DKS" as an algorithm so it does @@ -59,10 +68,26 @@ private void initialize() { * See SSLUtilBase.getKeyManagers and look for the * "DKS".equalsIgnoreCase(certificate.getCertificateKeystoreType() */ - putService(new Provider.Service(this, "KeyStore", "DKS", - KeyVaultKeyStore.class.getName(), Arrays.asList("DKS"), null)); - putService(new Provider.Service(this, "KeyStore", "AzureKeyVault", - KeyVaultKeyStore.class.getName(), Arrays.asList("AzureKeyVault"), null)); + putService( + new Provider.Service( + this, + "KeyStore", + "DKS", + KeyVaultKeyStore.class.getName(), + Collections.singletonList("DKS"), + null + ) + ); + putService( + new Provider.Service( + this, + "KeyStore", + "AzureKeyVault", + KeyVaultKeyStore.class.getName(), + Collections.singletonList("AzureKeyVault"), + null + ) + ); return null; }); } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java index 26075b6555885..ba1cf7d15203f 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import javax.net.ssl.X509ExtendedKeyManager; @@ -35,12 +36,12 @@ public class KeyVaultKeyManager extends X509ExtendedKeyManager { /** * Stores the keystore. */ - private KeyStore keystore; + private final KeyStore keystore; /** * Stores the password. */ - private char[] password; + private final char[] password; /** * Constructor. @@ -56,8 +57,11 @@ public KeyVaultKeyManager(KeyStore keystore, char[] password) { @Override public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { - LOGGER.entering("KeyVaultKeyManager", "chooseClientAlias", - new Object[] { keyType, issuers, socket }); + LOGGER.entering( + "KeyVaultKeyManager", + "chooseClientAlias", + new Object[] { keyType, issuers, socket } + ); String alias = null; try { /* @@ -77,8 +81,11 @@ public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket so @Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { - LOGGER.entering("KeyVaultKeyManager", "chooseServerAlias", - new Object[] { keyType, issuers, socket }); + LOGGER.entering( + "KeyVaultKeyManager", + "chooseServerAlias", + new Object[] { keyType, issuers, socket } + ); String alias = null; try { /* @@ -117,9 +124,9 @@ public X509Certificate[] getCertificateChain(String alias) { try { Certificate[] keystoreChain = keystore.getCertificateChain(alias); if (keystoreChain.length > 0) { - for (int i = 0; i < keystoreChain.length; i++) { - if (keystoreChain[i] instanceof X509Certificate) { - chain.add((X509Certificate) keystoreChain[i]); + for (Certificate certificate : keystoreChain) { + if (certificate instanceof X509Certificate) { + chain.add((X509Certificate) certificate); } } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java index 21b1ccd888ee1..156f3c15c4f02 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import javax.net.ssl.KeyManager; @@ -7,9 +8,6 @@ import javax.net.ssl.ManagerFactoryParameters; import java.security.InvalidAlgorithmParameterException; import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; @@ -29,19 +27,21 @@ public class KeyVaultKeyManagerFactory extends KeyManagerFactorySpi { /** * Stores the key managers. */ - private List keyManagers = new ArrayList<>(); + private final List keyManagers = new ArrayList<>(); @Override - protected void engineInit(KeyStore keystore, char[] password) throws KeyStoreException, NoSuchAlgorithmException, - UnrecoverableKeyException { - LOGGER.entering("KeyVaultKeyManagerFactory", "engineInit", - new Object[] { keystore, new String(password) }); + protected void engineInit(KeyStore keystore, char[] password) { + LOGGER.entering( + "KeyVaultKeyManagerFactory", + "engineInit", + new Object[] { keystore, new String(password) } + ); KeyVaultKeyManager manager = new KeyVaultKeyManager(keystore, password); keyManagers.add(manager); } @Override - protected void engineInit(ManagerFactoryParameters spec) throws InvalidAlgorithmParameterException { + protected void engineInit(ManagerFactoryParameters spec) { } @Override From 4d6a973b6bdcc9c6030068ed47245ef37f53aaa4 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 15:05:22 +0800 Subject: [PATCH 63/92] No logic change, just make code easier to read. --- .../security/keyvault/jca/AuthClient.java | 6 ++--- .../keyvault/jca/KeyVaultKeyStore.java | 26 ++++++++----------- .../jca/KeyVaultLoadStoreParameter.java | 1 + .../keyvault/jca/KeyVaultTrustManager.java | 1 + .../jca/KeyVaultTrustManagerFactory.java | 7 ++--- .../KeyVaultTrustManagerFactoryProvider.java | 14 +++++++--- .../keyvault/jca/rest/CertificateBundle.java | 1 + .../keyvault/jca/rest/CertificateItem.java | 1 + .../jca/rest/CertificateListResult.java | 1 + .../keyvault/jca/rest/CertificatePolicy.java | 1 + .../keyvault/jca/rest/KeyProperties.java | 1 + .../keyvault/jca/rest/OAuthToken.java | 11 ++++---- 12 files changed, 42 insertions(+), 29 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java index 77e0c8659a8c0..d96c7943a4ffd 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -91,7 +91,7 @@ public String getAccessToken(String resource, if (response != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); OAuthToken token = (OAuthToken) converter.fromJson(response, OAuthToken.class); - result = token.getAccess_token(); + result = token.getAccessToken(); } LOGGER.log(FINER, "Access token: {0}", result); return result; @@ -115,7 +115,7 @@ private String getAccessTokenOnAppService(String resource) { if (response != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); OAuthToken token = (OAuthToken) converter.fromJson(response, OAuthToken.class); - result = token.getAccess_token(); + result = token.getAccessToken(); } LOGGER.exiting("AuthClient", "getAccessTokenOnAppService", result); return result; @@ -141,7 +141,7 @@ private String getAccessTokenOnOthers(String resource) { if (body != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); - result = token.getAccess_token(); + result = token.getAccessToken(); } LOGGER.exiting("AuthClient", "getAccessTokenOnOthers", result); return result; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java index 56df9f1642901..6069094d11e56 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import java.io.BufferedReader; @@ -15,7 +16,6 @@ import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableEntryException; -import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; @@ -102,7 +102,7 @@ public boolean engineContainsAlias(String alias) { } @Override - public void engineDeleteEntry(String alias) throws KeyStoreException { + public void engineDeleteEntry(String alias) { } @Override @@ -167,7 +167,7 @@ public KeyStore.Entry engineGetEntry(String alias, KeyStore.ProtectionParameter } @Override - public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { + public Key engineGetKey(String alias, char[] password) { Key key; if (certificateKeys.containsKey(alias)) { key = certificateKeys.get(alias); @@ -197,8 +197,7 @@ public boolean engineIsKeyEntry(String alias) { } @Override - public void engineLoad(KeyStore.LoadStoreParameter param) throws IOException, NoSuchAlgorithmException, - CertificateException { + public void engineLoad(KeyStore.LoadStoreParameter param) { if (param instanceof KeyVaultLoadStoreParameter) { KeyVaultLoadStoreParameter parameter = (KeyVaultLoadStoreParameter) param; keyVault = new KeyVaultClient( @@ -211,13 +210,12 @@ public void engineLoad(KeyStore.LoadStoreParameter param) throws IOException, No } @Override - public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, - CertificateException { + public void engineLoad(InputStream stream, char[] password) { sideLoad(); } @Override - public void engineSetCertificateEntry(String alias, Certificate certificate) throws KeyStoreException { + public void engineSetCertificateEntry(String alias, Certificate certificate) { if (aliases == null) { aliases = keyVault.getAliases(); } @@ -233,11 +231,11 @@ public void engineSetEntry(String alias, KeyStore.Entry entry, KeyStore.Protecti } @Override - public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { + public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) { } @Override - public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException { + public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) { } @Override @@ -246,13 +244,11 @@ public int engineSize() { } @Override - public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, - CertificateException { + public void engineStore(OutputStream stream, char[] password) { } @Override - public void engineStore(KeyStore.LoadStoreParameter param) throws IOException, NoSuchAlgorithmException, - CertificateException { + public void engineStore(KeyStore.LoadStoreParameter param) { } /** @@ -317,7 +313,7 @@ private void sideLoad() { engineSetCertificateEntry(alias, certificate); LOGGER.log(INFO, "Side loaded certificate: {0} from: {1}", new Object[] { alias, filename }); - } catch (KeyStoreException | CertificateException e) { + } catch (CertificateException e) { LOGGER.log(WARNING, "Unable to side-load certificate", e); } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java index bb35f082b060d..c3c0c8a40621f 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import java.security.KeyStore; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java index 0f8e4f610fb4e..beea6a4641ff0 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import javax.net.ssl.TrustManagerFactory; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java index 81cccec5f0932..d517102313dc5 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import javax.net.ssl.ManagerFactoryParameters; @@ -27,16 +28,16 @@ public class KeyVaultTrustManagerFactory extends TrustManagerFactorySpi { /** * Stores the key managers. */ - private List trustManagers = new ArrayList<>(); + private final List trustManagers = new ArrayList<>(); @Override - protected void engineInit(KeyStore keystore) throws KeyStoreException { + protected void engineInit(KeyStore keystore) { LOGGER.entering("KeyVaultKeyManagerFactory", "engineInit", keystore); trustManagers.add(new KeyVaultTrustManager(keystore)); } @Override - protected void engineInit(ManagerFactoryParameters spec) throws InvalidAlgorithmParameterException { + protected void engineInit(ManagerFactoryParameters spec) { LOGGER.entering("KeyVaultKeyManagerFactory", "engineInit", spec); } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java index 34a0197d24cbb..09efb3f8d3fdd 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import java.security.AccessController; @@ -46,9 +47,16 @@ public KeyVaultTrustManagerFactoryProvider() { */ private void initialize() { AccessController.doPrivileged((PrivilegedAction) () -> { - putService(new Provider.Service(this, "TrustManagerFactory", "PKIX", - KeyVaultTrustManagerFactory.class.getName(), - null, null)); + putService( + new Provider.Service( + this, + "TrustManagerFactory", + "PKIX", + KeyVaultTrustManagerFactory.class.getName(), + null, + null + ) + ); return null; }); } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java index 4f69008d363d6..52eb043861123 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca.rest; import java.io.Serializable; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java index 92a09a4932106..a3d4c7ddb5906 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca.rest; import java.io.Serializable; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java index 97210624cfd62..bb64cb7b4d37b 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca.rest; import java.io.Serializable; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java index b520cb8f200f6..37f0eb540b467 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca.rest; import java.io.Serializable; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java index 4e0ef2a635ba8..3a5b4a9eb385b 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca.rest; import java.io.Serializable; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java index ec310f9b9163f..c3450519b0760 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca.rest; import java.io.Serializable; @@ -14,15 +15,15 @@ public class OAuthToken implements Serializable { /** * Stores the access token. */ - private String access_token; + private String accessToken; /** * Get the access token. * * @return the access token. */ - public String getAccess_token() { - return access_token; + public String getAccessToken() { + return accessToken; } /** @@ -30,7 +31,7 @@ public String getAccess_token() { * * @param accessToken the access token. */ - public void setAccess_token(String accessToken) { - this.access_token = accessToken; + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; } } From 4f0dbadd0ac19c90191332f04154357deb48445a Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 15:11:19 +0800 Subject: [PATCH 64/92] No logic change, just make code easier to read. --- .../com/azure/security/keyvault/jca/LegacyRestClient.java | 1 + .../azure/security/keyvault/jca/RestClientFactory.java | 1 + .../azure/security/keyvault/jca/rest/SecretBundle.java | 1 + .../com/azure/security/keyvault/jca/AuthClientTest.java | 8 ++++++-- .../security/keyvault/jca/DelegateRestClientTest.java | 1 + .../security/keyvault/jca/JacksonJsonConverterTest.java | 1 + .../security/keyvault/jca/KeyVaultCertificateTest.java | 1 + .../security/keyvault/jca/KeyVaultJcaProviderTest.java | 1 + .../azure/security/keyvault/jca/KeyVaultKeyStoreTest.java | 1 + .../keyvault/jca/KeyVaultLoadStoreParameterTest.java | 1 + .../azure/security/keyvault/jca/LegacyRestClientTest.java | 1 + .../security/keyvault/jca/RestClientFactoryTest.java | 1 + .../com/azure/security/keyvault/jca/ServerSocketTest.java | 1 + 13 files changed, 18 insertions(+), 2 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java index c4649d734ce60..1f970a5938dee 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import org.apache.hc.client5.http.classic.methods.HttpGet; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java index 24e23e9db6d21..7989e661c360a 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; /** diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java index 4d88a6d969831..301acf9eff3f6 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca.rest; import java.io.Serializable; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java index c5cc3c247d942..c77edab012510 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/AuthClientTest.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import org.junit.jupiter.api.Test; @@ -25,8 +26,11 @@ public void testGetAuthorizationToken() throws Exception { String clientSecret = "72-~tZ9~cG~rimDI0EkQSMQ1D9DYmGmI_I"; AuthClient authClient = new AuthClient(); String result = authClient.getAccessToken( - "https://management.azure.com/", tenantId, clientId, - URLEncoder.encode(clientSecret, "UTF-8")); + "https://management.azure.com/", + tenantId, + clientId, + URLEncoder.encode(clientSecret, "UTF-8") + ); assertNotNull(result); } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java index 8e62c8b5355cd..94d534680dfe8 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/DelegateRestClientTest.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import org.junit.jupiter.api.Test; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java index 85189eedb5180..5ad5273d2f7dc 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/JacksonJsonConverterTest.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import com.azure.security.keyvault.jca.rest.CertificateBundle; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java index 615f361c0ea38..53532c9e2d15b 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import org.junit.jupiter.api.BeforeEach; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java index bfa9add11b0d5..7940baa2c9170 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultJcaProviderTest.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import org.junit.jupiter.api.Test; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java index cf0751b3bd034..be7fbfe6adc4f 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import org.junit.jupiter.api.Test; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java index 49632d092df5d..1ba91bd622033 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import org.junit.jupiter.api.Test; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java index 322f41b56cd76..730a6867f19eb 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/LegacyRestClientTest.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import org.junit.jupiter.api.Test; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java index a9923ced3aad5..c99550db7609e 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/RestClientFactoryTest.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import org.junit.jupiter.api.Test; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java index 766be028bff6f..7de8f6d00b56b 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.security.keyvault.jca; import org.apache.hc.client5.http.classic.methods.HttpGet; From 67bdb82b6e1c35ebb0d6f8359444e552310913d4 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 15:32:58 +0800 Subject: [PATCH 65/92] No logic change, just make code easier to read. --- .../keyvault/jca/KeyVaultCertificateTest.java | 12 +-- .../keyvault/jca/KeyVaultKeyStoreTest.java | 97 +++---------------- .../jca/KeyVaultLoadStoreParameterTest.java | 6 +- .../keyvault/jca/ServerSocketTest.java | 16 +-- 4 files changed, 29 insertions(+), 102 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java index 53532c9e2d15b..ee521e308f080 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultCertificateTest.java @@ -20,6 +20,7 @@ import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.util.Base64; +import java.util.Calendar; import java.util.Date; import java.util.Set; @@ -69,10 +70,9 @@ public class KeyVaultCertificateTest { /** * Setup before each test. * - * @throws Exception when an exception occurs. */ @BeforeEach - public void setUp() throws Exception { + public void setUp() { try { byte[] certificateBytes = Base64.getDecoder().decode(TEST_CERTIFICATE); CertificateFactory cf = CertificateFactory.getInstance("X.509"); @@ -102,11 +102,11 @@ public void testCheckValidity() { public void testCheckValidity2() { try { KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); - certificate.checkValidity(new Date(100, 1, 1)); + certificate.checkValidity(new Date(100, Calendar.FEBRUARY, 1)); fail(); } catch (CertificateExpiredException ex) { fail(); - } catch (CertificateNotYetValidException cnyve) { + } catch (CertificateNotYetValidException exception) { // expecting this as the TEST_CERTIFICATE is not valid against given date. } } @@ -118,8 +118,8 @@ public void testCheckValidity2() { public void testCheckValidity3() { try { KeyVaultCertificate certificate = new KeyVaultCertificate(x509Certificate); - certificate.checkValidity(new Date(200, 1, 1)); - } catch (CertificateExpiredException | CertificateNotYetValidException cnyve) { + certificate.checkValidity(new Date(200, Calendar.FEBRUARY, 1)); + } catch (CertificateExpiredException | CertificateNotYetValidException exception) { fail(); } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java index be7fbfe6adc4f..1d016bf85f0ae 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreTest.java @@ -48,13 +48,8 @@ public class KeyVaultKeyStoreTest { + "U/aIAdQRfDaSE9jhtcVu5d5kCgBs7nz5AzeCisDPo5zIt4Mxej3iVaAJ79oEbHOE" + "p192KLXLV/pscA4Wgb+PJ8AAEa5B6xq8p9JO+Q=="; - /** - * Test engineGetCertificate method. - * - * @throws Exception when a serious error occurs. - */ @Test - public void testEngineGetCertificate() throws Exception { + public void testEngineGetCertificate() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( System.getProperty("azure.keyvault.uri"), @@ -65,13 +60,8 @@ public void testEngineGetCertificate() throws Exception { assertNull(keystore.engineGetCertificate("myalias")); } - /** - * Test engineGetCertificateAlias method. - * - * @throws Exception when an error occurs. - */ @Test - public void testEngineGetCertificateAlias() throws Exception { + public void testEngineGetCertificateAlias() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( System.getProperty("azure.keyvault.uri"), @@ -82,13 +72,8 @@ public void testEngineGetCertificateAlias() throws Exception { assertNull(keystore.engineGetCertificateAlias(null)); } - /** - * Test engineGetCertificateChain method. - * - * @throws Exception when an error occurs. - */ @Test - public void testEngineGetCertificateChain() throws Exception { + public void testEngineGetCertificateChain() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( System.getProperty("azure.keyvault.uri"), @@ -99,13 +84,8 @@ public void testEngineGetCertificateChain() throws Exception { assertNull(keystore.engineGetCertificateChain("myalias")); } - /** - * Test engineIsCertificateEntry method. - * - * @throws Exception when an error occurs. - */ @Test - public void testEngineIsCertificateEntry() throws Exception { + public void testEngineIsCertificateEntry() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( System.getProperty("azure.keyvault.uri"), @@ -116,13 +96,8 @@ public void testEngineIsCertificateEntry() throws Exception { assertFalse(keystore.engineIsCertificateEntry("myalias")); } - /** - * Test engineSetCertificateEntry method. - * - * @throws Exception when a serious error occurs. - */ @Test - public void testEngineSetCertificateEntry() throws Exception { + public void testEngineSetCertificateEntry() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( System.getProperty("azure.keyvault.uri"), @@ -145,13 +120,8 @@ public void testEngineSetCertificateEntry() throws Exception { assertNotNull(keystore.engineGetCertificate("setcert")); } - /** - * Test engineGetKey method. - * - * @throws Exception when an error occurs. - */ @Test - public void testEngineGetKey() throws Exception { + public void testEngineGetKey() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( System.getProperty("azure.keyvault.uri"), @@ -162,13 +132,8 @@ public void testEngineGetKey() throws Exception { assertNull(keystore.engineGetKey("myalias", null)); } - /** - * Test engineIsKeyEntry method. - * - * @throws Exception when an error occurs. - */ @Test - public void testEngineIsKeyEntry() throws Exception { + public void testEngineIsKeyEntry() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( System.getProperty("azure.keyvault.uri"), @@ -179,35 +144,20 @@ public void testEngineIsKeyEntry() throws Exception { assertFalse(keystore.engineIsKeyEntry("myalias")); } - /** - * Test engineSetKeyEntry method. - * - * @throws Exception when a serious error occurs. - */ @Test - public void testEngineSetKeyEntry() throws Exception { + public void testEngineSetKeyEntry() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); keystore.engineSetKeyEntry("myalias", null, null); } - /** - * Test engineSetKeyEntry method. - * - * @throws Exception when an error occurs. - */ @Test - public void testEngineSetKeyEntry2() throws Exception { + public void testEngineSetKeyEntry2() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); keystore.engineSetKeyEntry("myalias", null, null, null); } - /** - * Test engineAliases method. - * - * @throws Exception when a serious error occurs. - */ @Test - public void testEngineAliases() throws Exception { + public void testEngineAliases() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( System.getProperty("azure.keyvault.uri"), @@ -218,13 +168,8 @@ public void testEngineAliases() throws Exception { assertTrue(keystore.engineAliases().hasMoreElements()); } - /** - * Test engineContainsAlias method. - * - * @throws Exception when an error occurs. - */ @Test - public void testEngineContainsAlias() throws Exception { + public void testEngineContainsAlias() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( System.getProperty("azure.keyvault.uri"), @@ -235,42 +180,26 @@ public void testEngineContainsAlias() throws Exception { assertFalse(keystore.engineContainsAlias("myalias")); } - /** - * Test engineGetCretionDate method. - */ @Test public void testEngineGetCreationDate() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); assertNotNull(keystore.engineGetCreationDate("myalias")); } - /** - * Test engineDeleteEntry method. - * - * @throws Exception when a serious error occurs. - */ @Test - public void testEngineDeleteEntry() throws Exception { + public void testEngineDeleteEntry() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); keystore.engineDeleteEntry("myalias"); } - /** - * Test engineSize method. - */ @Test public void testEngineSize() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); assertTrue(keystore.engineSize() >= 0); } - /** - * Test engineStore method. - * - * @throws Exception when an error occurs. - */ @Test - public void testEngineStore() throws Exception { + public void testEngineStore() { KeyVaultKeyStore keystore = new KeyVaultKeyStore(); keystore.engineStore(null, null); } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java index 1ba91bd622033..727dca026e328 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameterTest.java @@ -20,7 +20,11 @@ public class KeyVaultLoadStoreParameterTest { @Test public void testGetProtectionParameter() { KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( - System.getProperty("azure.keyvault.uri"), null, null, null); + System.getProperty("azure.keyvault.uri"), + null, + null, + null + ); assertNull(parameter.getProtectionParameter()); } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java index 7de8f6d00b56b..4b2f4c1e9f50e 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/ServerSocketTest.java @@ -72,7 +72,7 @@ public void testServerSocket() throws Exception { SSLContext context = SSLContext.getInstance("TLS"); context.init(kmf.getKeyManagers(), null, null); - SSLServerSocketFactory factory = (SSLServerSocketFactory) context.getServerSocketFactory(); + SSLServerSocketFactory factory = context.getServerSocketFactory(); SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(8765); Thread server = new Thread(() -> { @@ -101,17 +101,13 @@ public void testServerSocket() throws Exception { SSLContext sslContext = SSLContexts .custom() - .loadTrustMaterial((final X509Certificate[] chain, final String authType) -> { - return true; - }) + .loadTrustMaterial((final X509Certificate[] chain, final String authType) -> true) .build(); SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder .create() .setSslContext(sslContext) - .setHostnameVerifier((hostname, session) -> { - return true; - }) + .setHostnameVerifier((hostname, session) -> true) .build(); PoolingHttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder @@ -181,7 +177,7 @@ public void testServerSocketWithSelfSignedClientTrust() throws Exception { SSLContext context = SSLContext.getInstance("TLS"); context.init(kmf.getKeyManagers(), null, null); - SSLServerSocketFactory factory = (SSLServerSocketFactory) context.getServerSocketFactory(); + SSLServerSocketFactory factory = context.getServerSocketFactory(); SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(8766); Thread server = new Thread(() -> { @@ -216,9 +212,7 @@ public void testServerSocketWithSelfSignedClientTrust() throws Exception { SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder .create() .setSslContext(sslContext) - .setHostnameVerifier((hostname, session) -> { - return true; - }) + .setHostnameVerifier((hostname, session) -> true) .build(); PoolingHttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder From bdd4047ed6747eb8bfb09cc20fe4fd416a7e3d90 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 15:38:13 +0800 Subject: [PATCH 66/92] Delete unused files. --- .../.gitignore | 33 -- .../.mvn/wrapper/MavenWrapperDownloader.java | 118 ------- .../.mvn/wrapper/maven-wrapper.jar | Bin 50710 -> 0 bytes .../.mvn/wrapper/maven-wrapper.properties | 2 - .../Dockerfile | 3 - .../mvnw | 310 ------------------ .../mvnw.cmd | 182 ---------- 7 files changed, 648 deletions(-) delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.gitignore delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.jar delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.properties delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile delete mode 100755 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw delete mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw.cmd diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.gitignore b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.gitignore deleted file mode 100644 index 549e00a2a96fa..0000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -HELP.md -target/ -!.mvn/wrapper/maven-wrapper.jar -!**/src/main/**/target/ -!**/src/test/**/target/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -build/ -!**/src/main/**/build/ -!**/src/test/**/build/ - -### VS Code ### -.vscode/ diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index 42c7d2138dd2b..0000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.6"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to use instead of the - * default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if (mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if (mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if (!outputFile.getParentFile().exists()) { - if (!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.jar b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50710 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 EfAhh=DF6Tf diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 642d572ce90e5..0000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,2 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile deleted file mode 100644 index 091170acf8810..0000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM mcr.microsoft.com/java/jdk:8-zulu-centos -ADD target/app.jar . -CMD java -jar app.jar diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw deleted file mode 100755 index a16b5431b4c3c..0000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw +++ /dev/null @@ -1,310 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw.cmd b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw.cmd deleted file mode 100644 index c8d43372c986d..0000000000000 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/mvnw.cmd +++ /dev/null @@ -1,182 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% From 6867d33121ae8521811d5e081af1ce892e10f98b Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 15:42:19 +0800 Subject: [PATCH 67/92] No logic change. --- .../certificates/sample/SampleApplication.java | 1 + .../certificates/sample/SampleController.java | 1 + .../src/main/resources/application.properties | 18 ------------------ 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleApplication.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleApplication.java index 9affcf1e69155..ced3662722399 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleApplication.java +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleApplication.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.spring.security.keyvault.certificates.sample; import org.springframework.boot.SpringApplication; diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleController.java b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleController.java index be05dd5644af7..e6bb798fc3632 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleController.java +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/sample/SampleController.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.spring.security.keyvault.certificates.sample; import org.springframework.web.bind.annotation.GetMapping; diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties index aa139496fa7a8..932545d08d837 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/src/main/resources/application.properties @@ -1,41 +1,23 @@ -# # The URI to the Azure KeyVault used -# azure.keyvault.uri=${AZURE_KEYVAULT_URI} -# # The alias corresponding to the certificate in Azure KeyVault. -# server.ssl.key-alias=${SERVER_SSL_KEY_ALIAS} -# # The keystore type that enables the use of Azure KeyVault for your server-side # SSL certificate. -# server.ssl.key-store-type=AzureKeyVault -# # The truststore type that enables the use of Azure KeyVault for trusted # certificates, a.k.a the ones you trust when making an outbound SSL connection -# # server.ssl.trust-store-type=AzureKeyVault -# # The Tenant ID for your Azure KeyVault (needed if you are not using managed # identity). -# azure.keyvault.tenantId=${AZURE_KEYVAULT_TENTANT_ID} -# # The Client ID that has been setup with access to your Azure KeyVault (needed # if you are not using managed identity). -# azure.keyvault.clientId=${AZURE_KEYVAULT_CLIENT_ID} -# # The Client Secret that will be used for accessing your Azure KeyVault (needed # if you are not using managed identity). -# azure.keyvault.clientSecret=${AZURE_KEYVAULT_CLIENT_SECRET} -# # The server port. -# server.port=8443 -# # Just for debugging purposes. -# management.endpoints.web.exposure.include=* From 8a2ab04a2ae4432597ed21e459610498456b0078 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 15:46:06 +0800 Subject: [PATCH 68/92] Update release version and current version of 'azure-spring-boot-starter-keyvault-certificates'. --- eng/versioning/version_client.txt | 2 +- .../azure-spring-boot-sample-keyvault-certificates/pom.xml | 2 +- .../CHANGELOG.md | 2 +- .../azure-spring-boot-starter-keyvault-certificates/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/versioning/version_client.txt b/eng/versioning/version_client.txt index d27edb9fb7814..28416cfa959d8 100644 --- a/eng/versioning/version_client.txt +++ b/eng/versioning/version_client.txt @@ -66,7 +66,7 @@ com.azure.spring:azure-spring-boot-starter-active-directory-b2c;3.0.0-beta.1;3.0 com.azure.spring:azure-spring-boot-starter-active-directory;3.0.0-beta.1;3.0.0-beta.1 com.azure.spring:azure-spring-boot-starter-cosmos;3.0.0-beta.1;3.0.0-beta.1 com.azure.spring:azure-spring-boot-starter-data-gremlin;3.0.0-beta.1;3.0.0-beta.1 -com.azure.spring:azure-spring-boot-starter-keyvault-certificates;3.0.0-beta.1;3.0.0-beta.1 +com.azure.spring:azure-spring-boot-starter-keyvault-certificates;2.4.0-beta.1;2.3.3 com.azure.spring:azure-spring-boot-starter-keyvault-secrets;3.0.0-beta.1;3.0.0-beta.1 com.azure.spring:azure-spring-boot-starter-metrics;3.0.0-beta.1;3.0.0-beta.1 com.azure.spring:azure-spring-boot-starter-servicebus-jms;3.0.0-beta.1;3.0.0-beta.1 diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml index e92be03a9290d..ce9f3a063405a 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml @@ -83,7 +83,7 @@ com.azure azure-spring-boot-starter-keyvault-certificates - 3.0.0-beta.1 + 2.4.0-beta.1 org.springframework.boot diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md index 6456f7f08de9c..2e1ccf5fe5f0b 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md @@ -6,7 +6,7 @@ ## 2.3.3 (2020-08-13) _New Features_ - Support connection to multiple Key Vault from a single application configuration file -- Support case sensitive keys in Key Vault +- Support case-sensitive keys in Key Vault - Key Vault Spring Boot Actuator _Improved_ diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index cfa81e01ce92b..c8b8332fc8b7f 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -13,7 +13,7 @@ --> com.azure azure-spring-boot-starter-keyvault-certificates - 3.0.0-beta.1 + 2.4.0-beta.1 Azure Key Vault Certificates Spring Boot Starter Spring Boot Starter supporting Azure Key Vault Certificates From 3f8c15216655c55fa1f62f70fb7d1765c93e4d9a Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 15:52:43 +0800 Subject: [PATCH 69/92] Update README.md. --- .../README.md | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 2a438c1aff837..ed11f29a5f548 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -4,7 +4,7 @@ ### Using a managed identity -To use the starter for server side SSL you will need to add the following to +To use the starter for server side SSL, you will need to add the following to your application.properties (if the application is using Spring Cloud Config Server for its configuration add it to the bootstrap.yml of the application) @@ -14,7 +14,7 @@ server.ssl.key-alias= server.ssl.key-store-type=AzureKeyVault ``` -Note make sure the managed identity has access to the Azure KeyVault to access +Note: make sure the managed identity has access to the Azure KeyVault to access keys, secrets and certificates. Add then add the following Maven dependency to your POM file. @@ -28,7 +28,7 @@ Add then add the following Maven dependency to your POM file. ### Using a client ID and client secret -To use the starter for server side SSL you will need to add the following to +To use the starter for server side SSL, you will need to add the following to your application.properties (if the application is using Spring Cloud Config Server for its configuration add it to the bootstrap.yml of the application) @@ -41,7 +41,7 @@ server.ssl.key-alias= server.ssl.key-store-type=AzureKeyVault ``` -Note make sure the client ID has access to the Azure KeyVault to access +Note: make sure the client ID has access to the Azure KeyVault to access keys, secrets and certificates. Add then add the following Maven dependency to your POM file. @@ -57,14 +57,14 @@ Add then add the following Maven dependency to your POM file. ### Using a managed identity -To use the starter for client side SSL you will need to add the following to +To use the starter for client side SSL, you will need to add the following to your application.properties (if the application is using Spring Cloud Config Server for its configuration add it to the bootstrap.yml of the application) ``` azure.keyvault.uri= ``` -Note make sure the managed identity has access to the Azure KeyVault to access +Note: make sure the managed identity has access to the Azure KeyVault to access keys, secrets and certificates. Add then add the following Maven dependency to your POM file. @@ -76,7 +76,7 @@ Add then add the following Maven dependency to your POM file. ``` -And if you are using RestTemplate use code similar to the example below. +If you are using RestTemplate use code similar to the example below. ```java @Bean @@ -103,7 +103,7 @@ And if you are using RestTemplate use code similar to the example below. ### Using a client ID and client secret -To use the starter for client side SSL you will need to add the following to +To use the starter for client side SSL, you will need to add the following to your application.properties (if the application is using Spring Cloud Config Server for its configuration add it to the bootstrap.yml of the application) @@ -114,7 +114,7 @@ azure.keyvault.clientId= azure.keyvault.clientSecret= ``` -Note make sure the client ID has access to the Azure KeyVault to access +Note: make sure the client ID has access to the Azure KeyVault to access keys, secrets and certificates. Add then add the following Maven dependency to your POM file. @@ -126,7 +126,7 @@ Add then add the following Maven dependency to your POM file. ``` -And then if you are using RestTemplate use the code below as a starting +Then if you are using RestTemplate use the code below as a starting point: ```java @@ -166,7 +166,7 @@ azure: overrideTrustManagerFactory: true ``` -Note if any of your routes point to a service where the FQDN does not match the +Note: if any of your routes point to a service where the FQDN does not match the issued certificate you will need to disable hostname verification. This will be the case if your service is dynamically assigned a hostname by the hosting platform you use. In this particular case add the configuration below to disable @@ -179,7 +179,7 @@ azure: disableHostnameVerification: true ``` -If you are developing you can completely disable certificate and hostname +If you are developing you can completely disable the certificate and hostname validation altogether by using the configuration below. Note this is NOT recommended for production! @@ -242,11 +242,11 @@ the application. To side-load add your certificates to the `src/main/resources/keyvault` folder. -Note the alias (certificate name) is constructed from the filename of the +Notes: +1. The alias (certificate name) is constructed from the filename of the certificate (minus the extension). So if your filename is `mycert.x509` the certificate will be added with the alias of `mycert`. - -Be aware that certificates coming from Azure KeyVault take precedence over +2. Certificates coming from Azure KeyVault take precedence over side-loaded certificates. ## Testing the current version under development From 74306ece6b01047ec828e3d51307a5751e7d2085 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 16:04:58 +0800 Subject: [PATCH 70/92] 1. Set azure-security-keyvault-jca's version to 1.0.0-beta.1. 2. Set parent for azure-spring-boot-starter-keyvault-certificates. --- eng/versioning/version_client.txt | 1 + .../azure-security-keyvault-jca/pom.xml | 2 +- .../pom.xml | 18 +++++++++--------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/eng/versioning/version_client.txt b/eng/versioning/version_client.txt index 28416cfa959d8..07ba100b072a1 100644 --- a/eng/versioning/version_client.txt +++ b/eng/versioning/version_client.txt @@ -45,6 +45,7 @@ com.azure:azure-search-documents;11.1.1;11.2.0-beta.3 com.azure:azure-search-perf;1.0.0-beta.1;1.0.0-beta.1 com.azure:azure-security-keyvault-administration;4.0.0-beta.2;4.0.0-beta.3 com.azure:azure-security-keyvault-certificates;4.1.2;4.2.0-beta.3 +com.azure:azure-security-keyvault-jca;1.0.0-beta.1;1.0.0-beta.1 com.azure:azure-security-keyvault-keys;4.2.2;4.3.0-beta.3 com.azure:azure-security-keyvault-secrets;4.2.2;4.3.0-beta.3 com.azure:azure-sdk-template;1.2.1-beta.2;1.2.1-beta.16 diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index ac332cfd7629f..022c005b01e6f 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -12,7 +12,7 @@ com.azure azure-security-keyvault-jca - 1.0.0 + 1.0.0-beta.1 JCA Provider for Azure Key Vault The Java Crypto Architecture (JCA) Provider for Azure KeyVault diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index c8b8332fc8b7f..e131217a9d1fa 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -3,14 +3,14 @@ xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - + ../../parents/azure-client-sdk-parent - --> + com.azure azure-spring-boot-starter-keyvault-certificates 2.4.0-beta.1 @@ -23,17 +23,17 @@ org.springframework.boot spring-boot-starter - 2.3.3.RELEASE + 2.3.3.RELEASE org.springframework.boot spring-boot-starter-validation - 2.3.3.RELEASE + 2.3.3.RELEASE com.azure azure-security-keyvault-jca - 1.0.0 + 1.0.0-beta.1 From 039d92ca5049fb1bd017bd49c05a8500febac1ae Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 16:19:20 +0800 Subject: [PATCH 71/92] No logic change. --- ...tCertificatesEnvironmentPostProcessor.java | 129 +++++++----------- 1 file changed, 53 insertions(+), 76 deletions(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index d046018749834..ba710a78ef58c 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -1,15 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.azure.spring.security.keyvault.certificates.starter; import com.azure.security.keyvault.jca.KeyVaultJcaProvider; import com.azure.security.keyvault.jca.KeyVaultTrustManagerFactoryProvider; - -import java.security.Security; -import java.util.Properties; -import java.util.logging.Logger; -import javax.net.ssl.HttpsURLConnection; - import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.annotation.Order; @@ -18,9 +13,14 @@ import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.env.PropertySource; -import static org.springframework.core.Ordered.LOWEST_PRECEDENCE; +import javax.net.ssl.HttpsURLConnection; +import java.security.Security; +import java.util.Optional; +import java.util.Properties; +import java.util.logging.Logger; +import java.util.stream.Stream; -@Order(LOWEST_PRECEDENCE) +@Order public class KeyVaultCertificatesEnvironmentPostProcessor implements EnvironmentPostProcessor { /** @@ -31,79 +31,56 @@ public class KeyVaultCertificatesEnvironmentPostProcessor implements Environment @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - + if (environment.getProperty("azure.keyvault.uri") == null) { + return; + } Properties systemProperties = System.getProperties(); - - String uri = environment.getProperty("azure.keyvault.uri"); - if (uri != null) { - systemProperties.put("azure.keyvault.uri", uri); - - String tenantId = environment.getProperty("azure.keyvault.tenantId"); - if (tenantId != null) { - systemProperties.put("azure.keyvault.tenantId", tenantId); - } - - String clientId = environment.getProperty("azure.keyvault.clientId"); - if (clientId != null) { - systemProperties.put("azure.keyvault.clientId", clientId); + Stream.of("uri", "tenantId", "clientId", "clientSecret") + .forEach(key -> { + String property = "azure.keyvault." + key; + Optional.of(property) + .map(environment::getProperty) + .ifPresent(value -> systemProperties.put(property, value)); + }); + String keyStoreType = environment.getProperty("server.ssl.key-store-type"); + if (keyStoreType != null && keyStoreType.equals("AzureKeyVault")) { + MutablePropertySources sources = environment.getPropertySources(); + Properties properties = new Properties(); + properties.put("server.ssl.key-store", "classpath:keyvault.dummy"); + try { + Class.forName("org.apache.tomcat.InstanceManager"); + properties.put("server.ssl.key-store-type", "DKS"); + } catch (ClassNotFoundException ignored) { } + PropertySource propertySource = new PropertiesPropertySource("KeyStorePropertySource", properties); + sources.addFirst(propertySource); + } - String clientSecret = environment.getProperty("azure.keyvault.clientSecret"); - if (clientSecret != null) { - systemProperties.put("azure.keyvault.clientSecret", clientSecret); - } - - String keyStoreType = environment.getProperty("server.ssl.key-store-type"); - - if (keyStoreType != null && keyStoreType.equals("AzureKeyVault")) { - MutablePropertySources sources = environment.getPropertySources(); - Properties properties = new Properties(); - properties.put("server.ssl.key-store", "classpath:keyvault.dummy"); - - try { - Class.forName("org.apache.tomcat.InstanceManager"); - properties.put("server.ssl.key-store-type", "DKS"); - } catch (ClassNotFoundException ex) { - } - - PropertySource propertySource = new PropertiesPropertySource("KeyStorePropertySource", properties); - sources.addFirst(propertySource); - - } - - String trustStoreType = environment.getProperty("server.ssl.trust-store-type"); - - if (trustStoreType != null && trustStoreType.equals("AzureKeyVault")) { - MutablePropertySources sources = environment.getPropertySources(); - Properties properties = new Properties(); - properties.put("server.ssl.trust-store", "classpath:keyvault.dummy"); - - try { - Class.forName("org.apache.tomcat.InstanceManager"); - properties.put("server.ssl.trust-store-type", "DKS"); - } catch (ClassNotFoundException ex) { - } - - PropertySource propertySource = new PropertiesPropertySource("TrustStorePropertySource", properties); - sources.addFirst(propertySource); - } - - KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); - Security.insertProviderAt(provider, 1); - - String enabled = environment.getProperty("azure.keyvault.jca.overrideTrustManagerFactory"); - if (Boolean.valueOf(enabled)) { - KeyVaultTrustManagerFactoryProvider factoryProvider = - new KeyVaultTrustManagerFactoryProvider(); - Security.insertProviderAt(factoryProvider, 1); + String trustStoreType = environment.getProperty("server.ssl.trust-store-type"); + if (trustStoreType != null && trustStoreType.equals("AzureKeyVault")) { + MutablePropertySources sources = environment.getPropertySources(); + Properties properties = new Properties(); + properties.put("server.ssl.trust-store", "classpath:keyvault.dummy"); + try { + Class.forName("org.apache.tomcat.InstanceManager"); + properties.put("server.ssl.trust-store-type", "DKS"); + } catch (ClassNotFoundException ignored) { } + PropertySource propertySource = new PropertiesPropertySource("TrustStorePropertySource", properties); + sources.addFirst(propertySource); + } - enabled = environment.getProperty("azure.keyvault.jca.disableHostnameVerification"); - if (Boolean.valueOf(enabled)) { - HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> { - return true; - }); - } + KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); + Security.insertProviderAt(provider, 1); + String enabled = environment.getProperty("azure.keyvault.jca.overrideTrustManagerFactory"); + if (Boolean.parseBoolean(enabled)) { + KeyVaultTrustManagerFactoryProvider factoryProvider = + new KeyVaultTrustManagerFactoryProvider(); + Security.insertProviderAt(factoryProvider, 1); + } + enabled = environment.getProperty("azure.keyvault.jca.disableHostnameVerification"); + if (Boolean.parseBoolean(enabled)) { + HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true); } } } From 4c3a3a758fef1e3ed30aeb8ef03c4c30f5caf775 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 16:27:59 +0800 Subject: [PATCH 72/92] Change azure-spring-boot-sample-keyvault-certificates's groupId to com.azure.spring. --- .../azure-spring-boot-sample-keyvault-certificates/pom.xml | 6 +++--- .../azure-spring-boot-starter-keyvault-certificates/pom.xml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml index ce9f3a063405a..d9c9d17b78268 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml @@ -11,7 +11,7 @@ - com.azure + com.azure.spring azure-spring-boot-sample-keyvault-certificates 1.0.0 jar @@ -81,9 +81,9 @@ - com.azure + com.azure.spring azure-spring-boot-starter-keyvault-certificates - 2.4.0-beta.1 + 2.4.0-beta.1 org.springframework.boot diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index e131217a9d1fa..97a267c570b26 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -11,9 +11,9 @@ ../../parents/azure-client-sdk-parent - com.azure + com.azure.spring azure-spring-boot-starter-keyvault-certificates - 2.4.0-beta.1 + 2.4.0-beta.1 Azure Key Vault Certificates Spring Boot Starter Spring Boot Starter supporting Azure Key Vault Certificates From eee1baf9fa320e0be8a446f34b243bc04a07b959 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 17:10:57 +0800 Subject: [PATCH 73/92] Skip maven-surefire-plugin by default. --- sdk/keyvault/azure-security-keyvault-jca/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index 022c005b01e6f..815a2c39f5ffc 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -171,7 +171,7 @@ maven-surefire-plugin 3.0.0-M3 - false + true ${azure.keyvault.uri} ${azure.tenant.id} From f1568c2d0d1f1daf05d335f08386247045fef5c0 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 17:20:59 +0800 Subject: [PATCH 74/92] Change azure-spring-boot-starter-keyvault-certificates's version to 3.0.0-beta.1. --- eng/versioning/version_client.txt | 2 +- .../pom.xml | 2 +- .../CHANGELOG.md | 15 +-------------- .../pom.xml | 2 +- 4 files changed, 4 insertions(+), 17 deletions(-) diff --git a/eng/versioning/version_client.txt b/eng/versioning/version_client.txt index 07ba100b072a1..302912c0415bb 100644 --- a/eng/versioning/version_client.txt +++ b/eng/versioning/version_client.txt @@ -67,7 +67,7 @@ com.azure.spring:azure-spring-boot-starter-active-directory-b2c;3.0.0-beta.1;3.0 com.azure.spring:azure-spring-boot-starter-active-directory;3.0.0-beta.1;3.0.0-beta.1 com.azure.spring:azure-spring-boot-starter-cosmos;3.0.0-beta.1;3.0.0-beta.1 com.azure.spring:azure-spring-boot-starter-data-gremlin;3.0.0-beta.1;3.0.0-beta.1 -com.azure.spring:azure-spring-boot-starter-keyvault-certificates;2.4.0-beta.1;2.3.3 +com.azure.spring:azure-spring-boot-starter-keyvault-certificates;3.0.0-beta.1;3.0.0-beta.1 com.azure.spring:azure-spring-boot-starter-keyvault-secrets;3.0.0-beta.1;3.0.0-beta.1 com.azure.spring:azure-spring-boot-starter-metrics;3.0.0-beta.1;3.0.0-beta.1 com.azure.spring:azure-spring-boot-starter-servicebus-jms;3.0.0-beta.1;3.0.0-beta.1 diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml index d9c9d17b78268..7937464ffb28f 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/pom.xml @@ -83,7 +83,7 @@ com.azure.spring azure-spring-boot-starter-keyvault-certificates - 2.4.0-beta.1 + 3.0.0-beta.1 org.springframework.boot diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md index 2e1ccf5fe5f0b..02434784717da 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/CHANGELOG.md @@ -1,16 +1,3 @@ # Release History -## 2.4.0-beta.1 (Unreleased) - - -## 2.3.3 (2020-08-13) -_New Features_ -- Support connection to multiple Key Vault from a single application configuration file -- Support case-sensitive keys in Key Vault -- Key Vault Spring Boot Actuator - -_Improved_ -- Revamp KeyVault refreshing logic to avoid unnecessary updates. - -_Bug Fixes_ -- Address CVEs and cleaned up all warnings at build time. +## 3.0.0-beta.1 (Unreleased) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index 97a267c570b26..1ccc208794bee 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -13,7 +13,7 @@ com.azure.spring azure-spring-boot-starter-keyvault-certificates - 2.4.0-beta.1 + 3.0.0-beta.1 Azure Key Vault Certificates Spring Boot Starter Spring Boot Starter supporting Azure Key Vault Certificates From 625c50f879815abbdfca356acd5201ec9f1816df Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Mon, 19 Oct 2020 17:23:05 +0800 Subject: [PATCH 75/92] Fix groupId error about httpclient5. --- eng/versioning/external_dependencies.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/versioning/external_dependencies.txt b/eng/versioning/external_dependencies.txt index 7a0d985c107d8..2f6ab7cc1ebf2 100644 --- a/eng/versioning/external_dependencies.txt +++ b/eng/versioning/external_dependencies.txt @@ -63,7 +63,7 @@ org.apache.avro:avro-maven-plugin;1.9.2 org.apache.commons:commons-compress;1.20 org.apache.commons:commons-lang3;3.10 org.apache.httpcomponents:httpclient;4.5.12 -org.apache.httpcomponents:httpclient5;5.0.1 +org.apache.httpcomponents.client5:httpclient5;5.0.1 org.apache.logging.log4j:log4j-api;2.13.3 org.apache.logging.log4j:log4j-core;2.13.3 org.apache.logging.log4j:log4j-slf4j-impl;2.13.3 From 5c90b80bd17690bf00c0e525497bdb47ad3d3914 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 09:35:09 -0600 Subject: [PATCH 76/92] Changes to accomodate X509ExtendedTrustManager --- .../azure-security-keyvault-jca/pom.xml | 10 +- .../security/keyvault/jca/AuthClient.java | 122 +++++++++++------ .../keyvault/jca/KeyVaultTrustManager.java | 25 +++- .../keyvault/jca/LegacyRestClient.java | 39 +++--- .../keyvault/jca/rest/OAuthToken.java | 11 +- .../pom.xml | 6 +- ...tCertificatesEnvironmentPostProcessor.java | 128 ++++++++++-------- 7 files changed, 214 insertions(+), 127 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index 815a2c39f5ffc..d229324a36120 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -4,12 +4,14 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + + 1.7.0 ../../parents/azure-client-sdk-parent + --> com.azure azure-security-keyvault-jca 1.0.0-beta.1 @@ -78,7 +80,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M3 + 3.0.0-M5 true @@ -169,9 +171,9 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M3 + 3.0.0-M5 - true + false ${azure.keyvault.uri} ${azure.tenant.id} diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java index d96c7943a4ffd..91a5f3c1cf1b1 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -1,12 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License./ - package com.azure.security.keyvault.jca; import com.azure.security.keyvault.jca.rest.OAuthToken; import java.util.HashMap; -import java.util.Optional; import java.util.logging.Logger; import static java.util.logging.Level.FINER; @@ -18,6 +16,42 @@ */ class AuthClient extends DelegateRestClient { + /** + * Stores the Client ID fragment. + */ + private static final String CLIENT_ID_FRAGMENT = "&client_id="; + + /** + * Stores the Client Secret fragment. + */ + private static final String CLIENT_SECRET_FRAGMENT = "&client_secret="; + + /** + * Stores the Grant Type fragment. + */ + private static final String GRANT_TYPE_FRAGMENT = "grant_type=client_credentials"; + + /** + * Stores the Resource fragment. + */ + private static final String RESOURCE_FRAGMENT = "&resource="; + + /** + * Stores the OAuth2 token base URL. + */ + private static final String OAUTH2_TOKEN_BASE_URL = "https://login.microsoftonline.com/"; + + /** + * Stores the OAuth2 token postfix. + */ + private static final String OAUTH2_TOKEN_POSTFIX = "/oauth2/token"; + + /** + * Stores the OAuth2 managed identity URL. + */ + private static final String OAUTH2_MANAGED_IDENTITY_TOKEN_URL + = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01"; + /** * Stores our logger. */ @@ -42,12 +76,9 @@ public AuthClient() { */ public String getAccessToken(String resource) { String result; - boolean siteNameSet = Optional.of("WEBSITE_SITE_NAME") - .map(System::getenv) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .isPresent(); - if (siteNameSet) { + + if (System.getenv("WEBSITE_SITE_NAME") != null + && !System.getenv("WEBSITE_SITE_NAME").isEmpty()) { result = getAccessTokenOnAppService(resource); } else { result = getAccessTokenOnOthers(resource); @@ -64,34 +95,29 @@ public String getAccessToken(String resource) { * @param clientSecret the client secret. * @return the authorization token. */ - public String getAccessToken(String resource, - String tenantId, - String clientId, - String clientSecret) { - LOGGER.entering( - "AuthClient", - "getAccessToken", - new Object[] { - resource, - tenantId, - clientId, - clientSecret - } - ); + public String getAccessToken(String resource, String tenantId, + String clientId, String clientSecret) { + LOGGER.entering("AuthClient", "getAccessToken", new Object[] { + resource, tenantId, clientId, clientSecret }); LOGGER.info("Getting access token using client ID / client secret"); String result = null; - String oauth2Url = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenantId); - String requestBody = String.format( - "grant_type=client_credentials&client_id=%s&client_secret=%s&resource=%s", - clientId, - clientSecret, - resource - ); - String response = post(oauth2Url, requestBody, "application/x-www-form-urlencoded"); - if (response != null) { + + StringBuilder oauth2Url = new StringBuilder(); + oauth2Url.append(OAUTH2_TOKEN_BASE_URL) + .append(tenantId) + .append(OAUTH2_TOKEN_POSTFIX); + + StringBuilder requestBody = new StringBuilder(); + requestBody.append(GRANT_TYPE_FRAGMENT) + .append(CLIENT_ID_FRAGMENT).append(clientId) + .append(CLIENT_SECRET_FRAGMENT).append(clientSecret) + .append(RESOURCE_FRAGMENT).append(resource); + + String body = post(oauth2Url.toString(), requestBody.toString(), "application/x-www-form-urlencoded"); + if (body != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); - OAuthToken token = (OAuthToken) converter.fromJson(response, OAuthToken.class); - result = token.getAccessToken(); + OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); + result = token.getAccess_token(); } LOGGER.log(FINER, "Access token: {0}", result); return result; @@ -107,15 +133,21 @@ private String getAccessTokenOnAppService(String resource) { LOGGER.entering("AuthClient", "getAccessTokenOnAppService", resource); LOGGER.info("Getting access token using managed identity based on MSI_SECRET"); String result = null; + + StringBuilder url = new StringBuilder(); + url.append(System.getenv("MSI_ENDPOINT")) + .append("?api-version=2017-09-01") + .append(RESOURCE_FRAGMENT).append(resource); + HashMap headers = new HashMap<>(); headers.put("Metadata", "true"); headers.put("Secret", System.getenv("MSI_SECRET")); - String url = String.format("%s?api-version=2017-09-01&resource=%s", System.getenv("MSI_ENDPOINT"), resource); - String response = get(url, headers); - if (response != null) { + String body = get(url.toString(), headers); + + if (body != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); - OAuthToken token = (OAuthToken) converter.fromJson(response, OAuthToken.class); - result = token.getAccessToken(); + OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); + result = token.getAccess_token(); } LOGGER.exiting("AuthClient", "getAccessTokenOnAppService", result); return result; @@ -131,17 +163,19 @@ private String getAccessTokenOnOthers(String resource) { LOGGER.entering("AuthClient", "getAccessTokenOnOthers", resource); LOGGER.info("Getting access token using managed identity"); String result = null; - String url = String.format( - "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=%s", - resource - ); + + StringBuilder url = new StringBuilder(); + url.append(OAUTH2_MANAGED_IDENTITY_TOKEN_URL) + .append(RESOURCE_FRAGMENT).append(resource); + HashMap headers = new HashMap<>(); headers.put("Metadata", "true"); - String body = get(url, headers); + String body = get(url.toString(), headers); + if (body != null) { JsonConverter converter = JsonConverterFactory.createJsonConverter(); OAuthToken token = (OAuthToken) converter.fromJson(body, OAuthToken.class); - result = token.getAccessToken(); + result = token.getAccess_token(); } LOGGER.exiting("AuthClient", "getAccessTokenOnOthers", result); return result; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java index beea6a4641ff0..61e6efc04a94e 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java @@ -6,19 +6,22 @@ import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import java.io.IOException; +import java.net.Socket; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.X509ExtendedTrustManager; /** * The KeyVault variant of the X509TrustManager. * * @author Manfred Riem (manfred.riem@microsoft.com) */ -public class KeyVaultTrustManager implements X509TrustManager { +public class KeyVaultTrustManager extends X509ExtendedTrustManager implements X509TrustManager { /** * Stores the default trust manager. @@ -129,4 +132,24 @@ public void checkServerTrusted(X509Certificate[] chain, String authType) public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { + checkClientTrusted(chain, authType); + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { + checkServerTrusted(chain, authType); + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { + checkClientTrusted(chain, authType); + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { + checkServerTrusted(chain, authType); + } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java index 1f970a5938dee..2a21d6831e965 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java @@ -1,6 +1,5 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. - package com.azure.security.keyvault.jca; import org.apache.hc.client5.http.classic.methods.HttpGet; @@ -36,9 +35,21 @@ public String get(String url, Map headers) { try (CloseableHttpClient client = HttpClients.createDefault()) { HttpGet httpGet = new HttpGet(url); if (headers != null) { - headers.forEach(httpGet::addHeader); + headers.entrySet().forEach(entry -> { + String key = entry.getKey(); + String value = entry.getValue(); + httpGet.addHeader(key, value); + }); } - HttpClientResponseHandler responseHandler = createHttpClientResponseHandler(); + HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { + int status = response.getCode(); + String result1 = null; + if (status >= 200 && status < 300) { + HttpEntity entity = response.getEntity(); + result1 = entity != null ? EntityUtils.toString(entity) : null; + } + return result1; + }; result = client.execute(httpGet, responseHandler); } catch (IOException ioe) { ioe.printStackTrace(); @@ -52,23 +63,19 @@ public String post(String url, String body, String contentType) { try (CloseableHttpClient client = HttpClients.createDefault()) { HttpPost httpPost = new HttpPost(url); httpPost.setEntity(HttpEntities.create(body, ContentType.create(contentType))); - HttpClientResponseHandler responseHandler = createHttpClientResponseHandler(); + HttpClientResponseHandler responseHandler = (ClassicHttpResponse response) -> { + int status = response.getCode(); + String result1 = null; + if (status >= 200 && status < 300) { + HttpEntity entity = response.getEntity(); + result1 = entity != null ? EntityUtils.toString(entity) : null; + } + return result1; + }; result = client.execute(httpPost, responseHandler); } catch (IOException ioe) { ioe.printStackTrace(); } return result; } - - private HttpClientResponseHandler createHttpClientResponseHandler() { - return (ClassicHttpResponse response) -> { - int status = response.getCode(); - String result = null; - if (status >= 200 && status < 300) { - HttpEntity entity = response.getEntity(); - result = entity != null ? EntityUtils.toString(entity) : null; - } - return result; - }; - } } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java index c3450519b0760..ec310f9b9163f 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java @@ -1,6 +1,5 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. - package com.azure.security.keyvault.jca.rest; import java.io.Serializable; @@ -15,15 +14,15 @@ public class OAuthToken implements Serializable { /** * Stores the access token. */ - private String accessToken; + private String access_token; /** * Get the access token. * * @return the access token. */ - public String getAccessToken() { - return accessToken; + public String getAccess_token() { + return access_token; } /** @@ -31,7 +30,7 @@ public String getAccessToken() { * * @param accessToken the access token. */ - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; + public void setAccess_token(String accessToken) { + this.access_token = accessToken; } } diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index 1ccc208794bee..7a345a65f8ad0 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -3,14 +3,14 @@ xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - + + 1.7.0 ../../parents/azure-client-sdk-parent - + --> com.azure.spring azure-spring-boot-starter-keyvault-certificates 3.0.0-beta.1 diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index ba710a78ef58c..6a7460d4a112c 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -1,10 +1,15 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. - package com.azure.spring.security.keyvault.certificates.starter; import com.azure.security.keyvault.jca.KeyVaultJcaProvider; import com.azure.security.keyvault.jca.KeyVaultTrustManagerFactoryProvider; + +import java.security.Security; +import java.util.Properties; +import java.util.logging.Logger; +import javax.net.ssl.HttpsURLConnection; + import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.annotation.Order; @@ -13,14 +18,9 @@ import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.env.PropertySource; -import javax.net.ssl.HttpsURLConnection; -import java.security.Security; -import java.util.Optional; -import java.util.Properties; -import java.util.logging.Logger; -import java.util.stream.Stream; +import static org.springframework.core.Ordered.LOWEST_PRECEDENCE; -@Order +@Order(LOWEST_PRECEDENCE) public class KeyVaultCertificatesEnvironmentPostProcessor implements EnvironmentPostProcessor { /** @@ -31,56 +31,78 @@ public class KeyVaultCertificatesEnvironmentPostProcessor implements Environment @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - if (environment.getProperty("azure.keyvault.uri") == null) { - return; - } + Properties systemProperties = System.getProperties(); - Stream.of("uri", "tenantId", "clientId", "clientSecret") - .forEach(key -> { - String property = "azure.keyvault." + key; - Optional.of(property) - .map(environment::getProperty) - .ifPresent(value -> systemProperties.put(property, value)); - }); - String keyStoreType = environment.getProperty("server.ssl.key-store-type"); - if (keyStoreType != null && keyStoreType.equals("AzureKeyVault")) { - MutablePropertySources sources = environment.getPropertySources(); - Properties properties = new Properties(); - properties.put("server.ssl.key-store", "classpath:keyvault.dummy"); - try { - Class.forName("org.apache.tomcat.InstanceManager"); - properties.put("server.ssl.key-store-type", "DKS"); - } catch (ClassNotFoundException ignored) { + + String uri = environment.getProperty("azure.keyvault.uri"); + if (uri != null) { + systemProperties.put("azure.keyvault.uri", uri); + + String tenantId = environment.getProperty("azure.keyvault.tenantId"); + if (tenantId != null) { + systemProperties.put("azure.keyvault.tenantId", tenantId); } - PropertySource propertySource = new PropertiesPropertySource("KeyStorePropertySource", properties); - sources.addFirst(propertySource); - } - String trustStoreType = environment.getProperty("server.ssl.trust-store-type"); - if (trustStoreType != null && trustStoreType.equals("AzureKeyVault")) { - MutablePropertySources sources = environment.getPropertySources(); - Properties properties = new Properties(); - properties.put("server.ssl.trust-store", "classpath:keyvault.dummy"); - try { - Class.forName("org.apache.tomcat.InstanceManager"); - properties.put("server.ssl.trust-store-type", "DKS"); - } catch (ClassNotFoundException ignored) { + String clientId = environment.getProperty("azure.keyvault.clientId"); + if (clientId != null) { + systemProperties.put("azure.keyvault.clientId", clientId); } - PropertySource propertySource = new PropertiesPropertySource("TrustStorePropertySource", properties); - sources.addFirst(propertySource); - } - KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); - Security.insertProviderAt(provider, 1); - String enabled = environment.getProperty("azure.keyvault.jca.overrideTrustManagerFactory"); - if (Boolean.parseBoolean(enabled)) { - KeyVaultTrustManagerFactoryProvider factoryProvider = - new KeyVaultTrustManagerFactoryProvider(); - Security.insertProviderAt(factoryProvider, 1); - } - enabled = environment.getProperty("azure.keyvault.jca.disableHostnameVerification"); - if (Boolean.parseBoolean(enabled)) { - HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true); + String clientSecret = environment.getProperty("azure.keyvault.clientSecret"); + if (clientSecret != null) { + systemProperties.put("azure.keyvault.clientSecret", clientSecret); + } + + String keyStoreType = environment.getProperty("server.ssl.key-store-type"); + + if (keyStoreType != null && keyStoreType.equals("AzureKeyVault")) { + MutablePropertySources sources = environment.getPropertySources(); + Properties properties = new Properties(); + properties.put("server.ssl.key-store", "classpath:keyvault.dummy"); + + try { + Class.forName("org.apache.tomcat.InstanceManager"); + properties.put("server.ssl.key-store-type", "DKS"); + } catch (ClassNotFoundException ex) { + } + + PropertySource propertySource = new PropertiesPropertySource("KeyStorePropertySource", properties); + sources.addFirst(propertySource); + } + + String trustStoreType = environment.getProperty("server.ssl.trust-store-type"); + + if (trustStoreType != null && trustStoreType.equals("AzureKeyVault")) { + MutablePropertySources sources = environment.getPropertySources(); + Properties properties = new Properties(); + properties.put("server.ssl.trust-store", "classpath:keyvault.dummy"); + + try { + Class.forName("org.apache.tomcat.InstanceManager"); + properties.put("server.ssl.trust-store-type", "DKS"); + } catch (ClassNotFoundException ex) { + } + + PropertySource propertySource = new PropertiesPropertySource("TrustStorePropertySource", properties); + sources.addFirst(propertySource); + } + + KeyVaultJcaProvider provider = new KeyVaultJcaProvider(); + Security.insertProviderAt(provider, 1); + + String enabled = environment.getProperty("azure.keyvault.jca.overrideTrustManagerFactory"); + if (Boolean.parseBoolean(enabled)) { + KeyVaultTrustManagerFactoryProvider factoryProvider = + new KeyVaultTrustManagerFactoryProvider(); + Security.insertProviderAt(factoryProvider, 1); + } + + enabled = environment.getProperty("azure.keyvault.jca.disableHostnameVerification"); + if (Boolean.parseBoolean(enabled)) { + HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> { + return true; + }); + } } } } From 767c6624aaae2225c21c14e1eae3ef80174a9e4b Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 12:24:50 -0600 Subject: [PATCH 77/92] Restore Dockerfile --- .../azure-security-keyvault-jca/README.md | 16 +++++++++++++++- .../Dockerfile | 3 +++ .../README.md | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index 85c418256d61d..35a16cf5dc3b0 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -110,4 +110,18 @@ For Spring Boot applications see our [Spring Boot starter](../../spring/azure-sp ## Reference -1. [Java Cryptography Architecture (JCA) Reference Guide](https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html) \ No newline at end of file +1. [Java Cryptography Architecture (JCA) Reference Guide](https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html) + +# Azure KeyVault JCA client library for Java + +# Getting started + +# Key concepts + +# Examples + +# Troubleshooting + +# Next steps + +# Contributing diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile new file mode 100644 index 0000000000000..091170acf8810 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates/Dockerfile @@ -0,0 +1,3 @@ +FROM mcr.microsoft.com/java/jdk:8-zulu-centos +ADD target/app.jar . +CMD java -jar app.jar diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index ed11f29a5f548..3834e5dd51a32 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -261,3 +261,18 @@ To build and install the starter use the following command line: ``` mvn clean install -DskipTests=true ``` + + +# Azure KeyVault Certificates client library for Java + +# Getting started + +# Key concepts + +# Examples + +# Troubleshooting + +# Next steps + +# Contributing \ No newline at end of file From ee6952d0682aab298dc39603928769585cc12f8f Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 12:37:14 -0600 Subject: [PATCH 78/92] Comment out links for now --- sdk/keyvault/azure-security-keyvault-jca/README.md | 2 +- .../azure-spring-boot-starter-keyvault-certificates/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/README.md b/sdk/keyvault/azure-security-keyvault-jca/README.md index 35a16cf5dc3b0..f6efb38fbe056 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/README.md +++ b/sdk/keyvault/azure-security-keyvault-jca/README.md @@ -106,7 +106,7 @@ of `azure.keyvault.uri`, and the rest of the parameters would be `null`. ## Spring Boot -For Spring Boot applications see our [Spring Boot starter](../../spring/azure-spring-boot-starter-keyvault-certificates/README.md). +For Spring Boot applications see our [Spring Boot starter]. ## Reference diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index 3834e5dd51a32..e32959f329f41 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -253,7 +253,7 @@ side-loaded certificates. If you want to test the current version under development you will have to -1. Build and install the [Microsoft Azure JCA Provider](../../keyvault/azure-security-keyvault-jca/README.md) for KeyVault +1. Build and install the [Microsoft Azure JCA Provider] for KeyVault 1. Build and install this starter. To build and install the starter use the following command line: From 30df750f99d01ac9f452da23d91c052f25ce5973 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 13:07:43 -0600 Subject: [PATCH 79/92] Add package-info for the starter --- ...tCertificatesEnvironmentPostProcessor.java | 7 +++-- .../certificates/starter/package-info.java | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/package-info.java diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java index 6a7460d4a112c..6d76e12b46196 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/KeyVaultCertificatesEnvironmentPostProcessor.java @@ -16,7 +16,6 @@ import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertiesPropertySource; -import org.springframework.core.env.PropertySource; import static org.springframework.core.Ordered.LOWEST_PRECEDENCE; @@ -66,7 +65,8 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, } catch (ClassNotFoundException ex) { } - PropertySource propertySource = new PropertiesPropertySource("KeyStorePropertySource", properties); + PropertiesPropertySource propertySource = + new PropertiesPropertySource("KeyStorePropertySource", properties); sources.addFirst(propertySource); } @@ -83,7 +83,8 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, } catch (ClassNotFoundException ex) { } - PropertySource propertySource = new PropertiesPropertySource("TrustStorePropertySource", properties); + PropertiesPropertySource propertySource = + new PropertiesPropertySource("TrustStorePropertySource", properties); sources.addFirst(propertySource); } diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/package-info.java b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/package-info.java new file mode 100644 index 0000000000000..2de5b95f6ece0 --- /dev/null +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/src/main/java/com/azure/spring/security/keyvault/certificates/starter/package-info.java @@ -0,0 +1,28 @@ +/* + * The MIT License + * + * Copyright 2020 Microsoft Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * The Azure Key Vault Certificate Spring Boot starter package. + */ +package com.azure.spring.security.keyvault.certificates.starter; From 41ada7f7d7262c81206d610096e4099dc3e41f6f Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 13:37:06 -0600 Subject: [PATCH 80/92] Add parent POMs back to see what else fails --- sdk/keyvault/azure-security-keyvault-jca/pom.xml | 6 +++--- .../azure-spring-boot-starter-keyvault-certificates/pom.xml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index d229324a36120..f74b0011e2cf1 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -4,14 +4,14 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - ../../parents/azure-client-sdk-parent - --> + com.azure azure-security-keyvault-jca 1.0.0-beta.1 diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index 7a345a65f8ad0..d53dc5cdd4be2 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -3,14 +3,14 @@ xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - ../../parents/azure-client-sdk-parent - --> + com.azure.spring azure-spring-boot-starter-keyvault-certificates 3.0.0-beta.1 From 5198b86c28c4cbc2c64bdef453a93cc5f56b4816 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 14:11:54 -0600 Subject: [PATCH 81/92] Updates for pipeline --- sdk/keyvault/azure-security-keyvault-jca/pom.xml | 2 +- .../azure-spring-boot-starter-keyvault-certificates/pom.xml | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index f74b0011e2cf1..fb344c995ac35 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -80,7 +80,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M5 + 3.0.0-M3 true diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index d53dc5cdd4be2..3bbd89d032e5b 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -46,11 +46,8 @@ - com.microsoft.azure:azure-spring-boot:[2.4.0-beta.1] - com.azure:azure-security-keyvault-secrets:[1.0.0] org.springframework.boot:spring-boot-starter:[2.3.3.RELEASE] - org.springframework.boot:spring-boot-starter-validation:[2.3.3.RELEASE] - + org.springframework.boot:spring-boot-starter-validation:[2.3.3.RELEASE] From 2438787c2456ffc5906e4b9378aa75bd55a64bbb Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 14:23:08 -0600 Subject: [PATCH 82/92] Updates for pipeline --- sdk/keyvault/azure-security-keyvault-jca/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index fb344c995ac35..a1c2f5f802e56 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -171,7 +171,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M5 + 3.0.0-M3 false From 5dc3b16b885c130e6b098e492116f9b9d6674484 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 14:39:12 -0600 Subject: [PATCH 83/92] Allow for given dependencies --- .../azure-security-keyvault-jca/pom.xml | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index a1c2f5f802e56..af6c78627402a 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -4,14 +4,14 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - + azure-client-sdk-parent com.azure 1.7.0 ../../parents/azure-client-sdk-parent - + com.azure azure-security-keyvault-jca 1.0.0-beta.1 @@ -105,6 +105,22 @@ + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + + org.apache.httpcomponents.client5:httpclient5:[5.0.1] + com.fasterxml.jackson.core:jackson-databind:[2.11.2] + org.slf4j:slf4j-nop:[1.7.30] + + + + + From da408a1c2c78fb9667a814e30a9885c2e51648ce Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 14:56:33 -0600 Subject: [PATCH 84/92] Make build pass --- .../azure-security-keyvault-jca/pom.xml | 8 + .../security/keyvault/jca/AuthClient.java | 5 +- .../keyvault/jca/JsonConverterFactory.java | 2 +- .../security/keyvault/jca/KeyVaultClient.java | 4 +- .../jca/KeyVaultTrustManagerFactory.java | 2 - .../pom.xml | 344 +++++++++--------- 6 files changed, 190 insertions(+), 175 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index af6c78627402a..86497c865c812 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -121,6 +121,14 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.1 + + true + + diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java index 91a5f3c1cf1b1..ffeb4ed1e7d69 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License./ +// Licensed under the MIT License. + package com.azure.security.keyvault.jca; import com.azure.security.keyvault.jca.rest.OAuthToken; @@ -64,7 +65,7 @@ class AuthClient extends DelegateRestClient { * The constructor creates a default RestClient. *

*/ - public AuthClient() { + AuthClient() { super(RestClientFactory.createClient()); } diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java index acb43c6aec6ff..34217851b9f12 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java @@ -8,7 +8,7 @@ * * @author Manfred Riem (manfred.riem@microsoft.com) */ -class JsonConverterFactory { +final class JsonConverterFactory { /** * Constructor. diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java index 96430e29aa85e..a7de1905ccad1 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java @@ -75,7 +75,7 @@ class KeyVaultClient extends DelegateRestClient { * * @param keyVaultUri the KeyVault URI. */ - public KeyVaultClient(String keyVaultUri) { + KeyVaultClient(String keyVaultUri) { super(RestClientFactory.createClient()); LOGGER.log(INFO, "Using KeyVault: {0}", keyVaultUri); if (!keyVaultUri.endsWith("/")) { @@ -92,7 +92,7 @@ public KeyVaultClient(String keyVaultUri) { * @param clientId the client ID. * @param clientSecret the client secret. */ - public KeyVaultClient(String keyVaultUri, String tenantId, String clientId, String clientSecret) { + KeyVaultClient(final String keyVaultUri, final String tenantId, final String clientId, final String clientSecret) { this(keyVaultUri); this.tenantId = tenantId; this.clientId = clientId; diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java index d517102313dc5..18fac1e8e0bdb 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java @@ -6,9 +6,7 @@ import javax.net.ssl.ManagerFactoryParameters; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactorySpi; -import java.security.InvalidAlgorithmParameterException; import java.security.KeyStore; -import java.security.KeyStoreException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index 3bbd89d032e5b..6dc2917444f04 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -2,176 +2,184 @@ - 4.0.0 + 4.0.0 - - com.azure - azure-client-sdk-parent - 1.7.0 - ../../parents/azure-client-sdk-parent - + + com.azure + azure-client-sdk-parent + 1.7.0 + ../../parents/azure-client-sdk-parent + - com.azure.spring - azure-spring-boot-starter-keyvault-certificates - 3.0.0-beta.1 + com.azure.spring + azure-spring-boot-starter-keyvault-certificates + 3.0.0-beta.1 - Azure Key Vault Certificates Spring Boot Starter - Spring Boot Starter supporting Azure Key Vault Certificates - https://github.com/Azure/azure-sdk-for-java + Azure Key Vault Certificates Spring Boot Starter + Spring Boot Starter supporting Azure Key Vault Certificates + https://github.com/Azure/azure-sdk-for-java - - - org.springframework.boot - spring-boot-starter - 2.3.3.RELEASE - - - org.springframework.boot - spring-boot-starter-validation - 2.3.3.RELEASE - - - com.azure - azure-security-keyvault-jca - 1.0.0-beta.1 - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.0.0-M3 - - - - - org.springframework.boot:spring-boot-starter:[2.3.3.RELEASE] - org.springframework.boot:spring-boot-starter-validation:[2.3.3.RELEASE] - - - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.1.1 - - - attach-javadocs - - jar - - - true - - - - - - org.apache.maven.plugins - maven-jar-plugin - 3.1.2 - - - - empty-javadoc-jar-with-readme - package - - jar - - - javadoc - ${project.basedir}/javadocTemp - - - - - - empty-sources-jar-with-readme - package - - jar - - - sources - ${project.basedir}/sourceTemp - - - - - - - org.apache.maven.plugins - maven-antrun-plugin - 1.8 - - - copy-readme-to-javadocTemp - prepare-package - - - Deleting existing ${project.basedir}/javadocTemp - - - - Copying ${project.basedir}/README.md to - ${project.basedir}/javadocTemp/README.md - - - - - - run - - - - copy-readme-to-sourceTemp - prepare-package - - - Deleting existing ${project.basedir}/sourceTemp - - - - Copying ${project.basedir}/README.md to - ${project.basedir}/sourceTemp/README.md - - - - - - run - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.0.1 - - - attach-sources - none - - - - - - - - 1.8 - 1.8 - + + + org.springframework.boot + spring-boot-starter + 2.3.3.RELEASE + + + org.springframework.boot + spring-boot-starter-validation + 2.3.3.RELEASE + + + com.azure + azure-security-keyvault-jca + 1.0.0-beta.1 + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + + org.springframework.boot:spring-boot-starter:[2.3.3.RELEASE] + org.springframework.boot:spring-boot-starter-validation:[2.3.3.RELEASE] + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.1.1 + + + attach-javadocs + + jar + + + true + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.2 + + + + empty-javadoc-jar-with-readme + package + + jar + + + javadoc + ${project.basedir}/javadocTemp + + + + + + empty-sources-jar-with-readme + package + + jar + + + sources + ${project.basedir}/sourceTemp + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + copy-readme-to-javadocTemp + prepare-package + + + Deleting existing ${project.basedir}/javadocTemp + + + + Copying ${project.basedir}/README.md to + ${project.basedir}/javadocTemp/README.md + + + + + + run + + + + copy-readme-to-sourceTemp + prepare-package + + + Deleting existing ${project.basedir}/sourceTemp + + + + Copying ${project.basedir}/README.md to + ${project.basedir}/sourceTemp/README.md + + + + + + run + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + none + + + + + + org.revapi + revapi-maven-plugin + 0.12.1 + + true + + + + + + 1.8 + 1.8 + From df48b766baea0d99551b1d5e5ff4c5e06a028239 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 15:00:05 -0600 Subject: [PATCH 85/92] Make build pass --- .../azure-security-keyvault-jca/pom.xml | 428 +++++++++--------- 1 file changed, 222 insertions(+), 206 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index 86497c865c812..73d0069b3abc6 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -3,214 +3,230 @@ - 4.0.0 + 4.0.0 - - azure-client-sdk-parent - com.azure - 1.7.0 - ../../parents/azure-client-sdk-parent - - - com.azure - azure-security-keyvault-jca - 1.0.0-beta.1 - JCA Provider for Azure Key Vault - The Java Crypto Architecture (JCA) Provider for Azure KeyVault - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 1.8 - 1.8 - ${project.build.sourceEncoding} - - - - org.apache.maven.plugins - maven-resources-plugin - 2.4.3 - - ${project.build.sourceEncoding} - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.4 - - - - shade - - - - - com.fasterxml.jackson - com.azure.keyvault.jca.com.fasterxml.jackson - - - org.apache.commons - com.azure.keyvault.jca.org.apache.commons - - - org.apache.hc - com.azure.keyvault.jca.org.apache.hc - - - mozilla - com.azure.keyvault.jca.mozilla - - - org.slf4j - com.azure.keyvault.jca.org.slf4j - - - - - - true - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M3 - - true - - - - org.jacoco - jacoco-maven-plugin - 0.8.5 - - - default-prepare-agent - - prepare-agent - - - - default-report - prepare-package - - report - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.0.0-M3 - - - - - org.apache.httpcomponents.client5:httpclient5:[5.0.1] - com.fasterxml.jackson.core:jackson-databind:[2.11.2] - org.slf4j:slf4j-nop:[1.7.30] - - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.1.1 - - true - - - - - - - - org.apache.httpcomponents.client5 - httpclient5 - 5.0.1 - true - - - - com.fasterxml.jackson.core - jackson-databind - 2.11.2 - true - - - - org.junit.jupiter - junit-jupiter-api - 5.6.2 - test - - - org.junit.jupiter - junit-jupiter-params - 5.6.2 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.6.2 - test - - - - org.slf4j - slf4j-nop - 1.7.30 - - - - - it - + ../../parents/azure-client-sdk-parent + - - azure.keyvault.uri - the KeyVault URI - - azure.tenant.id - your tenant ID - - azure.client.id - the (application) client ID - - azure.client.secret - the (application) client secret - - --> - - - azure.keyvault.uri - - - + com.azure + azure-security-keyvault-jca + 1.0.0-beta.1 + JCA Provider for Azure Key Vault + The Java Crypto Architecture (JCA) Provider for Azure KeyVault + - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M3 - - false - - ${azure.keyvault.uri} - ${azure.tenant.id} - ${azure.client.id} - ${azure.client.secret} - - - + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-resources-plugin + 2.4.3 + + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + + shade + + + + + com.fasterxml.jackson + com.azure.keyvault.jca.com.fasterxml.jackson + + + org.apache.commons + com.azure.keyvault.jca.org.apache.commons + + + org.apache.hc + com.azure.keyvault.jca.org.apache.hc + + + mozilla + com.azure.keyvault.jca.mozilla + + + org.slf4j + com.azure.keyvault.jca.org.slf4j + + + + + + true + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M3 + + true + + + + org.jacoco + jacoco-maven-plugin + 0.8.5 + + + default-prepare-agent + + prepare-agent + + + + default-report + prepare-package + + report + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + + org.apache.httpcomponents.client5:httpclient5:[5.0.1] + com.fasterxml.jackson.core:jackson-databind:[2.11.2] + org.slf4j:slf4j-nop:[1.7.30] + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.1 + + true + + + + com.github.spotbugs + spotbugs-maven-plugin + 4.1.4 + + true + + + + org.revapi + revapi-maven-plugin + 0.12.1 + + true + + - - - - - UTF-8 - + + + + + org.apache.httpcomponents.client5 + httpclient5 + 5.0.1 + true + + + + com.fasterxml.jackson.core + jackson-databind + 2.11.2 + true + + + + org.junit.jupiter + junit-jupiter-api + 5.6.2 + test + + + org.junit.jupiter + junit-jupiter-params + 5.6.2 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.2 + test + + + + org.slf4j + slf4j-nop + 1.7.30 + + + + + it + + + + azure.keyvault.uri + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M3 + + false + + ${azure.keyvault.uri} + ${azure.tenant.id} + ${azure.client.id} + ${azure.client.secret} + + + + + + + + + UTF-8 + From 51e9ada11f3d681fcab735668287190d97f9f6ab Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 15:11:20 -0600 Subject: [PATCH 86/92] Make build pass --- sdk/keyvault/azure-security-keyvault-jca/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index 73d0069b3abc6..5e3ddc6a6a642 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -124,7 +124,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.1 + 3.1.1 true @@ -132,7 +132,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.1.4 + 4.1.4 true @@ -140,7 +140,7 @@ org.revapi revapi-maven-plugin - 0.12.1 + 0.12.1 true From 966ba73d5e3e451611fc8a349295115855a93789 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 15:31:04 -0600 Subject: [PATCH 87/92] Make build pass --- sdk/keyvault/azure-security-keyvault-jca/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/pom.xml b/sdk/keyvault/azure-security-keyvault-jca/pom.xml index 5e3ddc6a6a642..b6be52e4b8caa 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/pom.xml +++ b/sdk/keyvault/azure-security-keyvault-jca/pom.xml @@ -124,7 +124,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.1 + 3.1.0 true @@ -132,7 +132,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.1.4 + 3.1.12.2 true @@ -140,7 +140,7 @@ org.revapi revapi-maven-plugin - 0.12.1 + 0.11.2 true From 75e41868e86a84b401914d778e6c54e8c6d19c29 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 15:39:41 -0600 Subject: [PATCH 88/92] Make build pass --- .../azure-spring-boot-starter-keyvault-certificates/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index 6dc2917444f04..8a26095e5c01a 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -171,7 +171,7 @@ org.revapi revapi-maven-plugin - 0.12.1 + 0.12.1 true From 22916a83b3adf58ca85e43fac5dabb01b489e1d2 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Mon, 19 Oct 2020 15:48:58 -0600 Subject: [PATCH 89/92] Make build pass --- .../azure-spring-boot-starter-keyvault-certificates/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml index 8a26095e5c01a..432c1ae31fb91 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/pom.xml @@ -171,7 +171,7 @@ org.revapi revapi-maven-plugin - 0.12.1 + 0.11.2 true From ea0d71be65833cabbe6aabb96f5a4988d30c3ada Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Tue, 20 Oct 2020 10:32:41 +0800 Subject: [PATCH 90/92] Add 2 new artifact into ci.yml. --- sdk/keyvault/ci.yml | 3 +++ sdk/spring/ci.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/sdk/keyvault/ci.yml b/sdk/keyvault/ci.yml index 331e673a980f7..f8c015c6c168b 100644 --- a/sdk/keyvault/ci.yml +++ b/sdk/keyvault/ci.yml @@ -54,6 +54,9 @@ extends: - name: azure-security-keyvault-certificates groupId: com.azure safeName: azuresecuritykeyvaultcertificates + - name: azure-security-keyvault-jca + groupId: com.azure + safeName: azuresecuritykeyvaultjca - name: azure-security-keyvault-keys groupId: com.azure safeName: azuresecuritykeyvaultkeys diff --git a/sdk/spring/ci.yml b/sdk/spring/ci.yml index c947a220b03f5..d405d35bdaacc 100644 --- a/sdk/spring/ci.yml +++ b/sdk/spring/ci.yml @@ -48,6 +48,9 @@ extends: - name: azure-spring-boot-starter-data-gremlin groupId: com.azure.spring safeName: azurespringbootstarterdatagremlin + - name: azure-spring-boot-starter-keyvault-certificates + groupId: com.azure.spring + safeName: azurespringbootstarterkeyvaultcertificates - name: azure-spring-boot-starter-keyvault-secrets groupId: com.azure.spring safeName: azurespringbootstarterkeyvaultsecrets From 01a56131b1edde280cd7ec6ea9aa6ee8ab4db60f Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Tue, 20 Oct 2020 10:42:22 +0800 Subject: [PATCH 91/92] Fix error in pipeline. --- sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md index 025d359b28644..c9a78334999c7 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md +++ b/sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md @@ -1,4 +1,4 @@ # Release History -## 3.0.0-beta.1 (Unreleased) +## 1.0.0-beta.1 (Unreleased) From 59b9585bd9ca4de1246d417961916376e3bf226f Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 20 Oct 2020 06:26:13 -0600 Subject: [PATCH 92/92] Removed @author --- .../main/java/com/azure/security/keyvault/jca/AuthClient.java | 2 -- .../com/azure/security/keyvault/jca/DelegateRestClient.java | 2 -- .../com/azure/security/keyvault/jca/JacksonJsonConverter.java | 2 -- .../java/com/azure/security/keyvault/jca/JsonConverter.java | 2 -- .../com/azure/security/keyvault/jca/JsonConverterFactory.java | 2 -- .../com/azure/security/keyvault/jca/KeyVaultCertificate.java | 2 -- .../java/com/azure/security/keyvault/jca/KeyVaultClient.java | 2 -- .../com/azure/security/keyvault/jca/KeyVaultJcaProvider.java | 2 -- .../com/azure/security/keyvault/jca/KeyVaultKeyManager.java | 2 -- .../azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java | 3 --- .../java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java | 2 -- .../security/keyvault/jca/KeyVaultLoadStoreParameter.java | 2 -- .../com/azure/security/keyvault/jca/KeyVaultTrustManager.java | 2 -- .../security/keyvault/jca/KeyVaultTrustManagerFactory.java | 2 -- .../keyvault/jca/KeyVaultTrustManagerFactoryProvider.java | 2 -- .../java/com/azure/security/keyvault/jca/LegacyRestClient.java | 2 -- .../main/java/com/azure/security/keyvault/jca/RestClient.java | 2 -- .../com/azure/security/keyvault/jca/RestClientFactory.java | 2 -- .../azure/security/keyvault/jca/rest/CertificateBundle.java | 2 -- .../com/azure/security/keyvault/jca/rest/CertificateItem.java | 2 -- .../security/keyvault/jca/rest/CertificateListResult.java | 2 -- .../azure/security/keyvault/jca/rest/CertificatePolicy.java | 2 -- .../com/azure/security/keyvault/jca/rest/KeyProperties.java | 2 -- .../java/com/azure/security/keyvault/jca/rest/OAuthToken.java | 2 -- .../com/azure/security/keyvault/jca/rest/SecretBundle.java | 2 -- 25 files changed, 51 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java index ffeb4ed1e7d69..7fab5629bce92 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/AuthClient.java @@ -12,8 +12,6 @@ /** * The REST client specific to getting an access token for Azure REST APIs. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ class AuthClient extends DelegateRestClient { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java index b0402d3aea4a0..fc75c5e99c065 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/DelegateRestClient.java @@ -7,8 +7,6 @@ /** * A RestClient that delegates to another RestClient. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ class DelegateRestClient implements RestClient { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java index 3506f69bc5a6e..768c2285fadff 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JacksonJsonConverter.java @@ -13,8 +13,6 @@ /** * The Jackson JsonConverter. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ class JacksonJsonConverter implements JsonConverter { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java index 049b7346881fd..fb4e22c1b0137 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverter.java @@ -5,8 +5,6 @@ /** * The JSON converter API. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ interface JsonConverter { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java index 34217851b9f12..c0e9f7d7ddb88 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/JsonConverterFactory.java @@ -5,8 +5,6 @@ /** * The JsonConverterFactory. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ final class JsonConverterFactory { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java index 68c48dc5bda2a..c37e93563046c 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultCertificate.java @@ -20,8 +20,6 @@ /** * The KeyVault certificate. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ class KeyVaultCertificate extends X509Certificate { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java index a7de1905ccad1..0bb01049216bf 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultClient.java @@ -35,8 +35,6 @@ /** * The REST client specific to Azure KeyVault. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ class KeyVaultClient extends DelegateRestClient { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java index 66eba3e4f847d..c91b441867acb 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultJcaProvider.java @@ -11,8 +11,6 @@ /** * The Azure KeyVault security provider. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class KeyVaultJcaProvider extends Provider { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java index ba1cf7d15203f..247f61bcd71a1 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManager.java @@ -23,8 +23,6 @@ /** * The KeyVault variant of the X509ExtendedKeyManager. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class KeyVaultKeyManager extends X509ExtendedKeyManager { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java index 156f3c15c4f02..7f1bf1e436483 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyManagerFactory.java @@ -6,7 +6,6 @@ import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactorySpi; import javax.net.ssl.ManagerFactoryParameters; -import java.security.InvalidAlgorithmParameterException; import java.security.KeyStore; import java.util.ArrayList; import java.util.List; @@ -14,8 +13,6 @@ /** * The KeyVault variant of the KeyManagerFactory. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class KeyVaultKeyManagerFactory extends KeyManagerFactorySpi { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java index 6069094d11e56..46e12d87f41f1 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java @@ -33,8 +33,6 @@ /** * The Azure KeyVault implementation of the KeyStoreSpi. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class KeyVaultKeyStore extends KeyStoreSpi { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java index c3c0c8a40621f..5a1e616eb1682 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultLoadStoreParameter.java @@ -7,8 +7,6 @@ /** * The Azure KeyVault LoadStoreParameter of the KeyStoreSpi. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class KeyVaultLoadStoreParameter implements KeyStore.LoadStoreParameter { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java index 61e6efc04a94e..0a35624aeb875 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManager.java @@ -18,8 +18,6 @@ /** * The KeyVault variant of the X509TrustManager. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class KeyVaultTrustManager extends X509ExtendedTrustManager implements X509TrustManager { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java index 18fac1e8e0bdb..73d1e4abe696c 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactory.java @@ -13,8 +13,6 @@ /** * The KeyVault variant of the TrustManagerFactory. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class KeyVaultTrustManagerFactory extends TrustManagerFactorySpi { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java index 09efb3f8d3fdd..a70efe2ca1e60 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultTrustManagerFactoryProvider.java @@ -9,8 +9,6 @@ /** * The Azure KeyVault TrustManagerFactory provider. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class KeyVaultTrustManagerFactoryProvider extends Provider { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java index 2a21d6831e965..90460273d213a 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/LegacyRestClient.java @@ -18,8 +18,6 @@ /** * The RestClient that uses the Apache HttpClient class. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ class LegacyRestClient implements RestClient { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java index 218558b7d5acf..510262d5b810f 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClient.java @@ -7,8 +7,6 @@ /** * The REST client API. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ interface RestClient { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java index 7989e661c360a..5d31247675059 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/RestClientFactory.java @@ -5,8 +5,6 @@ /** * The RestClientFactory. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ class RestClientFactory { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java index 52eb043861123..c874a5483b3c3 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateBundle.java @@ -7,8 +7,6 @@ /** * The CertificateBundle REST model. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class CertificateBundle implements Serializable { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java index a3d4c7ddb5906..66dbcf277c66d 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateItem.java @@ -7,8 +7,6 @@ /** * The CertificateItem REST model. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class CertificateItem implements Serializable { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java index bb64cb7b4d37b..59dd984e3db49 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificateListResult.java @@ -8,8 +8,6 @@ /** * The CertificateItem REST model. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class CertificateListResult implements Serializable { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java index 37f0eb540b467..e678c296b6bbe 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/CertificatePolicy.java @@ -7,8 +7,6 @@ /** * The CertificatePolicy REST model. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class CertificatePolicy implements Serializable { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java index 3a5b4a9eb385b..52ee90d4826a3 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/KeyProperties.java @@ -7,8 +7,6 @@ /** * The KeyProperties REST model. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class KeyProperties implements Serializable { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java index ec310f9b9163f..e394baaa55910 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/OAuthToken.java @@ -6,8 +6,6 @@ /** * An OAuth2 token. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class OAuthToken implements Serializable { diff --git a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java index 301acf9eff3f6..a15f8ba47745e 100644 --- a/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java +++ b/sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/rest/SecretBundle.java @@ -7,8 +7,6 @@ /** * The SecretBundle REST model. - * - * @author Manfred Riem (manfred.riem@microsoft.com) */ public class SecretBundle implements Serializable {