Skip to content

Commit d36235f

Browse files
*Issue #, if available:* #41
*Description of changes:* Remaining fixes to allow BouncyCastle to be swapped out with other implementations. 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.
1 parent 3fa1cf8 commit d36235f

File tree

6 files changed

+52
-101
lines changed

6 files changed

+52
-101
lines changed

src/main/java/com/amazonaws/encryptionsdk/CryptoAlgorithm.java

+4-14
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import javax.crypto.SecretKey;
2525
import javax.crypto.spec.SecretKeySpec;
2626

27-
import com.amazonaws.encryptionsdk.internal.BouncyCastleConfiguration;
2827
import com.amazonaws.encryptionsdk.internal.HmacKeyDerivationFunction;
2928

3029
import com.amazonaws.encryptionsdk.internal.Constants;
@@ -99,27 +98,19 @@ public enum CryptoAlgorithm {
9998
private final int dataKeyLen_;
10099
private final boolean safeToCache_;
101100

102-
/**
103-
* This block is used to ensure static blocks of BouncyCastleConfiguration are evaluated as a dependency of
104-
* the CryptoAlgorithm class
105-
*/
106-
static {
107-
BouncyCastleConfiguration.init();
108-
}
109-
110101
/*
111102
* Create a mapping between the CiphertextType object and its byte value representation. Make
112103
* this is a static method so the map is created when the object is created. This enables fast
113104
* lookups of the CryptoAlgorithm given its short value representation.
114105
*/
115-
private static final Map<Short, CryptoAlgorithm> ID_MAPPING = new HashMap<Short, CryptoAlgorithm>();
106+
private static final Map<Short, CryptoAlgorithm> ID_MAPPING = new HashMap<>();
116107
static {
117108
for (final CryptoAlgorithm s : EnumSet.allOf(CryptoAlgorithm.class)) {
118109
ID_MAPPING.put(s.value_, s);
119110
}
120111
}
121112

122-
private CryptoAlgorithm(
113+
CryptoAlgorithm(
123114
final int blockSizeBits, final int nonceLenBytes, final int tagLenBytes,
124115
final long maxContentLen, final String keyAlgo, final int keyLenBytes, final int value,
125116
final String dataKeyAlgo, final int dataKeyLen, boolean safeToCache
@@ -130,7 +121,7 @@ private CryptoAlgorithm(
130121

131122
}
132123

133-
private CryptoAlgorithm(
124+
CryptoAlgorithm(
134125
final int blockSizeBits, final int nonceLenBytes, final int tagLenBytes,
135126
final long maxContentLen, final String keyAlgo, final int keyLenBytes, final int value,
136127
final String dataKeyAlgo, final int dataKeyLen,
@@ -164,8 +155,7 @@ private CryptoAlgorithm(
164155
* @return the CryptoAlgorithm object that matches the given value, null if no match is found.
165156
*/
166157
public static CryptoAlgorithm deserialize(final short value) {
167-
final CryptoAlgorithm result = ID_MAPPING.get(value);
168-
return result;
158+
return ID_MAPPING.get(value);
169159
}
170160

171161
/**

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

-37
This file was deleted.

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ private static final class ECDSASignatureAlgorithm extends TrailingSignatureAlgo
5959
private static final BigInteger THREE = BigInteger.valueOf(3);
6060
private static final BigInteger FOUR = BigInteger.valueOf(4);
6161

62-
private ECDSASignatureAlgorithm(ECGenParameterSpec ecSpec, String messageDigestAlgorithm) {
62+
private ECDSASignatureAlgorithm(ECGenParameterSpec ecSpec, String messageDigestAlgorithm, String hashAndSignAlgorithm) {
6363
if (!ecSpec.getName().startsWith(SEC_PRIME_FIELD_PREFIX)) {
6464
throw new IllegalStateException("Non-prime curves are not supported at this time");
6565
}
6666

6767
this.ecSpec = ecSpec;
6868
this.messageDigestAlgorithm = messageDigestAlgorithm;
69-
this.hashAndSignAlgorithm = messageDigestAlgorithm + "withECDSA";
69+
this.hashAndSignAlgorithm = hashAndSignAlgorithm;
7070

7171
try {
7272
final AlgorithmParameters parameters = AlgorithmParameters.getInstance(ELLIPTIC_CURVE_ALGORITHM);
@@ -190,9 +190,9 @@ public KeyPair generateKey() throws GeneralSecurityException {
190190
}
191191

192192
private static final ECDSASignatureAlgorithm SHA256_ECDSA_P256
193-
= new ECDSASignatureAlgorithm(new ECGenParameterSpec(SEC_PRIME_FIELD_PREFIX + "256r1"), "SHA256");
193+
= new ECDSASignatureAlgorithm(new ECGenParameterSpec(SEC_PRIME_FIELD_PREFIX + "256r1"), "SHA-256", "SHA256withECDSA");
194194
private static final ECDSASignatureAlgorithm SHA384_ECDSA_P384
195-
= new ECDSASignatureAlgorithm(new ECGenParameterSpec(SEC_PRIME_FIELD_PREFIX + "384r1"), "SHA384");
195+
= new ECDSASignatureAlgorithm(new ECGenParameterSpec(SEC_PRIME_FIELD_PREFIX + "384r1"), "SHA-384", "SHA384withECDSA");
196196

197197
public static TrailingSignatureAlgorithm forCryptoAlgorithm(CryptoAlgorithm algorithm) {
198198
switch (algorithm) {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ public static ByteBuffer limit(final ByteBuffer buff, final int newLimit) {
268268
* @return decoded data as a byte array
269269
*/
270270
public static byte[] decodeBase64String(final String encoded) {
271-
return Base64.decode(encoded);
271+
return encoded.isEmpty() ? new byte[0] : Base64.decode(encoded);
272272
}
273273

274274
/**

src/test/java/com/amazonaws/encryptionsdk/internal/CipherHandlerTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void tamperCiphertext() {
4747
final byte[] keyBytes = RandomBytesGenerator.generate(cryptoAlgorithm.getKeyLength());
4848
final byte[] nonce = RandomBytesGenerator.generate(cryptoAlgorithm.getNonceLen());
4949

50-
final SecretKey key = new SecretKeySpec(keyBytes, cryptoAlgorithm.name());
50+
final SecretKey key = new SecretKeySpec(keyBytes, cryptoAlgorithm.getKeyAlgo());
5151
CipherHandler cipherHandler = createCipherHandler(key, cryptoAlgorithm, Cipher.ENCRYPT_MODE);
5252
final byte[] encryptedBytes = cipherHandler.cipherData(nonce, contentAad_, content, 0, content.length);
5353

@@ -72,7 +72,7 @@ private byte[] encryptDecrypt(final byte[] content, final CryptoAlgorithm crypto
7272
final byte[] keyBytes = RandomBytesGenerator.generate(cryptoAlgorithm.getKeyLength());
7373
final byte[] nonce = RandomBytesGenerator.generate(cryptoAlgorithm.getNonceLen());
7474

75-
final SecretKey key = new SecretKeySpec(keyBytes, cryptoAlgorithm.name());
75+
final SecretKey key = new SecretKeySpec(keyBytes, cryptoAlgorithm.getKeyAlgo());
7676
CipherHandler cipherHandler = createCipherHandler(key, cryptoAlgorithm, Cipher.ENCRYPT_MODE);
7777
final byte[] encryptedBytes = cipherHandler.cipherData( nonce, contentAad_, content, 0, content.length);
7878

src/test/java/com/amazonaws/encryptionsdk/jce/KeyStoreProviderTest.java

+41-43
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,14 @@
2727
import java.security.KeyStore.PasswordProtection;
2828
import java.security.KeyStoreException;
2929
import java.security.SecureRandom;
30-
import java.security.Security;
3130
import java.security.cert.Certificate;
3231
import java.security.cert.X509Certificate;
32+
import java.time.Instant;
33+
import java.time.temporal.ChronoUnit;
3334
import java.util.Date;
3435

3536
import javax.crypto.spec.SecretKeySpec;
36-
import javax.security.auth.x500.X500Principal;
3737

38-
import org.bouncycastle.asn1.x509.X509Name;
39-
import org.bouncycastle.jce.provider.BouncyCastleProvider;
40-
import org.bouncycastle.x509.X509V3CertificateGenerator;
4138
import org.junit.Before;
4239
import org.junit.Test;
4340

@@ -46,8 +43,15 @@
4643
import com.amazonaws.encryptionsdk.MasterKeyProvider;
4744
import com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException;
4845
import com.amazonaws.encryptionsdk.multi.MultipleProviderFactory;
46+
import sun.security.x509.AlgorithmId;
47+
import sun.security.x509.CertificateAlgorithmId;
48+
import sun.security.x509.CertificateSerialNumber;
49+
import sun.security.x509.CertificateValidity;
50+
import sun.security.x509.CertificateX509Key;
51+
import sun.security.x509.X500Name;
52+
import sun.security.x509.X509CertImpl;
53+
import sun.security.x509.X509CertInfo;
4954

50-
@SuppressWarnings("deprecation")
5155
public class KeyStoreProviderTest {
5256
private static final SecureRandom RND = new SecureRandom();
5357
private static final KeyPairGenerator KG;
@@ -72,7 +76,7 @@ public void setup() throws Exception {
7276
}
7377

7478
@Test
75-
public void singleKeyPkcs1() throws GeneralSecurityException {
79+
public void singleKeyPkcs1() throws Exception {
7680
addEntry("key1");
7781
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/PKCS1Padding", "key1");
7882
final JceMasterKey mk1 = mkp.getMasterKey("key1");
@@ -87,7 +91,7 @@ public void singleKeyPkcs1() throws GeneralSecurityException {
8791
}
8892

8993
@Test
90-
public void singleKeyOaepSha1() throws GeneralSecurityException {
94+
public void singleKeyOaepSha1() throws Exception {
9195
addEntry("key1");
9296
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-1AndMGF1Padding",
9397
"key1");
@@ -103,7 +107,7 @@ public void singleKeyOaepSha1() throws GeneralSecurityException {
103107
}
104108

105109
@Test
106-
public void singleKeyOaepSha256() throws GeneralSecurityException {
110+
public void singleKeyOaepSha256() throws Exception {
107111
addEntry("key1");
108112
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding",
109113
"key1");
@@ -119,7 +123,7 @@ public void singleKeyOaepSha256() throws GeneralSecurityException {
119123
}
120124

121125
@Test
122-
public void multipleKeys() throws GeneralSecurityException {
126+
public void multipleKeys() throws Exception {
123127
addEntry("key1");
124128
addEntry("key2");
125129
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding",
@@ -146,7 +150,7 @@ public void multipleKeys() throws GeneralSecurityException {
146150
}
147151

148152
@Test(expected = CannotUnwrapDataKeyException.class)
149-
public void encryptOnly() throws GeneralSecurityException {
153+
public void encryptOnly() throws Exception {
150154
addPublicEntry("key1");
151155
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding",
152156
"key1");
@@ -157,7 +161,7 @@ public void encryptOnly() throws GeneralSecurityException {
157161
}
158162

159163
@Test
160-
public void escrowAndSymmetric() throws GeneralSecurityException {
164+
public void escrowAndSymmetric() throws Exception {
161165
addPublicEntry("key1");
162166
addEntry("key2");
163167
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding",
@@ -185,7 +189,7 @@ public void escrowAndSymmetric() throws GeneralSecurityException {
185189
}
186190

187191
@Test
188-
public void escrowAndSymmetricSecondProvider() throws GeneralSecurityException {
192+
public void escrowAndSymmetricSecondProvider() throws GeneralSecurityException, IOException {
189193
addPublicEntry("key1");
190194
addEntry("key2");
191195
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding",
@@ -263,40 +267,34 @@ public void keystoreAndRawProvider() throws GeneralSecurityException, IOExceptio
263267
assertArrayEquals(PLAINTEXT, crypto.decryptData(ksp, ct.getResult()).getResult());
264268
}
265269

266-
private void addEntry(final String alias) throws GeneralSecurityException {
270+
private void addEntry(final String alias) throws GeneralSecurityException, IOException {
267271
final KeyPair pair = KG.generateKeyPair();
268-
// build a certificate generator
269-
final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
270-
final X500Principal dnName = new X500Principal("cn=" + alias);
271-
272-
certGen.setSerialNumber(new BigInteger(256, RND));
273-
certGen.setSubjectDN(new X509Name("dc=" + alias));
274-
certGen.setIssuerDN(dnName); // use the same
275-
certGen.setNotBefore(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000));
276-
certGen.setNotAfter(new Date(System.currentTimeMillis() + 2 * 365 * 24 * 60 * 60 * 1000));
277-
certGen.setPublicKey(pair.getPublic());
278-
certGen.setSignatureAlgorithm("SHA256WithRSA");
279-
final X509Certificate cert = certGen.generate(pair.getPrivate(), "BC");
280-
281-
ks.setEntry(alias, new KeyStore.PrivateKeyEntry(pair.getPrivate(), new X509Certificate[] { cert }), PP);
272+
ks.setEntry(alias, new KeyStore.PrivateKeyEntry(pair.getPrivate(),
273+
new X509Certificate[] { generateCertificate(pair, alias) }), PP);
282274
}
283275

284-
private void addPublicEntry(final String alias) throws GeneralSecurityException {
276+
private void addPublicEntry(final String alias) throws GeneralSecurityException, IOException {
285277
final KeyPair pair = KG.generateKeyPair();
286-
// build a certificate generator
287-
final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
288-
final X500Principal dnName = new X500Principal("cn=" + alias);
289-
290-
certGen.setSerialNumber(new BigInteger(256, RND));
291-
certGen.setSubjectDN(new X509Name("dc=" + alias));
292-
certGen.setIssuerDN(dnName); // use the same
293-
certGen.setNotBefore(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000));
294-
certGen.setNotAfter(new Date(System.currentTimeMillis() + 2 * 365 * 24 * 60 * 60 * 1000));
295-
certGen.setPublicKey(pair.getPublic());
296-
certGen.setSignatureAlgorithm("SHA256WithRSA");
297-
final X509Certificate cert = certGen.generate(pair.getPrivate(), "BC");
298-
299-
ks.setEntry(alias, new KeyStore.TrustedCertificateEntry(cert), null);
278+
ks.setEntry(alias, new KeyStore.TrustedCertificateEntry(generateCertificate(pair, alias)), null);
279+
}
280+
281+
private X509Certificate generateCertificate(final KeyPair pair, final String alias) throws GeneralSecurityException, IOException {
282+
final X509CertInfo info = new X509CertInfo();
283+
final X500Name name = new X500Name("dc=" + alias);
284+
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(new BigInteger(256, RND)));
285+
info.set(X509CertInfo.SUBJECT, name);
286+
info.set(X509CertInfo.ISSUER, name);
287+
info.set(X509CertInfo.VALIDITY,
288+
new CertificateValidity(Date.from(Instant.now().minus(1, ChronoUnit.DAYS)),
289+
Date.from(Instant.now().plus(730, ChronoUnit.DAYS))));
290+
info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
291+
info.set(X509CertInfo.ALGORITHM_ID,
292+
new CertificateAlgorithmId(new AlgorithmId(AlgorithmId.sha256WithRSAEncryption_oid)));
293+
294+
final X509CertImpl cert = new X509CertImpl(info);
295+
cert.sign(pair.getPrivate(), AlgorithmId.sha256WithRSAEncryption_oid.toString());
296+
297+
return cert;
300298
}
301299

302300
private void copyPublicPart(final KeyStore src, final KeyStore dst, final String alias) throws KeyStoreException {

0 commit comments

Comments
 (0)