Skip to content

Commit 4b6a5ab

Browse files
Support connect to multi keyvault for keyless (Azure#24718)
1 parent e72e89d commit 4b6a5ab

File tree

9 files changed

+53
-17
lines changed

9 files changed

+53
-17
lines changed

eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545
<!-- Fields tenantId, clientId and clientSecret are not set in all constructors. -->
4646
<suppress checks="com.azure.tools.checkstyle.checks.EnforceFinalFieldsCheck" files="com.azure.security.keyvault.jca.implementation.KeyVaultClient"/>
4747

48+
<!-- We should move KeyVaultPrivateKey into implementation. -->
49+
<suppress checks="com.azure.tools.checkstyle.checks.NoImplInPublicAPI" files="com.azure.security.keyvault.jca.KeyVaultPrivateKey"/>
50+
4851
<!-- Fields defaultTrustManager and keyStore might be set more than once. -->
4952
<suppress checks="com.azure.tools.checkstyle.checks.EnforceFinalFieldsCheck" files="com.azure.security.keyvault.jca.KeyVaultTrustManager"/>
5053

eng/code-quality-reports/src/main/resources/spotbugs/spotbugs-exclude.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2414,6 +2414,10 @@
24142414
<Method name="~(get|post)"/>
24152415
<Bug pattern="RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE"/>
24162416
</Match>
2417+
<Match>
2418+
<Class name="com.azure.security.keyvault.jca.KeyVaultPrivateKey"/>
2419+
<Bug pattern="SE_BAD_FIELD"/>
2420+
</Match>
24172421

24182422
<!-- Returning a new copy of the object is not necessary for queuing system use cases.
24192423
Client do not change content of message once message is created. Array copy would degrade the performance.

sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultPrivateKey.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
package com.azure.security.keyvault.jca;
55

6+
import com.azure.security.keyvault.jca.implementation.KeyVaultClient;
7+
68
import javax.crypto.SecretKey;
79
import java.security.PrivateKey;
810

@@ -20,14 +22,35 @@ public class KeyVaultPrivateKey implements PrivateKey, SecretKey {
2022

2123
private String algorithm;
2224

25+
private final KeyVaultClient keyVaultClient;
26+
2327
/**
2428
* Builder for key vault private key
2529
* @param algorithm algorithm
2630
* @param kid The key id
31+
* @param keyVaultClient related keyVaultClient
2732
*/
28-
public KeyVaultPrivateKey(String algorithm, String kid) {
33+
public KeyVaultPrivateKey(String algorithm, String kid, KeyVaultClient keyVaultClient) {
2934
this.algorithm = algorithm;
3035
this.kid = kid;
36+
this.keyVaultClient = keyVaultClient;
37+
}
38+
39+
/**
40+
* Builder for key vault private key
41+
* @param algorithm algorithm
42+
* @param kid The key id
43+
*/
44+
public KeyVaultPrivateKey(String algorithm, String kid) {
45+
this(algorithm, kid, null);
46+
}
47+
48+
/**
49+
* Get related keyVaultClient, which will be used when signature
50+
* @return related keyVaultClient
51+
*/
52+
public KeyVaultClient getKeyVaultClient() {
53+
return keyVaultClient;
3154
}
3255

3356
/**

sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/implementation/KeyVaultClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ public Key getKey(String alias, char[] password) {
330330
LOGGER.exiting("KeyVaultClient", "getKey", null);
331331
return Optional.ofNullable(certificateBundle)
332332
.map(CertificateBundle::getKid)
333-
.map(kid -> new KeyVaultPrivateKey(keyType, kid))
333+
.map(kid -> new KeyVaultPrivateKey(keyType, kid, this))
334334
.orElse(null);
335335
}
336336
String certificateSecretUri = certificateBundle.getSid();

sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/implementation/signature/AbstractKeyVaultKeyLessSignature.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import java.security.AlgorithmParameters;
1616
import java.security.InvalidAlgorithmParameterException;
1717
import java.security.spec.AlgorithmParameterSpec;
18-
import static com.azure.security.keyvault.jca.implementation.KeyVaultClient.createKeyVaultClientBySystemProperty;
1918

2019
/**
2120
* KeyVault Signature to key less sign
@@ -35,14 +34,6 @@ public abstract class AbstractKeyVaultKeyLessSignature extends SignatureSpi {
3534
*/
3635
public abstract String getAlgorithmName();
3736

38-
public AbstractKeyVaultKeyLessSignature() {
39-
this.keyVaultClient = createKeyVaultClientBySystemProperty();
40-
}
41-
42-
void setKeyVaultClient(KeyVaultClient keyVaultClient) {
43-
this.keyVaultClient = keyVaultClient;
44-
}
45-
4637
// After throw UnsupportedOperationException, other methods will be called.
4738
// such as RSAPSSSignature#engineInitVerify.
4839
@Override
@@ -81,6 +72,7 @@ protected void engineSetParameter(String param, Object value)
8172
protected void engineInitSign(PrivateKey privateKey, SecureRandom random) {
8273
if (privateKey instanceof KeyVaultPrivateKey) {
8374
keyId = ((KeyVaultPrivateKey) privateKey).getKid();
75+
keyVaultClient = ((KeyVaultPrivateKey) privateKey).getKeyVaultClient();
8476
} else {
8577
throw new UnsupportedOperationException("engineInitSign() not supported which private key is not instance of KeyVaultPrivateKey");
8678
}

sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/implementation/signature/KeyVaultKeyLessECSignature.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ public abstract class KeyVaultKeyLessECSignature extends AbstractKeyVaultKeyLess
3535
protected byte[] engineSign() {
3636
byte[] mHash = getDigestValue();
3737
String encode = Base64.getEncoder().encodeToString(mHash);
38-
byte[] encrypted = keyVaultClient.getSignedWithPrivateKey(keyVaultDigestName, encode, keyId);
39-
return encodeByte(encrypted);
38+
if (keyVaultClient != null) {
39+
byte[] encrypted = keyVaultClient.getSignedWithPrivateKey(keyVaultDigestName, encode, keyId);
40+
return encodeByte(encrypted);
41+
}
42+
return new byte[0];
4043
}
4144

4245
}

sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/implementation/signature/KeyVaultKeyLessRsaSignature.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ protected byte[] engineSign() {
2828
byte[] mHash = getDigestValue();
2929
String encode = Base64.getEncoder().encodeToString(mHash);
3030
//For all RSA type certificate in keyVault, we can use PS256 to encrypt.
31-
return keyVaultClient.getSignedWithPrivateKey("PS256", encode, keyId);
31+
if (keyVaultClient != null) {
32+
return keyVaultClient.getSignedWithPrivateKey("PS256", encode, keyId);
33+
}
34+
return new byte[0];
3235
}
3336

3437
@Override

sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/implementation/signature/KeyVaultKeyLessECSignatureTest.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package com.azure.security.keyvault.jca.implementation.signature;
55

66
import com.azure.security.keyvault.jca.KeyVaultEncode;
7+
import com.azure.security.keyvault.jca.KeyVaultPrivateKey;
78
import com.azure.security.keyvault.jca.implementation.KeyVaultClient;
89
import org.junit.jupiter.api.Assertions;
910
import org.junit.jupiter.api.BeforeEach;
@@ -24,6 +25,8 @@ public class KeyVaultKeyLessECSignatureTest {
2425

2526
private final KeyVaultClient keyVaultClient = mock(KeyVaultClient.class);
2627

28+
private final KeyVaultPrivateKey keyVaultPrivateKey = mock(KeyVaultPrivateKey.class);
29+
2730
private final byte[] signedWithES256 = "fake256Value".getBytes();
2831
private final byte[] signedWithES384 = "fake384Value".getBytes();
2932

@@ -98,11 +101,12 @@ public void engineSetParameterTest() {
98101
public void setDigestNameAndEngineSignTest() {
99102
keyVaultKeyLessECSignature = new KeyVaultKeyLessEcSha256Signature();
100103
when(keyVaultClient.getSignedWithPrivateKey(ArgumentMatchers.eq("ES256"), anyString(), ArgumentMatchers.eq(null))).thenReturn(signedWithES256);
101-
keyVaultKeyLessECSignature.setKeyVaultClient(keyVaultClient);
104+
when(keyVaultPrivateKey.getKeyVaultClient()).thenReturn(keyVaultClient);
105+
keyVaultKeyLessECSignature.engineInitSign(keyVaultPrivateKey, null);
102106
Assertions.assertArrayEquals(KeyVaultEncode.encodeByte(signedWithES256), keyVaultKeyLessECSignature.engineSign());
103107

104108
keyVaultKeyLessECSignature = new KeyVaultKeyLessEcSha384Signature();
105-
keyVaultKeyLessECSignature.setKeyVaultClient(keyVaultClient);
109+
keyVaultKeyLessECSignature.engineInitSign(keyVaultPrivateKey, null);
106110
when(keyVaultClient.getSignedWithPrivateKey(ArgumentMatchers.eq("ES384"), anyString(), ArgumentMatchers.eq(null))).thenReturn(signedWithES384);
107111
assertArrayEquals(KeyVaultEncode.encodeByte(signedWithES384), keyVaultKeyLessECSignature.engineSign());
108112
}

sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/implementation/signature/KeyVaultKeyLessRsaSignatureTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
package com.azure.security.keyvault.jca.implementation.signature;
55

6+
import com.azure.security.keyvault.jca.KeyVaultPrivateKey;
67
import com.azure.security.keyvault.jca.implementation.KeyVaultClient;
78
import org.junit.jupiter.api.BeforeEach;
89
import org.junit.jupiter.api.Test;
@@ -29,6 +30,8 @@ public class KeyVaultKeyLessRsaSignatureTest {
2930

3031
private final KeyVaultClient keyVaultClient = mock(KeyVaultClient.class);
3132

33+
private final KeyVaultPrivateKey keyVaultPrivateKey = mock(KeyVaultPrivateKey.class);
34+
3235
@BeforeEach
3336
public void before() {
3437
System.setProperty("azure.keyvault.uri", KEY_VAULT_TEST_URI_GLOBAL);
@@ -97,7 +100,8 @@ public void engineSetParameterTest() {
97100
@Test
98101
public void setDigestNameAndEngineSignTest() throws InvalidAlgorithmParameterException {
99102
keyVaultKeyLessRsaSignature = new KeyVaultKeyLessRsaSignature();
100-
keyVaultKeyLessRsaSignature.setKeyVaultClient(keyVaultClient);
103+
when(keyVaultPrivateKey.getKeyVaultClient()).thenReturn(keyVaultClient);
104+
keyVaultKeyLessRsaSignature.engineInitSign(keyVaultPrivateKey, null);
101105
keyVaultKeyLessRsaSignature.engineSetParameter(new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 20, 1));
102106
when(keyVaultClient.getSignedWithPrivateKey(ArgumentMatchers.eq("PS256"), anyString(), ArgumentMatchers.eq(null))).thenReturn("fakeValue".getBytes());
103107
assertArrayEquals("fakeValue".getBytes(), keyVaultKeyLessRsaSignature.engineSign());

0 commit comments

Comments
 (0)