-
Notifications
You must be signed in to change notification settings - Fork 122
Remaining fixes to allow BouncyCastle to be swapped out with other implementations. #131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
af0e969
3fa1cf8
d36235f
9d86ce2
4c2c0a5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,17 +27,14 @@ | |
import java.security.KeyStore.PasswordProtection; | ||
import java.security.KeyStoreException; | ||
import java.security.SecureRandom; | ||
import java.security.Security; | ||
import java.security.cert.Certificate; | ||
import java.security.cert.X509Certificate; | ||
import java.time.Instant; | ||
import java.time.temporal.ChronoUnit; | ||
import java.util.Date; | ||
|
||
import javax.crypto.spec.SecretKeySpec; | ||
import javax.security.auth.x500.X500Principal; | ||
|
||
import org.bouncycastle.asn1.x509.X509Name; | ||
import org.bouncycastle.jce.provider.BouncyCastleProvider; | ||
import org.bouncycastle.x509.X509V3CertificateGenerator; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
|
@@ -46,8 +43,15 @@ | |
import com.amazonaws.encryptionsdk.MasterKeyProvider; | ||
import com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException; | ||
import com.amazonaws.encryptionsdk.multi.MultipleProviderFactory; | ||
import sun.security.x509.AlgorithmId; | ||
import sun.security.x509.CertificateAlgorithmId; | ||
import sun.security.x509.CertificateSerialNumber; | ||
import sun.security.x509.CertificateValidity; | ||
import sun.security.x509.CertificateX509Key; | ||
import sun.security.x509.X500Name; | ||
import sun.security.x509.X509CertImpl; | ||
import sun.security.x509.X509CertInfo; | ||
Comment on lines
+50
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any way to do this without importing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Standard BC and FIPS BC have different APIs for certificate generation, and the two packages are not compatible with each other so we can't just add a new test dependency. I added a comment about the usage of the sun packages. This method passes the compatibility tests using either standard BC or FIPS BC |
||
|
||
@SuppressWarnings("deprecation") | ||
public class KeyStoreProviderTest { | ||
private static final SecureRandom RND = new SecureRandom(); | ||
private static final KeyPairGenerator KG; | ||
|
@@ -72,7 +76,7 @@ public void setup() throws Exception { | |
} | ||
|
||
@Test | ||
public void singleKeyPkcs1() throws GeneralSecurityException { | ||
public void singleKeyPkcs1() throws Exception { | ||
addEntry("key1"); | ||
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/PKCS1Padding", "key1"); | ||
final JceMasterKey mk1 = mkp.getMasterKey("key1"); | ||
|
@@ -87,7 +91,7 @@ public void singleKeyPkcs1() throws GeneralSecurityException { | |
} | ||
|
||
@Test | ||
public void singleKeyOaepSha1() throws GeneralSecurityException { | ||
public void singleKeyOaepSha1() throws Exception { | ||
addEntry("key1"); | ||
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-1AndMGF1Padding", | ||
"key1"); | ||
|
@@ -103,7 +107,7 @@ public void singleKeyOaepSha1() throws GeneralSecurityException { | |
} | ||
|
||
@Test | ||
public void singleKeyOaepSha256() throws GeneralSecurityException { | ||
public void singleKeyOaepSha256() throws Exception { | ||
addEntry("key1"); | ||
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", | ||
"key1"); | ||
|
@@ -119,7 +123,7 @@ public void singleKeyOaepSha256() throws GeneralSecurityException { | |
} | ||
|
||
@Test | ||
public void multipleKeys() throws GeneralSecurityException { | ||
public void multipleKeys() throws Exception { | ||
addEntry("key1"); | ||
addEntry("key2"); | ||
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", | ||
|
@@ -146,7 +150,7 @@ public void multipleKeys() throws GeneralSecurityException { | |
} | ||
|
||
@Test(expected = CannotUnwrapDataKeyException.class) | ||
public void encryptOnly() throws GeneralSecurityException { | ||
public void encryptOnly() throws Exception { | ||
addPublicEntry("key1"); | ||
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", | ||
"key1"); | ||
|
@@ -157,7 +161,7 @@ public void encryptOnly() throws GeneralSecurityException { | |
} | ||
|
||
@Test | ||
public void escrowAndSymmetric() throws GeneralSecurityException { | ||
public void escrowAndSymmetric() throws Exception { | ||
addPublicEntry("key1"); | ||
addEntry("key2"); | ||
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", | ||
|
@@ -185,7 +189,7 @@ public void escrowAndSymmetric() throws GeneralSecurityException { | |
} | ||
|
||
@Test | ||
public void escrowAndSymmetricSecondProvider() throws GeneralSecurityException { | ||
public void escrowAndSymmetricSecondProvider() throws GeneralSecurityException, IOException { | ||
addPublicEntry("key1"); | ||
addEntry("key2"); | ||
final KeyStoreProvider mkp = new KeyStoreProvider(ks, PP, "KeyStore", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", | ||
|
@@ -263,40 +267,34 @@ public void keystoreAndRawProvider() throws GeneralSecurityException, IOExceptio | |
assertArrayEquals(PLAINTEXT, crypto.decryptData(ksp, ct.getResult()).getResult()); | ||
} | ||
|
||
private void addEntry(final String alias) throws GeneralSecurityException { | ||
private void addEntry(final String alias) throws GeneralSecurityException, IOException { | ||
final KeyPair pair = KG.generateKeyPair(); | ||
// build a certificate generator | ||
final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); | ||
final X500Principal dnName = new X500Principal("cn=" + alias); | ||
|
||
certGen.setSerialNumber(new BigInteger(256, RND)); | ||
certGen.setSubjectDN(new X509Name("dc=" + alias)); | ||
certGen.setIssuerDN(dnName); // use the same | ||
certGen.setNotBefore(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000)); | ||
certGen.setNotAfter(new Date(System.currentTimeMillis() + 2 * 365 * 24 * 60 * 60 * 1000)); | ||
certGen.setPublicKey(pair.getPublic()); | ||
certGen.setSignatureAlgorithm("SHA256WithRSA"); | ||
final X509Certificate cert = certGen.generate(pair.getPrivate(), "BC"); | ||
|
||
ks.setEntry(alias, new KeyStore.PrivateKeyEntry(pair.getPrivate(), new X509Certificate[] { cert }), PP); | ||
ks.setEntry(alias, new KeyStore.PrivateKeyEntry(pair.getPrivate(), | ||
new X509Certificate[] { generateCertificate(pair, alias) }), PP); | ||
} | ||
|
||
private void addPublicEntry(final String alias) throws GeneralSecurityException { | ||
private void addPublicEntry(final String alias) throws GeneralSecurityException, IOException { | ||
final KeyPair pair = KG.generateKeyPair(); | ||
// build a certificate generator | ||
final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); | ||
final X500Principal dnName = new X500Principal("cn=" + alias); | ||
|
||
certGen.setSerialNumber(new BigInteger(256, RND)); | ||
certGen.setSubjectDN(new X509Name("dc=" + alias)); | ||
certGen.setIssuerDN(dnName); // use the same | ||
certGen.setNotBefore(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000)); | ||
certGen.setNotAfter(new Date(System.currentTimeMillis() + 2 * 365 * 24 * 60 * 60 * 1000)); | ||
certGen.setPublicKey(pair.getPublic()); | ||
certGen.setSignatureAlgorithm("SHA256WithRSA"); | ||
final X509Certificate cert = certGen.generate(pair.getPrivate(), "BC"); | ||
|
||
ks.setEntry(alias, new KeyStore.TrustedCertificateEntry(cert), null); | ||
ks.setEntry(alias, new KeyStore.TrustedCertificateEntry(generateCertificate(pair, alias)), null); | ||
} | ||
|
||
private X509Certificate generateCertificate(final KeyPair pair, final String alias) throws GeneralSecurityException, IOException { | ||
final X509CertInfo info = new X509CertInfo(); | ||
final X500Name name = new X500Name("dc=" + alias); | ||
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(new BigInteger(256, RND))); | ||
info.set(X509CertInfo.SUBJECT, name); | ||
info.set(X509CertInfo.ISSUER, name); | ||
info.set(X509CertInfo.VALIDITY, | ||
new CertificateValidity(Date.from(Instant.now().minus(1, ChronoUnit.DAYS)), | ||
Date.from(Instant.now().plus(730, ChronoUnit.DAYS)))); | ||
info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic())); | ||
info.set(X509CertInfo.ALGORITHM_ID, | ||
new CertificateAlgorithmId(new AlgorithmId(AlgorithmId.sha256WithRSAEncryption_oid))); | ||
|
||
final X509CertImpl cert = new X509CertImpl(info); | ||
cert.sign(pair.getPrivate(), AlgorithmId.sha256WithRSAEncryption_oid.toString()); | ||
|
||
return cert; | ||
} | ||
|
||
private void copyPublicPart(final KeyStore src, final KeyStore dst, final String alias) throws KeyStoreException { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should already have a constant defined for a zero-byte array. Return that instead. Otherwise you create needless memory pressure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't see a constant defined in Constants.java, so I just used the one in Apache Commons Lang ArrayUtils. If you prefer I can add the constant to Constants.java