diff options
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/jcajce/provider')
70 files changed, 1223 insertions, 464 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java index 0f7d2029..5b6b8c49 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java @@ -1,5 +1,8 @@ package org.bouncycastle.jcajce.provider.asymmetric; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.jcajce.provider.asymmetric.dh.KeyFactorySpi; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; @@ -36,6 +39,9 @@ public class DH provider.addAlgorithm("Cipher.DHIESwithAES", PREFIX + "IESCipher$IESwithAES"); provider.addAlgorithm("Cipher.DHIESWITHAES", PREFIX + "IESCipher$IESwithAES"); provider.addAlgorithm("Cipher.DHIESWITHDESEDE", PREFIX + "IESCipher$IESwithDESede"); + + registerOid(provider, PKCSObjectIdentifiers.dhKeyAgreement, "DH", new KeyFactorySpi()); + registerOid(provider, X9ObjectIdentifiers.dhpublicnumber, "DH", new KeyFactorySpi()); } } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java index d06e05c5..d7b437cb 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java @@ -1,5 +1,6 @@ package org.bouncycastle.jcajce.provider.asymmetric; +import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers; import org.bouncycastle.asn1.eac.EACObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; @@ -25,6 +26,7 @@ public class EC provider.addAlgorithm("KeyAgreement.ECMQV", PREFIX + "KeyAgreementSpi$MQV"); provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA1KDF"); provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA1KDF"); + provider.addAlgorithm("KeyAgreement.ECDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHwithSHA1KDF"); registerOid(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC", new KeyFactorySpi.EC()); // TODO Should this be an alias for ECDH? @@ -45,6 +47,7 @@ public class EC provider.addAlgorithm("KeyPairGenerator.EC", PREFIX + "KeyPairGeneratorSpi$EC"); provider.addAlgorithm("KeyPairGenerator.ECDSA", PREFIX + "KeyPairGeneratorSpi$ECDSA"); provider.addAlgorithm("KeyPairGenerator.ECDH", PREFIX + "KeyPairGeneratorSpi$ECDH"); + provider.addAlgorithm("KeyPairGenerator.ECDHWITHSHA1KDF", PREFIX + "KeyPairGeneratorSpi$ECDH"); provider.addAlgorithm("KeyPairGenerator.ECDHC", PREFIX + "KeyPairGeneratorSpi$ECDHC"); provider.addAlgorithm("KeyPairGenerator.ECIES", PREFIX + "KeyPairGeneratorSpi$ECDH"); provider.addAlgorithm("KeyPairGenerator.ECMQV", PREFIX + "KeyPairGeneratorSpi$ECMQV"); @@ -54,6 +57,10 @@ public class EC provider.addAlgorithm("Cipher.ECIESWITHAES", PREFIX + "IESCipher$ECIESwithAES"); provider.addAlgorithm("Cipher.ECIESwithDESEDE", PREFIX + "IESCipher$ECIESwithDESede"); provider.addAlgorithm("Cipher.ECIESWITHDESEDE", PREFIX + "IESCipher$ECIESwithDESede"); + provider.addAlgorithm("Cipher.ECIESwithAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC"); + provider.addAlgorithm("Cipher.ECIESWITHAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC"); + provider.addAlgorithm("Cipher.ECIESwithDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC"); + provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC"); provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA"); provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone"); @@ -91,6 +98,13 @@ public class EC addSignatureAlgorithm(provider, "SHA256", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA256", EACObjectIdentifiers.id_TA_ECDSA_SHA_256); addSignatureAlgorithm(provider, "SHA384", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA384", EACObjectIdentifiers.id_TA_ECDSA_SHA_384); addSignatureAlgorithm(provider, "SHA512", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA512", EACObjectIdentifiers.id_TA_ECDSA_SHA_512); + + addSignatureAlgorithm(provider, "SHA1", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA", BSIObjectIdentifiers.ecdsa_plain_SHA1); + addSignatureAlgorithm(provider, "SHA224", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA224", BSIObjectIdentifiers.ecdsa_plain_SHA224); + addSignatureAlgorithm(provider, "SHA256", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA256", BSIObjectIdentifiers.ecdsa_plain_SHA256); + addSignatureAlgorithm(provider, "SHA384", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA384", BSIObjectIdentifiers.ecdsa_plain_SHA384); + addSignatureAlgorithm(provider, "SHA512", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA512", BSIObjectIdentifiers.ecdsa_plain_SHA512); + addSignatureAlgorithm(provider, "RIPEMD160", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecPlainDSARP160", BSIObjectIdentifiers.ecdsa_plain_RIPEMD160); } } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java index 70fe3860..b65b859a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java @@ -80,6 +80,10 @@ public class RSA provider.addAlgorithm("Signature." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA"); provider.addAlgorithm("Signature.OID." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA"); + provider.addAlgorithm("Signature.SHA224WITHRSAANDMGF1", PREFIX + "PSSSignatureSpi$SHA224withRSA"); + provider.addAlgorithm("Signature.SHA256WITHRSAANDMGF1", PREFIX + "PSSSignatureSpi$SHA256withRSA"); + provider.addAlgorithm("Signature.SHA384WITHRSAANDMGF1", PREFIX + "PSSSignatureSpi$SHA384withRSA"); + provider.addAlgorithm("Signature.SHA512WITHRSAANDMGF1", PREFIX + "PSSSignatureSpi$SHA512withRSA"); provider.addAlgorithm("Signature.SHA224withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA224withRSA"); provider.addAlgorithm("Signature.SHA256withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA256withRSA"); provider.addAlgorithm("Signature.SHA384withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA384withRSA"); @@ -101,10 +105,6 @@ public class RSA provider.addAlgorithm("Alg.Alias.Signature.SHA256withRSAandMGF1", "SHA256withRSA/PSS"); provider.addAlgorithm("Alg.Alias.Signature.SHA384withRSAandMGF1", "SHA384withRSA/PSS"); provider.addAlgorithm("Alg.Alias.Signature.SHA512withRSAandMGF1", "SHA512withRSA/PSS"); - provider.addAlgorithm("Alg.Alias.Signature.SHA224WITHRSAANDMGF1", "SHA224withRSA/PSS"); - provider.addAlgorithm("Alg.Alias.Signature.SHA256WITHRSAANDMGF1", "SHA256withRSA/PSS"); - provider.addAlgorithm("Alg.Alias.Signature.SHA384WITHRSAANDMGF1", "SHA384withRSA/PSS"); - provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHRSAANDMGF1", "SHA512withRSA/PSS"); if (provider.hasAlgorithm("MessageDigest", "MD2")) { @@ -137,6 +137,10 @@ public class RSA provider.addAlgorithm("Signature.SHA1withRSA/ISO9796-2", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption"); provider.addAlgorithm("Alg.Alias.Signature." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); provider.addAlgorithm("Alg.Alias.Signature.OID." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); + + provider.addAlgorithm("Alg.Alias.Signature.SHA1withRSA/X9.31", "SHA1WITHRSA/X9.31"); + provider.addAlgorithm("Alg.Alias.Signature.SHA1WithRSA/X9.31", "SHA1WITHRSA/X9.31"); + provider.addAlgorithm("Signature.SHA1WITHRSA/X9.31", PREFIX + "X931SignatureSpi$SHA1WithRSAEncryption"); } addDigestSignature(provider, "SHA224", PREFIX + "DigestSignatureSpi$SHA224", PKCSObjectIdentifiers.sha224WithRSAEncryption); @@ -144,10 +148,26 @@ public class RSA addDigestSignature(provider, "SHA384", PREFIX + "DigestSignatureSpi$SHA384", PKCSObjectIdentifiers.sha384WithRSAEncryption); addDigestSignature(provider, "SHA512", PREFIX + "DigestSignatureSpi$SHA512", PKCSObjectIdentifiers.sha512WithRSAEncryption); + provider.addAlgorithm("Alg.Alias.Signature.SHA224withRSA/X9.31", "SHA224WITHRSA/X9.31"); + provider.addAlgorithm("Alg.Alias.Signature.SHA224WithRSA/X9.31", "SHA224WITHRSA/X9.31"); + provider.addAlgorithm("Signature.SHA224WITHRSA/X9.31", PREFIX + "X931SignatureSpi$SHA224WithRSAEncryption"); + provider.addAlgorithm("Alg.Alias.Signature.SHA256withRSA/X9.31", "SHA256WITHRSA/X9.31"); + provider.addAlgorithm("Alg.Alias.Signature.SHA256WithRSA/X9.31", "SHA256WITHRSA/X9.31"); + provider.addAlgorithm("Signature.SHA256WITHRSA/X9.31", PREFIX + "X931SignatureSpi$SHA256WithRSAEncryption"); + provider.addAlgorithm("Alg.Alias.Signature.SHA384withRSA/X9.31", "SHA384WITHRSA/X9.31"); + provider.addAlgorithm("Alg.Alias.Signature.SHA384WithRSA/X9.31", "SHA384WITHRSA/X9.31"); + provider.addAlgorithm("Signature.SHA384WITHRSA/X9.31", PREFIX + "X931SignatureSpi$SHA384WithRSAEncryption"); + provider.addAlgorithm("Alg.Alias.Signature.SHA512withRSA/X9.31", "SHA512WITHRSA/X9.31"); + provider.addAlgorithm("Alg.Alias.Signature.SHA512WithRSA/X9.31", "SHA512WITHRSA/X9.31"); + provider.addAlgorithm("Signature.SHA512WITHRSA/X9.31", PREFIX + "X931SignatureSpi$SHA512WithRSAEncryption"); + if (provider.hasAlgorithm("MessageDigest", "RIPEMD128")) { addDigestSignature(provider, "RIPEMD128", PREFIX + "DigestSignatureSpi$RIPEMD128", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); addDigestSignature(provider, "RMD128", PREFIX + "DigestSignatureSpi$RIPEMD128", null); + provider.addAlgorithm("Alg.Alias.Signature.RIPEMD128withRSA/X9.31", "RIPEMD128WITHRSA/X9.31"); + provider.addAlgorithm("Alg.Alias.Signature.RIPEMD128WithRSA/X9.31", "RIPEMD128WITHRSA/X9.31"); + provider.addAlgorithm("Signature.RIPEMD128WITHRSA/X9.31", PREFIX + "X931SignatureSpi$RIPEMD128WithRSAEncryption"); } if (provider.hasAlgorithm("MessageDigest", "RIPEMD160")) @@ -156,6 +176,9 @@ public class RSA addDigestSignature(provider, "RMD160", PREFIX + "DigestSignatureSpi$RIPEMD160", null); provider.addAlgorithm("Alg.Alias.Signature.RIPEMD160WithRSA/ISO9796-2", "RIPEMD160withRSA/ISO9796-2"); provider.addAlgorithm("Signature.RIPEMD160withRSA/ISO9796-2", PREFIX + "ISOSignatureSpi$RIPEMD160WithRSAEncryption"); + provider.addAlgorithm("Alg.Alias.Signature.RIPEMD160withRSA/X9.31", "RIPEMD160WITHRSA/X9.31"); + provider.addAlgorithm("Alg.Alias.Signature.RIPEMD160WithRSA/X9.31", "RIPEMD160WITHRSA/X9.31"); + provider.addAlgorithm("Signature.RIPEMD160WITHRSA/X9.31", PREFIX + "X931SignatureSpi$RIPEMD160WithRSAEncryption"); } if (provider.hasAlgorithm("MessageDigest", "RIPEMD256")) @@ -163,6 +186,14 @@ public class RSA addDigestSignature(provider, "RIPEMD256", PREFIX + "DigestSignatureSpi$RIPEMD256", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); addDigestSignature(provider, "RMD256", PREFIX + "DigestSignatureSpi$RIPEMD256", null); } + + if (provider.hasAlgorithm("MessageDigest", "WHIRLPOOL")) + { + provider.addAlgorithm("Alg.Alias.Signature.WhirlpoolWithRSA/X9.31", "WHIRLPOOLWITHRSA/X9.31"); + provider.addAlgorithm("Alg.Alias.Signature.WHIRLPOOLwithRSA/X9.31", "WHIRLPOOLWITHRSA/X9.31"); + provider.addAlgorithm("Alg.Alias.Signature.WHIRLPOOLWithRSA/X9.31", "WHIRLPOOLWITHRSA/X9.31"); + provider.addAlgorithm("Signature.WHIRLPOOLWITHRSA/X9.31", PREFIX + "X931SignatureSpi$WhirlpoolWithRSAEncryption"); + } } private void addDigestSignature( diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java index 8bdcc551..e4c8172c 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java @@ -10,10 +10,10 @@ import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.crypto.generators.DHParametersGenerator; import org.bouncycastle.crypto.params.DHParameters; -import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jcajce.provider.asymmetric.util.BaseAlgorithmParameterGeneratorSpi; public class AlgorithmParameterGeneratorSpi - extends java.security.AlgorithmParameterGeneratorSpi + extends BaseAlgorithmParameterGeneratorSpi { protected SecureRandom random; protected int strength = 1024; @@ -63,7 +63,7 @@ public class AlgorithmParameterGeneratorSpi try { - params = AlgorithmParameters.getInstance("DH", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("DH"); params.init(new DHParameterSpec(p.getP(), p.getG(), l)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java index c29ff2dc..df6b6f91 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java @@ -7,8 +7,10 @@ import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; +import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; +import java.security.Security; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; @@ -43,6 +45,8 @@ import org.bouncycastle.crypto.params.IESWithCipherParameters; import org.bouncycastle.crypto.parsers.DHIESPublicKeyParser; import org.bouncycastle.jcajce.provider.asymmetric.util.DHUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.IESUtil; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.interfaces.IESKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.IESParameterSpec; @@ -53,6 +57,8 @@ import org.bouncycastle.util.Strings; public class IESCipher extends CipherSpi { + private final JcaJceHelper helper = new BCJcaJceHelper(); + private IESEngine engine; private int state = -1; private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); @@ -106,7 +112,7 @@ public class IESCipher { try { - engineParam = AlgorithmParameters.getInstance("IES", BouncyCastleProvider.PROVIDER_NAME); + engineParam = helper.createAlgorithmParameters("IES"); engineParam.init(engineSpec); } catch (Exception e) @@ -465,7 +471,6 @@ public class IESCipher } - /** * Classes that inherit from us */ diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java index d850e5de..2d7c4c5d 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java @@ -11,10 +11,10 @@ import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.generators.DSAParametersGenerator; import org.bouncycastle.crypto.params.DSAParameterGenerationParameters; import org.bouncycastle.crypto.params.DSAParameters; -import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jcajce.provider.asymmetric.util.BaseAlgorithmParameterGeneratorSpi; public class AlgorithmParameterGeneratorSpi - extends java.security.AlgorithmParameterGeneratorSpi + extends BaseAlgorithmParameterGeneratorSpi { protected SecureRandom random; protected int strength = 1024; @@ -90,7 +90,7 @@ public class AlgorithmParameterGeneratorSpi try { - params = AlgorithmParameters.getInstance("DSA", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("DSA"); params.init(new DSAParameterSpec(p.getP(), p.getQ(), p.getG())); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java index 61fa33c6..57224797 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java @@ -33,7 +33,6 @@ public class AlgorithmParametersSpi /** * Return the X.509 ASN.1 structure DSAParameter. - * <p/> * <pre> * DSAParameter ::= SEQUENCE { * prime INTEGER, -- p diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java index c6ddf9be..d2c2c712 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java @@ -34,9 +34,9 @@ public class KeyPairGeneratorSpi int strength, SecureRandom random) { - if (strength < 512 || strength > 1024 || strength % 64 != 0) + if (strength < 512 || strength > 4096 || ((strength < 1024) && strength % 64 != 0) || (strength >= 1024 && strength % 1024 != 0)) { - throw new InvalidParameterException("strength must be from 512 - 1024 and a multiple of 64"); + throw new InvalidParameterException("strength must be from 512 - 4096 and a multiple of 1024 above 1024"); } this.strength = strength; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PrivateKey.java index 9b7e7974..27d4b451 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PrivateKey.java @@ -13,12 +13,11 @@ import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERBitString; -import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.ua.DSTU4145NamedCurves; import org.bouncycastle.asn1.ua.UAObjectIdentifiers; @@ -244,9 +243,9 @@ public class BCDSTU4145PrivateKey } ASN1Encodable privKey = info.parsePrivateKey(); - if (privKey instanceof DERInteger) + if (privKey instanceof ASN1Integer) { - DERInteger derD = DERInteger.getInstance(privKey); + ASN1Integer derD = ASN1Integer.getInstance(privKey); this.d = derD.getValue(); } @@ -283,19 +282,22 @@ public class BCDSTU4145PrivateKey public byte[] getEncoded() { X962Parameters params; + int orderBitLength; if (ecSpec instanceof ECNamedCurveSpec) { - DERObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); + ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); if (curveOid == null) // guess it's the OID { - curveOid = new DERObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); + curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); + orderBitLength = ECUtil.getOrderBitLength(ecSpec.getOrder(), this.getS()); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); + orderBitLength = ECUtil.getOrderBitLength(null, this.getS()); } else { @@ -309,6 +311,7 @@ public class BCDSTU4145PrivateKey ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); + orderBitLength = ECUtil.getOrderBitLength(ecSpec.getOrder(), this.getS()); } PrivateKeyInfo info; @@ -316,11 +319,11 @@ public class BCDSTU4145PrivateKey if (publicKey != null) { - keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), publicKey, params); + keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params); } else { - keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), params); + keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params); } try diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PublicKey.java index c641ee97..11c52a74 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/BCDSTU4145PublicKey.java @@ -36,6 +36,8 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; 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; public class BCDSTU4145PublicKey implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder @@ -352,14 +354,7 @@ public class BCDSTU4145PublicKey { if (ecSpec == null) { - if (q instanceof org.bouncycastle.math.ec.ECPoint.Fp) - { - return new org.bouncycastle.math.ec.ECPoint.Fp(null, q.getAffineXCoord(), q.getAffineYCoord()); - } - else - { - return new org.bouncycastle.math.ec.ECPoint.F2m(null, q.getAffineXCoord(), q.getAffineYCoord()); - } + return q.getDetachedPoint(); } return q; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java index 45d5b081..c9ad4455 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java @@ -282,7 +282,8 @@ public class BCECPrivateKey */ public byte[] getEncoded() { - X962Parameters params; + X962Parameters params; + int orderBitLength; if (ecSpec instanceof ECNamedCurveSpec) { @@ -293,10 +294,12 @@ public class BCECPrivateKey } params = new X962Parameters(curveOid); + orderBitLength = ECUtil.getOrderBitLength(ecSpec.getOrder(), this.getS()); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); + orderBitLength = ECUtil.getOrderBitLength(null, this.getS()); } else { @@ -310,6 +313,7 @@ public class BCECPrivateKey ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); + orderBitLength = ECUtil.getOrderBitLength(ecSpec.getOrder(), this.getS()); } PrivateKeyInfo info; @@ -317,11 +321,11 @@ public class BCECPrivateKey if (publicKey != null) { - keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), publicKey, params); + keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params); } else { - keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), params); + keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params); } try diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java index 0eaae1db..ac0ddf5b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java @@ -34,6 +34,8 @@ import org.bouncycastle.jce.interfaces.ECPointEncoder; import org.bouncycastle.jce.provider.BouncyCastleProvider; 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; public class BCECPublicKey implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder @@ -82,6 +84,8 @@ public class BCECPublicKey ECCurve curve = spec.getParams().getCurve(); EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed()); + // this may seem a little long-winded but it's how we pick up the custom curve. + this.q = EC5Util.convertCurve(ellipticCurve).createPoint(spec.getQ().getAffineXCoord().toBigInteger(), spec.getQ().getAffineYCoord().toBigInteger()); this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams()); } else @@ -132,7 +136,6 @@ public class BCECPublicKey ECDomainParameters dp = params.getParameters(); this.algorithm = algorithm; - this.q = params.getQ(); if (spec == null) { @@ -147,6 +150,8 @@ public class BCECPublicKey this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec); } + this.q = EC5Util.convertCurve(ecSpec.getCurve()).createPoint(params.getQ().getAffineXCoord().toBigInteger(), params.getQ().getAffineYCoord().toBigInteger()); + this.configuration = configuration; } @@ -369,14 +374,7 @@ public class BCECPublicKey { if (ecSpec == null) { - if (q instanceof org.bouncycastle.math.ec.ECPoint.Fp) - { - return new org.bouncycastle.math.ec.ECPoint.Fp(null, q.getAffineXCoord(), q.getAffineYCoord()); - } - else - { - return new org.bouncycastle.math.ec.ECPoint.F2m(null, q.getAffineXCoord(), q.getAffineYCoord()); - } + return q.getDetachedPoint(); } return q; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java index 4ad05123..fbeb8f02 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java @@ -18,6 +18,7 @@ import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.ShortBufferException; +import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.KeyEncoder; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; @@ -29,22 +30,22 @@ import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.generators.EphemeralKeyPairGenerator; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.params.IESParameters; import org.bouncycastle.crypto.params.IESWithCipherParameters; +import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.parsers.ECIESPublicKeyParser; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.IESUtil; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.interfaces.ECKey; -import org.bouncycastle.jce.interfaces.ECPrivateKey; -import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.IESKey; -import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.IESParameterSpec; import org.bouncycastle.util.Strings; @@ -52,6 +53,9 @@ import org.bouncycastle.util.Strings; public class IESCipher extends CipherSpi { + private final JcaJceHelper helper = new BCJcaJceHelper(); + + private int ivLength; private IESEngine engine; private int state = -1; private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); @@ -65,8 +69,14 @@ public class IESCipher public IESCipher(IESEngine engine) { this.engine = engine; + this.ivLength = 0; } + public IESCipher(IESEngine engine, int ivLength) + { + this.engine = engine; + this.ivLength = ivLength; + } public int engineGetBlockSize() { @@ -99,14 +109,13 @@ public class IESCipher return null; } - public AlgorithmParameters engineGetParameters() { if (engineParam == null && engineSpec != null) { try { - engineParam = AlgorithmParameters.getInstance("IES", BouncyCastleProvider.PROVIDER_NAME); + engineParam = helper.createAlgorithmParameters("IES"); engineParam.init(engineSpec); } catch (Exception e) @@ -259,10 +268,24 @@ public class IESCipher throw new InvalidAlgorithmParameterException("must be passed IES parameters"); } + byte[] nonce = this.engineSpec.getNonce(); + + if (nonce != null) + { + if (ivLength == 0) + { + throw new InvalidAlgorithmParameterException("NONCE present in IES Parameters when none required"); + } + else if (nonce.length != ivLength) + { + throw new InvalidAlgorithmParameterException("NONCE in IES Parameters needs to be " + ivLength + " bytes long"); + } + } + // Parse the recipient's key if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) { - if (key instanceof ECPublicKey) + if (key instanceof PublicKey) { this.key = ECUtil.generatePublicKeyParameter((PublicKey)key); } @@ -280,7 +303,7 @@ public class IESCipher } else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) { - if (key instanceof ECPrivateKey) + if (key instanceof PrivateKey) { this.key = ECUtil.generatePrivateKeyParameter((PrivateKey)key); } @@ -368,11 +391,16 @@ public class IESCipher buffer.reset(); // Convert parameters for use in IESEngine - IESParameters params = new IESWithCipherParameters(engineSpec.getDerivationV(), + CipherParameters params = new IESWithCipherParameters(engineSpec.getDerivationV(), engineSpec.getEncodingV(), engineSpec.getMacKeySize(), engineSpec.getCipherKeySize()); + if (engineSpec.getNonce() != null) + { + params = new ParametersWithIV(params, engineSpec.getNonce()); + } + final ECDomainParameters ecParams = ((ECKeyParameters)key).getParameters(); final byte[] V; @@ -403,11 +431,12 @@ public class IESCipher ECKeyPairGenerator gen = new ECKeyPairGenerator(); gen.init(new ECKeyGenerationParameters(ecParams, random)); + final boolean usePointCompression = engineSpec.getPointCompression(); EphemeralKeyPairGenerator kGen = new EphemeralKeyPairGenerator(gen, new KeyEncoder() { public byte[] getEncoded(AsymmetricKeyParameter keyParameter) { - return ((ECPublicKeyParameters)keyParameter).getQ().getEncoded(); + return ((ECPublicKeyParameters)keyParameter).getQ().getEncoded(usePointCompression); } }); @@ -459,7 +488,6 @@ public class IESCipher return buf.length; } - /** * Classes that inherit from us */ @@ -498,4 +526,28 @@ public class IESCipher new PaddedBufferedBlockCipher(new AESEngine()))); } } + + static public class ECIESwithDESedeCBC + extends IESCipher + { + public ECIESwithDESedeCBC() + { + super(new IESEngine(new ECDHBasicAgreement(), + new KDF2BytesGenerator(new SHA1Digest()), + new HMac(new SHA1Digest()), + new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine()))), 8); + } + } + + static public class ECIESwithAESCBC + extends IESCipher + { + public ECIESwithAESCBC() + { + super(new IESEngine(new ECDHBasicAgreement(), + new KDF2BytesGenerator(new SHA1Digest()), + new HMac(new SHA1Digest()), + new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()))), 16); + } + } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java index 05563787..4ea57fee 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java @@ -17,6 +17,7 @@ import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x9.X9IntegerConverter; import org.bouncycastle.crypto.BasicAgreement; @@ -28,6 +29,7 @@ import org.bouncycastle.crypto.agreement.ECMQVBasicAgreement; import org.bouncycastle.crypto.agreement.kdf.DHKDFParameters; import org.bouncycastle.crypto.agreement.kdf.ECDHKEKGenerator; import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.crypto.params.DESParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; @@ -39,6 +41,7 @@ import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.MQVPrivateKey; import org.bouncycastle.jce.interfaces.MQVPublicKey; import org.bouncycastle.util.Integers; +import org.bouncycastle.util.Strings; /** * Diffie-Hellman key agreement using elliptic curve keys, ala IEEE P1363 @@ -51,9 +54,12 @@ public class KeyAgreementSpi { private static final X9IntegerConverter converter = new X9IntegerConverter(); private static final Hashtable algorithms = new Hashtable(); + private static final Hashtable oids = new Hashtable(); + private static final Hashtable des = new Hashtable(); static { + Integer i64 = Integers.valueOf(64); Integer i128 = Integers.valueOf(128); Integer i192 = Integers.valueOf(192); Integer i256 = Integers.valueOf(256); @@ -65,6 +71,18 @@ public class KeyAgreementSpi algorithms.put(NISTObjectIdentifiers.id_aes192_wrap.getId(), i192); algorithms.put(NISTObjectIdentifiers.id_aes256_wrap.getId(), i256); algorithms.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), i192); + algorithms.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), i192); + algorithms.put(OIWObjectIdentifiers.desCBC.getId(), i64); + + oids.put("DESEDE", PKCSObjectIdentifiers.des_EDE3_CBC); + oids.put("AES", NISTObjectIdentifiers.id_aes256_CBC); + oids.put("DES", OIWObjectIdentifiers.desCBC); + + des.put("DES", "DES"); + des.put("DESEDE", "DES"); + des.put(OIWObjectIdentifiers.desCBC.getId(), "DES"); + des.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), "DES"); + des.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), "DES"); } private String kaAlgorithm; @@ -76,7 +94,7 @@ public class KeyAgreementSpi private byte[] bigIntToBytes( BigInteger r) { - return converter.integerToBytes(r, converter.getByteLength(parameters.getG().getAffineXCoord())); + return converter.integerToBytes(r, converter.getByteLength(parameters.getCurve())); } protected KeyAgreementSpi( @@ -175,17 +193,24 @@ public class KeyAgreementSpi throws NoSuchAlgorithmException { byte[] secret = bigIntToBytes(result); + String algKey = Strings.toUpperCase(algorithm); + String oidAlgorithm = algorithm; + + if (oids.containsKey(algKey)) + { + oidAlgorithm = ((ASN1ObjectIdentifier)oids.get(algKey)).getId(); + } if (kdf != null) { - if (!algorithms.containsKey(algorithm)) + if (!algorithms.containsKey(oidAlgorithm)) { throw new NoSuchAlgorithmException("unknown algorithm encountered: " + algorithm); } - int keySize = ((Integer)algorithms.get(algorithm)).intValue(); + int keySize = ((Integer)algorithms.get(oidAlgorithm)).intValue(); - DHKDFParameters params = new DHKDFParameters(new ASN1ObjectIdentifier(algorithm), keySize, secret); + DHKDFParameters params = new DHKDFParameters(new ASN1ObjectIdentifier(oidAlgorithm), keySize, secret); byte[] keyBytes = new byte[keySize / 8]; kdf.init(params); @@ -194,7 +219,21 @@ public class KeyAgreementSpi } else { - // TODO Should we be ensuring the key is the right length? + if (algorithms.containsKey(oidAlgorithm)) + { + Integer length = (Integer)algorithms.get(oidAlgorithm); + + byte[] key = new byte[length.intValue() / 8]; + + System.arraycopy(secret, 0, key, 0, key.length); + + secret = key; + } + } + + if (des.containsKey(oidAlgorithm)) + { + DESParameters.setOddParity(secret); } return new SecretKeySpec(secret, algorithm); @@ -206,6 +245,11 @@ public class KeyAgreementSpi SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + if (params != null) + { + throw new InvalidAlgorithmParameterException("No algorithm parameters supported"); + } + initFromKey(key); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java index f47f8a24..ae9be26d 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java @@ -85,22 +85,20 @@ public abstract class KeyPairGeneratorSpi { this.strength = strength; this.random = random; + ECGenParameterSpec ecParams = (ECGenParameterSpec)ecParameters.get(Integers.valueOf(strength)); + if (ecParams == null) + { + throw new InvalidParameterException("unknown key size."); + } - if (ecParams != null) + try { - try - { - initialize(ecParams, random); - } - catch (InvalidAlgorithmParameterException e) - { - throw new InvalidParameterException("key size not configurable."); - } + initialize(ecParams, random); } - else + catch (InvalidAlgorithmParameterException e) { - throw new InvalidParameterException("unknown key size."); + throw new InvalidParameterException("key size not configurable."); } } @@ -109,97 +107,42 @@ public abstract class KeyPairGeneratorSpi SecureRandom random) throws InvalidAlgorithmParameterException { - if (params instanceof ECParameterSpec) + if (params == null) { - ECParameterSpec p = (ECParameterSpec)params; - this.ecParams = params; - - param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); + ECParameterSpec implicitCA = configuration.getEcImplicitlyCa(); + if (implicitCA == null) + { + throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set"); + } - engine.init(param); - initialised = true; + this.ecParams = null; + this.param = createKeyGenParamsBC(implicitCA, random); } - else if (params instanceof java.security.spec.ECParameterSpec) + else if (params instanceof ECParameterSpec) { - java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)params; this.ecParams = params; - - ECCurve curve = EC5Util.convertCurve(p.getCurve()); - ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false); - - param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random); - - engine.init(param); - initialised = true; + this.param = createKeyGenParamsBC((ECParameterSpec)params, random); } - else if (params instanceof ECGenParameterSpec || params instanceof ECNamedCurveGenParameterSpec) + else if (params instanceof java.security.spec.ECParameterSpec) { - String curveName; - - if (params instanceof ECGenParameterSpec) - { - curveName = ((ECGenParameterSpec)params).getName(); - } - else - { - curveName = ((ECNamedCurveGenParameterSpec)params).getName(); - } - - X9ECParameters ecP = ECNamedCurveTable.getByName(curveName); - if (ecP == null) - { - // See if it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug) - try - { - ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(curveName); - ecP = ECNamedCurveTable.getByOID(oid); - if (ecP == null) - { - throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName); - } - } - catch (IllegalArgumentException ex) - { - throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName); - } - } - - this.ecParams = new ECNamedCurveSpec( - curveName, - ecP.getCurve(), - ecP.getG(), - ecP.getN(), - ecP.getH(), - null); // ecP.getSeed()); Work-around JDK bug -- it won't look up named curves properly if seed is present - - java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams; - - ECCurve curve = EC5Util.convertCurve(p.getCurve()); - ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false); - - param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random); - - engine.init(param); - initialised = true; + this.ecParams = params; + this.param = createKeyGenParamsJCE((java.security.spec.ECParameterSpec)params, random); } - else if (params == null && configuration.getEcImplicitlyCa() != null) + else if (params instanceof ECGenParameterSpec) { - ECParameterSpec p = configuration.getEcImplicitlyCa(); - this.ecParams = params; - - param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random); - - engine.init(param); - initialised = true; + initializeNamedCurve(((ECGenParameterSpec)params).getName(), random); } - else if (params == null && configuration.getEcImplicitlyCa() == null) + else if (params instanceof ECNamedCurveGenParameterSpec) { - throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set"); + initializeNamedCurve(((ECNamedCurveGenParameterSpec)params).getName(), random); } else { throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec"); } + + engine.init(param); + initialised = true; } public KeyPair generateKeyPair() @@ -235,6 +178,58 @@ public abstract class KeyPairGeneratorSpi return new KeyPair(pubKey, new BCECPrivateKey(algorithm, priv, pubKey, p, configuration)); } } + + protected ECKeyGenerationParameters createKeyGenParamsBC(ECParameterSpec p, SecureRandom r) + { + return new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), r); + } + + protected ECKeyGenerationParameters createKeyGenParamsJCE(java.security.spec.ECParameterSpec p, SecureRandom r) + { + ECCurve curve = EC5Util.convertCurve(p.getCurve()); + ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false); + BigInteger n = p.getOrder(); + BigInteger h = BigInteger.valueOf(p.getCofactor()); + ECDomainParameters dp = new ECDomainParameters(curve, g, n, h); + return new ECKeyGenerationParameters(dp, r); + } + + protected ECNamedCurveSpec createNamedCurveSpec(String curveName) + throws InvalidAlgorithmParameterException + { + // NOTE: Don't bother with custom curves here as the curve will be converted to JCE type shortly + + X9ECParameters p = ECNamedCurveTable.getByName(curveName); + if (p == null) + { + try + { + // Check whether it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug) + p = ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(curveName)); + if (p == null) + { + throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName); + } + } + catch (IllegalArgumentException ex) + { + throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName); + } + } + + // Work-around for JDK bug -- it won't look up named curves properly if seed is present + byte[] seed = null; //p.getSeed(); + + return new ECNamedCurveSpec(curveName, p.getCurve(), p.getG(), p.getN(), p.getH(), seed); + } + + protected void initializeNamedCurve(String curveName, SecureRandom random) + throws InvalidAlgorithmParameterException + { + ECNamedCurveSpec namedCurve = createNamedCurveSpec(curveName); + this.ecParams = namedCurve; + this.param = createKeyGenParamsJCE(namedCurve, random); + } } public static class ECDSA diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java index e94746c3..5e2bb4e4 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java @@ -223,7 +223,7 @@ public class SignatureSpi { public ecCVCDSA() { - super(new SHA1Digest(), new ECDSASigner(), new CVCDSAEncoder()); + super(new SHA1Digest(), new ECDSASigner(), new PlainDSAEncoder()); } } @@ -232,7 +232,7 @@ public class SignatureSpi { public ecCVCDSA224() { - super(new SHA224Digest(), new ECDSASigner(), new CVCDSAEncoder()); + super(new SHA224Digest(), new ECDSASigner(), new PlainDSAEncoder()); } } @@ -241,7 +241,7 @@ public class SignatureSpi { public ecCVCDSA256() { - super(new SHA256Digest(), new ECDSASigner(), new CVCDSAEncoder()); + super(new SHA256Digest(), new ECDSASigner(), new PlainDSAEncoder()); } } @@ -250,7 +250,7 @@ public class SignatureSpi { public ecCVCDSA384() { - super(new SHA384Digest(), new ECDSASigner(), new CVCDSAEncoder()); + super(new SHA384Digest(), new ECDSASigner(), new PlainDSAEncoder()); } } @@ -259,7 +259,16 @@ public class SignatureSpi { public ecCVCDSA512() { - super(new SHA512Digest(), new ECDSASigner(), new CVCDSAEncoder()); + super(new SHA512Digest(), new ECDSASigner(), new PlainDSAEncoder()); + } + } + + static public class ecPlainDSARP160 + extends SignatureSpi + { + public ecPlainDSARP160() + { + super(new RIPEMD160Digest(), new ECDSASigner(), new PlainDSAEncoder()); } } @@ -293,7 +302,7 @@ public class SignatureSpi } } - private static class CVCDSAEncoder + private static class PlainDSAEncoder implements DSAEncoder { public byte[] encode( diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey.java index 2b1c3fae..4c046fea 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey.java @@ -13,14 +13,13 @@ import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; -import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; @@ -289,9 +288,9 @@ public class BCECGOST3410PrivateKey } ASN1Encodable privKey = info.parsePrivateKey(); - if (privKey instanceof DERInteger) + if (privKey instanceof ASN1Integer) { - DERInteger derD = DERInteger.getInstance(privKey); + ASN1Integer derD = ASN1Integer.getInstance(privKey); this.d = derD.getValue(); } @@ -348,19 +347,22 @@ public class BCECGOST3410PrivateKey else { X962Parameters params; + int orderBitLength; if (ecSpec instanceof ECNamedCurveSpec) { - DERObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); + ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); if (curveOid == null) // guess it's the OID { curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); } params = new X962Parameters(curveOid); + orderBitLength = ECUtil.getOrderBitLength(ecSpec.getOrder(), this.getS()); } else if (ecSpec == null) { params = new X962Parameters(DERNull.INSTANCE); + orderBitLength = ECUtil.getOrderBitLength(null, this.getS()); } else { @@ -374,6 +376,7 @@ public class BCECGOST3410PrivateKey ecSpec.getCurve().getSeed()); params = new X962Parameters(ecP); + orderBitLength = ECUtil.getOrderBitLength(ecSpec.getOrder(), this.getS()); } PrivateKeyInfo info; @@ -381,11 +384,11 @@ public class BCECGOST3410PrivateKey if (publicKey != null) { - keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), publicKey, params); + keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params); } else { - keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(this.getS(), params); + keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params); } try diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey.java index 650855ef..1240a0ff 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey.java @@ -32,6 +32,8 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; 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; public class BCECGOST3410PublicKey implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder @@ -316,14 +318,7 @@ public class BCECGOST3410PublicKey { if (ecSpec == null) { - if (q instanceof org.bouncycastle.math.ec.ECPoint.Fp) - { - return new org.bouncycastle.math.ec.ECPoint.Fp(null, q.getAffineXCoord(), q.getAffineYCoord()); - } - else - { - return new org.bouncycastle.math.ec.ECPoint.F2m(null, q.getAffineXCoord(), q.getAffineYCoord()); - } + return q.getDetachedPoint(); } return q; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/SignatureSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/SignatureSpi.java index b59db8fa..407dda57 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/SignatureSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ecgost/SignatureSpi.java @@ -58,14 +58,7 @@ public class SignatureSpi publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); - if (publicKey instanceof ECPublicKey) - { - param = ECUtil.generatePublicKeyParameter(publicKey); - } - else - { - throw new InvalidKeyException("can't recognise key type in DSA based signer"); - } + param = ECUtil.generatePublicKeyParameter(publicKey); } catch (Exception e) { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParameterGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParameterGeneratorSpi.java index 9cb9c87d..6097c3c4 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParameterGeneratorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParameterGeneratorSpi.java @@ -10,10 +10,10 @@ import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.crypto.generators.ElGamalParametersGenerator; import org.bouncycastle.crypto.params.ElGamalParameters; -import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jcajce.provider.asymmetric.util.BaseAlgorithmParameterGeneratorSpi; public class AlgorithmParameterGeneratorSpi - extends java.security.AlgorithmParameterGeneratorSpi + extends BaseAlgorithmParameterGeneratorSpi { protected SecureRandom random; protected int strength = 1024; @@ -63,7 +63,7 @@ public class AlgorithmParameterGeneratorSpi try { - params = AlgorithmParameters.getInstance("ElGamal", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("ElGamal"); params.init(new DHParameterSpec(p.getP(), p.getG(), l)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParametersSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParametersSpi.java index 2c56ee3a..3253fbb1 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParametersSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/AlgorithmParametersSpi.java @@ -8,7 +8,6 @@ import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.oiw.ElGamalParameter; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; import org.bouncycastle.jce.spec.ElGamalParameterSpec; @@ -20,7 +19,6 @@ public class AlgorithmParametersSpi /** * Return the X.509 ASN.1 structure ElGamalParameter. - * <p/> * <pre> * ElGamalParameter ::= SEQUENCE { * prime INTEGER, -- p @@ -95,7 +93,7 @@ public class AlgorithmParametersSpi { try { - ElGamalParameter elP = new ElGamalParameter((ASN1Sequence)ASN1Primitive.fromByteArray(params)); + ElGamalParameter elP = ElGamalParameter.getInstance(ASN1Primitive.fromByteArray(params)); currentSpec = new ElGamalParameterSpec(elP.getP(), elP.getG()); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPrivateKey.java index 0806b43e..f0f83fa4 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPrivateKey.java @@ -14,8 +14,6 @@ import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.oiw.ElGamalParameter; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; @@ -73,8 +71,8 @@ public class BCElGamalPrivateKey PrivateKeyInfo info) throws IOException { - ElGamalParameter params = new ElGamalParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); - DERInteger derX = ASN1Integer.getInstance(info.parsePrivateKey()); + ElGamalParameter params = ElGamalParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters()); + ASN1Integer derX = ASN1Integer.getInstance(info.parsePrivateKey()); this.x = derX.getValue(); this.elSpec = new ElGamalParameterSpec(params.getP(), params.getG()); @@ -112,7 +110,7 @@ public class BCElGamalPrivateKey { try { - PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(elSpec.getP(), elSpec.getG())), new DERInteger(getX())); + PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(elSpec.getP(), elSpec.getG())), new ASN1Integer(getX())); return info.getEncoded(ASN1Encoding.DER); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPublicKey.java index e0f72980..cd31cc57 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/BCElGamalPublicKey.java @@ -10,8 +10,7 @@ import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPublicKeySpec; import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERInteger; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.oiw.ElGamalParameter; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; @@ -75,12 +74,12 @@ public class BCElGamalPublicKey BCElGamalPublicKey( SubjectPublicKeyInfo info) { - ElGamalParameter params = new ElGamalParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); - DERInteger derY = null; + ElGamalParameter params = ElGamalParameter.getInstance(info.getAlgorithm().getParameters()); + ASN1Integer derY = null; try { - derY = (DERInteger)info.parsePublicKey(); + derY = (ASN1Integer)info.parsePublicKey(); } catch (IOException e) { @@ -105,7 +104,7 @@ public class BCElGamalPublicKey { try { - SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(elSpec.getP(), elSpec.getG())), new DERInteger(y)); + SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(elSpec.getP(), elSpec.getG())), new ASN1Integer(y)); return info.getEncoded(ASN1Encoding.DER); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/CipherSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/CipherSpi.java index fbf4f754..9c28670b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/CipherSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/elgamal/CipherSpi.java @@ -34,7 +34,6 @@ import org.bouncycastle.jcajce.provider.util.DigestFactory; import org.bouncycastle.jce.interfaces.ElGamalKey; import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; import org.bouncycastle.jce.interfaces.ElGamalPublicKey; -import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Strings; public class CipherSpi @@ -104,7 +103,7 @@ public class CipherSpi { try { - engineParams = AlgorithmParameters.getInstance("OAEP", BouncyCastleProvider.PROVIDER_NAME); + engineParams = createParametersInstance("OAEP"); engineParams.init(paramSpec); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParameterGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParameterGeneratorSpi.java index 7019b819..2e7ee7c3 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParameterGeneratorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParameterGeneratorSpi.java @@ -7,12 +7,12 @@ import java.security.spec.AlgorithmParameterSpec; import org.bouncycastle.crypto.generators.GOST3410ParametersGenerator; import org.bouncycastle.crypto.params.GOST3410Parameters; -import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jcajce.provider.asymmetric.util.BaseAlgorithmParameterGeneratorSpi; import org.bouncycastle.jce.spec.GOST3410ParameterSpec; import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec; public abstract class AlgorithmParameterGeneratorSpi - extends java.security.AlgorithmParameterGeneratorSpi + extends BaseAlgorithmParameterGeneratorSpi { protected SecureRandom random; protected int strength = 1024; @@ -52,7 +52,7 @@ public abstract class AlgorithmParameterGeneratorSpi try { - params = AlgorithmParameters.getInstance("GOST3410", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("GOST3410"); params.init(new GOST3410ParameterSpec(new GOST3410PublicKeyParameterSetSpec(p.getP(), p.getQ(), p.getA()))); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParametersSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParametersSpi.java index 0af98e0b..88f78bd5 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParametersSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/gost/AlgorithmParametersSpi.java @@ -37,7 +37,6 @@ public class AlgorithmParametersSpi /** * Return the X.509 ASN.1 structure GOST3410Parameter. - * <p/> * <pre> * GOST3410Parameter ::= SEQUENCE { * prime INTEGER, -- p diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java index 2f39c4ae..61f1e373 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java @@ -6,10 +6,10 @@ import java.security.spec.InvalidParameterSpecException; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.jce.spec.IESParameterSpec; @@ -48,7 +48,7 @@ public class AlgorithmParametersSpi v.add(new DEROctetString(currentSpec.getDerivationV())); v.add(new DEROctetString(currentSpec.getEncodingV())); - v.add(new DERInteger(currentSpec.getMacKeySize())); + v.add(new ASN1Integer(currentSpec.getMacKeySize())); return new DERSequence(v).getEncoded(ASN1Encoding.DER); } @@ -104,7 +104,7 @@ public class AlgorithmParametersSpi this.currentSpec = new IESParameterSpec( ((ASN1OctetString)s.getObjectAt(0)).getOctets(), ((ASN1OctetString)s.getObjectAt(0)).getOctets(), - ((DERInteger)s.getObjectAt(0)).getValue().intValue()); + ((ASN1Integer)s.getObjectAt(0)).getValue().intValue()); } catch (ClassCastException e) { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/CipherSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/CipherSpi.java index 8cfaf2a4..430f6b1b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/CipherSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/CipherSpi.java @@ -13,6 +13,7 @@ import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.interfaces.DHPrivateKey; +import javax.crypto.interfaces.DHPublicKey; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; @@ -22,17 +23,19 @@ import org.bouncycastle.crypto.engines.IESEngine; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.IESParameters; -import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jcajce.provider.asymmetric.util.DHUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.interfaces.ECPrivateKey; -import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.IESKey; import org.bouncycastle.jce.spec.IESParameterSpec; public class CipherSpi extends javax.crypto.CipherSpi { + private final JcaJceHelper helper = new BCJcaJceHelper(); + private IESEngine cipher; private int state = -1; private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); @@ -116,7 +119,7 @@ public class CipherSpi try { - engineParam = AlgorithmParameters.getInstance(name, BouncyCastleProvider.PROVIDER_NAME); + engineParam = helper.createAlgorithmParameters(name); engineParam.init(engineParams); } catch (Exception e) @@ -183,15 +186,16 @@ public class CipherSpi CipherParameters pubKey; CipherParameters privKey; - if (ieKey.getPublic() instanceof ECPublicKey) + if (ieKey.getPublic() instanceof DHPublicKey) { - pubKey = ECUtil.generatePublicKeyParameter(ieKey.getPublic()); - privKey = ECUtil.generatePrivateKeyParameter(ieKey.getPrivate()); + pubKey = DHUtil.generatePublicKeyParameter(ieKey.getPublic()); + privKey = DHUtil.generatePrivateKeyParameter(ieKey.getPrivate()); + } else { - pubKey = DHUtil.generatePublicKeyParameter(ieKey.getPublic()); - privKey = DHUtil.generatePrivateKeyParameter(ieKey.getPrivate()); + pubKey = ECUtil.generatePublicKeyParameter(ieKey.getPublic()); + privKey = ECUtil.generatePrivateKeyParameter(ieKey.getPrivate()); } this.engineParams = (IESParameterSpec)params; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java index 0aa81b48..b82c5f80 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java @@ -55,6 +55,12 @@ public class BCRSAPrivateKey this.privateExponent = key.getPrivateExponent(); } + BCRSAPrivateKey(org.bouncycastle.asn1.pkcs.RSAPrivateKey key) + { + this.modulus = key.getModulus(); + this.privateExponent = key.getPrivateExponent(); + } + public BigInteger getModulus() { return modulus; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java index a2114fa4..6f5292ce 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java @@ -1,5 +1,6 @@ package org.bouncycastle.jcajce.provider.asymmetric.rsa; +import java.io.EOFException; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -156,6 +157,10 @@ public class BCRSAPublicKey { algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER; } + catch (EOFException e) + { + algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER; + } } private void writeObject( diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java index dc8dcb23..239e5113 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java @@ -33,12 +33,16 @@ import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi; import org.bouncycastle.jcajce.provider.util.DigestFactory; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Strings; public class CipherSpi extends BaseCipherSpi { + private final JcaJceHelper helper = new BCJcaJceHelper(); + private AsymmetricBlockCipher cipher; private AlgorithmParameterSpec paramSpec; private AlgorithmParameters engineParams; @@ -143,7 +147,7 @@ public class CipherSpi { try { - engineParams = AlgorithmParameters.getInstance("OAEP", BouncyCastleProvider.PROVIDER_NAME); + engineParams = helper.createAlgorithmParameters("OAEP"); engineParams.init(paramSpec); } catch (Exception e) @@ -307,7 +311,7 @@ public class CipherSpi } else { - throw new IllegalArgumentException("unknown parameter type."); + throw new InvalidAlgorithmParameterException("unknown parameter type: " + params.getClass().getName()); } if (!(cipher instanceof RSABlindedEngine)) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java index 44625485..c04bec9e 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java @@ -37,6 +37,7 @@ import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; +import org.bouncycastle.util.Arrays; public class DigestSignatureSpi extends SignatureSpi @@ -171,13 +172,7 @@ public class DigestSignatureSpi if (sig.length == expected.length) { - for (int i = 0; i < sig.length; i++) - { - if (sig[i] != expected[i]) - { - return false; - } - } + return Arrays.constantTimeAreEqual(sig, expected); } else if (sig.length == expected.length - 2) // NULL left out { @@ -187,28 +182,26 @@ public class DigestSignatureSpi expected[1] -= 2; // adjust lengths expected[3] -= 2; + int nonEqual = 0; + for (int i = 0; i < hash.length; i++) { - if (sig[sigOffset + i] != expected[expectedOffset + i]) // check hash - { - return false; - } + nonEqual |= (sig[sigOffset + i] ^ expected[expectedOffset + i]); } for (int i = 0; i < sigOffset; i++) { - if (sig[i] != expected[i]) // check header less NULL - { - return false; - } + nonEqual |= (sig[i] ^ expected[i]); // check header less NULL } + + return nonEqual == 0; } else { + Arrays.constantTimeAreEqual(expected, expected); // keep time "steady". + return false; } - - return true; } protected void engineSetParameter( diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java index d8eb5394..80690f7c 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java @@ -137,7 +137,16 @@ public class KeyFactorySpi if (RSAUtil.isRsaOid(algOid)) { - return new BCRSAPrivateCrtKey(keyInfo); + RSAPrivateKey rsaPrivKey = RSAPrivateKey.getInstance(keyInfo.parsePrivateKey()); + + if (rsaPrivKey.getCoefficient().intValue() == 0) + { + return new BCRSAPrivateKey(rsaPrivKey); + } + else + { + return new BCRSAPrivateCrtKey(keyInfo); + } } else { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java index c61e7cb8..f779a66a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java @@ -23,7 +23,7 @@ public class KeyPairGeneratorSpi } final static BigInteger defaultPublicExponent = BigInteger.valueOf(0x10001); - final static int defaultTests = 12; + final static int defaultTests = 112; RSAKeyGenerationParameters param; RSAKeyPairGenerator engine; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/PSSSignatureSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/PSSSignatureSpi.java index c0a2fc92..ea632fcf 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/PSSSignatureSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/PSSSignatureSpi.java @@ -22,11 +22,15 @@ import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.engines.RSABlindedEngine; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.jcajce.provider.util.DigestFactory; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class PSSSignatureSpi extends SignatureSpi { + private final JcaJceHelper helper = new BCJcaJceHelper(); + private AlgorithmParameters engineParams; private PSSParameterSpec paramSpec; private PSSParameterSpec originalSpec; @@ -234,7 +238,7 @@ public class PSSSignatureSpi { try { - engineParams = AlgorithmParameters.getInstance("PSS", BouncyCastleProvider.PROVIDER_NAME); + engineParams = helper.createAlgorithmParameters("PSS"); engineParams.init(paramSpec); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/X931SignatureSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/X931SignatureSpi.java new file mode 100644 index 00000000..727f6852 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/X931SignatureSpi.java @@ -0,0 +1,194 @@ +package org.bouncycastle.jcajce.provider.asymmetric.rsa; + +import java.security.InvalidKeyException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.SignatureSpi; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.AlgorithmParameterSpec; + +import org.bouncycastle.crypto.AsymmetricBlockCipher; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.digests.MD5Digest; +import org.bouncycastle.crypto.digests.RIPEMD128Digest; +import org.bouncycastle.crypto.digests.RIPEMD160Digest; +import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.crypto.digests.SHA224Digest; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.digests.SHA384Digest; +import org.bouncycastle.crypto.digests.SHA512Digest; +import org.bouncycastle.crypto.digests.WhirlpoolDigest; +import org.bouncycastle.crypto.engines.RSABlindedEngine; +import org.bouncycastle.crypto.signers.ISO9796d2Signer; +import org.bouncycastle.crypto.signers.X931Signer; + +public class X931SignatureSpi + extends SignatureSpi +{ + private X931Signer signer; + + protected X931SignatureSpi( + Digest digest, + AsymmetricBlockCipher cipher) + { + signer = new X931Signer(cipher, digest); + } + + protected void engineInitVerify( + PublicKey publicKey) + throws InvalidKeyException + { + CipherParameters param = RSAUtil.generatePublicKeyParameter((RSAPublicKey)publicKey); + + signer.init(false, param); + } + + protected void engineInitSign( + PrivateKey privateKey) + throws InvalidKeyException + { + CipherParameters param = RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey); + + signer.init(true, param); + } + + protected void engineUpdate( + byte b) + throws SignatureException + { + signer.update(b); + } + + protected void engineUpdate( + byte[] b, + int off, + int len) + throws SignatureException + { + signer.update(b, off, len); + } + + protected byte[] engineSign() + throws SignatureException + { + try + { + byte[] sig = signer.generateSignature(); + + return sig; + } + catch (Exception e) + { + throw new SignatureException(e.toString()); + } + } + + protected boolean engineVerify( + byte[] sigBytes) + throws SignatureException + { + boolean yes = signer.verifySignature(sigBytes); + + return yes; + } + + protected void engineSetParameter( + AlgorithmParameterSpec params) + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + /** + * @deprecated replaced with <a href = "#engineSetParameter(java.security.spec.AlgorithmParameterSpec)"> + */ + protected void engineSetParameter( + String param, + Object value) + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + /** + * @deprecated + */ + protected Object engineGetParameter( + String param) + { + throw new UnsupportedOperationException("engineSetParameter unsupported"); + } + + static public class RIPEMD128WithRSAEncryption + extends X931SignatureSpi + { + public RIPEMD128WithRSAEncryption() + { + super(new RIPEMD128Digest(), new RSABlindedEngine()); + } + } + + static public class RIPEMD160WithRSAEncryption + extends X931SignatureSpi + { + public RIPEMD160WithRSAEncryption() + { + super(new RIPEMD160Digest(), new RSABlindedEngine()); + } + } + + static public class SHA1WithRSAEncryption + extends X931SignatureSpi + { + public SHA1WithRSAEncryption() + { + super(new SHA1Digest(), new RSABlindedEngine()); + } + } + + static public class SHA224WithRSAEncryption + extends X931SignatureSpi + { + public SHA224WithRSAEncryption() + { + super(new SHA224Digest(), new RSABlindedEngine()); + } + } + + static public class SHA256WithRSAEncryption + extends X931SignatureSpi + { + public SHA256WithRSAEncryption() + { + super(new SHA256Digest(), new RSABlindedEngine()); + } + } + + static public class SHA384WithRSAEncryption + extends X931SignatureSpi + { + public SHA384WithRSAEncryption() + { + super(new SHA384Digest(), new RSABlindedEngine()); + } + } + + static public class SHA512WithRSAEncryption + extends X931SignatureSpi + { + public SHA512WithRSAEncryption() + { + super(new SHA512Digest(), new RSABlindedEngine()); + } + } + + static public class WhirlpoolWithRSAEncryption + extends X931SignatureSpi + { + public WhirlpoolWithRSAEncryption() + { + super(new WhirlpoolDigest(), new RSABlindedEngine()); + } + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAlgorithmParameterGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAlgorithmParameterGeneratorSpi.java new file mode 100644 index 00000000..d9fb3fbf --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAlgorithmParameterGeneratorSpi.java @@ -0,0 +1,25 @@ +package org.bouncycastle.jcajce.provider.asymmetric.util; + +import java.security.AlgorithmParameterGeneratorSpi; +import java.security.AlgorithmParameters; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; + +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; + +public abstract class BaseAlgorithmParameterGeneratorSpi + extends AlgorithmParameterGeneratorSpi +{ + private final JcaJceHelper helper = new BCJcaJceHelper(); + + public BaseAlgorithmParameterGeneratorSpi() + { + } + + protected final AlgorithmParameters createParametersInstance(String algorithm) + throws NoSuchAlgorithmException, NoSuchProviderException + { + return helper.createAlgorithmParameters(algorithm); + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java index 722a5cae..482329c2 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java @@ -25,6 +25,8 @@ import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.provider.BouncyCastleProvider; public abstract class BaseCipherSpi @@ -41,6 +43,7 @@ public abstract class BaseCipherSpi RC5ParameterSpec.class }; + private final JcaJceHelper helper = new BCJcaJceHelper(); protected AlgorithmParameters engineParams = null; @@ -80,6 +83,12 @@ public abstract class BaseCipherSpi return null; } + protected final AlgorithmParameters createParametersInstance(String algorithm) + throws NoSuchAlgorithmException, NoSuchProviderException + { + return helper.createAlgorithmParameters(algorithm); + } + protected void engineSetMode( String mode) throws NoSuchAlgorithmException @@ -186,7 +195,7 @@ public abstract class BaseCipherSpi { try { - KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); + KeyFactory kf = helper.createKeyFactory(wrappedKeyAlgorithm); if (wrappedKeyType == Cipher.PUBLIC_KEY) { @@ -197,17 +206,17 @@ public abstract class BaseCipherSpi return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); } } - catch (NoSuchProviderException e) + catch (NoSuchAlgorithmException e) { throw new InvalidKeyException("Unknown key type " + e.getMessage()); } - catch (NoSuchAlgorithmException e) + catch (InvalidKeySpecException e) { throw new InvalidKeyException("Unknown key type " + e.getMessage()); } - catch (InvalidKeySpecException e2) + catch (NoSuchProviderException e) { - throw new InvalidKeyException("Unknown key type " + e2.getMessage()); + throw new InvalidKeyException("Unknown key type " + e.getMessage()); } throw new InvalidKeyException("Unknown key type " + wrappedKeyType); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java index 490bf4ed..cb34f447 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java @@ -1,6 +1,5 @@ package org.bouncycastle.jcajce.provider.asymmetric.util; -import java.io.IOException; import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java index 5eea1b92..d5b62fe8 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java @@ -7,22 +7,46 @@ import java.security.spec.ECFieldFp; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.EllipticCurve; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import org.bouncycastle.asn1.x9.ECNamedCurveTable; +import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.crypto.ec.CustomNamedCurves; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveSpec; +import org.bouncycastle.math.ec.ECAlgorithms; import org.bouncycastle.math.ec.ECCurve; public class EC5Util { + private static Map customCurves = new HashMap(); + + static + { + Enumeration e = CustomNamedCurves.getNames(); + while (e.hasMoreElements()) + { + String name = (String)e.nextElement(); + + X9ECParameters curveParams = ECNamedCurveTable.getByName(name); + if (curveParams != null) // there may not be a regular curve, may just be a custom curve. + { + customCurves.put(curveParams.getCurve(), CustomNamedCurves.getByName(name).getCurve()); + } + } + } + public static EllipticCurve convertCurve( ECCurve curve, byte[] seed) { // TODO: the Sun EC implementation doesn't currently handle the seed properly // so at the moment it's set to null. Should probably look at making this configurable - if (curve instanceof ECCurve.Fp) + if (ECAlgorithms.isFpCurve(curve)) { - return new EllipticCurve(new ECFieldFp(((ECCurve.Fp)curve).getQ()), curve.getA().toBigInteger(), curve.getB().toBigInteger(), null); + return new EllipticCurve(new ECFieldFp(curve.getField().getCharacteristic()), curve.getA().toBigInteger(), curve.getB().toBigInteger(), null); } else { @@ -53,7 +77,14 @@ public class EC5Util if (field instanceof ECFieldFp) { - return new ECCurve.Fp(((ECFieldFp)field).getP(), a, b); + ECCurve.Fp curve = new ECCurve.Fp(((ECFieldFp)field).getP(), a, b); + + if (customCurves.containsKey(curve)) + { + return (ECCurve)customCurves.get(curve); + } + + return curve; } else { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java index 97ade380..b1805f6a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java @@ -1,5 +1,6 @@ package org.bouncycastle.jcajce.provider.asymmetric.util; +import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; @@ -12,7 +13,9 @@ import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962NamedCurves; +import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.crypto.ec.CustomNamedCurves; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; @@ -213,6 +216,25 @@ public class ECUtil throw new InvalidKeyException("can't identify EC private key."); } + public static int getOrderBitLength(BigInteger order, BigInteger privateValue) + { + if (order == null) // implicitly CA + { + ECParameterSpec implicitCA = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); + + if (implicitCA == null) + { + return privateValue.bitLength(); // a guess but better than an exception! + } + + return implicitCA.getN().bitLength(); + } + else + { + return order.bitLength(); + } + } + public static ASN1ObjectIdentifier getNamedCurveOid( String name) { @@ -241,11 +263,15 @@ public class ECUtil public static X9ECParameters getNamedCurveByOid( ASN1ObjectIdentifier oid) { - X9ECParameters params = X962NamedCurves.getByOID(oid); - + X9ECParameters params = CustomNamedCurves.getByOID(oid); + if (params == null) { - params = SECNamedCurves.getByOID(oid); + params = X962NamedCurves.getByOID(oid); + if (params == null) + { + params = SECNamedCurves.getByOID(oid); + } if (params == null) { params = NISTNamedCurves.getByOID(oid); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java index 532554d2..3e328dae 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java @@ -12,7 +12,6 @@ import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; -import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; public class PKCS12BagAttributeCarrierImpl @@ -90,7 +89,7 @@ public class PKCS12BagAttributeCarrierImpl while (e.hasMoreElements()) { - DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); + ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); aOut.writeObject(oid); aOut.writeObject((ASN1Encodable)pkcs12Attributes.get(oid)); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java index 8699c3cb..8116f294 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java @@ -6,7 +6,7 @@ import java.io.InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.util.encoders.Base64; -public class PEMUtil +class PEMUtil { private final String _header1; private final String _header2; @@ -33,11 +33,6 @@ public class PEMUtil { while (((c = in.read()) != '\r') && c != '\n' && (c >= 0)) { - if (c == '\r') - { - continue; - } - l.append((char)c); } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java index 91d48294..b82d0917 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java @@ -34,7 +34,8 @@ import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SignedData; -import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; @@ -45,6 +46,8 @@ import org.bouncycastle.util.io.pem.PemWriter; public class PKIXCertPath extends CertPath { + private final JcaJceHelper helper = new BCJcaJceHelper(); + static final List certPathEncodings; static @@ -180,7 +183,7 @@ public class PKIXCertPath } Enumeration e = ((ASN1Sequence)derObject).getObjects(); certificates = new ArrayList(); - CertificateFactory certFactory = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); + CertificateFactory certFactory = helper.createCertificateFactory("X.509"); while (e.hasMoreElements()) { ASN1Encodable element = (ASN1Encodable)e.nextElement(); @@ -193,7 +196,7 @@ public class PKIXCertPath { inStream = new BufferedInputStream(inStream); certificates = new ArrayList(); - CertificateFactory certFactory= CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); + CertificateFactory certFactory= helper.createCertificateFactory("X.509"); Certificate cert; while ((cert = certFactory.generateCertificate(inStream)) != null) { @@ -213,7 +216,7 @@ public class PKIXCertPath { throw new CertificateException("BouncyCastle provider not found while trying to get a CertificateFactory:\n" + ex.toString()); } - + this.certificates = sortCerts(certificates); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java index 32e595c2..0b53bd37 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java @@ -23,7 +23,6 @@ import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.TBSCertList; -import org.bouncycastle.asn1.x509.X509Extension; /** * The following extensions are listed in RFC 2459 as relevant to CRL Entries @@ -31,7 +30,7 @@ import org.bouncycastle.asn1.x509.X509Extension; * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer * (critical) */ -public class X509CRLEntryObject extends X509CRLEntry +class X509CRLEntryObject extends X509CRLEntry { private TBSCertList.CRLEntry c; @@ -285,11 +284,11 @@ public class X509CRLEntryObject extends X509CRLEntry buf.append(" critical(").append(ext.isCritical()).append(") "); try { - if (oid.equals(X509Extension.reasonCode)) + if (oid.equals(Extension.reasonCode)) { buf.append(CRLReason.getInstance(ASN1Enumerated.getInstance(dIn.readObject()))).append(nl); } - else if (oid.equals(X509Extension.certificateIssuer)) + else if (oid.equals(Extension.certificateIssuer)) { buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java index c7d04020..cd877d04 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java @@ -42,7 +42,6 @@ import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.jce.provider.RFC3280CertPathUtilities; import org.bouncycastle.util.encoders.Hex; /** @@ -54,7 +53,7 @@ import org.bouncycastle.util.encoders.Hex; * Delta CRL Indicator (critical) * Issuing Distribution Point (critical) */ -public class X509CRLObject +class X509CRLObject extends X509CRL { private CertificateList c; @@ -120,8 +119,8 @@ public class X509CRLObject return false; } - extns.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT); - extns.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR); + extns.remove(Extension.issuingDistributionPoint.getId()); + extns.remove(Extension.deltaCRLIndicator.getId()); return !extns.isEmpty(); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java index 44220622..56df6344 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java @@ -9,9 +9,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.Security; import java.security.Signature; import java.security.SignatureException; import java.security.cert.Certificate; @@ -61,7 +59,6 @@ import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrie import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.jce.provider.RFC3280CertPathUtilities; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Hex; @@ -238,37 +235,11 @@ class X509CertificateObject /** * return a more "meaningful" representation for the signature algorithm used in - * the certficate. + * the certificate. */ public String getSigAlgName() { - Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME); - - if (prov != null) - { - String algName = prov.getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); - - if (algName != null) - { - return algName; - } - } - - Provider[] provs = Security.getProviders(); - - // - // search every provider looking for a real algorithm - // - for (int i = 0; i != provs.length; i++) - { - String algName = provs[i].getProperty("Alg.Alias.Signature." + this.getSigAlgOID()); - if (algName != null) - { - return algName; - } - } - - return this.getSigAlgOID(); + return X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); } /** @@ -522,19 +493,18 @@ class X509CertificateObject while (e.hasMoreElements()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); - String oidId = oid.getId(); - - if (oidId.equals(RFC3280CertPathUtilities.KEY_USAGE) - || oidId.equals(RFC3280CertPathUtilities.CERTIFICATE_POLICIES) - || oidId.equals(RFC3280CertPathUtilities.POLICY_MAPPINGS) - || oidId.equals(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY) - || oidId.equals(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS) - || oidId.equals(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT) - || oidId.equals(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR) - || oidId.equals(RFC3280CertPathUtilities.POLICY_CONSTRAINTS) - || oidId.equals(RFC3280CertPathUtilities.BASIC_CONSTRAINTS) - || oidId.equals(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME) - || oidId.equals(RFC3280CertPathUtilities.NAME_CONSTRAINTS)) + + if (oid.equals(Extension.keyUsage) + || oid.equals(Extension.certificatePolicies) + || oid.equals(Extension.policyMappings) + || oid.equals(Extension.inhibitAnyPolicy) + || oid.equals(Extension.cRLDistributionPoints) + || oid.equals(Extension.issuingDistributionPoint) + || oid.equals(Extension.deltaCRLIndicator) + || oid.equals(Extension.policyConstraints) + || oid.equals(Extension.basicConstraints) + || oid.equals(Extension.subjectAlternativeName) + || oid.equals(Extension.nameConstraints)) { continue; } @@ -775,7 +745,16 @@ class X509CertificateObject InvalidKeyException, NoSuchProviderException, SignatureException { String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm()); - Signature signature = Signature.getInstance(sigName, sigProvider); + Signature signature; + + if (sigProvider != null) + { + signature = Signature.getInstance(sigName, sigProvider); + } + else + { + signature = Signature.getInstance(sigName); + } checkSignature(key, signature); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java index 127b5341..8488f808 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java @@ -5,15 +5,17 @@ import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.spec.PSSParameterSpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Null; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; @@ -22,6 +24,7 @@ import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.jce.provider.BouncyCastleProvider; class X509SignatureUtil { @@ -76,7 +79,33 @@ class X509SignatureUtil { ASN1Sequence ecDsaParams = ASN1Sequence.getInstance(params); - return getDigestAlgName((DERObjectIdentifier)ecDsaParams.getObjectAt(0)) + "withECDSA"; + return getDigestAlgName((ASN1ObjectIdentifier)ecDsaParams.getObjectAt(0)) + "withECDSA"; + } + } + + Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME); + + if (prov != null) + { + String algName = prov.getProperty("Alg.Alias.Signature." + sigAlgId.getAlgorithm().getId()); + + if (algName != null) + { + return algName; + } + } + + Provider[] provs = Security.getProviders(); + + // + // search every provider looking for a real algorithm + // + for (int i = 0; i != provs.length; i++) + { + String algName = provs[i].getProperty("Alg.Alias.Signature." + sigAlgId.getAlgorithm().getId()); + if (algName != null) + { + return algName; } } @@ -88,7 +117,7 @@ class X509SignatureUtil * representations rather the the algorithm identifier (if possible). */ private static String getDigestAlgName( - DERObjectIdentifier digestAlgOID) + ASN1ObjectIdentifier digestAlgOID) { if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java index 05bfa1c3..123ff7de 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java @@ -15,7 +15,7 @@ public interface ConfigurableProvider static final String THREAD_LOCAL_EC_IMPLICITLY_CA = "threadLocalEcImplicitlyCa"; /** - * Elliptic Curve CA parameters - thread local version + * Elliptic Curve CA parameters - VM wide version */ static final String EC_IMPLICITLY_CA = "ecImplicitlyCa"; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/PKCS12StoreParameter.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/PKCS12StoreParameter.java index 36a32b17..7d0b203f 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/PKCS12StoreParameter.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/PKCS12StoreParameter.java @@ -2,50 +2,31 @@ package org.bouncycastle.jcajce.provider.config; import java.io.OutputStream; import java.security.KeyStore; -import java.security.KeyStore.LoadStoreParameter; import java.security.KeyStore.ProtectionParameter; +/** + * @deprecated use org.bouncycastle.jcajce.PKCS12StoreParameter + */ public class PKCS12StoreParameter - implements LoadStoreParameter + extends org.bouncycastle.jcajce.PKCS12StoreParameter { - private final OutputStream out; - private final ProtectionParameter protectionParameter; - private final boolean forDEREncoding; - public PKCS12StoreParameter(OutputStream out, char[] password) { - this(out, password, false); + super(out, password, false); } public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter) { - this(out, protectionParameter, false); + super(out, protectionParameter, false); } public PKCS12StoreParameter(OutputStream out, char[] password, boolean forDEREncoding) { - this(out, new KeyStore.PasswordProtection(password), forDEREncoding); + super(out, new KeyStore.PasswordProtection(password), forDEREncoding); } public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter, boolean forDEREncoding) { - this.out = out; - this.protectionParameter = protectionParameter; - this.forDEREncoding = forDEREncoding; - } - - public OutputStream getOutputStream() - { - return out; - } - - public ProtectionParameter getProtectionParameter() - { - return protectionParameter; - } - - public boolean isForDEREncoding() - { - return forDEREncoding; + super(out, protectionParameter, forDEREncoding); } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java index ea892610..06406698 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java @@ -14,8 +14,10 @@ import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; +import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; +import java.security.Security; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; @@ -46,6 +48,8 @@ import org.bouncycastle.crypto.io.DigestOutputStream; import org.bouncycastle.crypto.io.MacInputStream; import org.bouncycastle.crypto.io.MacOutputStream; import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.interfaces.BCKeyStore; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; @@ -88,6 +92,8 @@ public class BcKeyStoreSpi protected int version; + private final JcaJceHelper helper = new BCJcaJceHelper(); + public BcKeyStoreSpi(int version) { this.version = version; @@ -361,7 +367,7 @@ public class BcKeyStoreSpi try { - CertificateFactory cFact = CertificateFactory.getInstance(type, BouncyCastleProvider.PROVIDER_NAME); + CertificateFactory cFact = helper.createCertificateFactory(type); ByteArrayInputStream bIn = new ByteArrayInputStream(cEnc); return cFact.generateCertificate(bIn); @@ -436,11 +442,11 @@ public class BcKeyStoreSpi switch (keyType) { case KEY_PRIVATE: - return KeyFactory.getInstance(algorithm, BouncyCastleProvider.PROVIDER_NAME).generatePrivate(spec); + return helper.createKeyFactory(algorithm).generatePrivate(spec); case KEY_PUBLIC: - return KeyFactory.getInstance(algorithm, BouncyCastleProvider.PROVIDER_NAME).generatePublic(spec); + return helper.createKeyFactory(algorithm).generatePublic(spec); case KEY_SECRET: - return SecretKeyFactory.getInstance(algorithm, BouncyCastleProvider.PROVIDER_NAME).generateSecret(spec); + return helper.createSecretKeyFactory(algorithm).generateSecret(spec); default: throw new IOException("Key type " + keyType + " not recognised!"); } @@ -462,10 +468,10 @@ public class BcKeyStoreSpi try { PBEKeySpec pbeSpec = new PBEKeySpec(password); - SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm, BouncyCastleProvider.PROVIDER_NAME); + SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm); PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount); - Cipher cipher = Cipher.getInstance(algorithm, BouncyCastleProvider.PROVIDER_NAME); + Cipher cipher = helper.createCipher(algorithm); cipher.init(mode, keyFact.generateSecret(pbeSpec), defParams); @@ -1041,6 +1047,18 @@ public class BcKeyStoreSpi } } + static Provider getBouncyCastleProvider() + { + if (Security.getProvider("BC") != null) + { + return Security.getProvider("BC"); + } + else + { + return new BouncyCastleProvider(); + } + } + public static class Std extends BcKeyStoreSpi { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java index 9a62c98e..3fc0396e 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java @@ -15,6 +15,7 @@ import java.security.KeyStore.ProtectionParameter; import java.security.KeyStoreException; import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PrivateKey; import java.security.Provider; @@ -84,10 +85,14 @@ import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; -import org.bouncycastle.jcajce.provider.config.PKCS12StoreParameter; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.jcajce.PKCS12StoreParameter; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec; import org.bouncycastle.jcajce.spec.PBKDF2KeySpec; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.interfaces.BCKeyStore; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -101,10 +106,11 @@ public class PKCS12KeyStoreSpi extends KeyStoreSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers, BCKeyStore { + private final JcaJceHelper helper = new BCJcaJceHelper(); + private static final int SALT_SIZE = 20; private static final int MIN_ITERATIONS = 1024; - private static final Provider bcProvider = new BouncyCastleProvider(); private static final DefaultSecretKeyProvider keySizeProvider = new DefaultSecretKeyProvider(); private IgnoresCaseHashtable keys = new IgnoresCaseHashtable(); @@ -209,7 +215,7 @@ public class PKCS12KeyStoreSpi SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( (ASN1Sequence)ASN1Primitive.fromByteArray(pubKey.getEncoded())); - return new SubjectKeyIdentifier(info); + return new SubjectKeyIdentifier(getDigest(info)); } catch (Exception e) { @@ -217,6 +223,17 @@ public class PKCS12KeyStoreSpi } } + private static byte[] getDigest(SubjectPublicKeyInfo spki) + { + Digest digest = new SHA1Digest(); + byte[] resBuf = new byte[digest.getDigestSize()]; + + byte[] bytes = spki.getPublicKeyData().getBytes(); + digest.update(bytes, 0, bytes.length); + digest.doFinal(resBuf, 0); + return resBuf; + } + public void setRandom( SecureRandom rand) { @@ -588,8 +605,8 @@ public class PKCS12KeyStoreSpi PBEKeySpec pbeSpec = new PBEKeySpec(password); PrivateKey out; - SecretKeyFactory keyFact = SecretKeyFactory.getInstance( - algorithm.getId(), bcProvider); + SecretKeyFactory keyFact = helper.createSecretKeyFactory( + algorithm.getId()); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); @@ -598,7 +615,7 @@ public class PKCS12KeyStoreSpi ((BCPBEKey)k).setTryWrongPKCS12Zero(wrongPKCS12Zero); - Cipher cipher = Cipher.getInstance(algorithm.getId(), bcProvider); + Cipher cipher = helper.createCipher(algorithm.getId()); cipher.init(Cipher.UNWRAP_MODE, k, defParams); @@ -634,13 +651,12 @@ public class PKCS12KeyStoreSpi try { - SecretKeyFactory keyFact = SecretKeyFactory.getInstance( - algorithm, bcProvider); + SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); - Cipher cipher = Cipher.getInstance(algorithm, bcProvider); + Cipher cipher = helper.createCipher(algorithm); cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), defParams); @@ -663,6 +679,7 @@ public class PKCS12KeyStoreSpi throws IOException { ASN1ObjectIdentifier algorithm = algId.getAlgorithm(); + int mode = forEncryption ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds)) { @@ -671,7 +688,7 @@ public class PKCS12KeyStoreSpi try { - SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm.getId(), bcProvider); + SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm.getId()); PBEParameterSpec defParams = new PBEParameterSpec( pbeParams.getIV(), pbeParams.getIterations().intValue()); @@ -679,8 +696,8 @@ public class PKCS12KeyStoreSpi key.setTryWrongPKCS12Zero(wrongPKCS12Zero); - Cipher cipher = Cipher.getInstance(algorithm.getId(), bcProvider); - int mode = forEncryption ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; + Cipher cipher = helper.createCipher(algorithm.getId()); + cipher.init(mode, key, defParams); return cipher.doFinal(data); } @@ -693,7 +710,7 @@ public class PKCS12KeyStoreSpi { try { - Cipher cipher = createCipher(Cipher.DECRYPT_MODE, password, algId); + Cipher cipher = createCipher(mode, password, algId); return cipher.doFinal(data); } @@ -709,13 +726,13 @@ public class PKCS12KeyStoreSpi } private Cipher createCipher(int mode, char[] password, AlgorithmIdentifier algId) - throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException + throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, NoSuchProviderException { PBES2Parameters alg = PBES2Parameters.getInstance(algId.getParameters()); PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters()); AlgorithmIdentifier encScheme = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme()); - SecretKeyFactory keyFact = SecretKeyFactory.getInstance(alg.getKeyDerivationFunc().getAlgorithm().getId(), bcProvider); + SecretKeyFactory keyFact = helper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId()); SecretKey key; if (func.isDefaultPrf()) @@ -1021,9 +1038,9 @@ public class PKCS12KeyStoreSpi Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { - ASN1Sequence sq = (ASN1Sequence)e.nextElement(); - ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); - ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); + ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement()); + ASN1ObjectIdentifier aOid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0)); + ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1)); ASN1Primitive attr = null; if (attrSet.size() > 0) @@ -1044,16 +1061,16 @@ public class PKCS12KeyStoreSpi { bagAttr.setBagAttribute(aOid, attr); } - } - if (aOid.equals(pkcs_9_at_friendlyName)) - { - alias = ((DERBMPString)attr).getString(); - keys.put(alias, privKey); - } - else if (aOid.equals(pkcs_9_at_localKeyId)) - { - localId = (ASN1OctetString)attr; + if (aOid.equals(pkcs_9_at_friendlyName)) + { + alias = ((DERBMPString)attr).getString(); + keys.put(alias, privKey); + } + else if (aOid.equals(pkcs_9_at_localKeyId)) + { + localId = (ASN1OctetString)attr; + } } } @@ -1121,38 +1138,43 @@ public class PKCS12KeyStoreSpi Enumeration e = b.getBagAttributes().getObjects(); while (e.hasMoreElements()) { - ASN1Sequence sq = (ASN1Sequence)e.nextElement(); - ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)sq.getObjectAt(0); - ASN1Primitive attr = (ASN1Primitive)((ASN1Set)sq.getObjectAt(1)).getObjectAt(0); - PKCS12BagAttributeCarrier bagAttr = null; + ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement()); + ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0)); + ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1)); - if (cert instanceof PKCS12BagAttributeCarrier) + if (attrSet.size() > 0) // sometimes this is empty! { - bagAttr = (PKCS12BagAttributeCarrier)cert; + ASN1Primitive attr = (ASN1Primitive)attrSet.getObjectAt(0); + PKCS12BagAttributeCarrier bagAttr = null; - ASN1Encodable existing = bagAttr.getBagAttribute(oid); - if (existing != null) + if (cert instanceof PKCS12BagAttributeCarrier) { - // OK, but the value has to be the same - if (!existing.toASN1Primitive().equals(attr)) + bagAttr = (PKCS12BagAttributeCarrier)cert; + + ASN1Encodable existing = bagAttr.getBagAttribute(oid); + if (existing != null) { - throw new IOException( - "attempt to add existing attribute with different value"); + // OK, but the value has to be the same + if (!existing.toASN1Primitive().equals(attr)) + { + throw new IOException( + "attempt to add existing attribute with different value"); + } + } + else + { + bagAttr.setBagAttribute(oid, attr); } } - else + + if (oid.equals(pkcs_9_at_friendlyName)) { - bagAttr.setBagAttribute(oid, attr); + alias = ((DERBMPString)attr).getString(); + } + else if (oid.equals(pkcs_9_at_localKeyId)) + { + localId = (ASN1OctetString)attr; } - } - - if (oid.equals(pkcs_9_at_friendlyName)) - { - alias = ((DERBMPString)attr).getString(); - } - else if (oid.equals(pkcs_9_at_localKeyId)) - { - localId = (ASN1OctetString)attr; } } } @@ -1629,7 +1651,7 @@ public class PKCS12KeyStoreSpi asn1Out.writeObject(pfx); } - private static byte[] calculatePbeMac( + private byte[] calculatePbeMac( ASN1ObjectIdentifier oid, byte[] salt, int itCount, @@ -1638,13 +1660,13 @@ public class PKCS12KeyStoreSpi byte[] data) throws Exception { - SecretKeyFactory keyFact = SecretKeyFactory.getInstance(oid.getId(), bcProvider); + SecretKeyFactory keyFact = helper.createSecretKeyFactory(oid.getId()); PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount); PBEKeySpec pbeSpec = new PBEKeySpec(password); BCPBEKey key = (BCPBEKey)keyFact.generateSecret(pbeSpec); key.setTryWrongPKCS12Zero(wrongPkcs12Zero); - Mac mac = Mac.getInstance(oid.getId(), bcProvider); + Mac mac = helper.createMac(oid.getId()); mac.init(key, defParams); mac.update(data); return mac.doFinal(); @@ -1655,7 +1677,7 @@ public class PKCS12KeyStoreSpi { public BCPKCS12KeyStore() { - super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); + super(new BouncyCastleProvider(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } @@ -1664,7 +1686,7 @@ public class PKCS12KeyStoreSpi { public BCPKCS12KeyStore3DES() { - super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); + super(new BouncyCastleProvider(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java index a600604e..e69f39fd 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java @@ -12,6 +12,7 @@ import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.IvParameterSpec; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.asn1.cms.CCMParameters; import org.bouncycastle.asn1.cms.GCMParameters; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.crypto.BlockCipher; @@ -20,10 +21,12 @@ import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.engines.AESWrapEngine; import org.bouncycastle.crypto.engines.RFC3211WrapEngine; +import org.bouncycastle.crypto.engines.RFC5649WrapEngine; import org.bouncycastle.crypto.generators.Poly1305KeyGenerator; import org.bouncycastle.crypto.macs.CMac; import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.CBCBlockCipher; +import org.bouncycastle.crypto.modes.CCMBlockCipher; import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; @@ -37,7 +40,6 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; -import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Integers; public final class AES @@ -99,6 +101,15 @@ public final class AES } } + static public class CCM + extends BaseBlockCipher + { + public CCM() + { + super(new CCMBlockCipher(new AESFastEngine())); + } + } + public static class AESCMAC extends BaseMac { @@ -153,7 +164,15 @@ public final class AES } } - + public static class RFC5649Wrap + extends BaseWrapCipher + { + public RFC5649Wrap() + { + super(new RFC5649WrapEngine(new AESFastEngine())); + } + } + /** * PBEWithAES-CBC */ @@ -341,7 +360,7 @@ public final class AES try { - params = AlgorithmParameters.getInstance("AES", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("AES"); params.init(new IvParameterSpec(iv)); } catch (Exception e) @@ -353,6 +372,82 @@ public final class AES } } + public static class AlgParamGenCCM + extends BaseAlgorithmParameterGenerator + { + protected void engineInit( + AlgorithmParameterSpec genParamSpec, + SecureRandom random) + throws InvalidAlgorithmParameterException + { + throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for AES parameter generation."); + } + + protected AlgorithmParameters engineGenerateParameters() + { + byte[] iv = new byte[12]; + + if (random == null) + { + random = new SecureRandom(); + } + + random.nextBytes(iv); + + AlgorithmParameters params; + + try + { + params = createParametersInstance("CCM"); + params.init(new CCMParameters(iv, 12).getEncoded()); + } + catch (Exception e) + { + throw new RuntimeException(e.getMessage()); + } + + return params; + } + } + + public static class AlgParamGenGCM + extends BaseAlgorithmParameterGenerator + { + protected void engineInit( + AlgorithmParameterSpec genParamSpec, + SecureRandom random) + throws InvalidAlgorithmParameterException + { + throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for AES parameter generation."); + } + + protected AlgorithmParameters engineGenerateParameters() + { + byte[] nonce = new byte[12]; + + if (random == null) + { + random = new SecureRandom(); + } + + random.nextBytes(nonce); + + AlgorithmParameters params; + + try + { + params = createParametersInstance("GCM"); + params.init(new GCMParameters(nonce, 12).getEncoded()); + } + catch (Exception e) + { + throw new RuntimeException(e.getMessage()); + } + + return params; + } + } + public static class AlgParams extends IvAlgorithmParameters { @@ -377,8 +472,7 @@ public final class AES Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]); Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]); - - gcmParams = new GCMParameters((byte[])iv.invoke(paramSpec, new Object[0]), ((Integer)tLen.invoke(paramSpec, new Object[0])).intValue()); + gcmParams = new GCMParameters((byte[])iv.invoke(paramSpec, new Object[0]), ((Integer)tLen.invoke(paramSpec, new Object[0])).intValue() / 8); } catch (Exception e) { @@ -433,9 +527,84 @@ public final class AES { try { - Constructor constructor = gcmSpecClass.getConstructor(new Class[] { byte[].class, Integer.class }); + Constructor constructor = gcmSpecClass.getConstructor(new Class[] { Integer.TYPE, byte[].class }); - return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { gcmParams.getNonce(), Integers.valueOf(gcmParams.getIcvLen()) }); + return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() }); + } + catch (NoSuchMethodException e) + { + throw new InvalidParameterSpecException("no constructor found!"); // should never happen + } + catch (Exception e) + { + throw new InvalidParameterSpecException("construction failed: " + e.getMessage()); // should never happen + } + } + + throw new InvalidParameterSpecException("unknown parameter spec: " + paramSpec.getName()); + } + } + + public static class AlgParamsCCM + extends BaseAlgorithmParameters + { + private CCMParameters ccmParams; + + protected void engineInit(AlgorithmParameterSpec paramSpec) + throws InvalidParameterSpecException + { + throw new InvalidParameterSpecException("No supported AlgorithmParameterSpec for AES parameter generation."); + } + + protected void engineInit(byte[] params) + throws IOException + { + ccmParams = CCMParameters.getInstance(params); + } + + protected void engineInit(byte[] params, String format) + throws IOException + { + if (!isASN1FormatString(format)) + { + throw new IOException("unknown format specified"); + } + + ccmParams = CCMParameters.getInstance(params); + } + + protected byte[] engineGetEncoded() + throws IOException + { + return ccmParams.getEncoded(); + } + + protected byte[] engineGetEncoded(String format) + throws IOException + { + if (!isASN1FormatString(format)) + { + throw new IOException("unknown format specified"); + } + + return ccmParams.getEncoded(); + } + + protected String engineToString() + { + return "CCM"; + } + + protected AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec) + throws InvalidParameterSpecException + { + if (gcmSpecClass != null) + { + try + { + Constructor constructor = gcmSpecClass.getConstructor(new Class[] { Integer.TYPE, byte[].class }); + + return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(ccmParams.getIcvLen() * 8), ccmParams.getNonce() }); } catch (NoSuchMethodException e) { @@ -484,6 +653,11 @@ public final class AES provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes192_GCM, "GCM"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes256_GCM, "GCM"); + provider.addAlgorithm("AlgorithmParameters.CCM", PREFIX + "$AlgParamsCCM"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes128_CCM, "CCM"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes192_CCM, "CCM"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes256_CCM, "CCM"); + provider.addAlgorithm("AlgorithmParameterGenerator.AES", PREFIX + "$AlgParamGen"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + wrongAES128, "AES"); provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + wrongAES192, "AES"); @@ -512,7 +686,24 @@ public final class AES provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes128_wrap, "AESWRAP"); provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes192_wrap, "AESWRAP"); provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes256_wrap, "AESWRAP"); + provider.addAlgorithm("Cipher.AESRFC3211WRAP", PREFIX + "$RFC3211Wrap"); + provider.addAlgorithm("Cipher.AESRFC5649WRAP", PREFIX + "$RFC5649Wrap"); + + provider.addAlgorithm("AlgorithmParameterGenerator.CCM", PREFIX + "$AlgParamGenCCM"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes128_CCM, "CCM"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes192_CCM, "CCM"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes256_CCM, "CCM"); + + provider.addAlgorithm("Cipher.CCM", PREFIX + "$CCM"); + provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes128_CCM, "CCM"); + provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes192_CCM, "CCM"); + provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes256_CCM, "CCM"); + + provider.addAlgorithm("AlgorithmParameterGenerator.GCM", PREFIX + "$AlgParamGenGCM"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes128_GCM, "GCM"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes192_GCM, "GCM"); + provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes256_GCM, "GCM"); provider.addAlgorithm("Cipher.GCM", PREFIX + "$GCM"); provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes128_GCM, "GCM"); @@ -539,6 +730,12 @@ public final class AES provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_wrap, PREFIX + "$KeyGen128"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_wrap, PREFIX + "$KeyGen192"); provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_wrap, PREFIX + "$KeyGen256"); + provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_GCM, PREFIX + "$KeyGen128"); + provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_GCM, PREFIX + "$KeyGen192"); + provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_GCM, PREFIX + "$KeyGen256"); + provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_CCM, PREFIX + "$KeyGen128"); + provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_CCM, PREFIX + "$KeyGen192"); + provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_CCM, PREFIX + "$KeyGen256"); provider.addAlgorithm("Mac.AESCMAC", PREFIX + "$AESCMAC"); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/CAST5.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/CAST5.java index f360a41f..7fa4ce49 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/CAST5.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/CAST5.java @@ -81,7 +81,7 @@ public final class CAST5 try { - params = AlgorithmParameters.getInstance("CAST5", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("CAST5"); params.init(new IvParameterSpec(iv)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Camellia.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Camellia.java index 95b51567..5dde846a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Camellia.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Camellia.java @@ -25,7 +25,6 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; -import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class Camellia { @@ -169,7 +168,7 @@ public final class Camellia try { - params = AlgorithmParameters.getInstance("Camellia", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("Camellia"); params.init(new IvParameterSpec(iv)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java index f3411950..2ab70869 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java @@ -40,7 +40,6 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory; import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.symmetric.util.PBE; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; -import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class DES { @@ -179,7 +178,7 @@ public final class DES try { - params = AlgorithmParameters.getInstance("DES", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("DES"); params.init(new IvParameterSpec(iv)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java index 0f53e504..d7a52db2 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java @@ -31,7 +31,6 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory; import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; -import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class DESede { @@ -267,7 +266,7 @@ public final class DESede try { - params = AlgorithmParameters.getInstance("DES", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("DES"); params.init(new IvParameterSpec(iv)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GOST28147.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GOST28147.java index b3ff96b3..a849a187 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GOST28147.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GOST28147.java @@ -21,7 +21,6 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; -import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class GOST28147 { @@ -90,7 +89,7 @@ public final class GOST28147 SecureRandom random) throws InvalidAlgorithmParameterException { - throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for AES parameter generation."); + throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for GOST28147 parameter generation."); } protected AlgorithmParameters engineGenerateParameters() @@ -108,7 +107,7 @@ public final class GOST28147 try { - params = AlgorithmParameters.getInstance("GOST28147", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("GOST28147"); params.init(new IvParameterSpec(iv)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/IDEA.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/IDEA.java index 4248eb8d..69100515 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/IDEA.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/IDEA.java @@ -25,7 +25,6 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; -import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class IDEA { @@ -104,7 +103,7 @@ public final class IDEA try { - params = AlgorithmParameters.getInstance("IDEA", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("IDEA"); params.init(new IvParameterSpec(iv)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Noekeon.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Noekeon.java index a92f21dd..1fefd14b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Noekeon.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Noekeon.java @@ -20,7 +20,6 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; -import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class Noekeon { @@ -105,7 +104,7 @@ public final class Noekeon try { - params = AlgorithmParameters.getInstance("Noekeon", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("Noekeon"); params.init(new IvParameterSpec(iv)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC2.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC2.java index 4160999f..18d780d7 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC2.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC2.java @@ -28,7 +28,6 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; -import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; public final class RC2 @@ -235,7 +234,7 @@ public final class RC2 try { - params = AlgorithmParameters.getInstance("RC2", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("RC2"); params.init(new IvParameterSpec(iv)); } catch (Exception e) @@ -247,7 +246,7 @@ public final class RC2 { try { - params = AlgorithmParameters.getInstance("RC2", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("RC2"); params.init(spec); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC5.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC5.java index aa63a951..2f1d83a1 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC5.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC5.java @@ -108,7 +108,7 @@ public final class RC5 try { - params = AlgorithmParameters.getInstance("RC5", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("RC5"); params.init(new IvParameterSpec(iv)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC6.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC6.java index 114c40b6..674ea489 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC6.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC6.java @@ -136,7 +136,7 @@ public final class RC6 try { - params = AlgorithmParameters.getInstance("RC6", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("RC6"); params.init(new IvParameterSpec(iv)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SEED.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SEED.java index e7e257c3..510d92ee 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SEED.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SEED.java @@ -24,7 +24,6 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; -import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class SEED { @@ -127,7 +126,7 @@ public final class SEED try { - params = AlgorithmParameters.getInstance("SEED", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("SEED"); params.init(new IvParameterSpec(iv)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Shacal2.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Shacal2.java index 81666af7..ea4ccda1 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Shacal2.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Shacal2.java @@ -17,7 +17,6 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; -import org.bouncycastle.jce.provider.BouncyCastleProvider; public final class Shacal2 { @@ -84,7 +83,7 @@ public final class Shacal2 try { - params = AlgorithmParameters.getInstance("Shacal2", BouncyCastleProvider.PROVIDER_NAME); + params = createParametersInstance("Shacal2"); params.init(new IvParameterSpec(iv)); } catch (Exception e) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SipHash.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SipHash.java index 25fb887e..5a115318 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SipHash.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SipHash.java @@ -1,6 +1,8 @@ package org.bouncycastle.jcajce.provider.symmetric; +import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; @@ -9,11 +11,11 @@ public final class SipHash private SipHash() { } - - public static class Mac + + public static class Mac24 extends BaseMac { - public Mac() + public Mac24() { super(new org.bouncycastle.crypto.macs.SipHash()); } @@ -28,6 +30,15 @@ public final class SipHash } } + public static class KeyGen + extends BaseKeyGenerator + { + public KeyGen() + { + super("SipHash", 128, new CipherKeyGenerator()); + } + } + public static class Mappings extends AlgorithmProvider { @@ -39,9 +50,13 @@ public final class SipHash public void configure(ConfigurableProvider provider) { - provider.addAlgorithm("Mac.SIPHASH", PREFIX + "$Mac"); - provider.addAlgorithm("Alg.Alias.Mac.SIPHASH-2-4", "SIPHASH"); + provider.addAlgorithm("Mac.SIPHASH-2-4", PREFIX + "$Mac24"); + provider.addAlgorithm("Alg.Alias.Mac.SIPHASH", "SIPHASH-2-4"); provider.addAlgorithm("Mac.SIPHASH-4-8", PREFIX + "$Mac48"); + + provider.addAlgorithm("KeyGenerator.SIPHASH", PREFIX + "$KeyGen"); + provider.addAlgorithm("Alg.Alias.KeyGenerator.SIPHASH-2-4", "SIPHASH"); + provider.addAlgorithm("Alg.Alias.KeyGenerator.SIPHASH-4-8", "SIPHASH"); } } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameterGenerator.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameterGenerator.java index 63d6548e..296d6925 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameterGenerator.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameterGenerator.java @@ -1,14 +1,32 @@ package org.bouncycastle.jcajce.provider.symmetric.util; import java.security.AlgorithmParameterGeneratorSpi; +import java.security.AlgorithmParameters; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.security.SecureRandom; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; + public abstract class BaseAlgorithmParameterGenerator extends AlgorithmParameterGeneratorSpi { + private final JcaJceHelper helper = new BCJcaJceHelper(); + protected SecureRandom random; protected int strength = 1024; + public BaseAlgorithmParameterGenerator() + { + } + + protected final AlgorithmParameters createParametersInstance(String algorithm) + throws NoSuchAlgorithmException, NoSuchProviderException + { + return helper.createAlgorithmParameters(algorithm); + } + protected void engineInit( int strength, SecureRandom random) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java index 943fa186..08ddfb4d 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java @@ -1,5 +1,6 @@ package org.bouncycastle.jcajce.provider.symmetric.util; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.security.AlgorithmParameters; @@ -162,6 +163,11 @@ public class BaseBlockCipher protected byte[] engineGetIV() { + if (aeadParams != null) + { + return aeadParams.getNonce(); + } + return (ivParam != null) ? ivParam.getIV() : null; } @@ -185,7 +191,7 @@ public class BaseBlockCipher { try { - engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, BouncyCastleProvider.PROVIDER_NAME); + engineParams = createParametersInstance(pbeAlgorithm); engineParams.init(pbeSpec); } catch (Exception e) @@ -204,7 +210,7 @@ public class BaseBlockCipher try { - engineParams = AlgorithmParameters.getInstance(name, BouncyCastleProvider.PROVIDER_NAME); + engineParams = createParametersInstance(name); engineParams.init(ivParam.getIV()); } catch (Exception e) @@ -216,7 +222,7 @@ public class BaseBlockCipher { try { - engineParams = AlgorithmParameters.getInstance("GCM", BouncyCastleProvider.PROVIDER_NAME); + engineParams = createParametersInstance("GCM"); engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize()).getEncoded()); } catch (Exception e) @@ -334,7 +340,9 @@ public class BaseBlockCipher { if (engineProvider != null) { - // Nonce restricted to max 120 bits over 128 bit block cipher since draft-irtf-cfrg-ocb-03 + /* + * RFC 7253 4.2. Nonce is a string of no more than 120 bits + */ ivLength = 15; cipher = new AEADGenericBlockCipher(new OCBBlockCipher(baseEngine, engineProvider.get())); } @@ -814,10 +822,6 @@ public class BaseBlockCipher { throw new IllegalBlockSizeException(e.getMessage()); } - catch (InvalidCipherTextException e) - { - throw new BadPaddingException(e.getMessage()); - } if (len == tmp.length) { @@ -858,10 +862,6 @@ public class BaseBlockCipher { throw new IllegalBlockSizeException(e.getMessage()); } - catch (InvalidCipherTextException e) - { - throw new BadPaddingException(e.getMessage()); - } } private boolean isAEADModeName( @@ -898,7 +898,8 @@ public class BaseBlockCipher throws DataLengthException; public int doFinal(byte[] out, int outOff) - throws IllegalStateException, InvalidCipherTextException; + throws IllegalStateException, + BadPaddingException; } private static class BufferedGenericBlockCipher @@ -967,15 +968,48 @@ public class BaseBlockCipher return cipher.processBytes(in, inOff, len, out, outOff); } - public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException + public int doFinal(byte[] out, int outOff) throws IllegalStateException, BadPaddingException { - return cipher.doFinal(out, outOff); + try + { + return cipher.doFinal(out, outOff); + } + catch (InvalidCipherTextException e) + { + throw new BadPaddingException(e.getMessage()); + } } } private static class AEADGenericBlockCipher implements GenericBlockCipher { + private static final Constructor aeadBadTagConstructor; + + static { + Class aeadBadTagClass = lookup("javax.crypto.AEADBadTagException"); + if (aeadBadTagClass != null) + { + aeadBadTagConstructor = findExceptionConstructor(aeadBadTagClass); + } + else + { + aeadBadTagConstructor = null; + } + } + + private static Constructor findExceptionConstructor(Class clazz) + { + try + { + return clazz.getConstructor(new Class[]{String.class}); + } + catch (Exception e) + { + return null; + } + } + private AEADBlockCipher cipher; AEADGenericBlockCipher(AEADBlockCipher cipher) @@ -1029,9 +1063,33 @@ public class BaseBlockCipher return cipher.processBytes(in, inOff, len, out, outOff); } - public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException + public int doFinal(byte[] out, int outOff) throws IllegalStateException, BadPaddingException { - return cipher.doFinal(out, outOff); + try + { + return cipher.doFinal(out, outOff); + } + catch (InvalidCipherTextException e) + { + if (aeadBadTagConstructor != null) + { + BadPaddingException aeadBadTag = null; + try + { + aeadBadTag = (BadPaddingException)aeadBadTagConstructor + .newInstance(new Object[]{e.getMessage()}); + } + catch (Exception i) + { + // Shouldn't happen, but fall through to BadPaddingException + } + if (aeadBadTag != null) + { + throw aeadBadTag; + } + } + throw new BadPaddingException(e.getMessage()); + } } } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java index 31ba38f4..665bcabb 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java @@ -5,6 +5,7 @@ import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; +import java.security.Provider; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; @@ -17,10 +18,8 @@ import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.RC5ParameterSpec; -import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.StreamBlockCipher; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; @@ -57,15 +56,6 @@ public class BaseStreamCipher this.ivLength = ivLength; } - protected BaseStreamCipher( - BlockCipher engine, - int ivLength) - { - this.ivLength = ivLength; - - cipher = new StreamBlockCipher(engine); - } - protected int engineGetBlockSize() { return 0; @@ -96,7 +86,7 @@ public class BaseStreamCipher { try { - AlgorithmParameters engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, BouncyCastleProvider.PROVIDER_NAME); + AlgorithmParameters engineParams = createParametersInstance(pbeAlgorithm); engineParams.init(pbeSpec); return engineParams; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java index 4492a7bd..5d9aea03 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java @@ -8,7 +8,9 @@ import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; +import java.security.Provider; import java.security.SecureRandom; +import java.security.Security; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; @@ -32,6 +34,9 @@ import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.provider.BouncyCastleProvider; public abstract class BaseWrapCipher @@ -61,6 +66,8 @@ public abstract class BaseWrapCipher private int ivSize; private byte[] iv; + private final JcaJceHelper helper = new BCJcaJceHelper(); + protected BaseWrapCipher() { } @@ -106,6 +113,12 @@ public abstract class BaseWrapCipher return null; } + protected final AlgorithmParameters createParametersInstance(String algorithm) + throws NoSuchAlgorithmException, NoSuchProviderException + { + return helper.createAlgorithmParameters(algorithm); + } + protected void engineSetMode( String mode) throws NoSuchAlgorithmException @@ -164,6 +177,11 @@ public abstract class BaseWrapCipher param = new ParametersWithIV(param, iv); } + if (random != null) + { + param = new ParametersWithRandom(param, random); + } + switch (opmode) { case Cipher.WRAP_MODE: @@ -361,7 +379,7 @@ public abstract class BaseWrapCipher { try { - KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); + KeyFactory kf = helper.createKeyFactory(wrappedKeyAlgorithm); if (wrappedKeyType == Cipher.PUBLIC_KEY) { |