From 3ef8958d1ea8d2ebe98214c0a3240d94667b05c2 Mon Sep 17 00:00:00 2001 From: Wesley Rosenblum <55108558+WesleyRosenblum@users.noreply.github.com> Date: Wed, 23 Oct 2019 16:43:21 -0700 Subject: [PATCH] Fix unit tests to work with FIPS certified Bouncy Castle (#132) *Issue #, if available:* #99 *Description of changes:* These changes allow for the unit tests to pass when the FIPS validated Bouncy Castle provider is explicitly set. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. # Check any applicable: - [ ] Were any files moved? Moving files changes their URL, which breaks all hyperlinks to the files. --- .../internal/RandomBytesGenerator.java | 27 ----------- .../internal/RandomBytesGenerator.java | 48 +++++++++++++++++++ .../internal/StaticMasterKey.java | 9 +++- 3 files changed, 55 insertions(+), 29 deletions(-) delete mode 100644 src/main/java/com/amazonaws/encryptionsdk/internal/RandomBytesGenerator.java create mode 100644 src/test/java/com/amazonaws/encryptionsdk/internal/RandomBytesGenerator.java diff --git a/src/main/java/com/amazonaws/encryptionsdk/internal/RandomBytesGenerator.java b/src/main/java/com/amazonaws/encryptionsdk/internal/RandomBytesGenerator.java deleted file mode 100644 index e9e4fe2d8..000000000 --- a/src/main/java/com/amazonaws/encryptionsdk/internal/RandomBytesGenerator.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.encryptionsdk.internal; - -import java.security.SecureRandom; - -public class RandomBytesGenerator { - private static final SecureRandom RND = new SecureRandom(); - - public static byte[] generate(final int len) { - byte[] result = new byte[len]; - RND.nextBytes(result); - return result; - } - -} diff --git a/src/test/java/com/amazonaws/encryptionsdk/internal/RandomBytesGenerator.java b/src/test/java/com/amazonaws/encryptionsdk/internal/RandomBytesGenerator.java new file mode 100644 index 000000000..45718b230 --- /dev/null +++ b/src/test/java/com/amazonaws/encryptionsdk/internal/RandomBytesGenerator.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.encryptionsdk.internal; + +import java.security.SecureRandom; + +public class RandomBytesGenerator { + private static final SecureRandom RND = new SecureRandom(); + + /* Some Providers (such as the FIPS certified Bouncy Castle) enforce a + * maximum number of bytes that may be requested from SecureRandom. If + * the requested len is larger than this value, the Secure Random will + * be called multiple times to achieve the requested total length. */ + private static final int MAX_BYTES = 1 << 15; + + /** + * Generates a byte array of random data of the given length. + * + * @param len The length of the byte array. + * @return The byte array. + */ + public static byte[] generate(final int len) { + final byte[] result = new byte[len]; + int bytesGenerated = 0; + + while (bytesGenerated < len) { + final int requestSize = Math.min(MAX_BYTES, len - bytesGenerated); + final byte[] request = new byte[requestSize]; + RND.nextBytes(request); + System.arraycopy(request, 0, result, bytesGenerated, requestSize); + bytesGenerated += requestSize; + } + + return result; + } + +} diff --git a/src/test/java/com/amazonaws/encryptionsdk/internal/StaticMasterKey.java b/src/test/java/com/amazonaws/encryptionsdk/internal/StaticMasterKey.java index b0f1d8fb7..b4d5b66db 100644 --- a/src/test/java/com/amazonaws/encryptionsdk/internal/StaticMasterKey.java +++ b/src/test/java/com/amazonaws/encryptionsdk/internal/StaticMasterKey.java @@ -49,7 +49,12 @@ public class StaticMasterKey extends MasterKey { /** * Encryption algorithm for the master key-pair */ - private static final String MASTER_KEY_ENCRYPTION_ALGORITHM = "RSA"; + private static final String MASTER_KEY_ENCRYPTION_ALGORITHM = "RSA/ECB/PKCS1Padding"; + + /** + * Encryption algorithm for the KeyFactory + */ + private static final String MASTER_KEY_ALGORITHM = "RSA"; /** * Encryption algorithm for the randomly generated data key @@ -95,7 +100,7 @@ public StaticMasterKey(@Nonnull final String keyId) { this.keyId_ = Objects.requireNonNull(keyId); try { - KeyFactory keyFactory = KeyFactory.getInstance(MASTER_KEY_ENCRYPTION_ALGORITHM); + KeyFactory keyFactory = KeyFactory.getInstance(MASTER_KEY_ALGORITHM); KeySpec publicKeySpec = new X509EncodedKeySpec(publicKey_v1); PublicKey pubKey = keyFactory.generatePublic(publicKeySpec); KeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKey_v1);