diff options
author | Sergio Giro <sgiro@google.com> | 2016-02-02 15:16:50 +0000 |
---|---|---|
committer | Sergio Giro <sgiro@google.com> | 2016-02-02 15:16:50 +0000 |
commit | bdb7b3d37025690a0434040b4e0d0623d9fa74af (patch) | |
tree | 999e02ffd121091903c893bfa01244d9c8d27456 /bcprov/src/main/java/org/bouncycastle/jce | |
parent | 6d876f3f0ae553704a1dcf7e89003fcf14717037 (diff) | |
download | bouncycastle-bdb7b3d37025690a0434040b4e0d0623d9fa74af.tar.gz |
bouncycastle: Android tree with upstream code for version 1.54
Change-Id: I3958e32dd005cfb37985a6f13e2464a872290658
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/jce')
57 files changed, 1714 insertions, 526 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/ECKeyUtil.java b/bcprov/src/main/java/org/bouncycastle/jce/ECKeyUtil.java index c4c72cf4..818926a3 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/ECKeyUtil.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/ECKeyUtil.java @@ -70,7 +70,7 @@ public class ECKeyUtil { SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(key.getEncoded())); - if (info.getAlgorithmId().getObjectId().equals(CryptoProObjectIdentifiers.gostR3410_2001)) + if (info.getAlgorithmId().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001)) { throw new IllegalArgumentException("cannot convert GOST key to explicit parameters."); } @@ -160,7 +160,7 @@ public class ECKeyUtil { PrivateKeyInfo info = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(key.getEncoded())); - if (info.getAlgorithmId().getObjectId().equals(CryptoProObjectIdentifiers.gostR3410_2001)) + if (info.getAlgorithmId().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001)) { throw new UnsupportedEncodingException("cannot convert GOST key to explicit parameters."); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java b/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java index 13bed1a9..d0456ac2 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java @@ -346,7 +346,7 @@ public class PKCS10CertificationRequest try { ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(key.getEncoded()); - this.reqInfo = new CertificationRequestInfo(subject, new SubjectPublicKeyInfo(seq), attributes); + this.reqInfo = new CertificationRequestInfo(subject, SubjectPublicKeyInfo.getInstance(seq), attributes); } catch (IOException e) { @@ -397,7 +397,7 @@ public class PKCS10CertificationRequest try { - X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getBytes()); + X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getOctets()); AlgorithmIdentifier keyAlg = subjectPKInfo.getAlgorithm(); try { @@ -415,9 +415,9 @@ public class PKCS10CertificationRequest // // try an alternate // - if (keyAlgorithms.get(keyAlg.getObjectId()) != null) + if (keyAlgorithms.get(keyAlg.getAlgorithm()) != null) { - String keyAlgorithm = (String)keyAlgorithms.get(keyAlg.getObjectId()); + String keyAlgorithm = (String)keyAlgorithms.get(keyAlg.getAlgorithm()); if (provider == null) { @@ -490,9 +490,9 @@ public class PKCS10CertificationRequest // // try an alternate // - if (oids.get(sigAlgId.getObjectId()) != null) + if (oids.get(sigAlgId.getAlgorithm()) != null) { - String signatureAlgorithm = (String)oids.get(sigAlgId.getObjectId()); + String signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm()); if (provider == null) { @@ -522,7 +522,7 @@ public class PKCS10CertificationRequest throw new SignatureException("exception encoding TBS cert request - " + e); } - return sig.verify(sigBits.getBytes()); + return sig.verify(sigBits.getOctets()); } /** @@ -579,14 +579,14 @@ public class PKCS10CertificationRequest if (params != null && !DERNull.INSTANCE.equals(params)) { - if (sigAlgId.getObjectId().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) + if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); - return getDigestAlgName(rsaParams.getHashAlgorithm().getObjectId()) + "withRSAandMGF1"; + return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1"; } } - return sigAlgId.getObjectId().getId(); + return sigAlgId.getAlgorithm().getId(); } private static String getDigestAlgName( diff --git a/bcprov/src/main/java/org/bouncycastle/jce/PKCS12Util.java b/bcprov/src/main/java/org/bouncycastle/jce/PKCS12Util.java index c7059b26..b791d553 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/PKCS12Util.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/PKCS12Util.java @@ -82,9 +82,9 @@ public class PKCS12Util { int itCount = mData.getIterationCount().intValue(); byte[] data = ASN1OctetString.getInstance(info.getContent()).getOctets(); - byte[] res = calculatePbeMac(mData.getMac().getAlgorithmId().getObjectId(), mData.getSalt(), itCount, passwd, data, provider); + byte[] res = calculatePbeMac(mData.getMac().getAlgorithmId().getAlgorithm(), mData.getSalt(), itCount, passwd, data, provider); - AlgorithmIdentifier algId = new AlgorithmIdentifier(mData.getMac().getAlgorithmId().getObjectId(), DERNull.INSTANCE); + AlgorithmIdentifier algId = new AlgorithmIdentifier(mData.getMac().getAlgorithmId().getAlgorithm(), DERNull.INSTANCE); DigestInfo dInfo = new DigestInfo(algId, res); mData = new MacData(dInfo, mData.getSalt(), itCount); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalKey.java b/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalKey.java index e6394836..fa3d4376 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalKey.java @@ -1,8 +1,11 @@ package org.bouncycastle.jce.interfaces; +import javax.crypto.interfaces.DHKey; + import org.bouncycastle.jce.spec.ElGamalParameterSpec; public interface ElGamalKey + extends DHKey { public ElGamalParameterSpec getParameters(); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPrivateKey.java index 609a2a84..b37dc38e 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPrivateKey.java @@ -1,10 +1,11 @@ package org.bouncycastle.jce.interfaces; import java.math.BigInteger; -import java.security.PrivateKey; + +import javax.crypto.interfaces.DHPrivateKey; public interface ElGamalPrivateKey - extends ElGamalKey, PrivateKey + extends ElGamalKey, DHPrivateKey { public BigInteger getX(); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPublicKey.java index c9fe35e6..1f759870 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/interfaces/ElGamalPublicKey.java @@ -1,10 +1,11 @@ package org.bouncycastle.jce.interfaces; import java.math.BigInteger; -import java.security.PublicKey; + +import javax.crypto.interfaces.DHPublicKey; public interface ElGamalPublicKey - extends ElGamalKey, PublicKey + extends ElGamalKey, DHPublicKey { public BigInteger getY(); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java b/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java index 39dd35ad..f8a1a6fd 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java @@ -86,9 +86,8 @@ public class NetscapeCertRequest + spkac.size()); } - sigAlg = new AlgorithmIdentifier((ASN1Sequence)spkac - .getObjectAt(1)); - sigBits = ((DERBitString)spkac.getObjectAt(2)).getBytes(); + sigAlg = AlgorithmIdentifier.getInstance(spkac.getObjectAt(1)); + sigBits = ((DERBitString)spkac.getObjectAt(2)).getOctets(); // // PublicKeyAndChallenge ::= SEQUENCE { @@ -110,14 +109,13 @@ public class NetscapeCertRequest //could potentially alter the bytes content = new DERBitString(pkac); - SubjectPublicKeyInfo pubkeyinfo = new SubjectPublicKeyInfo( - (ASN1Sequence)pkac.getObjectAt(0)); + SubjectPublicKeyInfo pubkeyinfo = SubjectPublicKeyInfo.getInstance(pkac.getObjectAt(0)); X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString( pubkeyinfo).getBytes()); - keyAlg = pubkeyinfo.getAlgorithmId(); - pubkey = KeyFactory.getInstance(keyAlg.getObjectId().getId(), "BC") + keyAlg = pubkeyinfo.getAlgorithm(); + pubkey = KeyFactory.getInstance(keyAlg.getAlgorithm().getId(), "BC") .generatePublic(xspec); } @@ -205,7 +203,7 @@ public class NetscapeCertRequest // Verify the signature .. shows the response was generated // by someone who knew the associated private key // - Signature sig = Signature.getInstance(sigAlg.getObjectId().getId(), + Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId(), "BC"); sig.initVerify(pubkey); sig.update(content.getBytes()); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java index a02ca15a..8af487d1 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java @@ -44,7 +44,7 @@ import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; public final class BouncyCastleProvider extends Provider implements ConfigurableProvider { - private static String info = "BouncyCastle Security Provider v1.52"; + private static String info = "BouncyCastle Security Provider v1.54"; public static final String PROVIDER_NAME = "BC"; @@ -71,8 +71,8 @@ public final class BouncyCastleProvider extends Provider { "AES", "ARC4", "Blowfish", "Camellia", "CAST5", "CAST6", "ChaCha", "DES", "DESede", "GOST28147", "Grainv1", "Grain128", "HC128", "HC256", "IDEA", "Noekeon", "RC2", "RC5", - "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Shacal2", "Skipjack", "TEA", "Twofish", "Threefish", - "VMPC", "VMPCKSA3", "XTEA", "XSalsa20" + "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Shacal2", "Skipjack", "SM4", "TEA", "Twofish", "Threefish", + "VMPC", "VMPCKSA3", "XTEA", "XSalsa20", "OpenSSLPBKDF" }; /* @@ -98,7 +98,8 @@ public final class BouncyCastleProvider extends Provider private static final String DIGEST_PACKAGE = "org.bouncycastle.jcajce.provider.digest."; private static final String[] DIGESTS = { - "GOST3411", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "Skein", "SM3", "Tiger", "Whirlpool" + "GOST3411", "Keccak", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", + "SHA256", "SHA384", "SHA512", "SHA3", "Skein", "SM3", "Tiger", "Whirlpool", "Blake2b" }; /* @@ -117,7 +118,7 @@ public final class BouncyCastleProvider extends Provider */ public BouncyCastleProvider() { - super(PROVIDER_NAME, 1.52, info); + super(PROVIDER_NAME, 1.54, info); AccessController.doPrivileged(new PrivilegedAction() { @@ -250,6 +251,12 @@ public final class BouncyCastleProvider extends Provider put(key, value); } + public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className) + { + addAlgorithm(type + "." + oid, className); + addAlgorithm(type + ".OID." + oid, className); + } + public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter) { keyInfoConverters.put(oid, keyInfoConverter); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java index 1807aa87..7b89cd7a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java @@ -36,6 +36,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.security.auth.x500.X500Principal; + import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1GeneralizedTime; @@ -715,7 +717,7 @@ class CertPathValidatorUtilities for (int j = 0; j < genNames.length; j++) { - PKIXCRLStore store = namedCRLStoreMap.get(genNames[i]); + PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]); if (store != null) { stores.add(store); @@ -889,12 +891,17 @@ class CertPathValidatorUtilities return; } - X500Name certIssuer = X500Name.getInstance(crl_entry.getCertificateIssuer().getEncoded()); + X500Principal certificateIssuer = crl_entry.getCertificateIssuer(); - if (certIssuer == null) + X500Name certIssuer; + if (certificateIssuer == null) { certIssuer = PrincipalUtils.getIssuerPrincipal(crl); } + else + { + certIssuer = X500Name.getInstance(certificateIssuer.getEncoded()); + } if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(certIssuer)) { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java index 67e40b40..eb6a95d0 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java @@ -37,6 +37,7 @@ import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.util.Strings; public class JCEECPrivateKey implements ECPrivateKey, org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder @@ -426,7 +427,7 @@ public class JCEECPrivateKey public String toString() { StringBuffer buf = new StringBuffer(); - String nl = System.getProperty("line.separator"); + String nl = Strings.lineSeparator(); buf.append("EC Private Key").append(nl); buf.append(" S: ").append(this.d.toString(16)).append(nl); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java index c82be8ca..6c67431f 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java @@ -40,6 +40,7 @@ import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.custom.sec.SecP256K1Point; import org.bouncycastle.math.ec.custom.sec.SecP256R1Point; +import org.bouncycastle.util.Strings; public class JCEECPublicKey implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder @@ -181,7 +182,7 @@ public class JCEECPublicKey private void populateFromPubKeyInfo(SubjectPublicKeyInfo info) { - if (info.getAlgorithmId().getObjectId().equals(CryptoProObjectIdentifiers.gostR3410_2001)) + if (info.getAlgorithmId().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001)) { DERBitString bits = info.getPublicKeyData(); ASN1OctetString key; @@ -465,7 +466,7 @@ public class JCEECPublicKey public String toString() { StringBuffer buf = new StringBuffer(); - String nl = System.getProperty("line.separator"); + String nl = Strings.lineSeparator(); buf.append("EC Public Key").append(nl); buf.append(" X: ").append(this.q.getAffineXCoord().toBigInteger().toString(16)).append(nl); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java index f9bb5dd3..40f007f3 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java @@ -12,6 +12,7 @@ import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; +import org.bouncycastle.util.Strings; /** * A provider representation for a RSA private key, with CRT factors included. @@ -224,7 +225,7 @@ public class JCERSAPrivateCrtKey public String toString() { StringBuffer buf = new StringBuffer(); - String nl = System.getProperty("line.separator"); + String nl = Strings.lineSeparator(); buf.append("RSA Private CRT Key").append(nl); buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java index a09295d5..adf0e3e8 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java @@ -5,14 +5,13 @@ import java.math.BigInteger; import java.security.interfaces.RSAPublicKey; import java.security.spec.RSAPublicKeySpec; -import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x509.RSAPublicKeyStructure; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; +import org.bouncycastle.util.Strings; public class JCERSAPublicKey implements RSAPublicKey @@ -48,7 +47,7 @@ public class JCERSAPublicKey { try { - RSAPublicKeyStructure pubKey = new RSAPublicKeyStructure((ASN1Sequence)info.parsePublicKey()); + org.bouncycastle.asn1.pkcs.RSAPublicKey pubKey = org.bouncycastle.asn1.pkcs.RSAPublicKey.getInstance(info.parsePublicKey()); this.modulus = pubKey.getModulus(); this.publicExponent = pubKey.getPublicExponent(); @@ -91,7 +90,7 @@ public class JCERSAPublicKey public byte[] getEncoded() { - return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKeyStructure(getModulus(), getPublicExponent())); + return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new org.bouncycastle.asn1.pkcs.RSAPublicKey(getModulus(), getPublicExponent())); } public int hashCode() @@ -120,7 +119,7 @@ public class JCERSAPublicKey public String toString() { StringBuffer buf = new StringBuffer(); - String nl = System.getProperty("line.separator"); + String nl = Strings.lineSeparator(); buf.append("RSA Public Key").append(nl); buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java index 80bbf3c5..95a1ad74 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java @@ -18,6 +18,7 @@ import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; +import org.bouncycastle.util.Strings; public class JDKDSAPublicKey implements DSAPublicKey @@ -126,7 +127,7 @@ public class JDKDSAPublicKey public String toString() { StringBuffer buf = new StringBuffer(); - String nl = System.getProperty("line.separator"); + String nl = Strings.lineSeparator(); buf.append("DSA Public Key").append(nl); buf.append(" y: ").append(this.getY().toString(16)).append(nl); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java index b7133951..dfe9cef5 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java @@ -44,16 +44,6 @@ public class PKIXCertPathBuilderSpi public CertPathBuilderResult engineBuild(CertPathParameters params) throws CertPathBuilderException, InvalidAlgorithmParameterException { - if (!(params instanceof PKIXBuilderParameters) - && !(params instanceof ExtendedPKIXBuilderParameters) - && !(params instanceof PKIXExtendedBuilderParameters)) - { - throw new InvalidAlgorithmParameterException( - "Parameters must be an instance of " - + PKIXBuilderParameters.class.getName() + " or " - + PKIXExtendedBuilderParameters.class.getName() + "."); - } - PKIXExtendedBuilderParameters paramsPKIX; if (params instanceof PKIXBuilderParameters) { @@ -81,10 +71,17 @@ public class PKIXCertPathBuilderSpi paramsPKIX = paramsBldrPKIXBldr.build(); } - else + else if (params instanceof PKIXExtendedBuilderParameters) { paramsPKIX = (PKIXExtendedBuilderParameters)params; } + else + { + throw new InvalidAlgorithmParameterException( + "Parameters must be an instance of " + + PKIXBuilderParameters.class.getName() + " or " + + PKIXExtendedBuilderParameters.class.getName() + "."); + } Collection targets; Iterator targetIter; diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java index f87b427d..991aa4b2 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java @@ -22,6 +22,7 @@ import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters; import org.bouncycastle.jcajce.PKIXExtendedParameters; import org.bouncycastle.jcajce.util.BCJcaJceHelper; @@ -48,12 +49,6 @@ public class PKIXCertPathValidatorSpi throws CertPathValidatorException, InvalidAlgorithmParameterException { - if (!(params instanceof CertPathParameters)) - { - throw new InvalidAlgorithmParameterException("Parameters must be a " + PKIXParameters.class.getName() - + " instance."); - } - PKIXExtendedParameters paramsPKIX; if (params instanceof PKIXParameters) { @@ -73,10 +68,14 @@ public class PKIXCertPathValidatorSpi { paramsPKIX = ((PKIXExtendedBuilderParameters)params).getBaseParameters(); } - else + else if (params instanceof PKIXExtendedParameters) { paramsPKIX = (PKIXExtendedParameters)params; } + else + { + throw new InvalidAlgorithmParameterException("Parameters must be a " + PKIXParameters.class.getName() + " instance."); + } if (paramsPKIX.getTrustAnchors() == null) { @@ -96,7 +95,7 @@ public class PKIXCertPathValidatorSpi if (certs.isEmpty()) { - throw new CertPathValidatorException("Certification path is empty.", null, certPath, 0); + throw new CertPathValidatorException("Certification path is empty.", null, certPath, -1); } // @@ -435,6 +434,7 @@ public class PKIXCertPathValidatorSpi criticalExtensions.remove(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME); criticalExtensions.remove(RFC3280CertPathUtilities.NAME_CONSTRAINTS); criticalExtensions.remove(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS); + criticalExtensions.remove(Extension.extendedKeyUsage.getId()); } else { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java index 7e76a897..d5e23382 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java @@ -24,6 +24,7 @@ import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.X509Extension; +import org.bouncycastle.util.Strings; /** * The following extensions are listed in RFC 2459 as relevant to CRL Entries @@ -259,7 +260,7 @@ public class X509CRLEntryObject extends X509CRLEntry public String toString() { StringBuffer buf = new StringBuffer(); - String nl = System.getProperty("line.separator"); + String nl = Strings.lineSeparator(); buf.append(" userCertificate: ").append(this.getSerialNumber()).append(nl); buf.append(" revocationDate: ").append(this.getRevocationDate()).append(nl); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java index c9ee77c8..b6885ace 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java @@ -6,6 +6,7 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; +import java.security.Provider; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; @@ -41,6 +42,7 @@ import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.jce.X509Principal; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; /** @@ -201,21 +203,45 @@ public class X509CRLObject } public void verify(PublicKey key) - throws CRLException, NoSuchAlgorithmException, - InvalidKeyException, NoSuchProviderException, SignatureException + throws CRLException, NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException, SignatureException { - verify(key, BouncyCastleProvider.PROVIDER_NAME); + Signature sig; + + try + { + sig = Signature.getInstance(getSigAlgName(), BouncyCastleProvider.PROVIDER_NAME); + } + catch (Exception e) + { + sig = Signature.getInstance(getSigAlgName()); + } + + doVerify(key, sig); } public void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, - InvalidKeyException, NoSuchProviderException, SignatureException + InvalidKeyException, NoSuchProviderException, SignatureException { - if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature())) + Signature sig; + + if (sigProvider != null) { - throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList."); + sig = Signature.getInstance(getSigAlgName(), sigProvider); + } + else + { + sig = Signature.getInstance(getSigAlgName()); } + doVerify(key, sig); + } + + public void verify(PublicKey key, Provider sigProvider) + throws CRLException, NoSuchAlgorithmException, + InvalidKeyException, SignatureException + { Signature sig; if (sigProvider != null) @@ -227,6 +253,18 @@ public class X509CRLObject sig = Signature.getInstance(getSigAlgName()); } + doVerify(key, sig); + } + + private void doVerify(PublicKey key, Signature sig) + throws CRLException, NoSuchAlgorithmException, + InvalidKeyException, SignatureException + { + if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature())) + { + throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList."); + } + sig.initVerify(key); sig.update(this.getTBSCertList()); @@ -353,7 +391,7 @@ public class X509CRLObject public byte[] getSignature() { - return c.getSignature().getBytes(); + return c.getSignature().getOctets(); } public String getSigAlgName() @@ -388,7 +426,7 @@ public class X509CRLObject public String toString() { StringBuffer buf = new StringBuffer(); - String nl = System.getProperty("line.separator"); + String nl = Strings.lineSeparator(); buf.append(" Version: ").append(this.getVersion()).append( nl); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java index 97ff6f98..bd4d6930 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java @@ -32,6 +32,7 @@ import java.util.Set; import javax.security.auth.x500.X500Principal; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; @@ -62,6 +63,7 @@ import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; public class X509CertificateObject @@ -101,7 +103,7 @@ public class X509CertificateObject byte[] bytes = this.getExtensionBytes("2.5.29.15"); if (bytes != null) { - DERBitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes)); + ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes)); bytes = bits.getBytes(); int length = (bytes.length * 8) - bits.getPadBits(); @@ -231,7 +233,7 @@ public class X509CertificateObject public byte[] getSignature() { - return c.getSignature().getBytes(); + return c.getSignature().getOctets(); } /** @@ -653,7 +655,7 @@ public class X509CertificateObject public String toString() { StringBuffer buf = new StringBuffer(); - String nl = System.getProperty("line.separator"); + String nl = Strings.lineSeparator(); buf.append(" [0] Version: ").append(this.getVersion()).append(nl); buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl); @@ -772,12 +774,42 @@ public class X509CertificateObject throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { - String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); - Signature signature = Signature.getInstance(sigName, sigProvider); + String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); + Signature signature; + + if (sigProvider != null) + { + signature = Signature.getInstance(sigName, sigProvider); + } + else + { + signature = Signature.getInstance(sigName); + } checkSignature(key, signature); } + public final void verify( + PublicKey key, + Provider sigProvider) + throws CertificateException, NoSuchAlgorithmException, + InvalidKeyException, SignatureException + { + String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); + Signature signature; + + if (sigProvider != null) + { + signature = Signature.getInstance(sigName, sigProvider); + } + else + { + signature = Signature.getInstance(sigName); + } + + checkSignature(key, signature); + } + private void checkSignature( PublicKey key, Signature signature) diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AEADTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AEADTest.java index 7d89515a..92c07e52 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AEADTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AEADTest.java @@ -180,7 +180,7 @@ public class AEADTest extends SimpleTest GCMParameters gcmParameters = GCMParameters.getInstance(encParams); - if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce()) || spec.getTLen() != gcmParameters.getIcvLen()) + if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce()) || spec.getTLen() != gcmParameters.getIcvLen() * 8) { fail("parameters mismatch"); } @@ -280,7 +280,7 @@ public class AEADTest extends SimpleTest GCMParameters gcmParameters = GCMParameters.getInstance(encParams); - if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce()) || spec.getTLen() != gcmParameters.getIcvLen()) + if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce()) || spec.getTLen() != gcmParameters.getIcvLen() * 8) { fail("parameters mismatch"); } @@ -328,7 +328,7 @@ public class AEADTest extends SimpleTest GCMParameters gcmParameters = GCMParameters.getInstance(encParams); - if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce()) || spec.getTLen() != gcmParameters.getIcvLen()) + if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce()) || spec.getTLen() != gcmParameters.getIcvLen() * 8) { fail("parameters mismatch"); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AESTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AESTest.java index 72a8a347..ce0ac4cb 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AESTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AESTest.java @@ -356,9 +356,8 @@ public class AESTest byte[] kek2 = Hex.decode("000102030405060708090a0b0c0d0e0f"); byte[] in2 = Hex.decode("00112233445566778899aabbccddeeff"); byte[] out2 = Hex.decode("7c8798dfc802553b3f00bb4315e3a087322725c92398b9c112c74d0925c63b61"); - String rndData = "68d38e9635962288d4daa1df203e3e2a15adb2f1da8998b72ac24ab1c78cceac"; - wrapTest(2, "AESRFC3211WRAP", kek2, kek2, new FixedSecureRandom(Hex.decode(rndData + rndData)), in2, out2); + wrapTest(2, "AESRFC3211WRAP", kek2, kek2, new FixedSecureRandom(Hex.decode("9688df2af1b7b1ac9688df2a")), in2, out2); byte[] kek3 = Hex.decode("5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8"); byte[] in3 = Hex.decode("c37b7e6492584340bed12207808941155068f738"); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AlgorithmParametersTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AlgorithmParametersTest.java index 72f38854..02b7b927 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AlgorithmParametersTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AlgorithmParametersTest.java @@ -1,16 +1,22 @@ package org.bouncycastle.jce.provider.test; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.util.encoders.Base64; -import org.bouncycastle.util.test.SimpleTest; - import java.io.IOException; import java.security.AlgorithmParameters; import java.security.Security; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAParameterSpec; +import java.security.spec.ECGenParameterSpec; import java.security.spec.InvalidParameterSpecException; +import javax.crypto.spec.IvParameterSpec; + +import org.bouncycastle.asn1.sec.SECObjectIdentifiers; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; + public class AlgorithmParametersTest extends SimpleTest { @@ -48,9 +54,12 @@ public class AlgorithmParametersTest // expected already initialized } + // check default + spec = alg.getParameterSpec(AlgorithmParameterSpec.class); + try { - spec = alg.getParameterSpec(AlgorithmParameterSpec.class); + spec = alg.getParameterSpec(IvParameterSpec.class); fail("wrong spec not detected"); } catch (InvalidParameterSpecException e) @@ -93,6 +102,15 @@ public class AlgorithmParametersTest throws Exception { basicTest("DSA", DSAParameterSpec.class, dsaParams); + + AlgorithmParameters al = AlgorithmParameters.getInstance("EC", "BC"); + + al.init(new ECGenParameterSpec(SECObjectIdentifiers.secp224k1.getId())); + + if (!Arrays.areEqual(Hex.decode("06052b81040020"), al.getEncoded())) + { + fail("EC param test failed"); + } } public String getName() diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AllTests.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AllTests.java index 34767457..15e9fbd5 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AllTests.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AllTests.java @@ -2,35 +2,16 @@ package org.bouncycastle.jce.provider.test; import java.security.Security; +import junit.extensions.TestSetup; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.jce.provider.test.rsa3.RSA3CertTest; import org.bouncycastle.util.test.SimpleTestResult; public class AllTests extends TestCase { - public void testJCE() - { - org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; - - for (int i = 0; i != tests.length; i++) - { - SimpleTestResult result = (SimpleTestResult)tests[i].perform(); - - if (!result.isSuccessful()) - { - if (result.getException() != null) - { - result.getException().printStackTrace(); - } - fail(result.toString()); - } - } - } - public static void main (String[] args) { junit.textui.TestRunner.run(suite()); @@ -39,15 +20,52 @@ public class AllTests public static Test suite() { TestSuite suite = new TestSuite("JCE Tests"); + + suite.addTestSuite(SimpleTestTest.class); - if (Security.getProvider("BC") == null) + return new BCTestSetup(suite); + } + + public static class SimpleTestTest + extends TestCase + { + public void testJCE() { - Security.addProvider(new BouncyCastleProvider()); + org.bouncycastle.util.test.Test[] tests = RegressionTest.tests; + + for (int i = 0; i != tests.length; i++) + { + SimpleTestResult result = (SimpleTestResult)tests[i].perform(); + + if (!result.isSuccessful()) + { + if (result.getException() != null) + { + result.getException().printStackTrace(); + } + fail(result.toString()); + } + } + } + } + + static class BCTestSetup + extends TestSetup + { + public BCTestSetup(Test test) + { + super(test); + } + + protected void setUp() + { + Security.addProvider(new BouncyCastleProvider()); + } + + protected void tearDown() + { + Security.removeProvider("BC"); } - - suite.addTestSuite(RSA3CertTest.class); - suite.addTestSuite(AllTests.class); - - return suite; } + } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/BlockCipherTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/BlockCipherTest.java index 0c9cf01b..ea1e2fa0 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/BlockCipherTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/BlockCipherTest.java @@ -15,6 +15,8 @@ import java.security.SecureRandom; import java.security.Security; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; +import java.util.HashSet; +import java.util.Set; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; @@ -31,8 +33,10 @@ import javax.crypto.spec.RC5ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; +import org.bouncycastle.util.test.TestFailedException; /** * basic test class for a block cipher, basically this just exercises the provider, and makes sure we @@ -41,6 +45,18 @@ import org.bouncycastle.util.test.SimpleTest; public class BlockCipherTest extends SimpleTest { + private static Set<String> shortIvOkay = new HashSet<String>(); + + static + { + shortIvOkay.add("EAX"); + shortIvOkay.add("OCB"); + shortIvOkay.add("CCM"); + shortIvOkay.add("GCM"); + shortIvOkay.add("SIC"); + shortIvOkay.add("CTR"); + } + static String[] cipherTests1 = { "DES", @@ -51,6 +67,8 @@ public class BlockCipherTest "d4de46d52274dbb029f33b076043f8c40089f906751623de29f33b076043f8c4ac99b90f9396cb04", "Blowfish", "7870ebe7f6a52803eb9396ba6c5198216ce81d76d8d4c74beb9396ba6c5198211212473b05214e9f", + "GOST28147", + "0a77f4114451b37d44c5192619b723dd49093d1047c2373544c5192619b723dd06618da5b04d3670", "Twofish", "70336d9c9718a8a2ced1b19deed973a3c58af7ea71a69e7efc4df082dca581c0839e31468661bcfc57a14899ceeb0253", "RC2", @@ -128,6 +146,8 @@ public class BlockCipherTest "Rijndael/CBC/PKCS7Padding", "cf87f4d8bb9d1abb36cdd9f44ead7d046db2f802d99e1ef0a5940f306079e08389a44c4a8cc1a47cbaee1128da55bbb7", "Serpent/CBC/PKCS7Padding", + "d8b971931de211cb2d31721773a5b1f9dc4e263efe0465f97c024daa26dd7d03473e9beb82ba809cf36071d4807e4706", + "Tnepres/CBC/PKCS7Padding", "f8940ca31aba8ce1e0693b1ae0b1e08daef6de03c80f019774280052f824ac44540bb8dd74dfad47f83f9c7ec268ca68", "CAST5/CBC/PKCS7Padding", "87b6dc0c5a1d23d42fa740b0548be0b298112000544610d889d6361994cf8e670a19d6af72d7289f", @@ -154,6 +174,8 @@ public class BlockCipherTest "Rijndael/CTS/NoPadding", "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04", "Serpent/CTS/NoPadding", + "dc4e263efe0465f97c024daa26dd7d03d8b971931de211cb2d31721773a5b1f9", + "Tnepres/CTS/NoPadding", "aef6de03c80f019774280052f824ac44f8940ca31aba8ce1e0693b1ae0b1e08d", "CAST5/CTS/NoPadding", "87b6dc0c5a1d23d42fa740b0548be0b289d6361994cf8e6798112000544610d8", @@ -182,6 +204,8 @@ public class BlockCipherTest "Rijndael/CBC/WithCTS", "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04", "Serpent/CBC/WithCTS", + "dc4e263efe0465f97c024daa26dd7d03d8b971931de211cb2d31721773a5b1f9", + "Tnepres/CBC/WithCTS", "aef6de03c80f019774280052f824ac44f8940ca31aba8ce1e0693b1ae0b1e08d", "CAST5/CBC/WithCTS", "87b6dc0c5a1d23d42fa740b0548be0b289d6361994cf8e6798112000544610d8", @@ -195,6 +219,12 @@ public class BlockCipherTest "d4a96bf4e44f89fd91b46830bc95b130c44695633c07010f3a0d8f7ea046a642", "IDEA/CBC/WithCTS", "30cd990ebdae80fe12b6c6e4fcd1c06497351c8684e4c4d9a27d985c276b3d70", + "Blowfish/CTR/NoPadding", + "6cd6f7c5d2c65555d2b31f8614f54ec654f5e7888d515008d59302c3edfcc6cb", + "CAST5/CTR/NoPadding", + "9ef6c08987f02d3dc218513450cf0f8d6aa9eb15d0ad92dde14863731a7e39c2", + "Camellia/CTR/NoPadding", + "9132cee4b4f13574ed61c00997f8049e8b45f941f6394e333926a3245f11d759", "DES/OFB/NoPadding", "537572e480c1714f5c9a4f3b874df824dc6681b1fd6c11982debcad91e3f78b7", "DESede/OFB/NoPadding", @@ -313,6 +343,88 @@ public class BlockCipherTest "c62b233df296283b97f17364d5f69a1ff91f46659cf9856caefd322a936203a7", "IDEA/CTR/NoPadding", "dd447da3cbdcf81f4694ab7715d79e3f90af5682e8c318b8f7dadbed6b5c9714", + "Blowfish/EAX/NoPadding", + "bee85ae6512b8a2346d46f7bac31526238091ccc5de75760c9a39628fb45d44a653bfac0", + "CAST5/EAX/NoPadding", + "85e0dbd3402f2179f96d231315ec73f04f64f1b7ab1347423b9aec51a07a7222e2bc65a3", + "DES/EAX/NoPadding", + "07d12249945e77607086f7463f316966466e6a0c0789b3307b8b51a7cc807e3c1fb91f98", + "DESede/EAX/NoPadding", + "278b28f13537dc13bb688c95391754bd6d39c79a7361b407f8dee0b111b264f20391cb0e", + "GOST28147/EAX/NoPadding", + "1416713d52affb595b880be996e838edd377e67dfe822fbb0ff235f1b706e6ce34d68dc5", + "IDEA/EAX/NoPadding", + "b2e9f3e40954c140ac60423466dee0138f84e879fbde003780202bd83c91571b64df7bb7", + "RC2/EAX/NoPadding", + "5d1c095de75bd5eef6a5146f7d6c44545807a8b452f7a38e2719a14f1a269709d2eda2d3", + "SEED/EAX/NoPadding", + "6780f18b2dd1f75a934b5a3e45e8fd44877fd3498a9b919b417b3d8a7c67c6021d74bbaef71841ef", + "Serpent/EAX/NoPadding", + "13c2b1fec2bda74f5ccc8ca31b36a2e91ee024a215387219808640b2fc7a6a41e017aacee3ed893a", + "Tnepres/EAX/NoPadding", + "8d5ac312ca0d436a0154d56568d39811ccf6bb970012398014fc8a49ed669b117443c0249b07ead8", + "SM4/EAX/NoPadding", + "e072a95da8e529b41199859482142b3fdfa6b7af27348e5ebf35445a099583dae882affde90ea4a4", + "Twofish/EAX/NoPadding", + "9a90dffe1233a04733fc8869e8ec4cba2fa53d9543f0206825293b1ff102e63f81a60b12204e1fd8", + "IDEA/OFB/NoPadding", + "dd447da3cbdcf81f4053fb446596261cb00a3c49a66085485af5f7c10ba20dad", + "RC2/OFB/NoPadding", + "0a07cb78537cb04c0c74e28a7b86b80f80acadf87d6ef32792f1a8cf74b39f74", + "SEED/OFB/NoPadding", + "9fd249435dc66d3d5d41abad270df5e3c6b972692fadfcb6c311b047f96fb114", + "SEED/OCB/NoPadding", + "eb04b3612769e1ad681f975af1a6f401d94dc88276dd50fc3ebce791c28825c652b7351acbad8c63d4d66191de94c970", + "SEED/CCM/NoPadding", + "8bb16b37e7f1d4eb97bb1fa3b9bfd411aca64a3581bb3c5b2a91346983aa334984d73ad629a847f7", + "SEED/GCM/NoPadding", + "ed5f6293c9a4f280af6695750bfb3bb3b60c214565a049494df955152757812ebfb93705895606c4378498a93f2541b5", + "SM4/GCM/NoPadding", + "323b601a951da693f87e53c6832380719b4d4bd306c94248202b7e337c81e2d9de0044b77a4c556f15f6fd19f828236b", + "DES/ECB/TBCPadding", + "466da00648ef0e1f9617b1f002e225251a3248d09172f46b9617b1f002e22525698575eb3998481b", + "GOST28147/ECB/TBCPadding", + "0a77f4114451b37d44c5192619b723dd49093d1047c2373544c5192619b723dde7b0810d205c07ab", + "IDEA/ECB/TBCPadding", + "8c9fd56823ffdc523f6ccf7f614aa6173553e594fc7a21b53f6ccf7f614aa61747a7c95a57b9eaf4", + "RC2/ECB/TBCPadding", + "eb5b889bbcced12eb6b1a3da6a3d965bba66a5edfdd4c8a6b6b1a3da6a3d965b6b5359ba5e69b179", + "SEED/ECB/TBCPadding", + "d53d4ce1f48b9879420949467bfcbfbe2c6a7d4a8770bee0c71211def898d7c509f6e111845db39b4cce1dd155aa592b", + "DES/CBC/TBCPadding", + "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122ad3b3f002c927f1fd", + "GOST28147/CBC/TBCPadding", + "ba87be9c465cbb30e1bf0148daa9639c2e4cbc1b6777cfcda860760686596159aa564fd65e66c125", + "IDEA/CBC/TBCPadding", + "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d922f14e12faecaa0b", + "RC2/CBC/TBCPadding", + "a51facdb3933c9676795cd38cc3146fd4694722b468b1a979a399c77606abf9997b47d2f64a37e2f", + "SEED/CBC/TBCPadding", + "fc34f03ddf4d2a4d9934addc82011af1d5f76ee015b691a6524d7ad5464422d7989825d19e23a60ba759407e13d1ea02", + "DES/CFB8/NoPadding", + "53cb0cdff712a825eb283b23c31e7323aa12495e7e751428b5c4eb89b28a25d4", + "GOST28147/CFB8/NoPadding", + "29f6ca1ca7ae9670413183932a28cdd4a09f2ba630c3c3fbf6f071d3774d7577", + "IDEA/CFB8/NoPadding", + "dd7839d2525420d10f95eec23dbaf3463302c445972a28c563c2635191bc19af", + "RC2/CFB8/NoPadding", + "0aa227f94be3a32ff927c5d25647ea41d7c2a1e94012fc7f2ad6767b9664bce5", + "SEED/CFB8/NoPadding", + "9f1622c3785a034ee4c595df05fb11e69e4d52036e238d2d451e190e87ee876e", + "DES/CTS/NoPadding", + "60fa2f8fae5aa2a38e9ac77d0246726bcf99f75cc6e0122aeb7511e4515feb12", + "GOST28147/CTS/NoPadding", + "ba87be9c465cbb30e1bf0148daa9639ca8607606865961592e4cbc1b6777cfcd", + "IDEA/CTS/NoPadding", + "30cd990ebdae80fe12b6c6e4fcd1c06497351c8684e4c4d9a27d985c276b3d70", + "RC2/CTS/NoPadding", + "a51facdb3933c9676795cd38cc3146fd9a399c77606abf994694722b468b1a97", + "SEED/CTS/NoPadding", + "d5f76ee015b691a6524d7ad5464422d7fc34f03ddf4d2a4d9934addc82011af1", + "SHACAL-2/CBC/PKCS7Padding", + "3af7c54ea55d2497162ac9c79d9b2f7837898f83aa4b50b7b762979aa8087669b6a81cdec475ed4d2394d7ad771404a52eb52d245a39f0d7d3e8062d3b0f0e54", + "SHACAL-2/CBC/TBCPadding", + "3af7c54ea55d2497162ac9c79d9b2f7837898f83aa4b50b7b762979aa80876693f17fbe9a5baa88ed21b2e1a863dc449061f40cafadfc3cf73486208f87b9352", }; static String[] cipherTests2 = @@ -329,6 +441,30 @@ public class BlockCipherTest static String[] cipherTestsLargeBlock = { + "SHACAL-2/CBC/withCTS", + "3af7c54ea55d2497162ac9c79d9b2f7837898f83aa4b50b7b762979aa8087669c7228283218babbc53af6eb9edefe37ddd827ded8dd6d99557e9f10075b53e18fff454cccdc913a1817dcad39fca72820e014892ff16432233e9a0a19aa499b456478bbaaa6c1a4adcda6564906a71fd49669fffec5806dd86c451052d70f276", + "SHACAL-2/CBC/PKCS7Padding", + "3af7c54ea55d2497162ac9c79d9b2f7837898f83aa4b50b7b762979aa8087669c7228283218babbc53af6eb9edefe37ddd827ded8dd6d99557e9f10075b53e1856478bbaaa6c1a4adcda6564906a71fd49669fffec5806dd86c451052d70f276fff454cccdc913a1817dcad39fca72820e014892ff16432233e9a0a19aa499b4dda7154ca3f53f3c8ff443f31b7821aa05cdcf584add4dbfb436abb2cffec14d", + "SHACAL-2/CBC/ISO10126-2Padding", + "3af7c54ea55d2497162ac9c79d9b2f7837898f83aa4b50b7b762979aa8087669c7228283218babbc53af6eb9edefe37ddd827ded8dd6d99557e9f10075b53e1856478bbaaa6c1a4adcda6564906a71fd49669fffec5806dd86c451052d70f276fff454cccdc913a1817dcad39fca72820e014892ff16432233e9a0a19aa499b46ba38f310460943eca68cbe924899c32e4436e71c3b7c9714d139ca559a4a63c", + "SHACAL-2/CBC/ISO7816-4Padding", + "3af7c54ea55d2497162ac9c79d9b2f7837898f83aa4b50b7b762979aa8087669c7228283218babbc53af6eb9edefe37ddd827ded8dd6d99557e9f10075b53e1856478bbaaa6c1a4adcda6564906a71fd49669fffec5806dd86c451052d70f276fff454cccdc913a1817dcad39fca72820e014892ff16432233e9a0a19aa499b499af44e121ef1a08eaaa3b96f2c4fe6248c375435a69f7fc0e1c22eed8aeeac2", + "SHACAL-2/CBC/X923Padding", + "3af7c54ea55d2497162ac9c79d9b2f7837898f83aa4b50b7b762979aa8087669c7228283218babbc53af6eb9edefe37ddd827ded8dd6d99557e9f10075b53e1856478bbaaa6c1a4adcda6564906a71fd49669fffec5806dd86c451052d70f276fff454cccdc913a1817dcad39fca72820e014892ff16432233e9a0a19aa499b46ba38f310460943eca68cbe924899c32e4436e71c3b7c9714d139ca559a4a63c", + "SHACAL-2/CBC/TBCPadding", + "3af7c54ea55d2497162ac9c79d9b2f7837898f83aa4b50b7b762979aa8087669c7228283218babbc53af6eb9edefe37ddd827ded8dd6d99557e9f10075b53e1856478bbaaa6c1a4adcda6564906a71fd49669fffec5806dd86c451052d70f276fff454cccdc913a1817dcad39fca72820e014892ff16432233e9a0a19aa499b49607ddd0d5c54de11ed6ae50afa7fe6ed7f298b5963254e60e069f0916b8f0e1", + "SHACAL-2/CTR/NoPadding", + "e128b4dd0a8a3bf0d4b558ec2a76700a754a1f99cf83a28b3e3a4c2c6b7c6d2cbeb759073b08aa4294730bbed03cfb77a506efb833a4c09a906bbabf25daca6d7ee7df13ef0c462a54dcede0b282914f7914b1cf6f64409c6ce4ea48c7da26ea95fcb7f4b8d169f4bd6b0515f6a37d784b3b9fbb519f931a912391250a78e0c5", + "SHACAL-2/CFB8/NoPadding", + "e185119f49ecb9370bc6915d9f3748e352a4bbd26a7d4911089762cd2933912e220909b2c4a5c047038a547f89701ab6b0ab7fb6cc3e48c79ab573e218793d01f78c3b590ad9d6ce078d3ccecedd228bb8cce130b94dcfe8d5d0ed6fcbb9d1d06768da1f0a4b979c2cdd590474f05e6c0073c35e5202b3f8f73e5e9028120c2b", + "SHACAL-2/CFB256/NoPadding", + "e128b4dd0a8a3bf0d4b558ec2a76700a754a1f99cf83a28b3e3a4c2c6b7c6d2ccd3ea6711fea5531f1bb21be35c6cc8b25e86942f397106b65c56b42267f4bf62782bd6011cb320bb073ceb037de8a5bd775f6fb3ee74525ef6286c54bbb1d19f29e2ed08c7519ecd1440a50fc68a254f7f5ac085f9b7d63e4fa651a25ab7a3b", + "SHACAL-2/CFB/NoPadding", + "e128b4dd0a8a3bf0d4b558ec2a76700a754a1f99cf83a28b3e3a4c2c6b7c6d2ccd3ea6711fea5531f1bb21be35c6cc8b25e86942f397106b65c56b42267f4bf62782bd6011cb320bb073ceb037de8a5bd775f6fb3ee74525ef6286c54bbb1d19f29e2ed08c7519ecd1440a50fc68a254f7f5ac085f9b7d63e4fa651a25ab7a3b", + "SHACAL-2/OFB/NoPadding", + "e128b4dd0a8a3bf0d4b558ec2a76700a754a1f99cf83a28b3e3a4c2c6b7c6d2cb231d2897aba5cffa1b64a99fb6f9b5c9df8875dcd0d88412dacfaf61c2985ee726c4f534c109b16289811f1fc8e20d73c3a4c07dc30e07e806bc631a7e901e5d77fe48114b52abbed9a0c58bde5622c1a624ad8714e5044081016da78518d58", + "SHACAL-2/EAX/NoPadding", + "002e7bac7a8776e78ae9f0ea5df37b3c02a9210a91d583b1ef8dfad22cc346acbe9ff20ea8707e49ba85ed5718225b9f5b4550cefd6ef93566283f411ec0a05f4852b92f2a5b68a5c2c2acd170ac98dcbdc4c2b30787f5b55f3dd88f596852f0bda40ed840dfbb4cc1c8504e729ba724f3fada64e2d3897a3335da5b8c04f1afc2daf2d3a3012b3fec847f663e22a842", "Threefish-256", "9f82b577cf4cca7a504e9f7a2cd7dbb4ef4ac167c716fca19ab1211f195f610f" + "9f82b577cf4cca7a504e9f7a2cd7dbb4ef4ac167c716fca19ab1211f195f610f" + @@ -440,6 +576,27 @@ public class BlockCipherTest "702390d3a53d1a4132f59383cce4fe61e08cd3c73c570190d1c8b60940031ef7" + "42f6775b00fb0b4273a14b46a3fc0e760e02f75dc6100ca9c038c3f151e03145" + "92686fd8cccbee74d246a8c59ad80205c9f9aaeb100ea5812837ee8699753301", + "Threefish-256/EAX/NoPadding", + "13e8b245045cd24c287c8eff69efff7eb884d6451e06825a16b5877a5c31701d" + + "873c4ad59b6920ad065a661dc3318299f2ce6bfffef82c5f8d076ca619fb785b" + + "799c08e25920e8e4ec322a5059adf8ccecf19b68233c912c64e95327e65f8643" + + "8bc1a9d71a872e706b1fd948c6dd2544ba8cee4e535d0e4fde2034be790b316f" + + "71c6eb1b6282d6abe5d47b8918e0bd68", + "Threefish-512/EAX/NoPadding", + "a27669576966dc3c623f4e14e57cbd039c54dcdf44290905b147b5f2debcc58b" + + "5e6c35a18f24de3ad1f5103c67705ba30eab18e02e2813650ab2ab2daabfdf7" + + "ebae0ecb2d0b90cc8a3d9cbbd68a4b4542e5289f84dc7f4eff5a9e2589d5aa0" + + "bab92db80824956f2b74961456943f8f99c81bc986b4e8a089e9085f665f1bd" + + "b455f05cedbaddb01ef90a70a51272fca60f49021fa0b699faef835fa14a32a" + + "3152", + "Threefish-1024/EAX/NoPadding", + "e247bb71d487cd77edb8eabfeb1f8d2501f6b408dd1004f9c2c4463ea897993" + + "c2288c8bb0334d56a5e239adf1d463a7dc21c690307a5c48612be7f56d57f48" + + "a5a145c4955a7a13a2ae21f49194dc8ce65c4d7d4c88d122dbe6bc869f2d39e" + + "04f983344122d15bffb4e0dfdda82512c5d6450a32d019a5f08f214b0843a03" + + "22095a9d37588d3d469c1051b473c4d645512a805f06d34971c83e18c5b5dab" + + "2e8ed2958f038f7d8133333f90cfef1d72eefc69623e2f07a19ff520b8b4e75" + + "3d9255", }; static byte[] input1 = Hex.decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f"); @@ -505,18 +662,21 @@ public class BlockCipherTest rand = new FixedSecureRandom(); + String baseAlgorithm, mode; try { - String baseAlgorithm; - int index = algorithm.indexOf('/'); + + int index = algorithm.indexOf('/'); if (index > 0) { baseAlgorithm = algorithm.substring(0, index); + mode = algorithm.substring(index + 1, algorithm.lastIndexOf('/')); } else { baseAlgorithm = algorithm; + mode = null; } if (baseAlgorithm.equals("IDEA") & noIDEA()) @@ -564,6 +724,7 @@ public class BlockCipherTest catch (Exception e) { fail("" + algorithm + " failed initialisation - " + e.toString(), e); + return; } // @@ -593,16 +754,19 @@ public class BlockCipherTest iv = out.getIV(); if (iv != null) { - try - { - byte[] nIv = new byte[iv.length - 1]; - - in.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(nIv)); - fail("failed to pick up short IV"); - } - catch (InvalidAlgorithmParameterException e) + if (!shortIvOkay.contains(mode)) { - // ignore - this is what we want... + try + { + byte[] nIv = new byte[iv.length - 1]; + + in.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(nIv)); + fail("failed to pick up short IV"); + } + catch (InvalidAlgorithmParameterException e) + { + // ignore - this is what we want... + } } IvParameterSpec spec; @@ -617,6 +781,10 @@ public class BlockCipherTest } } } + catch (TestFailedException e) + { + throw e; + } catch (Exception e) { fail("" + algorithm + " failed initialisation - " + e.toString()); @@ -670,6 +838,8 @@ public class BlockCipherTest bytes[i] = (byte)dIn.read(); } dIn.readFully(bytes, input.length / 2, bytes.length - input.length / 2); + + dIn.close(); } catch (Exception e) { @@ -680,6 +850,88 @@ public class BlockCipherTest { fail("" + algorithm + " failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(bytes))); } + + // + // short buffer test + // + try + { + byte[] out1 = new byte[input.length / 2]; + + try + { + in.doFinal(output, 0, output.length, out1, 0); + + fail("ShortBufferException not triggered"); + } + catch (ShortBufferException e) + { + byte[] out2 = new byte[in.getOutputSize(output.length)]; + + int count = in.doFinal(output, 0, output.length, out2, 0); + + if (!areEqual(out2, count, input)) + { + fail("doFinal " + algorithm + " failed decryption - expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out2))); + } + } + } + catch (TestFailedException e) + { + throw e; + } + catch (Exception e) + { + fail("" + algorithm + " failed short buffer decryption - " + e.toString()); + } + + try + { + if (algorithm.indexOf("CCM") < 0 && algorithm.indexOf("Threefish") < 0 && algorithm.indexOf("PGPCFB") < 0) + { + // + // short buffer on update test + // + byte[] input2 = new byte[input.length * 8]; + + System.arraycopy(input, 0, input2, 0, input.length); + System.arraycopy(input, 0, input2, input.length, input.length); + System.arraycopy(input, 0, input2, input.length * 2, input.length); + System.arraycopy(input, 0, input2, input.length * 3, input.length); + + byte[] output2 = out.doFinal(input2); + + byte[] out1 = new byte[input2.length / 2 - out.getBlockSize() * 2 - 1]; + + try + { + out.update(input2, 0, input2.length / 2, out1, 0); + + fail("ShortBufferException not triggered: " + algorithm + " " + input2.length); + } + catch (ShortBufferException e) + { + byte[] out2 = new byte[out.getOutputSize(input2.length / 2)]; + + System.arraycopy(input2, 0, out2, 0, out2.length); + + int count = out.update(out2, 0, out2.length, out2, 0); + + if (!areEqual(out2, count, Arrays.copyOfRange(output2, 0, count))) + { + fail("update " + algorithm + " failed decryption - expected " + new String(Hex.encode(output2)) + " got " + new String(Hex.encode(out2))); + } + } + } + } + catch (TestFailedException e) + { + throw e; + } + catch (Exception e) + { + fail("" + algorithm + " failed short buffer decryption - " + e.toString()); + } } private boolean noIDEA() @@ -696,6 +948,24 @@ public class BlockCipherTest } } + private boolean areEqual(byte[] a, int aLen, byte[] b) + { + if (b.length != aLen) + { + return false; + } + + for (int i = 0; i != aLen; i++) + { + if (a[i] != b[i]) + { + return false; + } + } + + return true; + } + private void testExceptions() { SecretKeyFactory skF = null; diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CMacTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CMacTest.java index 29ffc7f5..e9702e6b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CMacTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CMacTest.java @@ -1,11 +1,13 @@ package org.bouncycastle.jce.provider.test; +import java.security.Key; import java.security.Security; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -51,6 +53,8 @@ public class CMacTest private final byte[] output_des_ede = Hex.decode("1ca670dea381d37c"); + private static final byte[] general_input = Strings.toByteArray("The quick brown fox jumps over the lazy dog."); + public CMacTest() { } @@ -272,6 +276,43 @@ public class CMacTest fail("Failed - expected " + new String(Hex.encode(output_des_ede)) + " got " + new String(Hex.encode(out))); } + + testCMac(Mac.getInstance("DESedeCMAC", "BC"), keyBytes128, "DESede", input0, output_des_ede); + + testCMac(Mac.getInstance("BlowfishCMAC", "BC"), "2b7e151628aed2a6abf7158809cf4f3c", "Blowfish", "875d73b9bc3de78a"); + testCMac(Mac.getInstance("SEED-CMAC", "BC"), "2b7e151628aed2a6abf7158809cf4f3c", "SEED", "73624c03548a1aaeab9104e47fbd14b1"); + testCMac(Mac.getInstance("SM4-CMAC", "BC"), "2b7e151628aed2a6abf7158809cf4f3c", "SM4", "25b84c0bb3f0cb0c285148a62a09940a"); + testCMac(Mac.getInstance("SHACAL-2CMAC", "BC"), "2b7e151628aed2a6abf7158809cf4f3c", "SHACAL-2", "794b2766cd0d550877f1ded48ab74f9ddff20f32e6d69fae8a1ede4205e7d640"); + testCMac(Mac.getInstance("Threefish-256CMAC", "BC"), "2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c", "Threefish-256", "107a7afec4d17ba4a7bf6b80e5f34b39d066abf168d413ddd16d7ad97515bfff"); + testCMac(Mac.getInstance("Threefish-512CMAC", "BC"), "2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c", "Threefish-512", "b3499567f5846fa6de3bd3f8d885d726976026cd0b04ec2e95431d9aed7743b7c1629d5759b3bca48aeb0c76a905ddfed5cd45c598dfd41d3a9f5964b3a6c4cf"); + testCMac(Mac.getInstance("Threefish-1024CMAC", "BC"), "2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c", + "Threefish-1024", "644009204fcf388e692f989c435a41b4218c6cb7ee3589170e3cf791d007f5c9fd0b389be769f144d36ea19b4c7489812a68c81ba7cc756c6d143a4bbe3175a415897b70f736cd4251b98cff3d357d0c2a1036d0df154bf6cf514c04ce01c1059002082c4792dbb4b7638aa04064d8b93c2c8fe5512f2e05d14ac9bf66397dea"); + } + + private void testCMac(Mac mac, String keyBytes, String algorithm, String expected) + throws Exception + { + testCMac(mac, Hex.decode(keyBytes), algorithm, general_input, Hex.decode(expected)); + } + + private void testCMac(Mac mac, byte[] keyBytes, String algorithm, byte[] input, byte[] expected) + throws Exception + { + Key key = new SecretKeySpec(keyBytes, algorithm); + + mac.init(key); + + mac.update(input, 0, input.length); + + byte[] out = new byte[mac.getMacLength()]; + + mac.doFinal(out, 0); + + if (!areEqual(out, expected)) + { + fail("Failed - expected " + new String(Hex.encode(expected)) + + " got " + new String(Hex.encode(out))); + } } public String getName() diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java index d4c2b420..c8a43089 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java @@ -272,6 +272,41 @@ public class CertPathValidatorTest (PKIXCertPathValidatorResult) cpv.validate(cp, param); } + public void testEmptyPath() + throws Exception + { + CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); + X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.rootCertBin)); + + List list = new ArrayList(); + list.add(rootCert); + CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); + CertStore store = CertStore.getInstance("Collection", ccsp, "BC"); + + List certchain = new ArrayList(); + CertPath cp = CertificateFactory.getInstance("X.509","BC").generateCertPath(certchain); + Set trust = new HashSet(); + trust.add(new TrustAnchor(rootCert, null)); + + CertPathValidator cpv = CertPathValidator.getInstance("PKIX","BC"); + PKIXParameters param = new PKIXParameters(trust); + param.addCertStore(store); + MyChecker checker = new MyChecker(); + param.addCertPathChecker(checker); + + try + { + cpv.validate(cp, param); + } + catch (CertPathValidatorException e) + { + if (!"Certification path is empty.".equals(e.getMessage())) + { + fail("message mismatch"); + } + } + } + public void performTest() throws Exception { @@ -372,6 +407,47 @@ public class CertPathValidatorTest checkCircProcessing(); checkPolicyProcessingAtDomainMatch(); + validateWithExtendedKeyUsage(); + testEmptyPath(); + } + + // extended key usage chain + static byte[] extEE = Base64.decode("MIICtDCCAh2gAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBkjELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxKDAmBgNVBAsMH0JvdW5jeSBJbnRlcm1lZGlhdGUgQ2VydGlmaWNhdGUxLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTE1MDMyNDAzNTEwOVoXDTE1MDUyMzAzNTEwOVowgZYxCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxGDAWBgNVBAMMD0VyaWMgSC4gRWNoaWRuYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwWjANBgkqhkiG9w0BAQEFAANJADBGAkEAtKfkYXBXTxapcIKyK+WLaipil5hBm+EocqS9umJs+umQD3ar+xITnc5d5WVk+rK2VDFloEDGBoh0IOM9ke1+1wIBEaNaMFgwHQYDVR0OBBYEFNBs7G01g7xVEhsMyz7+1yamFmRoMB8GA1UdIwQYMBaAFJQIM28yQPeHN9rRIKrtLqduyckeMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4GBAICrsNswvaXFMreUHHRHrhU4QqPOds8XJe0INx3v/5TfyjPPDMihMEm8WtWbVpFgFAqUQoZscf8cE/SO5375unYFgxrK+p2/je9E82VLF4Xb0cWizjQoWvvTmvFYjt43cGGXgySFLTrW87ju9uNFr/l4W9xvI0hoLI96vEW7Ccho"); + static byte[] extCA = Base64.decode("MIIDIzCCAoygAwIBAgIBAjANBgkqhkiG9w0BAQUFADBcMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECwwaQm91bmN5IFByaW1hcnkgQ2VydGlmaWNhdGUwHhcNMTUwMzI0MDM1MTA5WhcNMTUwNTIzMDM1MTA5WjCBkjELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxKDAmBgNVBAsMH0JvdW5jeSBJbnRlcm1lZGlhdGUgQ2VydGlmaWNhdGUxLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCN4NETxec2lpyNKwR6JD+P4Y7a1kzenoQtNmkjDKSG98/d4fjuxU0ZBf/wSsyF5hCT4YDK3GzqQH8ZPUS7DpRJuNu0l4TNnjYmDDngapRymZeMbtgwByTohxmM/t4g8/veZY+ivQeL6Uajkr00nytJxIbiDEBViOMGcGyQFzCOaQIDAP//o4G9MIG6MB0GA1UdDgQWBBSUCDNvMkD3hzfa0SCq7S6nbsnJHjCBhAYDVR0jBH0we4AUwDYZB63EiJeoXnJvawnr5ebxKVyhYKReMFwxCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMSMwIQYDVQQLDBpCb3VuY3kgUHJpbWFyeSBDZXJ0aWZpY2F0ZYIBATASBgNVHRMBAf8ECDAGAQH/AgEAMA0GCSqGSIb3DQEBBQUAA4GBAJqUlDjse7Og+7qkkFsiXHzQ8FxT82hzfcji8W7bPwZddCPBEluxCJiJBPYXWsLvwo6BEmCDzT9lLQZ+QZyL1fVbOVHiI24hAalbEBEIrEO4GXMD9spqRQ5yoTJ8CgZHTPo0rJkH/ebprp0YHtahVF440zBOvuLM0QTYpERgO2Oe"); + static byte[] extTrust = Base64.decode("MIICJTCCAY4CAQEwDQYJKoZIhvcNAQEFBQAwXDELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxIzAhBgNVBAsMGkJvdW5jeSBQcmltYXJ5IENlcnRpZmljYXRlMB4XDTE1MDMyNDAzNTEwOVoXDTE1MDUyMzAzNTEwOVowXDELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxIzAhBgNVBAsMGkJvdW5jeSBQcmltYXJ5IENlcnRpZmljYXRlMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCyWdLW5ienaMlL42Fkwtn8edl6q5JTFA5b8XdRGXcx1vdUDSUJ57n/7gpwpuJtVuktLt1/hauoVgC2kInzX2vb88KY4FhCU12fBk5rA5HLfTBuCi0gxN+057SalkC96ibBCtacPwUAfOJRPO5Ez+AZmOYrbDY30/wDkQebJu421QIBETANBgkqhkiG9w0BAQUFAAOBgQCDNfqQnQbbmnGzZTl7ccWIyw7SPzWnijpKsQpuRNGkoXfkCcuQLZudytEFZGEL0cycNBnierjJWAn78zGpCQtab01r1GwytRMYz8qO5IIrhsJ4XNafNypYZbi0WtPa07UCQp8tipMbfQNLzSkvkIAaD5IfhdaWKLrSQJwmGg7YAg=="); + + private void validateWithExtendedKeyUsage() + throws Exception + { + CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); + + X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(extTrust)); + X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(extCA)); + X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(extEE)); + + List list = new ArrayList(); + list.add(rootCert); + list.add(interCert); + list.add(finalCert); + + CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); + CertStore store = CertStore.getInstance("Collection", ccsp, "BC"); + Date validDate = new Date(rootCert.getNotBefore().getTime() + 60 * 60 * 1000); + //validating path + List certchain = new ArrayList(); + certchain.add(finalCert); + certchain.add(interCert); + CertPath cp = CertificateFactory.getInstance("X.509","BC").generateCertPath(certchain); + Set trust = new HashSet(); + trust.add(new TrustAnchor(rootCert, null)); + + CertPathValidator cpv = CertPathValidator.getInstance("PKIX", "BC"); + PKIXParameters param = new PKIXParameters(trust); + param.addCertStore(store); + param.setDate(validDate); + param.setRevocationEnabled(false); + + PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, param); } public String getName() diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CertTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CertTest.java index 1ad59fa6..0661bd70 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CertTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CertTest.java @@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.math.BigInteger; +import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; @@ -29,7 +30,10 @@ import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.SignedData; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.test.SimpleTest; @@ -1097,6 +1101,21 @@ public class CertTest "AGfsxfTyldQDEOVzD/Uq8Xh4gIHuSqki9mRSjMR19MQtTKRmI9TRHIeTdIZ6l3P7" + "jFfGJvTP0E9NYSolx+kM"); + private final String ecPemCert = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC\n" + + "VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ\n" + + "cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ\n" + + "BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt\n" + + "VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D\n" + + "0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9\n" + + "ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G\n" + + "A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G\n" + + "A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs\n" + + "aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I\n" + + "flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==\n" + + "-----END CERTIFICATE-----"; + private PublicKey dudPublicKey = new PublicKey() { public String getAlgorithm() @@ -1141,7 +1160,7 @@ public class CertTest } catch (Exception e) { - fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); + fail(dump + Strings.lineSeparator() + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } @@ -1170,7 +1189,7 @@ public class CertTest } catch (Exception e) { - fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); + fail(dump + Strings.lineSeparator() + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } @@ -1201,7 +1220,7 @@ public class CertTest } catch (Exception e) { - fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); + fail(dump + Strings.lineSeparator() + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } @@ -1239,7 +1258,7 @@ public class CertTest } catch (Exception e) { - fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); + fail(dump + Strings.lineSeparator() + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } @@ -1263,7 +1282,7 @@ public class CertTest } catch (Exception e) { - fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e); + fail(dump + Strings.lineSeparator() + getName() + ": "+ id + " failed - exception " + e.toString(), e); } } @@ -1328,6 +1347,20 @@ public class CertTest { fail("PEM crl collection not right"); } + + cert = readPEMCert(cf, ecPemCert); + + SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(cert.getPublicKey().getEncoded()); + + AlgorithmParameters ecParams = AlgorithmParameters.getInstance("EC", "BC"); + + ecParams.init(pubInfo.getAlgorithm().getParameters().toASN1Primitive().getEncoded()); + + if (!new BigInteger("ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973", 16) + .equals(((ECPublicKey)cert.getPublicKey()).getParameters().getN())) + { + fail("N incorrect"); + } } private static Certificate readPEMCert(CertificateFactory cf, String pemData) diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CipherStreamTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CipherStreamTest.java index 0110d222..28f99e57 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CipherStreamTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/CipherStreamTest.java @@ -20,6 +20,7 @@ import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; +import org.bouncycastle.util.test.TestFailedException; /** * check that cipher input/output streams are working correctly @@ -109,10 +110,11 @@ public class CipherStreamTest kGen = KeyGenerator.getInstance(name.substring(0, name.indexOf('/')), "BC"); } + byte[] data = lCode.getBytes(); Cipher in = Cipher.getInstance(name, "BC"); Cipher out = Cipher.getInstance(name, "BC"); Key key = kGen.generateKey(); - ByteArrayInputStream bIn = new ByteArrayInputStream(lCode.getBytes()); + ByteArrayInputStream bIn = new ByteArrayInputStream(data); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); in.init(Cipher.ENCRYPT_MODE, key); @@ -146,6 +148,61 @@ public class CipherStreamTest { fail("Failed - decrypted data doesn't match."); } + + + // + // short buffer test + // + try + { + byte[] enc = in.doFinal(data); + byte[] out1 = new byte[enc.length / 2]; + + try + { + out.doFinal(enc, 0, enc.length, out1, 0); + + fail("ShortBufferException not triggered"); + } + catch (ShortBufferException e) + { + byte[] out2 = new byte[in.getOutputSize(enc.length)]; + + int count = out.doFinal(enc, 0, enc.length, out2, 0); + + if (!areEqual(out2, count, data)) + { + fail("" + name + " failed decryption - expected " + new String(Hex.encode(data)) + " got " + new String(Hex.encode(out2))); + } + } + } + catch (TestFailedException e) + { + throw e; + } + catch (Exception e) + { + fail("" + name + " failed short buffer decryption - " + e.toString()); + } + } + + + private boolean areEqual(byte[] a, int aLen, byte[] b) + { + if (b.length != aLen) + { + return false; + } + + for (int i = 0; i != aLen; i++) + { + if (a[i] != b[i]) + { + return false; + } + } + + return true; } private void testAlgorithm(String name, byte[] keyBytes, byte[] iv, byte[] plainText, byte[] cipherText) diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DHTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DHTest.java index 6b9ad4e5..ef4c0454 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DHTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DHTest.java @@ -570,7 +570,7 @@ public class DHTest } } - private void testECDH(String algorithm, String cipher, int keyLen) + private void testECDH(String algorithm, String curveName, String cipher, int keyLen) throws Exception { ECNamedCurveParameterSpec parameterSpec = ECNamedCurveTable.getParameterSpec("secp521r1"); @@ -863,9 +863,9 @@ public class DHTest 384); DHParameterSpec dhSpec1024 = new DHParameterSpec( - new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16), - new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16), - 512); + new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16), + new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16), + 512); prov.setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, dhSpec512); @@ -967,11 +967,16 @@ public class DHTest testECDH("ECDH"); testECDH("ECDHC"); - testECDH("ECDH", "AES", 256); - testECDH("ECDH", "DESEDE", 192); - testECDH("ECDH", "DES", 64); - testECDH("ECDHwithSHA1KDF", "AES", 256); - testECDH("ECDHwithSHA1KDF", "DESEDE", 192); + testECDH("ECDH", "secp521r1", "AES", 256); + testECDH("ECDH", "secp521r1", "DESEDE", 192); + testECDH("ECDH", "secp521r1", "DES", 64); + testECDH("ECDHwithSHA1KDF", "secp521r1", "AES", 256); + testECDH("ECDHwithSHA1KDF", "secp521r1", "DESEDE", 192); + testECDH("ECDH", "Curve25519", "AES", 256); + testECDH("ECDH", "Curve25519", "DESEDE", 192); + testECDH("ECDH", "Curve25519", "DES", 64); + testECDH("ECDHwithSHA1KDF", "Curve25519", "AES", 256); + testECDH("ECDHwithSHA1KDF", "Curve25519", "DESEDE", 192); testExceptions(); testDESAndDESede(g768, p768); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DSATest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DSATest.java index 3e2ebd41..0dd9981a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DSATest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DSATest.java @@ -44,6 +44,7 @@ import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; @@ -317,15 +318,15 @@ public class DSATest if (!r.equals(sig[0])) { - fail("r component wrong." + System.getProperty("line.separator") - + " expecting: " + r + System.getProperty("line.separator") + fail("r component wrong." + Strings.lineSeparator() + + " expecting: " + r + Strings.lineSeparator() + " got : " + sig[0]); } if (!s.equals(sig[1])) { - fail("s component wrong." + System.getProperty("line.separator") - + " expecting: " + s + System.getProperty("line.separator") + fail("s component wrong." + Strings.lineSeparator() + + " expecting: " + s + Strings.lineSeparator() + " got : " + sig[1]); } } @@ -461,15 +462,15 @@ public class DSATest if (!r.equals(sig[0])) { - fail("r component wrong." + System.getProperty("line.separator") - + " expecting: " + r + System.getProperty("line.separator") + fail("r component wrong." + Strings.lineSeparator() + + " expecting: " + r + Strings.lineSeparator() + " got : " + sig[0]); } if (!s.equals(sig[1])) { - fail("s component wrong." + System.getProperty("line.separator") - + " expecting: " + s + System.getProperty("line.separator") + fail("s component wrong." + Strings.lineSeparator() + + " expecting: " + s + Strings.lineSeparator() + " got : " + sig[1]); } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DSTU4145Test.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DSTU4145Test.java index 5d29841c..a3e1a803 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DSTU4145Test.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DSTU4145Test.java @@ -23,6 +23,7 @@ import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; @@ -95,16 +96,16 @@ public class DSTU4145Test if (!r.equals(sig[0])) { fail( - ": r component wrong." + System.getProperty("line.separator") - + " expecting: " + r + System.getProperty("line.separator") + ": r component wrong." + Strings.lineSeparator() + + " expecting: " + r + Strings.lineSeparator() + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { fail( - ": s component wrong." + System.getProperty("line.separator") - + " expecting: " + s + System.getProperty("line.separator") + ": s component wrong." + Strings.lineSeparator() + + " expecting: " + s + Strings.lineSeparator() + " got : " + sig[1].toString(16)); } } @@ -157,16 +158,16 @@ public class DSTU4145Test if (!r.equals(sig[0])) { fail( - ": r component wrong." + System.getProperty("line.separator") - + " expecting: " + r + System.getProperty("line.separator") + ": r component wrong." + Strings.lineSeparator() + + " expecting: " + r + Strings.lineSeparator() + " got : " + sig[0].toString(16)); } if (!s.equals(sig[1])) { fail( - ": s component wrong." + System.getProperty("line.separator") - + " expecting: " + s + System.getProperty("line.separator") + ": s component wrong." + Strings.lineSeparator() + + " expecting: " + s + Strings.lineSeparator() + " got : " + sig[1].toString(16)); } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DigestTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DigestTest.java index 679f3eab..fd4b1c7f 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DigestTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/DigestTest.java @@ -3,6 +3,7 @@ package org.bouncycastle.jce.provider.test; import java.security.MessageDigest; import java.security.Security; +import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -32,6 +33,23 @@ public class DigestTest { "GOST3411", "b285056dbf18d7392d7677369524dd14747459ed8143997e163b2986f92fd42c" }, { "WHIRLPOOL", "4E2448A4C6F486BB16B6562C73B4020BF3043E3A731BCE721AE1B303D97E6D4C7181EEBDB6C57E277D0E34957114CBD6C797FC9D95D8B582D225292076D4EEF5" }, { "SM3", "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0" }, + { "SHA3-224", "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf" }, + { "SHA3-256", "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532" }, + { "SHA3-384", "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25" }, + { "SHA3-512", "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0" }, + { "KECCAK-224", "c30411768506ebe1c2871b1ee2e87d38df342317300a9b97a95ec6a8" }, + { "KECCAK-256", "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45" }, + { "KECCAK-288", "20ff13d217d5789fa7fc9e0e9a2ee627363ec28171d0b6c52bbd2f240554dbc94289f4d6" }, + { "KECCAK-384", "f7df1165f033337be098e7d288ad6a2f74409d7a60b49c36642218de161b1f99f8c681e4afaf31a34db29fb763e3c28e" }, + { "KECCAK-512", "18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96" }, + { "BLAKE2B-160", "384264f676f39536840523f284921cdc68b6846b" }, + { "BLAKE2B-256", "bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319" }, + { "BLAKE2B-384", "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbda46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4" }, + { "BLAKE2B-512", "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923" }, + { MiscObjectIdentifiers.id_blake2b160.getId(), "384264f676f39536840523f284921cdc68b6846b" }, + { MiscObjectIdentifiers.id_blake2b256.getId(), "bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319" }, + { MiscObjectIdentifiers.id_blake2b384.getId(), "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbda46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4" }, + { MiscObjectIdentifiers.id_blake2b512.getId(), "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923" }, }; public String getName() @@ -92,7 +110,7 @@ public class DigestTest result2 = d.digest(); if (!MessageDigest.isEqual(result, result2)) - { + { System.err.println(Hex.toHexString(result2)); System.err.println(Hex.toHexString(result)); fail("Result object 4(b) not equal"); } @@ -128,11 +146,11 @@ public class DigestTest byte[] result = digest.digest(abc); if (!MessageDigest.isEqual(result, Hex.decode(hash))) - { + { System.err.println(Hex.toHexString(result)); fail("abc result not equal for " + algorithm); } } - + public void performTest() throws Exception { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/ECDSA5Test.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/ECDSA5Test.java index 87773da8..734711a3 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/ECDSA5Test.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/ECDSA5Test.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; +import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyFactory; @@ -33,6 +34,8 @@ import java.security.spec.EllipticCurve; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; +import javax.crypto.KeyAgreement; + import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; @@ -40,6 +43,8 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTNamedCurves; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.sec.SECObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; @@ -48,12 +53,15 @@ import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; +import org.bouncycastle.jcajce.spec.MQVParameterSpec; import org.bouncycastle.jce.ECKeyUtil; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.ECPointUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; @@ -147,15 +155,15 @@ public class ECDSA5Test if (!r.equals(sig[0])) { - fail("r component wrong." + System.getProperty("line.separator") - + " expecting: " + r + System.getProperty("line.separator") + fail("r component wrong." + Strings.lineSeparator() + + " expecting: " + r + Strings.lineSeparator() + " got : " + sig[0]); } if (!s.equals(sig[1])) { - fail("s component wrong." + System.getProperty("line.separator") - + " expecting: " + s + System.getProperty("line.separator") + fail("s component wrong." + Strings.lineSeparator() + + " expecting: " + s + Strings.lineSeparator() + " got : " + sig[1]); } } @@ -275,15 +283,15 @@ public class ECDSA5Test if (!r.equals(sig[0])) { - fail("r component wrong." + System.getProperty("line.separator") - + " expecting: " + r + System.getProperty("line.separator") + fail("r component wrong." + Strings.lineSeparator() + + " expecting: " + r + Strings.lineSeparator() + " got : " + sig[0]); } if (!s.equals(sig[1])) { - fail("s component wrong." + System.getProperty("line.separator") - + " expecting: " + s + System.getProperty("line.separator") + fail("s component wrong." + Strings.lineSeparator() + + " expecting: " + s + Strings.lineSeparator() + " got : " + sig[1]); } } @@ -717,6 +725,34 @@ public class ECDSA5Test } } + private void testAlgorithmParameters() + throws Exception + { + AlgorithmParameters algParam = AlgorithmParameters.getInstance("EC", "BC"); + + algParam.init(new ECGenParameterSpec("P-256")); + + byte[] encoded = algParam.getEncoded(); + + algParam = AlgorithmParameters.getInstance("EC", "BC"); + + algParam.init(encoded); + + ECGenParameterSpec genSpec = algParam.getParameterSpec(ECGenParameterSpec.class); + + if (!genSpec.getName().equals(X9ObjectIdentifiers.prime256v1.getId())) + { + fail("curve name not recovered"); + } + + ECParameterSpec ecSpec = algParam.getParameterSpec(ECParameterSpec.class); + + if (!ecSpec.getOrder().equals(NISTNamedCurves.getByName("P-256").getN())) + { + fail("incorrect spec recovered"); + } + } + private void testKeyPairGenerationWithOIDs() throws Exception { @@ -888,6 +924,78 @@ public class ECDSA5Test } } + /** + COUNT = 1 + dsCAVS = 00000179557decd75b797bea9db656ce99c03a6e0ab13804b5b589644f7db41ceba05c3940c300361061074ca72a828428d9198267fa0b75e1e3e785a0ff20e839414be0 + QsCAVSx = 000001ce7da31681d5f176f3618f205969b9142520363dd26a596866c89988c932e3ce01904d12d1e9b105462e56163dbe7658ba3c472bf1f3c8165813295393ae346764 + QsCAVSy = 000000e70d6e55b76ebd362ff071ab819315593cec650276209a9fdc2c1c48e03c35945f04e74d958cabd3f5e4d1f096a991e807a8f9d217de306a6b561038ca15aea4b9 + NonceEphemCAVS = 4214a1a0a1d11679ae22f98d7ae483c1a74008a9cd7f7cf71b1f373a4226f5c58eb621ec56e2537797c01750dcbff07f613b9c58774f9af32aebeadd2226140dc7d56b1aa95c93ab1ec4412e2d0e42cdaac7bf9da3ddbf19fbb1edd0556d9c5a339808905fe8defd8b57ff8f34788192cc0cf7df17d1f351d69ac979a3a495931c287fb8 + dsIUT = 000000c14895dfcc5a6b24994828cfd0a0cc0a881a70173a3eb05c57b098046c8e60a868f6176284aa346eff1fd1b8b879052c5a6d5fd0ae146b35ed7ecee32e294103cd + QsIUTx = 00000174a658695049db59f6bbe2ad23e1753bf58384a56fc9b3dec13eb873b33e1f4dbd24b6b4ca05a9a11ad531f6d99e9430a774980e8a8d9fd2d1e2a0d76fe3dd36c7 + QsIUTy = 00000030639849e1df341973db44e7bbba5bb597884a439f9ce54620c3ca73a9804cc26fcda3aaf73ae5a11d5b325cae0e95cfafe1985c6c2fdb892722e7dd2c5d744cf3 + deIUT = 00000138f54e986c7b44f49da389fa9f61bb7265f0cebdeddf09d47c72e55186e2520965fc2c31bb9c0a557e3c28e02a751f097e413c4252c7b0d22452d89f9ac314bc6e + QeIUTx = 000001b9fbce9c9ebb31070a4a4ac7af54ec9189c1f98948cd24ca0a5029217e4784d3c8692da08a6a512d1c9875d20d8e03664c148fa5d34bbac6d42e499ee5dbf01120 + QeIUTy = 000000994a714b6d09afa896dbba9b4f436ab3cdb0d11dcd2aad28b7ba35d6fa6be537b6ffb0f9bf5fe1d594b8f8b8829687c9395c3d938c873f26c7100888c3aca2d59a + OI = a1b2c3d4e54341565369646dbb63a273c81e0aad02f92699bf7baa28fd4509145b0096746894e98e209a85ecb415b8 + CAVSTag = 4ade5dc983cc1cf61c90fdbf726fa6a88e9bf411bbaf0015db06ff4348560e4d + Z = 019a19a0a99f60221ee23323b3317292e8c10d57ba04e0b33f6241979ec3895945eed0bdcbc59ab576e7047061f0d63d1aaf78b1d442028605aa1c0f963a3bc9d61a + MacData = 4b435f315f55a1b2c3d4e543415653696401b9fbce9c9ebb31070a4a4ac7af54ec9189c1f98948cd24ca0a5029217e4784d3c8692da08a6a512d1c9875d20d8e03664c148fa5d34bbac6d42e499ee5dbf0112000994a714b6d09afa896dbba9b4f436ab3cdb0d11dcd2aad28b7ba35d6fa6be537b6ffb0f9bf5fe1d594b8f8b8829687c9395c3d938c873f26c7100888c3aca2d59a4214a1a0a1d11679ae22f98d7ae483c1a74008a9cd7f7cf71b1f373a4226f5c58eb621ec56e2537797c01750dcbff07f613b9c58774f9af32aebeadd2226140dc7d56b1aa95c93ab1ec4412e2d0e42cdaac7bf9da3ddbf19fbb1edd0556d9c5a339808905fe8defd8b57ff8f34788192cc0cf7df17d1f351d69ac979a3a495931c287fb8 + DKM = 0744e1774149a8b8f88d3a1e20ac1517efd2f54ba4b5f178de99f33b68eea426 + Result = P (14 - DKM value should have leading 0 nibble ) + */ + public void testMQVwithHMACOnePass() + throws Exception + { + AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance("EC", "BC"); + + algorithmParameters.init(new ECGenParameterSpec("P-521")); + + ECParameterSpec ecSpec = algorithmParameters.getParameterSpec(ECParameterSpec.class); + KeyFactory keyFact = KeyFactory.getInstance("EC", "BC"); + + ECPrivateKey dsCAVS = (ECPrivateKey)keyFact.generatePrivate(new ECPrivateKeySpec(new BigInteger("00000179557decd75b797bea9db656ce99c03a6e0ab13804b5b589644f7db41ceba05c3940c300361061074ca72a828428d9198267fa0b75e1e3e785a0ff20e839414be0", 16), ecSpec)); + ECPublicKey qsCAVS = (ECPublicKey)keyFact.generatePublic(new ECPublicKeySpec(new ECPoint( + new BigInteger("000001ce7da31681d5f176f3618f205969b9142520363dd26a596866c89988c932e3ce01904d12d1e9b105462e56163dbe7658ba3c472bf1f3c8165813295393ae346764", 16), + new BigInteger("000000e70d6e55b76ebd362ff071ab819315593cec650276209a9fdc2c1c48e03c35945f04e74d958cabd3f5e4d1f096a991e807a8f9d217de306a6b561038ca15aea4b9", 16)), ecSpec)); + + ECPrivateKey dsIUT = (ECPrivateKey)keyFact.generatePrivate(new ECPrivateKeySpec(new BigInteger("000000c14895dfcc5a6b24994828cfd0a0cc0a881a70173a3eb05c57b098046c8e60a868f6176284aa346eff1fd1b8b879052c5a6d5fd0ae146b35ed7ecee32e294103cd", 16), ecSpec)); + ECPublicKey qsIUT = (ECPublicKey)keyFact.generatePublic(new ECPublicKeySpec(new ECPoint( + new BigInteger("00000174a658695049db59f6bbe2ad23e1753bf58384a56fc9b3dec13eb873b33e1f4dbd24b6b4ca05a9a11ad531f6d99e9430a774980e8a8d9fd2d1e2a0d76fe3dd36c7", 16), + new BigInteger("00000030639849e1df341973db44e7bbba5bb597884a439f9ce54620c3ca73a9804cc26fcda3aaf73ae5a11d5b325cae0e95cfafe1985c6c2fdb892722e7dd2c5d744cf3", 16)), ecSpec)); + + ECPrivateKey deIUT = (ECPrivateKey)keyFact.generatePrivate(new ECPrivateKeySpec(new BigInteger("00000138f54e986c7b44f49da389fa9f61bb7265f0cebdeddf09d47c72e55186e2520965fc2c31bb9c0a557e3c28e02a751f097e413c4252c7b0d22452d89f9ac314bc6e", 16), ecSpec)); + ECPublicKey qeIUT = (ECPublicKey)keyFact.generatePublic(new ECPublicKeySpec(new ECPoint( + new BigInteger("000001b9fbce9c9ebb31070a4a4ac7af54ec9189c1f98948cd24ca0a5029217e4784d3c8692da08a6a512d1c9875d20d8e03664c148fa5d34bbac6d42e499ee5dbf01120", 16), + new BigInteger("000000994a714b6d09afa896dbba9b4f436ab3cdb0d11dcd2aad28b7ba35d6fa6be537b6ffb0f9bf5fe1d594b8f8b8829687c9395c3d938c873f26c7100888c3aca2d59a", 16)), ecSpec)); + + KeyAgreement uAgree = KeyAgreement.getInstance("ECMQVwithSHA512CKDF", "BC"); + + uAgree.init(dsCAVS, new MQVParameterSpec(dsCAVS, qeIUT, Hex.decode("a1b2c3d4e54341565369646dbb63a273c81e0aad02f92699bf7baa28fd4509145b0096746894e98e209a85ecb415b8"))); + + + KeyAgreement vAgree = KeyAgreement.getInstance("ECMQVwithSHA512CKDF", "BC"); + vAgree.init(dsIUT, new MQVParameterSpec(deIUT, qsCAVS, Hex.decode("a1b2c3d4e54341565369646dbb63a273c81e0aad02f92699bf7baa28fd4509145b0096746894e98e209a85ecb415b8"))); + + // + // agreement + // + uAgree.doPhase(qsIUT, true); + vAgree.doPhase(qsCAVS, true); + + byte[] ux = uAgree.generateSecret(PKCSObjectIdentifiers.id_hmacWithSHA512.getId()).getEncoded(); + byte[] vx = vAgree.generateSecret(PKCSObjectIdentifiers.id_hmacWithSHA512.getId()).getEncoded(); + + if (!Arrays.areEqual(ux, vx)) + { + fail("agreement values don't match"); + } + + if (!Arrays.areEqual(Hex.decode("0744e1774149a8b8f88d3a1e20ac1517efd2f54ba4b5f178de99f33b68eea426"), Arrays.copyOfRange(ux, 0, 32))) + { + fail("agreement values not correct"); + } + } + protected BigInteger[] derDecode( byte[] encoding) throws IOException @@ -922,6 +1030,8 @@ public class ECDSA5Test testNamedCurveParameterPreservation(); testNamedCurveSigning(); testBSI(); + testMQVwithHMACOnePass(); + testAlgorithmParameters(); } public static void main( diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/ECNRTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/ECNRTest.java index 74695060..165faa73 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/ECNRTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/ECNRTest.java @@ -19,6 +19,7 @@ import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.util.BigIntegers; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; @@ -194,16 +195,16 @@ public class ECNRTest if (!r.equals(sig[0])) { fail(size + "bit" - + ": r component wrong." + System.getProperty("line.separator") - + " expecting: " + r + System.getProperty("line.separator") + + ": r component wrong." + Strings.lineSeparator() + + " expecting: " + r + Strings.lineSeparator() + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail(size + "bit" - + ": s component wrong." + System.getProperty("line.separator") - + " expecting: " + s + System.getProperty("line.separator") + + ": s component wrong." + Strings.lineSeparator() + + " expecting: " + s + Strings.lineSeparator() + " got : " + sig[1]); } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/EncryptedPrivateKeyInfoTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/EncryptedPrivateKeyInfoTest.java index 80e64ac6..da6811c5 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/EncryptedPrivateKeyInfoTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/EncryptedPrivateKeyInfoTest.java @@ -13,23 +13,26 @@ import java.security.spec.PKCS8EncodedKeySpec; import javax.crypto.Cipher; import javax.crypto.EncryptedPrivateKeyInfo; import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; +import org.bouncycastle.jcajce.PKCS12KeyWithParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.util.test.SimpleTestResult; +import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.util.test.Test; import org.bouncycastle.util.test.TestResult; public class EncryptedPrivateKeyInfoTest - implements Test + extends SimpleTest { String alg = "1.2.840.113549.1.12.1.3"; // 3 key triple DES with SHA-1 - public TestResult perform() + public void performTest() + throws Exception { - try - { + doTestWithExplicitIV(); + KeyPairGenerator fact = KeyPairGenerator.getInstance("RSA", "BC"); fact.initialize(512, new SecureRandom()); @@ -83,7 +86,7 @@ public class EncryptedPrivateKeyInfoTest if (!MessageDigest.isEqual(priKey.getEncoded(), keySpec.getEncoded())) { - return new SimpleTestResult(false, "Private key does not match"); + fail("Private key does not match"); } // @@ -116,14 +119,65 @@ public class EncryptedPrivateKeyInfoTest if (!MessageDigest.isEqual(priKey.getEncoded(), keySpec.getEncoded())) { - return new SimpleTestResult(false, "Private key does not match"); + fail("Private key does not match"); } - - return new SimpleTestResult(true, getName() + ": Okay"); - } - catch (Exception e) + } + + public void doTestWithExplicitIV() + throws Exception + { + KeyPairGenerator fact = KeyPairGenerator.getInstance("RSA", "BC"); + fact.initialize(512, new SecureRandom()); + + KeyPair keyPair = fact.generateKeyPair(); + + PrivateKey priKey = keyPair.getPrivate(); + PublicKey pubKey = keyPair.getPublic(); + + // + // set up the parameters + // + byte[] salt = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + int iterationCount = 100; + PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount); + + AlgorithmParameters params = AlgorithmParameters.getInstance(alg, "BC"); + + params.init(defParams); + + // + // set up the key + // + char[] password1 = { 'h', 'e', 'l', 'l', 'o' }; + + Cipher cipher = Cipher.getInstance(alg, "BC"); + + byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 }; + + cipher.init(Cipher.WRAP_MODE, new PKCS12KeyWithParameters(password1, salt, iterationCount), new IvParameterSpec(iv)); + + byte[] wrappedKey = cipher.wrap(priKey); + + // + // create encrypted object + // + + EncryptedPrivateKeyInfo pInfo = new EncryptedPrivateKeyInfo(params, wrappedKey); + + // + // decryption step + // + char[] password2 = { 'h', 'e', 'l', 'l', 'o' }; + + cipher = Cipher.getInstance(pInfo.getAlgName(), "BC"); + + cipher.init(Cipher.DECRYPT_MODE, new PKCS12KeyWithParameters(password2, salt, iterationCount), new IvParameterSpec(iv)); + + PKCS8EncodedKeySpec keySpec = pInfo.getKeySpec(cipher); + + if (!MessageDigest.isEqual(priKey.getEncoded(), keySpec.getEncoded())) { - return new SimpleTestResult(false, getName() + ": exception - " + e.toString(), e); + fail("Private key does not match"); } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GMacTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GMacTest.java index 3a26d3cd..991ce0d5 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GMacTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GMacTest.java @@ -3,7 +3,6 @@ package org.bouncycastle.jce.provider.test; import java.security.NoSuchAlgorithmException; import java.security.Security; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import javax.crypto.Cipher; @@ -38,7 +37,7 @@ public class GMacTest List missingMacs = new ArrayList(); List missingKeyGens = new ArrayList(); - String[] ciphers = new String[] { "AES", "NOEKEON", "Twofish", "CAST6", "SEED", "Serpent", "RC6", "CAMELLIA" }; + String[] ciphers = new String[] { "AES", "NOEKEON", "Twofish", "CAST6", "SEED", "Tnepres", "Serpent", "SM4", "RC6", "CAMELLIA" }; String[] macs = new String[] { "a52308801b32d4770c701ace9b826f12", @@ -47,6 +46,8 @@ public class GMacTest "d13a33e78e48b274bf7d64bf9aecdb82", "d05d550054735c6e7e01b6981fc14b4e", "4a34dfe4f5410afd7c40b1e110377a73", + "80c3cc898899e41fd4e21c6c1261fedb", + "d394f3d12bec3cf6c5302265ecab9af1", "d9f597c96b41f641da6c83d4760f543b", "371ad8cc920c6bda2a26d8f237bd446b" }; @@ -108,7 +109,7 @@ public class GMacTest if (!Arrays.areEqual(bytes, Hex.decode(macOutput))) { - fail("wrong mac value computed for " + name); + fail("wrong mac value computed for " + name + " " + Hex.toHexString(bytes)); } try diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GOST28147Test.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GOST28147Test.java index 93e3ad74..d95b7610 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GOST28147Test.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GOST28147Test.java @@ -10,12 +10,14 @@ import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; +import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -237,6 +239,15 @@ public class GOST28147Test oidTest(); } + + Mac mac = Mac.getInstance("GOST28147MAC", "BC"); + + mac.init(new SecretKeySpec(Hex.decode("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), "GOST28147")); + + if (!Arrays.areEqual(Hex.decode("1b69996e"), mac.doFinal(Hex.decode("4e6f77206973207468652074696d6520666f7220616c6c20")))) + { + fail("mac test falied."); + } } public static void main( diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GOST3410Test.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GOST3410Test.java index 472f2742..71378bb3 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GOST3410Test.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/GOST3410Test.java @@ -42,9 +42,8 @@ import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.math.ec.ECCurve; -import org.bouncycastle.math.ec.ECFieldElement; -import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.BigIntegers; +import org.bouncycastle.util.Strings; import org.bouncycastle.util.test.FixedSecureRandom; import org.bouncycastle.util.test.SimpleTest; import org.bouncycastle.x509.X509V3CertificateGenerator; @@ -72,19 +71,19 @@ public class GOST3410Test ECParameterSpec spec = new ECParameterSpec( curve, - new ECPoint.Fp(curve, - new ECFieldElement.Fp(mod_p,new BigInteger("2")), // x - new ECFieldElement.Fp(mod_p,new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"))), // y - new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q + curve.createPoint( + new BigInteger("2"), // x + new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280")), // y + new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q ECPrivateKeySpec priKey = new ECPrivateKeySpec( new BigInteger("55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d spec); ECPublicKeySpec pubKey = new ECPublicKeySpec( - new ECPoint.Fp(curve, - new ECFieldElement.Fp(mod_p, new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403")), // x - new ECFieldElement.Fp(mod_p, new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994"))), // y + curve.createPoint( + new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403"), // x + new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994")), // y spec); Signature sgr = Signature.getInstance("ECGOST3410", "BC"); @@ -114,16 +113,16 @@ public class GOST3410Test if (!r.equals(sig[0])) { fail( - ": r component wrong." + System.getProperty("line.separator") - + " expecting: " + r + System.getProperty("line.separator") + ": r component wrong." + Strings.lineSeparator() + + " expecting: " + r + Strings.lineSeparator() + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail( - ": s component wrong." + System.getProperty("line.separator") - + " expecting: " + s + System.getProperty("line.separator") + ": s component wrong." + Strings.lineSeparator() + + " expecting: " + s + Strings.lineSeparator() + " got : " + sig[1]); } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/HMacTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/HMacTest.java index 080df072..06e1429c 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/HMacTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/HMacTest.java @@ -10,11 +10,11 @@ import javax.crypto.SecretKey; import javax.crypto.spec.RC5ParameterSpec; import javax.crypto.spec.SecretKeySpec; +import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; -import org.bouncycastle.asn1.iana.IANAObjectIdentifiers; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; /** * HMAC tester @@ -40,6 +40,12 @@ public class HMacTest static byte[] outputOld384 = Hex.decode("0a046aaa0255e432912228f8ccda437c8a8363fb160afb0570ab5b1fd5ddc20eb1888b9ed4e5b6cb5bc034cd9ef70e40"); static byte[] outputOld512 = Hex.decode("9656975ee5de55e75f2976ecce9a04501060b9dc22a6eda2eaef638966280182477fe09f080b2bf564649cad42af8607a2bd8d02979df3a980f15e2326a0a22a"); + static byte[] outputKck224 = Hex.decode("b73d595a2ba9af815e9f2b4e53e78581ebd34a80b3bbaac4e702c4cc"); + static byte[] outputKck256 = Hex.decode("9663d10c73ee294054dc9faf95647cb99731d12210ff7075fb3d3395abfb9821"); + static byte[] outputKck288 = Hex.decode("36145df8742160a1811139494d708f9a12757c30dedc622a98aa6ecb69da32a34ea55441"); + static byte[] outputKck384 = Hex.decode("892dfdf5d51e4679bf320cd16d4c9dc6f749744608e003add7fba894acff87361efa4e5799be06b6461f43b60ae97048"); + static byte[] outputKck512 = Hex.decode("8852c63be8cfc21541a4ee5e5a9a852fc2f7a9adec2ff3a13718ab4ed81aaea0b87b7eb397323548e261a64e7fc75198f6663a11b22cd957f7c8ec858a1c7755"); + public HMacTest() { } @@ -142,6 +148,11 @@ public class HMacTest testHMac("HMac-RIPEMD128", outputRipeMD128); testHMac("HMac-RIPEMD160", outputRipeMD160); testHMac("HMac-TIGER", outputTiger); + testHMac("HMac-KECCAK224", outputKck224); + testHMac("HMac-KECCAK256", outputKck256); + testHMac("HMac-KECCAK288", outputKck288); + testHMac("HMac-KECCAK384", outputKck384); + testHMac("HMac-KECCAK512", outputKck512); testHMac("HMac/SHA1", output1); testHMac("HMac/MD5", outputMD5); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/IESTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/IESTest.java index 8dc1c0b5..177ec2ed 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/IESTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/IESTest.java @@ -132,10 +132,24 @@ public class IESTest byte[] message = Hex.decode("1234567890abcdef"); + int estLen1 = c1.getOutputSize(message.length); + byte[] out1 = c1.doFinal(message, 0, message.length); + if (estLen1 < out1.length) + { + fail("output size incorrect"); + } + + int estLen2 = c2.getOutputSize(out1.length); + byte[] out2 = c2.doFinal(out1, 0, out1.length); + if (estLen2 < out2.length) + { + fail("output size incorrect"); + } + if (!areEqual(out2, message)) { fail("stream cipher test failed"); @@ -176,10 +190,23 @@ public class IESTest byte[] message = Hex.decode("1234567890abcdef"); + int estLen1 = c1.getOutputSize(message.length); + byte[] out1 = c1.doFinal(message, 0, message.length); + if (estLen1 < out1.length) + { + fail("output size incorrect"); + } + + int estLen2 = c2.getOutputSize(out1.length); byte[] out2 = c2.doFinal(out1, 0, out1.length); + if (estLen2 < out2.length) + { + fail("output size incorrect"); + } + if (!areEqual(out2, message)) { fail("stream cipher test failed"); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/MQVTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/MQVTest.java index 3b0b8a2f..28852f7c 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/MQVTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/MQVTest.java @@ -11,6 +11,7 @@ import java.security.spec.EllipticCurve; import javax.crypto.KeyAgreement; +import org.bouncycastle.jcajce.spec.MQVParameterSpec; import org.bouncycastle.jce.ECPointUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.MQVPrivateKeySpec; @@ -29,10 +30,11 @@ public class MQVTest public void performTest() throws Exception { + testECMQVDeprecated(); testECMQV(); } - private void testECMQV() + private void testECMQVDeprecated() throws Exception { KeyPairGenerator g = KeyPairGenerator.getInstance("ECMQV", "BC"); @@ -79,6 +81,57 @@ public class MQVTest if (!ux.equals(vx)) { + fail("Deprecated Agreement failed"); + } + } + + private void testECMQV() + throws Exception + { + KeyPairGenerator g = KeyPairGenerator.getInstance("ECMQV", "BC"); + + EllipticCurve curve = new EllipticCurve( + new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b + + ECParameterSpec ecSpec = new ECParameterSpec( + curve, + ECPointUtil.decodePoint(curve, Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G + new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n + 1); // h + + g.initialize(ecSpec, new SecureRandom()); + + // + // U side + // + KeyPair U1 = g.generateKeyPair(); + KeyPair U2 = g.generateKeyPair(); + + // + // V side + // + KeyPair V1 = g.generateKeyPair(); + KeyPair V2 = g.generateKeyPair(); + + KeyAgreement uAgree = KeyAgreement.getInstance("ECMQV", "BC"); + uAgree.init(U1.getPrivate(), new MQVParameterSpec(U2, V2.getPublic())); + + KeyAgreement vAgree = KeyAgreement.getInstance("ECMQV", "BC"); + vAgree.init(V1.getPrivate(), new MQVParameterSpec(V2, U2.getPublic())); + + // + // agreement + // + uAgree.doPhase(V1.getPublic(), true); + vAgree.doPhase(U1.getPublic(), true); + + BigInteger ux = new BigInteger(uAgree.generateSecret()); + BigInteger vx = new BigInteger(vAgree.generateSecret()); + + if (!ux.equals(vx)) + { fail("Agreement failed"); } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/NamedCurveTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/NamedCurveTest.java index aeb0871d..3a8693d4 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/NamedCurveTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/NamedCurveTest.java @@ -42,7 +42,7 @@ public class NamedCurveTest CURVE_NAMES.put("secp224r1", "secp224r1"); CURVE_NAMES.put("B-409", SECNamedCurves.getName(NISTNamedCurves.getOID("B-409"))); // nist CURVE_NAMES.put("P-521", SECNamedCurves.getName(NISTNamedCurves.getOID("P-521"))); - CURVE_NAMES.put("brainpoolp160r1", "brainpoolp160r1"); // TeleTrusT + CURVE_NAMES.put("brainpoolP160r1", "brainpoolP160r1"); // TeleTrusT CURVE_ALIASES.put("secp192r1", "prime192v1"); CURVE_ALIASES.put("secp256r1", "prime256v1"); @@ -295,7 +295,7 @@ public class NamedCurveTest testCurve("secp224r1"); testCurve("B-409"); // nist testCurve("P-521"); - testCurve("brainpoolp160r1"); // TeleTrusT + testCurve("brainpoolP160r1"); // TeleTrusT for (Enumeration en = X962NamedCurves.getNames(); en.hasMoreElements();) { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/NetscapeCertRequestTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/NetscapeCertRequestTest.java index d670f54b..076dfc35 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/NetscapeCertRequestTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/NetscapeCertRequestTest.java @@ -60,7 +60,7 @@ public class NetscapeCertRequestTest //now try to generate one KeyPairGenerator kpg = - KeyPairGenerator.getInstance (nscr.getKeyAlgorithm().getObjectId ().getId(), "BC"); + KeyPairGenerator.getInstance (nscr.getKeyAlgorithm().getAlgorithm().getId(), "BC"); kpg.initialize (1024); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/OCBTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/OCBTest.java index c693ce8e..668ff613 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/OCBTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/OCBTest.java @@ -29,7 +29,7 @@ public class OCBTest private void checkRegistrations() throws Exception { - String[] ciphers = new String[] { "AES", "NOEKEON", "Twofish", "CAST6", "SEED", "Serpent", "RC6", "CAMELLIA" }; + String[] ciphers = new String[] { "AES", "NOEKEON", "Twofish", "CAST6", "SEED", "Tnepres", "Serpent", "RC6", "CAMELLIA" }; String[] cipherText = new String[] { "BEA5E8798DBE7110031C144DA0B2612213CC8B747807121A4CBB3E4BD6B456AF", @@ -38,6 +38,7 @@ public class OCBTest "5b9b738b2ac7000b33b89dd4eec18dd853f4f7c1d9e17b565405f17a0a8c8b63", "fcdbcee69d02c69858ed4569f78b81920b3027cdb7f1f154634aa5ace9e6ba29", "4f7154cb34558940e85db7d3e96ac6c9cb0d9c1b00b18e82e15d1be83deef9df", + "3dd3477801e71807ea1f1f690d8428ed6b1002831428a64f88c36b6d5610022f", "23f3e450c4c7199563a0ed601a5c60d75eb88db2a0d090ae5e84d98438a146aa", "ac13ce9db4af148e910a813fc728e5785e23b1bf1d04a961a3f95f356b9417ab" }; diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PBETest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PBETest.java index d5781f4c..939dd12f 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PBETest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PBETest.java @@ -25,6 +25,8 @@ import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.jcajce.PKCS12KeyWithParameters; +import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; @@ -600,6 +602,8 @@ public class PBETest openSSLTests[i].perform(); } + testPKCS12Interop(); + testPBEHMac("PBEWithHMacSHA1", hMac1); testPBEHMac("PBEWithHMacRIPEMD160", hMac2); @@ -612,6 +616,37 @@ public class PBETest checkPBE("PBKDF2WithHmacSHA1", true, "f14687fc31a66e2f7cc01d0a65f687961bd27e20", "6f6579193d6433a3e4600b243bb390674f04a615"); } + private void testPKCS12Interop() + throws Exception + { + final String algorithm = "PBEWithSHA256And192BitAES-CBC-BC"; + + final PBEKeySpec keySpec = new PBEKeySpec("foo123".toCharArray(), Hex.decode("01020304050607080910"), 1024); + final SecretKeyFactory fact = SecretKeyFactory.getInstance(algorithm, "BC"); + + BCPBEKey bcpbeKey = (BCPBEKey)fact.generateSecret(keySpec); + + Cipher c1 = Cipher.getInstance(algorithm, "BC"); + + c1.init(Cipher.ENCRYPT_MODE, new PKCS12KeyWithParameters("foo123".toCharArray(), Hex.decode("01020304050607080910"), 1024)); + + Cipher c2 = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); + + c2.init(Cipher.DECRYPT_MODE, new SecretKeySpec(bcpbeKey.getEncoded(), "AES"), new IvParameterSpec(((ParametersWithIV)bcpbeKey.getParam()).getIV())); + + if (!Arrays.areEqual(Hex.decode("deadbeef"), c2.doFinal(c1.doFinal(Hex.decode("deadbeef"))))) + { + fail("new key failed"); + } + + c1.init(Cipher.ENCRYPT_MODE, bcpbeKey); + + if (!Arrays.areEqual(Hex.decode("deadbeef"), c2.doFinal(c1.doFinal(Hex.decode("deadbeef"))))) + { + fail("old key failed"); + } + } + private void checkPBE(String baseAlg, boolean defIsUTF8, String utf8, String eightBit) throws Exception { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKCS10CertRequestTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKCS10CertRequestTest.java index 65ed2912..527e5ab5 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKCS10CertRequestTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKCS10CertRequestTest.java @@ -197,7 +197,7 @@ public class PKCS10CertRequestTest fail("Failed verify check EC uncompressed encoded."); } - if (!req.getSignatureAlgorithm().getObjectId().equals(algOid)) + if (!req.getSignatureAlgorithm().getAlgorithm().equals(algOid)) { fail("ECDSA oid incorrect."); } @@ -282,7 +282,7 @@ public class PKCS10CertRequestTest fail("Failed verify check EC uncompressed encoded."); } - if (!req.getSignatureAlgorithm().getObjectId().equals(algOid)) + if (!req.getSignatureAlgorithm().getAlgorithm().equals(algOid)) { fail("ECDSA oid incorrect."); } @@ -332,7 +332,7 @@ public class PKCS10CertRequestTest fail("Failed verify check EC encoded."); } - if (!req.getSignatureAlgorithm().getObjectId().equals(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001)) + if (!req.getSignatureAlgorithm().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001)) { fail("ECGOST oid incorrect."); } @@ -389,7 +389,7 @@ public class PKCS10CertRequestTest fail("Failed verify check PSS encoded."); } - if (!req.getSignatureAlgorithm().getObjectId().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) + if (!req.getSignatureAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) { fail("PSS oid incorrect."); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKCS12StoreTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKCS12StoreTest.java index 1faa65dc..0a515e6d 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKCS12StoreTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKCS12StoreTest.java @@ -17,10 +17,7 @@ import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; -import java.util.Date; import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; @@ -35,9 +32,11 @@ import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Pfx; import org.bouncycastle.asn1.pkcs.SafeBag; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.X500NameBuilder; +import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.jcajce.PKCS12StoreParameter; import org.bouncycastle.jce.PKCS12Util; -import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.JDKPKCS12StoreParameter; @@ -45,7 +44,6 @@ import org.bouncycastle.jce.provider.X509CertificateObject; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; -import org.bouncycastle.x509.X509V3CertificateGenerator; /** * Exercise the various key stores, making sure we at least get back what we put in! @@ -470,6 +468,86 @@ public class PKCS12StoreTest + "CgYGKoUDAgIJBQAEIJbGZorQsNM63+xozwEI561cTFVCbyHAEEpkvF3eijT8" + "BAgY5sDtkrVeBQICCAA="); + byte[] certChainCycle = Base64.decode( + "MIIKEAIBAzCCCcoGCSqGSIb3DQEHAaCCCbsEggm3MIIJszCCAyAGCSqGSIb3" + + "DQEHAaCCAxEEggMNMIIDCTCCAwUGCyqGSIb3DQEMCgECoIICsjCCAq4wKAYK" + + "KoZIhvcNAQwBAzAaBBQesw38x26DXisTDrMMSoAanDOAQgICBAAEggKAja8F" + + "U82RAAxhc36SWNXgWGV4CDSbDLFjlJuuXLTelz77KcX4dqPOQdKakm3OVl96" + + "cbp6mWNSOoo0F8bh/Qu51vayt7hT5NIuI8jJ/Q1FYUffMKRxGt14JwuuTQ8W" + + "5DO3z7422fm/rUu+Nkd6y+Sr0Q3FAE8QH/vNc9aUwusVAihr0AZCdT0/HwxK" + + "AKAXLtMHeTWRpdq3WPSilPEWeeZI9Gk14uKbjEeQIUsa8IujSxTE43XwNRQN" + + "z3Qm4oMxGOZP+DPxuKnj+Ug1OXgX5x+GD2fbwytzss9Isv/Zq8wq0gO3t1Ru" + + "PjpxPt/MH2PxNLe4JJTxg1tIXfNP5ZU1SivcIjGLWWcEu+xADG9uq2eDBOja" + + "mW2ZQ1cInSQw8mKcBbX7aEl0NVadSMfxMZxIw0unmoNEETmScoGr50G4Ha5H" + + "ty1iJLNtI69MUA1c2DsoOqyzlnumTTLwuqsZ/E8rFLfO4sHncMxMRdmCEUjn" + + "N2ZOfRqMrgtSFfBsYQ5YjxJ6CI1DLAJwIJhvx8tZgyGItgiI8pSyG8xsRliI" + + "WPQzocO39zHK0hG6ERGnfJyll62/MlDNl9BqjobswPu97BV9nMtPIl3yVBPa" + + "sZxj5LUPYt5nmBlIjIkT5K4cEOIWHKCHPOnAsk8AGW/vrugBcTsyw9nAsRx+" + + "PbmOmmgyo0g2SiPsUX0fGQIWOBVZNxkGP/E4qgDOFS0YavxrdUd2Bgo9q9Sc" + + "hENPI9wjhPztR2UNLtBviWd8utQJ7NhX+6guWEE4AN6Th/xLb/pe9c0sIsEO" + + "41ViDbu4wDGUz6kw3fpXjIu7i6QKniWXEUL9uuchUgZD1GJHQLhD8xgdR6YQ" + + "5SwfIadoWTFAMBkGCSqGSIb3DQEJFDEMHgoAYwB5AGMAbABlMCMGCSqGSIb3" + + "DQEJFTEWBBRoHxEy+w9gB2sa3ykN2Ok7sb3AajCCBosGCSqGSIb3DQEHBqCC" + + "BnwwggZ4AgEAMIIGcQYJKoZIhvcNAQcBMCgGCiqGSIb3DQEMAQYwGgQU40Mi" + + "gMmdUNKyHyGi8miA/3bKZO0CAgQAgIIGOIk1Ouu1n1yoHWGM7YsLpB5fqK6D" + + "LbhUoxsshDSxqemUX3QDJQVmPC9wQOUp1BUapkfB3uxsM15uUG/EUAPlF3iW" + + "0MKDpmcKTC8y1WzMtgZBmmXwRUbguH2gmn4nd6lI2SkLWQg5boQ47aHjZLO2" + + "MZsH1b/DUoT4m6fSrgsMnIVh03z1Gs2XO+Ky3qXqQJM9T3VtCfmeIJBIM2eP" + + "YqvWfnvoGZZZA+pmqVUSMu6q0U7cDA5CD9zhZ87tZvaJeQ198fVIKpMUHBdf" + + "WRGY/opZh4YTfqn+ZiiysEa9jjjx4hSkxS2XGkyUfwPEx4/1E2AdIBfi3KKW" + + "BSyx8hurMyf89YsjxqJudfCAQI2GdWLDEXwwHMi1mM3wn5NVFzZUqM/u+t2W" + + "f3gJGfykxwECxrn4TmerRJ3znyn7soLPEyy6Pp+JPNLyen3Z8gva5tU7Y2J4" + + "aW6YGbBuQ9iW6QcMA93UtWBMGRAJL1jZ9WDguaTkvH8ffSj90jfu7iTHCm/P" + + "4EEtEV7D4ciyLc5xVyq7gIQnIIViVRifAHyjbazrIFQ2yXYwINAk0yNmDqxu" + + "8W4KNxkhNTGvQP/kkk+oDpSCa7XfxMpny+2BudjEryen2q3skMp3HjU/svHQ" + + "+4Y9kxZ5rVYII9S8TRFmgxiRO7cQCdNEwiZndQVGahjVbLI3Jp3vmQhLg+2l" + + "QF07yT7Q0nxeyhbpDGUEizUyIKzs9Or0DEHbq0StU3YwLgHGLlllARLm0eAO" + + "SVhuxKGATS6GtCb/0jmzV+kX4GrK1Qkmit3Xxt9Lbq9b2v2eSMANqGrGpYyr" + + "ETfJ5Ri/UL0nF7M9+tXrrZam1dEM5nJXR04rXQXjxxIuxsrz5xhvS/I+45RY" + + "VKN9l1yw80wNYJlE3Un/eUxT0szk6XA7eguhB6ULGTZNDUMZdELAtwPcq+E4" + + "4+0oih/XLzo/losH10RZ1bBf58mFVl/SlZ0CDE3x6GnFyH/tyTb6pR3Vre1v" + + "TcBod/rkTyEnkPlFSztbBfCXXIRUcSUcbVXge3Vqn7Orhq1+sb6MPcr88uhU" + + "c9Z6g6oKf1liIhiELpMZ5qG06hTwmMlE8prE0tdReGP/eaS2eCu8MyN70adT" + + "IfW1PAopoZTfDYKxJYdsJUVkUojZUvmJ21sNeNREPaFBbwncHBR/y19afhqE" + + "yyvyzDhDJ1D81TkFUR0OwGk7FvV/5JEQCyJq0wIty9G6mJRbUi2tjCc5WpP7" + + "edDW5PBS/rfJPTDMGLy80LlD+obCTFc0sSaBI+dag02Xmxe31V9c96VPOsFt" + + "GQ532OFwZU52E9zYLQSL8L2sdNlEK+OCvTd1MNVbH6PGBYgxrmoDfNBQlYBh" + + "yX2R9wFClraNUBBV9Dtebb6MSqPW7m8xZWAXCmXkDqR9A9kP6qTMd4X3gSFT" + + "qJaezTWbHH44PTgffpK5A1ZBQj37se82QWtBKNPU14KEVvXcI+uuM/TmoAJY" + + "0hqMeXK/1JfzhxTuJsJl+c45LuGjq9dLY9tgTSqMLeKOqal7sLH1AVs4BCCA" + + "J/sHN5pgOjQNLZ1Zup5mZHXR/ynIhKnpYDADOfnAXLizn/UZZFs5huYJYQEQ" + + "K7zcDuzPuxcmFVqUa4AyL9Ul1N42rBx3VsKZ+pvcBTQU5mWsaYwPFox4wLx0" + + "HITx7v7cFYsqki7IHfgnvpJlIS8hrvqqXHl75b61T7ZfJMJNQjhf29//OZ36" + + "QU4mj7lXwudAe+qAJbn1De5B54dQhtLA7B6sX7/7Sy6xP42QJqXhlWngbhF1" + + "IsrgZZrFPJ7zeaKnjOfrLWr8bs1nthHNNoL4cqlPuYtliUGy5zxj9bpQH8xj" + + "oh8+PjTOT4H57IvUN/US/6R0awy8WafJ211diVjbU2IbjS/P+xa6Xlbaql4Z" + + "KlvXRmoMZNl6xPbJg4x6t2anadNmuS7TXHqfTpp+UxeSsr1phyPmxQZPujZY" + + "BADnjfNhTRi7esePheR/DPaPLwjllhetm+U7s7EZzMCdEcd5RB/jiceqRQ5b" + + "xoqSyvIW1ZcdTzRQEAFAhnMWRdVT0O0KYDATiSVqcBr0b70dIQ0lZvYk/TUy" + + "FdYhRXqC8Gzh8xQZPr3CBGoB02pWpp0Hbb5bHtpf3VnfsEmfwBtRPaEUMD0w" + + "ITAJBgUrDgMCGgUABBSsUQPThQeWi8r3oQZ22tcQW2dDqgQUSOpRzALP2lIV" + + "GOtPKKbIhe5YCbkCAgQA"); + + byte[] gostOpenSSLIntegerDPfx = Base64.decode( + "MIIC/wIBAzCCAsUGCSqGSIb3DQEHAaCCArYEggKyMIICrjCCAc8GCSqGSIb3" + + "DQEHBqCCAcAwggG8AgEAMIIBtQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYw" + + "DgQIb1OLAOp7o6ACAggAgIIBiFSfDqzkF2Lv9arM6fdxKrixa9Zu8sGkrsbN" + + "1mYEPYRRJFyfTHB2cOn4yl2I6Ldo9m9GKtnTGGYugMTAFLdBNe0f7X0c4fjr" + + "norM2ODUDfzuqI0a54DLwixvV4U9Q0qakLKQJDAHnCSsWu7N8tRktpYt9oIZ" + + "3sVJ9r01+yxBrDOapAqT3UtaFILSiUU94Zdyehu9hmL3cq33s7Y+orfESC8A" + + "O7OYYks7c6sEjNsvUHag2bC3GClzEapiboIs2F2vb12NoiQ0skU3dbO7Jr1T" + + "P6qkjBYFvG31c3vG8pNxJ7iwJr5+FonJ6uVg3y8EmYCROD5Eyd0MeGaa+eBr" + + "z/CPFaaM50NT6RAL3CTmfqOEzOlXE2qyKZiPD65TxowbjYOmDh8Tb/mfOQUK" + + "hx8Tgzttk0CHHHZmUQkMm0RXDj/n07JaeGuQJQ1pK/3Wg7ejfGxj7eFgzmPU" + + "jOhIAAe/fwOkxUC8quv/+db/L+EeSQBSEyacU5MliXwOPVytMUOP4pFMtonw" + + "C6NzBU5JMIHYBgkqhkiG9w0BBwGggcoEgccwgcQwgcEGCyqGSIb3DQEMCgEC" + + "oHIwcDAcBgoqhkiG9w0BDAEDMA4ECF6BMzmkD7DbAgIIAARQlev2YN09882U" + + "niwvu9nMIgS3hmjSlqlpkf5aYQLosSy5eaOWCq0Vskqgv5i+77vKyQYcKOH0" + + "VnQYu98kWUgZy4fNfesufL+m3d29LX/JGdoxPjAXBgkqhkiG9w0BCRQxCh4I" + + "AHQAZQBzAHQwIwYJKoZIhvcNAQkVMRYEFIaC9GvZM/XUGW4U50bkjCfsTrW8" + + "MDEwITAJBgUrDgMCGgUABBT3iAwuHw7KQXrl09gBkHaUVbOoBAQIIm90qua1" + + "2i4CAggA"); + /** * we generate a self signed certificate for the sake of testing - RSA */ @@ -483,47 +561,23 @@ public class PKCS12StoreTest // // distinguished name table. // - Hashtable issuerAttrs = new Hashtable(); - - issuerAttrs.put(X509Principal.C, "AU"); - issuerAttrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); - issuerAttrs.put(X509Principal.L, "Melbourne"); - issuerAttrs.put(X509Principal.ST, "Victoria"); - issuerAttrs.put(X509Principal.EmailAddress, issuerEmail); - - Hashtable subjectAttrs = new Hashtable(); + X500NameBuilder issuerBldr = new X500NameBuilder(); - subjectAttrs.put(X509Principal.C, "AU"); - subjectAttrs.put(X509Principal.O, "The Legion of the Bouncy Castle"); - subjectAttrs.put(X509Principal.L, "Melbourne"); - subjectAttrs.put(X509Principal.ST, "Victoria"); - subjectAttrs.put(X509Principal.EmailAddress, subjectEmail); + issuerBldr.addRDN(BCStyle.C, "AU"); + issuerBldr.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); + issuerBldr.addRDN(BCStyle.L, "Melbourne"); + issuerBldr.addRDN(BCStyle.ST, "Victoria"); + issuerBldr.addRDN(BCStyle.EmailAddress, issuerEmail); - Vector order = new Vector(); - order.add(X509Principal.C); - order.add(X509Principal.O); - order.add(X509Principal.L); - order.add(X509Principal.ST); - order.add(X509Principal.EmailAddress); + X500NameBuilder subjectBldr = new X500NameBuilder(); - // - // extensions - // + subjectBldr.addRDN(BCStyle.C, "AU"); + subjectBldr.addRDN(BCStyle.O, "The Legion of the Bouncy Castle"); + subjectBldr.addRDN(BCStyle.L, "Melbourne"); + subjectBldr.addRDN(BCStyle.ST, "Victoria"); + subjectBldr.addRDN(BCStyle.EmailAddress, subjectEmail); - // - // create the certificate - version 3 - // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.setSerialNumber(BigInteger.valueOf(1)); - certGen.setIssuerDN(new X509Principal(order, issuerAttrs)); - certGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); - certGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30))); - certGen.setSubjectDN(new X509Principal(order, subjectAttrs)); - certGen.setPublicKey(pubKey); - certGen.setSignatureAlgorithm("MD5WithRSAEncryption"); - - return certGen.generate(privKey); + return TestUtils.createCert(issuerBldr.build(), privKey, subjectBldr.build(), "SHA1withRSA", null, pubKey); } private void testGOSTStore() @@ -556,6 +610,29 @@ public class PKCS12StoreTest { fail("key test failed in GOST store"); } + + KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); + + ks.load(new ByteArrayInputStream(gostOpenSSLIntegerDPfx), "password".toCharArray()); + + PrivateKey key = (PrivateKey)ks.getKey("test", "password".toCharArray()); + + X509Certificate cert = (X509Certificate)ks.getCertificate("test"); + + sig.initSign(key); + + sig.update(data); + + signature = sig.sign(); + + sig.initVerify(cert.getPublicKey()); + + sig.update(data); + + if (!sig.verify(signature)) + { + fail("key test failed in 2nd GOST store"); + } } public void testPKCS12Store() @@ -1175,6 +1252,124 @@ public class PKCS12StoreTest } } + private void testChainCycle() + throws Exception + { + KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); + + // initialize key store + keyStore.load(new ByteArrayInputStream(certChainCycle), "test".toCharArray()); + + keyStore.getEntry("cycle", new KeyStore.PasswordProtection("test".toCharArray())); + } + + private void testOrphanedCertCleanup() + throws Exception + { + KeyPair kp1 = TestUtils.generateRSAKeyPair(); + KeyPair kp1ca = TestUtils.generateRSAKeyPair(); + KeyPair kp1ee = TestUtils.generateRSAKeyPair(); + + X509Certificate kp1Root = TestUtils.generateRootCert(kp1, new X500Name("CN=KP1 ROOT")); + X509Certificate kp1CA = TestUtils.generateIntermediateCert(kp1ca.getPublic(), new X500Name("CN=KP1 CA"), kp1.getPrivate(), kp1Root); + X509Certificate kp1EE = TestUtils.generateEndEntityCert(kp1ee.getPublic(), new X500Name("CN=KP1 EE"), kp1ca.getPrivate(), kp1CA); + + Certificate[] kp1Chain = new Certificate[] { kp1EE, kp1CA, kp1Root }; + + KeyPair kp2 = TestUtils.generateRSAKeyPair(); + KeyPair kp2ca = TestUtils.generateRSAKeyPair(); + KeyPair kp2ee = TestUtils.generateRSAKeyPair(); + + X509Certificate kp2Root = TestUtils.generateRootCert(kp2, new X500Name("CN=KP2 ROOT")); + X509Certificate kp2CA = TestUtils.generateIntermediateCert(kp2ca.getPublic(), new X500Name("CN=KP2 CA"), kp2.getPrivate(), kp1Root); + X509Certificate kp2EE = TestUtils.generateEndEntityCert(kp2ee.getPublic(), new X500Name("CN=KP2 EE"), kp2ca.getPrivate(), kp1CA); + + Certificate[] kp2Chain = new Certificate[] { kp2EE, kp2CA, kp2Root }; + + KeyPair kp3 = TestUtils.generateRSAKeyPair(); + X509Certificate kp3Root = TestUtils.generateRootCert(kp3, new X500Name("CN=KP3 ROOT")); + + KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); + + keyStore.load(null, null); + + keyStore.setKeyEntry("kp1", kp1ee.getPrivate(), null, kp1Chain); + keyStore.setCertificateEntry("kp1root", kp1Root); + keyStore.setKeyEntry("kp2", kp1ee.getPrivate(), null, kp2Chain); + + keyStore.setCertificateEntry("kp3root", kp3Root); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + keyStore.store(bOut, "fred".toCharArray()); + + byte[] baseData = bOut.toByteArray(); + + KeyStore ks1 = KeyStore.getInstance("PKCS12", "BC"); + + ks1.load(new ByteArrayInputStream(baseData), "fred".toCharArray()); + + if (!ks1.containsAlias("kp1") || !ks1.isKeyEntry("kp1") || ks1.getCertificateChain("kp1").length != 3) + { + fail("kp1 missing in ks1"); + } + + ks1.deleteEntry("kp1"); + + ByteArrayOutputStream bOut1 = new ByteArrayOutputStream(); + + ks1.store(bOut1, "fred".toCharArray()); + + KeyStore ks2 = KeyStore.getInstance("PKCS12", "BC"); + + ks2.load(new ByteArrayInputStream(bOut1.toByteArray()), "fred".toCharArray()); + + if (!ks2.containsAlias("kp2") || !ks2.isKeyEntry("kp2") || ks2.getCertificateChain("kp2").length != 3) + { + fail("kp2 missing in ks2"); + } + + if (!ks2.containsAlias("kp1root") || !ks2.isCertificateEntry("kp1root")) + { + fail("kp1root missing in ks2"); + } + + if (!ks2.containsAlias("kp3root") || !ks2.isCertificateEntry("kp3root")) + { + fail("kp3root missing in ks2"); + } + + if (ks2.size() != 3) + { + fail("ks2 wrong size"); + } + + ks2.deleteEntry("kp2"); + + ByteArrayOutputStream bOut2 = new ByteArrayOutputStream(); + + ks2.store(bOut2, "fred".toCharArray()); + + KeyStore ks3 = KeyStore.getInstance("PKCS12", "BC"); + + ks3.load(new ByteArrayInputStream(bOut2.toByteArray()), "fred".toCharArray()); + + if (!ks3.containsAlias("kp1root") || !ks3.isCertificateEntry("kp1root")) + { + fail("kp1root missing in ks3"); + } + + if (!ks3.containsAlias("kp3root") || !ks3.isCertificateEntry("kp3root")) + { + fail("kp3root missing in ks3"); + } + + if (ks3.size() != 2) + { + fail("ks3 wrong size"); + } + } + public String getName() { return "PKCS12Store"; @@ -1185,6 +1380,7 @@ public class PKCS12StoreTest { testPKCS12Store(); testGOSTStore(); + testChainCycle(); // converter tests @@ -1215,6 +1411,8 @@ public class PKCS12StoreTest { fail("Failed deep DER conversion test - inner."); } + + testOrphanedCertCleanup(); } public static void main( diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKIXPolicyMappingTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKIXPolicyMappingTest.java index 069a0063..f929a9de 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKIXPolicyMappingTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/PKIXPolicyMappingTest.java @@ -277,7 +277,12 @@ public class PKIXPolicyMappingTest map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); - + + if (!"CertificatePolicies: [Policy information: 2.5.29.32.0]".equals(intPolicies.toString())) + { + fail("1st toString() test"); + } + policies = new ASN1EncodableVector(); policies.add(new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.2"))); endCert = createEndEntityCert(pubKey, intPrivKey, intPubKey, policies); @@ -327,6 +332,11 @@ public class PKIXPolicyMappingTest { new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.3.2.1.48.3")), new PolicyInformation(new ASN1ObjectIdentifier("2.5.29.32.0")) }); + if (!"CertificatePolicies: [Policy information: 2.16.840.1.101.3.2.1.48.3, Policy information: 2.5.29.32.0]".equals(intPolicies.toString())) + { + fail("2nd toString() test"); + } + map = new Hashtable(); map.put("2.16.840.1.101.3.2.1.48.1","2.16.840.1.101.3.2.1.48.2"); intCert = createIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/Poly1305Test.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/Poly1305Test.java index c147c173..7bf0eadc 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/Poly1305Test.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/Poly1305Test.java @@ -23,7 +23,7 @@ public class Poly1305Test extends SimpleTest { private static final byte[] MASTER_KEY = Hex - .decode("95cc0e44d0b79a8856afcae1bec4fe3c01bcb20bfc8b6e03609ddd09f44b060f"); + .decode("95cc0e44d0b79a8856afcae1bec4fe3c01bcb20bfc8b6e03609ddd09f44b060f"); public String getName() { @@ -42,16 +42,17 @@ public class Poly1305Test List missingMacs = new ArrayList(); List missingKeyGens = new ArrayList(); - String[] ciphers = new String[]{"AES", "NOEKEON", "Twofish", "CAST6", "SEED", "Serpent", "RC6", "CAMELLIA"}; + String[] ciphers = new String[]{"AES", "NOEKEON", "Twofish", "CAST6", "SEED", "Serpent", "SM4", "RC6", "CAMELLIA"}; String[] macs = new String[]{ - "4bb5e21dd13001ed5faccfcfdaf8a854", - "6d601be3d5ebbb9972a64ed3223d913d", - "211195296d9afc7b35a1223a79487c87", - "f328857a1b653684e73760c804c55b1d", - "21cd8adb23ca84eb4dbb12780595bf28", - "211195296d9afc7b35a1223a79487c87", - "db86de7b1fcae429753d68b1263d7ca0", - "11918174f33a2f278fb86554da094112"}; + "4bb5e21dd13001ed5faccfcfdaf8a854", + "6d601be3d5ebbb9972a64ed3223d913d", + "211195296d9afc7b35a1223a79487c87", + "f328857a1b653684e73760c804c55b1d", + "21cd8adb23ca84eb4dbb12780595bf28", + "211195296d9afc7b35a1223a79487c87", + "9bb04be6a1c314a9054ae3c94d3c941b", + "db86de7b1fcae429753d68b1263d7ca0", + "11918174f33a2f278fb86554da094112"}; for (int i = 0; i < ciphers.length; i++) { @@ -60,7 +61,8 @@ public class Poly1305Test try { cipher = Cipher.getInstance(cipherName, "BC"); - } catch (Exception e) + } + catch (Exception e) { System.err.println(cipherName + ": " + e.getMessage()); continue; @@ -69,7 +71,8 @@ public class Poly1305Test try { blocksize = cipher.getBlockSize(); - } catch (Exception e) + } + catch (Exception e) { System.err.println(cipherName + ": " + e.getMessage()); continue; @@ -107,7 +110,8 @@ public class Poly1305Test try { Poly1305KeyGenerator.checkKey(key.getEncoded()); - } catch (IllegalArgumentException e) + } + catch (IllegalArgumentException e) { fail("Generated key for algo " + name + " does not match required Poly1305 format."); } @@ -123,19 +127,23 @@ public class Poly1305Test { fail("wrong mac value computed for " + name, macOutput, new String(Hex.encode(bytes))); } - } catch (NoSuchAlgorithmException e) + } + catch (NoSuchAlgorithmException e) { missingMacs.add(name); } - } catch (NoSuchAlgorithmException e) + } + catch (NoSuchAlgorithmException e) { missingKeyGens.add(name); } - } catch (TestFailedException e) + } + catch (TestFailedException e) { throw e; - } catch (Exception e) + } + catch (Exception e) { fail("Unexpected error", e); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/RegressionTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/RegressionTest.java index 2dce85e4..216b954f 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/RegressionTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/RegressionTest.java @@ -29,6 +29,7 @@ public class RegressionTest new ImplicitlyCaTest(), new ECNRTest(), new ECIESTest(), + new ECIESVectorTest(), new ECDSA5Test(), new GOST3410Test(), new ElGamalTest(), @@ -72,11 +73,12 @@ public class RegressionTest new CRL5Test(), new Poly1305Test(), new SipHashTest(), - new SHA3Test(), + new KeccakTest(), new SkeinTest(), new Shacal2Test(), new DetDSATest(), - new ThreefishTest() + new ThreefishTest(), + new SM4Test() }; public static void main( diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/SHA3Test.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/SHA3Test.java deleted file mode 100644 index 89b85ae4..00000000 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/SHA3Test.java +++ /dev/null @@ -1,136 +0,0 @@ -package org.bouncycastle.jce.provider.test; - -import java.security.MessageDigest; -import java.security.Security; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.util.encoders.Hex; -import org.bouncycastle.util.test.SimpleTest; - -public class SHA3Test - extends SimpleTest -{ - final static String provider = "BC"; - - static private byte[] nullMsg = new byte[0]; - - static private String[][] nullVectors = - { - { "SHA3-224", "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd" }, - { "SHA3-256", "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" }, - { "SHA3-384", "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff" }, - { "SHA3-512", "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e" }, - }; - - static private byte[] shortMsg = Hex.decode("54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f67"); - - static private String[][] shortVectors = - { - { "SHA3-224", "310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe" }, - { "SHA3-256", "4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15" }, - { "SHA3-384", "283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3" }, - { "SHA3-512", "d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609" }, - }; - - public String getName() - { - return "SHA3"; - } - - void test(String algorithm, byte[] message, String expected) - throws Exception - { - MessageDigest digest = MessageDigest.getInstance(algorithm, provider); - - byte[] result = digest.digest(message); - byte[] result2 = digest.digest(message); - - // test zero results valid - if (!MessageDigest.isEqual(result, Hex.decode(expected))) - { - fail("null result not equal for " + algorithm); - } - - // test one digest the same message with the same instance - if (!MessageDigest.isEqual(result, result2)) - { - fail("Result object 1 not equal"); - } - - if (!MessageDigest.isEqual(result, Hex.decode(expected))) - { - fail("Result object 1 not equal"); - } - - // test two, single byte updates - for (int i = 0; i < message.length; i++) - { - digest.update(message[i]); - } - result2 = digest.digest(); - - if (!MessageDigest.isEqual(result, result2)) - { - fail("Result object 2 not equal"); - } - - // test three, two half updates - digest.update(message, 0, message.length/2); - digest.update(message, message.length/2, message.length-message.length/2); - result2 = digest.digest(); - - if (!MessageDigest.isEqual(result, result2)) - { - fail("Result object 3 not equal"); - } - - // test four, clone test - digest.update(message, 0, message.length/2); - MessageDigest d = (MessageDigest)digest.clone(); - digest.update(message, message.length/2, message.length-message.length/2); - result2 = digest.digest(); - - if (!MessageDigest.isEqual(result, result2)) - { - fail("Result object 4(a) not equal"); - } - - d.update(message, message.length/2, message.length-message.length/2); - result2 = d.digest(); - - if (!MessageDigest.isEqual(result, result2)) - { - fail("Result object 4(b) not equal"); - } - - // test five, check reset() method - digest.update(message, 0, message.length/2); - digest.reset(); - digest.update(message, 0, message.length/2); - digest.update(message, message.length/2, message.length-message.length/2); - result2 = digest.digest(); - - if (!MessageDigest.isEqual(result, result2)) - { - fail("Result object 5 not equal"); - } - - } - - public void performTest() - throws Exception - { - for (int i = 0; i != nullVectors.length; i++) - { - test(nullVectors[i][0], nullMsg, nullVectors[i][1]); - test(shortVectors[i][0], shortMsg, shortVectors[i][1]); - } - } - - public static void main(String[] args) - { - Security.addProvider(new BouncyCastleProvider()); - - runTest(new SHA3Test()); - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/Shacal2Test.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/Shacal2Test.java index 14157b12..511d72db 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/Shacal2Test.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/Shacal2Test.java @@ -45,42 +45,45 @@ public class Shacal2Test private static final int KEY_SIZE_BITS = 512; - private static final byte[] TEST_BYTES = new byte[ 1536 ]; + private static final byte[] TEST_BYTES = new byte[1536]; - private static final char[] TEST_PASSWORD = new char[ 1536 ]; + private static final char[] TEST_PASSWORD = new char[1536]; - static + static + { + new SecureRandom().nextBytes(TEST_BYTES); + int total = TEST_PASSWORD.length; + for (char c = 'A'; c <= 'Z' && total > 0; TEST_PASSWORD[TEST_PASSWORD.length - total] = c, c++, total--) { - new SecureRandom().nextBytes( TEST_BYTES ); - int total = TEST_PASSWORD.length; - for ( char c = 'A'; c <= 'Z' && total > 0; TEST_PASSWORD[TEST_PASSWORD.length - total] = c, c++, total-- ); + ; } + } - private void blockTest() - throws Exception - { - final byte[] salt = new byte[KEY_SIZE_BITS / 8]; - new SecureRandom().nextBytes(salt); + private void blockTest() + throws Exception + { + final byte[] salt = new byte[KEY_SIZE_BITS / 8]; + new SecureRandom().nextBytes(salt); - final KeySpec keySpec = new PBEKeySpec(TEST_PASSWORD, salt, 262144, KEY_SIZE_BITS); - final SecretKey secretKey = new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2", "BC"). - generateSecret(keySpec).getEncoded(), "Shacal2"); + final KeySpec keySpec = new PBEKeySpec(TEST_PASSWORD, salt, 262144, KEY_SIZE_BITS); + final SecretKey secretKey = new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2", "BC"). + generateSecret(keySpec).getEncoded(), "Shacal2"); - final Cipher cipher = Cipher.getInstance("Shacal2/CBC/ISO10126Padding", "BC"); - cipher.init(Cipher.ENCRYPT_MODE, secretKey); + final Cipher cipher = Cipher.getInstance("Shacal2/CBC/ISO10126Padding", "BC"); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); - final byte[] iv = cipher.getIV(); - final byte[] ciphertext = cipher.doFinal(TEST_BYTES); + final byte[] iv = cipher.getIV(); + final byte[] ciphertext = cipher.doFinal(TEST_BYTES); - cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); + cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); - final byte[] cleartext = cipher.doFinal(ciphertext); + final byte[] cleartext = cipher.doFinal(ciphertext); - if (!Arrays.areEqual(TEST_BYTES, cleartext)) - { - fail("Invalid cleartext."); - } + if (!Arrays.areEqual(TEST_BYTES, cleartext)) + { + fail("Invalid cleartext."); } + } public void testECB( int strength, diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/SigTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/SigTest.java index 2c2f5128..af9a8f5e 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/SigTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/SigTest.java @@ -14,6 +14,8 @@ import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.SignatureException; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; @@ -307,6 +309,25 @@ public class SigTest fail("SHA1/ISO verification failed"); } + trySig("SHA512(224)WithRSA", data, signingKey, verifyKey); + trySig("SHA512(256)WithRSA", data, signingKey, verifyKey); + + trySig("SHA1WithRSAAndMGF1", data, signingKey, verifyKey); + trySig("SHA224WithRSAAndMGF1", data, signingKey, verifyKey); + trySig("SHA256WithRSAAndMGF1", data, signingKey, verifyKey); + //trySig("SHA384WithRSAAndMGF1", data, signingKey, verifyKey); + //trySig("SHA512WithRSAAndMGF1", data, signingKey, verifyKey); + trySig("SHA512(224)WithRSAAndMGF1", data, signingKey, verifyKey); + trySig("SHA512(256)WithRSAAndMGF1", data, signingKey, verifyKey); + + trySig("SHA1WithRSA/ISO9796-2", data, signingKey, verifyKey); + trySig("SHA224WithRSA/ISO9796-2", data, signingKey, verifyKey); + trySig("SHA256withRSA/ISO9796-2", data, signingKey, verifyKey); + trySig("SHA384WithRSA/ISO9796-2", data, signingKey, verifyKey); + trySig("SHA512WithRSA/ISO9796-2", data, signingKey, verifyKey); + trySig("SHA512(224)WithRSA/ISO9796-2", data, signingKey, verifyKey); + trySig("SHA512(256)WithRSA/ISO9796-2", data, signingKey, verifyKey); + trySig("WhirlpoolWithRSA/ISO9796-2", data, signingKey, verifyKey); trySig("RIPEMD160WithRSA/ISO9796-2", data, signingKey, verifyKey); trySig("RIPEMD128WithRSA/X9.31", data, signingKey, verifyKey); @@ -316,8 +337,19 @@ public class SigTest trySig("SHA256withRSA/X9.31", data, signingKey, verifyKey); trySig("SHA384WithRSA/X9.31", data, signingKey, verifyKey); trySig("SHA512WithRSA/X9.31", data, signingKey, verifyKey); + trySig("SHA512(224)WithRSA/X9.31", data, signingKey, verifyKey); + trySig("SHA512(256)WithRSA/X9.31", data, signingKey, verifyKey); trySig("WhirlpoolWithRSA/X9.31", data, signingKey, verifyKey); + KeyFactory keyFact = KeyFactory.getInstance("RSA", "BC"); + + BigInteger mod = new BigInteger("f6b18dfb2eb944d8df7e8b8077f8857ffa7a4192ea10cdd87edf7839872d50029ed86fc17c8b90bef725517b7f2f6403559957d0d4220ed8283ebde769d9f7024b84654d7b398d64b582520e6b7a7e07c1aea5eedbfac0474ac239a5ceb6e5e7", 16); + + RSAPublicKey vKey = (RSAPublicKey)keyFact.generatePublic(new RSAPublicKeySpec(mod, new BigInteger("10001", 16))); + RSAPrivateKey sKey = (RSAPrivateKey)keyFact.generatePrivate(new RSAPrivateKeySpec(mod, new BigInteger("6af2b6d6fa7e9f76560e0a747b8e66720129175c95d50b289c784d2ac38bc5701d653fade64cab47dee572d9d35dbc414be785166afe59a4dd3e7b5a19e756ed83c56319ece6a3a8a4e8d982526361bb133d49a27c4299a5d717189ebd9159a1", 16))); + + trySig("SHA1WithRSA/X9.31", data, sKey, vKey); + shouldPassSignatureX931Test1(); shouldPassSignatureX931Test2(); shouldPassSignatureX931Test3(); @@ -325,7 +357,7 @@ public class SigTest // // standard vector test - B.1.3 RIPEMD160, implicit. // - BigInteger mod = new BigInteger("ffffffff78f6c55506c59785e871211ee120b0b5dd644aa796d82413a47b24573f1be5745b5cd9950f6b389b52350d4e01e90009669a8720bf265a2865994190a661dea3c7828e2e7ca1b19651adc2d5", 16); + mod = new BigInteger("ffffffff78f6c55506c59785e871211ee120b0b5dd644aa796d82413a47b24573f1be5745b5cd9950f6b389b52350d4e01e90009669a8720bf265a2865994190a661dea3c7828e2e7ca1b19651adc2d5", 16); BigInteger pub = new BigInteger("03", 16); BigInteger pri = new BigInteger("2aaaaaaa942920e38120ee965168302fd0301d73a4e60c7143ceb0adf0bf30b9352f50e8b9e4ceedd65343b2179005b2f099915e4b0c37e41314bb0821ad8330d23cba7f589e0f129b04c46b67dfce9d", 16); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/TestUtils.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/TestUtils.java index 4d57efe0..768c926b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/TestUtils.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/TestUtils.java @@ -1,5 +1,6 @@ package org.bouncycastle.jce.provider.test; +import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyPair; @@ -10,30 +11,52 @@ import java.security.Principal; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; +import java.security.Signature; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateFactory; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import java.util.Set; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLNumber; import org.bouncycastle.asn1.x509.CRLReason; +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.Extensions; +import org.bouncycastle.asn1.x509.ExtensionsGenerator; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x509.TBSCertificate; +import org.bouncycastle.asn1.x509.Time; +import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator; +import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.jce.PrincipalUtil; -import org.bouncycastle.jce.X509Principal; -import org.bouncycastle.x509.X509V1CertificateGenerator; import org.bouncycastle.x509.X509V2CRLGenerator; -import org.bouncycastle.x509.X509V3CertificateGenerator; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; /** @@ -41,98 +64,191 @@ import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; */ class TestUtils { + private static AtomicLong serialNumber = new AtomicLong(System.currentTimeMillis()); + private static Map algIds = new HashMap(); + + static + { + algIds.put("GOST3411withGOST3410", new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94)); + algIds.put("SHA1withRSA", new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption, DERNull.INSTANCE)); + algIds.put("SHA256withRSA", new AlgorithmIdentifier(PKCSObjectIdentifiers.sha256WithRSAEncryption, DERNull.INSTANCE)); + } + + public static X509Certificate createSelfSignedCert(String dn, String sigName, KeyPair keyPair) + throws Exception + { + return createSelfSignedCert(new X500Name(dn), sigName, keyPair); + } + + public static X509Certificate createSelfSignedCert(X500Name dn, String sigName, KeyPair keyPair) + throws Exception + { + V1TBSCertificateGenerator certGen = new V1TBSCertificateGenerator(); + + long time = System.currentTimeMillis(); + + certGen.setSerialNumber(new ASN1Integer(serialNumber.getAndIncrement())); + certGen.setIssuer(dn); + certGen.setSubject(dn); + certGen.setStartDate(new Time(new Date(time - 5000))); + certGen.setEndDate(new Time(new Date(time + 30 * 60 * 1000))); + certGen.setSignature((AlgorithmIdentifier)algIds.get(sigName)); + certGen.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded())); + + Signature sig = Signature.getInstance(sigName, "BC"); + + sig.initSign(keyPair.getPrivate()); + + sig.update(certGen.generateTBSCertificate().getEncoded(ASN1Encoding.DER)); + + TBSCertificate tbsCert = certGen.generateTBSCertificate(); + + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(tbsCert); + v.add((AlgorithmIdentifier)algIds.get(sigName)); + v.add(new DERBitString(sig.sign())); + + return (X509Certificate)CertificateFactory.getInstance("X.509", "BC").generateCertificate(new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER))); + } + + public static X509Certificate createCert(X500Name signerName, PrivateKey signerKey, String dn, String sigName, Extensions extensions, PublicKey pubKey) + throws Exception + { + return createCert(signerName, signerKey, new X500Name(dn), sigName, extensions, pubKey); + } + + public static X509Certificate createCert(X500Name signerName, PrivateKey signerKey, X500Name dn, String sigName, Extensions extensions, PublicKey pubKey) + throws Exception + { + V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); + + long time = System.currentTimeMillis(); + + certGen.setSerialNumber(new ASN1Integer(serialNumber.getAndIncrement())); + certGen.setIssuer(signerName); + certGen.setSubject(dn); + certGen.setStartDate(new Time(new Date(time - 5000))); + certGen.setEndDate(new Time(new Date(time + 30 * 60 * 1000))); + certGen.setSignature((AlgorithmIdentifier)algIds.get(sigName)); + certGen.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded())); + certGen.setExtensions(extensions); + + Signature sig = Signature.getInstance(sigName, "BC"); + + sig.initSign(signerKey); + + sig.update(certGen.generateTBSCertificate().getEncoded(ASN1Encoding.DER)); + + TBSCertificate tbsCert = certGen.generateTBSCertificate(); + + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(tbsCert); + v.add((AlgorithmIdentifier)algIds.get(sigName)); + v.add(new DERBitString(sig.sign())); + + return (X509Certificate)CertificateFactory.getInstance("X.509", "BC").generateCertificate(new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER))); + } + /** * Create a random 1024 bit RSA key pair */ public static KeyPair generateRSAKeyPair() throws Exception { - KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); - + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC"); + kpGen.initialize(1024, new SecureRandom()); - + return kpGen.generateKeyPair(); } - + public static X509Certificate generateRootCert(KeyPair pair) throws Exception { - X509V1CertificateGenerator certGen = new X509V1CertificateGenerator(); - - certGen.setSerialNumber(BigInteger.valueOf(1)); - certGen.setIssuerDN(new X509Principal("CN=Test CA Certificate")); - certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); - certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); - certGen.setSubjectDN(new X509Principal("CN=Test CA Certificate")); - certGen.setPublicKey(pair.getPublic()); - certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); - - return certGen.generate(pair.getPrivate(), "BC"); + return createSelfSignedCert("CN=Test CA Certificate", "SHA256withRSA", pair); + } + + public static X509Certificate generateRootCert(KeyPair pair, X500Name dn) + throws Exception + { + return createSelfSignedCert(dn, "SHA256withRSA", pair); } - + public static X509Certificate generateIntermediateCert(PublicKey intKey, PrivateKey caKey, X509Certificate caCert) throws Exception { - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.setSerialNumber(BigInteger.valueOf(1)); - certGen.setIssuerDN(PrincipalUtil.getSubjectX509Principal(caCert)); - certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); - certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); - certGen.setSubjectDN(new X509Principal("CN=Test Intermediate Certificate")); - certGen.setPublicKey(intKey); - certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); - - certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert)); - certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifier(getDigest(SubjectPublicKeyInfo.getInstance(intKey.getEncoded())))); - certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(0)); - certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign)); - - return certGen.generate(caKey, "BC"); + return generateIntermediateCert( + intKey, new X500Name("CN=Test Intermediate Certificate"), caKey, caCert); + } + + public static X509Certificate generateIntermediateCert(PublicKey intKey, X500Name subject, PrivateKey caKey, X509Certificate caCert) + throws Exception + { + Certificate caCertLw = Certificate.getInstance(caCert.getEncoded()); + + ExtensionsGenerator extGen = new ExtensionsGenerator(); + + extGen.addExtension(Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifier(getDigest(caCertLw.getSubjectPublicKeyInfo()), + new GeneralNames(new GeneralName(caCertLw.getIssuer())), + caCertLw.getSerialNumber().getValue())); + extGen.addExtension(Extension.subjectKeyIdentifier, false, new SubjectKeyIdentifier(getDigest(SubjectPublicKeyInfo.getInstance(intKey.getEncoded())))); + extGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0)); + extGen.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign)); + + return createCert( + caCertLw.getSubject(), + caKey, subject, "SHA256withRSA", extGen.generate(), intKey); + } + + public static X509Certificate generateEndEntityCert(PublicKey intKey, PrivateKey caKey, X509Certificate caCert) + throws Exception + { + return generateEndEntityCert( + intKey, new X500Name("CN=Test End Certificate"), caKey, caCert); } - - public static X509Certificate generateEndEntityCert(PublicKey entityKey, PrivateKey caKey, X509Certificate caCert) + + public static X509Certificate generateEndEntityCert(PublicKey entityKey, X500Name subject, PrivateKey caKey, X509Certificate caCert) throws Exception { - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.setSerialNumber(BigInteger.valueOf(1)); - certGen.setIssuerDN(PrincipalUtil.getSubjectX509Principal(caCert)); - certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000)); - certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000)); - certGen.setSubjectDN(new X509Principal("CN=Test End Certificate")); - certGen.setPublicKey(entityKey); - certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); - - certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert)); - certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifier(getDigest(SubjectPublicKeyInfo.getInstance(entityKey.getEncoded())))); - certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false)); - certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment)); - - return certGen.generate(caKey, "BC"); + Certificate caCertLw = Certificate.getInstance(caCert.getEncoded()); + + ExtensionsGenerator extGen = new ExtensionsGenerator(); + + extGen.addExtension(Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifier(getDigest(caCertLw.getSubjectPublicKeyInfo()), + new GeneralNames(new GeneralName(caCertLw.getIssuer())), + caCertLw.getSerialNumber().getValue())); + extGen.addExtension(Extension.subjectKeyIdentifier, false, new SubjectKeyIdentifier(getDigest(entityKey.getEncoded()))); + extGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0)); + extGen.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign)); + + return createCert( + caCertLw.getSubject(), + caKey, subject, "SHA256withRSA", extGen.generate(), entityKey); } - + public static X509CRL createCRL( - X509Certificate caCert, - PrivateKey caKey, - BigInteger serialNumber) + X509Certificate caCert, + PrivateKey caKey, + BigInteger serialNumber) throws Exception { - X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); - Date now = new Date(); - BigInteger revokedSerialNumber = BigInteger.valueOf(2); - + X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); + Date now = new Date(); + BigInteger revokedSerialNumber = BigInteger.valueOf(2); + crlGen.setIssuerDN(PrincipalUtil.getSubjectX509Principal(caCert)); - + crlGen.setThisUpdate(now); crlGen.setNextUpdate(new Date(now.getTime() + 100000)); crlGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); - + crlGen.addCRLEntry(serialNumber, now, CRLReason.privilegeWithdrawn); - + crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert)); crlGen.addExtension(X509Extensions.CRLNumber, false, new CRLNumber(BigInteger.valueOf(1))); - + return crlGen.generate(caKey, "BC"); } @@ -151,12 +267,14 @@ class TestUtils _exceptionOnEncode = exceptionOnEncode; } - public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException + public void checkValidity() + throws CertificateExpiredException, CertificateNotYetValidException { throw new CertificateNotYetValidException(); } - public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException + public void checkValidity(Date date) + throws CertificateExpiredException, CertificateNotYetValidException { throw new CertificateExpiredException(); } @@ -191,7 +309,8 @@ class TestUtils return null; } - public byte[] getTBSCertificate() throws CertificateEncodingException + public byte[] getTBSCertificate() + throws CertificateEncodingException { throw new CertificateEncodingException(); } @@ -236,22 +355,25 @@ class TestUtils return 0; } - public byte[] getEncoded() throws CertificateEncodingException + public byte[] getEncoded() + throws CertificateEncodingException { if (_exceptionOnEncode) { throw new CertificateEncodingException(); } - + return new byte[0]; } - public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException + public void verify(PublicKey key) + throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { throw new CertificateException(); } - public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException + public void verify(PublicKey key, String sigProvider) + throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { throw new CertificateException(); } @@ -290,12 +412,31 @@ class TestUtils private static byte[] getDigest(SubjectPublicKeyInfo spki) { + return getDigest(spki.getPublicKeyData().getBytes()); + } + + private static byte[] getDigest(byte[] bytes) + { Digest digest = new SHA1Digest(); - byte[] resBuf = new byte[digest.getDigestSize()]; + byte[] resBuf = new byte[digest.getDigestSize()]; - byte[] bytes = spki.getPublicKeyData().getBytes(); digest.update(bytes, 0, bytes.length); digest.doFinal(resBuf, 0); return resBuf; } + + private static class AtomicLong + { + private long value; + + public AtomicLong(long value) + { + this.value = value; + } + + public synchronized long getAndIncrement() + { + return value++; + } + } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java b/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java index c1b5ccc6..36aa595e 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java @@ -1,6 +1,7 @@ package org.bouncycastle.jce.spec; import java.math.BigInteger; +import java.security.spec.ECField; import java.security.spec.ECFieldF2m; import java.security.spec.ECFieldFp; import java.security.spec.ECPoint; @@ -8,6 +9,10 @@ import java.security.spec.EllipticCurve; import org.bouncycastle.math.ec.ECAlgorithms; import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.math.field.FiniteField; +import org.bouncycastle.math.field.Polynomial; +import org.bouncycastle.math.field.PolynomialExtensionField; +import org.bouncycastle.util.Arrays; /** * specification signifying that the curve parameters can also be @@ -22,29 +27,24 @@ public class ECNamedCurveSpec ECCurve curve, byte[] seed) { - if (ECAlgorithms.isFpCurve(curve)) + ECField field = convertField(curve.getField()); + BigInteger a = curve.getA().toBigInteger(), b = curve.getB().toBigInteger(); + return new EllipticCurve(field, a, b, seed); + } + + private static ECField convertField(FiniteField field) + { + if (ECAlgorithms.isFpField(field)) { - return new EllipticCurve(new ECFieldFp(curve.getField().getCharacteristic()), curve.getA().toBigInteger(), curve.getB().toBigInteger(), seed); + return new ECFieldFp(field.getCharacteristic()); } - else + else //if (ECAlgorithms.isF2mField(curveField)) { - ECCurve.F2m curveF2m = (ECCurve.F2m)curve; - int ks[]; - - if (curveF2m.isTrinomial()) - { - ks = new int[] { curveF2m.getK1() }; - - return new EllipticCurve(new ECFieldF2m(curveF2m.getM(), ks), curve.getA().toBigInteger(), curve.getB().toBigInteger(), seed); - } - else - { - ks = new int[] { curveF2m.getK3(), curveF2m.getK2(), curveF2m.getK1() }; - - return new EllipticCurve(new ECFieldF2m(curveF2m.getM(), ks), curve.getA().toBigInteger(), curve.getB().toBigInteger(), seed); - } + Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial(); + int[] exponents = poly.getExponentsPresent(); + int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1)); + return new ECFieldF2m(poly.getDegree(), ks); } - } private static ECPoint convertPoint( diff --git a/bcprov/src/main/java/org/bouncycastle/jce/spec/MQVPrivateKeySpec.java b/bcprov/src/main/java/org/bouncycastle/jce/spec/MQVPrivateKeySpec.java index bdd988d0..d103270b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/spec/MQVPrivateKeySpec.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/spec/MQVPrivateKeySpec.java @@ -9,6 +9,7 @@ import org.bouncycastle.jce.interfaces.MQVPrivateKey; /** * Static/ephemeral private key (pair) for use with ECMQV key agreement * (Optionally provides the ephemeral public key) + * @deprecated use MQVParameterSpec */ public class MQVPrivateKeySpec implements KeySpec, MQVPrivateKey diff --git a/bcprov/src/main/java/org/bouncycastle/jce/spec/MQVPublicKeySpec.java b/bcprov/src/main/java/org/bouncycastle/jce/spec/MQVPublicKeySpec.java index 8b50d05f..afc1f3f0 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/spec/MQVPublicKeySpec.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/spec/MQVPublicKeySpec.java @@ -7,6 +7,7 @@ import org.bouncycastle.jce.interfaces.MQVPublicKey; /** * Static/ephemeral public key pair for use with ECMQV key agreement + * @deprecated use MQVParameterSpec */ public class MQVPublicKeySpec implements KeySpec, MQVPublicKey |