From 568e41f70454bcf96b6bf3057df8f4573b2d878f Mon Sep 17 00:00:00 2001 From: tiffanyachen Date: Mon, 4 Jun 2018 12:12:40 -0700 Subject: [PATCH 1/5] min addititons for rsa-oaep-256 and rsassa-pss support --- .../cryptography/AlgorithmResolver.java | 2 + .../cryptography/algorithms/RsaSignature.java | 86 ++++++++++++++ .../cryptography/algorithms/RsaesOaep256.java | 103 +++++++++++++++++ .../cryptography/algorithms/RsassaPss.java | 105 ++++++++++++++++++ .../cryptography/test/RsaKeyTest.java | 27 +++++ 5 files changed, 323 insertions(+) create mode 100644 azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaesOaep256.java create mode 100644 azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsassaPss.java diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/AlgorithmResolver.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/AlgorithmResolver.java index 7727041..c0c2f84 100644 --- a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/AlgorithmResolver.java +++ b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/AlgorithmResolver.java @@ -25,6 +25,7 @@ import com.microsoft.azure.keyvault.cryptography.algorithms.Rs256; import com.microsoft.azure.keyvault.cryptography.algorithms.Rsa15; import com.microsoft.azure.keyvault.cryptography.algorithms.RsaOaep; +import com.microsoft.azure.keyvault.cryptography.algorithms.RsaesOaep256; public class AlgorithmResolver { @@ -45,6 +46,7 @@ public class AlgorithmResolver { Default.put(Rsa15.ALGORITHM_NAME, new Rsa15()); Default.put(RsaOaep.ALGORITHM_NAME, new RsaOaep()); + Default.put(RsaesOaep256.ALGORITHM_NAME, new RsaesOaep256()); Default.put( Rs256.ALGORITHM_NAME, new Rs256() ); // Default.put( RsNull.ALGORITHM_NAME, new RsNull() ); diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaSignature.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaSignature.java index 2e5a475..2b3e141 100644 --- a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaSignature.java +++ b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaSignature.java @@ -10,8 +10,10 @@ import java.security.KeyPair; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; +import java.security.spec.PSSParameterSpec; import java.util.Arrays; import com.microsoft.azure.keyvault.cryptography.AsymmetricSignatureAlgorithm; @@ -125,6 +127,90 @@ protected BigInteger RSAVP1(RSAPublicKey K, BigInteger s) { return s.modPow(e, n); } + /** + * See https://tools.ietf.org/html/rfc3447#section-9.1.1 + */ + protected byte[] EMSA_PSS_ENCODE_HASH(byte[] mHash, int emLen, String algorithm) { + // Let mHash = Hash(M), an octet string of length hLen. + // This function takes in the mHash. + + PSSParameterSpec spec = PSSParameterSpec.DEFAULT; + spec.getMGFAlgorithm(); + MessageDigest hash = null; + try { + hash = MessageDigest.getInstance(spec.getDigestAlgorithm()); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + int sLen = PSSParameterSpec.DEFAULT.getSaltLength(); + int hLen = mHash.length; + + // If emLen < hLen + sLen + 2, output "encoding error" and stop. + if (emLen < (hLen + sLen + 2)) { + throw new IllegalArgumentException("encoding error"); + } + + // Generate a random octet string salt of length sLen; if sLen = 0, + // then salt is the empty string. + + byte[] salt = new byte[hash.getDigestLength()]; + SecureRandom rng = new SecureRandom(); + rng.nextBytes(salt); + + // 5. Let + // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt; + // M' is an octet string of length 8 + hLen + sLen with eight + // initial zero octets. + + hash.update(new byte[8]); + hash.update(mHash); + + // 6. Let H = Hash(M'), an octet string of length hLen. + byte[] H = hash.digest(salt); + + + // 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2 + // zero octets. The length of PS may be 0. + + // 8. Let DB = PS || 0x01 || salt; DB is an octet string of length + // emLen - hLen - 1. + + byte[] DB = new byte[emLen - hLen - 1]; + DB[emLen - sLen - hLen - 2] = 0x01; + System.arraycopy(salt, 0, DB, emLen - sLen - hLen - 1, sLen); + + // 9. Let dbMask = MGF(H, emLen - hLen - 1). + byte[] dbMask = + } + + /** + * See https://tools.ietf.org/html/rfc3447#appendix-B.2.1 + * @param digest + * @param mgfSeed + * @param maskLen + * @return + */ + protected byte[] MGF(MessageDigest digest, byte[] mgfSeed, int maskLen) { + int hashCount = (maskLen + digest.getDigestLength() - 1) / digest.getDigestLength(); + + byte[] mask = new byte[0]; + + for (int i = 0; i < hashCount; i++) { + digest.update(mgfSeed); + digest.update(new byte[3]); + digest.update((byte) i); + byte[] hash = digest.digest(); + + mask = Bytes.concat(mask, hash); + } + + byte[] output = new byte[maskLen]; + System.arraycopy(mask, 0, output, 0, output.length); + + return output; + } + /* * See https://tools.ietf.org/html/rfc3447#section-9.2 */ diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaesOaep256.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaesOaep256.java new file mode 100644 index 0000000..faff9f9 --- /dev/null +++ b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaesOaep256.java @@ -0,0 +1,103 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + */ + +package com.microsoft.azure.keyvault.cryptography.algorithms; + +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +import com.microsoft.azure.keyvault.cryptography.ICryptoTransform; + +public final class RsaesOaep256 extends RsaEncryption { + + class RsaesOaep256Decryptor implements ICryptoTransform { + + private final Cipher _cipher; + + RsaesOaep256Decryptor(KeyPair keyPair, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { + + // Create a cipher object using the provider, if specified + if (provider == null) { + _cipher = Cipher.getInstance(RSAESOAEP256); + } else { + _cipher = Cipher.getInstance(RSAESOAEP256, provider); + } + + // encrypt the plain text using the public key + _cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); + } + + @Override + public byte[] doFinal(byte[] plaintext) throws IllegalBlockSizeException, BadPaddingException { + + return _cipher.doFinal(plaintext); + } + + } + + class RsaesOaep256Encryptor implements ICryptoTransform { + + private final Cipher _cipher; + + RsaesOaep256Encryptor(KeyPair keyPair, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { + + // Create a cipher object using the provider, if specified + if (provider == null) { + _cipher = Cipher.getInstance(RSAESOAEP256); + } else { + _cipher = Cipher.getInstance(RSAESOAEP256, provider); + } + + // encrypt the plain text using the public key + _cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); + } + + @Override + public byte[] doFinal(byte[] plaintext) throws IllegalBlockSizeException, BadPaddingException { + + return _cipher.doFinal(plaintext); + } + + } + + final static String RSAESOAEP256 = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"; + + public final static String ALGORITHM_NAME = "RSAES-OAEP-SHA256"; + + public RsaesOaep256() { + super(ALGORITHM_NAME); + } + + @Override + public ICryptoTransform CreateEncryptor(KeyPair keyPair) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { + return CreateEncryptor(keyPair, null); + } + + @Override + public ICryptoTransform CreateEncryptor(KeyPair keyPair, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { + + return new RsaesOaep256Encryptor(keyPair, provider); + } + + @Override + public ICryptoTransform CreateDecryptor(KeyPair keyPair) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { + return CreateDecryptor(keyPair, null); + } + + @Override + public ICryptoTransform CreateDecryptor(KeyPair keyPair, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { + + return new RsaesOaep256Decryptor(keyPair, provider); + } + +} diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsassaPss.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsassaPss.java new file mode 100644 index 0000000..321d895 --- /dev/null +++ b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsassaPss.java @@ -0,0 +1,105 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + */ + +package com.microsoft.azure.keyvault.cryptography.algorithms; + +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PSSParameterSpec; +import java.security.Signature; + +import com.microsoft.azure.keyvault.cryptography.ByteExtensions; +import com.microsoft.azure.keyvault.cryptography.ISignatureTransform; + +/** + * + */ +public class RsassaPss extends RsaSignature { + + static final String RsaNone = "RSA/ECB/PKCS1Padding"; + + class Rs256SignatureTransform implements ISignatureTransform { + + private final KeyPair _keyPair; + private final int _emLen; + + Rs256SignatureTransform(KeyPair keyPair) { + _keyPair = keyPair; + + BigInteger modulus = ((RSAPublicKey)_keyPair.getPublic()).getModulus(); + + _emLen = getOctetLength( modulus.bitLength() ); + + } + + @Override + public byte[] sign(byte[] digest) throws NoSuchAlgorithmException { + + Signature signature = Signature.getInstance(ALGORITHM); + signature.setParameter(PSSParameterSpec.DEFAULT); + signature.initSign(_keyPair.getPrivate()); + signature.update(digest); + return signature.sign(); + + // Signing isn't just a case of encrypting the digest, there is much more to do. + // For details of the algorithm, see https://tools.ietf.org/html/rfc3447#section-8.2 + + if ( _keyPair.getPrivate() == null ) { + // TODO + } + + byte[] EM = EMSA_PSS_ENCODE_HASH(digest, _emLen, "SHA-256"); + + // Construct the encoded message + byte[] EM = EMSA_PKCS1_V1_5_ENCODE_HASH(digest, _emLen, "SHA-256"); + + // Convert to integer message + BigInteger s = OS2IP(EM); + + // RSASP1(s) + s = RSASP1((RSAPrivateKey)_keyPair.getPrivate(), s); + + // Convert to octet sequence + return I2OSP(s, _emLen ); + } + + @Override + public boolean verify(byte[] digest, byte[] signature) throws NoSuchAlgorithmException { + + if ( signature.length != _emLen ) { + throw new IllegalArgumentException( "invalid signature length"); + } + + // Convert to integer signature + BigInteger s = OS2IP(signature); + + // Convert integer message + BigInteger m = RSAVP1((RSAPublicKey)_keyPair.getPublic(), s); + + byte[] EM = I2OSP(m, _emLen ); + byte[] EM2 = EMSA_PKCS1_V1_5_ENCODE_HASH(digest, _emLen, "SHA-256"); + + // Use constant time compare + return ByteExtensions.sequenceEqualConstantTime(EM, EM2); + } + + } + + public final static String ALGORITHM_NAME = "RS256"; + + public RsassaPss() { + super(ALGORITHM_NAME); + } + + @Override + public ISignatureTransform createSignatureTransform(KeyPair keyPair) { + + return new Rs256SignatureTransform(keyPair); + } +} diff --git a/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java b/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java index 4944910..0a03dbe 100644 --- a/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java +++ b/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java @@ -19,6 +19,7 @@ import com.microsoft.azure.keyvault.cryptography.algorithms.Rs256; import com.microsoft.azure.keyvault.cryptography.algorithms.Rsa15; import com.microsoft.azure.keyvault.cryptography.algorithms.RsaOaep; +import com.microsoft.azure.keyvault.cryptography.algorithms.RsaesOaep256; import com.microsoft.azure.keyvault.webkey.JsonWebKey; public class RsaKeyTest { @@ -98,6 +99,31 @@ public void testRsaOaep() throws Exception { key.close(); } + + @Test + public void testRsaesOaep256() throws Exception { + + RsaKey key = getTestRsaKey(); + + // Wrap and Unwrap + Pair wrapped = key.wrapKeyAsync(CEK, RsaesOaep256.ALGORITHM_NAME).get(); + byte[] unwrapped = key.unwrapKeyAsync(wrapped.getLeft(), wrapped.getRight()).get(); + + // Assert + assertEquals(RsaesOaep256.ALGORITHM_NAME, wrapped.getRight()); + assertArrayEquals(CEK, unwrapped); + + // Encrypt and Decrypt + Triple encrypted = key.encryptAsync(CEK, null, null, RsaesOaep256.ALGORITHM_NAME).get(); + byte[] decrypted = key.decryptAsync(encrypted.getLeft(), null, null, null, encrypted.getRight()).get(); + + // Assert + assertEquals(RsaesOaep256.ALGORITHM_NAME, encrypted.getRight()); + assertArrayEquals(CEK, decrypted); + + key.close(); + } + @Test public void testDefaultAlgorithm() throws Exception { @@ -127,6 +153,7 @@ public void testDefaultAlgorithm() throws Exception { key.close(); } + @Test public void testSignVerify() throws Exception { From 7a1802c888b2eb8fcf2a3bd2d01cd3a78deca42f Mon Sep 17 00:00:00 2001 From: tiffanyachen Date: Fri, 8 Jun 2018 13:06:28 -0700 Subject: [PATCH 2/5] Added RSASSA-PSS and recorded tests --- azure-keyvault-cryptography/pom.xml | 64 ++- .../cryptography/AlgorithmResolver.java | 8 + .../azure/keyvault/cryptography/RsaKey.java | 7 +- .../cryptography/algorithms/Ps256.java | 21 + .../cryptography/algorithms/Ps384.java | 21 + .../cryptography/algorithms/Ps512.java | 19 + .../cryptography/algorithms/PsBase.java | 97 ++++ .../cryptography/algorithms/RsaSignature.java | 535 +++++++++++------- .../cryptography/algorithms/RsassaPss.java | 105 ---- .../test/RsaKeyBCProviderTest.java | 2 +- .../cryptography/test/RsaKeyTest.java | 389 ++++++++++++- .../session-records/testDefaultAlgorithm.json | 4 + .../session-records/testRsa15.json | 4 + .../session-records/testRsaOaep.json | 4 + .../session-records/testRsaesOaep256.json | 4 + .../session-records/testSignVerify.json | 4 + .../session-records/testSignVerifyPs256.json | 4 + .../session-records/testSignVerifyPs384.json | 4 + .../session-records/testSignVerifyPs512.json | 4 + .../testSignVerifyServicePs256.json | 112 ++++ .../testSignVerifyServicePs384.json | 112 ++++ .../testSignVerifyServicePs512.json | 112 ++++ .../session-records/testToFromJsonWebKey.json | 4 + 23 files changed, 1264 insertions(+), 376 deletions(-) create mode 100644 azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps256.java create mode 100644 azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps384.java create mode 100644 azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps512.java create mode 100644 azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/PsBase.java delete mode 100644 azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsassaPss.java create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testDefaultAlgorithm.json create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testRsa15.json create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testRsaOaep.json create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testRsaesOaep256.json create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testSignVerify.json create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs256.json create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs384.json create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs512.json create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs256.json create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs384.json create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs512.json create mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testToFromJsonWebKey.json diff --git a/azure-keyvault-cryptography/pom.xml b/azure-keyvault-cryptography/pom.xml index eae8042..14a6943 100644 --- a/azure-keyvault-cryptography/pom.xml +++ b/azure-keyvault-cryptography/pom.xml @@ -4,12 +4,12 @@ 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-parent - 1.1-beta-1 - ../pom.xml - + + com.microsoft.azure + azure-keyvault-parent + 1.1-beta-1 + ../pom.xml + azure-keyvault-cryptography jar @@ -40,38 +40,46 @@ - - - junit - junit - test - - - org.bouncycastle - bcprov-jdk15on - test - 1.59 - - - com.microsoft.azure - azure-keyvault-webkey - 1.1-beta-1 - - + + + org.bouncycastle + bcprov-jdk15on + test + 1.59 + + + com.microsoft.azure + azure-keyvault-webkey + 1.1-beta-1 + + com.microsoft.azure azure-keyvault-core 1.0.0 + + junit + junit + test + + + com.microsoft.azure + azure-keyvault + test + 1.1-beta-1 + com.microsoft.rest client-runtime 1.3.0 + test com.microsoft.azure - azure-client-authentication - 1.3.0 + azure-mgmt-resources + 1.3.1-SNAPSHOT + test-jar + test - - + diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/AlgorithmResolver.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/AlgorithmResolver.java index c0c2f84..31bf10e 100644 --- a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/AlgorithmResolver.java +++ b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/AlgorithmResolver.java @@ -22,10 +22,14 @@ import com.microsoft.azure.keyvault.cryptography.algorithms.Es256; import com.microsoft.azure.keyvault.cryptography.algorithms.Es384; import com.microsoft.azure.keyvault.cryptography.algorithms.Es512; +import com.microsoft.azure.keyvault.cryptography.algorithms.Ps256; +import com.microsoft.azure.keyvault.cryptography.algorithms.Ps384; +import com.microsoft.azure.keyvault.cryptography.algorithms.Ps512; import com.microsoft.azure.keyvault.cryptography.algorithms.Rs256; import com.microsoft.azure.keyvault.cryptography.algorithms.Rsa15; import com.microsoft.azure.keyvault.cryptography.algorithms.RsaOaep; import com.microsoft.azure.keyvault.cryptography.algorithms.RsaesOaep256; +import com.microsoft.azure.keyvault.cryptography.algorithms.PsBase; public class AlgorithmResolver { @@ -49,6 +53,10 @@ public class AlgorithmResolver { Default.put(RsaesOaep256.ALGORITHM_NAME, new RsaesOaep256()); Default.put( Rs256.ALGORITHM_NAME, new Rs256() ); + Default.put( Ps256.ALGORITHM_NAME, new Ps256()); + Default.put( Ps384.ALGORITHM_NAME, new Ps384()); + Default.put( Ps512.ALGORITHM_NAME, new Ps512()); + // Default.put( RsNull.ALGORITHM_NAME, new RsNull() ); Default.put(Ecdsa256.ALGORITHM_NAME, new Ecdsa256()); diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/RsaKey.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/RsaKey.java index c0ae1b5..6f39ccd 100644 --- a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/RsaKey.java +++ b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/RsaKey.java @@ -22,6 +22,7 @@ import com.microsoft.azure.keyvault.core.IKey; import com.microsoft.azure.keyvault.cryptography.algorithms.Rs256; import com.microsoft.azure.keyvault.cryptography.algorithms.RsaOaep; +import com.microsoft.azure.keyvault.cryptography.algorithms.RsaSignature; import com.microsoft.azure.keyvault.webkey.JsonWebKey; public class RsaKey implements IKey { @@ -346,12 +347,12 @@ public ListenableFuture> signAsync(final byte[] digest, fin throw new NoSuchAlgorithmException(algorithm); } - Rs256 algo = (Rs256)baseAlgorithm; + RsaSignature algo = (RsaSignature) baseAlgorithm; ISignatureTransform signer = algo.createSignatureTransform(_keyPair); try { - return Futures.immediateFuture(Pair.of(signer.sign(digest), Rs256.ALGORITHM_NAME)); + return Futures.immediateFuture(Pair.of(signer.sign(digest), algorithm)); } catch (Exception e) { return Futures.immediateFailedFuture(e); } @@ -376,7 +377,7 @@ public ListenableFuture verifyAsync(final byte[] digest, final byte[] s throw new NoSuchAlgorithmException(algorithm); } - Rs256 algo = (Rs256)baseAlgorithm; + RsaSignature algo = (RsaSignature) baseAlgorithm; ISignatureTransform signer = algo.createSignatureTransform(_keyPair); diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps256.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps256.java new file mode 100644 index 0000000..3b4ea50 --- /dev/null +++ b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps256.java @@ -0,0 +1,21 @@ +package com.microsoft.azure.keyvault.cryptography.algorithms; + +import java.security.KeyPair; + +import com.microsoft.azure.keyvault.cryptography.ISignatureTransform; + +public class Ps256 extends PsBase { + + public final static String ALGORITHM_NAME = "PS256"; + public final static String DIGEST_HASH_NAME = "SHA-256"; + + public Ps256() { + super(ALGORITHM_NAME); + } + + @Override + public ISignatureTransform createSignatureTransform(KeyPair keyPair) { + return createSignatureTransform(keyPair, DIGEST_HASH_NAME); + } + +} diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps384.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps384.java new file mode 100644 index 0000000..7017d3b --- /dev/null +++ b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps384.java @@ -0,0 +1,21 @@ +package com.microsoft.azure.keyvault.cryptography.algorithms; + +import java.security.KeyPair; + +import com.microsoft.azure.keyvault.cryptography.ISignatureTransform; + +public class Ps384 extends PsBase { + + public final static String ALGORITHM_NAME = "PS384"; + public final static String DIGEST_HASH_NAME = "SHA-384"; + + public Ps384() { + super(ALGORITHM_NAME); + } + + @Override + public ISignatureTransform createSignatureTransform(KeyPair keyPair) { + return createSignatureTransform(keyPair, DIGEST_HASH_NAME); + } + +} diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps512.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps512.java new file mode 100644 index 0000000..02b8591 --- /dev/null +++ b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/Ps512.java @@ -0,0 +1,19 @@ +package com.microsoft.azure.keyvault.cryptography.algorithms; + +import java.security.KeyPair; + +import com.microsoft.azure.keyvault.cryptography.ISignatureTransform; + +public class Ps512 extends PsBase { + public final static String ALGORITHM_NAME = "PS512"; + public final static String DIGEST_HASH_NAME = "SHA-512"; + + public Ps512() { + super(ALGORITHM_NAME); + } + + @Override + public ISignatureTransform createSignatureTransform(KeyPair keyPair) { + return createSignatureTransform(keyPair, DIGEST_HASH_NAME); + } +} diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/PsBase.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/PsBase.java new file mode 100644 index 0000000..3ca44c3 --- /dev/null +++ b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/PsBase.java @@ -0,0 +1,97 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + */ + +package com.microsoft.azure.keyvault.cryptography.algorithms; + +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PSSParameterSpec; +import java.util.Arrays; +import java.util.zip.DataFormatException; +import java.security.Signature; + +import com.microsoft.azure.keyvault.cryptography.ByteExtensions; +import com.microsoft.azure.keyvault.cryptography.ISignatureTransform; + +/** + * + */ +public abstract class PsBase extends RsaSignature { + + protected PsBase(String name) { + super(name); + } + + class PsBaseSignatureTransform implements ISignatureTransform { + + private final KeyPair _keyPair; + private final int _emLen; + private final int _modBits; + private final String _digestName; + + PsBaseSignatureTransform(KeyPair keyPair, String digestName) { + _keyPair = keyPair; + BigInteger modulus = ((RSAPublicKey) _keyPair.getPublic()).getModulus(); + _emLen = getOctetLength(modulus.bitLength()); + _modBits = ((RSAPublicKey) _keyPair.getPublic()).getModulus().bitLength(); + _digestName = digestName; + } + + @Override + public byte[] sign(byte[] digest) throws NoSuchAlgorithmException { + + if (_keyPair.getPrivate() == null) { + throw new IllegalArgumentException("Keypair must have private key to for signing."); + } + + // Construct the encoded message + // Apply the EMSA-PSS encoding operation (Section + // 9.1.1) to the message M to produce an encoded message EM of length + // \ceil ((modBits - 1)/8) octets such that the bit length of the + // integer OS2IP (EM) (see Section 4.2) is at most modBits - 1, where + // modBits is the length in bits of the RSA modulus n: + MessageDigest messageDigest = MessageDigest.getInstance(_digestName); + byte[] EM = EMSA_PSS_ENCODE_HASH(digest, _modBits - 1, messageDigest); + + // Convert to integer message + BigInteger m = OS2IP(EM); + + // RSASP1(s) + m = RSASP1((RSAPrivateKey) _keyPair.getPrivate(), m); + + // Convert to octet sequence + return I2OSP(m, _emLen); + } + + @Override + public boolean verify(byte[] digest, byte[] signature) throws NoSuchAlgorithmException { + + if (signature.length != _emLen) { + throw new IllegalArgumentException("invalid signature length"); + } + + // Convert to integer signature + BigInteger s = OS2IP(signature); + + // Convert integer message + BigInteger m = RSAVP1((RSAPublicKey) _keyPair.getPublic(), s); + + byte[] EM = I2OSP(m, _emLen); + + MessageDigest messageDigest = MessageDigest.getInstance(_digestName); + return EMSA_PSS_VERIFY(digest, EM, _modBits, messageDigest); + } + + } + + public ISignatureTransform createSignatureTransform(KeyPair keyPair, String digestString) { + return new PsBaseSignatureTransform(keyPair, digestString); + } +} diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaSignature.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaSignature.java index 2b3e141..906ccd0 100644 --- a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaSignature.java +++ b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsaSignature.java @@ -13,292 +13,411 @@ import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; -import java.security.spec.PSSParameterSpec; import java.util.Arrays; +import com.google.common.primitives.Bytes; import com.microsoft.azure.keyvault.cryptography.AsymmetricSignatureAlgorithm; import com.microsoft.azure.keyvault.cryptography.ISignatureTransform; import com.microsoft.azure.keyvault.cryptography.Strings; public abstract class RsaSignature extends AsymmetricSignatureAlgorithm { - private static final BigInteger twoFiveSix = new BigInteger("256"); - private static final byte[] sha256Prefix = new byte[] { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, (byte) 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; + private static final BigInteger twoFiveSix = new BigInteger("256"); + private static final byte[] sha256Prefix = new byte[] { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, (byte) 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; protected RsaSignature(String name) { super(name); } - + protected int getOctetLength(int bits) { - return ( bits % 8 > 0 ) ? bits >> 3 + 1 : bits >> 3; + return (bits % 8 > 0) ? bits >> 3 + 1 : bits >> 3; } - + /* * See https://tools.ietf.org/html/rfc3447#section-4.2 */ protected BigInteger OS2IP(byte[] x) { - - if ( x == null || x.length == 0 ) { - throw new IllegalArgumentException("x"); - } - - return new BigInteger(1,x); + + if (x == null || x.length == 0) { + throw new IllegalArgumentException("x"); + } + + return new BigInteger(1, x); } - + /* * See https://tools.ietf.org/html/rfc3447#section-4.1 */ protected byte[] I2OSP(BigInteger x, int xLen) { - - if ( x == null ) { - throw new IllegalArgumentException("x"); - } - - if ( xLen <= 0 ) { - throw new IllegalArgumentException("xLen"); - } - - if ( x.compareTo( twoFiveSix.pow(xLen) ) == 1 ) { - throw new IllegalArgumentException("integer too large"); - } - - // Even if x is less than 256^xLen, sometiems x.toByteArray() returns 257 bytes with leading zero - byte[] bigEndianBytes = x.toByteArray(); - byte[] bytes; - if (bigEndianBytes.length == 257 && bigEndianBytes[0] == 0) { - bytes = Arrays.copyOfRange(bigEndianBytes, 1, 257); - } else { - bytes = bigEndianBytes; - } - - if ( bytes.length > xLen ) { - throw new IllegalArgumentException("integer too large"); - } - - byte[] result = new byte[xLen]; - - System.arraycopy(bytes, 0, result, xLen - bytes.length, bytes.length); - - return result; - } + + if (x == null) { + throw new IllegalArgumentException("x"); + } + + if (xLen <= 0) { + throw new IllegalArgumentException("xLen"); + } + + if (x.compareTo(twoFiveSix.pow(xLen)) == 1) { + throw new IllegalArgumentException("integer too large"); + } + + // Even if x is less than 256^xLen, sometiems x.toByteArray() returns 257 bytes + // with leading zero + byte[] bigEndianBytes = x.toByteArray(); + byte[] bytes; + if (bigEndianBytes.length == 257 && bigEndianBytes[0] == 0) { + bytes = Arrays.copyOfRange(bigEndianBytes, 1, 257); + } else { + bytes = bigEndianBytes; + } + + if (bytes.length > xLen) { + throw new IllegalArgumentException("integer too large"); + } + + byte[] result = new byte[xLen]; + + System.arraycopy(bytes, 0, result, xLen - bytes.length, bytes.length); + + return result; + } /* * See https://tools.ietf.org/html/rfc3447#section-5.2.1 */ protected BigInteger RSASP1(RSAPrivateKey K, BigInteger m) { - - if ( K == null ) { - throw new IllegalArgumentException("K"); - } - - if ( m == null ) { - throw new IllegalArgumentException("m"); - } - - BigInteger n = K.getModulus(); - BigInteger d = K.getPrivateExponent(); - - if ( m.compareTo(BigInteger.ONE) == -1 || m.compareTo(n) != -1 ) { - throw new IllegalArgumentException("message representative out of range"); - } - - return m.modPow(d, n); + + if (K == null) { + throw new IllegalArgumentException("K"); + } + + if (m == null) { + throw new IllegalArgumentException("m"); + } + + BigInteger n = K.getModulus(); + BigInteger d = K.getPrivateExponent(); + + if (m.compareTo(BigInteger.ONE) == -1 || m.compareTo(n) != -1) { + throw new IllegalArgumentException("message representative out of range"); + } + + return m.modPow(d, n); } - + /* * See https://tools.ietf.org/html/rfc3447#section-5.2.2 */ protected BigInteger RSAVP1(RSAPublicKey K, BigInteger s) { - - if ( K == null ) { - throw new IllegalArgumentException("K"); - } - - if ( s == null ) { - throw new IllegalArgumentException("s"); - } - BigInteger n = K.getModulus(); - BigInteger e = K.getPublicExponent(); - - if ( s.compareTo(BigInteger.ONE) == -1 || s.compareTo(n) != -1 ) { - throw new IllegalArgumentException("message representative out of range"); - } - - return s.modPow(e, n); + + if (K == null) { + throw new IllegalArgumentException("K"); + } + + if (s == null) { + throw new IllegalArgumentException("s"); + } + BigInteger n = K.getModulus(); + BigInteger e = K.getPublicExponent(); + + if (s.compareTo(BigInteger.ONE) == -1 || s.compareTo(n) != -1) { + throw new IllegalArgumentException("message representative out of range"); + } + + return s.modPow(e, n); } /** * See https://tools.ietf.org/html/rfc3447#section-9.1.1 + * + * @param mHash the hashed message (hashed with the corresponding digest: i.e., SHA-256 for PS256, SHA-384 for PS384, SHA-512 for PS512 + * @param emBits the maximal bit length of the integer OS2IP(EM) + * @param messageDigest the messageDigest (or hash) that corresponds to the algorithm + * @return */ - protected byte[] EMSA_PSS_ENCODE_HASH(byte[] mHash, int emLen, String algorithm) { + protected byte[] EMSA_PSS_ENCODE_HASH(byte[] mHash, int emBits, MessageDigest messageDigest) { + // Let mHash = Hash(M), an octet string of length hLen. - // This function takes in the mHash. - - PSSParameterSpec spec = PSSParameterSpec.DEFAULT; - spec.getMGFAlgorithm(); - MessageDigest hash = null; - try { - hash = MessageDigest.getInstance(spec.getDigestAlgorithm()); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - - int sLen = PSSParameterSpec.DEFAULT.getSaltLength(); + // function takes in the mHash. + + // salt length for the service corresponds to the digest length, which is the hash length / 8 + int sLen = messageDigest.getDigestLength(); int hLen = mHash.length; - + int emLen = (int) Math.ceil(emBits / 8.0); + // If emLen < hLen + sLen + 2, output "encoding error" and stop. if (emLen < (hLen + sLen + 2)) { throw new IllegalArgumentException("encoding error"); } - + // Generate a random octet string salt of length sLen; if sLen = 0, // then salt is the empty string. - - byte[] salt = new byte[hash.getDigestLength()]; + + byte[] salt = new byte[sLen]; SecureRandom rng = new SecureRandom(); rng.nextBytes(salt); - - // 5. Let + + // 5. Let // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt; // M' is an octet string of length 8 + hLen + sLen with eight // initial zero octets. - - hash.update(new byte[8]); - hash.update(mHash); - - // 6. Let H = Hash(M'), an octet string of length hLen. - byte[] H = hash.digest(salt); - - - // 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2 - // zero octets. The length of PS may be 0. - - // 8. Let DB = PS || 0x01 || salt; DB is an octet string of length + messageDigest.update(new byte[8]); + messageDigest.update(mHash); + messageDigest.update(salt); + + // 6. Let H = Hash(M'), an octet string of length hLen. + byte[] H = messageDigest.digest(); + + // 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2 + // zero octets. The length of PS may be 0. + byte[] PS = new byte[emLen - sLen - hLen - 2]; + + // 8. Let DB = PS || 0x01 || salt; DB is an octet string of length // emLen - hLen - 1. - + byte[] DB = new byte[emLen - hLen - 1]; - DB[emLen - sLen - hLen - 2] = 0x01; + + System.arraycopy(PS, 0, DB, 0, emLen - sLen - hLen - 2); + DB[emLen - sLen - hLen - 2] = (byte) 0x01; System.arraycopy(salt, 0, DB, emLen - sLen - hLen - 1, sLen); - - // 9. Let dbMask = MGF(H, emLen - hLen - 1). - byte[] dbMask = + + // 9. Let dbMask = MGF(H, emLen - hLen - 1). + byte[] dbMask = MGF(H, emLen - hLen - 1, messageDigest); + + byte[] maskedDB = new byte[Math.min(DB.length, dbMask.length)]; + + // 10. Let maskedDB = DB \xor dbMask. + for (int i = 0; i < maskedDB.length; i++) { + maskedDB[i] = (byte) (((int) DB[i]) ^ ((int) dbMask[i])); + } + + // 11. Set the leftmost 8emLen - emBits bits of the leftmost octet in + // maskedDB to zero. + int bitMask = 0x000000FF >>> (8 * emLen - emBits); + maskedDB[0] &= (byte) bitMask; + + // 12. Let EM = maskedDB || H || 0xbc. + return Bytes.concat(maskedDB, H, new byte[] { (byte) 0xbc }); + + } + + /** + * See https://tools.ietf.org/html/rfc3447#section-9.1.2 + * + * @param mHash the hashed message (hashed with the corresponding digest: i.e., SHA-256 for PS256, SHA-384 for PS384, SHA-512 for PS512 + * @param EM encoded message, an octet string of emLen = \ceil(emBits/8) + * @param emBits maximal bit length of the integer OS2IP(EM) + * @param messageDigest the messageDigest that corresponds to the algorithm (see above) + * @return true if output consistent with algorithm, false otherwise + */ + protected boolean EMSA_PSS_VERIFY(byte[] mHash, byte[] EM, int emBits, MessageDigest messageDigest) { + + // salt length for the service corresponds to the digest length, which is the hash length / 8 + int sLen = messageDigest.getDigestLength(); + int hLen = mHash.length; + int emLen = (int) Math.ceil(emBits / 8.0); + + // 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop. + if (emLen < hLen + sLen + 2) { + return false; + } + + // 4. If the rightmost octet of EM does not have hexadecimal value + // 0xbc, output "inconsistent" and stop. + if (EM[EM.length - 1] != (byte) 0xbc) { + return false; + } + + // 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and + // let H be the next hLen octets. + byte[] maskedDB = Arrays.copyOfRange(EM, 0, emLen - hLen - 1); + byte[] H = Arrays.copyOfRange(EM, emLen - hLen - 1, emLen - 1); + + // 6. If the leftmost 8emLen - emBits bits of the leftmost octet in + // maskedDB are not all equal to zero, output "inconsistent" and + // stop. + byte mask = 0x00; + for (int i = 0; i < (8 * emLen - emBits); i++) { + mask = (byte) (mask | (1 << i)); + if ((maskedDB[0] & mask) != 0) { + return false; + } + mask = 0x00; + } + + // 7. Let dbMask = MGF(H, emLen - hLen - 1). + byte[] dbMask = MGF(H, emLen - hLen - 1, messageDigest); + + // 8. Let DB = maskedDB \xor dbMask. + byte[] DB = new byte[Math.min(maskedDB.length, dbMask.length)]; + for (int i = 0; i < maskedDB.length; i++) { + DB[i] = (byte) (maskedDB[i] ^ dbMask[i]); + } + + // 9. Set the leftmost 8emLen - emBits bits of the leftmost octet in DB + // to zero. + + int bitMask = 0x000000FF >> (8 * emLen - emBits + 1); + DB[0] &= bitMask; + + // 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero + // or if the octet at position emLen - hLen - sLen - 1 (the leftmost + // position is "position 1") does not have hexadecimal value 0x01, + // output "inconsistent" and stop. + for (int i = 0; i < (emLen - hLen - sLen - 2); i++) { + if (DB[i] != 0) { + return false; + } + } + + if (DB[emLen - hLen - sLen - 2] != (byte) 0x01) { + return false; + } + + // 11. Let salt be the last sLen octets of DB. + byte[] salt = Arrays.copyOfRange(DB, DB.length - sLen, DB.length); + + // 12. Let + // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ; + // M' is an octet string of length 8 + hLen + sLen with eight + // initial zero octets. + // 13. Let H' = Hash(M'), an octet string of length hLen. + + // 14. If H = H', output "consistent." Otherwise, output "inconsistent." + messageDigest.update(new byte[8]); + messageDigest.update(mHash); + return Arrays.equals(H, messageDigest.digest(salt)); } /** * See https://tools.ietf.org/html/rfc3447#appendix-B.2.1 - * @param digest - * @param mgfSeed - * @param maskLen - * @return + * + * @param mgfSeed seed from which mask is generated, an octet string + * @param maskLen intended length in octets of the mask, at most 2^32 hLen + * @param digest messageDigest - the hash function corresponding to the length of the hash + * @return mask, an octet string of length maskLen */ - protected byte[] MGF(MessageDigest digest, byte[] mgfSeed, int maskLen) { - int hashCount = (maskLen + digest.getDigestLength() - 1) / digest.getDigestLength(); + protected byte[] MGF(byte[] mgfSeed, int maskLen, MessageDigest digest) { + + if (maskLen > Math.pow(2, 32) * 32) { + throw new IllegalArgumentException("mask too long"); + } + int hashCount = (int) (Math.ceil(maskLen * 1.0 / digest.getDigestLength()) - 1); byte[] mask = new byte[0]; - - for (int i = 0; i < hashCount; i++) { + + // 3.For counter from 0 to \lceil{l / hLen}\ceil-1, do the following: + for (int i = 0; i <= hashCount; i++) { digest.update(mgfSeed); - digest.update(new byte[3]); - digest.update((byte) i); + + // a.Convert counter to an octet string C of length 4 with the primitive + // I2OSP: C = I2OSP (counter, 4) + digest.update(I2OSP(BigInteger.valueOf(i), 4)); + + // b.Concatenate the hash of the seed Z and C to the octet string T: T = + // T || Hash (Z || C) byte[] hash = digest.digest(); - mask = Bytes.concat(mask, hash); } byte[] output = new byte[maskLen]; System.arraycopy(mask, 0, output, 0, output.length); - return output; } - + /* * See https://tools.ietf.org/html/rfc3447#section-9.2 */ protected byte[] EMSA_PKCS1_V1_5_ENCODE(byte[] m, int emLen, String algorithm) throws NoSuchAlgorithmException { - - // Check m - if ( m == null || m.length == 0 ) { - throw new IllegalArgumentException("m"); - } - - MessageDigest messageDigest = null; - - // Check algorithm - if ( Strings.isNullOrWhiteSpace(algorithm) ) { - throw new IllegalArgumentException("algorithm"); - } - - // Only supported algorithms - if ( algorithm.equals("SHA-256") ) { - - // Initialize digest - messageDigest = MessageDigest.getInstance("SHA-256"); - } else { - throw new IllegalArgumentException("algorithm"); - } - - // Hash the message - byte[] digest = messageDigest.digest(m); - - // Construct T, the DER encoded DigestInfo structure - return EMSA_PKCS1_V1_5_ENCODE_HASH(digest, emLen, algorithm); + + // Check m + if (m == null || m.length == 0) { + throw new IllegalArgumentException("m"); + } + + MessageDigest messageDigest = null; + + // Check algorithm + if (Strings.isNullOrWhiteSpace(algorithm)) { + throw new IllegalArgumentException("algorithm"); + } + + // Only supported algorithms + if (algorithm.equals("SHA-256")) { + + // Initialize digest + messageDigest = MessageDigest.getInstance("SHA-256"); + } else { + throw new IllegalArgumentException("algorithm"); + } + + // Hash the message + byte[] digest = messageDigest.digest(m); + + // Construct T, the DER encoded DigestInfo structure + return EMSA_PKCS1_V1_5_ENCODE_HASH(digest, emLen, algorithm); } - + /* * See https://tools.ietf.org/html/rfc3447#section-9.2 */ - protected byte[] EMSA_PKCS1_V1_5_ENCODE_HASH(byte[] h, int emLen, String algorithm) throws NoSuchAlgorithmException { - - // Check m - if ( h == null || h.length == 0 ) { - throw new IllegalArgumentException("m"); - } - - byte[] algorithmPrefix = null; - - // Check algorithm - if ( Strings.isNullOrWhiteSpace(algorithm) ) { - throw new IllegalArgumentException("algorithm"); - } - - // Only supported algorithms - if ( algorithm.equals("SHA-256") ) { - - // Initialize prefix and digest - algorithmPrefix = sha256Prefix; - - if ( h.length != 32 ) { - throw new IllegalArgumentException("h is incorrect length for SHA-256"); - } - } else { - throw new IllegalArgumentException("algorithm"); - } - - - // Construct T, the DER encoded DigestInfo structure - byte[] T = new byte[algorithmPrefix.length + h.length]; - - System.arraycopy(algorithmPrefix, 0, T, 0, algorithmPrefix.length); - System.arraycopy(h, 0, T, algorithmPrefix.length, h.length); - - if ( emLen < T.length + 11 ) { - throw new IllegalArgumentException("intended encoded message length too short"); - } - - // Construct PS - byte[] PS = new byte[emLen - T.length - 3]; - - for ( int i = 0; i < PS.length; i++ ) PS[i] = (byte) 0xff; - - // Construct EM - byte[] EM = new byte[PS.length + T.length + 3]; - - EM[0] = 0x00; EM[1] = 0x01; EM[PS.length + 2] = 0x00; - - System.arraycopy(PS, 0, EM, 2, PS.length); - System.arraycopy(T, 0, EM, PS.length + 3, T.length); - - return EM; + protected byte[] EMSA_PKCS1_V1_5_ENCODE_HASH(byte[] h, int emLen, String algorithm) + throws NoSuchAlgorithmException { + + // Check m + if (h == null || h.length == 0) { + throw new IllegalArgumentException("m"); + } + + byte[] algorithmPrefix = null; + + // Check algorithm + if (Strings.isNullOrWhiteSpace(algorithm)) { + throw new IllegalArgumentException("algorithm"); + } + + // Only supported algorithms + if (algorithm.equals("SHA-256")) { + + // Initialize prefix and digest + algorithmPrefix = sha256Prefix; + + if (h.length != 32) { + throw new IllegalArgumentException("h is incorrect length for SHA-256"); + } + } else { + throw new IllegalArgumentException("algorithm"); + } + + // Construct T, the DER encoded DigestInfo structure + byte[] T = new byte[algorithmPrefix.length + h.length]; + + System.arraycopy(algorithmPrefix, 0, T, 0, algorithmPrefix.length); + System.arraycopy(h, 0, T, algorithmPrefix.length, h.length); + + if (emLen < T.length + 11) { + throw new IllegalArgumentException("intended encoded message length too short"); + } + + // Construct PS + byte[] PS = new byte[emLen - T.length - 3]; + + for (int i = 0; i < PS.length; i++) + PS[i] = (byte) 0xff; + + // Construct EM + byte[] EM = new byte[PS.length + T.length + 3]; + + EM[0] = 0x00; + EM[1] = 0x01; + EM[PS.length + 2] = 0x00; + + System.arraycopy(PS, 0, EM, 2, PS.length); + System.arraycopy(T, 0, EM, PS.length + 3, T.length); + + return EM; } public abstract ISignatureTransform createSignatureTransform(KeyPair keyPair); diff --git a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsassaPss.java b/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsassaPss.java deleted file mode 100644 index 321d895..0000000 --- a/azure-keyvault-cryptography/src/main/java/com/microsoft/azure/keyvault/cryptography/algorithms/RsassaPss.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for - * license information. - */ - -package com.microsoft.azure.keyvault.cryptography.algorithms; - -import java.math.BigInteger; -import java.security.KeyPair; -import java.security.NoSuchAlgorithmException; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.PSSParameterSpec; -import java.security.Signature; - -import com.microsoft.azure.keyvault.cryptography.ByteExtensions; -import com.microsoft.azure.keyvault.cryptography.ISignatureTransform; - -/** - * - */ -public class RsassaPss extends RsaSignature { - - static final String RsaNone = "RSA/ECB/PKCS1Padding"; - - class Rs256SignatureTransform implements ISignatureTransform { - - private final KeyPair _keyPair; - private final int _emLen; - - Rs256SignatureTransform(KeyPair keyPair) { - _keyPair = keyPair; - - BigInteger modulus = ((RSAPublicKey)_keyPair.getPublic()).getModulus(); - - _emLen = getOctetLength( modulus.bitLength() ); - - } - - @Override - public byte[] sign(byte[] digest) throws NoSuchAlgorithmException { - - Signature signature = Signature.getInstance(ALGORITHM); - signature.setParameter(PSSParameterSpec.DEFAULT); - signature.initSign(_keyPair.getPrivate()); - signature.update(digest); - return signature.sign(); - - // Signing isn't just a case of encrypting the digest, there is much more to do. - // For details of the algorithm, see https://tools.ietf.org/html/rfc3447#section-8.2 - - if ( _keyPair.getPrivate() == null ) { - // TODO - } - - byte[] EM = EMSA_PSS_ENCODE_HASH(digest, _emLen, "SHA-256"); - - // Construct the encoded message - byte[] EM = EMSA_PKCS1_V1_5_ENCODE_HASH(digest, _emLen, "SHA-256"); - - // Convert to integer message - BigInteger s = OS2IP(EM); - - // RSASP1(s) - s = RSASP1((RSAPrivateKey)_keyPair.getPrivate(), s); - - // Convert to octet sequence - return I2OSP(s, _emLen ); - } - - @Override - public boolean verify(byte[] digest, byte[] signature) throws NoSuchAlgorithmException { - - if ( signature.length != _emLen ) { - throw new IllegalArgumentException( "invalid signature length"); - } - - // Convert to integer signature - BigInteger s = OS2IP(signature); - - // Convert integer message - BigInteger m = RSAVP1((RSAPublicKey)_keyPair.getPublic(), s); - - byte[] EM = I2OSP(m, _emLen ); - byte[] EM2 = EMSA_PKCS1_V1_5_ENCODE_HASH(digest, _emLen, "SHA-256"); - - // Use constant time compare - return ByteExtensions.sequenceEqualConstantTime(EM, EM2); - } - - } - - public final static String ALGORITHM_NAME = "RS256"; - - public RsassaPss() { - super(ALGORITHM_NAME); - } - - @Override - public ISignatureTransform createSignatureTransform(KeyPair keyPair) { - - return new Rs256SignatureTransform(keyPair); - } -} diff --git a/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyBCProviderTest.java b/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyBCProviderTest.java index c9a9c70..10d01e4 100644 --- a/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyBCProviderTest.java +++ b/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyBCProviderTest.java @@ -6,7 +6,7 @@ public class RsaKeyBCProviderTest extends RsaKeyTest { @Before - public void setUp() throws Exception { + public void beforeMethod() throws Exception { try { super.setProvider((Provider) Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider").newInstance()); } catch (Exception ex) { diff --git a/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java b/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java index 0a03dbe..9843b1b 100644 --- a/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java +++ b/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java @@ -1,33 +1,88 @@ package com.microsoft.azure.keyvault.cryptography.test; -import static org.junit.Assert.*; - +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.KeyFactory; +import java.security.KeyPair; import java.security.MessageDigest; import java.security.Provider; +import java.security.spec.KeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; import org.junit.After; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestName; import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.aad.adal4j.AuthenticationContext; +import com.microsoft.aad.adal4j.AuthenticationResult; +import com.microsoft.aad.adal4j.ClientCredential; +import com.microsoft.azure.AzureResponseBuilder; +import com.microsoft.azure.keyvault.KeyIdentifier; +import com.microsoft.azure.keyvault.KeyVaultClient; +import com.microsoft.azure.keyvault.authentication.KeyVaultCredentials; import com.microsoft.azure.keyvault.cryptography.RsaKey; import com.microsoft.azure.keyvault.cryptography.algorithms.Rs256; import com.microsoft.azure.keyvault.cryptography.algorithms.Rsa15; import com.microsoft.azure.keyvault.cryptography.algorithms.RsaOaep; import com.microsoft.azure.keyvault.cryptography.algorithms.RsaesOaep256; +import com.microsoft.azure.keyvault.models.KeyBundle; +import com.microsoft.azure.keyvault.models.KeyOperationResult; +import com.microsoft.azure.keyvault.models.KeyVerifyResult; +import com.microsoft.azure.keyvault.requests.ImportKeyRequest; import com.microsoft.azure.keyvault.webkey.JsonWebKey; +import com.microsoft.azure.keyvault.webkey.JsonWebKeyOperation; +import com.microsoft.azure.keyvault.webkey.JsonWebKeySignatureAlgorithm; +import com.microsoft.azure.keyvault.webkey.JsonWebKeyType; +import com.microsoft.azure.management.resources.core.InterceptorManager; +import com.microsoft.azure.management.resources.core.TestBase; +import com.microsoft.azure.management.resources.fluentcore.utils.ResourceManagerThrottlingInterceptor; +import com.microsoft.azure.serializer.AzureJacksonAdapter; +import com.microsoft.rest.LogLevel; +import com.microsoft.rest.RestClient; +import com.microsoft.rest.credentials.ServiceClientCredentials; +import com.microsoft.rest.interceptors.LoggingInterceptor; public class RsaKeyTest { - // A Content Encryption Key, or Message. This value is kept consistent with the .NET + private static TestBase.TestMode testMode = null; + + protected InterceptorManager interceptorManager = null; + + protected final static String ZERO_SUBSCRIPTION = "00000000-0000-0000-0000-000000000000"; + protected final static String ZERO_TENANT = "00000000-0000-0000-0000-000000000000"; + private static final String PLAYBACK_URI_BASE = "http://localhost:"; + protected static String playbackUri = null; + + static KeyVaultClient keyVaultClient; + final static String KEY_NAME = "otherkey2"; + static String VAULT_URI; + + // A Content Encryption Key, or Message. This value is kept consistent with the + // .NET // unit test cases to enable cross platform testing. - static final byte[] CEK = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte)0x88, (byte)0x99, (byte)0xAA, (byte)0xBB, (byte)0xCC, (byte)0xDD, (byte)0xEE, (byte)0xFF }; - static final String CrossPlatformHash = "qPrtarvzXBKksm5A9v6xnXNtkARcg7n5ox9jjTI+aBE="; + static final byte[] CEK = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0x88, (byte) 0x99, (byte) 0xAA, + (byte) 0xBB, (byte) 0xCC, (byte) 0xDD, (byte) 0xEE, (byte) 0xFF }; + static final String CrossPlatformHash = "qPrtarvzXBKksm5A9v6xnXNtkARcg7n5ox9jjTI+aBE="; static final String CrossPlatformSignature = "RaNc+8WcWxplS8I7ynJLSoLJKz+dgBvrZhIGH3VFlTTyzu7b9d+lpaV9IKhzCNBsgSysKhgL7EZwVCOTBZ4m6xvKSXqVFXYaBPyBTD7VoKPMYMW6ai5x6xV5XAMaZPfMkff3Deg/RXcc8xQ28FhYuUa8yly01GySY4Hk55anEvb2wBxSy1UGun/0LE1lYH3C3XEgSry4cEkJHDJl1hp+wB4J/noXOqn5ECGU+/4ehBJOyW1gtUH0/gRe8yXnDH0AXepHRyH8iBHLWlKX1r+1/OrMulqOoi82RZzJlTyEz9X+bsQhllqGF6n3hdLS6toH9o7wUtwYNqSx82JuQT6iMg=="; private Provider _provider = null; @@ -40,8 +95,46 @@ public static void setUpBeforeClass() throws Exception { public static void tearDownAfterClass() throws Exception { } + @BeforeClass + public static void setUp() throws Exception { + initTestMode(); + initPlaybackUri(); + } + + @Rule + public TestName testName = new TestName(); + @Before - public void setUp() throws Exception { + public void beforeMethod() throws Exception { + VAULT_URI = System.getenv("VAULT_URI"); + + RestClient restClient; + ServiceClientCredentials credentials = createTestCredentials(); + interceptorManager = InterceptorManager.create(testName.getMethodName(), testMode); + + if (isRecordMode()) { + restClient = new RestClient.Builder().withBaseUrl("https://{vaultBaseUrl}") + .withSerializerAdapter(new AzureJacksonAdapter()) + .withResponseBuilderFactory(new AzureResponseBuilder.Factory()).withCredentials(credentials) + .withLogLevel(LogLevel.NONE) + .withNetworkInterceptor(new LoggingInterceptor(LogLevel.BODY_AND_HEADERS)) + .withNetworkInterceptor(interceptorManager.initInterceptor()) + .withInterceptor(new ResourceManagerThrottlingInterceptor()).build(); + + interceptorManager.addTextReplacementRule("https://management.azure.com/", playbackUri + "/"); + interceptorManager.addTextReplacementRule("https://graph.windows.net/", playbackUri + "/"); + + keyVaultClient = new KeyVaultClient(restClient); + } else { // is Playback Mode + restClient = new RestClient.Builder().withBaseUrl(playbackUri + "/") + .withSerializerAdapter(new AzureJacksonAdapter()) + .withResponseBuilderFactory(new AzureResponseBuilder.Factory()).withCredentials(credentials) + .withLogLevel(LogLevel.NONE) + .withNetworkInterceptor(new LoggingInterceptor(LogLevel.BODY_AND_HEADERS)) + .withNetworkInterceptor(interceptorManager.initInterceptor()) + .withInterceptor(new ResourceManagerThrottlingInterceptor()).build(); + keyVaultClient = new KeyVaultClient(restClient); + } } @After @@ -58,8 +151,8 @@ public void testRsa15() throws Exception { RsaKey key = getTestRsaKey(); // Wrap and Unwrap - Pair wrapped = key.wrapKeyAsync(CEK, Rsa15.ALGORITHM_NAME).get(); - byte[] unwrapped = key.unwrapKeyAsync(wrapped.getLeft(), wrapped.getRight()).get(); + Pair wrapped = key.wrapKeyAsync(CEK, Rsa15.ALGORITHM_NAME).get(); + byte[] unwrapped = key.unwrapKeyAsync(wrapped.getLeft(), wrapped.getRight()).get(); // Assert assertEquals(Rsa15.ALGORITHM_NAME, wrapped.getRight()); @@ -67,7 +160,7 @@ public void testRsa15() throws Exception { // Encrypt and Decrypt Triple encrypted = key.encryptAsync(CEK, null, null, Rsa15.ALGORITHM_NAME).get(); - byte[] decrypted = key.decryptAsync(encrypted.getLeft(), null, null, null, encrypted.getRight()).get(); + byte[] decrypted = key.decryptAsync(encrypted.getLeft(), null, null, null, encrypted.getRight()).get(); // Assert assertEquals(Rsa15.ALGORITHM_NAME, encrypted.getRight()); @@ -82,8 +175,8 @@ public void testRsaOaep() throws Exception { RsaKey key = getTestRsaKey(); // Wrap and Unwrap - Pair wrapped = key.wrapKeyAsync(CEK, RsaOaep.ALGORITHM_NAME).get(); - byte[] unwrapped = key.unwrapKeyAsync(wrapped.getLeft(), wrapped.getRight()).get(); + Pair wrapped = key.wrapKeyAsync(CEK, RsaOaep.ALGORITHM_NAME).get(); + byte[] unwrapped = key.unwrapKeyAsync(wrapped.getLeft(), wrapped.getRight()).get(); // Assert assertEquals(RsaOaep.ALGORITHM_NAME, wrapped.getRight()); @@ -91,7 +184,7 @@ public void testRsaOaep() throws Exception { // Encrypt and Decrypt Triple encrypted = key.encryptAsync(CEK, null, null, RsaOaep.ALGORITHM_NAME).get(); - byte[] decrypted = key.decryptAsync(encrypted.getLeft(), null, null, null, encrypted.getRight()).get(); + byte[] decrypted = key.decryptAsync(encrypted.getLeft(), null, null, null, encrypted.getRight()).get(); // Assert assertEquals(RsaOaep.ALGORITHM_NAME, encrypted.getRight()); @@ -99,15 +192,15 @@ public void testRsaOaep() throws Exception { key.close(); } - + @Test public void testRsaesOaep256() throws Exception { RsaKey key = getTestRsaKey(); // Wrap and Unwrap - Pair wrapped = key.wrapKeyAsync(CEK, RsaesOaep256.ALGORITHM_NAME).get(); - byte[] unwrapped = key.unwrapKeyAsync(wrapped.getLeft(), wrapped.getRight()).get(); + Pair wrapped = key.wrapKeyAsync(CEK, RsaesOaep256.ALGORITHM_NAME).get(); + byte[] unwrapped = key.unwrapKeyAsync(wrapped.getLeft(), wrapped.getRight()).get(); // Assert assertEquals(RsaesOaep256.ALGORITHM_NAME, wrapped.getRight()); @@ -115,7 +208,7 @@ public void testRsaesOaep256() throws Exception { // Encrypt and Decrypt Triple encrypted = key.encryptAsync(CEK, null, null, RsaesOaep256.ALGORITHM_NAME).get(); - byte[] decrypted = key.decryptAsync(encrypted.getLeft(), null, null, null, encrypted.getRight()).get(); + byte[] decrypted = key.decryptAsync(encrypted.getLeft(), null, null, null, encrypted.getRight()).get(); // Assert assertEquals(RsaesOaep256.ALGORITHM_NAME, encrypted.getRight()); @@ -123,7 +216,6 @@ public void testRsaesOaep256() throws Exception { key.close(); } - @Test public void testDefaultAlgorithm() throws Exception { @@ -135,16 +227,17 @@ public void testDefaultAlgorithm() throws Exception { assertEquals(Rs256.ALGORITHM_NAME, key.getDefaultSignatureAlgorithm()); // Wrap and Unwrap - Pair wrapped = key.wrapKeyAsync(CEK, key.getDefaultKeyWrapAlgorithm()).get(); - byte[] unwrapped = key.unwrapKeyAsync(wrapped.getLeft(), wrapped.getRight()).get(); + Pair wrapped = key.wrapKeyAsync(CEK, key.getDefaultKeyWrapAlgorithm()).get(); + byte[] unwrapped = key.unwrapKeyAsync(wrapped.getLeft(), wrapped.getRight()).get(); // Assert assertEquals(RsaOaep.ALGORITHM_NAME, wrapped.getRight()); assertArrayEquals(CEK, unwrapped); // Encrypt and Decrypt - Triple encrypted = key.encryptAsync(CEK, null, null, key.getDefaultEncryptionAlgorithm()).get(); - byte[] decrypted = key.decryptAsync(encrypted.getLeft(), null, null, null, encrypted.getRight()).get(); + Triple encrypted = key + .encryptAsync(CEK, null, null, key.getDefaultEncryptionAlgorithm()).get(); + byte[] decrypted = key.decryptAsync(encrypted.getLeft(), null, null, null, encrypted.getRight()).get(); // Assert assertEquals(RsaOaep.ALGORITHM_NAME, encrypted.getRight()); @@ -153,7 +246,6 @@ public void testDefaultAlgorithm() throws Exception { key.close(); } - @Test public void testSignVerify() throws Exception { @@ -162,16 +254,16 @@ public void testSignVerify() throws Exception { MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hash = digest.digest(CEK); - byte[] crossPlatformHash = Base64.decodeBase64(CrossPlatformHash); + byte[] crossPlatformHash = Base64.decodeBase64(CrossPlatformHash); byte[] crossPlatformSignature = Base64.decodeBase64(CrossPlatformSignature); // Check the hash - assertNotNull( hash ); - assertEquals( 32, hash.length ); + assertNotNull(hash); + assertEquals(32, hash.length); assertArrayEquals(hash, crossPlatformHash); Pair signature = key.signAsync(hash, "RS256").get(); - boolean result = key.verifyAsync(hash, signature.getLeft(), "RS256").get(); + boolean result = key.verifyAsync(hash, signature.getLeft(), "RS256").get(); // Check the signature assertTrue(result); @@ -185,12 +277,137 @@ public void testSignVerify() throws Exception { key.close(); } + @Test + public void testSignVerifyPs256() throws Exception { + signVerifyLocal("PS256", "SHA-256"); + } + + @Test + public void testSignVerifyPs384() throws Exception { + signVerifyLocal("PS384", "SHA-384"); + } + + @Test + public void testSignVerifyPs512() throws Exception { + signVerifyLocal("PS512", "SHA-512"); + } + + private void signVerifyLocal(String algName, String digestAlg) throws Exception { + RsaKey key = getTestRsaKey(); + + MessageDigest digest = MessageDigest.getInstance(digestAlg); + byte[] hash = digest.digest(CEK); + + Pair signature = key.signAsync(hash, algName).get(); + boolean result = key.verifyAsync(hash, signature.getLeft(), algName).get(); + + assertTrue(result); + + key.close(); + } + + @Test + public void testSignVerifyServicePs256() throws Exception { + signVerifyWithService(KEY_NAME, JsonWebKeySignatureAlgorithm.PS256, "SHA-256"); + } + + @Test + public void testSignVerifyServicePs384() throws Exception { + signVerifyWithService(KEY_NAME, JsonWebKeySignatureAlgorithm.PS384, "SHA-384"); + } + + @Test + public void testSignVerifyServicePs512() throws Exception { + signVerifyWithService(KEY_NAME, JsonWebKeySignatureAlgorithm.PS512, "SHA-512"); + } + + private void signVerifyWithService(String keyName, JsonWebKeySignatureAlgorithm algorithm, String digestAlg) + throws Exception { + + JsonWebKey testKey = importTestKey(keyName); + + RsaKey key = new RsaKey(testKey.kid(), getWellKnownKey()); + + KeyIdentifier keyId = new KeyIdentifier(testKey.kid()); + + // Test variables + byte[] plainText = new byte[100]; + new Random(0x1234567L).nextBytes(plainText); + MessageDigest md = MessageDigest.getInstance(digestAlg); + md.update(plainText); + byte[] digest = md.digest(); + byte[] signature; + + KeyOperationResult result; + KeyVerifyResult verifyResult; + + // Using kid WO version + { + signature = key.signAsync(digest, algorithm.toString()).get().getLeft(); + verifyResult = keyVaultClient.verify(keyId.baseIdentifier(), algorithm, digest, signature); + Assert.assertEquals(new Boolean(true), verifyResult.value()); + } + + { + result = keyVaultClient.sign(keyId.baseIdentifier(), algorithm, digest); + signature = result.result(); + Assert.assertTrue(key.verifyAsync(digest, signature, algorithm.toString()).get()); + } + key.close(); + } + + private static JsonWebKey importTestKey(String keyName) throws Exception { + + KeyBundle keyBundle = new KeyBundle(); + JsonWebKey key = JsonWebKey.fromRSA(getTestKeyMaterial()); + + key.withKty(JsonWebKeyType.RSA); + key.withKeyOps(Arrays.asList(JsonWebKeyOperation.ENCRYPT, JsonWebKeyOperation.DECRYPT, JsonWebKeyOperation.SIGN, + JsonWebKeyOperation.VERIFY, JsonWebKeyOperation.WRAP_KEY, JsonWebKeyOperation.UNWRAP_KEY)); + + System.out.println(key.kid()); + + keyBundle = keyVaultClient + .importKey(new ImportKeyRequest.Builder(VAULT_URI, KEY_NAME, key).withHsm(false).build()); + + return keyBundle.key(); + } + + private static KeyPair getTestKeyMaterial() throws Exception { + return getWellKnownKey(); + } + + private static KeyPair getWellKnownKey() throws Exception { + BigInteger modulus = new BigInteger( + "27266783713040163753473734334021230592631652450892850648620119914958066181400432364213298181846462385257448168605902438305568194683691563208578540343969522651422088760509452879461613852042845039552547834002168737350264189810815735922734447830725099163869215360401162450008673869707774119785881115044406101346450911054819448375712432746968301739007624952483347278954755460152795801894283389540036131881712321193750961817346255102052653789197325341350920441746054233522546543768770643593655942246891652634114922277138937273034902434321431672058220631825053788262810480543541597284376261438324665363067125951152574540779"); + BigInteger publicExponent = new BigInteger("65537"); + BigInteger privateExponent = new BigInteger( + "10466613941269075477152428927796086150095892102279802916937552172064636326433780566497000814207416485739683286961848843255766652023400959086290344987308562817062506476465756840999981989957456897020361717197805192876094362315496459535960304928171129585813477132331538577519084006595335055487028872410579127692209642938724850603554885478763205394868103298473476811627231543504190652483290944218004086457805431824328448422034887148115990501701345535825110962804471270499590234116100216841170344686381902328362376624405803648588830575558058257742073963036264273582756620469659464278207233345784355220317478103481872995809"); + BigInteger primeP = new BigInteger( + "175002941104568842715096339107566771592009112128184231961529953978142750732317724951747797764638217287618769007295505214923187971350518217670604044004381362495186864051394404165602744235299100790551775147322153206730562450301874236875459336154569893255570576967036237661594595803204808064127845257496057219227"); + BigInteger primeQ = new BigInteger( + "155807574095269324897144428622185380283967159190626345335083690114147315509962698765044950001909553861571493035240542031420213144237033208612132704562174772894369053916729901982420535940939821673277140180113593951522522222348910536202664252481405241042414183668723338300649954708432681241621374644926879028977"); + BigInteger primeExponentP = new BigInteger( + "79745606804504995938838168837578376593737280079895233277372027184693457251170125851946171360348440134236338520742068873132216695552312068793428432338173016914968041076503997528137698610601222912385953171485249299873377130717231063522112968474603281996190849604705284061306758152904594168593526874435238915345"); + BigInteger primeExponentQ = new BigInteger( + "80619964983821018303966686284189517841976445905569830731617605558094658227540855971763115484608005874540349730961777634427740786642996065386667564038755340092176159839025706183161615488856833433976243963682074011475658804676349317075370362785860401437192843468423594688700132964854367053490737073471709030801"); + BigInteger crtCoefficient = new BigInteger( + "2157818511040667226980891229484210846757728661751992467240662009652654684725325675037512595031058612950802328971801913498711880111052682274056041470625863586779333188842602381844572406517251106159327934511268610438516820278066686225397795046020275055545005189953702783748235257613991379770525910232674719428"); + + KeySpec publicKeySpec = new RSAPublicKeySpec(modulus, publicExponent); + KeySpec privateKeySpec = new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, primeP, primeQ, + primeExponentP, primeExponentQ, crtCoefficient); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + + return new KeyPair(keyFactory.generatePublic(publicKeySpec), keyFactory.generatePrivate(privateKeySpec)); + } + @Test public void testToFromJsonWebKey() throws Exception { RsaKey key = getTestRsaKey(); JsonWebKey jwk = key.toJsonWebKey(); jwk.withKid("new kid"); - //setting kid + // setting kid RsaKey sameKey = RsaKey.fromJsonWebKey(jwk, true, _provider); JsonWebKey jwkSame = sameKey.toJsonWebKey(); jwkSame.withKid("new kid"); @@ -198,13 +415,123 @@ public void testToFromJsonWebKey() throws Exception { } private RsaKey getTestRsaKey() throws Exception { - String jwkString = "{\"kty\":\"RSA\",\"n\":\"rZ8pnmXkhfmmgNWVVdtNcYy2q0OAcCGIpeFzsN9URqJsiBEiWQfxlUxFTbM4kVWPqjauKt6byvApBGEeMA7Qs8kxwRVP-BD4orXRe9VPgliM92rH0UxQWHmCHUe7G7uUAFPwbiDVhWuFzELxNa6Kljg6Z9DuUKoddmQvlYWj8uSunofCtDi_zzlZKGYTOYJma5IYScHNww1yjLp8-b-Be2UdHbrPkCv6Nuwi6MVIKjPpEeRQgfefRmxDBJQKY3OfydMXZmEwukYXVkUcdIP8XwG2OxnfdRK0oAo0NDebNNVuT89k_3AyZLTr1KbDmx1nnjwa8uB8k-uLtcOC9igbTw\",\"e\":\"AQAB\",\"d\":\"H-z7hy_vVJ9yeZBMtIvt8qpQUK_J51STPwV085otcgud72tPKJXoW2658664ASl9kGwbnLBwb2G3-SEunuGqiNS_PGUB3niob6sFSUMRKsPDsB9HfPoOcCZvwZiWFGRqs6C7vlR1TuJVqRjKJ_ffbf4K51oo6FZPspx7j4AShLAwLUSQ60Ld5QPuxYMYZIMpdVbMVIVHJ26pR4Y18e_0GYmEGnbF5N0HkwqQmfmTiIK5aoGnD3GGgqHeHmWBwh6_WAq90ITLcX_zBeqQUgBSj-Z5v61SroO9Eang36T9mMoYrcPpYwemtAOb4HhQYDj8dCCfbeOcVmvZ9UJKWCX2oQ\",\"dp\":\"HW87UpwPoj3lPI9B9K1hJFeuGgarpakvtHuk1HpZ5hXWFGAJiXoWRV-jvYyjoM2k7RpSxPyuuFFmYHcIxiGFp2ES4HnP0BIhKVa2DyugUxIEcMK53C43Ub4mboJPZTSC3sapKgAmA2ue624sapWmshTPpx9qnUP2Oj3cSMkgMGE\",\"dq\":\"RhwEwb5FYio0GS2tmul8FAYsNH7JDehwI1yUApnTiakhSenFetml4PYyVkKR4csgLZEi3RY6J3R8Tg-36zrZuF7hxhVJn80L5_KETSpfEI3jcrXMVg4SRaMsWLY9Ahxflt2FJgUnHOmWRLmP6_hmaTcxxSACjbyUd_HhwNavD5E\",\"qi\":\"wYPZ4lKIslA1w3FaAzQifnNLABYXXUZ_KAA3a8T8fuxkdE4OP3xIFX7WHhnmBd6uOFiEcGoeq2jNQqDg91rV5661-5muQKcvp4uUsNId5rQw9EZw-kdDcwMtVFTEBfvVuyp83X974xYAHn1Jd8wWohSwrpi1QuH5cQMR5Fm6I1A\",\"p\":\"74Ot7MgxRu4euB31UWnGtrqYPjJmvbjYESS43jfDfo-s62ggV5a39P_YPg6oosgtGHNw0QDxunUOXNu9iriaYPf_imptRk69bKN8Nrl727Y-AaBYdLf1UZuwz8X07FqHAH5ghYpk79djld8QvkUUJLpx6rzcW8BJLTOi46DtzZE\",\"q\":\"uZJu-qenARIt28oj_Jlsk-p_KLnqdczczZfbRDd7XNp6csGLa8R0EyYqUB4xLWELQZsX4tAu9SaAO62tuuEy5wbOAmOVrq2ntoia1mGQSJdoeVq6OqtN300xVnaBc3us0rm8C6-824fEQ1PWXoulXLKcSqBhFT-hQahsYi-kat8\"}"; - ObjectMapper mapper = new ObjectMapper(); - JsonWebKey jwk = null; + String jwkString = "{\"kty\":\"RSA\",\"n\":\"rZ8pnmXkhfmmgNWVVdtNcYy2q0OAcCGIpeFzsN9URqJsiBEiWQfxlUxFTbM4kVWPqjauKt6byvApBGEeMA7Qs8kxwRVP-BD4orXRe9VPgliM92rH0UxQWHmCHUe7G7uUAFPwbiDVhWuFzELxNa6Kljg6Z9DuUKoddmQvlYWj8uSunofCtDi_zzlZKGYTOYJma5IYScHNww1yjLp8-b-Be2UdHbrPkCv6Nuwi6MVIKjPpEeRQgfefRmxDBJQKY3OfydMXZmEwukYXVkUcdIP8XwG2OxnfdRK0oAo0NDebNNVuT89k_3AyZLTr1KbDmx1nnjwa8uB8k-uLtcOC9igbTw\",\"e\":\"AQAB\",\"d\":\"H-z7hy_vVJ9yeZBMtIvt8qpQUK_J51STPwV085otcgud72tPKJXoW2658664ASl9kGwbnLBwb2G3-SEunuGqiNS_PGUB3niob6sFSUMRKsPDsB9HfPoOcCZvwZiWFGRqs6C7vlR1TuJVqRjKJ_ffbf4K51oo6FZPspx7j4AShLAwLUSQ60Ld5QPuxYMYZIMpdVbMVIVHJ26pR4Y18e_0GYmEGnbF5N0HkwqQmfmTiIK5aoGnD3GGgqHeHmWBwh6_WAq90ITLcX_zBeqQUgBSj-Z5v61SroO9Eang36T9mMoYrcPpYwemtAOb4HhQYDj8dCCfbeOcVmvZ9UJKWCX2oQ\",\"dp\":\"HW87UpwPoj3lPI9B9K1hJFeuGgarpakvtHuk1HpZ5hXWFGAJiXoWRV-jvYyjoM2k7RpSxPyuuFFmYHcIxiGFp2ES4HnP0BIhKVa2DyugUxIEcMK53C43Ub4mboJPZTSC3sapKgAmA2ue624sapWmshTPpx9qnUP2Oj3cSMkgMGE\",\"dq\":\"RhwEwb5FYio0GS2tmul8FAYsNH7JDehwI1yUApnTiakhSenFetml4PYyVkKR4csgLZEi3RY6J3R8Tg-36zrZuF7hxhVJn80L5_KETSpfEI3jcrXMVg4SRaMsWLY9Ahxflt2FJgUnHOmWRLmP6_hmaTcxxSACjbyUd_HhwNavD5E\",\"qi\":\"wYPZ4lKIslA1w3FaAzQifnNLABYXXUZ_KAA3a8T8fuxkdE4OP3xIFX7WHhnmBd6uOFiEcGoeq2jNQqDg91rV5661-5muQKcvp4uUsNId5rQw9EZw-kdDcwMtVFTEBfvVuyp83X974xYAHn1Jd8wWohSwrpi1QuH5cQMR5Fm6I1A\",\"p\":\"74Ot7MgxRu4euB31UWnGtrqYPjJmvbjYESS43jfDfo-s62ggV5a39P_YPg6oosgtGHNw0QDxunUOXNu9iriaYPf_imptRk69bKN8Nrl727Y-AaBYdLf1UZuwz8X07FqHAH5ghYpk79djld8QvkUUJLpx6rzcW8BJLTOi46DtzZE\",\"q\":\"uZJu-qenARIt28oj_Jlsk-p_KLnqdczczZfbRDd7XNp6csGLa8R0EyYqUB4xLWELQZsX4tAu9SaAO62tuuEy5wbOAmOVrq2ntoia1mGQSJdoeVq6OqtN300xVnaBc3us0rm8C6-824fEQ1PWXoulXLKcSqBhFT-hQahsYi-kat8\"}"; + ObjectMapper mapper = new ObjectMapper(); + JsonWebKey jwk = null; jwk = mapper.readValue(jwkString, JsonWebKey.class); - return new RsaKey("foo", jwk.toRSA(true, _provider) ); + return new RsaKey("foo", jwk.toRSA(true, _provider)); + } + + private static AuthenticationResult getAccessToken(String authorization, String resource) throws Exception { + + String clientId = System.getenv("arm.clientid"); + + if (clientId == null) { + throw new Exception("Please inform arm.clientid in the environment settings."); + } + + String clientKey = System.getenv("arm.clientkey"); + String username = System.getenv("arm.username"); + String password = System.getenv("arm.password"); + + AuthenticationResult result = null; + ExecutorService service = null; + try { + service = Executors.newFixedThreadPool(1); + AuthenticationContext context = new AuthenticationContext(authorization, false, service); + + Future future = null; + + if (clientKey != null && password == null) { + ClientCredential credentials = new ClientCredential(clientId, clientKey); + future = context.acquireToken(resource, credentials, null); + } + + if (password != null && clientKey == null) { + future = context.acquireToken(resource, clientId, username, password, null); + } + + if (future == null) { + throw new Exception( + "Missing or ambiguous credentials - please inform exactly one of arm.clientkey or arm.password in the environment settings."); + } + + result = future.get(); + } finally { + service.shutdown(); + } + + if (result == null) { + throw new RuntimeException("authentication result was null"); + } + return result; + } + + private static ServiceClientCredentials createTestCredentials() throws Exception { + return new KeyVaultCredentials() { + + @Override + public String doAuthenticate(String authorization, String resource, String scope) { + try { + if (isRecordMode()) { + AuthenticationResult authResult = getAccessToken(authorization, resource); + return authResult.getAccessToken(); + } else { + return ""; + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + }; + } + + @After + public void afterMethod() throws IOException { + interceptorManager.finalizeInterceptor(); + } + + private static void initPlaybackUri() throws IOException { + if (isPlaybackMode()) { + // 11080 and 11081 needs to be in sync with values in jetty.xml file + playbackUri = PLAYBACK_URI_BASE + "11080"; + } else { + playbackUri = PLAYBACK_URI_BASE + "1234"; + } + } + + public static boolean isPlaybackMode() { + if (testMode == null) + try { + initTestMode(); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Can't init test mode."); + } + return testMode == TestBase.TestMode.PLAYBACK; + } + + public static boolean isRecordMode() { + return !isPlaybackMode(); + } + + private static void initTestMode() throws IOException { + String azureTestMode = System.getenv("AZURE_TEST_MODE"); + if (azureTestMode != null) { + if (azureTestMode.equalsIgnoreCase("Record")) { + testMode = TestBase.TestMode.RECORD; + } else if (azureTestMode.equalsIgnoreCase("Playback")) { + testMode = TestBase.TestMode.PLAYBACK; + } else { + throw new IOException("Unknown AZURE_TEST_MODE: " + azureTestMode); + } + } else { + // System.out.print("Environment variable 'AZURE_TEST_MODE' has not been set + // yet. Using 'Playback' mode."); + testMode = TestBase.TestMode.PLAYBACK; + } } } diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testDefaultAlgorithm.json b/azure-keyvault-cryptography/target/test-classes/session-records/testDefaultAlgorithm.json new file mode 100644 index 0000000..723a9ae --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testDefaultAlgorithm.json @@ -0,0 +1,4 @@ +{ + "networkCallRecords" : [ ], + "variables" : [ ] +} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testRsa15.json b/azure-keyvault-cryptography/target/test-classes/session-records/testRsa15.json new file mode 100644 index 0000000..723a9ae --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testRsa15.json @@ -0,0 +1,4 @@ +{ + "networkCallRecords" : [ ], + "variables" : [ ] +} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testRsaOaep.json b/azure-keyvault-cryptography/target/test-classes/session-records/testRsaOaep.json new file mode 100644 index 0000000..723a9ae --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testRsaOaep.json @@ -0,0 +1,4 @@ +{ + "networkCallRecords" : [ ], + "variables" : [ ] +} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testRsaesOaep256.json b/azure-keyvault-cryptography/target/test-classes/session-records/testRsaesOaep256.json new file mode 100644 index 0000000..723a9ae --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testRsaesOaep256.json @@ -0,0 +1,4 @@ +{ + "networkCallRecords" : [ ], + "variables" : [ ] +} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerify.json b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerify.json new file mode 100644 index 0000000..723a9ae --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerify.json @@ -0,0 +1,4 @@ +{ + "networkCallRecords" : [ ], + "variables" : [ ] +} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs256.json b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs256.json new file mode 100644 index 0000000..723a9ae --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs256.json @@ -0,0 +1,4 @@ +{ + "networkCallRecords" : [ ], + "variables" : [ ] +} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs384.json b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs384.json new file mode 100644 index 0000000..723a9ae --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs384.json @@ -0,0 +1,4 @@ +{ + "networkCallRecords" : [ ], + "variables" : [ ] +} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs512.json b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs512.json new file mode 100644 index 0000000..723a9ae --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs512.json @@ -0,0 +1,4 @@ +{ + "networkCallRecords" : [ ], + "variables" : [ ] +} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs256.json b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs256.json new file mode 100644 index 0000000..b6db285 --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs256.json @@ -0,0 +1,112 @@ +{ + "networkCallRecords" : [ { + "Method" : "PUT", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:58:58 GMT", + "content-length" : "0", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "www-authenticate" : "Bearer authorization=\"https://login.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47\", resource=\"https://vault.azure.net\"", + "retry-after" : "0", + "StatusCode" : "401", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "2c49eec5-fc84-40de-bea9-a37983db6c30", + "Body" : "" + } + }, { + "Method" : "PUT", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:58:59 GMT", + "content-length" : "666", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "f299864a-5b05-481c-897f-1204f9dc8de0", + "Body" : "{\"key\":{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/1e95800035d647749643d20870f75e71\",\"kty\":\"RSA\",\"key_ops\":[\"encrypt\",\"decrypt\",\"sign\",\"verify\",\"wrapKey\",\"unwrapKey\"],\"n\":\"1_6ZtP288hEkKML-L6nFyZh1PD1rmAgwbbwjEvTSDK_008BYWhjp_6ULy9BhWtRIytNkPkm9gzaBTrCpp-vyDXPGa836Htp-w8u5JmxoUZchJh576m3m-8ZYWTmZSAp5SpruyKAmLSxPJHEWPXQntnmuTMjb9HBT9Ltrwc0ZDk-jsMLYunDJrNmrRUxQgb0zQ_Tl5fJjj8j-0KVx2RXtbfWFvf5fRdBYyP3m0aUpoopQPwtXszD2LcSKMJ_TnmnvMWr8MOA5aRlBaGdBk7zBgRafvDPam3Q2AvFA9mfcAVncpfZ3JFm73VARw6MofXtRqOHtZ7y4oNbY95xXwU2r6w\",\"e\":\"AQAB\"},\"attributes\":{\"enabled\":true,\"created\":1528487939,\"updated\":1528487939,\"recoveryLevel\":\"Recoverable+Purgeable\"}}" + } + }, { + "Method" : "POST", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//verify?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:59:00 GMT", + "content-length" : "14", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "e44d8f8a-001e-444d-8f5e-604f8a14aabb", + "Body" : "{\"value\":true}" + } + }, { + "Method" : "POST", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//sign?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:59:01 GMT", + "content-length" : "457", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "5780f1c8-d5e3-436c-840e-acfcea90e595", + "Body" : "{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/1e95800035d647749643d20870f75e71\",\"value\":\"Y2eM4E9rumhwvEbcjEPkwxvQ-t27FnYhU_vt_WefTfDCy4Em-vXaHs2Q_Rrm81mCq-nq7iHRdR_4HY0Qa5yAvUZgC4e9T5eBysv2JDDsRI5BgvVnL7pRswAKkMJp1tXlUnOHgiX8sW2YIw--qRZK-bSOhw0iGCJWihdomomoLKUf5QdimQbS2_hyw-9EQctigTPSzu1UvkPoxeiOakUUkNXh7SzVwdyzM9gNCvazEFm8eYR21olASdYxdKJv4HNJw6n2N1UTCQUmGcPVB9CTcxbzUNIrj8lw1MHe-XYCGtAKulGlBSK4i6dGfw0NlhQgJn62BZfAMMP103ZIIIoOTQ\"}" + } + } ], + "variables" : [ ] +} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs384.json b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs384.json new file mode 100644 index 0000000..32989db --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs384.json @@ -0,0 +1,112 @@ +{ + "networkCallRecords" : [ { + "Method" : "PUT", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:59:01 GMT", + "content-length" : "0", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "www-authenticate" : "Bearer authorization=\"https://login.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47\", resource=\"https://vault.azure.net\"", + "retry-after" : "0", + "StatusCode" : "401", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "0f4a2092-a0c2-48fb-a02e-9a43288d1385", + "Body" : "" + } + }, { + "Method" : "PUT", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:59:04 GMT", + "content-length" : "666", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "d944b732-5079-4005-9434-72f54e96a434", + "Body" : "{\"key\":{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/336d87b9d80a47e18cc3c744c4d11896\",\"kty\":\"RSA\",\"key_ops\":[\"encrypt\",\"decrypt\",\"sign\",\"verify\",\"wrapKey\",\"unwrapKey\"],\"n\":\"1_6ZtP288hEkKML-L6nFyZh1PD1rmAgwbbwjEvTSDK_008BYWhjp_6ULy9BhWtRIytNkPkm9gzaBTrCpp-vyDXPGa836Htp-w8u5JmxoUZchJh576m3m-8ZYWTmZSAp5SpruyKAmLSxPJHEWPXQntnmuTMjb9HBT9Ltrwc0ZDk-jsMLYunDJrNmrRUxQgb0zQ_Tl5fJjj8j-0KVx2RXtbfWFvf5fRdBYyP3m0aUpoopQPwtXszD2LcSKMJ_TnmnvMWr8MOA5aRlBaGdBk7zBgRafvDPam3Q2AvFA9mfcAVncpfZ3JFm73VARw6MofXtRqOHtZ7y4oNbY95xXwU2r6w\",\"e\":\"AQAB\"},\"attributes\":{\"enabled\":true,\"created\":1528487944,\"updated\":1528487944,\"recoveryLevel\":\"Recoverable+Purgeable\"}}" + } + }, { + "Method" : "POST", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//verify?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:59:04 GMT", + "content-length" : "14", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "b87e6201-9ba6-4881-814c-40614bffd3f0", + "Body" : "{\"value\":true}" + } + }, { + "Method" : "POST", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//sign?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:59:06 GMT", + "content-length" : "457", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "5fe00def-a4fb-426d-99c3-ce6f66c696b1", + "Body" : "{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/336d87b9d80a47e18cc3c744c4d11896\",\"value\":\"istBdKDaP2b8Tm8EjGUMO3ZM2o1RUOskXs3gm2mM_e5LOEzMv2BnGtO8yMDCFFa9nyYbtahzWmOImZpWaRx9FaSOmLpy12OqcVVABgvXGuXnjqT0VK0l9s3wJv_Gk4giAZrzcqprZZPLdQOjeg-lunzAShsm7-TrdrQVsVUpqnOICbfPFSVZU1n3TWwpHG51hcLdowLL8bMo-6gyMAoZhO5QyhHxB4tgN72xHbkR1Cd02lAiBMU2B_vGLe_tkYjQY7b-krHPaa8yhLzrOWCGr1hxlq-u0BFTsuFI7Oitg_0-IqvvhW-qNDubjL2vXu1WoHqzSGLZm7myWWP-XXFjFQ\"}" + } + } ], + "variables" : [ ] +} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs512.json b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs512.json new file mode 100644 index 0000000..f6bdd3e --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs512.json @@ -0,0 +1,112 @@ +{ + "networkCallRecords" : [ { + "Method" : "PUT", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:59:07 GMT", + "content-length" : "0", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "www-authenticate" : "Bearer authorization=\"https://login.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47\", resource=\"https://vault.azure.net\"", + "retry-after" : "0", + "StatusCode" : "401", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "8cf9c8b0-7a34-4c29-9837-831aea552394", + "Body" : "" + } + }, { + "Method" : "PUT", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:59:09 GMT", + "content-length" : "666", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "a4294f1d-edb7-42b9-ac6d-600983782007", + "Body" : "{\"key\":{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/3789a33dc0b64934a666bc3e646d9691\",\"kty\":\"RSA\",\"key_ops\":[\"encrypt\",\"decrypt\",\"sign\",\"verify\",\"wrapKey\",\"unwrapKey\"],\"n\":\"1_6ZtP288hEkKML-L6nFyZh1PD1rmAgwbbwjEvTSDK_008BYWhjp_6ULy9BhWtRIytNkPkm9gzaBTrCpp-vyDXPGa836Htp-w8u5JmxoUZchJh576m3m-8ZYWTmZSAp5SpruyKAmLSxPJHEWPXQntnmuTMjb9HBT9Ltrwc0ZDk-jsMLYunDJrNmrRUxQgb0zQ_Tl5fJjj8j-0KVx2RXtbfWFvf5fRdBYyP3m0aUpoopQPwtXszD2LcSKMJ_TnmnvMWr8MOA5aRlBaGdBk7zBgRafvDPam3Q2AvFA9mfcAVncpfZ3JFm73VARw6MofXtRqOHtZ7y4oNbY95xXwU2r6w\",\"e\":\"AQAB\"},\"attributes\":{\"enabled\":true,\"created\":1528487949,\"updated\":1528487949,\"recoveryLevel\":\"Recoverable+Purgeable\"}}" + } + }, { + "Method" : "POST", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//verify?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:59:10 GMT", + "content-length" : "14", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "feb9ddbb-861c-451b-a7f4-739d315436e8", + "Body" : "{\"value\":true}" + } + }, { + "Method" : "POST", + "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//sign?api-version=7.0-preview", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", + "Content-Type" : "application/json; charset=utf-8" + }, + "Response" : { + "date" : "Fri, 08 Jun 2018 19:59:11 GMT", + "content-length" : "457", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "x-aspnet-version" : "4.0.30319", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000;includeSubDomains", + "x-content-type-options" : "nosniff", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "x-ms-keyvault-network-info" : "addr=167.220.1.18;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region" : "West US", + "cache-control" : "no-cache", + "x-ms-keyvault-service-version" : "1.0.0.849", + "x-ms-request-id" : "3365c873-26b3-4a2c-a62b-5ebeeb8481a2", + "Body" : "{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/3789a33dc0b64934a666bc3e646d9691\",\"value\":\"DP9rsnU4XbxwOTqLmQGZiGTxKGR7OPZrrOiqLXhNKxaiD2TK7zmDv1rEhK83r1MQ64jBHLNIXhNsayhiqX_tR56s1qWhw0sCw0TIbGw02PaR_DaRdS9LsALnpq9sqnphwcx7hK1jHUFgZX-njk193x8fgOVRSq_BnLfwDiIvLehYxr8kU2E_WhkBDVwSB_VzWfaAPM-9Snr00ciZ3_TL-avKhdIBSrl8OXFKa1CPu2pMSPb3JMhOoeI6Uwj6g_6ACXnHveeoG7YyVswS4kTUhr0uUqQobEyVpEcuS177hb1xL3n5Ze5nXX3laDyfM0-Zkfjr-J13gpzsn-fb8rx2Og\"}" + } + } ], + "variables" : [ ] +} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testToFromJsonWebKey.json b/azure-keyvault-cryptography/target/test-classes/session-records/testToFromJsonWebKey.json new file mode 100644 index 0000000..723a9ae --- /dev/null +++ b/azure-keyvault-cryptography/target/test-classes/session-records/testToFromJsonWebKey.json @@ -0,0 +1,4 @@ +{ + "networkCallRecords" : [ ], + "variables" : [ ] +} \ No newline at end of file From c513a022a2567712339db42f3ba729ca0baea626 Mon Sep 17 00:00:00 2001 From: tiffanyachen Date: Fri, 8 Jun 2018 13:06:50 -0700 Subject: [PATCH 3/5] updated pom --- azure-keyvault-cryptography/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/azure-keyvault-cryptography/pom.xml b/azure-keyvault-cryptography/pom.xml index 14a6943..d14a108 100644 --- a/azure-keyvault-cryptography/pom.xml +++ b/azure-keyvault-cryptography/pom.xml @@ -39,7 +39,6 @@ true - org.bouncycastle From 775b4d87e02540dfa09935a5351d466fde12df82 Mon Sep 17 00:00:00 2001 From: tiffanyachen Date: Fri, 8 Jun 2018 15:52:15 -0700 Subject: [PATCH 4/5] Refactored integration tests to external module --- azure-keyvault-cryptography/pom.xml | 19 -- .../cryptography/test/RsaKeyTest.java | 285 +--------------- .../session-records/testDefaultAlgorithm.json | 4 - .../session-records/testRsa15.json | 4 - .../session-records/testRsaOaep.json | 4 - .../session-records/testRsaesOaep256.json | 4 - .../session-records/testSignVerify.json | 4 - .../session-records/testSignVerifyPs256.json | 4 - .../session-records/testSignVerifyPs384.json | 4 - .../session-records/testSignVerifyPs512.json | 4 - .../session-records/testToFromJsonWebKey.json | 4 - azure-keyvault-integration-tests/.gitignore | 1 + azure-keyvault-integration-tests/pom.xml | 45 +++ ...eKeyVaultCryptographyIntegrationTests.java | 322 ++++++++++++++++++ .../testSignVerifyServicePs256.json | 28 +- .../testSignVerifyServicePs384.json | 28 +- .../testSignVerifyServicePs512.json | 28 +- pom.xml | 11 +- 18 files changed, 419 insertions(+), 384 deletions(-) delete mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testDefaultAlgorithm.json delete mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testRsa15.json delete mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testRsaOaep.json delete mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testRsaesOaep256.json delete mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testSignVerify.json delete mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs256.json delete mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs384.json delete mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs512.json delete mode 100644 azure-keyvault-cryptography/target/test-classes/session-records/testToFromJsonWebKey.json create mode 100644 azure-keyvault-integration-tests/.gitignore create mode 100644 azure-keyvault-integration-tests/pom.xml create mode 100644 azure-keyvault-integration-tests/src/test/java/com/microsoft/azure/keyvault/test/AzureKeyVaultCryptographyIntegrationTests.java rename {azure-keyvault-cryptography => azure-keyvault-integration-tests}/target/test-classes/session-records/testSignVerifyServicePs256.json (65%) rename {azure-keyvault-cryptography => azure-keyvault-integration-tests}/target/test-classes/session-records/testSignVerifyServicePs384.json (65%) rename {azure-keyvault-cryptography => azure-keyvault-integration-tests}/target/test-classes/session-records/testSignVerifyServicePs512.json (65%) diff --git a/azure-keyvault-cryptography/pom.xml b/azure-keyvault-cryptography/pom.xml index d14a108..6901103 100644 --- a/azure-keyvault-cryptography/pom.xml +++ b/azure-keyvault-cryptography/pom.xml @@ -61,24 +61,5 @@ junit test - - com.microsoft.azure - azure-keyvault - test - 1.1-beta-1 - - - com.microsoft.rest - client-runtime - 1.3.0 - test - - - com.microsoft.azure - azure-mgmt-resources - 1.3.1-SNAPSHOT - test-jar - test - diff --git a/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java b/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java index 9843b1b..be7b43e 100644 --- a/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java +++ b/azure-keyvault-cryptography/src/test/java/com/microsoft/azure/keyvault/cryptography/test/RsaKeyTest.java @@ -37,25 +37,18 @@ import com.microsoft.aad.adal4j.AuthenticationResult; import com.microsoft.aad.adal4j.ClientCredential; import com.microsoft.azure.AzureResponseBuilder; -import com.microsoft.azure.keyvault.KeyIdentifier; -import com.microsoft.azure.keyvault.KeyVaultClient; -import com.microsoft.azure.keyvault.authentication.KeyVaultCredentials; + import com.microsoft.azure.keyvault.cryptography.RsaKey; import com.microsoft.azure.keyvault.cryptography.algorithms.Rs256; import com.microsoft.azure.keyvault.cryptography.algorithms.Rsa15; import com.microsoft.azure.keyvault.cryptography.algorithms.RsaOaep; import com.microsoft.azure.keyvault.cryptography.algorithms.RsaesOaep256; -import com.microsoft.azure.keyvault.models.KeyBundle; -import com.microsoft.azure.keyvault.models.KeyOperationResult; -import com.microsoft.azure.keyvault.models.KeyVerifyResult; -import com.microsoft.azure.keyvault.requests.ImportKeyRequest; + import com.microsoft.azure.keyvault.webkey.JsonWebKey; import com.microsoft.azure.keyvault.webkey.JsonWebKeyOperation; import com.microsoft.azure.keyvault.webkey.JsonWebKeySignatureAlgorithm; import com.microsoft.azure.keyvault.webkey.JsonWebKeyType; -import com.microsoft.azure.management.resources.core.InterceptorManager; -import com.microsoft.azure.management.resources.core.TestBase; -import com.microsoft.azure.management.resources.fluentcore.utils.ResourceManagerThrottlingInterceptor; + import com.microsoft.azure.serializer.AzureJacksonAdapter; import com.microsoft.rest.LogLevel; import com.microsoft.rest.RestClient; @@ -64,19 +57,6 @@ public class RsaKeyTest { - private static TestBase.TestMode testMode = null; - - protected InterceptorManager interceptorManager = null; - - protected final static String ZERO_SUBSCRIPTION = "00000000-0000-0000-0000-000000000000"; - protected final static String ZERO_TENANT = "00000000-0000-0000-0000-000000000000"; - private static final String PLAYBACK_URI_BASE = "http://localhost:"; - protected static String playbackUri = null; - - static KeyVaultClient keyVaultClient; - final static String KEY_NAME = "otherkey2"; - static String VAULT_URI; - // A Content Encryption Key, or Message. This value is kept consistent with the // .NET // unit test cases to enable cross platform testing. @@ -87,60 +67,6 @@ public class RsaKeyTest { private Provider _provider = null; - @BeforeClass - public static void setUpBeforeClass() throws Exception { - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @BeforeClass - public static void setUp() throws Exception { - initTestMode(); - initPlaybackUri(); - } - - @Rule - public TestName testName = new TestName(); - - @Before - public void beforeMethod() throws Exception { - VAULT_URI = System.getenv("VAULT_URI"); - - RestClient restClient; - ServiceClientCredentials credentials = createTestCredentials(); - interceptorManager = InterceptorManager.create(testName.getMethodName(), testMode); - - if (isRecordMode()) { - restClient = new RestClient.Builder().withBaseUrl("https://{vaultBaseUrl}") - .withSerializerAdapter(new AzureJacksonAdapter()) - .withResponseBuilderFactory(new AzureResponseBuilder.Factory()).withCredentials(credentials) - .withLogLevel(LogLevel.NONE) - .withNetworkInterceptor(new LoggingInterceptor(LogLevel.BODY_AND_HEADERS)) - .withNetworkInterceptor(interceptorManager.initInterceptor()) - .withInterceptor(new ResourceManagerThrottlingInterceptor()).build(); - - interceptorManager.addTextReplacementRule("https://management.azure.com/", playbackUri + "/"); - interceptorManager.addTextReplacementRule("https://graph.windows.net/", playbackUri + "/"); - - keyVaultClient = new KeyVaultClient(restClient); - } else { // is Playback Mode - restClient = new RestClient.Builder().withBaseUrl(playbackUri + "/") - .withSerializerAdapter(new AzureJacksonAdapter()) - .withResponseBuilderFactory(new AzureResponseBuilder.Factory()).withCredentials(credentials) - .withLogLevel(LogLevel.NONE) - .withNetworkInterceptor(new LoggingInterceptor(LogLevel.BODY_AND_HEADERS)) - .withNetworkInterceptor(interceptorManager.initInterceptor()) - .withInterceptor(new ResourceManagerThrottlingInterceptor()).build(); - keyVaultClient = new KeyVaultClient(restClient); - } - } - - @After - public void tearDown() throws Exception { - } - protected void setProvider(Provider provider) { _provider = provider; } @@ -306,102 +232,6 @@ private void signVerifyLocal(String algName, String digestAlg) throws Exception key.close(); } - @Test - public void testSignVerifyServicePs256() throws Exception { - signVerifyWithService(KEY_NAME, JsonWebKeySignatureAlgorithm.PS256, "SHA-256"); - } - - @Test - public void testSignVerifyServicePs384() throws Exception { - signVerifyWithService(KEY_NAME, JsonWebKeySignatureAlgorithm.PS384, "SHA-384"); - } - - @Test - public void testSignVerifyServicePs512() throws Exception { - signVerifyWithService(KEY_NAME, JsonWebKeySignatureAlgorithm.PS512, "SHA-512"); - } - - private void signVerifyWithService(String keyName, JsonWebKeySignatureAlgorithm algorithm, String digestAlg) - throws Exception { - - JsonWebKey testKey = importTestKey(keyName); - - RsaKey key = new RsaKey(testKey.kid(), getWellKnownKey()); - - KeyIdentifier keyId = new KeyIdentifier(testKey.kid()); - - // Test variables - byte[] plainText = new byte[100]; - new Random(0x1234567L).nextBytes(plainText); - MessageDigest md = MessageDigest.getInstance(digestAlg); - md.update(plainText); - byte[] digest = md.digest(); - byte[] signature; - - KeyOperationResult result; - KeyVerifyResult verifyResult; - - // Using kid WO version - { - signature = key.signAsync(digest, algorithm.toString()).get().getLeft(); - verifyResult = keyVaultClient.verify(keyId.baseIdentifier(), algorithm, digest, signature); - Assert.assertEquals(new Boolean(true), verifyResult.value()); - } - - { - result = keyVaultClient.sign(keyId.baseIdentifier(), algorithm, digest); - signature = result.result(); - Assert.assertTrue(key.verifyAsync(digest, signature, algorithm.toString()).get()); - } - key.close(); - } - - private static JsonWebKey importTestKey(String keyName) throws Exception { - - KeyBundle keyBundle = new KeyBundle(); - JsonWebKey key = JsonWebKey.fromRSA(getTestKeyMaterial()); - - key.withKty(JsonWebKeyType.RSA); - key.withKeyOps(Arrays.asList(JsonWebKeyOperation.ENCRYPT, JsonWebKeyOperation.DECRYPT, JsonWebKeyOperation.SIGN, - JsonWebKeyOperation.VERIFY, JsonWebKeyOperation.WRAP_KEY, JsonWebKeyOperation.UNWRAP_KEY)); - - System.out.println(key.kid()); - - keyBundle = keyVaultClient - .importKey(new ImportKeyRequest.Builder(VAULT_URI, KEY_NAME, key).withHsm(false).build()); - - return keyBundle.key(); - } - - private static KeyPair getTestKeyMaterial() throws Exception { - return getWellKnownKey(); - } - - private static KeyPair getWellKnownKey() throws Exception { - BigInteger modulus = new BigInteger( - "27266783713040163753473734334021230592631652450892850648620119914958066181400432364213298181846462385257448168605902438305568194683691563208578540343969522651422088760509452879461613852042845039552547834002168737350264189810815735922734447830725099163869215360401162450008673869707774119785881115044406101346450911054819448375712432746968301739007624952483347278954755460152795801894283389540036131881712321193750961817346255102052653789197325341350920441746054233522546543768770643593655942246891652634114922277138937273034902434321431672058220631825053788262810480543541597284376261438324665363067125951152574540779"); - BigInteger publicExponent = new BigInteger("65537"); - BigInteger privateExponent = new BigInteger( - "10466613941269075477152428927796086150095892102279802916937552172064636326433780566497000814207416485739683286961848843255766652023400959086290344987308562817062506476465756840999981989957456897020361717197805192876094362315496459535960304928171129585813477132331538577519084006595335055487028872410579127692209642938724850603554885478763205394868103298473476811627231543504190652483290944218004086457805431824328448422034887148115990501701345535825110962804471270499590234116100216841170344686381902328362376624405803648588830575558058257742073963036264273582756620469659464278207233345784355220317478103481872995809"); - BigInteger primeP = new BigInteger( - "175002941104568842715096339107566771592009112128184231961529953978142750732317724951747797764638217287618769007295505214923187971350518217670604044004381362495186864051394404165602744235299100790551775147322153206730562450301874236875459336154569893255570576967036237661594595803204808064127845257496057219227"); - BigInteger primeQ = new BigInteger( - "155807574095269324897144428622185380283967159190626345335083690114147315509962698765044950001909553861571493035240542031420213144237033208612132704562174772894369053916729901982420535940939821673277140180113593951522522222348910536202664252481405241042414183668723338300649954708432681241621374644926879028977"); - BigInteger primeExponentP = new BigInteger( - "79745606804504995938838168837578376593737280079895233277372027184693457251170125851946171360348440134236338520742068873132216695552312068793428432338173016914968041076503997528137698610601222912385953171485249299873377130717231063522112968474603281996190849604705284061306758152904594168593526874435238915345"); - BigInteger primeExponentQ = new BigInteger( - "80619964983821018303966686284189517841976445905569830731617605558094658227540855971763115484608005874540349730961777634427740786642996065386667564038755340092176159839025706183161615488856833433976243963682074011475658804676349317075370362785860401437192843468423594688700132964854367053490737073471709030801"); - BigInteger crtCoefficient = new BigInteger( - "2157818511040667226980891229484210846757728661751992467240662009652654684725325675037512595031058612950802328971801913498711880111052682274056041470625863586779333188842602381844572406517251106159327934511268610438516820278066686225397795046020275055545005189953702783748235257613991379770525910232674719428"); - - KeySpec publicKeySpec = new RSAPublicKeySpec(modulus, publicExponent); - KeySpec privateKeySpec = new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, primeP, primeQ, - primeExponentP, primeExponentQ, crtCoefficient); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - - return new KeyPair(keyFactory.generatePublic(publicKeySpec), keyFactory.generatePrivate(privateKeySpec)); - } - @Test public void testToFromJsonWebKey() throws Exception { RsaKey key = getTestRsaKey(); @@ -424,114 +254,5 @@ private RsaKey getTestRsaKey() throws Exception { return new RsaKey("foo", jwk.toRSA(true, _provider)); } - private static AuthenticationResult getAccessToken(String authorization, String resource) throws Exception { - - String clientId = System.getenv("arm.clientid"); - - if (clientId == null) { - throw new Exception("Please inform arm.clientid in the environment settings."); - } - - String clientKey = System.getenv("arm.clientkey"); - String username = System.getenv("arm.username"); - String password = System.getenv("arm.password"); - - AuthenticationResult result = null; - ExecutorService service = null; - try { - service = Executors.newFixedThreadPool(1); - AuthenticationContext context = new AuthenticationContext(authorization, false, service); - - Future future = null; - - if (clientKey != null && password == null) { - ClientCredential credentials = new ClientCredential(clientId, clientKey); - future = context.acquireToken(resource, credentials, null); - } - - if (password != null && clientKey == null) { - future = context.acquireToken(resource, clientId, username, password, null); - } - - if (future == null) { - throw new Exception( - "Missing or ambiguous credentials - please inform exactly one of arm.clientkey or arm.password in the environment settings."); - } - - result = future.get(); - } finally { - service.shutdown(); - } - - if (result == null) { - throw new RuntimeException("authentication result was null"); - } - return result; - } - - private static ServiceClientCredentials createTestCredentials() throws Exception { - return new KeyVaultCredentials() { - - @Override - public String doAuthenticate(String authorization, String resource, String scope) { - try { - if (isRecordMode()) { - AuthenticationResult authResult = getAccessToken(authorization, resource); - return authResult.getAccessToken(); - } else { - return ""; - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - }; - } - - @After - public void afterMethod() throws IOException { - interceptorManager.finalizeInterceptor(); - } - - private static void initPlaybackUri() throws IOException { - if (isPlaybackMode()) { - // 11080 and 11081 needs to be in sync with values in jetty.xml file - playbackUri = PLAYBACK_URI_BASE + "11080"; - } else { - playbackUri = PLAYBACK_URI_BASE + "1234"; - } - } - - public static boolean isPlaybackMode() { - if (testMode == null) - try { - initTestMode(); - } catch (IOException e) { - e.printStackTrace(); - throw new RuntimeException("Can't init test mode."); - } - return testMode == TestBase.TestMode.PLAYBACK; - } - - public static boolean isRecordMode() { - return !isPlaybackMode(); - } - - private static void initTestMode() throws IOException { - String azureTestMode = System.getenv("AZURE_TEST_MODE"); - if (azureTestMode != null) { - if (azureTestMode.equalsIgnoreCase("Record")) { - testMode = TestBase.TestMode.RECORD; - } else if (azureTestMode.equalsIgnoreCase("Playback")) { - testMode = TestBase.TestMode.PLAYBACK; - } else { - throw new IOException("Unknown AZURE_TEST_MODE: " + azureTestMode); - } - } else { - // System.out.print("Environment variable 'AZURE_TEST_MODE' has not been set - // yet. Using 'Playback' mode."); - testMode = TestBase.TestMode.PLAYBACK; - } - } } diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testDefaultAlgorithm.json b/azure-keyvault-cryptography/target/test-classes/session-records/testDefaultAlgorithm.json deleted file mode 100644 index 723a9ae..0000000 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testDefaultAlgorithm.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "networkCallRecords" : [ ], - "variables" : [ ] -} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testRsa15.json b/azure-keyvault-cryptography/target/test-classes/session-records/testRsa15.json deleted file mode 100644 index 723a9ae..0000000 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testRsa15.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "networkCallRecords" : [ ], - "variables" : [ ] -} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testRsaOaep.json b/azure-keyvault-cryptography/target/test-classes/session-records/testRsaOaep.json deleted file mode 100644 index 723a9ae..0000000 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testRsaOaep.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "networkCallRecords" : [ ], - "variables" : [ ] -} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testRsaesOaep256.json b/azure-keyvault-cryptography/target/test-classes/session-records/testRsaesOaep256.json deleted file mode 100644 index 723a9ae..0000000 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testRsaesOaep256.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "networkCallRecords" : [ ], - "variables" : [ ] -} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerify.json b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerify.json deleted file mode 100644 index 723a9ae..0000000 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerify.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "networkCallRecords" : [ ], - "variables" : [ ] -} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs256.json b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs256.json deleted file mode 100644 index 723a9ae..0000000 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs256.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "networkCallRecords" : [ ], - "variables" : [ ] -} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs384.json b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs384.json deleted file mode 100644 index 723a9ae..0000000 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs384.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "networkCallRecords" : [ ], - "variables" : [ ] -} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs512.json b/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs512.json deleted file mode 100644 index 723a9ae..0000000 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyPs512.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "networkCallRecords" : [ ], - "variables" : [ ] -} \ No newline at end of file diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testToFromJsonWebKey.json b/azure-keyvault-cryptography/target/test-classes/session-records/testToFromJsonWebKey.json deleted file mode 100644 index 723a9ae..0000000 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testToFromJsonWebKey.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "networkCallRecords" : [ ], - "variables" : [ ] -} \ No newline at end of file diff --git a/azure-keyvault-integration-tests/.gitignore b/azure-keyvault-integration-tests/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/azure-keyvault-integration-tests/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/azure-keyvault-integration-tests/pom.xml b/azure-keyvault-integration-tests/pom.xml new file mode 100644 index 0000000..5153f69 --- /dev/null +++ b/azure-keyvault-integration-tests/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + com.microsoft.azure + azure-keyvault-parent + 1.1-beta-1 + + azure-keyvault-integration-tests + azure-keyvault-integration-tests + http://maven.apache.org + + UTF-8 + + + + com.microsoft.azure + azure-keyvault-webkey + test + 1.1-beta-1 + + + com.microsoft.azure + azure-keyvault + test + 1.1-beta-1 + + + + com.microsoft.rest + client-runtime + 1.3.0 + test + + + com.microsoft.azure + azure-mgmt-resources + 1.3.1-SNAPSHOT + test-jar + test + + + diff --git a/azure-keyvault-integration-tests/src/test/java/com/microsoft/azure/keyvault/test/AzureKeyVaultCryptographyIntegrationTests.java b/azure-keyvault-integration-tests/src/test/java/com/microsoft/azure/keyvault/test/AzureKeyVaultCryptographyIntegrationTests.java new file mode 100644 index 0000000..293f77f --- /dev/null +++ b/azure-keyvault-integration-tests/src/test/java/com/microsoft/azure/keyvault/test/AzureKeyVaultCryptographyIntegrationTests.java @@ -0,0 +1,322 @@ +package com.microsoft.azure.keyvault.test; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.MessageDigest; +import java.security.spec.KeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; + +import com.microsoft.aad.adal4j.AuthenticationContext; +import com.microsoft.aad.adal4j.AuthenticationResult; +import com.microsoft.aad.adal4j.ClientCredential; +import com.microsoft.azure.AzureResponseBuilder; +import com.microsoft.azure.keyvault.KeyIdentifier; +import com.microsoft.azure.keyvault.KeyVaultClient; +import com.microsoft.azure.keyvault.authentication.KeyVaultCredentials; +import com.microsoft.azure.keyvault.cryptography.RsaKey; +import com.microsoft.azure.keyvault.models.KeyBundle; +import com.microsoft.azure.keyvault.models.KeyOperationResult; +import com.microsoft.azure.keyvault.models.KeyVerifyResult; +import com.microsoft.azure.keyvault.requests.ImportKeyRequest; +import com.microsoft.azure.keyvault.webkey.JsonWebKey; +import com.microsoft.azure.keyvault.webkey.JsonWebKeyOperation; +import com.microsoft.azure.keyvault.webkey.JsonWebKeySignatureAlgorithm; +import com.microsoft.azure.keyvault.webkey.JsonWebKeyType; +import com.microsoft.azure.management.resources.core.InterceptorManager; +import com.microsoft.azure.management.resources.core.TestBase; +import com.microsoft.azure.management.resources.fluentcore.utils.ResourceManagerThrottlingInterceptor; +import com.microsoft.azure.serializer.AzureJacksonAdapter; +import com.microsoft.rest.LogLevel; +import com.microsoft.rest.RestClient; +import com.microsoft.rest.credentials.ServiceClientCredentials; +import com.microsoft.rest.interceptors.LoggingInterceptor; +public class AzureKeyVaultCryptographyIntegrationTests { + + private static TestBase.TestMode testMode = null; + + protected InterceptorManager interceptorManager = null; + + protected final static String ZERO_SUBSCRIPTION = "00000000-0000-0000-0000-000000000000"; + protected final static String ZERO_TENANT = "00000000-0000-0000-0000-000000000000"; + private static final String PLAYBACK_URI_BASE = "http://localhost:"; + private static final String PLAYBACK_VAULT = "https://test-vault.vault.azure.net"; + + protected static String playbackUri = null; + + static KeyVaultClient keyVaultClient; + + final static String KEY_NAME = "otherkey2"; + static String VAULT_URI; + + + @Rule + public TestName testName = new TestName(); + + + + @BeforeClass + public static void setUp() throws Exception { + initTestMode(); + initPlaybackUri(); + } + + @Before + public void beforeMethod() throws Exception { + + RestClient restClient; + ServiceClientCredentials credentials = createTestCredentials(); + interceptorManager = InterceptorManager.create(testName.getMethodName(), testMode); + + if (isRecordMode()) { + VAULT_URI = System.getenv("VAULT_URI"); + restClient = new RestClient.Builder().withBaseUrl("https://{vaultBaseUrl}") + .withSerializerAdapter(new AzureJacksonAdapter()) + .withResponseBuilderFactory(new AzureResponseBuilder.Factory()).withCredentials(credentials) + .withLogLevel(LogLevel.NONE) + .withNetworkInterceptor(new LoggingInterceptor(LogLevel.BODY_AND_HEADERS)) + .withNetworkInterceptor(interceptorManager.initInterceptor()) + .withInterceptor(new ResourceManagerThrottlingInterceptor()).build(); + + interceptorManager.addTextReplacementRule("https://management.azure.com/", playbackUri + "/"); + interceptorManager.addTextReplacementRule("https://graph.windows.net/", playbackUri + "/"); + interceptorManager.addTextReplacementRule(VAULT_URI, PLAYBACK_VAULT); + keyVaultClient = new KeyVaultClient(restClient); + } else { // is Playback Mode + VAULT_URI = PLAYBACK_VAULT; + restClient = new RestClient.Builder().withBaseUrl(playbackUri + "/") + .withSerializerAdapter(new AzureJacksonAdapter()) + .withResponseBuilderFactory(new AzureResponseBuilder.Factory()).withCredentials(credentials) + .withLogLevel(LogLevel.NONE) + .withNetworkInterceptor(new LoggingInterceptor(LogLevel.BODY_AND_HEADERS)) + .withNetworkInterceptor(interceptorManager.initInterceptor()) + .withInterceptor(new ResourceManagerThrottlingInterceptor()).build(); + keyVaultClient = new KeyVaultClient(restClient); + } + } + + @Test + public void testSignVerifyServicePs256() throws Exception { + signVerifyWithService(KEY_NAME, JsonWebKeySignatureAlgorithm.PS256, "SHA-256"); + } + + @Test + public void testSignVerifyServicePs384() throws Exception { + signVerifyWithService(KEY_NAME, JsonWebKeySignatureAlgorithm.PS384, "SHA-384"); + } + + @Test + public void testSignVerifyServicePs512() throws Exception { + signVerifyWithService(KEY_NAME, JsonWebKeySignatureAlgorithm.PS512, "SHA-512"); + } + + private void signVerifyWithService(String keyName, JsonWebKeySignatureAlgorithm algorithm, String digestAlg) + throws Exception { + + JsonWebKey testKey = importTestKey(keyName); + + RsaKey key = new RsaKey(testKey.kid(), getWellKnownKey()); + + KeyIdentifier keyId = new KeyIdentifier(testKey.kid()); + + // Test variables + byte[] plainText = new byte[100]; + new Random(0x1234567L).nextBytes(plainText); + MessageDigest md = MessageDigest.getInstance(digestAlg); + md.update(plainText); + byte[] digest = md.digest(); + byte[] signature; + + KeyOperationResult result; + KeyVerifyResult verifyResult; + + // Using kid WO version + { + signature = key.signAsync(digest, algorithm.toString()).get().getLeft(); + verifyResult = keyVaultClient.verify(keyId.baseIdentifier(), algorithm, digest, signature); + Assert.assertEquals(new Boolean(true), verifyResult.value()); + } + + { + result = keyVaultClient.sign(keyId.baseIdentifier(), algorithm, digest); + signature = result.result(); + Assert.assertTrue(key.verifyAsync(digest, signature, algorithm.toString()).get()); + } + key.close(); + } + + + private static JsonWebKey importTestKey(String keyName) throws Exception { + + KeyBundle keyBundle = new KeyBundle(); + JsonWebKey key = JsonWebKey.fromRSA(getTestKeyMaterial()); + + key.withKty(JsonWebKeyType.RSA); + key.withKeyOps(Arrays.asList(JsonWebKeyOperation.ENCRYPT, JsonWebKeyOperation.DECRYPT, JsonWebKeyOperation.SIGN, + JsonWebKeyOperation.VERIFY, JsonWebKeyOperation.WRAP_KEY, JsonWebKeyOperation.UNWRAP_KEY)); + + System.out.println(key.kid()); + + keyBundle = keyVaultClient + .importKey(new ImportKeyRequest.Builder(VAULT_URI, KEY_NAME, key).withHsm(false).build()); + + return keyBundle.key(); + } + + private static KeyPair getTestKeyMaterial() throws Exception { + return getWellKnownKey(); + } + + private static KeyPair getWellKnownKey() throws Exception { + BigInteger modulus = new BigInteger( + "27266783713040163753473734334021230592631652450892850648620119914958066181400432364213298181846462385257448168605902438305568194683691563208578540343969522651422088760509452879461613852042845039552547834002168737350264189810815735922734447830725099163869215360401162450008673869707774119785881115044406101346450911054819448375712432746968301739007624952483347278954755460152795801894283389540036131881712321193750961817346255102052653789197325341350920441746054233522546543768770643593655942246891652634114922277138937273034902434321431672058220631825053788262810480543541597284376261438324665363067125951152574540779"); + BigInteger publicExponent = new BigInteger("65537"); + BigInteger privateExponent = new BigInteger( + "10466613941269075477152428927796086150095892102279802916937552172064636326433780566497000814207416485739683286961848843255766652023400959086290344987308562817062506476465756840999981989957456897020361717197805192876094362315496459535960304928171129585813477132331538577519084006595335055487028872410579127692209642938724850603554885478763205394868103298473476811627231543504190652483290944218004086457805431824328448422034887148115990501701345535825110962804471270499590234116100216841170344686381902328362376624405803648588830575558058257742073963036264273582756620469659464278207233345784355220317478103481872995809"); + BigInteger primeP = new BigInteger( + "175002941104568842715096339107566771592009112128184231961529953978142750732317724951747797764638217287618769007295505214923187971350518217670604044004381362495186864051394404165602744235299100790551775147322153206730562450301874236875459336154569893255570576967036237661594595803204808064127845257496057219227"); + BigInteger primeQ = new BigInteger( + "155807574095269324897144428622185380283967159190626345335083690114147315509962698765044950001909553861571493035240542031420213144237033208612132704562174772894369053916729901982420535940939821673277140180113593951522522222348910536202664252481405241042414183668723338300649954708432681241621374644926879028977"); + BigInteger primeExponentP = new BigInteger( + "79745606804504995938838168837578376593737280079895233277372027184693457251170125851946171360348440134236338520742068873132216695552312068793428432338173016914968041076503997528137698610601222912385953171485249299873377130717231063522112968474603281996190849604705284061306758152904594168593526874435238915345"); + BigInteger primeExponentQ = new BigInteger( + "80619964983821018303966686284189517841976445905569830731617605558094658227540855971763115484608005874540349730961777634427740786642996065386667564038755340092176159839025706183161615488856833433976243963682074011475658804676349317075370362785860401437192843468423594688700132964854367053490737073471709030801"); + BigInteger crtCoefficient = new BigInteger( + "2157818511040667226980891229484210846757728661751992467240662009652654684725325675037512595031058612950802328971801913498711880111052682274056041470625863586779333188842602381844572406517251106159327934511268610438516820278066686225397795046020275055545005189953702783748235257613991379770525910232674719428"); + + KeySpec publicKeySpec = new RSAPublicKeySpec(modulus, publicExponent); + KeySpec privateKeySpec = new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, primeP, primeQ, + primeExponentP, primeExponentQ, crtCoefficient); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + + return new KeyPair(keyFactory.generatePublic(publicKeySpec), keyFactory.generatePrivate(privateKeySpec)); + } + + private static AuthenticationResult getAccessToken(String authorization, String resource) throws Exception { + + String clientId = System.getenv("arm.clientid"); + + if (clientId == null) { + throw new Exception("Please inform arm.clientid in the environment settings."); + } + + String clientKey = System.getenv("arm.clientkey"); + String username = System.getenv("arm.username"); + String password = System.getenv("arm.password"); + + AuthenticationResult result = null; + ExecutorService service = null; + try { + service = Executors.newFixedThreadPool(1); + AuthenticationContext context = new AuthenticationContext(authorization, false, service); + + Future future = null; + + if (clientKey != null && password == null) { + ClientCredential credentials = new ClientCredential(clientId, clientKey); + future = context.acquireToken(resource, credentials, null); + } + + if (password != null && clientKey == null) { + future = context.acquireToken(resource, clientId, username, password, null); + } + + if (future == null) { + throw new Exception( + "Missing or ambiguous credentials - please inform exactly one of arm.clientkey or arm.password in the environment settings."); + } + + result = future.get(); + } finally { + service.shutdown(); + } + + if (result == null) { + throw new RuntimeException("authentication result was null"); + } + return result; + } + + private static ServiceClientCredentials createTestCredentials() throws Exception { + return new KeyVaultCredentials() { + + @Override + public String doAuthenticate(String authorization, String resource, String scope) { + try { + if (isRecordMode()) { + AuthenticationResult authResult = getAccessToken(authorization, resource); + return authResult.getAccessToken(); + } else { + return ""; + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + }; + } + + @After + public void afterMethod() throws IOException { + interceptorManager.finalizeInterceptor(); + } + + private static void initPlaybackUri() throws IOException { + if (isPlaybackMode()) { + // 11080 and 11081 needs to be in sync with values in jetty.xml file + playbackUri = PLAYBACK_URI_BASE + "11080"; + } else { + playbackUri = PLAYBACK_URI_BASE + "1234"; + } + } + + public static boolean isPlaybackMode() { + if (testMode == null) + try { + initTestMode(); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Can't init test mode."); + } + return testMode == TestBase.TestMode.PLAYBACK; + } + + public static boolean isRecordMode() { + return !isPlaybackMode(); + } + + private static void initTestMode() throws IOException { + String azureTestMode = System.getenv("AZURE_TEST_MODE"); + if (azureTestMode != null) { + if (azureTestMode.equalsIgnoreCase("Record")) { + testMode = TestBase.TestMode.RECORD; + } else if (azureTestMode.equalsIgnoreCase("Playback")) { + testMode = TestBase.TestMode.PLAYBACK; + } else { + throw new IOException("Unknown AZURE_TEST_MODE: " + azureTestMode); + } + } else { + // System.out.print("Environment variable 'AZURE_TEST_MODE' has not been set + // yet. Using 'Playback' mode."); + testMode = TestBase.TestMode.PLAYBACK; + } + } + +} diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs256.json b/azure-keyvault-integration-tests/target/test-classes/session-records/testSignVerifyServicePs256.json similarity index 65% rename from azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs256.json rename to azure-keyvault-integration-tests/target/test-classes/session-records/testSignVerifyServicePs256.json index b6db285..6070e58 100644 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs256.json +++ b/azure-keyvault-integration-tests/target/test-classes/session-records/testSignVerifyServicePs256.json @@ -1,13 +1,13 @@ { "networkCallRecords" : [ { "Method" : "PUT", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:58:58 GMT", + "date" : "Fri, 08 Jun 2018 22:49:34 GMT", "content-length" : "0", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -23,18 +23,18 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "2c49eec5-fc84-40de-bea9-a37983db6c30", + "x-ms-request-id" : "b9cb5545-50a0-4938-a559-081d48bfdffe", "Body" : "" } }, { "Method" : "PUT", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:58:59 GMT", + "date" : "Fri, 08 Jun 2018 22:49:39 GMT", "content-length" : "666", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -50,18 +50,18 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "f299864a-5b05-481c-897f-1204f9dc8de0", - "Body" : "{\"key\":{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/1e95800035d647749643d20870f75e71\",\"kty\":\"RSA\",\"key_ops\":[\"encrypt\",\"decrypt\",\"sign\",\"verify\",\"wrapKey\",\"unwrapKey\"],\"n\":\"1_6ZtP288hEkKML-L6nFyZh1PD1rmAgwbbwjEvTSDK_008BYWhjp_6ULy9BhWtRIytNkPkm9gzaBTrCpp-vyDXPGa836Htp-w8u5JmxoUZchJh576m3m-8ZYWTmZSAp5SpruyKAmLSxPJHEWPXQntnmuTMjb9HBT9Ltrwc0ZDk-jsMLYunDJrNmrRUxQgb0zQ_Tl5fJjj8j-0KVx2RXtbfWFvf5fRdBYyP3m0aUpoopQPwtXszD2LcSKMJ_TnmnvMWr8MOA5aRlBaGdBk7zBgRafvDPam3Q2AvFA9mfcAVncpfZ3JFm73VARw6MofXtRqOHtZ7y4oNbY95xXwU2r6w\",\"e\":\"AQAB\"},\"attributes\":{\"enabled\":true,\"created\":1528487939,\"updated\":1528487939,\"recoveryLevel\":\"Recoverable+Purgeable\"}}" + "x-ms-request-id" : "4295eef2-ad71-4396-bc23-9b86e77df135", + "Body" : "{\"key\":{\"kid\":\"https://test-vault.vault.azure.net/keys/otherkey2/dc826d7462dd4e38bf0f207c3bf053ab\",\"kty\":\"RSA\",\"key_ops\":[\"encrypt\",\"decrypt\",\"sign\",\"verify\",\"wrapKey\",\"unwrapKey\"],\"n\":\"1_6ZtP288hEkKML-L6nFyZh1PD1rmAgwbbwjEvTSDK_008BYWhjp_6ULy9BhWtRIytNkPkm9gzaBTrCpp-vyDXPGa836Htp-w8u5JmxoUZchJh576m3m-8ZYWTmZSAp5SpruyKAmLSxPJHEWPXQntnmuTMjb9HBT9Ltrwc0ZDk-jsMLYunDJrNmrRUxQgb0zQ_Tl5fJjj8j-0KVx2RXtbfWFvf5fRdBYyP3m0aUpoopQPwtXszD2LcSKMJ_TnmnvMWr8MOA5aRlBaGdBk7zBgRafvDPam3Q2AvFA9mfcAVncpfZ3JFm73VARw6MofXtRqOHtZ7y4oNbY95xXwU2r6w\",\"e\":\"AQAB\"},\"attributes\":{\"enabled\":true,\"created\":1528498179,\"updated\":1528498179,\"recoveryLevel\":\"Recoverable+Purgeable\"}}" } }, { "Method" : "POST", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//verify?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2//verify?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:59:00 GMT", + "date" : "Fri, 08 Jun 2018 22:49:41 GMT", "content-length" : "14", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -77,18 +77,18 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "e44d8f8a-001e-444d-8f5e-604f8a14aabb", + "x-ms-request-id" : "8739205c-44e9-4a76-bf15-877a03d7686d", "Body" : "{\"value\":true}" } }, { "Method" : "POST", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//sign?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2//sign?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:59:01 GMT", + "date" : "Fri, 08 Jun 2018 22:49:43 GMT", "content-length" : "457", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -104,8 +104,8 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "5780f1c8-d5e3-436c-840e-acfcea90e595", - "Body" : "{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/1e95800035d647749643d20870f75e71\",\"value\":\"Y2eM4E9rumhwvEbcjEPkwxvQ-t27FnYhU_vt_WefTfDCy4Em-vXaHs2Q_Rrm81mCq-nq7iHRdR_4HY0Qa5yAvUZgC4e9T5eBysv2JDDsRI5BgvVnL7pRswAKkMJp1tXlUnOHgiX8sW2YIw--qRZK-bSOhw0iGCJWihdomomoLKUf5QdimQbS2_hyw-9EQctigTPSzu1UvkPoxeiOakUUkNXh7SzVwdyzM9gNCvazEFm8eYR21olASdYxdKJv4HNJw6n2N1UTCQUmGcPVB9CTcxbzUNIrj8lw1MHe-XYCGtAKulGlBSK4i6dGfw0NlhQgJn62BZfAMMP103ZIIIoOTQ\"}" + "x-ms-request-id" : "7272cb1e-fb5c-4920-88d4-2037ab9f1597", + "Body" : "{\"kid\":\"https://test-vault.vault.azure.net/keys/otherkey2/dc826d7462dd4e38bf0f207c3bf053ab\",\"value\":\"oAnlOVb7hcetFCBhs5hyGc07zhmTMmyE6cv5m0MoU7tMl8eswnys6PVB2JvcQb1FSqrl9puQTFe3OkTF8gjA5yZFOMrFfhf0ASnlXceEW7ZbPi4-QRjD357uW-yZ0o7C7mrLUgVPCV79szJslVh1sVV7ivjxFZPD8LKld_QDv1OAubUEpOr_G1YAxSTlgB8QVdkliikECfb_XZDqblGdtlIHjN-hTfb7No6HnmKLEnjM7Fok5fN5Sjw4Ah2E-bkZstWYrExsRkadUniLAJhQeIZZkC8UtBOTBElgqhIJNK8aSejPn3tQ65rTlSCt9l_FeNTgjSEjWf2kKjGWYJSV9A\"}" } } ], "variables" : [ ] diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs384.json b/azure-keyvault-integration-tests/target/test-classes/session-records/testSignVerifyServicePs384.json similarity index 65% rename from azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs384.json rename to azure-keyvault-integration-tests/target/test-classes/session-records/testSignVerifyServicePs384.json index 32989db..ee28d33 100644 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs384.json +++ b/azure-keyvault-integration-tests/target/test-classes/session-records/testSignVerifyServicePs384.json @@ -1,13 +1,13 @@ { "networkCallRecords" : [ { "Method" : "PUT", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:59:01 GMT", + "date" : "Fri, 08 Jun 2018 22:49:43 GMT", "content-length" : "0", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -23,18 +23,18 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "0f4a2092-a0c2-48fb-a02e-9a43288d1385", + "x-ms-request-id" : "fa37b118-7261-4a97-aa9d-23c31e55f344", "Body" : "" } }, { "Method" : "PUT", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:59:04 GMT", + "date" : "Fri, 08 Jun 2018 22:49:45 GMT", "content-length" : "666", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -50,18 +50,18 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "d944b732-5079-4005-9434-72f54e96a434", - "Body" : "{\"key\":{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/336d87b9d80a47e18cc3c744c4d11896\",\"kty\":\"RSA\",\"key_ops\":[\"encrypt\",\"decrypt\",\"sign\",\"verify\",\"wrapKey\",\"unwrapKey\"],\"n\":\"1_6ZtP288hEkKML-L6nFyZh1PD1rmAgwbbwjEvTSDK_008BYWhjp_6ULy9BhWtRIytNkPkm9gzaBTrCpp-vyDXPGa836Htp-w8u5JmxoUZchJh576m3m-8ZYWTmZSAp5SpruyKAmLSxPJHEWPXQntnmuTMjb9HBT9Ltrwc0ZDk-jsMLYunDJrNmrRUxQgb0zQ_Tl5fJjj8j-0KVx2RXtbfWFvf5fRdBYyP3m0aUpoopQPwtXszD2LcSKMJ_TnmnvMWr8MOA5aRlBaGdBk7zBgRafvDPam3Q2AvFA9mfcAVncpfZ3JFm73VARw6MofXtRqOHtZ7y4oNbY95xXwU2r6w\",\"e\":\"AQAB\"},\"attributes\":{\"enabled\":true,\"created\":1528487944,\"updated\":1528487944,\"recoveryLevel\":\"Recoverable+Purgeable\"}}" + "x-ms-request-id" : "01b15906-28a8-4a74-a345-5afe3511bff2", + "Body" : "{\"key\":{\"kid\":\"https://test-vault.vault.azure.net/keys/otherkey2/a046f43b2e4e4e10b6c3b2de746a9ed7\",\"kty\":\"RSA\",\"key_ops\":[\"encrypt\",\"decrypt\",\"sign\",\"verify\",\"wrapKey\",\"unwrapKey\"],\"n\":\"1_6ZtP288hEkKML-L6nFyZh1PD1rmAgwbbwjEvTSDK_008BYWhjp_6ULy9BhWtRIytNkPkm9gzaBTrCpp-vyDXPGa836Htp-w8u5JmxoUZchJh576m3m-8ZYWTmZSAp5SpruyKAmLSxPJHEWPXQntnmuTMjb9HBT9Ltrwc0ZDk-jsMLYunDJrNmrRUxQgb0zQ_Tl5fJjj8j-0KVx2RXtbfWFvf5fRdBYyP3m0aUpoopQPwtXszD2LcSKMJ_TnmnvMWr8MOA5aRlBaGdBk7zBgRafvDPam3Q2AvFA9mfcAVncpfZ3JFm73VARw6MofXtRqOHtZ7y4oNbY95xXwU2r6w\",\"e\":\"AQAB\"},\"attributes\":{\"enabled\":true,\"created\":1528498185,\"updated\":1528498185,\"recoveryLevel\":\"Recoverable+Purgeable\"}}" } }, { "Method" : "POST", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//verify?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2//verify?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:59:04 GMT", + "date" : "Fri, 08 Jun 2018 22:49:46 GMT", "content-length" : "14", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -77,18 +77,18 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "b87e6201-9ba6-4881-814c-40614bffd3f0", + "x-ms-request-id" : "3359eb4c-303e-4236-85a2-83106393a901", "Body" : "{\"value\":true}" } }, { "Method" : "POST", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//sign?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2//sign?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:59:06 GMT", + "date" : "Fri, 08 Jun 2018 22:49:50 GMT", "content-length" : "457", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -104,8 +104,8 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "5fe00def-a4fb-426d-99c3-ce6f66c696b1", - "Body" : "{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/336d87b9d80a47e18cc3c744c4d11896\",\"value\":\"istBdKDaP2b8Tm8EjGUMO3ZM2o1RUOskXs3gm2mM_e5LOEzMv2BnGtO8yMDCFFa9nyYbtahzWmOImZpWaRx9FaSOmLpy12OqcVVABgvXGuXnjqT0VK0l9s3wJv_Gk4giAZrzcqprZZPLdQOjeg-lunzAShsm7-TrdrQVsVUpqnOICbfPFSVZU1n3TWwpHG51hcLdowLL8bMo-6gyMAoZhO5QyhHxB4tgN72xHbkR1Cd02lAiBMU2B_vGLe_tkYjQY7b-krHPaa8yhLzrOWCGr1hxlq-u0BFTsuFI7Oitg_0-IqvvhW-qNDubjL2vXu1WoHqzSGLZm7myWWP-XXFjFQ\"}" + "x-ms-request-id" : "b1abe427-40a5-4590-8bf4-0c99e5caab4f", + "Body" : "{\"kid\":\"https://test-vault.vault.azure.net/keys/otherkey2/a046f43b2e4e4e10b6c3b2de746a9ed7\",\"value\":\"QsN05RCM9lADsZalIFlxeRBDr2zEQdlrdkjsqWr3t5wYt3R_X6driSEw-PRMw2JypZvB5I-OfPG716DSz-gZaYVIsNMLQdYj8pzhGly8meUClwRWWhZ_6GjSv0lkHTUEdsYTzDVYPz7F0Ykwxl8lBhaAM7GIcTzs4qyYDsGViMQzUjrwS9zDh-m7qgBvGGANul2Z5USc18aBRcLXEOmW7PADrnr3uxi0KNOhQeHHgtguuGyEMwF83fyD6jIf2NfYF75LOkeaSwAWfRhYJ_seX5gN_HI19wkRGF-2vPRu5z_IpCBtp7_Wk3f4zmURnotD5xpruZntbcitbZqXH0N1Yg\"}" } } ], "variables" : [ ] diff --git a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs512.json b/azure-keyvault-integration-tests/target/test-classes/session-records/testSignVerifyServicePs512.json similarity index 65% rename from azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs512.json rename to azure-keyvault-integration-tests/target/test-classes/session-records/testSignVerifyServicePs512.json index f6bdd3e..922603f 100644 --- a/azure-keyvault-cryptography/target/test-classes/session-records/testSignVerifyServicePs512.json +++ b/azure-keyvault-integration-tests/target/test-classes/session-records/testSignVerifyServicePs512.json @@ -1,13 +1,13 @@ { "networkCallRecords" : [ { "Method" : "PUT", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:59:07 GMT", + "date" : "Fri, 08 Jun 2018 22:49:49 GMT", "content-length" : "0", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -23,18 +23,18 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "8cf9c8b0-7a34-4c29-9837-831aea552394", + "x-ms-request-id" : "764b0170-345f-4204-ba41-55317c5e41b0", "Body" : "" } }, { "Method" : "PUT", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:59:09 GMT", + "date" : "Fri, 08 Jun 2018 22:49:54 GMT", "content-length" : "666", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -50,18 +50,18 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "a4294f1d-edb7-42b9-ac6d-600983782007", - "Body" : "{\"key\":{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/3789a33dc0b64934a666bc3e646d9691\",\"kty\":\"RSA\",\"key_ops\":[\"encrypt\",\"decrypt\",\"sign\",\"verify\",\"wrapKey\",\"unwrapKey\"],\"n\":\"1_6ZtP288hEkKML-L6nFyZh1PD1rmAgwbbwjEvTSDK_008BYWhjp_6ULy9BhWtRIytNkPkm9gzaBTrCpp-vyDXPGa836Htp-w8u5JmxoUZchJh576m3m-8ZYWTmZSAp5SpruyKAmLSxPJHEWPXQntnmuTMjb9HBT9Ltrwc0ZDk-jsMLYunDJrNmrRUxQgb0zQ_Tl5fJjj8j-0KVx2RXtbfWFvf5fRdBYyP3m0aUpoopQPwtXszD2LcSKMJ_TnmnvMWr8MOA5aRlBaGdBk7zBgRafvDPam3Q2AvFA9mfcAVncpfZ3JFm73VARw6MofXtRqOHtZ7y4oNbY95xXwU2r6w\",\"e\":\"AQAB\"},\"attributes\":{\"enabled\":true,\"created\":1528487949,\"updated\":1528487949,\"recoveryLevel\":\"Recoverable+Purgeable\"}}" + "x-ms-request-id" : "cfdd5e4e-1f7a-4d61-a2c7-0e6ad6159f47", + "Body" : "{\"key\":{\"kid\":\"https://test-vault.vault.azure.net/keys/otherkey2/47041a5e3b994e4b9db708d6352408d0\",\"kty\":\"RSA\",\"key_ops\":[\"encrypt\",\"decrypt\",\"sign\",\"verify\",\"wrapKey\",\"unwrapKey\"],\"n\":\"1_6ZtP288hEkKML-L6nFyZh1PD1rmAgwbbwjEvTSDK_008BYWhjp_6ULy9BhWtRIytNkPkm9gzaBTrCpp-vyDXPGa836Htp-w8u5JmxoUZchJh576m3m-8ZYWTmZSAp5SpruyKAmLSxPJHEWPXQntnmuTMjb9HBT9Ltrwc0ZDk-jsMLYunDJrNmrRUxQgb0zQ_Tl5fJjj8j-0KVx2RXtbfWFvf5fRdBYyP3m0aUpoopQPwtXszD2LcSKMJ_TnmnvMWr8MOA5aRlBaGdBk7zBgRafvDPam3Q2AvFA9mfcAVncpfZ3JFm73VARw6MofXtRqOHtZ7y4oNbY95xXwU2r6w\",\"e\":\"AQAB\"},\"attributes\":{\"enabled\":true,\"created\":1528498195,\"updated\":1528498195,\"recoveryLevel\":\"Recoverable+Purgeable\"}}" } }, { "Method" : "POST", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//verify?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2//verify?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:59:10 GMT", + "date" : "Fri, 08 Jun 2018 22:49:57 GMT", "content-length" : "14", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -77,18 +77,18 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "feb9ddbb-861c-451b-a7f4-739d315436e8", + "x-ms-request-id" : "60f00eb1-21fe-458e-97b0-23c9d89610c2", "Body" : "{\"value\":true}" } }, { "Method" : "POST", - "Uri" : "https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2//sign?api-version=7.0-preview", + "Uri" : "https://test-vault.vault.azure.net/keys/otherkey2//sign?api-version=7.0-preview", "Headers" : { "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:08b8c65810754c5927ba6275e7902c61544ffc9cb2de4d24196bc80b2fbba780 Java:1.8.0_172 (KeyVaultClientBase, 7.0-preview)", "Content-Type" : "application/json; charset=utf-8" }, "Response" : { - "date" : "Fri, 08 Jun 2018 19:59:11 GMT", + "date" : "Fri, 08 Jun 2018 22:49:57 GMT", "content-length" : "457", "server" : "Microsoft-IIS/10.0", "expires" : "-1", @@ -104,8 +104,8 @@ "x-ms-keyvault-region" : "West US", "cache-control" : "no-cache", "x-ms-keyvault-service-version" : "1.0.0.849", - "x-ms-request-id" : "3365c873-26b3-4a2c-a62b-5ebeeb8481a2", - "Body" : "{\"kid\":\"https://tifchen-keyvault-fancy.vault.azure.net/keys/otherkey2/3789a33dc0b64934a666bc3e646d9691\",\"value\":\"DP9rsnU4XbxwOTqLmQGZiGTxKGR7OPZrrOiqLXhNKxaiD2TK7zmDv1rEhK83r1MQ64jBHLNIXhNsayhiqX_tR56s1qWhw0sCw0TIbGw02PaR_DaRdS9LsALnpq9sqnphwcx7hK1jHUFgZX-njk193x8fgOVRSq_BnLfwDiIvLehYxr8kU2E_WhkBDVwSB_VzWfaAPM-9Snr00ciZ3_TL-avKhdIBSrl8OXFKa1CPu2pMSPb3JMhOoeI6Uwj6g_6ACXnHveeoG7YyVswS4kTUhr0uUqQobEyVpEcuS177hb1xL3n5Ze5nXX3laDyfM0-Zkfjr-J13gpzsn-fb8rx2Og\"}" + "x-ms-request-id" : "4c7af713-5c3f-4436-a1b6-5e3e68048ca7", + "Body" : "{\"kid\":\"https://test-vault.vault.azure.net/keys/otherkey2/47041a5e3b994e4b9db708d6352408d0\",\"value\":\"Gf3Nw4iUaJI3Ob0M3x4WcQJl5K8JbRyGsU6ucPESEYB5aMSKeysMriinXCVZZnm6FMYh39BKqCrlhsv7mvMmwqRFVbGkfjiargwuB1ZS2j1xQOn0CCpIJ4WBpZVWjk8oALp_UuanmdmP6J1hoWa0CNeExMMU_5dDUYTafPM9ttHDmuEZ35cUucS5BxjKCqGI_j0wMbc2FjkpAg1NDuOHyos9fTbbMSF0ts0wp7FTSBoYE39-wj7PMTmA3YWodqH-ZCK8vpfbSQ0_zNvbF7nDxxvZ8HUj1oyrmg9DTwNBWKSb1bIkHjgYjW2ThN2VLVJaNel9J_1MukzeQT1NDyFbyA\"}" } } ], "variables" : [ ] diff --git a/pom.xml b/pom.xml index 5c78c38..5a79765 100644 --- a/pom.xml +++ b/pom.xml @@ -1,9 +1,9 @@ + - +--> 4.0.0 com.microsoft.azure 1.1-beta-1 @@ -302,7 +302,7 @@ - + @@ -345,7 +345,7 @@ - + @@ -361,5 +361,6 @@ ./azure-keyvault-webkey ./azure-keyvault-cryptography ./azure-keyvault-extensions + ./azure-keyvault-integration-tests - + \ No newline at end of file From 34a5888f4ba6a39cee11dbe4e810a633ee2218bf Mon Sep 17 00:00:00 2001 From: tiffanyachen Date: Fri, 8 Jun 2018 15:58:31 -0700 Subject: [PATCH 5/5] needed junit --- azure-keyvault-integration-tests/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/azure-keyvault-integration-tests/pom.xml b/azure-keyvault-integration-tests/pom.xml index 5153f69..463fdf1 100644 --- a/azure-keyvault-integration-tests/pom.xml +++ b/azure-keyvault-integration-tests/pom.xml @@ -15,6 +15,11 @@ UTF-8 + + junit + junit + test + com.microsoft.azure azure-keyvault-webkey