Skip to content

Commit 7e2dde6

Browse files
Adding validation to AesGcm key cipher and moving ArrayPrefixEquals to Utils
1 parent f789a23 commit 7e2dde6

File tree

4 files changed

+46
-14
lines changed

4 files changed

+46
-14
lines changed

src/main/java/com/amazonaws/encryptionsdk/internal/AesGcmJceKeyCipher.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.DataOutputStream;
2323
import java.io.IOException;
2424
import java.security.GeneralSecurityException;
25+
import java.security.InvalidKeyException;
2526
import java.security.Key;
2627
import java.security.SecureRandom;
2728
import java.util.Map;
@@ -54,11 +55,20 @@ private static byte[] specToBytes(final GCMParameterSpec spec) {
5455
return baos.toByteArray();
5556
}
5657

57-
private static GCMParameterSpec bytesToSpec(final byte[] data, final int offset) {
58+
private static GCMParameterSpec bytesToSpec(final byte[] data, final int offset) throws GeneralSecurityException {
5859
final ByteArrayInputStream bais = new ByteArrayInputStream(data, offset, data.length - offset);
5960
try (final DataInputStream dis = new DataInputStream(bais)) {
6061
final int tagLen = dis.readInt();
6162
final int nonceLen = dis.readInt();
63+
64+
if(tagLen != TAG_LENGTH) {
65+
throw new InvalidKeyException(String.format("Authentication tag length must be %s", TAG_LENGTH));
66+
}
67+
68+
if(nonceLen != NONCE_LENGTH) {
69+
throw new InvalidKeyException(String.format("Initialization vector (IV) length must be %s", NONCE_LENGTH));
70+
}
71+
6272
final byte[] nonce = new byte[nonceLen];
6373
dis.readFully(nonce);
6474
return new GCMParameterSpec(tagLen, nonce);

src/main/java/com/amazonaws/encryptionsdk/internal/Utils.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,4 +311,24 @@ public static byte[] bigIntegerToByteArray(final BigInteger bigInteger, final in
311311
System.arraycopy(rawBytes, 0, paddedResult, length - rawBytes.length, rawBytes.length);
312312
return paddedResult;
313313
}
314+
315+
/**
316+
* Returns true if the prefix of the given length for the input arrays are equal.
317+
*
318+
* @param a The first array.
319+
* @param b The second array.
320+
* @param length The length of the prefix to compare.
321+
* @return True if the prefixes are equal, false otherwise.
322+
*/
323+
public static boolean arrayPrefixEquals(final byte[] a, final byte[] b, final int length) {
324+
if (a == null || b == null || a.length < length || b.length < length) {
325+
return false;
326+
}
327+
for (int x = 0; x < length; x++) {
328+
if (a[x] != b[x]) {
329+
return false;
330+
}
331+
}
332+
return true;
333+
}
314334
}

src/main/java/com/amazonaws/encryptionsdk/jce/JceMasterKey.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.amazonaws.encryptionsdk.exception.AwsCryptoException;
2121
import com.amazonaws.encryptionsdk.exception.UnsupportedProviderException;
2222
import com.amazonaws.encryptionsdk.internal.JceKeyCipher;
23+
import com.amazonaws.encryptionsdk.internal.Utils;
2324

2425
import javax.crypto.SecretKey;
2526
import javax.crypto.spec.SecretKeySpec;
@@ -142,7 +143,7 @@ public DataKey<JceMasterKey> decryptDataKey(final CryptoAlgorithm algorithm,
142143
for (final EncryptedDataKey edk : encryptedDataKeys) {
143144
try {
144145
if (edk.getProviderId().equals(getProviderId())
145-
&& arrayPrefixEquals(edk.getProviderInformation(), keyIdBytes_, keyIdBytes_.length)) {
146+
&& Utils.arrayPrefixEquals(edk.getProviderInformation(), keyIdBytes_, keyIdBytes_.length)) {
146147
final byte[] decryptedKey = jceKeyCipher_.decryptKey(edk, keyId_, encryptionContext);
147148

148149
// Validate that the decrypted key length is as expected
@@ -157,16 +158,4 @@ && arrayPrefixEquals(edk.getProviderInformation(), keyIdBytes_, keyIdBytes_.leng
157158
}
158159
throw buildCannotDecryptDksException(exceptions);
159160
}
160-
161-
private static boolean arrayPrefixEquals(final byte[] a, final byte[] b, final int len) {
162-
if (a == null || b == null || a.length < len || b.length < len) {
163-
return false;
164-
}
165-
for (int x = 0; x < len; x++) {
166-
if (a[x] != b[x]) {
167-
return false;
168-
}
169-
}
170-
return true;
171-
}
172161
}

src/test/java/com/amazonaws/encryptionsdk/UtilsTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.junit.Assert.assertArrayEquals;
44
import static org.junit.Assert.assertEquals;
5+
import static org.junit.Assert.assertFalse;
56
import static org.junit.Assert.assertNotEquals;
67
import static org.junit.Assert.assertTrue;
78

@@ -121,5 +122,17 @@ public void testBigIntegerToByteArray_InvalidLength() {
121122
Utils.bigIntegerToByteArray(new BigInteger(bytes), 3));
122123
}
123124

125+
@Test
126+
public void testArrayPrefixEquals() {
127+
byte[] a = new byte[] {10, 11, 12, 13, 14, 15};
128+
byte[] b = new byte[] {10, 11, 12, 13, 20, 21, 22};
129+
130+
assertFalse(Utils.arrayPrefixEquals(null, b, 4));
131+
assertFalse(Utils.arrayPrefixEquals(a, null, 4));
132+
assertFalse(Utils.arrayPrefixEquals(a, b, a.length + 1));
133+
assertTrue(Utils.arrayPrefixEquals(a, b, 4));
134+
assertFalse(Utils.arrayPrefixEquals(a, b, 5));
135+
}
136+
124137
}
125138

0 commit comments

Comments
 (0)