diff options
author | Sergio Giro <sgiro@google.com> | 2015-04-09 14:10:16 +0100 |
---|---|---|
committer | Sergio Giro <sgiro@google.com> | 2015-04-20 15:41:23 +0100 |
commit | 028ab6e01e3b911024b9b9243e9a0f4ac377c0fa (patch) | |
tree | 35d98bf60cbe7a6487bd0014728eb263e89004bb /bcprov/src/main/java | |
parent | b44aff7a3b88138f0070630d467c7527cd90c2f3 (diff) | |
download | android_external_bouncycastle-028ab6e01e3b911024b9b9243e9a0f4ac377c0fa.tar.gz android_external_bouncycastle-028ab6e01e3b911024b9b9243e9a0f4ac377c0fa.tar.bz2 android_external_bouncycastle-028ab6e01e3b911024b9b9243e9a0f4ac377c0fa.zip |
bouncycastle: upgrade to version 1.52
Change-Id: I227db8e458e67af46ccb1c07bfca77a733f25979
Diffstat (limited to 'bcprov/src/main/java')
90 files changed, 2812 insertions, 1721 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java index d760a1f..bbe5ae1 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java @@ -153,7 +153,7 @@ public class ASN1GeneralizedTime /** * return the time - always in the form of * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm). - * <p/> + * <p> * Normally in a certificate we would expect "Z" rather than "GMT", * however adding the "GMT" means we can just use: * <pre> @@ -161,6 +161,7 @@ public class ASN1GeneralizedTime * </pre> * To read in the time and get a date which is compatible with our local * time zone. + * </p> */ public String getTime() { diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java index cfda1a6..304866f 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java @@ -3,11 +3,13 @@ package org.bouncycastle.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; +import org.bouncycastle.util.Encodable; + /** * Base class for defining an ASN.1 object. */ public abstract class ASN1Object - implements ASN1Encodable + implements ASN1Encodable, Encodable { /** * Return the default BER or DER encoding for this object. diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java index 895f002..b4d263a 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java @@ -481,22 +481,17 @@ public abstract class ASN1Set return len == a.length; } - private byte[] getEncoded( + private byte[] getDEREncoded( ASN1Encodable obj) { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - ASN1OutputStream aOut = new ASN1OutputStream(bOut); - try { - aOut.writeObject(obj); + return obj.toASN1Primitive().getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new IllegalArgumentException("cannot encode object added to SET"); } - - return bOut.toByteArray(); } protected void sort() @@ -513,13 +508,13 @@ public abstract class ASN1Set { int index = 0; int swapIndex = 0; - byte[] a = getEncoded((ASN1Encodable)set.elementAt(0)); + byte[] a = getDEREncoded((ASN1Encodable)set.elementAt(0)); swapped = false; while (index != lastSwap) { - byte[] b = getEncoded((ASN1Encodable)set.elementAt(index + 1)); + byte[] b = getDEREncoded((ASN1Encodable)set.elementAt(index + 1)); if (lessThanOrEqual(a, b)) { diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java index dfc3121..098656c 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java @@ -35,9 +35,16 @@ public interface MiscObjectIdentifiers static final ASN1ObjectIdentifier verisign = new ASN1ObjectIdentifier("2.16.840.1.113733.1"); /** Verisign CZAG (Country,Zip,Age,Gender) Extension OID: 2.16.840.1.113733.1.6.3 */ - static final ASN1ObjectIdentifier verisignCzagExtension = verisign.branch("6.3"); + static final ASN1ObjectIdentifier verisignCzagExtension = verisign.branch("6.3"); + + static final ASN1ObjectIdentifier verisignPrivate_6_9 = verisign.branch("6.9"); + static final ASN1ObjectIdentifier verisignOnSiteJurisdictionHash = verisign.branch("6.11"); + static final ASN1ObjectIdentifier verisignBitString_6_13 = verisign.branch("6.13"); + /** Verisign D&B D-U-N-S number Extension OID: 2.16.840.1.113733.1.6.15 */ - static final ASN1ObjectIdentifier verisignDnbDunsNumber = verisign.branch("6.15"); + static final ASN1ObjectIdentifier verisignDnbDunsNumber = verisign.branch("6.15"); + + static final ASN1ObjectIdentifier verisignIssStrongCrypto = verisign.branch("8.1"); // // Novell diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java index d2acd30..fb418ae 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java @@ -67,18 +67,18 @@ public class CertificationRequestInfo * @param attributes any attributes to be associated with the request. */ public CertificationRequestInfo( - X500Name subject, + X500Name subject, SubjectPublicKeyInfo pkInfo, ASN1Set attributes) { - this.subject = subject; - this.subjectPKInfo = pkInfo; - this.attributes = attributes; - - if ((subject == null) || (version == null) || (subjectPKInfo == null)) + if ((subject == null) || (pkInfo == null)) { throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator."); } + + this.subject = subject; + this.subjectPKInfo = pkInfo; + this.attributes = attributes; } /** @@ -89,14 +89,14 @@ public class CertificationRequestInfo SubjectPublicKeyInfo pkInfo, ASN1Set attributes) { - this.subject = X500Name.getInstance(subject.toASN1Primitive()); - this.subjectPKInfo = pkInfo; - this.attributes = attributes; - - if ((subject == null) || (version == null) || (subjectPKInfo == null)) + if ((subject == null) || (pkInfo == null)) { throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator."); } + + this.subject = X500Name.getInstance(subject.toASN1Primitive()); + this.subjectPKInfo = pkInfo; + this.attributes = attributes; } /** diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java index df2238a..269466d 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java @@ -47,10 +47,26 @@ public class ECPrivateKey return null; } + /** + * @deprecated use constructor which takes orderBitLength to guarantee correct encoding. + */ public ECPrivateKey( BigInteger key) { - byte[] bytes = BigIntegers.asUnsignedByteArray(key); + this(key.bitLength(), key); + } + + /** + * Base constructor. + * + * @param orderBitLength the bitLength of the order of the curve. + * @param key the private key value. + */ + public ECPrivateKey( + int orderBitLength, + BigInteger key) + { + byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key); ASN1EncodableVector v = new ASN1EncodableVector(); @@ -60,6 +76,9 @@ public class ECPrivateKey seq = new DERSequence(v); } + /** + * @deprecated use constructor which takes orderBitLength to guarantee correct encoding. + */ public ECPrivateKey( BigInteger key, ASN1Encodable parameters) @@ -67,12 +86,32 @@ public class ECPrivateKey this(key, null, parameters); } + /** + * @deprecated use constructor which takes orderBitLength to guarantee correct encoding. + */ + public ECPrivateKey( + BigInteger key, + DERBitString publicKey, + ASN1Encodable parameters) + { + this(key.bitLength(), key, publicKey, parameters); + } + + public ECPrivateKey( + int orderBitLength, + BigInteger key, + ASN1Encodable parameters) + { + this(orderBitLength, key, null, parameters); + } + public ECPrivateKey( + int orderBitLength, BigInteger key, DERBitString publicKey, ASN1Encodable parameters) { - byte[] bytes = BigIntegers.asUnsignedByteArray(key); + byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key); ASN1EncodableVector v = new ASN1EncodableVector(); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java index b4f1794..9df924c 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java @@ -322,7 +322,10 @@ public class IETFUtils } else { - IETFUtils.appendTypeAndValue(buf, rdn.getFirst(), oidSymbols); + if (rdn.getFirst() != null) + { + IETFUtils.appendTypeAndValue(buf, rdn.getFirst(), oidSymbols); + } } } @@ -438,7 +441,7 @@ public class IETFUtils public static String canonicalize(String s) { - String value = Strings.toLowerCase(s.trim()); + String value = Strings.toLowerCase(s); if (value.length() > 0 && value.charAt(0) == '#') { @@ -446,7 +449,27 @@ public class IETFUtils if (obj instanceof ASN1String) { - value = Strings.toLowerCase(((ASN1String)obj).getString().trim()); + value = Strings.toLowerCase(((ASN1String)obj).getString()); + } + } + + if (value.length() > 1) + { + int start = 0; + while (start + 1 < value.length() && value.charAt(start) == '\\' && value.charAt(start + 1) == ' ') + { + start += 2; + } + + int end = value.length() - 1; + while (end - 1 > 0 && value.charAt(end - 1) == '\\' && value.charAt(end) == ' ') + { + end -= 2; + } + + if (start > 0 || end < value.length() - 1) + { + value = value.substring(start, end + 1); } } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java index 1aeed15..6508f93 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java @@ -43,8 +43,9 @@ public class Extensions /** * Constructor from ASN1Sequence. - * <p/> - * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString) + * <p> + * The extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString) + * </p> */ private Extensions( ASN1Sequence seq) diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java index eabf90e..53a4373 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java @@ -63,78 +63,78 @@ public interface X9ObjectIdentifiers /** * Named curves base * <p> - * OID: 1.2.840.10045.1 + * OID: 1.2.840.10045.3 */ static final ASN1ObjectIdentifier ellipticCurve = ansi_X9_62.branch("3"); /** * Two Curves * <p> - * OID: 1.2.840.10045.1.0 + * OID: 1.2.840.10045.3.0 */ static final ASN1ObjectIdentifier cTwoCurve = ellipticCurve.branch("0"); - /** Two Curve c2pnb163v1, OID: 1.2.840.10045.1.0.1 */ + /** Two Curve c2pnb163v1, OID: 1.2.840.10045.3.0.1 */ static final ASN1ObjectIdentifier c2pnb163v1 = cTwoCurve.branch("1"); - /** Two Curve c2pnb163v2, OID: 1.2.840.10045.1.0.2 */ + /** Two Curve c2pnb163v2, OID: 1.2.840.10045.3.0.2 */ static final ASN1ObjectIdentifier c2pnb163v2 = cTwoCurve.branch("2"); - /** Two Curve c2pnb163v3, OID: 1.2.840.10045.1.0.3 */ + /** Two Curve c2pnb163v3, OID: 1.2.840.10045.3.0.3 */ static final ASN1ObjectIdentifier c2pnb163v3 = cTwoCurve.branch("3"); - /** Two Curve c2pnb176w1, OID: 1.2.840.10045.1.0.4 */ + /** Two Curve c2pnb176w1, OID: 1.2.840.10045.3.0.4 */ static final ASN1ObjectIdentifier c2pnb176w1 = cTwoCurve.branch("4"); - /** Two Curve c2tnb191v1, OID: 1.2.840.10045.1.0.5 */ + /** Two Curve c2tnb191v1, OID: 1.2.840.10045.3.0.5 */ static final ASN1ObjectIdentifier c2tnb191v1 = cTwoCurve.branch("5"); - /** Two Curve c2tnb191v2, OID: 1.2.840.10045.1.0.6 */ + /** Two Curve c2tnb191v2, OID: 1.2.840.10045.3.0.6 */ static final ASN1ObjectIdentifier c2tnb191v2 = cTwoCurve.branch("6"); - /** Two Curve c2tnb191v3, OID: 1.2.840.10045.1.0.7 */ + /** Two Curve c2tnb191v3, OID: 1.2.840.10045.3.0.7 */ static final ASN1ObjectIdentifier c2tnb191v3 = cTwoCurve.branch("7"); - /** Two Curve c2onb191v4, OID: 1.2.840.10045.1.0.8 */ + /** Two Curve c2onb191v4, OID: 1.2.840.10045.3.0.8 */ static final ASN1ObjectIdentifier c2onb191v4 = cTwoCurve.branch("8"); - /** Two Curve c2onb191v5, OID: 1.2.840.10045.1.0.9 */ + /** Two Curve c2onb191v5, OID: 1.2.840.10045.3.0.9 */ static final ASN1ObjectIdentifier c2onb191v5 = cTwoCurve.branch("9"); - /** Two Curve c2pnb208w1, OID: 1.2.840.10045.1.0.10 */ + /** Two Curve c2pnb208w1, OID: 1.2.840.10045.3.0.10 */ static final ASN1ObjectIdentifier c2pnb208w1 = cTwoCurve.branch("10"); - /** Two Curve c2tnb239v1, OID: 1.2.840.10045.1.0.11 */ + /** Two Curve c2tnb239v1, OID: 1.2.840.10045.3.0.11 */ static final ASN1ObjectIdentifier c2tnb239v1 = cTwoCurve.branch("11"); - /** Two Curve c2tnb239v2, OID: 1.2.840.10045.1.0.12 */ + /** Two Curve c2tnb239v2, OID: 1.2.840.10045.3.0.12 */ static final ASN1ObjectIdentifier c2tnb239v2 = cTwoCurve.branch("12"); - /** Two Curve c2tnb239v3, OID: 1.2.840.10045.1.0.13 */ + /** Two Curve c2tnb239v3, OID: 1.2.840.10045.3.0.13 */ static final ASN1ObjectIdentifier c2tnb239v3 = cTwoCurve.branch("13"); - /** Two Curve c2onb239v4, OID: 1.2.840.10045.1.0.14 */ + /** Two Curve c2onb239v4, OID: 1.2.840.10045.3.0.14 */ static final ASN1ObjectIdentifier c2onb239v4 = cTwoCurve.branch("14"); - /** Two Curve c2onb239v5, OID: 1.2.840.10045.1.0.15 */ + /** Two Curve c2onb239v5, OID: 1.2.840.10045.3.0.15 */ static final ASN1ObjectIdentifier c2onb239v5 = cTwoCurve.branch("15"); - /** Two Curve c2pnb272w1, OID: 1.2.840.10045.1.0.16 */ + /** Two Curve c2pnb272w1, OID: 1.2.840.10045.3.0.16 */ static final ASN1ObjectIdentifier c2pnb272w1 = cTwoCurve.branch("16"); - /** Two Curve c2pnb304w1, OID: 1.2.840.10045.1.0.17 */ + /** Two Curve c2pnb304w1, OID: 1.2.840.10045.3.0.17 */ static final ASN1ObjectIdentifier c2pnb304w1 = cTwoCurve.branch("17"); - /** Two Curve c2tnb359v1, OID: 1.2.840.10045.1.0.18 */ + /** Two Curve c2tnb359v1, OID: 1.2.840.10045.3.0.18 */ static final ASN1ObjectIdentifier c2tnb359v1 = cTwoCurve.branch("18"); - /** Two Curve c2pnb368w1, OID: 1.2.840.10045.1.0.19 */ + /** Two Curve c2pnb368w1, OID: 1.2.840.10045.3.0.19 */ static final ASN1ObjectIdentifier c2pnb368w1 = cTwoCurve.branch("19"); - /** Two Curve c2tnb431r1, OID: 1.2.840.10045.1.0.20 */ + /** Two Curve c2tnb431r1, OID: 1.2.840.10045.3.0.20 */ static final ASN1ObjectIdentifier c2tnb431r1 = cTwoCurve.branch("20"); /** * Prime Curves * <p> - * OID: 1.2.840.10045.1.1 + * OID: 1.2.840.10045.3.1 */ static final ASN1ObjectIdentifier primeCurve = ellipticCurve.branch("1"); - /** Prime Curve prime192v1, OID: 1.2.840.10045.1.1.1 */ + /** Prime Curve prime192v1, OID: 1.2.840.10045.3.1.1 */ static final ASN1ObjectIdentifier prime192v1 = primeCurve.branch("1"); - /** Prime Curve prime192v2, OID: 1.2.840.10045.1.1.2 */ + /** Prime Curve prime192v2, OID: 1.2.840.10045.3.1.2 */ static final ASN1ObjectIdentifier prime192v2 = primeCurve.branch("2"); - /** Prime Curve prime192v3, OID: 1.2.840.10045.1.1.3 */ + /** Prime Curve prime192v3, OID: 1.2.840.10045.3.1.3 */ static final ASN1ObjectIdentifier prime192v3 = primeCurve.branch("3"); - /** Prime Curve prime239v1, OID: 1.2.840.10045.1.1.4 */ + /** Prime Curve prime239v1, OID: 1.2.840.10045.3.1.4 */ static final ASN1ObjectIdentifier prime239v1 = primeCurve.branch("4"); - /** Prime Curve prime239v2, OID: 1.2.840.10045.1.1.5 */ + /** Prime Curve prime239v2, OID: 1.2.840.10045.3.1.5 */ static final ASN1ObjectIdentifier prime239v2 = primeCurve.branch("5"); - /** Prime Curve prime239v3, OID: 1.2.840.10045.1.1.6 */ + /** Prime Curve prime239v3, OID: 1.2.840.10045.3.1.6 */ static final ASN1ObjectIdentifier prime239v3 = primeCurve.branch("6"); - /** Prime Curve prime256v1, OID: 1.2.840.10045.1.1.7 */ + /** Prime Curve prime256v1, OID: 1.2.840.10045.3.1.7 */ static final ASN1ObjectIdentifier prime256v1 = primeCurve.branch("7"); /** diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java index 8e41e49..39f59da 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java @@ -141,7 +141,7 @@ public class BufferedBlockCipher } /** - * process a single byte, producing an output block if neccessary. + * process a single byte, producing an output block if necessary. * * @param in the input byte. * @param out the space for any output that might be produced. diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java index c78b1a5..7ba71c7 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java @@ -70,7 +70,7 @@ public class PKCS1Encoding * @param cipher * The cipher to use for cryptographic operation. * @param fallback - * The fallback value, we don't to a arraycopy here. + * The fallback value, we don't do an arraycopy here. */ public PKCS1Encoding( AsymmetricBlockCipher cipher, @@ -350,7 +350,8 @@ public class PKCS1Encoding * If the length of the expected plaintext is known, we use a constant-time decryption. * If the decryption fails, we return a random value. */ - if (this.pLen != -1) { + if (this.pLen != -1) + { return this.decodeBlockOrRandom(in, inOff, inLen); } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java index 5d316ac..6d3e5ac 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java @@ -9,8 +9,21 @@ package org.bouncycastle.crypto.engines; public class AESWrapEngine extends RFC3394WrapEngine { + /** + * Create a regular AESWrapEngine specifying the encrypt for wrapping, decrypt for unwrapping. + */ public AESWrapEngine() { super(new AESEngine()); } + + /** + * Create an AESWrapEngine where the underlying cipher is set to decrypt for wrapping, encrypt for unwrapping. + * + * @param useReverseDirection true if underlying cipher should be used in decryption mode, false otherwise. + */ + public AESWrapEngine(boolean useReverseDirection) + { + super(new AESEngine(), useReverseDirection); + } } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java index cfd86fb..d2886e7 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java @@ -21,6 +21,7 @@ public class RFC3394WrapEngine implements Wrapper { private BlockCipher engine; + private boolean wrapCipherMode; private KeyParameter param; private boolean forWrapping; @@ -28,9 +29,26 @@ public class RFC3394WrapEngine (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6 }; + /** + * Create a RFC 3394 WrapEngine specifying the encrypt for wrapping, decrypt for unwrapping. + * + * @param engine the block cipher to be used for wrapping. + */ public RFC3394WrapEngine(BlockCipher engine) { + this(engine, false); + } + + /** + * Create a RFC 3394 WrapEngine specifying the direction for wrapping and unwrapping.. + * + * @param engine the block cipher to be used for wrapping. + * @param useReverseDirection true if engine should be used in decryption mode for wrapping, false otherwise. + */ + public RFC3394WrapEngine(BlockCipher engine, boolean useReverseDirection) + { this.engine = engine; + this.wrapCipherMode = (useReverseDirection) ? false : true; } public void init( @@ -87,7 +105,7 @@ public class RFC3394WrapEngine System.arraycopy(iv, 0, block, 0, iv.length); System.arraycopy(in, inOff, block, iv.length, inLen); - engine.init(true, param); + engine.init(wrapCipherMode, param); for (int j = 0; j != 6; j++) { @@ -140,7 +158,7 @@ public class RFC3394WrapEngine System.arraycopy(in, inOff, a, 0, iv.length); System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length); - engine.init(false, param); + engine.init(!wrapCipherMode, param); n = n - 1; diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java index 928c6a6..7277045 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java @@ -1,5 +1,7 @@ package org.bouncycastle.crypto.generators; +import java.math.BigInteger; + import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; @@ -8,8 +10,6 @@ import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.math.ec.WNafUtil; -import java.math.BigInteger; - /** * an RSA key pair generator. */ @@ -27,96 +27,118 @@ public class RSAKeyPairGenerator public AsymmetricCipherKeyPair generateKeyPair() { - BigInteger p, q, n, d, e, pSub1, qSub1, phi; + AsymmetricCipherKeyPair result = null; + boolean done = false; - // - // p and q values should have a length of half the strength in bits - // - int strength = param.getStrength(); - int qBitlength = strength >>> 1; - int pBitlength = strength - qBitlength; - int mindiffbits = strength / 3; - int minWeight = strength >>> 2; + while (!done) + { + BigInteger p, q, n, d, e, pSub1, qSub1, phi, lcm, dLowerBound; - e = param.getPublicExponent(); + // + // p and q values should have a length of half the strength in bits + // + int strength = param.getStrength(); + int pbitlength = (strength + 1) / 2; + int qbitlength = strength - pbitlength; + int mindiffbits = strength / 3; + int minWeight = strength >> 2; - // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes) - // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") + e = param.getPublicExponent(); - p = chooseRandomPrime(pBitlength, e); + // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes) + // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") - // - // generate a modulus of the required length - // - for (;;) - { - q = chooseRandomPrime(qBitlength, e); - - // p and q should not be too close together (or equal!) - BigInteger diff = q.subtract(p).abs(); - if (diff.bitLength() < mindiffbits) - { - continue; - } + p = chooseRandomPrime(pbitlength, e); // - // calculate the modulus + // generate a modulus of the required length // - n = p.multiply(q); - - if (n.bitLength() != strength) + for (;;) { + q = chooseRandomPrime(qbitlength, e); + + // p and q should not be too close together (or equal!) + BigInteger diff = q.subtract(p).abs(); + if (diff.bitLength() < mindiffbits) + { + continue; + } + // - // if we get here our primes aren't big enough, make the largest - // of the two p and try again + // calculate the modulus // - p = p.max(q); - continue; - } - - /* - * Require a minimum weight of the NAF representation, since low-weight composites may - * be weak against a version of the number-field-sieve for factoring. - * - * See "The number field sieve for integers of low weight", Oliver Schirokauer. - */ - if (WNafUtil.getNafWeight(n) < minWeight) + n = p.multiply(q); + + if (n.bitLength() != strength) + { + // + // if we get here our primes aren't big enough, make the largest + // of the two p and try again + // + p = p.max(q); + continue; + } + + /* + * Require a minimum weight of the NAF representation, since low-weight composites may + * be weak against a version of the number-field-sieve for factoring. + * + * See "The number field sieve for integers of low weight", Oliver Schirokauer. + */ + if (WNafUtil.getNafWeight(n) < minWeight) + { + p = chooseRandomPrime(pbitlength, e); + continue; + } + + break; + } + + if (p.compareTo(q) < 0) { - p = chooseRandomPrime(pBitlength, e); - continue; + phi = p; + p = q; + q = phi; } - break; - } + pSub1 = p.subtract(ONE); + qSub1 = q.subtract(ONE); + phi = pSub1.multiply(qSub1); + lcm = phi.divide(pSub1.gcd(qSub1)); - if (p.compareTo(q) < 0) - { - phi = p; - p = q; - q = phi; - } + // + // calculate the private exponent + // + d = e.modInverse(lcm); - pSub1 = p.subtract(ONE); - qSub1 = q.subtract(ONE); - phi = pSub1.multiply(qSub1); + // if d is less than or equal to dLowerBound, we need to start over + // also, for backward compatibility, if d is not the same as + // e.modInverse(phi), we need to start over - // - // calculate the private exponent - // - d = e.modInverse(phi); + if (d.bitLength() <= qbitlength || !d.equals(e.modInverse(phi))) + { + continue; + } + else + { + done = true; + } - // - // calculate the CRT factors - // - BigInteger dP, dQ, qInv; + // + // calculate the CRT factors + // + BigInteger dP, dQ, qInv; - dP = d.remainder(pSub1); - dQ = d.remainder(qSub1); - qInv = q.modInverse(p); + dP = d.remainder(pSub1); + dQ = d.remainder(qSub1); + qInv = q.modInverse(p); + + result = new AsymmetricCipherKeyPair( + new RSAKeyParameters(false, n, e), + new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)); + } - return new AsymmetricCipherKeyPair( - new RSAKeyParameters(false, n, e), - new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)); + return result; } /** diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java index 5388b40..64b076d 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java @@ -4,6 +4,7 @@ import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.StreamBlockCipher; /** * A Cipher Text Stealing (CTS) mode cipher. CTS allows block ciphers to @@ -22,9 +23,8 @@ public class CTSBlockCipher public CTSBlockCipher( BlockCipher cipher) { - if ((cipher instanceof OFBBlockCipher) || (cipher instanceof CFBBlockCipher) || (cipher instanceof SICBlockCipher)) + if (cipher instanceof StreamBlockCipher) { - // TODO: This is broken - need to introduce marker interface to differentiate block cipher primitive from mode? throw new IllegalArgumentException("CTSBlockCipher can only accept ECB, or CBC ciphers"); } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java index 024eb86..93f0fe9 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java @@ -7,6 +7,7 @@ import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.modes.gcm.GCMExponentiator; import org.bouncycastle.crypto.modes.gcm.GCMMultiplier; +import org.bouncycastle.crypto.modes.gcm.GCMUtil; import org.bouncycastle.crypto.modes.gcm.Tables1kGCMExponentiator; import org.bouncycastle.crypto.modes.gcm.Tables8kGCMMultiplier; import org.bouncycastle.crypto.params.AEADParameters; @@ -366,7 +367,7 @@ public class GCMBlockCipher // Find the difference between the AAD hashes if (atLengthPre > 0) { - xor(S_at, S_atPre); + GCMUtil.xor(S_at, S_atPre); } // Number of cipher-text blocks produced @@ -382,10 +383,10 @@ public class GCMBlockCipher exp.exponentiateX(c, H_c); // Carry the difference forward - multiply(S_at, H_c); + GCMUtil.multiply(S_at, H_c); // Adjust the current hash - xor(S, S_at); + GCMUtil.xor(S, S_at); } // Final gHASH @@ -398,7 +399,7 @@ public class GCMBlockCipher // T = MSBt(GCTRk(J0,S)) byte[] tag = new byte[BLOCK_SIZE]; cipher.processBlock(J0, 0, tag, 0); - xor(tag, S); + GCMUtil.xor(tag, S); int resultLen = extra; @@ -473,7 +474,7 @@ public class GCMBlockCipher { byte[] tmp = getNextCounterBlock(); - xor(tmp, block); + GCMUtil.xor(tmp, block); System.arraycopy(tmp, 0, out, outOff, BLOCK_SIZE); gHASHBlock(S, forEncryption ? tmp : block); @@ -485,7 +486,7 @@ public class GCMBlockCipher { byte[] tmp = getNextCounterBlock(); - xor(tmp, buf, off, len); + GCMUtil.xor(tmp, buf, off, len); System.arraycopy(tmp, 0, out, outOff, len); gHASHPartial(S, forEncryption ? tmp : buf, 0, len); @@ -504,13 +505,13 @@ public class GCMBlockCipher private void gHASHBlock(byte[] Y, byte[] b) { - xor(Y, b); + GCMUtil.xor(Y, b); multiplier.multiplyH(Y); } private void gHASHPartial(byte[] Y, byte[] b, int off, int len) { - xor(Y, b, off, len); + GCMUtil.xor(Y, b, off, len); multiplier.multiplyH(Y); } @@ -532,65 +533,4 @@ public class GCMBlockCipher cipher.processBlock(counter, 0, tmp, 0); return tmp; } - - private static void multiply(byte[] block, byte[] val) - { - byte[] tmp = Arrays.clone(block); - byte[] c = new byte[16]; - - for (int i = 0; i < 16; ++i) - { - byte bits = val[i]; - for (int j = 7; j >= 0; --j) - { - if ((bits & (1 << j)) != 0) - { - xor(c, tmp); - } - - boolean lsb = (tmp[15] & 1) != 0; - shiftRight(tmp); - if (lsb) - { - // R = new byte[]{ 0xe1, ... }; -// xor(v, R); - tmp[0] ^= (byte)0xe1; - } - } - } - - System.arraycopy(c, 0, block, 0, 16); - } - - private static void shiftRight(byte[] block) - { - int i = 0; - int bit = 0; - for (;;) - { - int b = block[i] & 0xff; - block[i] = (byte) ((b >>> 1) | bit); - if (++i == 16) - { - break; - } - bit = (b & 1) << 7; - } - } - - private static void xor(byte[] block, byte[] val) - { - for (int i = 15; i >= 0; --i) - { - block[i] ^= val[i]; - } - } - - private static void xor(byte[] block, byte[] val, int off, int len) - { - while (len-- > 0) - { - block[len] ^= val[off + len]; - } - } } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java index 5dd47ae..fbc8bf4 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java @@ -106,6 +106,27 @@ public class SICBlockCipher return rv; } + private void incrementCounterPow2(int pow2Div8) + { + // increment counter by 1 << 8 * pow2Div8 + for (int i = counter.length - (1 + pow2Div8); i >= 0 && ++counter[i] == 0; i--) + { + ; // do nothing - pre-increment and test for 0 in counter does the job. + } + } + + private void incrementCounter(int offSet) + { + byte old = counter[counter.length - 1]; + + counter[counter.length - 1] += offSet; + + if (old != 0 && counter[counter.length - 1] < old) + { + incrementCounterPow2(1); + } + } + private void incrementCounter() { // increment counter by 1. @@ -115,6 +136,33 @@ public class SICBlockCipher } } + private void decrementCounterPow2(int pow2Div8) + { + if (counter[pow2Div8] == 0) + { + boolean nonZero = false; + + for (int i = counter.length - (1 + pow2Div8); i > 0; i--) + { + if (counter[i] != 0) + { + nonZero = true; + } + } + + if (!nonZero) + { + throw new IllegalStateException("attempt to reduce counter past zero."); + } + } + + // decrement counter by 1. + for (int i = counter.length - (1 + pow2Div8); i >= 0 && --counter[i] == -1; i--) + { + ; + } + } + private void decrementCounter() { if (counter[0] == 0) @@ -148,9 +196,27 @@ public class SICBlockCipher { long numBlocks = (n + byteCount) / blockSize; - for (long i = 0; i != numBlocks; i++) + if (numBlocks > 255) + { + long gap = numBlocks; + + for (int i = 5; i >= 1; i--) + { + long diff = 1L << (8 * i); + + while (gap >= diff) + { + incrementCounterPow2(i); + + gap -= diff; + } + } + + incrementCounter((int)gap); + } + else { - incrementCounter(); + incrementCounter((int)numBlocks); } byteCount = (int)((n + byteCount) - (blockSize * numBlocks)); @@ -159,9 +225,33 @@ public class SICBlockCipher { long numBlocks = (-n - byteCount) / blockSize; - for (long i = 0; i != numBlocks; i++) + if (numBlocks > 255) { - decrementCounter(); + long gap = numBlocks; + + for (int i = 5; i >= 1; i--) + { + long diff = 1L << (8 * i); + + while (gap > diff) + { + decrementCounterPow2(i); + + gap -= diff; + } + } + + for (long i = 0; i != gap; i++) + { + decrementCounter(); + } + } + else + { + for (long i = 0; i != numBlocks; i++) + { + decrementCounter(); + } } int gap = (int)(byteCount + n + (blockSize * numBlocks)); @@ -209,7 +299,7 @@ public class SICBlockCipher for (int i = res.length - 1; i >= 1; i--) { - int v = (res[i] - IV[i]); + int v = (res[i] & 0xff) - (IV[i] & 0xff); if (v < 0) { diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java index f5ed7e4..58f4078 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java @@ -1,13 +1,11 @@ package org.bouncycastle.crypto.modes.gcm; -import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Pack; -abstract class GCMUtil +public abstract class GCMUtil { private static final int E1 = 0xe1000000; - private static final byte E1B = (byte)0xe1; - private static final long E1L = (E1 & 0xFFFFFFFFL) << 24; + private static final long E1L = (E1 & 0xFFFFFFFFL) << 32; private static int[] generateLookup() { @@ -31,170 +29,151 @@ abstract class GCMUtil private static final int[] LOOKUP = generateLookup(); - static byte[] oneAsBytes() + public static byte[] oneAsBytes() { byte[] tmp = new byte[16]; tmp[0] = (byte)0x80; return tmp; } - static int[] oneAsInts() + public static int[] oneAsInts() { int[] tmp = new int[4]; tmp[0] = 1 << 31; return tmp; } - static long[] oneAsLongs() + public static long[] oneAsLongs() { long[] tmp = new long[2]; tmp[0] = 1L << 63; return tmp; } - static byte[] asBytes(int[] x) + public static byte[] asBytes(int[] x) { byte[] z = new byte[16]; Pack.intToBigEndian(x, z, 0); return z; } - static void asBytes(int[] x, byte[] z) + public static void asBytes(int[] x, byte[] z) { Pack.intToBigEndian(x, z, 0); } - static byte[] asBytes(long[] x) + public static byte[] asBytes(long[] x) { byte[] z = new byte[16]; Pack.longToBigEndian(x, z, 0); return z; } - static void asBytes(long[] x, byte[] z) + public static void asBytes(long[] x, byte[] z) { Pack.longToBigEndian(x, z, 0); } - static int[] asInts(byte[] x) + public static int[] asInts(byte[] x) { int[] z = new int[4]; Pack.bigEndianToInt(x, 0, z); return z; } - static void asInts(byte[] x, int[] z) + public static void asInts(byte[] x, int[] z) { Pack.bigEndianToInt(x, 0, z); } - static long[] asLongs(byte[] x) + public static long[] asLongs(byte[] x) { long[] z = new long[2]; Pack.bigEndianToLong(x, 0, z); return z; } - static void asLongs(byte[] x, long[] z) + public static void asLongs(byte[] x, long[] z) { Pack.bigEndianToLong(x, 0, z); } - static void multiply(byte[] x, byte[] y) + public static void multiply(byte[] x, byte[] y) { - byte[] r0 = Arrays.clone(x); - byte[] r1 = new byte[16]; - - for (int i = 0; i < 16; ++i) - { - byte bits = y[i]; - for (int j = 7; j >= 0; --j) - { - if ((bits & (1 << j)) != 0) - { - xor(r1, r0); - } - - if (shiftRight(r0) != 0) - { - r0[0] ^= E1B; - } - } - } - - System.arraycopy(r1, 0, x, 0, 16); + int[] t1 = GCMUtil.asInts(x); + int[] t2 = GCMUtil.asInts(y); + GCMUtil.multiply(t1, t2); + GCMUtil.asBytes(t1, x); } - static void multiply(int[] x, int[] y) + public static void multiply(int[] x, int[] y) { - int[] r0 = Arrays.clone(x); - int[] r1 = new int[4]; - + int r00 = x[0], r01 = x[1], r02 = x[2], r03 = x[3]; + int r10 = 0, r11 = 0, r12 = 0, r13 = 0; + for (int i = 0; i < 4; ++i) { int bits = y[i]; - for (int j = 31; j >= 0; --j) + for (int j = 0; j < 32; ++j) { - if ((bits & (1 << j)) != 0) - { - xor(r1, r0); - } - - if (shiftRight(r0) != 0) - { - r0[0] ^= E1; - } + int m1 = bits >> 31; bits <<= 1; + r10 ^= (r00 & m1); + r11 ^= (r01 & m1); + r12 ^= (r02 & m1); + r13 ^= (r03 & m1); + + int m2 = (r03 << 31) >> 8; + r03 = (r03 >>> 1) | (r02 << 63); + r02 = (r02 >>> 1) | (r01 << 63); + r01 = (r01 >>> 1) | (r00 << 63); + r00 = (r00 >>> 1) ^ (m2 & E1); } } - System.arraycopy(r1, 0, x, 0, 4); + x[0] = r10; + x[1] = r11; + x[2] = r12; + x[3] = r13; } - static void multiply(long[] x, long[] y) + public static void multiply(long[] x, long[] y) { - long[] r0 = new long[]{ x[0], x[1] }; - long[] r1 = new long[2]; + long r00 = x[0], r01 = x[1], r10 = 0, r11 = 0; for (int i = 0; i < 2; ++i) { long bits = y[i]; - for (int j = 63; j >= 0; --j) + for (int j = 0; j < 64; ++j) { - if ((bits & (1L << j)) != 0) - { - xor(r1, r0); - } + long m1 = bits >> 63; bits <<= 1; + r10 ^= (r00 & m1); + r11 ^= (r01 & m1); - if (shiftRight(r0) != 0) - { - r0[0] ^= E1L; - } + long m2 = (r01 << 63) >> 8; + r01 = (r01 >>> 1) | (r00 << 63); + r00 = (r00 >>> 1) ^ (m2 & E1L); } } - x[0] = r1[0]; - x[1] = r1[1]; + x[0] = r10; + x[1] = r11; } // P is the value with only bit i=1 set - static void multiplyP(int[] x) + public static void multiplyP(int[] x) { - if (shiftRight(x) != 0) - { - x[0] ^= E1; - } + int m = shiftRight(x) >> 8; + x[0] ^= (m & E1); } - static void multiplyP(int[] x, int[] y) + public static void multiplyP(int[] x, int[] z) { - if (shiftRight(x, y) != 0) - { - y[0] ^= E1; - } + int m = shiftRight(x, z) >> 8; + z[0] ^= (m & E1); } // P is the value with only bit i=1 set - static void multiplyP8(int[] x) + public static void multiplyP8(int[] x) { // for (int i = 8; i != 0; --i) // { @@ -205,74 +184,12 @@ abstract class GCMUtil x[0] ^= LOOKUP[c >>> 24]; } - static void multiplyP8(int[] x, int[] y) + public static void multiplyP8(int[] x, int[] y) { int c = shiftRightN(x, 8, y); y[0] ^= LOOKUP[c >>> 24]; } - static byte shiftRight(byte[] x) - { -// int c = 0; -// for (int i = 0; i < 16; ++i) -// { -// int b = x[i] & 0xff; -// x[i] = (byte)((b >>> 1) | c); -// c = (b & 1) << 7; -// } -// return (byte)c; - - int i = 0, c = 0; - do - { - int b = x[i] & 0xff; - x[i++] = (byte)((b >>> 1) | c); - c = (b & 1) << 7; - b = x[i] & 0xff; - x[i++] = (byte)((b >>> 1) | c); - c = (b & 1) << 7; - b = x[i] & 0xff; - x[i++] = (byte)((b >>> 1) | c); - c = (b & 1) << 7; - b = x[i] & 0xff; - x[i++] = (byte)((b >>> 1) | c); - c = (b & 1) << 7; - } - while (i < 16); - return (byte)c; - } - - static byte shiftRight(byte[] x, byte[] z) - { -// int c = 0; -// for (int i = 0; i < 16; ++i) -// { -// int b = x[i] & 0xff; -// z[i] = (byte) ((b >>> 1) | c); -// c = (b & 1) << 7; -// } -// return (byte) c; - - int i = 0, c = 0; - do - { - int b = x[i] & 0xff; - z[i++] = (byte)((b >>> 1) | c); - c = (b & 1) << 7; - b = x[i] & 0xff; - z[i++] = (byte)((b >>> 1) | c); - c = (b & 1) << 7; - b = x[i] & 0xff; - z[i++] = (byte)((b >>> 1) | c); - c = (b & 1) << 7; - b = x[i] & 0xff; - z[i++] = (byte)((b >>> 1) | c); - c = (b & 1) << 7; - } - while (i < 16); - return (byte)c; - } - static int shiftRight(int[] x) { // int c = 0; @@ -393,7 +310,7 @@ abstract class GCMUtil return b << nInv; } - static void xor(byte[] x, byte[] y) + public static void xor(byte[] x, byte[] y) { int i = 0; do @@ -406,15 +323,15 @@ abstract class GCMUtil while (i < 16); } - static void xor(byte[] x, byte[] y, int yOff, int yLen) + public static void xor(byte[] x, byte[] y, int yOff, int yLen) { - while (yLen-- > 0) + while (--yLen >= 0) { x[yLen] ^= y[yOff + yLen]; } } - static void xor(byte[] x, byte[] y, byte[] z) + public static void xor(byte[] x, byte[] y, byte[] z) { int i = 0; do @@ -427,7 +344,7 @@ abstract class GCMUtil while (i < 16); } - static void xor(int[] x, int[] y) + public static void xor(int[] x, int[] y) { x[0] ^= y[0]; x[1] ^= y[1]; @@ -435,7 +352,7 @@ abstract class GCMUtil x[3] ^= y[3]; } - static void xor(int[] x, int[] y, int[] z) + public static void xor(int[] x, int[] y, int[] z) { z[0] = x[0] ^ y[0]; z[1] = x[1] ^ y[1]; @@ -443,13 +360,13 @@ abstract class GCMUtil z[3] = x[3] ^ y[3]; } - static void xor(long[] x, long[] y) + public static void xor(long[] x, long[] y) { x[0] ^= y[0]; x[1] ^= y[1]; } - static void xor(long[] x, long[] y, long[] z) + public static void xor(long[] x, long[] y, long[] z) { z[0] = x[0] ^ y[0]; z[1] = x[1] ^ y[1]; diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PKCS7Padding.java b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PKCS7Padding.java index 93b149f..8b30398 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PKCS7Padding.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PKCS7Padding.java @@ -57,18 +57,19 @@ public class PKCS7Padding throws InvalidCipherTextException { int count = in[in.length - 1] & 0xff; + byte countAsbyte = (byte)count; - if (count > in.length || count == 0) + // constant time version + boolean failed = (count > in.length | count == 0); + + for (int i = 0; i < in.length; i++) { - throw new InvalidCipherTextException("pad block corrupted"); + failed |= (in.length - i <= count) & (in[i] != countAsbyte); } - - for (int i = 1; i <= count; i++) + + if (failed) { - if (in[in.length - i] != count) - { - throw new InvalidCipherTextException("pad block corrupted"); - } + throw new InvalidCipherTextException("pad block corrupted"); } return count; diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/DHParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/DHParameters.java index b679287..fec6dfd 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/params/DHParameters.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/DHParameters.java @@ -84,8 +84,7 @@ public class DHParameters { if (l != 0) { - BigInteger bigL = BigInteger.valueOf(2L ^ (l - 1)); - if (bigL.compareTo(p) == 1) + if (l > p.bitLength()) { throw new IllegalArgumentException("when l value specified, it must satisfy 2^(l-1) <= p"); } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java index f3614f3..44f838b 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java @@ -80,32 +80,28 @@ public class DSASigner byte[] message) { DSAParameters params = key.getParameters(); - BigInteger m = calculateE(params.getQ(), message); + BigInteger q = params.getQ(); + BigInteger m = calculateE(q, message); + BigInteger x = ((DSAPrivateKeyParameters)key).getX(); if (kCalculator.isDeterministic()) { - kCalculator.init(params.getQ(), ((DSAPrivateKeyParameters)key).getX(), message); + kCalculator.init(q, x, message); } else { - kCalculator.init(params.getQ(), random); + kCalculator.init(q, random); } BigInteger k = kCalculator.nextK(); - BigInteger r = params.getG().modPow(k, params.getP()).mod(params.getQ()); + BigInteger r = params.getG().modPow(k, params.getP()).mod(q); - k = k.modInverse(params.getQ()).multiply( - m.add(((DSAPrivateKeyParameters)key).getX().multiply(r))); + k = k.modInverse(q).multiply(m.add(x.multiply(r))); - BigInteger s = k.mod(params.getQ()); + BigInteger s = k.mod(q); - BigInteger[] res = new BigInteger[2]; - - res[0] = r; - res[1] = s; - - return res; + return new BigInteger[]{ r, s }; } /** @@ -119,28 +115,30 @@ public class DSASigner BigInteger s) { DSAParameters params = key.getParameters(); - BigInteger m = calculateE(params.getQ(), message); + BigInteger q = params.getQ(); + BigInteger m = calculateE(q, message); BigInteger zero = BigInteger.valueOf(0); - if (zero.compareTo(r) >= 0 || params.getQ().compareTo(r) <= 0) + if (zero.compareTo(r) >= 0 || q.compareTo(r) <= 0) { return false; } - if (zero.compareTo(s) >= 0 || params.getQ().compareTo(s) <= 0) + if (zero.compareTo(s) >= 0 || q.compareTo(s) <= 0) { return false; } - BigInteger w = s.modInverse(params.getQ()); + BigInteger w = s.modInverse(q); - BigInteger u1 = m.multiply(w).mod(params.getQ()); - BigInteger u2 = r.multiply(w).mod(params.getQ()); + BigInteger u1 = m.multiply(w).mod(q); + BigInteger u2 = r.multiply(w).mod(q); - u1 = params.getG().modPow(u1, params.getP()); - u2 = ((DSAPublicKeyParameters)key).getY().modPow(u2, params.getP()); + BigInteger p = params.getP(); + u1 = params.getG().modPow(u1, p); + u2 = ((DSAPublicKeyParameters)key).getY().modPow(u2, p); - BigInteger v = u1.multiply(u2).mod(params.getP()).mod(params.getQ()); + BigInteger v = u1.multiply(u2).mod(p).mod(q); return v.equals(r); } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java index 2a32278..a8ef959 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java @@ -224,6 +224,8 @@ public class RSADigestSigner } else { + Arrays.constantTimeAreEqual(expected, expected); // keep time "steady". + return false; } } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java index bbd8cda..6a69308 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java @@ -3,7 +3,7 @@ package org.bouncycastle.crypto.signers; import java.math.BigInteger; import java.security.SecureRandom; -class RandomDSAKCalculator +public class RandomDSAKCalculator implements DSAKCalculator { private static final BigInteger ZERO = BigInteger.valueOf(0); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12StoreParameter.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12StoreParameter.java new file mode 100644 index 0000000..b53eca5 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12StoreParameter.java @@ -0,0 +1,62 @@ +package org.bouncycastle.jcajce; + +import java.io.OutputStream; +import java.security.KeyStore; +import java.security.KeyStore.LoadStoreParameter; +import java.security.KeyStore.ProtectionParameter; + +/** + * LoadStoreParameter to allow for additional config with PKCS12 files. + * <p> + * Note: if you want a straight DER encoding of a PKCS#12 file you should use this. + * </p> + */ +public class PKCS12StoreParameter + implements LoadStoreParameter +{ + private final OutputStream out; + private final ProtectionParameter protectionParameter; + private final boolean forDEREncoding; + + public PKCS12StoreParameter(OutputStream out, char[] password) + { + this(out, password, false); + } + + public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter) + { + this(out, protectionParameter, false); + } + + public PKCS12StoreParameter(OutputStream out, char[] password, boolean forDEREncoding) + { + this(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; + } + + /** + * Return whether the KeyStore used with this parameter should be DER encoded on saving. + * + * @return true for straight DER encoding, false otherwise, + */ + public boolean isForDEREncoding() + { + return forDEREncoding; + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStore.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStore.java new file mode 100644 index 0000000..b344720 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStore.java @@ -0,0 +1,15 @@ +package org.bouncycastle.jcajce; + +import java.security.cert.CRL; +import java.util.Collection; + +import org.bouncycastle.util.Selector; +import org.bouncycastle.util.Store; +import org.bouncycastle.util.StoreException; + +public interface PKIXCRLStore<T extends CRL> + extends Store<T> +{ + Collection<T> getMatches(Selector<T> selector) + throws StoreException; +} diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java new file mode 100644 index 0000000..9c68433 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java @@ -0,0 +1,313 @@ +package org.bouncycastle.jcajce; + +import java.math.BigInteger; +import java.security.cert.CRL; +import java.security.cert.CRLSelector; +import java.security.cert.CertStore; +import java.security.cert.CertStoreException; +import java.security.cert.X509CRL; +import java.security.cert.X509CRLSelector; +import java.security.cert.X509Certificate; +import java.util.Collection; + +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Selector; + +/** + * This class is a Selector implementation for X.509 certificate revocation + * lists. + * + * @see org.bouncycastle.util.Selector + */ +public class PKIXCRLStoreSelector<T extends CRL> + implements Selector<T> +{ + public static class Builder + { + private final CRLSelector baseSelector; + + private boolean deltaCRLIndicator = false; + private boolean completeCRLEnabled = false; + private BigInteger maxBaseCRLNumber = null; + private byte[] issuingDistributionPoint = null; + private boolean issuingDistributionPointEnabled = false; + + public Builder(CRLSelector certSelector) + { + this.baseSelector = (CRLSelector)certSelector.clone(); + } + + + /** + * If set to <code>true</code> only complete CRLs are returned. + * <p> + * {@link #setCompleteCRLEnabled(boolean)} and + * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. + * + * @param completeCRLEnabled <code>true</code> if only complete CRLs + * should be returned. + */ + public Builder setCompleteCRLEnabled(boolean completeCRLEnabled) + { + this.completeCRLEnabled = completeCRLEnabled; + + return this; + } + + /** + * If this is set to <code>true</code> the CRL reported contains the delta + * CRL indicator CRL extension. + * <p> + * {@link #setCompleteCRLEnabled(boolean)} and + * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. + * + * @param deltaCRLIndicator <code>true</code> if the delta CRL indicator + * extension must be in the CRL. + */ + public Builder setDeltaCRLIndicatorEnabled(boolean deltaCRLIndicator) + { + this.deltaCRLIndicator = deltaCRLIndicator; + + return this; + } + + /** + * Sets the maximum base CRL number. Setting to <code>null</code> disables + * this cheack. + * <p> + * This is only meaningful for delta CRLs. Complete CRLs must have a CRL + * number which is greater or equal than the base number of the + * corresponding CRL. + * + * @param maxBaseCRLNumber The maximum base CRL number to set. + */ + public void setMaxBaseCRLNumber(BigInteger maxBaseCRLNumber) + { + this.maxBaseCRLNumber = maxBaseCRLNumber; + } + + /** + * Enables or disables the issuing distribution point check. + * + * @param issuingDistributionPointEnabled <code>true</code> to enable the + * issuing distribution point check. + */ + public void setIssuingDistributionPointEnabled( + boolean issuingDistributionPointEnabled) + { + this.issuingDistributionPointEnabled = issuingDistributionPointEnabled; + } + + /** + * Sets the issuing distribution point. + * <p> + * The issuing distribution point extension is a CRL extension which + * identifies the scope and the distribution point of a CRL. The scope + * contains among others information about revocation reasons contained in + * the CRL. Delta CRLs and complete CRLs must have matching issuing + * distribution points. + * <p> + * The byte array is cloned to protect against subsequent modifications. + * <p> + * You must also enable or disable this criteria with + * {@link #setIssuingDistributionPointEnabled(boolean)}. + * + * @param issuingDistributionPoint The issuing distribution point to set. + * This is the DER encoded OCTET STRING extension value. + * @see #getIssuingDistributionPoint() + */ + public void setIssuingDistributionPoint(byte[] issuingDistributionPoint) + { + this.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint); + } + + public PKIXCRLStoreSelector<? extends CRL> build() + { + return new PKIXCRLStoreSelector(this); + } + } + + private final CRLSelector baseSelector; + private final boolean deltaCRLIndicator; + private final boolean completeCRLEnabled; + private final BigInteger maxBaseCRLNumber; + private final byte[] issuingDistributionPoint; + private final boolean issuingDistributionPointEnabled; + + private PKIXCRLStoreSelector(Builder baseBuilder) + { + this.baseSelector = baseBuilder.baseSelector; + this.deltaCRLIndicator = baseBuilder.deltaCRLIndicator; + this.completeCRLEnabled = baseBuilder.completeCRLEnabled; + this.maxBaseCRLNumber = baseBuilder.maxBaseCRLNumber; + this.issuingDistributionPoint = baseBuilder.issuingDistributionPoint; + this.issuingDistributionPointEnabled = baseBuilder.issuingDistributionPointEnabled; + } + + + /** + * Returns if the issuing distribution point criteria should be applied. + * Defaults to <code>false</code>. + * <p> + * You may also set the issuing distribution point criteria if not a missing + * issuing distribution point should be assumed. + * + * @return Returns if the issuing distribution point check is enabled. + */ + public boolean isIssuingDistributionPointEnabled() + { + return issuingDistributionPointEnabled; + } + + + + public boolean match(CRL obj) + { + if (!(obj instanceof X509CRL)) + { + return baseSelector.match(obj); + } + + X509CRL crl = (X509CRL)obj; + ASN1Integer dci = null; + try + { + byte[] bytes = crl + .getExtensionValue(Extension.deltaCRLIndicator.getId()); + if (bytes != null) + { + dci = ASN1Integer.getInstance(ASN1OctetString.getInstance(bytes).getOctets()); + } + } + catch (Exception e) + { + return false; + } + if (isDeltaCRLIndicatorEnabled()) + { + if (dci == null) + { + return false; + } + } + if (isCompleteCRLEnabled()) + { + if (dci != null) + { + return false; + } + } + if (dci != null) + { + + if (maxBaseCRLNumber != null) + { + if (dci.getPositiveValue().compareTo(maxBaseCRLNumber) == 1) + { + return false; + } + } + } + if (issuingDistributionPointEnabled) + { + byte[] idp = crl + .getExtensionValue(Extension.issuingDistributionPoint + .getId()); + if (issuingDistributionPoint == null) + { + if (idp != null) + { + return false; + } + } + else + { + if (!Arrays.areEqual(idp, issuingDistributionPoint)) + { + return false; + } + } + + } + return baseSelector.match(obj); + } + + /** + * Returns if this selector must match CRLs with the delta CRL indicator + * extension set. Defaults to <code>false</code>. + * + * @return Returns <code>true</code> if only CRLs with the delta CRL + * indicator extension are selected. + */ + public boolean isDeltaCRLIndicatorEnabled() + { + return deltaCRLIndicator; + } + + public Object clone() + { + return this; + } + + /** + * If <code>true</code> only complete CRLs are returned. Defaults to + * <code>false</code>. + * + * @return <code>true</code> if only complete CRLs are returned. + */ + public boolean isCompleteCRLEnabled() + { + return completeCRLEnabled; + } + + /** + * Get the maximum base CRL number. Defaults to <code>null</code>. + * + * @return Returns the maximum base CRL number. + */ + public BigInteger getMaxBaseCRLNumber() + { + return maxBaseCRLNumber; + } + + + /** + * Returns the issuing distribution point. Defaults to <code>null</code>, + * which is a missing issuing distribution point extension. + * <p> + * The internal byte array is cloned before it is returned. + * <p> + * The criteria must be enable with Builder.setIssuingDistributionPointEnabled(boolean)}. + * + * @return Returns the issuing distribution point. + */ + public byte[] getIssuingDistributionPoint() + { + return Arrays.clone(issuingDistributionPoint); + } + + public X509Certificate getCertificateChecking() + { + return ((X509CRLSelector)baseSelector).getCertificateChecking(); + } + + public static Collection<? extends CRL> getCRLs(final PKIXCRLStoreSelector selector, CertStore certStore) + throws CertStoreException + { + return certStore.getCRLs(new CRLSelector() + { + public boolean match(CRL crl) + { + return selector.match(crl); + } + + public Object clone() + { + return this; + } + }); + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStore.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStore.java new file mode 100644 index 0000000..092872f --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStore.java @@ -0,0 +1,15 @@ +package org.bouncycastle.jcajce; + +import java.security.cert.Certificate; +import java.util.Collection; + +import org.bouncycastle.util.Selector; +import org.bouncycastle.util.Store; +import org.bouncycastle.util.StoreException; + +public interface PKIXCertStore<T extends Certificate> + extends Store<T> +{ + Collection<T> getMatches(Selector<T> selector) + throws StoreException; +} diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java new file mode 100644 index 0000000..1775de7 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java @@ -0,0 +1,67 @@ +package org.bouncycastle.jcajce; + +import java.security.cert.CertSelector; +import java.security.cert.CertStore; +import java.security.cert.CertStoreException; +import java.security.cert.Certificate; +import java.util.Collection; + +import org.bouncycastle.util.Selector; + +/** + * This class is a Selector implementation for certificates. + * + * @see org.bouncycastle.util.Selector + */ +public class PKIXCertStoreSelector<T extends Certificate> + implements Selector<T> +{ + public static class Builder + { + private final CertSelector baseSelector; + + public Builder(CertSelector certSelector) + { + this.baseSelector = (CertSelector)certSelector.clone(); + } + + public PKIXCertStoreSelector<? extends Certificate> build() + { + return new PKIXCertStoreSelector(baseSelector); + } + } + + private final CertSelector baseSelector; + + private PKIXCertStoreSelector(CertSelector baseSelector) + { + this.baseSelector = baseSelector; + } + + public boolean match(Certificate cert) + { + return baseSelector.match(cert); + } + + public Object clone() + { + return new PKIXCertStoreSelector(baseSelector); + } + + public static Collection<? extends Certificate> getCertificates(final PKIXCertStoreSelector selector, CertStore certStore) + throws CertStoreException + { + return certStore.getCertificates(new CertSelector() + { + public boolean match(Certificate certificate) + { + return (selector == null) ? true : selector.match(certificate); + } + + public Object clone() + { + return this; + } + }); + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java new file mode 100644 index 0000000..3369d0d --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java @@ -0,0 +1,138 @@ +package org.bouncycastle.jcajce; + +import java.security.InvalidParameterException; +import java.security.cert.CertPathParameters; +import java.security.cert.PKIXBuilderParameters; +import java.security.cert.X509Certificate; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * This class contains extended parameters for PKIX certification path builders. + * + * @see java.security.cert.PKIXBuilderParameters + */ +public class PKIXExtendedBuilderParameters + implements CertPathParameters +{ + public static class Builder + { + private final PKIXExtendedParameters baseParameters; + + private int maxPathLength = 5; + private Set<X509Certificate> excludedCerts = new HashSet<X509Certificate>(); + + public Builder(PKIXBuilderParameters baseParameters) + { + this.baseParameters = new PKIXExtendedParameters.Builder(baseParameters).build(); + this.maxPathLength = baseParameters.getMaxPathLength(); + } + + public Builder(PKIXExtendedParameters baseParameters) + { + this.baseParameters = baseParameters; + } + + /** + * Adds excluded certificates which are not used for building a + * certification path. + * <p> + * The given set is cloned to protect it against subsequent modifications. + * + * @param excludedCerts The excluded certificates to set. + */ + public Builder addExcludedCerts(Set<X509Certificate> excludedCerts) + { + this.excludedCerts.addAll(excludedCerts); + + return this; + } + + /** + * Sets the maximum number of intermediate non-self-issued certificates in a + * certification path. The PKIX <code>CertPathBuilder</code> must not + * build paths longer then this length. + * <p> + * A value of 0 implies that the path can only contain a single certificate. + * A value of -1 does not limit the length. The default length is 5. + * + * <p> + * + * The basic constraints extension of a CA certificate overrides this value + * if smaller. + * + * @param maxPathLength the maximum number of non-self-issued intermediate + * certificates in the certification path + * @throws java.security.InvalidParameterException if <code>maxPathLength</code> is set + * to a value less than -1 + * + * @see #getMaxPathLength + */ + public Builder setMaxPathLength(int maxPathLength) + { + if (maxPathLength < -1) + { + throw new InvalidParameterException("The maximum path " + + "length parameter can not be less than -1."); + } + this.maxPathLength = maxPathLength; + + return this; + } + + public PKIXExtendedBuilderParameters build() + { + return new PKIXExtendedBuilderParameters(this); + } + } + + private final PKIXExtendedParameters baseParameters; + private final Set<X509Certificate> excludedCerts; + private final int maxPathLength; + + private PKIXExtendedBuilderParameters(Builder builder) + { + this.baseParameters = builder.baseParameters; + this.excludedCerts = Collections.unmodifiableSet(builder.excludedCerts); + this.maxPathLength = builder.maxPathLength; + } + + public PKIXExtendedParameters getBaseParameters() + { + return baseParameters; + } + + /** + * Excluded certificates are not used for building a certification path. + * <p> + * The returned set is immutable. + * + * @return Returns the excluded certificates. + */ + public Set getExcludedCerts() + { + return excludedCerts; + } + + /** + * Returns the value of the maximum number of intermediate non-self-issued + * certificates in the certification path. + * + * @return the maximum number of non-self-issued intermediate certificates + * in the certification path, or -1 if no limit exists. + */ + public int getMaxPathLength() + { + return maxPathLength; + } + + /** + * @return this object + */ + public Object clone() + { + return this; + } +} + diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java new file mode 100644 index 0000000..3a86f2a --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java @@ -0,0 +1,340 @@ +package org.bouncycastle.jcajce; + +import java.security.cert.CertPathParameters; +import java.security.cert.CertSelector; +import java.security.cert.CertStore; +import java.security.cert.PKIXParameters; +import java.security.cert.TrustAnchor; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bouncycastle.asn1.x509.GeneralName; + +/** + * This class extends the PKIXParameters with a validity model parameter. + */ +public class PKIXExtendedParameters + implements CertPathParameters +{ + /** + * This is the default PKIX validity model. Actually there are two variants + * of this: The PKIX model and the modified PKIX model. The PKIX model + * verifies that all involved certificates must have been valid at the + * current time. The modified PKIX model verifies that all involved + * certificates were valid at the signing time. Both are indirectly choosen + * with the {@link java.security.cert.PKIXParameters#setDate(java.util.Date)} method, so this + * methods sets the Date when <em>all</em> certificates must have been + * valid. + */ + public static final int PKIX_VALIDITY_MODEL = 0; + + /** + * This model uses the following validity model. Each certificate must have + * been valid at the moment where is was used. That means the end + * certificate must have been valid at the time the signature was done. The + * CA certificate which signed the end certificate must have been valid, + * when the end certificate was signed. The CA (or Root CA) certificate must + * have been valid, when the CA certificate was signed and so on. So the + * {@link java.security.cert.PKIXParameters#setDate(java.util.Date)} method sets the time, when + * the <em>end certificate</em> must have been valid. + * <p> + * It is used e.g. + * in the German signature law. + * </p> + */ + public static final int CHAIN_VALIDITY_MODEL = 1; + + public static class Builder + { + private final PKIXParameters baseParameters; + private final Date date; + + private PKIXCertStoreSelector targetConstraints; + private List<PKIXCertStore> extraCertStores = new ArrayList<PKIXCertStore>(); + private Map<GeneralName, PKIXCertStore> namedCertificateStoreMap = new HashMap<GeneralName, PKIXCertStore>(); + private List<PKIXCRLStore> extraCRLStores = new ArrayList<PKIXCRLStore>(); + private Map<GeneralName, PKIXCRLStore> namedCRLStoreMap = new HashMap<GeneralName, PKIXCRLStore>(); + private boolean revocationEnabled; + private int validityModel = PKIX_VALIDITY_MODEL; + private boolean useDeltas = false; + private Set<TrustAnchor> trustAnchors; + + public Builder(PKIXParameters baseParameters) + { + this.baseParameters = (PKIXParameters)baseParameters.clone(); + CertSelector constraints = baseParameters.getTargetCertConstraints(); + if (constraints != null) + { + this.targetConstraints = new PKIXCertStoreSelector.Builder(constraints).build(); + } + Date checkDate = baseParameters.getDate(); + this.date = (checkDate == null) ? new Date() : checkDate; + this.revocationEnabled = baseParameters.isRevocationEnabled(); + this.trustAnchors = baseParameters.getTrustAnchors(); + } + + public Builder(PKIXExtendedParameters baseParameters) + { + this.baseParameters = baseParameters.baseParameters; + this.date = baseParameters.date; + this.targetConstraints = baseParameters.targetConstraints; + this.extraCertStores = new ArrayList<PKIXCertStore>(baseParameters.extraCertStores); + this.namedCertificateStoreMap = new HashMap<GeneralName, PKIXCertStore>(baseParameters.namedCertificateStoreMap); + this.extraCRLStores = new ArrayList<PKIXCRLStore>(baseParameters.extraCRLStores); + this.namedCRLStoreMap = new HashMap<GeneralName, PKIXCRLStore>(baseParameters.namedCRLStoreMap); + this.useDeltas = baseParameters.useDeltas; + this.validityModel = baseParameters.validityModel; + this.revocationEnabled = baseParameters.isRevocationEnabled(); + this.trustAnchors = baseParameters.getTrustAnchors(); + } + + public Builder addCertificateStore(PKIXCertStore store) + { + extraCertStores.add(store); + + return this; + } + + public Builder addNamedCertificateStore(GeneralName issuerAltName, PKIXCertStore store) + { + namedCertificateStoreMap.put(issuerAltName, store); + + return this; + } + + public Builder addCRLStore(PKIXCRLStore store) + { + extraCRLStores.add(store); + + return this; + } + + public Builder addNamedCRLStore(GeneralName issuerAltName, PKIXCRLStore store) + { + namedCRLStoreMap.put(issuerAltName, store); + + return this; + } + + public Builder setTargetConstraints(PKIXCertStoreSelector selector) + { + targetConstraints = selector; + + return this; + } + + /** + * Sets if delta CRLs should be used for checking the revocation status. + * + * @param useDeltas <code>true</code> if delta CRLs should be used. + */ + public Builder setUseDeltasEnabled(boolean useDeltas) + { + this.useDeltas = useDeltas; + + return this; + } + + /** + * @param validityModel The validity model to set. + * @see #CHAIN_VALIDITY_MODEL + * @see #PKIX_VALIDITY_MODEL + */ + public Builder setValidityModel(int validityModel) + { + this.validityModel = validityModel; + + return this; + } + + /** + * Set the trustAnchor to be used with these parameters. + * + * @param trustAnchor the trust anchor end-entity and CRLs must be based on. + * @return the current builder. + */ + public Builder setTrustAnchor(TrustAnchor trustAnchor) + { + this.trustAnchors = Collections.singleton(trustAnchor); + + return this; + } + + /** + * Set the set of trustAnchors to be used with these parameters. + * + * @param trustAnchors a set of trustAnchors, one of which a particular end-entity and it's associated CRLs must be based on. + * @return the current builder. + */ + public Builder setTrustAnchors(Set<TrustAnchor> trustAnchors) + { + this.trustAnchors = trustAnchors; + + return this; + } + + /** + * Flag whether or not revocation checking is to be enabled. + * + * @param revocationEnabled true if revocation checking to be enabled, false otherwise. + */ + public void setRevocationEnabled(boolean revocationEnabled) + { + this.revocationEnabled = revocationEnabled; + } + + public PKIXExtendedParameters build() + { + return new PKIXExtendedParameters(this); + } + } + + private final PKIXParameters baseParameters; + private final PKIXCertStoreSelector targetConstraints; + private final Date date; + private final List<PKIXCertStore> extraCertStores; + private final Map<GeneralName, PKIXCertStore> namedCertificateStoreMap; + private final List<PKIXCRLStore> extraCRLStores; + private final Map<GeneralName, PKIXCRLStore> namedCRLStoreMap; + private final boolean revocationEnabled; + private final boolean useDeltas; + private final int validityModel; + private final Set<TrustAnchor> trustAnchors; + + private PKIXExtendedParameters(Builder builder) + { + this.baseParameters = builder.baseParameters; + this.date = builder.date; + this.extraCertStores = Collections.unmodifiableList(builder.extraCertStores); + this.namedCertificateStoreMap = Collections.unmodifiableMap(new HashMap<GeneralName, PKIXCertStore>(builder.namedCertificateStoreMap)); + this.extraCRLStores = Collections.unmodifiableList(builder.extraCRLStores); + this.namedCRLStoreMap = Collections.unmodifiableMap(new HashMap<GeneralName, PKIXCRLStore>(builder.namedCRLStoreMap)); + this.targetConstraints = builder.targetConstraints; + this.revocationEnabled = builder.revocationEnabled; + this.useDeltas = builder.useDeltas; + this.validityModel = builder.validityModel; + this.trustAnchors = Collections.unmodifiableSet(builder.trustAnchors); + } + + public List<PKIXCertStore> getCertificateStores() + { + return extraCertStores; + } + + + public Map<GeneralName, PKIXCertStore> getNamedCertificateStoreMap() + { + return namedCertificateStoreMap; + } + + public List<PKIXCRLStore> getCRLStores() + { + return extraCRLStores; + } + + public Map<GeneralName, PKIXCRLStore> getNamedCRLStoreMap() + { + return namedCRLStoreMap; + } + + public Date getDate() + { + return new Date(date.getTime()); + } + + + + + /** + * Defaults to <code>false</code>. + * + * @return Returns if delta CRLs should be used. + */ + public boolean isUseDeltasEnabled() + { + return useDeltas; + } + + + + /** + * @return Returns the validity model. + * @see #CHAIN_VALIDITY_MODEL + * @see #PKIX_VALIDITY_MODEL + */ + public int getValidityModel() + { + return validityModel; + } + + public Object clone() + { + return this; + } + + /** + * Returns the required constraints on the target certificate. + * The constraints are returned as an instance of + * <code>Selector</code>. If <code>null</code>, no constraints are + * defined. + * + * @return a <code>Selector</code> specifying the constraints on the + * target certificate or attribute certificate (or <code>null</code>) + * @see PKIXCertStoreSelector + */ + public PKIXCertStoreSelector getTargetConstraints() + { + return targetConstraints; + } + + public Set getTrustAnchors() + { + return trustAnchors; + } + + public Set getInitialPolicies() + { + return baseParameters.getInitialPolicies(); + } + + public String getSigProvider() + { + return baseParameters.getSigProvider(); + } + + public boolean isExplicitPolicyRequired() + { + return baseParameters.isExplicitPolicyRequired(); + } + + public boolean isAnyPolicyInhibited() + { + return baseParameters.isAnyPolicyInhibited(); + } + + public boolean isPolicyMappingInhibited() + { + return baseParameters.isPolicyMappingInhibited(); + } + + public List getCertPathCheckers() + { + return baseParameters.getCertPathCheckers(); + } + + public List<CertStore> getCertStores() + { + return baseParameters.getCertStores(); + } + + public boolean isRevocationEnabled() + { + return revocationEnabled; + } + +} 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 bd83a8a..1266abd 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 @@ -37,12 +37,16 @@ public class EC registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC()); // BEGIN android-removed // registerOid(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV()); + // + // // Android comment: the registration below is causing CTS tests to fail and doesn't seem + // // to be implemented by bouncycastle (so looks like an bug in bouncycastle). + // registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC"); // END android-removed - - registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC"); // TODO Should this be an alias for ECDH? - registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC"); // BEGIN android-removed + // // Android comment: the registration below is causing CTS tests to fail and doesn't seem + // // to be implemented by bouncycastle (so looks like an bug in bouncycastle). + // registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC"); // registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "EC"); // END android-removed 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 2265199..d4046f9 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 @@ -155,6 +155,12 @@ public class RSA // END android-removed provider.addAlgorithm("Alg.Alias.Signature." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); provider.addAlgorithm("Alg.Alias.Signature.OID." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); + + // BEGIN android-removed + // 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"); + // END android-removed } addDigestSignature(provider, "SHA224", PREFIX + "DigestSignatureSpi$SHA224", PKCSObjectIdentifiers.sha224WithRSAEncryption); @@ -163,26 +169,53 @@ public class RSA addDigestSignature(provider, "SHA512", PREFIX + "DigestSignatureSpi$SHA512", PKCSObjectIdentifiers.sha512WithRSAEncryption); // BEGIN android-removed + // 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")) // { // addDigestSignature(provider, "RIPEMD160", PREFIX + "DigestSignatureSpi$RIPEMD160", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); // 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")) // { // addDigestSignature(provider, "RIPEMD256", PREFIX + "DigestSignatureSpi$RIPEMD256", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); // addDigestSignature(provider, "RMD256", PREFIX + "DigestSignatureSpi$RIPEMD256", null); // } - // END android-removed + // + // 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"); + // } + // END android-removed } 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 8bdcc55..e4c8172 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/dsa/AlgorithmParameterGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java index d850e5d..2d7c4c5 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 61fa33c..5722479 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/ec/BCECPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java index 45d5b08..c9ad445 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/rsa/CipherSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java index dcb9c23..aceb5ee 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 @@ -35,12 +35,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; @@ -145,7 +149,7 @@ public class CipherSpi { try { - engineParams = AlgorithmParameters.getInstance("OAEP", BouncyCastleProvider.PROVIDER_NAME); + engineParams = helper.createAlgorithmParameters("OAEP"); engineParams.init(paramSpec); } catch (Exception e) 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 13f7c93..123ed41 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 @@ -44,6 +44,7 @@ import org.bouncycastle.crypto.digests.AndroidDigestFactory; // END android-added import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; +import org.bouncycastle.util.Arrays; public class DigestSignatureSpi extends SignatureSpi @@ -178,13 +179,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 { @@ -194,28 +189,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/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java index c61e7cb..f779a66 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/util/BaseAlgorithmParameterGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAlgorithmParameterGeneratorSpi.java new file mode 100644 index 0000000..d9fb3fb --- /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 fabad43..5842b9e 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 @@ -27,6 +27,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 @@ -45,6 +47,7 @@ public abstract class BaseCipherSpi // END android-removed }; + private final JcaJceHelper helper = new BCJcaJceHelper(); protected AlgorithmParameters engineParams = null; @@ -84,6 +87,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 @@ -190,7 +199,7 @@ public abstract class BaseCipherSpi { try { - KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); + KeyFactory kf = helper.createKeyFactory(wrappedKeyAlgorithm); if (wrappedKeyType == Cipher.PUBLIC_KEY) { @@ -201,17 +210,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/ECUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java index 06a93e5..b8ef398 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; @@ -16,6 +17,7 @@ import org.bouncycastle.asn1.sec.SECNamedCurves; // END android-removed 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; @@ -218,6 +220,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) { 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 e4aaf30..8116f29 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; 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 9b14731..8bb4c3a 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; // BEGIN android-removed // import org.bouncycastle.util.io.pem.PemWriter; @@ -47,6 +48,8 @@ import org.bouncycastle.util.io.pem.PemObject; public class PKIXCertPath extends CertPath { + private final JcaJceHelper helper = new BCJcaJceHelper(); + static final List certPathEncodings; static @@ -184,7 +187,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(); @@ -197,7 +200,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) { @@ -217,7 +220,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 32e595c..0b53bd3 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 c7d0402..cd877d0 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 6604b4a..3157ea6 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; @@ -64,7 +62,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; @@ -241,37 +238,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()); } /** @@ -525,19 +496,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; } @@ -786,7 +756,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 a6959ba..61b0545 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,6 +5,8 @@ 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; @@ -26,6 +28,7 @@ import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; // END android-removed import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.jce.provider.BouncyCastleProvider; class X509SignatureUtil { @@ -84,6 +87,32 @@ class X509SignatureUtil } } + 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; + } + } + return sigAlgId.getAlgorithm().getId(); } 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 36a32b1..7d0b203 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 ea89261..0640669 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 f986734..53548f0 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; @@ -88,12 +89,14 @@ import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.jcajce.provider.config.PKCS12StoreParameter; +import org.bouncycastle.jcajce.PKCS12StoreParameter; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; // BEGIN android-removed // import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec; // END android-removed 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; @@ -107,10 +110,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(); @@ -605,8 +609,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()); @@ -615,7 +619,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); @@ -651,13 +655,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); @@ -689,7 +692,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()); @@ -697,7 +700,7 @@ public class PKCS12KeyStoreSpi key.setTryWrongPKCS12Zero(wrongPKCS12Zero); - Cipher cipher = Cipher.getInstance(algorithm.getId(), bcProvider); + Cipher cipher = helper.createCipher(algorithm.getId()); cipher.init(mode, key, defParams); return cipher.doFinal(data); @@ -727,13 +730,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()) @@ -1654,7 +1657,7 @@ public class PKCS12KeyStoreSpi asn1Out.writeObject(pfx); } - private static byte[] calculatePbeMac( + private byte[] calculatePbeMac( ASN1ObjectIdentifier oid, byte[] salt, int itCount, @@ -1663,13 +1666,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(); @@ -1680,20 +1683,19 @@ public class PKCS12KeyStoreSpi { public BCPKCS12KeyStore() { - super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); + super(new BouncyCastleProvider(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); } } - // BEGIN android-removed // public static class BCPKCS12KeyStore3DES // extends PKCS12KeyStoreSpi // { // public BCPKCS12KeyStore3DES() // { - // super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); + // super(new BouncyCastleProvider(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); // } // } - // + // // public static class DefPKCS12KeyStore // extends PKCS12KeyStoreSpi // { @@ -1702,7 +1704,7 @@ public class PKCS12KeyStoreSpi // super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); // } // } - // + // // public static class DefPKCS12KeyStore3DES // extends PKCS12KeyStoreSpi // { 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 55f5ace..630a3ca 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 @@ -16,6 +16,9 @@ import java.security.spec.InvalidParameterSpecException; // END android-removed import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +// BEGIN android-removed +// import org.bouncycastle.asn1.cms.CCMParameters; +// END android-removed import org.bouncycastle.asn1.cms.GCMParameters; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.crypto.BlockCipher; @@ -31,6 +34,9 @@ import org.bouncycastle.crypto.engines.AESWrapEngine; // import org.bouncycastle.crypto.macs.GMac; // END android-removed import org.bouncycastle.crypto.modes.CBCBlockCipher; +// BEGIN android-removed +// import org.bouncycastle.crypto.modes.CCMBlockCipher; +// END android-removed import org.bouncycastle.crypto.modes.CFBBlockCipher; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.modes.OFBBlockCipher; @@ -48,9 +54,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; -// BEGIN android-removed -// import org.bouncycastle.jce.provider.BouncyCastleProvider; -// END android-removed import org.bouncycastle.util.Integers; public final class AES @@ -113,6 +116,15 @@ public final class AES } // BEGIN android-removed + // static public class CCM + // extends BaseBlockCipher + // { + // public CCM() + // { + // super(new CCMBlockCipher(new AESFastEngine())); + // } + // } + // // public static class AESCMAC // extends BaseMac // { @@ -369,7 +381,7 @@ public final class AES // // try // { - // params = AlgorithmParameters.getInstance("AES", BouncyCastleProvider.PROVIDER_NAME); + // params = createParametersInstance("AES"); // params.init(new IvParameterSpec(iv)); // } // catch (Exception e) @@ -380,6 +392,82 @@ public final class AES // return params; // } // } + // + // 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; + // } + // } // END android-removed public static class AlgParams @@ -406,8 +494,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) { @@ -464,7 +551,7 @@ public final class AES { Constructor constructor = gcmSpecClass.getConstructor(new Class[] { Integer.TYPE, byte[].class }); - return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen()), gcmParams.getNonce() }); + return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() }); } catch (NoSuchMethodException e) { @@ -480,6 +567,83 @@ public final class AES } } + // BEGIN android-removed + // 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) + // { + // 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()); + // } + // } + // END android-removed + public static class Mappings extends SymmetricAlgorithmProvider { @@ -512,8 +676,12 @@ public final class AES provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes128_GCM, "GCM"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes192_GCM, "GCM"); provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes256_GCM, "GCM"); - // BEGIN android-removed + // 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"); @@ -549,6 +717,21 @@ public final class AES // BEGIN android-removed // 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"); // END android-removed provider.addAlgorithm("Cipher.GCM", PREFIX + "$GCM"); @@ -577,7 +760,13 @@ 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"); // END android-removed 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 6d5c5e8..b4c7c06 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 @@ -44,7 +44,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 { @@ -187,7 +186,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 6b9b6d6..7b3addd 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 @@ -43,7 +43,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 { @@ -270,30 +269,30 @@ public final class DESede // { // throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DES parameter generation."); // } - // + // protected AlgorithmParameters engineGenerateParameters() // { // byte[] iv = new byte[8]; - // + // if (random == null) // { // random = new SecureRandom(); // } - // + // random.nextBytes(iv); - // + // AlgorithmParameters params; - // + // try // { - // params = AlgorithmParameters.getInstance("DES", BouncyCastleProvider.PROVIDER_NAME); + // params = createParametersInstance("DES"); // params.init(new IvParameterSpec(iv)); // } // catch (Exception e) // { // throw new RuntimeException(e.getMessage()); // } - // + // return params; // } // } 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 09426b2..4056aa7 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 @@ -36,10 +36,7 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; // END android-removed import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -// BEGIN android-removed -// import org.bouncycastle.util.Arrays; -// END android-removed +import org.bouncycastle.util.Arrays; public final class RC2 { @@ -218,7 +215,7 @@ public final class RC2 // extends BaseAlgorithmParameterGenerator // { // RC2ParameterSpec spec = null; - // + // // protected void engineInit( // AlgorithmParameterSpec genParamSpec, // SecureRandom random) @@ -229,28 +226,28 @@ public final class RC2 // spec = (RC2ParameterSpec)genParamSpec; // return; // } - // + // // throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for RC2 parameter generation."); // } - // + // // protected AlgorithmParameters engineGenerateParameters() // { // AlgorithmParameters params; - // + // // if (spec == null) // { // byte[] iv = new byte[8]; - // + // // if (random == null) // { // random = new SecureRandom(); // } - // + // // random.nextBytes(iv); - // + // // try // { - // params = AlgorithmParameters.getInstance("RC2", BouncyCastleProvider.PROVIDER_NAME); + // params = createParametersInstance("RC2"); // params.init(new IvParameterSpec(iv)); // } // catch (Exception e) @@ -262,7 +259,7 @@ public final class RC2 // { // try // { - // params = AlgorithmParameters.getInstance("RC2", BouncyCastleProvider.PROVIDER_NAME); + // params = createParametersInstance("RC2"); // params.init(spec); // } // catch (Exception e) @@ -270,11 +267,11 @@ public final class RC2 // throw new RuntimeException(e.getMessage()); // } // } - // + // // return params; // } // } - // + // // public static class KeyGenerator // extends BaseKeyGenerator // { @@ -283,7 +280,7 @@ public final class RC2 // super("RC2", 128, new CipherKeyGenerator()); // } // } - // + // // public static class AlgParams // extends BaseAlgorithmParameters // { @@ -305,7 +302,7 @@ public final class RC2 // 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, // 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab // }; - // + // // private static final short[] ekb = { // 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5, // 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5, @@ -324,15 +321,15 @@ public final class RC2 // 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7, // 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd // }; - // + // // private byte[] iv; // private int parameterVersion = 58; - // + // // protected byte[] engineGetEncoded() // { // return Arrays.clone(iv); // } - // + // // protected byte[] engineGetEncoded( // String format) // throws IOException @@ -348,15 +345,15 @@ public final class RC2 // return new RC2CBCParameter(parameterVersion, engineGetEncoded()).getEncoded(); // } // } - // + // // if (format.equals("RAW")) // { // return engineGetEncoded(); // } - // + // // return null; // } - // + // // protected AlgorithmParameterSpec localEngineGetParameterSpec( // Class paramSpec) // throws InvalidParameterSpecException @@ -375,15 +372,15 @@ public final class RC2 // } // } // } - // + // // if (paramSpec == IvParameterSpec.class) // { // return new IvParameterSpec(iv); // } - // + // // throw new InvalidParameterSpecException("unknown parameter spec passed to RC2 parameters object."); // } - // + // // protected void engineInit( // AlgorithmParameterSpec paramSpec) // throws InvalidParameterSpecException @@ -406,7 +403,7 @@ public final class RC2 // parameterVersion = effKeyBits; // } // } - // + // // this.iv = ((RC2ParameterSpec)paramSpec).getIV(); // } // else @@ -414,14 +411,14 @@ public final class RC2 // throw new InvalidParameterSpecException("IvParameterSpec or RC2ParameterSpec required to initialise a RC2 parameters algorithm parameters object"); // } // } - // + // // protected void engineInit( // byte[] params) // throws IOException // { // this.iv = Arrays.clone(params); // } - // + // // protected void engineInit( // byte[] params, // String format) @@ -430,26 +427,26 @@ public final class RC2 // if (this.isASN1FormatString(format)) // { // RC2CBCParameter p = RC2CBCParameter.getInstance(ASN1Primitive.fromByteArray(params)); - // + // // if (p.getRC2ParameterVersion() != null) // { // parameterVersion = p.getRC2ParameterVersion().intValue(); // } - // + // // iv = p.getIV(); - // + // // return; // } - // + // // if (format.equals("RAW")) // { // engineInit(params); // return; // } - // + // // throw new IOException("Unknown parameters format in IV parameters object"); // } - // + // // protected String engineToString() // { // return "RC2 Parameters"; 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 63d6548..296d692 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 faf31b3..0e933b7 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 @@ -207,7 +207,7 @@ public class BaseBlockCipher { try { - engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, BouncyCastleProvider.PROVIDER_NAME); + engineParams = createParametersInstance(pbeAlgorithm); engineParams.init(pbeSpec); } catch (Exception e) @@ -226,7 +226,7 @@ public class BaseBlockCipher try { - engineParams = AlgorithmParameters.getInstance(name, BouncyCastleProvider.PROVIDER_NAME); + engineParams = createParametersInstance(name); engineParams.init(ivParam.getIV()); } catch (Exception e) @@ -238,7 +238,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) 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 b37a9fe..fba61b8 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; @@ -89,7 +90,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 5be73e5..a26d980 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; @@ -35,6 +37,8 @@ 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 @@ -66,6 +70,8 @@ public abstract class BaseWrapCipher private int ivSize; private byte[] iv; + private final JcaJceHelper helper = new BCJcaJceHelper(); + protected BaseWrapCipher() { } @@ -111,6 +117,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 @@ -374,7 +386,7 @@ public abstract class BaseWrapCipher { try { - KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); + KeyFactory kf = helper.createKeyFactory(wrappedKeyAlgorithm); if (wrappedKeyType == Cipher.PUBLIC_KEY) { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java new file mode 100644 index 0000000..4008761 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java @@ -0,0 +1,30 @@ +package org.bouncycastle.jcajce.util; + +import java.security.Provider; +import java.security.Security; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +/** + * A JCA/JCE helper that refers to the BC provider for all it's needs. + */ +public class BCJcaJceHelper + extends ProviderJcaJceHelper +{ + private static Provider getBouncyCastleProvider() + { + if (Security.getProvider("BC") != null) + { + return Security.getProvider("BC"); + } + else + { + return new BouncyCastleProvider(); + } + } + + public BCJcaJceHelper() + { + super(getBouncyCastleProvider()); + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java index 43a97f3..27ca55a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java @@ -92,7 +92,7 @@ public class DefaultJcaJceHelper } public CertificateFactory createCertificateFactory(String algorithm) - throws NoSuchAlgorithmException, CertificateException + throws CertificateException { return CertificateFactory.getInstance(algorithm); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java index f5da335..7a78193 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java @@ -58,5 +58,5 @@ public interface JcaJceHelper throws NoSuchAlgorithmException, NoSuchProviderException; CertificateFactory createCertificateFactory(String algorithm) - throws NoSuchAlgorithmException, NoSuchProviderException, CertificateException; + throws NoSuchProviderException, CertificateException; } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java index ebbfacc..280539d 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java @@ -99,7 +99,7 @@ public class NamedJcaJceHelper } public CertificateFactory createCertificateFactory(String algorithm) - throws NoSuchAlgorithmException, CertificateException, NoSuchProviderException + throws CertificateException, NoSuchProviderException { return CertificateFactory.getInstance(algorithm, providerName); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java index fad1048..fb4b9a7 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java @@ -99,7 +99,7 @@ public class ProviderJcaJceHelper } public CertificateFactory createCertificateFactory(String algorithm) - throws NoSuchAlgorithmException, CertificateException + throws CertificateException { return CertificateFactory.getInstance(algorithm, provider); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/AnnotatedException.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/AnnotatedException.java index c9ac46e..e8a8abe 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/AnnotatedException.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/AnnotatedException.java @@ -8,14 +8,14 @@ public class AnnotatedException { private Throwable _underlyingException; - AnnotatedException(String string, Throwable e) + public AnnotatedException(String string, Throwable e) { super(string); _underlyingException = e; } - AnnotatedException(String string) + public AnnotatedException(String string) { this(string, null); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java index 145186a..82c6a5a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java @@ -44,7 +44,7 @@ import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; public final class BouncyCastleProvider extends Provider implements ConfigurableProvider { - private static String info = "BouncyCastle Security Provider v1.51"; + private static String info = "BouncyCastle Security Provider v1.52"; public static final String PROVIDER_NAME = "BC"; @@ -139,7 +139,7 @@ public final class BouncyCastleProvider extends Provider */ public BouncyCastleProvider() { - super(PROVIDER_NAME, 1.51, info); + super(PROVIDER_NAME, 1.52, info); AccessController.doPrivileged(new PrivilegedAction() { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java index b4338f6..f53f3ac 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java @@ -13,7 +13,6 @@ import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.Certificate; import java.security.cert.CertificateParsingException; -import java.security.cert.PKIXParameters; import java.security.cert.PolicyQualifierInfo; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; @@ -27,14 +26,15 @@ import java.security.spec.DSAPublicKeySpec; import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; - import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; @@ -47,10 +47,13 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERIA5String; +import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.DistributionPoint; @@ -60,27 +63,22 @@ import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.X509Extension; -// BEGIN android-removed -// import org.bouncycastle.jce.X509LDAPCertStoreParameters; -// END android-removed +import org.bouncycastle.jcajce.PKIXCRLStore; +import org.bouncycastle.jcajce.PKIXCRLStoreSelector; +import org.bouncycastle.jcajce.PKIXCertStore; +import org.bouncycastle.jcajce.PKIXCertStoreSelector; +import org.bouncycastle.jcajce.PKIXExtendedParameters; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; -import org.bouncycastle.util.Integers; import org.bouncycastle.util.Selector; +import org.bouncycastle.util.Store; import org.bouncycastle.util.StoreException; -import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; -import org.bouncycastle.x509.ExtendedPKIXParameters; -// BEGIN android-removed -// import org.bouncycastle.x509.X509AttributeCertStoreSelector; -// END android-removed import org.bouncycastle.x509.X509AttributeCertificate; -import org.bouncycastle.x509.X509CRLStoreSelector; -import org.bouncycastle.x509.X509CertStoreSelector; // BEGIN android-removed -// import org.bouncycastle.x509.X509Store; +// import org.bouncycastle.x509.extension.X509ExtensionUtil; // END android-removed -public class CertPathValidatorUtilities +class CertPathValidatorUtilities { protected static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil(); @@ -166,7 +164,7 @@ public class CertPathValidatorUtilities Exception invalidKeyEx = null; X509CertSelector certSelectX509 = new X509CertSelector(); - X500Principal certIssuer = getEncodedIssuerPrincipal(cert); + X500Name certIssuer = PrincipalUtils.getEncodedIssuerPrincipal(cert); try { @@ -197,7 +195,7 @@ public class CertPathValidatorUtilities { try { - X500Principal caName = new X500Principal(trust.getCAName()); + X500Name caName = PrincipalUtils.getCA(trust); if (certIssuer.equals(caName)) { trustPublicKey = trust.getCAPublicKey(); @@ -240,50 +238,41 @@ public class CertPathValidatorUtilities return trust; } - protected static void addAdditionalStoresFromAltNames( - X509Certificate cert, - ExtendedPKIXParameters pkixParams) + static List<PKIXCertStore> getAdditionalStoresFromAltNames( + byte[] issuerAlternativeName, + Map<GeneralName, PKIXCertStore> altNameCertStoreMap) throws CertificateParsingException { // if in the IssuerAltName extension an URI - // is given, add an additinal X.509 store - if (cert.getIssuerAlternativeNames() != null) + // is given, add an additional X.509 store + if (issuerAlternativeName != null) { - Iterator it = cert.getIssuerAlternativeNames().iterator(); - while (it.hasNext()) + GeneralNames issuerAltName = GeneralNames.getInstance(ASN1OctetString.getInstance(issuerAlternativeName).getOctets()); + + GeneralName[] names = issuerAltName.getNames(); + List<PKIXCertStore> stores = new ArrayList<PKIXCertStore>(); + + for (int i = 0; i != names.length; i++) { - // look for URI - List list = (List)it.next(); - if (list.get(0).equals(Integers.valueOf(GeneralName.uniformResourceIdentifier))) + GeneralName altName = names[i]; + + PKIXCertStore altStore = altNameCertStoreMap.get(altName); + + if (altStore != null) { - // found - String temp = (String)list.get(1); - CertPathValidatorUtilities.addAdditionalStoreFromLocation(temp, pkixParams); + stores.add(altStore); } } - } - } - /** - * Returns the issuer of an attribute certificate or certificate. - * - * @param cert The attribute certificate or certificate. - * @return The issuer as <code>X500Principal</code>. - */ - protected static X500Principal getEncodedIssuerPrincipal( - Object cert) - { - if (cert instanceof X509Certificate) - { - return ((X509Certificate)cert).getIssuerX500Principal(); + return stores; } else { - return (X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]; + return Collections.EMPTY_LIST; } } - protected static Date getValidDate(PKIXParameters paramsPKIX) + protected static Date getValidDate(PKIXExtendedParameters paramsPKIX) { Date validDate = paramsPKIX.getDate(); @@ -295,11 +284,6 @@ public class CertPathValidatorUtilities return validDate; } - protected static X500Principal getSubjectPrincipal(X509Certificate cert) - { - return cert.getSubjectX500Principal(); - } - protected static boolean isSelfIssued(X509Certificate cert) { return cert.getSubjectDN().equals(cert.getIssuerDN()); @@ -346,11 +330,6 @@ public class CertPathValidatorUtilities } } - protected static X500Principal getIssuerPrincipal(X509CRL crl) - { - return crl.getIssuerX500Principal(); - } - protected static AlgorithmIdentifier getAlgorithmIdentifier( PublicKey key) throws CertPathValidatorException @@ -361,7 +340,7 @@ public class CertPathValidatorUtilities SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject()); - return info.getAlgorithmId(); + return info.getAlgorithm(); } catch (Exception e) { @@ -655,73 +634,22 @@ public class CertPathValidatorUtilities return policySet == null || policySet.contains(ANY_POLICY) || policySet.isEmpty(); } - protected static void addAdditionalStoreFromLocation(String location, - ExtendedPKIXParameters pkixParams) - { - if (pkixParams.isAdditionalLocationsEnabled()) - { - try - { - // BEGIN android-removed - // if (location.startsWith("ldap://")) - // { - // // ldap://directory.d-trust.net/CN=D-TRUST - // // Qualified CA 2003 1:PN,O=D-Trust GmbH,C=DE - // // skip "ldap://" - // location = location.substring(7); - // // after first / baseDN starts - // String base = null; - // String url = null; - // if (location.indexOf("/") != -1) - // { - // base = location.substring(location.indexOf("/")); - // // URL - // url = "ldap://" - // + location.substring(0, location.indexOf("/")); - // } - // else - // { - // url = "ldap://" + location; - // } - // // use all purpose parameters - // X509LDAPCertStoreParameters params = new X509LDAPCertStoreParameters.Builder( - // url, base).build(); - // pkixParams.addAdditionalStore(X509Store.getInstance( - // "CERTIFICATE/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); - // pkixParams.addAdditionalStore(X509Store.getInstance( - // "CRL/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); - // pkixParams.addAdditionalStore(X509Store.getInstance( - // "ATTRIBUTECERTIFICATE/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); - // pkixParams.addAdditionalStore(X509Store.getInstance( - // "CERTIFICATEPAIR/LDAP", params, BouncyCastleProvider.PROVIDER_NAME)); - // } - // END android-removed - } - catch (Exception e) - { - // cannot happen - throw new RuntimeException("Exception adding X.509 stores."); - } - } - } - /** * Return a Collection of all certificates or attribute certificates found * in the X509Store's that are matching the certSelect criteriums. * * @param certSelect a {@link Selector} object that will be used to select * the certificates - * @param certStores a List containing only {@link X509Store} objects. These + * @param certStores a List containing only {@link Store} objects. These * are used to search for certificates. - * @return a Collection of all found {@link X509Certificate} or - * {@link org.bouncycastle.x509.X509AttributeCertificate} objects. + * @return a Collection of all found {@link X509Certificate} * May be empty but never <code>null</code>. */ - protected static Collection findCertificates(X509CertStoreSelector certSelect, + protected static Collection findCertificates(PKIXCertStoreSelector certSelect, List certStores) throws AnnotatedException { - Set certs = new HashSet(); + Set certs = new LinkedHashSet(); Iterator iter = certStores.iterator(); while (iter.hasNext()) @@ -749,7 +677,7 @@ public class CertPathValidatorUtilities try { - certs.addAll(certStore.getCertificates(certSelect)); + certs.addAll(PKIXCertStoreSelector.getCertificates(certSelect, certStore)); } catch (CertStoreException e) { @@ -762,38 +690,7 @@ public class CertPathValidatorUtilities return certs; } - // BEGIN android-removed - // protected static Collection findCertificates(X509AttributeCertStoreSelector certSelect, - // List certStores) - // throws AnnotatedException - // { - // Set certs = new HashSet(); - // Iterator iter = certStores.iterator(); - // - // while (iter.hasNext()) - // { - // Object obj = iter.next(); - // - // if (obj instanceof X509Store) - // { - // X509Store certStore = (X509Store)obj; - // try - // { - // certs.addAll(certStore.getMatches(certSelect)); - // } - // catch (StoreException e) - // { - // throw new AnnotatedException( - // "Problem while picking certificates from X.509 store.", e); - // } - // } - // } - // return certs; - // } - // END android-removed - - protected static void addAdditionalStoresFromCRLDistributionPoint( - CRLDistPoint crldp, ExtendedPKIXParameters pkixParams) + static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint(CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap) throws AnnotatedException { if (crldp != null) @@ -808,6 +705,8 @@ public class CertPathValidatorUtilities throw new AnnotatedException( "Distribution points could not be read.", e); } + List<PKIXCRLStore> stores = new ArrayList<PKIXCRLStore>(); + for (int i = 0; i < dps.length; i++) { DistributionPointName dpn = dps[i].getDistributionPoint(); @@ -818,21 +717,31 @@ public class CertPathValidatorUtilities { GeneralName[] genNames = GeneralNames.getInstance( dpn.getName()).getNames(); - // look for an URI + for (int j = 0; j < genNames.length; j++) { - if (genNames[j].getTagNo() == GeneralName.uniformResourceIdentifier) + // BEGIN android-removed + // PKIXCRLStore store = namedCRLStoreMap.get(genNames[i]); + // END android-removed + // BEGIN android-added + // Seems like a bug, unless there should be a guarantee that j < i, + // However, it's breaking the tests. + PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]); + // END android-added + if (store != null) { - String location = DERIA5String.getInstance( - genNames[j].getName()).getString(); - CertPathValidatorUtilities - .addAdditionalStoreFromLocation(location, - pkixParams); + stores.add(store); } } } } } + + return stores; + } + else + { + return Collections.EMPTY_LIST; } } @@ -840,26 +749,22 @@ public class CertPathValidatorUtilities * Add the CRL issuers from the cRLIssuer field of the distribution point or * from the certificate if not given to the issuer criterion of the * <code>selector</code>. - * <p/> + * <p> * The <code>issuerPrincipals</code> are a collection with a single - * <code>X500Principal</code> for <code>X509Certificate</code>s. For - * {@link X509AttributeCertificate}s the issuer may contain more than one - * <code>X500Principal</code>. - * + * <code>X500Name</code> for <code>X509Certificate</code>s. + * </p> * @param dp The distribution point. * @param issuerPrincipals The issuers of the certificate or attribute * certificate which contains the distribution point. * @param selector The CRL selector. - * @param pkixParams The PKIX parameters containing the cert stores. * @throws AnnotatedException if an exception occurs while processing. * @throws ClassCastException if <code>issuerPrincipals</code> does not - * contain only <code>X500Principal</code>s. + * contain only <code>X500Name</code>s. */ protected static void getCRLIssuersFromDistributionPoint( DistributionPoint dp, Collection issuerPrincipals, - X509CRLSelector selector, - ExtendedPKIXParameters pkixParams) + X509CRLSelector selector) throws AnnotatedException { List issuers = new ArrayList(); @@ -874,7 +779,7 @@ public class CertPathValidatorUtilities { try { - issuers.add(new X500Principal(genNames[j].getName() + issuers.add(X500Name.getInstance(genNames[j].getName() .toASN1Primitive().getEncoded())); } catch (IOException e) @@ -900,7 +805,7 @@ public class CertPathValidatorUtilities // add and check issuer principals for (Iterator it = issuerPrincipals.iterator(); it.hasNext(); ) { - issuers.add((X500Principal)it.next()); + issuers.add(it.next()); } } // TODO: is not found although this should correctly add the rel name. selector of Sun is buggy here or PKI test case is invalid @@ -952,7 +857,7 @@ public class CertPathValidatorUtilities { try { - selector.addIssuerName(((X500Principal)it.next()).getEncoded()); + selector.addIssuerName(((X500Name)it.next()).getEncoded()); } catch (IOException ex) { @@ -965,14 +870,7 @@ public class CertPathValidatorUtilities private static BigInteger getSerialNumber( Object cert) { - if (cert instanceof X509Certificate) - { - return ((X509Certificate)cert).getSerialNumber(); - } - else - { - return ((X509AttributeCertificate)cert).getSerialNumber(); - } + return ((X509Certificate)cert).getSerialNumber(); } protected static void getCertStatus( @@ -1002,20 +900,32 @@ public class CertPathValidatorUtilities { return; } - - X500Principal certIssuer = crl_entry.getCertificateIssuer(); + // BEGIN android-removed + // X500Name certIssuer = X500Name.getInstance(crl_entry.getCertificateIssuer().getEncoded()); + // END android-removed + // BEGIN android-added + // The original code throws null pointer exception for OpenSSLX509CRL, + // which uses the implementation for getCertificateIssuer() in X509CRL, method + // whose reference implementation has the following JavaDoc: "If the certificate + // issuer is also the CRL issuer, this method returns null." + X500Name certIssuer = null; + X500Principal certificateIssuerPrincipal = crl_entry.getCertificateIssuer(); + if (certificateIssuerPrincipal != null) { + certIssuer = X500Name.getInstance(certificateIssuerPrincipal.getEncoded()); + } + // END android-added if (certIssuer == null) { - certIssuer = getIssuerPrincipal(crl); + certIssuer = PrincipalUtils.getIssuerPrincipal(crl); } - if (!getEncodedIssuerPrincipal(cert).equals(certIssuer)) + if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(certIssuer)) { return; } } - else if (!getEncodedIssuerPrincipal(cert).equals(getIssuerPrincipal(crl))) + else if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(PrincipalUtils.getIssuerPrincipal(crl))) { return; // not for our issuer, ignore } @@ -1037,7 +947,7 @@ public class CertPathValidatorUtilities reasonCode = ASN1Enumerated .getInstance(CertPathValidatorUtilities .getExtensionValue(crl_entry, - X509Extension.reasonCode.getId())); + Extension.reasonCode.getId())); } catch (Exception e) { @@ -1074,31 +984,29 @@ public class CertPathValidatorUtilities /** * Fetches delta CRLs according to RFC 3280 section 5.2.4. * - * @param currentDate The date for which the delta CRLs must be valid. - * @param paramsPKIX The extended PKIX parameters. + * @param validityDate The date for which the delta CRLs must be valid. * @param completeCRL The complete CRL the delta CRL is for. * @return A <code>Set</code> of <code>X509CRL</code>s with delta CRLs. * @throws AnnotatedException if an exception occurs while picking the delta * CRLs. */ - protected static Set getDeltaCRLs(Date currentDate, - ExtendedPKIXParameters paramsPKIX, X509CRL completeCRL) + protected static Set getDeltaCRLs(Date validityDate, + X509CRL completeCRL, List<CertStore> certStores, List<PKIXCRLStore> pkixCrlStores) throws AnnotatedException { - - X509CRLStoreSelector deltaSelect = new X509CRLStoreSelector(); - + X509CRLSelector baseDeltaSelect = new X509CRLSelector(); // 5.2.4 (a) try { - deltaSelect.addIssuerName(CertPathValidatorUtilities - .getIssuerPrincipal(completeCRL).getEncoded()); + baseDeltaSelect.addIssuerName(PrincipalUtils.getIssuerPrincipal(completeCRL).getEncoded()); } catch (IOException e) { throw new AnnotatedException("Cannot extract issuer from CRL.", e); } + + BigInteger completeCRLNumber = null; try { @@ -1130,17 +1038,21 @@ public class CertPathValidatorUtilities // 5.2.4 (d) - deltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber + baseDeltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber .add(BigInteger.valueOf(1))); - deltaSelect.setIssuingDistributionPoint(idp); - deltaSelect.setIssuingDistributionPointEnabled(true); + PKIXCRLStoreSelector.Builder selBuilder = new PKIXCRLStoreSelector.Builder(baseDeltaSelect); + + selBuilder.setIssuingDistributionPoint(idp); + selBuilder.setIssuingDistributionPointEnabled(true); // 5.2.4 (c) - deltaSelect.setMaxBaseCRLNumber(completeCRLNumber); + selBuilder.setMaxBaseCRLNumber(completeCRLNumber); + + PKIXCRLStoreSelector deltaSelect = selBuilder.build(); // find delta CRLs - Set temp = CRL_UTIL.findCRLs(deltaSelect, paramsPKIX, currentDate); + Set temp = CRL_UTIL.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores); Set result = new HashSet(); @@ -1173,8 +1085,7 @@ public class CertPathValidatorUtilities * Fetches complete CRLs according to RFC 3280. * * @param dp The distribution point for which the complete CRL - * @param cert The <code>X509Certificate</code> or - * {@link org.bouncycastle.x509.X509AttributeCertificate} for + * @param cert The <code>X509Certificate</code> for * which the CRL should be searched. * @param currentDate The date for which the delta CRLs must be valid. * @param paramsPKIX The extended PKIX parameters. @@ -1184,66 +1095,51 @@ public class CertPathValidatorUtilities * or no CRLs are found. */ protected static Set getCompleteCRLs(DistributionPoint dp, Object cert, - Date currentDate, ExtendedPKIXParameters paramsPKIX) + Date currentDate, PKIXExtendedParameters paramsPKIX) throws AnnotatedException { - X509CRLStoreSelector crlselect = new X509CRLStoreSelector(); + X509CRLSelector baseCrlSelect = new X509CRLSelector(); + try { Set issuers = new HashSet(); - if (cert instanceof X509AttributeCertificate) - { - issuers.add(((X509AttributeCertificate)cert) - .getIssuer().getPrincipals()[0]); - } - else - { - issuers.add(getEncodedIssuerPrincipal(cert)); - } - CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, crlselect, paramsPKIX); + + issuers.add(PrincipalUtils.getEncodedIssuerPrincipal(cert)); + + CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, baseCrlSelect); } catch (AnnotatedException e) { throw new AnnotatedException( "Could not get issuer information from distribution point.", e); } + if (cert instanceof X509Certificate) { - crlselect.setCertificateChecking((X509Certificate)cert); - } - else if (cert instanceof X509AttributeCertificate) - { - crlselect.setAttrCertificateChecking((X509AttributeCertificate)cert); + baseCrlSelect.setCertificateChecking((X509Certificate)cert); } + PKIXCRLStoreSelector crlSelect = new PKIXCRLStoreSelector.Builder(baseCrlSelect).setCompleteCRLEnabled(true).build(); - crlselect.setCompleteCRLEnabled(true); - - Set crls = CRL_UTIL.findCRLs(crlselect, paramsPKIX, currentDate); + Date validityDate = currentDate; - if (crls.isEmpty()) + if (paramsPKIX.getDate() != null) { - if (cert instanceof X509AttributeCertificate) - { - X509AttributeCertificate aCert = (X509AttributeCertificate)cert; + validityDate = paramsPKIX.getDate(); + } - throw new AnnotatedException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\""); - } - else - { - X509Certificate xCert = (X509Certificate)cert; + Set crls = CRL_UTIL.findCRLs(crlSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores()); + + checkCRLsNotEmpty(crls, cert); - throw new AnnotatedException("No CRLs found for issuer \"" + xCert.getIssuerX500Principal() + "\""); - } - } return crls; } protected static Date getValidCertDateFromValidityModel( - ExtendedPKIXParameters paramsPKIX, CertPath certPath, int index) + PKIXExtendedParameters paramsPKIX, CertPath certPath, int index) throws AnnotatedException { - if (paramsPKIX.getValidityModel() == ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL) + if (paramsPKIX.getValidityModel() == PKIXExtendedParameters.CHAIN_VALIDITY_MODEL) { // if end cert use given signing/encryption/... time if (index <= 0) @@ -1324,7 +1220,7 @@ public class CertPathValidatorUtilities * <code>index</code> extended with DSA parameters if applicable. * @throws AnnotatedException if DSA parameters cannot be inherited. */ - protected static PublicKey getNextWorkingKey(List certs, int index) + protected static PublicKey getNextWorkingKey(List certs, int index, JcaJceHelper helper) throws CertPathValidatorException { Certificate cert = (Certificate)certs.get(index); @@ -1357,7 +1253,7 @@ public class CertPathValidatorUtilities dsaPubKey.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG()); try { - KeyFactory keyFactory = KeyFactory.getInstance("DSA", BouncyCastleProvider.PROVIDER_NAME); + KeyFactory keyFactory = helper.createKeyFactory("DSA"); return keyFactory.generatePublic(dsaPubKeySpec); } catch (Exception exception) @@ -1372,37 +1268,57 @@ public class CertPathValidatorUtilities * Find the issuer certificates of a given certificate. * * @param cert The certificate for which an issuer should be found. - * @param pkixParams * @return A <code>Collection</code> object containing the issuer * <code>X509Certificate</code>s. Never <code>null</code>. * @throws AnnotatedException if an error occurs. */ - protected static Collection findIssuerCerts( + static Collection findIssuerCerts( X509Certificate cert, - ExtendedPKIXBuilderParameters pkixParams) + List<CertStore> certStores, + List<PKIXCertStore> pkixCertStores) throws AnnotatedException { - X509CertStoreSelector certSelect = new X509CertStoreSelector(); - Set certs = new HashSet(); + X509CertSelector selector = new X509CertSelector(); + try { - certSelect.setSubject(cert.getIssuerX500Principal().getEncoded()); + selector.setSubject(PrincipalUtils.getIssuerPrincipal(cert).getEncoded()); } - catch (IOException ex) + catch (IOException e) { throw new AnnotatedException( - "Subject criteria for certificate selector to find issuer certificate could not be set.", ex); + "Subject criteria for certificate selector to find issuer certificate could not be set.", e); + } + + try + { + byte[] akiExtensionValue = cert.getExtensionValue(AUTHORITY_KEY_IDENTIFIER); + if (akiExtensionValue != null) + { + ASN1OctetString aki = ASN1OctetString.getInstance(akiExtensionValue); + byte[] authorityKeyIdentifier = AuthorityKeyIdentifier.getInstance(aki.getOctets()).getKeyIdentifier(); + if (authorityKeyIdentifier != null) + { + selector.setSubjectKeyIdentifier(new DEROctetString(authorityKeyIdentifier).getEncoded()); + } + } + } + catch (Exception e) + { + // authority key identifier could not be retrieved from target cert, just search without it } + PKIXCertStoreSelector certSelect = new PKIXCertStoreSelector.Builder(selector).build(); + Set certs = new LinkedHashSet(); + Iterator iter; try { List matches = new ArrayList(); - matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getCertStores())); - matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getStores())); - matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getAdditionalStores())); + matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, certStores)); + matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixCertStores)); iter = matches.iterator(); } @@ -1435,4 +1351,24 @@ public class CertPathValidatorUtilities cert.verify(publicKey, sigProvider); } } + + static void checkCRLsNotEmpty(Set crls, Object cert) + throws AnnotatedException + { + if (crls.isEmpty()) + { + if (cert instanceof X509AttributeCertificate) + { + X509AttributeCertificate aCert = (X509AttributeCertificate)cert; + + throw new AnnotatedException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\""); + } + else + { + X509Certificate xCert = (X509Certificate)cert; + + throw new AnnotatedException("No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(PrincipalUtils.getIssuerPrincipal(xCert)) + "\""); + } + } + } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEStreamCipher.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEStreamCipher.java deleted file mode 100644 index c5b6292..0000000 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEStreamCipher.java +++ /dev/null @@ -1,609 +0,0 @@ -package org.bouncycastle.jce.provider; - -import java.security.AlgorithmParameters; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PrivateKey; -import java.security.SecureRandom; -import java.security.spec.AlgorithmParameterSpec; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.CipherSpi; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SecretKey; -import javax.crypto.ShortBufferException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.PBEParameterSpec; -// BEGIN android-removed -// import javax.crypto.spec.RC2ParameterSpec; -// import javax.crypto.spec.RC5ParameterSpec; -// END android-removed -import javax.crypto.spec.SecretKeySpec; - -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.StreamCipher; -// BEGIN android-removed -// import org.bouncycastle.crypto.engines.BlowfishEngine; -// import org.bouncycastle.crypto.engines.DESEngine; -// import org.bouncycastle.crypto.engines.DESedeEngine; -// import org.bouncycastle.crypto.engines.SkipjackEngine; -// import org.bouncycastle.crypto.engines.TwofishEngine; -// END android-removed -import org.bouncycastle.crypto.modes.CFBBlockCipher; -import org.bouncycastle.crypto.modes.OFBBlockCipher; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.crypto.params.ParametersWithIV; -import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; -import org.bouncycastle.jcajce.provider.symmetric.util.PBE; - -public class JCEStreamCipher - extends CipherSpi - implements PBE -{ - // - // specs we can handle. - // - private Class[] availableSpecs = - { - // BEGIN android-removed - // RC2ParameterSpec.class, - // RC5ParameterSpec.class, - // END android-removed - IvParameterSpec.class, - PBEParameterSpec.class - }; - - private StreamCipher cipher; - private ParametersWithIV ivParam; - - private int ivLength = 0; - - private PBEParameterSpec pbeSpec = null; - private String pbeAlgorithm = null; - - private AlgorithmParameters engineParams; - - protected JCEStreamCipher( - StreamCipher engine, - int ivLength) - { - cipher = engine; - this.ivLength = ivLength; - } - - protected int engineGetBlockSize() - { - return 0; - } - - protected byte[] engineGetIV() - { - return (ivParam != null) ? ivParam.getIV() : null; - } - - protected int engineGetKeySize( - Key key) - { - return key.getEncoded().length * 8; - } - - protected int engineGetOutputSize( - int inputLen) - { - return inputLen; - } - - protected AlgorithmParameters engineGetParameters() - { - if (engineParams == null) - { - if (pbeSpec != null) - { - try - { - AlgorithmParameters engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, BouncyCastleProvider.PROVIDER_NAME); - engineParams.init(pbeSpec); - - return engineParams; - } - catch (Exception e) - { - return null; - } - } - } - - return engineParams; - } - - /** - * should never be called. - */ - protected void engineSetMode( - String mode) - { - if (!mode.equalsIgnoreCase("ECB")) - { - throw new IllegalArgumentException("can't support mode " + mode); - } - } - - /** - * should never be called. - */ - protected void engineSetPadding( - String padding) - throws NoSuchPaddingException - { - if (!padding.equalsIgnoreCase("NoPadding")) - { - throw new NoSuchPaddingException("Padding " + padding + " unknown."); - } - } - - protected void engineInit( - int opmode, - Key key, - AlgorithmParameterSpec params, - SecureRandom random) - throws InvalidKeyException, InvalidAlgorithmParameterException - { - CipherParameters param; - - this.pbeSpec = null; - this.pbeAlgorithm = null; - - this.engineParams = null; - - // - // basic key check - // - if (!(key instanceof SecretKey)) - { - throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption."); - } - - if (key instanceof BCPBEKey) - { - BCPBEKey k = (BCPBEKey)key; - - if (k.getOID() != null) - { - pbeAlgorithm = k.getOID().getId(); - } - else - { - pbeAlgorithm = k.getAlgorithm(); - } - - if (k.getParam() != null) - { - param = k.getParam(); - pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount()); - } - else if (params instanceof PBEParameterSpec) - { - param = PBE.Util.makePBEParameters(k, params, cipher.getAlgorithmName()); - pbeSpec = (PBEParameterSpec)params; - } - else - { - throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); - } - - if (k.getIvSize() != 0) - { - ivParam = (ParametersWithIV)param; - } - } - else if (params == null) - { - param = new KeyParameter(key.getEncoded()); - } - else if (params instanceof IvParameterSpec) - { - param = new ParametersWithIV(new KeyParameter(key.getEncoded()), ((IvParameterSpec)params).getIV()); - ivParam = (ParametersWithIV)param; - } - else - { - throw new IllegalArgumentException("unknown parameter type."); - } - - if ((ivLength != 0) && !(param instanceof ParametersWithIV)) - { - SecureRandom ivRandom = random; - - if (ivRandom == null) - { - ivRandom = new SecureRandom(); - } - - if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE)) - { - byte[] iv = new byte[ivLength]; - - ivRandom.nextBytes(iv); - param = new ParametersWithIV(param, iv); - ivParam = (ParametersWithIV)param; - } - else - { - throw new InvalidAlgorithmParameterException("no IV set when one expected"); - } - } - - switch (opmode) - { - case Cipher.ENCRYPT_MODE: - case Cipher.WRAP_MODE: - cipher.init(true, param); - break; - case Cipher.DECRYPT_MODE: - case Cipher.UNWRAP_MODE: - cipher.init(false, param); - break; - default: - System.out.println("eeek!"); - } - } - - protected void engineInit( - int opmode, - Key key, - AlgorithmParameters params, - SecureRandom random) - throws InvalidKeyException, InvalidAlgorithmParameterException - { - AlgorithmParameterSpec paramSpec = null; - - if (params != null) - { - for (int i = 0; i != availableSpecs.length; i++) - { - try - { - paramSpec = params.getParameterSpec(availableSpecs[i]); - break; - } - catch (Exception e) - { - continue; - } - } - - if (paramSpec == null) - { - throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString()); - } - } - - engineInit(opmode, key, paramSpec, random); - engineParams = params; - } - - protected void engineInit( - int opmode, - Key key, - SecureRandom random) - throws InvalidKeyException - { - try - { - engineInit(opmode, key, (AlgorithmParameterSpec)null, random); - } - catch (InvalidAlgorithmParameterException e) - { - throw new InvalidKeyException(e.getMessage()); - } - } - - protected byte[] engineUpdate( - byte[] input, - int inputOffset, - int inputLen) - { - byte[] out = new byte[inputLen]; - - cipher.processBytes(input, inputOffset, inputLen, out, 0); - - return out; - } - - protected int engineUpdate( - byte[] input, - int inputOffset, - int inputLen, - byte[] output, - int outputOffset) - throws ShortBufferException - { - try - { - cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); - - return inputLen; - } - catch (DataLengthException e) - { - throw new ShortBufferException(e.getMessage()); - } - } - - protected byte[] engineDoFinal( - byte[] input, - int inputOffset, - int inputLen) - throws BadPaddingException, IllegalBlockSizeException - { - if (inputLen != 0) - { - byte[] out = engineUpdate(input, inputOffset, inputLen); - - cipher.reset(); - - return out; - } - - cipher.reset(); - - return new byte[0]; - } - - protected int engineDoFinal( - byte[] input, - int inputOffset, - int inputLen, - byte[] output, - int outputOffset) - throws BadPaddingException - { - if (inputLen != 0) - { - cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); - } - - cipher.reset(); - - return inputLen; - } - - protected byte[] engineWrap( - Key key) - throws IllegalBlockSizeException, InvalidKeyException - { - byte[] encoded = key.getEncoded(); - if (encoded == null) - { - throw new InvalidKeyException("Cannot wrap key, null encoding."); - } - - try - { - return engineDoFinal(encoded, 0, encoded.length); - } - catch (BadPaddingException e) - { - throw new IllegalBlockSizeException(e.getMessage()); - } - } - - protected Key engineUnwrap( - byte[] wrappedKey, - String wrappedKeyAlgorithm, - int wrappedKeyType) - throws InvalidKeyException - { - byte[] encoded; - try - { - encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); - } - catch (BadPaddingException e) - { - throw new InvalidKeyException(e.getMessage()); - } - catch (IllegalBlockSizeException e2) - { - throw new InvalidKeyException(e2.getMessage()); - } - - if (wrappedKeyType == Cipher.SECRET_KEY) - { - return new SecretKeySpec(encoded, wrappedKeyAlgorithm); - } - else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) - { - /* - * The caller doesn't know the algorithm as it is part of - * the encrypted data. - */ - try - { - PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); - - PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in); - - if (privKey != null) - { - return privKey; - } - else - { - throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported"); - } - } - catch (Exception e) - { - throw new InvalidKeyException("Invalid key encoding."); - } - } - else - { - try - { - KeyFactory kf = KeyFactory.getInstance(wrappedKeyAlgorithm, BouncyCastleProvider.PROVIDER_NAME); - - if (wrappedKeyType == Cipher.PUBLIC_KEY) - { - return kf.generatePublic(new X509EncodedKeySpec(encoded)); - } - else if (wrappedKeyType == Cipher.PRIVATE_KEY) - { - return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); - } - } - catch (NoSuchProviderException e) - { - throw new InvalidKeyException("Unknown key type " + e.getMessage()); - } - catch (NoSuchAlgorithmException e) - { - throw new InvalidKeyException("Unknown key type " + e.getMessage()); - } - catch (InvalidKeySpecException e2) - { - throw new InvalidKeyException("Unknown key type " + e2.getMessage()); - } - - throw new InvalidKeyException("Unknown key type " + wrappedKeyType); - } - } - - /* - * The ciphers that inherit from us. - */ - - // BEGIN android-removed - // /** - // * DES - // */ - // static public class DES_CFB8 - // extends JCEStreamCipher - // { - // public DES_CFB8() - // { - // super(new CFBBlockCipher(new DESEngine(), 8), 64); - // } - // } - // - // /** - // * DESede - // */ - // static public class DESede_CFB8 - // extends JCEStreamCipher - // { - // public DESede_CFB8() - // { - // super(new CFBBlockCipher(new DESedeEngine(), 8), 64); - // } - // } - // - // /** - // * SKIPJACK - // */ - // static public class Skipjack_CFB8 - // extends JCEStreamCipher - // { - // public Skipjack_CFB8() - // { - // super(new CFBBlockCipher(new SkipjackEngine(), 8), 64); - // } - // } - // - // /** - // * Blowfish - // */ - // static public class Blowfish_CFB8 - // extends JCEStreamCipher - // { - // public Blowfish_CFB8() - // { - // super(new CFBBlockCipher(new BlowfishEngine(), 8), 64); - // } - // } - // - // /** - // * Twofish - // */ - // static public class Twofish_CFB8 - // extends JCEStreamCipher - // { - // public Twofish_CFB8() - // { - // super(new CFBBlockCipher(new TwofishEngine(), 8), 128); - // } - // } - // - // /** - // * DES - // */ - // static public class DES_OFB8 - // extends JCEStreamCipher - // { - // public DES_OFB8() - // { - // super(new OFBBlockCipher(new DESEngine(), 8), 64); - // } - // } - // - // /** - // * DESede - // */ - // static public class DESede_OFB8 - // extends JCEStreamCipher - // { - // public DESede_OFB8() - // { - // super(new OFBBlockCipher(new DESedeEngine(), 8), 64); - // } - // } - // - // /** - // * SKIPJACK - // */ - // static public class Skipjack_OFB8 - // extends JCEStreamCipher - // { - // public Skipjack_OFB8() - // { - // super(new OFBBlockCipher(new SkipjackEngine(), 8), 64); - // } - // } - // - // /** - // * Blowfish - // */ - // static public class Blowfish_OFB8 - // extends JCEStreamCipher - // { - // public Blowfish_OFB8() - // { - // super(new OFBBlockCipher(new BlowfishEngine(), 8), 64); - // } - // } - // - // /** - // * Twofish - // */ - // static public class Twofish_OFB8 - // extends JCEStreamCipher - // { - // public Twofish_OFB8() - // { - // super(new OFBBlockCipher(new TwofishEngine(), 8), 128); - // } - // } - // END android-removed -} diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java index ebd2f2a..b53b7aa 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java @@ -2,7 +2,6 @@ package org.bouncycastle.jce.provider; import java.security.cert.CertStore; import java.security.cert.CertStoreException; -import java.security.cert.PKIXParameters; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.Collection; @@ -12,16 +11,14 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import org.bouncycastle.jcajce.PKIXCRLStore; +import org.bouncycastle.jcajce.PKIXCRLStoreSelector; +import org.bouncycastle.util.Store; import org.bouncycastle.util.StoreException; -import org.bouncycastle.x509.ExtendedPKIXParameters; -import org.bouncycastle.x509.X509CRLStoreSelector; -// BEGIN android-removed -// import org.bouncycastle.x509.X509Store; -// END android-removed -public class PKIXCRLUtil +class PKIXCRLUtil { - public Set findCRLs(X509CRLStoreSelector crlselect, ExtendedPKIXParameters paramsPKIX, Date currentDate) + public Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores) throws AnnotatedException { Set initialSet = new HashSet(); @@ -29,9 +26,8 @@ public class PKIXCRLUtil // get complete CRL(s) try { - initialSet.addAll(findCRLs(crlselect, paramsPKIX.getAdditionalStores())); - initialSet.addAll(findCRLs(crlselect, paramsPKIX.getStores())); - initialSet.addAll(findCRLs(crlselect, paramsPKIX.getCertStores())); + initialSet.addAll(findCRLs(crlselect, pkixCrlStores)); + initialSet.addAll(findCRLs(crlselect, certStores)); } catch (AnnotatedException e) { @@ -39,12 +35,6 @@ public class PKIXCRLUtil } Set finalSet = new HashSet(); - Date validityDate = currentDate; - - if (paramsPKIX.getDate() != null) - { - validityDate = paramsPKIX.getDate(); - } // based on RFC 5280 6.3.3 for (Iterator it = initialSet.iterator(); it.hasNext();) @@ -72,38 +62,20 @@ public class PKIXCRLUtil return finalSet; } - public Set findCRLs(X509CRLStoreSelector crlselect, PKIXParameters paramsPKIX) - throws AnnotatedException - { - Set completeSet = new HashSet(); - - // get complete CRL(s) - try - { - completeSet.addAll(findCRLs(crlselect, paramsPKIX.getCertStores())); - } - catch (AnnotatedException e) - { - throw new AnnotatedException("Exception obtaining complete CRLs.", e); - } - - return completeSet; - } - -/** + /** * Return a Collection of all CRLs found in the X509Store's that are * matching the crlSelect criteriums. * - * @param crlSelect a {@link X509CRLStoreSelector} object that will be used + * @param crlSelect a {@link org.bouncycastle.jcajce.PKIXCRLStoreSelector} object that will be used * to select the CRLs * @param crlStores a List containing only - * {@link org.bouncycastle.x509.X509Store X509Store} objects. + * {@link Store} objects. * These are used to search for CRLs * * @return a Collection of all found {@link java.security.cert.X509CRL X509CRL} objects. May be * empty but never <code>null</code>. */ - private final Collection findCRLs(X509CRLStoreSelector crlSelect, + private final Collection findCRLs(PKIXCRLStoreSelector crlSelect, List crlStores) throws AnnotatedException { Set crls = new HashSet(); @@ -117,10 +89,10 @@ public class PKIXCRLUtil Object obj = iter.next(); // BEGIN android-removed - // if (obj instanceof X509Store) + // if (obj instanceof Store) // { - // X509Store store = (X509Store)obj; - // + // Store store = (Store)obj; + // try // { // crls.addAll(store.getMatches(crlSelect)); @@ -139,7 +111,7 @@ public class PKIXCRLUtil try { - crls.addAll(store.getCRLs(crlSelect)); + crls.addAll(PKIXCRLStoreSelector.getCRLs(crlSelect, store)); foundValidStore = true; } catch (CertStoreException e) diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java index 384eb86..b713395 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java @@ -6,8 +6,6 @@ import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathBuilderResult; import java.security.cert.CertPathBuilderSpi; import java.security.cert.CertPathParameters; -import java.security.cert.CertPathValidator; -import java.security.cert.CertificateFactory; import java.security.cert.CertificateParsingException; import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXCertPathBuilderResult; @@ -19,10 +17,15 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.jcajce.PKIXCertStore; +import org.bouncycastle.jcajce.PKIXCertStoreSelector; +import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters; +import org.bouncycastle.jcajce.PKIXExtendedParameters; +import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory; import org.bouncycastle.jce.exception.ExtCertPathBuilderException; -import org.bouncycastle.util.Selector; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; -import org.bouncycastle.x509.X509CertStoreSelector; +import org.bouncycastle.x509.ExtendedPKIXParameters; /** * Implements the PKIX CertPathBuilding algorithm for BouncyCastle. @@ -42,23 +45,45 @@ public class PKIXCertPathBuilderSpi throws CertPathBuilderException, InvalidAlgorithmParameterException { if (!(params instanceof PKIXBuilderParameters) - && !(params instanceof ExtendedPKIXBuilderParameters)) + && !(params instanceof ExtendedPKIXBuilderParameters) + && !(params instanceof PKIXExtendedBuilderParameters)) { throw new InvalidAlgorithmParameterException( "Parameters must be an instance of " + PKIXBuilderParameters.class.getName() + " or " - + ExtendedPKIXBuilderParameters.class.getName() + "."); + + PKIXExtendedBuilderParameters.class.getName() + "."); } - ExtendedPKIXBuilderParameters pkixParams = null; - if (params instanceof ExtendedPKIXBuilderParameters) + PKIXExtendedBuilderParameters paramsPKIX; + if (params instanceof PKIXBuilderParameters) { - pkixParams = (ExtendedPKIXBuilderParameters) params; + PKIXExtendedParameters.Builder paramsPKIXBldr = new PKIXExtendedParameters.Builder((PKIXBuilderParameters)params); + PKIXExtendedBuilderParameters.Builder paramsBldrPKIXBldr; + + if (params instanceof ExtendedPKIXParameters) + { + ExtendedPKIXBuilderParameters extPKIX = (ExtendedPKIXBuilderParameters)params; + + ; + for (Iterator it = extPKIX.getAdditionalStores().iterator(); it.hasNext();) + { + paramsPKIXBldr.addCertificateStore((PKIXCertStore)it.next()); + } + paramsBldrPKIXBldr = new PKIXExtendedBuilderParameters.Builder(paramsPKIXBldr.build()); + + paramsBldrPKIXBldr.addExcludedCerts(extPKIX.getExcludedCerts()); + paramsBldrPKIXBldr.setMaxPathLength(extPKIX.getMaxPathLength()); + } + else + { + paramsBldrPKIXBldr = new PKIXExtendedBuilderParameters.Builder((PKIXBuilderParameters)params); + } + + paramsPKIX = paramsBldrPKIXBldr.build(); } else { - pkixParams = (ExtendedPKIXBuilderParameters) ExtendedPKIXBuilderParameters - .getInstance((PKIXBuilderParameters) params); + paramsPKIX = (PKIXExtendedBuilderParameters)params; } Collection targets; @@ -68,19 +93,12 @@ public class PKIXCertPathBuilderSpi // search target certificates - Selector certSelect = pkixParams.getTargetConstraints(); - if (!(certSelect instanceof X509CertStoreSelector)) - { - throw new CertPathBuilderException( - "TargetConstraints must be an instance of " - + X509CertStoreSelector.class.getName() + " for " - + this.getClass().getName() + " class."); - } + PKIXCertStoreSelector certSelect = paramsPKIX.getBaseParameters().getTargetConstraints(); try { - targets = CertPathValidatorUtilities.findCertificates((X509CertStoreSelector)certSelect, pkixParams.getStores()); - targets.addAll(CertPathValidatorUtilities.findCertificates((X509CertStoreSelector)certSelect, pkixParams.getCertStores())); + targets = CertPathValidatorUtilities.findCertificates(certSelect, paramsPKIX.getBaseParameters().getCertificateStores()); + targets.addAll(CertPathValidatorUtilities.findCertificates(certSelect, paramsPKIX.getBaseParameters().getCertStores())); } catch (AnnotatedException e) { @@ -102,7 +120,7 @@ public class PKIXCertPathBuilderSpi while (targetIter.hasNext() && result == null) { cert = (X509Certificate) targetIter.next(); - result = build(cert, pkixParams, certPathList); + result = build(cert, paramsPKIX, certPathList); } if (result == null && certPathException != null) @@ -128,7 +146,7 @@ public class PKIXCertPathBuilderSpi private Exception certPathException; protected CertPathBuilderResult build(X509Certificate tbvCert, - ExtendedPKIXBuilderParameters pkixParams, List tbvPath) + PKIXExtendedBuilderParameters pkixParams, List tbvPath) { // If tbvCert is readily present in tbvPath, it indicates having run // into a cycle in the @@ -155,13 +173,13 @@ public class PKIXCertPathBuilderSpi tbvPath.add(tbvCert); CertificateFactory cFact; - CertPathValidator validator; + PKIXCertPathValidatorSpi validator; CertPathBuilderResult builderResult = null; try { - cFact = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); - validator = CertPathValidator.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); + cFact = new CertificateFactory(); + validator = new PKIXCertPathValidatorSpi(); } catch (Exception e) { @@ -172,8 +190,8 @@ public class PKIXCertPathBuilderSpi try { // check whether the issuer of <tbvCert> is a TrustAnchor - if (CertPathValidatorUtilities.findTrustAnchor(tbvCert, pkixParams.getTrustAnchors(), - pkixParams.getSigProvider()) != null) + if (CertPathValidatorUtilities.findTrustAnchor(tbvCert, pkixParams.getBaseParameters().getTrustAnchors(), + pkixParams.getBaseParameters().getSigProvider()) != null) { // exception message from possibly later tried certification // chains @@ -181,7 +199,7 @@ public class PKIXCertPathBuilderSpi PKIXCertPathValidatorResult result = null; try { - certPath = cFact.generateCertPath(tbvPath); + certPath = cFact.engineGenerateCertPath(tbvPath); } catch (Exception e) { @@ -192,7 +210,7 @@ public class PKIXCertPathBuilderSpi try { - result = (PKIXCertPathValidatorResult) validator.validate( + result = (PKIXCertPathValidatorResult) validator.engineValidate( certPath, pkixParams); } catch (Exception e) @@ -208,16 +226,21 @@ public class PKIXCertPathBuilderSpi } else { + List stores = new ArrayList(); + + + stores.addAll(pkixParams.getBaseParameters().getCertificateStores()); + // add additional X.509 stores from locations in certificate try { - CertPathValidatorUtilities.addAdditionalStoresFromAltNames( - tbvCert, pkixParams); + stores.addAll(CertPathValidatorUtilities.getAdditionalStoresFromAltNames( + tbvCert.getExtensionValue(Extension.issuerAlternativeName.getId()), pkixParams.getBaseParameters().getNamedCertificateStoreMap())); } catch (CertificateParsingException e) { throw new AnnotatedException( - "No additiontal X.509 stores can be added from certificate locations.", + "No additional X.509 stores can be added from certificate locations.", e); } Collection issuers = new HashSet(); @@ -225,7 +248,7 @@ public class PKIXCertPathBuilderSpi // of the stores try { - issuers.addAll(CertPathValidatorUtilities.findIssuerCerts(tbvCert, pkixParams)); + issuers.addAll(CertPathValidatorUtilities.findIssuerCerts(tbvCert, pkixParams.getBaseParameters().getCertStores(), stores)); } catch (AnnotatedException e) { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java index 19dc768..d902812 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java @@ -21,11 +21,14 @@ import java.util.Iterator; import java.util.List; import java.util.Set; -import javax.security.auth.x500.X500Principal; - import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters; +import org.bouncycastle.jcajce.PKIXExtendedParameters; +import org.bouncycastle.jcajce.util.BCJcaJceHelper; +import org.bouncycastle.jcajce.util.JcaJceHelper; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.x509.ExtendedPKIXParameters; @@ -36,6 +39,11 @@ import org.bouncycastle.x509.ExtendedPKIXParameters; public class PKIXCertPathValidatorSpi extends CertPathValidatorSpi { + private final JcaJceHelper helper = new BCJcaJceHelper(); + + public PKIXCertPathValidatorSpi() + { + } // BEGIN android-added private static class NoPreloadHolder { private final static CertBlacklist blacklist = new CertBlacklist(); @@ -48,21 +56,36 @@ public class PKIXCertPathValidatorSpi throws CertPathValidatorException, InvalidAlgorithmParameterException { - if (!(params instanceof PKIXParameters)) + if (!(params instanceof CertPathParameters)) { throw new InvalidAlgorithmParameterException("Parameters must be a " + PKIXParameters.class.getName() + " instance."); } - ExtendedPKIXParameters paramsPKIX; - if (params instanceof ExtendedPKIXParameters) + PKIXExtendedParameters paramsPKIX; + if (params instanceof PKIXParameters) { - paramsPKIX = (ExtendedPKIXParameters)params; + PKIXExtendedParameters.Builder paramsPKIXBldr = new PKIXExtendedParameters.Builder((PKIXParameters)params); + + if (params instanceof ExtendedPKIXParameters) + { + ExtendedPKIXParameters extPKIX = (ExtendedPKIXParameters)params; + + paramsPKIXBldr.setUseDeltasEnabled(extPKIX.isUseDeltasEnabled()); + paramsPKIXBldr.setValidityModel(extPKIX.getValidityModel()); + } + + paramsPKIX = paramsPKIXBldr.build(); + } + else if (params instanceof PKIXExtendedBuilderParameters) + { + paramsPKIX = ((PKIXExtendedBuilderParameters)params).getBaseParameters(); } else { - paramsPKIX = ExtendedPKIXParameters.getInstance((PKIXParameters)params); + paramsPKIX = (PKIXExtendedParameters)params; } + if (paramsPKIX.getTrustAnchors() == null) { throw new InvalidAlgorithmParameterException( @@ -129,6 +152,9 @@ public class PKIXCertPathValidatorSpi throw new CertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1); } + // RFC 5280 - CRLs must originate from the same trust anchor as the target certificate. + paramsPKIX = new PKIXExtendedParameters.Builder(paramsPKIX).setTrustAnchor(trust).build(); + // // (e), (f), (g) are part of the paramsPKIX object. // @@ -210,19 +236,19 @@ public class PKIXCertPathValidatorSpi // (g), (h), (i), (j) // PublicKey workingPublicKey; - X500Principal workingIssuerName; + X500Name workingIssuerName; X509Certificate sign = trust.getTrustedCert(); try { if (sign != null) { - workingIssuerName = CertPathValidatorUtilities.getSubjectPrincipal(sign); + workingIssuerName = PrincipalUtils.getSubjectPrincipal(sign); workingPublicKey = sign.getPublicKey(); } else { - workingIssuerName = new X500Principal(trust.getCAName()); + workingIssuerName = PrincipalUtils.getCA(trust); workingPublicKey = trust.getCAPublicKey(); } } @@ -305,7 +331,7 @@ public class PKIXCertPathValidatorSpi // RFC3280CertPathUtilities.processCertA(certPath, paramsPKIX, index, workingPublicKey, - verificationAlreadyPerformed, workingIssuerName, sign); + verificationAlreadyPerformed, workingIssuerName, sign, helper); RFC3280CertPathUtilities.processCertBC(certPath, index, nameConstraintValidator); @@ -390,12 +416,12 @@ public class PKIXCertPathValidatorSpi sign = cert; // (c) - workingIssuerName = CertPathValidatorUtilities.getSubjectPrincipal(sign); + workingIssuerName = PrincipalUtils.getSubjectPrincipal(sign); // (d) try { - workingPublicKey = CertPathValidatorUtilities.getNextWorkingKey(certPath.getCertificates(), index); + workingPublicKey = CertPathValidatorUtilities.getNextWorkingKey(certPath.getCertificates(), index, helper); } catch (CertPathValidatorException e) { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java index 7ecc486..0742712 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java @@ -635,13 +635,17 @@ public class PKIXNameConstraintValidator private boolean emailIsConstrained(String email, String constraint) { String sub = email.substring(email.indexOf('@') + 1); - // a particular mailbox + // a particular mailbox or @domain if (constraint.indexOf('@') != -1) { if (email.equalsIgnoreCase(constraint)) { return true; } + if (sub.equalsIgnoreCase(constraint.substring(1))) + { + return true; + } } // on particular host else if (!(constraint.charAt(0) == '.')) diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXPolicyNode.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXPolicyNode.java index 3437605..d89e920 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXPolicyNode.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXPolicyNode.java @@ -165,4 +165,9 @@ public class PKIXPolicyNode return _node; } + + public void setExpectedPolicies(Set expectedPolicies) + { + this.expectedPolicies = expectedPolicies; + } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PrincipalUtils.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PrincipalUtils.java new file mode 100644 index 0000000..9059079 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PrincipalUtils.java @@ -0,0 +1,53 @@ +package org.bouncycastle.jce.provider; + +import java.security.cert.TrustAnchor; +import java.security.cert.X509CRL; +import java.security.cert.X509CRLEntry; +import java.security.cert.X509Certificate; + +import javax.security.auth.x500.X500Principal; + +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.x509.X509AttributeCertificate; + +class PrincipalUtils +{ + static X500Name getSubjectPrincipal(X509Certificate cert) + { + return X500Name.getInstance(cert.getSubjectX500Principal().getEncoded()); + } + + static X500Name getIssuerPrincipal(X509CRL crl) + { + return X500Name.getInstance(crl.getIssuerX500Principal().getEncoded()); + } + + static X500Name getIssuerPrincipal(X509Certificate cert) + { + return X500Name.getInstance(cert.getIssuerX500Principal().getEncoded()); + } + + static X500Name getCA(TrustAnchor trustAnchor) + { + return X500Name.getInstance(trustAnchor.getCA().getEncoded()); + } + + /** + * Returns the issuer of an attribute certificate or certificate. + * + * @param cert The attribute certificate or certificate. + * @return The issuer as <code>X500Principal</code>. + */ + static X500Name getEncodedIssuerPrincipal( + Object cert) + { + if (cert instanceof X509Certificate) + { + return getIssuerPrincipal((X509Certificate)cert); + } + else + { + return X500Name.getInstance(((X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]).getEncoded()); + } + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java index 881ceeb..d67a77e 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java @@ -5,13 +5,14 @@ import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.PublicKey; import java.security.cert.CertPath; -import java.security.cert.CertPathBuilder; import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathValidatorException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.PKIXCertPathChecker; import java.security.cert.X509CRL; +import java.security.cert.X509CRLSelector; +import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.security.cert.X509Extension; import java.text.SimpleDateFormat; @@ -26,9 +27,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; -import java.util.Vector; - -import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; @@ -37,36 +35,42 @@ import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.x500.RDN; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; +import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.NameConstraints; import org.bouncycastle.asn1.x509.PolicyInformation; -import org.bouncycastle.asn1.x509.X509Extensions; -import org.bouncycastle.asn1.x509.X509Name; +import org.bouncycastle.jcajce.PKIXCRLStore; +import org.bouncycastle.jcajce.PKIXCRLStoreSelector; +import org.bouncycastle.jcajce.PKIXCertStoreSelector; +import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters; +import org.bouncycastle.jcajce.PKIXExtendedParameters; +import org.bouncycastle.jcajce.util.JcaJceHelper; +import org.bouncycastle.jce.PrincipalUtil; import org.bouncycastle.jce.exception.ExtCertPathValidatorException; import org.bouncycastle.util.Arrays; -import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; -import org.bouncycastle.x509.ExtendedPKIXParameters; -import org.bouncycastle.x509.X509CRLStoreSelector; -import org.bouncycastle.x509.X509CertStoreSelector; -public class RFC3280CertPathUtilities +class RFC3280CertPathUtilities { private static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil(); /** * If the complete CRL includes an issuing distribution point (IDP) CRL * extension check the following: - * <p/> + * <p> * (i) If the distribution point name is present in the IDP CRL extension * and the distribution field is present in the DP, then verify that one of * the names in the IDP matches one of the names in the DP. If the @@ -75,17 +79,17 @@ public class RFC3280CertPathUtilities * names in the IDP matches one of the names in the cRLIssuer field of the * DP. * </p> - * <p/> + * <p> * (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL * extension, verify that the certificate does not include the basic * constraints extension with the cA boolean asserted. * </p> - * <p/> + * <p> * (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL * extension, verify that the certificate includes the basic constraints * extension with the cA boolean asserted. * </p> - * <p/> + * <p> * (iv) Verify that the onlyContainsAttributeCerts boolean is not asserted. * </p> * @@ -133,20 +137,18 @@ public class RFC3280CertPathUtilities ASN1EncodableVector vec = new ASN1EncodableVector(); try { - Enumeration e = ASN1Sequence.getInstance( - ASN1Sequence.fromByteArray(CertPathValidatorUtilities.getIssuerPrincipal(crl) - .getEncoded())).getObjects(); + Enumeration e = ASN1Sequence.getInstance(PrincipalUtils.getIssuerPrincipal(crl)).getObjects(); while (e.hasMoreElements()) { vec.add((ASN1Encodable)e.nextElement()); } } - catch (IOException e) + catch (Exception e) { throw new AnnotatedException("Could not read CRL issuer.", e); } vec.add(dpName.getName()); - names.add(new GeneralName(X509Name.getInstance(new DERSequence(vec)))); + names.add(new GeneralName(X500Name.getInstance(new DERSequence(vec)))); } boolean matches = false; // verify that one of the names in the IDP matches one @@ -170,11 +172,10 @@ public class RFC3280CertPathUtilities genNames = new GeneralName[1]; try { - genNames[0] = new GeneralName(new X509Name( - (ASN1Sequence)ASN1Sequence.fromByteArray(CertPathValidatorUtilities - .getEncodedIssuerPrincipal(cert).getEncoded()))); + genNames[0] = new GeneralName(X500Name.getInstance(PrincipalUtils + .getEncodedIssuerPrincipal(cert).getEncoded())); } - catch (IOException e) + catch (Exception e) { throw new AnnotatedException("Could not read certificate issuer.", e); } @@ -188,7 +189,7 @@ public class RFC3280CertPathUtilities vec.add((ASN1Encodable)e.nextElement()); } vec.add(dpName.getName()); - genNames[j] = new GeneralName(new X509Name(new DERSequence(vec))); + genNames[j] = new GeneralName(X500Name.getInstance(new DERSequence(vec))); } } if (genNames != null) @@ -296,7 +297,16 @@ public class RFC3280CertPathUtilities isIndirect = true; } } - byte[] issuerBytes = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded(); + byte[] issuerBytes; + + try + { + issuerBytes = PrincipalUtils.getIssuerPrincipal(crl).getEncoded(); + } + catch (IOException e) + { + throw new AnnotatedException("Exception encoding CRL issuer: " + e.getMessage(), e); + } boolean matchIssuer = false; if (dp.getCRLIssuer() != null) @@ -331,8 +341,8 @@ public class RFC3280CertPathUtilities } else { - if (CertPathValidatorUtilities.getIssuerPrincipal(crl).equals( - CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert))) + if (PrincipalUtils.getIssuerPrincipal(crl).equals( + PrincipalUtils.getEncodedIssuerPrincipal(cert))) { matchIssuer = true; } @@ -377,33 +387,33 @@ public class RFC3280CertPathUtilities } - public static final String CERTIFICATE_POLICIES = X509Extensions.CertificatePolicies.getId(); + public static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId(); - public static final String POLICY_MAPPINGS = X509Extensions.PolicyMappings.getId(); + public static final String POLICY_MAPPINGS = Extension.policyMappings.getId(); - public static final String INHIBIT_ANY_POLICY = X509Extensions.InhibitAnyPolicy.getId(); + public static final String INHIBIT_ANY_POLICY = Extension.inhibitAnyPolicy.getId(); - public static final String ISSUING_DISTRIBUTION_POINT = X509Extensions.IssuingDistributionPoint.getId(); + public static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId(); - public static final String FRESHEST_CRL = X509Extensions.FreshestCRL.getId(); + public static final String FRESHEST_CRL = Extension.freshestCRL.getId(); - public static final String DELTA_CRL_INDICATOR = X509Extensions.DeltaCRLIndicator.getId(); + public static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId(); - public static final String POLICY_CONSTRAINTS = X509Extensions.PolicyConstraints.getId(); + public static final String POLICY_CONSTRAINTS = Extension.policyConstraints.getId(); - public static final String BASIC_CONSTRAINTS = X509Extensions.BasicConstraints.getId(); + public static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId(); - public static final String CRL_DISTRIBUTION_POINTS = X509Extensions.CRLDistributionPoints.getId(); + public static final String CRL_DISTRIBUTION_POINTS = Extension.cRLDistributionPoints.getId(); - public static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName.getId(); + public static final String SUBJECT_ALTERNATIVE_NAME = Extension.subjectAlternativeName.getId(); - public static final String NAME_CONSTRAINTS = X509Extensions.NameConstraints.getId(); + public static final String NAME_CONSTRAINTS = Extension.nameConstraints.getId(); - public static final String AUTHORITY_KEY_IDENTIFIER = X509Extensions.AuthorityKeyIdentifier.getId(); + public static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId(); - public static final String KEY_USAGE = X509Extensions.KeyUsage.getId(); + public static final String KEY_USAGE = Extension.keyUsage.getId(); - public static final String CRL_NUMBER = X509Extensions.CRLNumber.getId(); + public static final String CRL_NUMBER = Extension.cRLNumber.getId(); public static final String ANY_POLICY = "2.5.29.32.0"; @@ -438,18 +448,19 @@ public class RFC3280CertPathUtilities Object cert, X509Certificate defaultCRLSignCert, PublicKey defaultCRLSignKey, - ExtendedPKIXParameters paramsPKIX, - List certPathCerts) + PKIXExtendedParameters paramsPKIX, + List certPathCerts, + JcaJceHelper helper) throws AnnotatedException { // (f) // get issuer from CRL - X509CertStoreSelector selector = new X509CertStoreSelector(); + X509CertSelector certSelector = new X509CertSelector(); try { - byte[] issuerPrincipal = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded(); - selector.setSubject(issuerPrincipal); + byte[] issuerPrincipal = PrincipalUtils.getIssuerPrincipal(crl).getEncoded(); + certSelector.setSubject(issuerPrincipal); } catch (IOException e) { @@ -457,12 +468,13 @@ public class RFC3280CertPathUtilities "Subject criteria for certificate selector to find issuer certificate for CRL could not be set.", e); } + PKIXCertStoreSelector selector = new PKIXCertStoreSelector.Builder(certSelector).build(); + // get CRL signing certs Collection coll; try { - coll = CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getStores()); - coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getAdditionalStores())); + coll = CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertificateStores()); coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertStores())); } catch (AnnotatedException e) @@ -493,13 +505,13 @@ public class RFC3280CertPathUtilities } try { - CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); - selector = new X509CertStoreSelector(); - selector.setCertificate(signingCert); - ExtendedPKIXParameters temp = (ExtendedPKIXParameters)paramsPKIX.clone(); - temp.setTargetCertConstraints(selector); - ExtendedPKIXBuilderParameters params = (ExtendedPKIXBuilderParameters)ExtendedPKIXBuilderParameters - .getInstance(temp); + PKIXCertPathBuilderSpi builder = new PKIXCertPathBuilderSpi(); + X509CertSelector tmpCertSelector = new X509CertSelector(); + tmpCertSelector.setCertificate(signingCert); + + PKIXExtendedParameters.Builder paramsBuilder = new PKIXExtendedParameters.Builder(paramsPKIX) + .setTargetConstraints(new PKIXCertStoreSelector.Builder(tmpCertSelector).build()); + /* * if signingCert is placed not higher on the cert path a * dependency loop results. CRL for cert is checked, but @@ -511,19 +523,22 @@ public class RFC3280CertPathUtilities */ if (certPathCerts.contains(signingCert)) { - params.setRevocationEnabled(false); + paramsBuilder.setRevocationEnabled(false); } else { - params.setRevocationEnabled(true); + paramsBuilder.setRevocationEnabled(true); } - List certs = builder.build(params).getCertPath().getCertificates(); + + PKIXExtendedBuilderParameters extParams = new PKIXExtendedBuilderParameters.Builder(paramsBuilder.build()).build(); + + List certs = builder.engineBuild(extParams).getCertPath().getCertificates(); validCerts.add(signingCert); - validKeys.add(CertPathValidatorUtilities.getNextWorkingKey(certs, 0)); + validKeys.add(CertPathValidatorUtilities.getNextWorkingKey(certs, 0, helper)); } catch (CertPathBuilderException e) { - throw new AnnotatedException("Internal error.", e); + throw new AnnotatedException("CertPath for CRL signer failed to validate.", e); } catch (CertPathValidatorException e) { @@ -531,7 +546,7 @@ public class RFC3280CertPathUtilities } catch (Exception e) { - throw new RuntimeException(e.getMessage()); + throw new AnnotatedException(e.getMessage()); } } @@ -618,7 +633,7 @@ public class RFC3280CertPathUtilities protected static Set processCRLA1i( Date currentDate, - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, X509Certificate cert, X509CRL crl) throws AnnotatedException @@ -650,19 +665,24 @@ public class RFC3280CertPathUtilities } if (freshestCRL != null) { + List crlStores = new ArrayList(); + + crlStores.addAll(paramsPKIX.getCRLStores()); + try { - CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(freshestCRL, paramsPKIX); + crlStores.addAll(CertPathValidatorUtilities.getAdditionalStoresFromCRLDistributionPoint(freshestCRL, paramsPKIX.getNamedCRLStoreMap())); } catch (AnnotatedException e) { throw new AnnotatedException( "No new delta CRL locations could be added from Freshest CRL extension.", e); } + // get delta CRL(s) try { - set.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl)); + set.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, crl, paramsPKIX.getCertStores(), crlStores)); } catch (AnnotatedException e) { @@ -675,33 +695,41 @@ public class RFC3280CertPathUtilities protected static Set[] processCRLA1ii( Date currentDate, - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, X509Certificate cert, X509CRL crl) throws AnnotatedException { Set deltaSet = new HashSet(); - X509CRLStoreSelector crlselect = new X509CRLStoreSelector(); + X509CRLSelector crlselect = new X509CRLSelector(); crlselect.setCertificateChecking(cert); try { - crlselect.addIssuerName(crl.getIssuerX500Principal().getEncoded()); + crlselect.addIssuerName(PrincipalUtils.getIssuerPrincipal(crl).getEncoded()); } catch (IOException e) { throw new AnnotatedException("Cannot extract issuer from CRL." + e, e); } - crlselect.setCompleteCRLEnabled(true); - Set completeSet = CRL_UTIL.findCRLs(crlselect, paramsPKIX, currentDate); + PKIXCRLStoreSelector extSelect = new PKIXCRLStoreSelector.Builder(crlselect).setCompleteCRLEnabled(true).build(); + + Date validityDate = currentDate; + + if (paramsPKIX.getDate() != null) + { + validityDate = paramsPKIX.getDate(); + } + + Set completeSet = CRL_UTIL.findCRLs(extSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores()); if (paramsPKIX.isUseDeltasEnabled()) { // get delta CRL(s) try { - deltaSet.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl)); + deltaSet.addAll(CertPathValidatorUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores())); } catch (AnnotatedException e) { @@ -727,7 +755,7 @@ public class RFC3280CertPathUtilities protected static void processCRLC( X509CRL deltaCRL, X509CRL completeCRL, - ExtendedPKIXParameters pkixParams) + PKIXExtendedParameters pkixParams) throws AnnotatedException { if (deltaCRL == null) @@ -748,7 +776,7 @@ public class RFC3280CertPathUtilities if (pkixParams.isUseDeltasEnabled()) { // (c) (1) - if (!deltaCRL.getIssuerX500Principal().equals(completeCRL.getIssuerX500Principal())) + if (!PrincipalUtils.getIssuerPrincipal(deltaCRL).equals(PrincipalUtils.getIssuerPrincipal(completeCRL))) { throw new AnnotatedException("Complete CRL issuer does not match delta CRL issuer."); } @@ -835,7 +863,7 @@ public class RFC3280CertPathUtilities X509CRL deltacrl, Object cert, CertStatus certStatus, - ExtendedPKIXParameters pkixParams) + PKIXExtendedParameters pkixParams) throws AnnotatedException { if (pkixParams.isUseDeltasEnabled() && deltacrl != null) @@ -1164,13 +1192,12 @@ public class RFC3280CertPathUtilities // if (!(CertPathValidatorUtilities.isSelfIssued(cert) && (i < n))) { - X500Principal principal = CertPathValidatorUtilities.getSubjectPrincipal(cert); - ASN1InputStream aIn = new ASN1InputStream(principal.getEncoded()); + X500Name principal = PrincipalUtils.getSubjectPrincipal(cert); ASN1Sequence dns; try { - dns = DERSequence.getInstance(aIn.readObject()); + dns = DERSequence.getInstance(principal.getEncoded()); } catch (Exception e) { @@ -1200,10 +1227,11 @@ public class RFC3280CertPathUtilities throw new CertPathValidatorException("Subject alternative name extension could not be decoded.", e, certPath, index); } - Vector emails = new X509Name(dns).getValues(X509Name.EmailAddress); - for (Enumeration e = emails.elements(); e.hasMoreElements();) + RDN[] emails = X500Name.getInstance(dns).getRDNs(BCStyle.EmailAddress); + for (int eI = 0; eI != emails.length; eI++) { - String email = (String)e.nextElement(); + // TODO: this should take into account multi-valued RDNs + String email = ((ASN1String)emails[eI].getFirst().getValue()).getString(); GeneralName emailAsGeneralName = new GeneralName(GeneralName.rfc822Name, email); try { @@ -1450,12 +1478,13 @@ public class RFC3280CertPathUtilities protected static void processCertA( CertPath certPath, - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, int index, PublicKey workingPublicKey, boolean verificationAlreadyPerformed, - X500Principal workingIssuerName, - X509Certificate sign) + X500Name workingIssuerName, + X509Certificate sign, + JcaJceHelper helper) throws ExtCertPathValidatorException { List certs = certPath.getCertificates(); @@ -1506,7 +1535,7 @@ public class RFC3280CertPathUtilities try { checkCRLs(paramsPKIX, cert, CertPathValidatorUtilities.getValidCertDateFromValidityModel(paramsPKIX, - certPath, index), sign, workingPublicKey, certs); + certPath, index), sign, workingPublicKey, certs, helper); } catch (AnnotatedException e) { @@ -1522,9 +1551,9 @@ public class RFC3280CertPathUtilities // // (a) (4) name chaining // - if (!CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).equals(workingIssuerName)) + if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(workingIssuerName)) { - throw new ExtCertPathValidatorException("IssuerName(" + CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert) + throw new ExtCertPathValidatorException("IssuerName(" + PrincipalUtils.getEncodedIssuerPrincipal(cert) + ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null, certPath, index); } @@ -1725,14 +1754,15 @@ public class RFC3280CertPathUtilities */ private static void checkCRL( DistributionPoint dp, - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, X509Certificate cert, Date validDate, X509Certificate defaultCRLSignCert, PublicKey defaultCRLSignKey, CertStatus certStatus, ReasonsMask reasonMask, - List certPathCerts) + List certPathCerts, + JcaJceHelper helper) throws AnnotatedException { Date currentDate = new Date(System.currentTimeMillis()); @@ -1776,16 +1806,23 @@ public class RFC3280CertPathUtilities // (f) Set keys = RFC3280CertPathUtilities.processCRLF(crl, cert, defaultCRLSignCert, defaultCRLSignKey, - paramsPKIX, certPathCerts); + paramsPKIX, certPathCerts, helper); // (g) PublicKey key = RFC3280CertPathUtilities.processCRLG(crl, keys); X509CRL deltaCRL = null; + Date validityDate = currentDate; + + if (paramsPKIX.getDate() != null) + { + validityDate = paramsPKIX.getDate(); + } + if (paramsPKIX.isUseDeltasEnabled()) { // get delta CRLs - Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl); + Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores()); // we only want one valid delta CRL // (h) deltaCRL = RFC3280CertPathUtilities.processCRLH(deltaCRLs, key); @@ -1804,7 +1841,7 @@ public class RFC3280CertPathUtilities * the CRL validity time */ - if (paramsPKIX.getValidityModel() != ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL) + if (paramsPKIX.getValidityModel() != PKIXExtendedParameters.CHAIN_VALIDITY_MODEL) { /* * if a certificate has expired, but was revoked, it is not @@ -1844,8 +1881,8 @@ public class RFC3280CertPathUtilities if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); - criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId()); - criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId()); + criticalExtensions.remove(Extension.issuingDistributionPoint.getId()); + criticalExtensions.remove(Extension.deltaCRLIndicator.getId()); if (!criticalExtensions.isEmpty()) { @@ -1859,8 +1896,8 @@ public class RFC3280CertPathUtilities if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); - criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId()); - criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId()); + criticalExtensions.remove(Extension.issuingDistributionPoint.getId()); + criticalExtensions.remove(Extension.deltaCRLIndicator.getId()); if (!criticalExtensions.isEmpty()) { throw new AnnotatedException("Delta CRL contains unsupported critical extension."); @@ -1895,12 +1932,13 @@ public class RFC3280CertPathUtilities * or some error occurs. */ protected static void checkCRLs( - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, X509Certificate cert, Date validDate, X509Certificate sign, PublicKey workingPublicKey, - List certPathCerts) + List certPathCerts, + JcaJceHelper helper) throws AnnotatedException { AnnotatedException lastException = null; @@ -1914,9 +1952,15 @@ public class RFC3280CertPathUtilities { throw new AnnotatedException("CRL distribution point extension could not be read.", e); } + + PKIXExtendedParameters.Builder paramsBldr = new PKIXExtendedParameters.Builder(paramsPKIX); try { - CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(crldp, paramsPKIX); + List extras = CertPathValidatorUtilities.getAdditionalStoresFromCRLDistributionPoint(crldp, paramsPKIX.getNamedCRLStoreMap()); + for (Iterator it = extras.iterator(); it.hasNext();) + { + paramsBldr.addCRLStore((PKIXCRLStore)it.next()); + } } catch (AnnotatedException e) { @@ -1925,6 +1969,7 @@ public class RFC3280CertPathUtilities } CertStatus certStatus = new CertStatus(); ReasonsMask reasonsMask = new ReasonsMask(); + PKIXExtendedParameters finalParams = paramsBldr.build(); boolean validCrlFound = false; // for each distribution point @@ -1943,10 +1988,9 @@ public class RFC3280CertPathUtilities { for (int i = 0; i < dps.length && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons(); i++) { - ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone(); try { - checkCRL(dps[i], paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts); + checkCRL(dps[i], finalParams, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts, helper); validCrlFound = true; } catch (AnnotatedException e) @@ -1975,7 +2019,7 @@ public class RFC3280CertPathUtilities ASN1Primitive issuer = null; try { - issuer = new ASN1InputStream(CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).getEncoded()) + issuer = new ASN1InputStream(PrincipalUtils.getEncodedIssuerPrincipal(cert).getEncoded()) .readObject(); } catch (Exception e) @@ -1984,9 +2028,9 @@ public class RFC3280CertPathUtilities } DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames( new GeneralName(GeneralName.directoryName, issuer))), null, null); - ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone(); + PKIXExtendedParameters paramsPKIXClone = (PKIXExtendedParameters)paramsPKIX.clone(); checkCRL(dp, paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, - certPathCerts); + certPathCerts, helper); validCrlFound = true; } catch (AnnotatedException e) @@ -2391,7 +2435,7 @@ public class RFC3280CertPathUtilities protected static PKIXPolicyNode wrapupCertG( CertPath certPath, - ExtendedPKIXParameters paramsPKIX, + PKIXExtendedParameters paramsPKIX, Set userInitialPolicySet, int index, List[] policyNodes, diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java index b5b4f13..c9ee77c 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java @@ -62,7 +62,7 @@ public class X509CRLObject private boolean isHashCodeSet = false; private int hashCodeValue; - static boolean isIndirectCRL(X509CRL crl) + public static boolean isIndirectCRL(X509CRL crl) throws CRLException { try diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java index 3b334d2..7165bab 100644 --- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java +++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java @@ -124,6 +124,11 @@ public class ECAlgorithms public static void montgomeryTrick(ECFieldElement[] zs, int off, int len) { + montgomeryTrick(zs, off, len, null); + } + + public static void montgomeryTrick(ECFieldElement[] zs, int off, int len, ECFieldElement scale) + { /* * Uses the "Montgomery Trick" to invert many field elements, with only a single actual * field inversion. See e.g. the paper: @@ -140,7 +145,14 @@ public class ECAlgorithms c[i] = c[i - 1].multiply(zs[off + i]); } - ECFieldElement u = c[--i].invert(); + --i; + + if (scale != null) + { + c[i] = c[i].multiply(scale); + } + + ECFieldElement u = c[i].invert(); while (i > 0) { diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java index 4c658f2..0dc6853 100644 --- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java +++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java @@ -229,26 +229,57 @@ public abstract class ECCurve */ public void normalizeAll(ECPoint[] points) { - checkPoints(points); + normalizeAll(points, 0, points.length, null); + } - if (this.getCoordinateSystem() == ECCurve.COORD_AFFINE) + /** + * Normalization ensures that any projective coordinate is 1, and therefore that the x, y + * coordinates reflect those of the equivalent point in an affine coordinate system. Where more + * than one point is to be normalized, this method will generally be more efficient than + * normalizing each point separately. An (optional) z-scaling factor can be applied; effectively + * each z coordinate is scaled by this value prior to normalization (but only one + * actual multiplication is needed). + * + * @param points + * An array of points that will be updated in place with their normalized versions, + * where necessary + * @param off + * The start of the range of points to normalize + * @param len + * The length of the range of points to normalize + * @param iso + * The (optional) z-scaling factor - can be null + */ + public void normalizeAll(ECPoint[] points, int off, int len, ECFieldElement iso) + { + checkPoints(points, off, len); + + switch (this.getCoordinateSystem()) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: { + if (iso != null) + { + throw new IllegalArgumentException("'iso' not valid for affine coordinates"); + } return; } + } /* * Figure out which of the points actually need to be normalized */ - ECFieldElement[] zs = new ECFieldElement[points.length]; - int[] indices = new int[points.length]; + ECFieldElement[] zs = new ECFieldElement[len]; + int[] indices = new int[len]; int count = 0; - for (int i = 0; i < points.length; ++i) + for (int i = 0; i < len; ++i) { - ECPoint p = points[i]; - if (null != p && !p.isNormalized()) + ECPoint p = points[off + i]; + if (null != p && (iso != null || !p.isNormalized())) { zs[count] = p.getZCoord(0); - indices[count++] = i; + indices[count++] = off + i; } } @@ -257,7 +288,7 @@ public abstract class ECCurve return; } - ECAlgorithms.montgomeryTrick(zs, 0, count); + ECAlgorithms.montgomeryTrick(zs, 0, count, iso); for (int j = 0; j < count; ++j) { @@ -414,14 +445,23 @@ public abstract class ECCurve protected void checkPoints(ECPoint[] points) { + checkPoints(points, 0, points.length); + } + + protected void checkPoints(ECPoint[] points, int off, int len) + { if (points == null) { throw new IllegalArgumentException("'points' cannot be null"); } + if (off < 0 || len < 0 || (off > (points.length - len))) + { + throw new IllegalArgumentException("invalid range specified for 'points'"); + } - for (int i = 0; i < points.length; ++i) + for (int i = 0; i < len; ++i) { - ECPoint point = points[i]; + ECPoint point = points[off + i]; if (null != point && this != point.getCurve()) { throw new IllegalArgumentException("'points' entries must be null or on this curve"); diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java index 7cd04e4..4db27e0 100644 --- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java +++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java @@ -287,6 +287,9 @@ public abstract class ECPoint return x == null || y == null || (zs.length > 0 && zs[0].isZero()); } + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(boolean)} + */ public boolean isCompressed() { return this.withCompression; @@ -435,13 +438,19 @@ public abstract class ECPoint return sb.toString(); } + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(boolean)} + */ public byte[] getEncoded() { return getEncoded(this.withCompression); } /** - * return the field element encoded with point compression. (S 4.3.6) + * Get an encoding of the point value, optionally in compressed format. + * + * @param compressed whether to generate a compressed point encoding. + * @return the point encoding */ public byte[] getEncoded(boolean compressed) { @@ -771,14 +780,7 @@ public abstract class ECPoint Y3 = W1.subtract(X3).multiply(dy).subtract(A1); Z3 = dx; - if (Z1IsOne) - { - Z3Squared = C; - } - else - { - Z3 = Z3.multiply(Z1); - } + Z3 = Z3.multiply(Z1); } else { @@ -967,7 +969,7 @@ public abstract class ECPoint } else if (!a4.isZero()) { - ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.square(); + ECFieldElement Z1Squared = Z1.square(); ECFieldElement Z1Pow4 = Z1Squared.square(); if (a4Neg.bitLength() < a4.bitLength()) { diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java b/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java index 7ac3160..339689e 100644 --- a/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java +++ b/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java @@ -10,6 +10,7 @@ public abstract class WNafUtil private static final byte[] EMPTY_BYTES = new byte[0]; private static final int[] EMPTY_INTS = new int[0]; + private static final ECPoint[] EMPTY_POINTS = new ECPoint[0]; public static int[] generateCompactNaf(BigInteger k) { @@ -386,45 +387,99 @@ public abstract class WNafUtil ECCurve c = p.getCurve(); WNafPreCompInfo wnafPreCompInfo = getWNafPreCompInfo(c.getPreCompInfo(p, PRECOMP_NAME)); + int iniPreCompLen = 0, reqPreCompLen = 1 << Math.max(0, width - 2); + ECPoint[] preComp = wnafPreCompInfo.getPreComp(); if (preComp == null) { - preComp = new ECPoint[]{ p }; + preComp = EMPTY_POINTS; + } + else + { + iniPreCompLen = preComp.length; } - int preCompLen = preComp.length; - int reqPreCompLen = 1 << Math.max(0, width - 2); - - if (preCompLen < reqPreCompLen) + if (iniPreCompLen < reqPreCompLen) { preComp = resizeTable(preComp, reqPreCompLen); - if (reqPreCompLen == 2) + + if (reqPreCompLen == 1) { - preComp[1] = preComp[0].threeTimes(); + preComp[0] = p.normalize(); } else { - ECPoint twiceP = wnafPreCompInfo.getTwice(); - if (twiceP == null) + int curPreCompLen = iniPreCompLen; + if (curPreCompLen == 0) { - twiceP = preComp[0].twice(); - wnafPreCompInfo.setTwice(twiceP); + preComp[0] = p; + curPreCompLen = 1; } - for (int i = preCompLen; i < reqPreCompLen; i++) + ECFieldElement iso = null; + + if (reqPreCompLen == 2) { - /* - * Compute the new ECPoints for the precomputation array. The values 1, 3, 5, ..., - * 2^(width-1)-1 times p are computed - */ - preComp[i] = twiceP.add(preComp[i - 1]); + preComp[1] = p.threeTimes(); + } + else + { + ECPoint twiceP = wnafPreCompInfo.getTwice(), last = preComp[curPreCompLen - 1]; + if (twiceP == null) + { + twiceP = preComp[0].twice(); + wnafPreCompInfo.setTwice(twiceP); + + /* + * For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism + * where 'twiceP' is "affine", so that the subsequent additions are cheaper. This + * also requires scaling the initial point's X, Y coordinates, and reversing the + * isomorphism as part of the subsequent normalization. + * + * NOTE: The correctness of this optimization depends on: + * 1) additions do not use the curve's A, B coefficients. + * 2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ... + */ + if (ECAlgorithms.isFpCurve(c) && c.getFieldSize() >= 64) + { + switch (c.getCoordinateSystem()) + { + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + iso = twiceP.getZCoord(0); + twiceP = c.createPoint(twiceP.getXCoord().toBigInteger(), twiceP.getYCoord() + .toBigInteger()); + + ECFieldElement iso2 = iso.square(), iso3 = iso2.multiply(iso); + last = last.scaleX(iso2).scaleY(iso3); + + if (iniPreCompLen == 0) + { + preComp[0] = last; + } + break; + } + } + } + } + + while (curPreCompLen < reqPreCompLen) + { + /* + * Compute the new ECPoints for the precomputation array. The values 1, 3, + * 5, ..., 2^(width-1)-1 times p are computed + */ + preComp[curPreCompLen++] = last = last.add(twiceP); + } } - } - /* - * Having oft-used operands in affine form makes operations faster. - */ - c.normalizeAll(preComp); + /* + * Having oft-used operands in affine form makes operations faster. + */ + c.normalizeAll(preComp, iniPreCompLen, reqPreCompLen - iniPreCompLen, iso); + } } wnafPreCompInfo.setPreComp(preComp); diff --git a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java index 64ce17c..3c0646a 100644 --- a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java +++ b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java @@ -1,6 +1,7 @@ package org.bouncycastle.util; import java.math.BigInteger; +import java.util.Iterator; /** * General array utilities. @@ -968,4 +969,43 @@ public final class Arrays return result; } + + /** + * Iterator backed by a specific array. + */ + public static class Iterator<T> + implements java.util.Iterator<T> + { + private final T[] dataArray; + + private int position = 0; + + /** + * Base constructor. + * <p> + * Note: the array is not cloned, changes to it will affect the values returned by next(). + * </p> + * + * @param dataArray array backing the iterator. + */ + public Iterator(T[] dataArray) + { + this.dataArray = dataArray; + } + + public boolean hasNext() + { + return position < dataArray.length; + } + + public T next() + { + return dataArray[position++]; + } + + public void remove() + { + throw new UnsupportedOperationException("Cannot remove element from an Array."); + } + } } diff --git a/bcprov/src/main/java/org/bouncycastle/util/CollectionStore.java b/bcprov/src/main/java/org/bouncycastle/util/CollectionStore.java index 91aba14..1cc9641 100644 --- a/bcprov/src/main/java/org/bouncycastle/util/CollectionStore.java +++ b/bcprov/src/main/java/org/bouncycastle/util/CollectionStore.java @@ -8,10 +8,10 @@ import java.util.List; /** * A simple collection backed store. */ -public class CollectionStore - implements Store +public class CollectionStore<T> + implements Store<T>, Iterable<T> { - private Collection _local; + private Collection<T> _local; /** * Basic constructor. @@ -19,9 +19,9 @@ public class CollectionStore * @param collection - initial contents for the store, this is copied. */ public CollectionStore( - Collection collection) + Collection<T> collection) { - _local = new ArrayList(collection); + _local = new ArrayList<T>(collection); } /** @@ -30,20 +30,20 @@ public class CollectionStore * @param selector the selector to match against. * @return a possibly empty collection of matching objects. */ - public Collection getMatches(Selector selector) + public Collection<T> getMatches(Selector<T> selector) { if (selector == null) { - return new ArrayList(_local); + return new ArrayList<T>(_local); } else { - List col = new ArrayList(); - Iterator iter = _local.iterator(); + List<T> col = new ArrayList<T>(); + Iterator<T> iter = _local.iterator(); while (iter.hasNext()) { - Object obj = iter.next(); + T obj = iter.next(); if (selector.match(obj)) { @@ -54,4 +54,9 @@ public class CollectionStore return col; } } + + public Iterator<T> iterator() + { + return getMatches(null).iterator(); + } } diff --git a/bcprov/src/main/java/org/bouncycastle/util/Encodable.java b/bcprov/src/main/java/org/bouncycastle/util/Encodable.java new file mode 100644 index 0000000..67258fb --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/util/Encodable.java @@ -0,0 +1,18 @@ +package org.bouncycastle.util; + +import java.io.IOException; + +/** + * Interface implemented by objects that can be converted into byte arrays. + */ +public interface Encodable +{ + /** + * Return a byte array representing the implementing object. + * + * @return a byte array representing the encoding. + * @throws java.io.IOException if an issue arises generation the encoding. + */ + byte[] getEncoded() + throws IOException; +} diff --git a/bcprov/src/main/java/org/bouncycastle/util/Iterable.java b/bcprov/src/main/java/org/bouncycastle/util/Iterable.java new file mode 100644 index 0000000..a0fa9dc --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/util/Iterable.java @@ -0,0 +1,17 @@ +package org.bouncycastle.util; + +import java.util.Iterator; + +/** + * Utility class to allow use of Iterable feature in JDK 1.5+ + */ +public interface Iterable<T> + extends java.lang.Iterable<T> +{ + /** + * Returns an iterator over a set of elements of type T. + * + * @return an Iterator. + */ + Iterator<T> iterator(); +} diff --git a/bcprov/src/main/java/org/bouncycastle/util/Selector.java b/bcprov/src/main/java/org/bouncycastle/util/Selector.java index 7ad86bf..a3a5ec8 100644 --- a/bcprov/src/main/java/org/bouncycastle/util/Selector.java +++ b/bcprov/src/main/java/org/bouncycastle/util/Selector.java @@ -1,9 +1,9 @@ package org.bouncycastle.util; -public interface Selector +public interface Selector<T> extends Cloneable { - boolean match(Object obj); + boolean match(T obj); Object clone(); } diff --git a/bcprov/src/main/java/org/bouncycastle/util/Store.java b/bcprov/src/main/java/org/bouncycastle/util/Store.java index b994c92..fd28b83 100644 --- a/bcprov/src/main/java/org/bouncycastle/util/Store.java +++ b/bcprov/src/main/java/org/bouncycastle/util/Store.java @@ -2,8 +2,8 @@ package org.bouncycastle.util; import java.util.Collection; -public interface Store +public interface Store<T> { - Collection getMatches(Selector selector) + Collection<T> getMatches(Selector<T> selector) throws StoreException; } diff --git a/bcprov/src/main/java/org/bouncycastle/util/StringList.java b/bcprov/src/main/java/org/bouncycastle/util/StringList.java new file mode 100644 index 0000000..e733442 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/util/StringList.java @@ -0,0 +1,22 @@ +package org.bouncycastle.util; + +public interface StringList + extends Iterable<String> +{ + boolean add(String s); + + String get(int index); + + int size(); + + String[] toStringArray(); + + /** + * Return a section of the contents of the list. If the list is too short the array is filled with nulls. + * + * @param from the initial index of the range to be copied, inclusive + * @param to the final index of the range to be copied, exclusive. + * @return an array of length to - from + */ + String[] toStringArray(int from, int to); +} diff --git a/bcprov/src/main/java/org/bouncycastle/util/Strings.java b/bcprov/src/main/java/org/bouncycastle/util/Strings.java index 770edaa..44ff3ae 100644 --- a/bcprov/src/main/java/org/bouncycastle/util/Strings.java +++ b/bcprov/src/main/java/org/bouncycastle/util/Strings.java @@ -3,6 +3,7 @@ package org.bouncycastle.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Vector; public final class Strings @@ -311,4 +312,53 @@ public final class Strings } return res; } + + public static StringList newList() + { + return new StringListImpl(); + } + + private static class StringListImpl + extends ArrayList<String> + implements StringList + { + public boolean add(String s) + { + return super.add(s); + } + + public String set(int index, String element) + { + return super.set(index, element); + } + + public void add(int index, String element) + { + super.add(index, element); + } + + public String[] toStringArray() + { + String[] strs = new String[this.size()]; + + for (int i = 0; i != strs.length; i++) + { + strs[i] = this.get(i); + } + + return strs; + } + + public String[] toStringArray(int from, int to) + { + String[] strs = new String[to - from]; + + for (int i = from; i != this.size() && i != to; i++) + { + strs[i - from] = this.get(i); + } + + return strs; + } + } } diff --git a/bcprov/src/main/java/org/bouncycastle/x509/ExtendedPKIXBuilderParameters.java b/bcprov/src/main/java/org/bouncycastle/x509/ExtendedPKIXBuilderParameters.java index 51831d0..386fc3d 100644 --- a/bcprov/src/main/java/org/bouncycastle/x509/ExtendedPKIXBuilderParameters.java +++ b/bcprov/src/main/java/org/bouncycastle/x509/ExtendedPKIXBuilderParameters.java @@ -17,6 +17,7 @@ import java.util.Set; * * @see java.security.cert.PKIXBuilderParameters * @see org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi + * @deprecated use PKIXExtendedBuilderParameters */ public class ExtendedPKIXBuilderParameters extends ExtendedPKIXParameters { diff --git a/bcprov/src/main/java/org/bouncycastle/x509/ExtendedPKIXParameters.java b/bcprov/src/main/java/org/bouncycastle/x509/ExtendedPKIXParameters.java index 6386618..952f775 100644 --- a/bcprov/src/main/java/org/bouncycastle/x509/ExtendedPKIXParameters.java +++ b/bcprov/src/main/java/org/bouncycastle/x509/ExtendedPKIXParameters.java @@ -18,6 +18,8 @@ import java.util.Set; /** * This class extends the PKIXParameters with a validity model parameter. + * + * @deprecated use PKIXExtendedParameters */ public class ExtendedPKIXParameters extends PKIXParameters @@ -42,8 +44,11 @@ public class ExtendedPKIXParameters /** * Creates an instance of <code>PKIXParameters</code> with the specified * <code>Set</code> of most-trusted CAs. Each element of the set is a - * {@link TrustAnchor TrustAnchor}. <p/> Note that the <code>Set</code> + * {@link TrustAnchor TrustAnchor}. + * <p> + * Note that the <code>Set</code> * is copied to protect against subsequent modifications. + * </p> * * @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s * @throws InvalidAlgorithmParameterException if the specified @@ -154,8 +159,11 @@ public class ExtendedPKIXParameters * when the end certificate was signed. The CA (or Root CA) certificate must * have been valid, when the CA certificate was signed and so on. So the * {@link PKIXParameters#setDate(java.util.Date)} method sets the time, when - * the <em>end certificate</em> must have been valid. <p/> It is used e.g. + * the <em>end certificate</em> must have been valid. + * <p> + * It is used e.g. * in the German signature law. + * </p> */ public static final int CHAIN_VALIDITY_MODEL = 1; @@ -278,6 +286,7 @@ public class ExtendedPKIXParameters * * @param store The store to add. * @see #getStores() + * @deprectaed use addStore(). */ public void addAdditionalStore(Store store) { |