diff options
author | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2013-07-24 21:19:20 +0100 |
---|---|---|
committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2013-07-24 21:19:20 +0100 |
commit | b9107e03cbb02e73f61e2105df4d5de9d2c6ab52 (patch) | |
tree | 2e7b3d1017b49e6eac5c09a733c3a63e03a4b562 /bcprov/src | |
parent | fb958eec615d74410d4d26b20aeeb632479884e0 (diff) | |
parent | 57c3bb556ef873a72010d6022edddc14e6bba9be (diff) | |
download | android_external_bouncycastle-stable/cm-10.2.tar.gz android_external_bouncycastle-stable/cm-10.2.tar.bz2 android_external_bouncycastle-stable/cm-10.2.zip |
Merge tag 'android-4.3_r2.1' into cm-10.2cm-10.2.1cm-10.2.0cm-10.2-M1stable/cm-10.2cm-10.2
Android 4.3 release 2.1
Diffstat (limited to 'bcprov/src')
160 files changed, 2542 insertions, 1341 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java index 2aa68b3..ecfca6a 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java @@ -1,5 +1,6 @@ package org.bouncycastle.asn1; +import java.util.Enumeration; import java.util.Vector; public class ASN1EncodableVector @@ -15,6 +16,14 @@ public class ASN1EncodableVector v.addElement(obj); } + public void addAll(ASN1EncodableVector other) + { + for (Enumeration en = other.v.elements(); en.hasMoreElements();) + { + v.addElement(en.nextElement()); + } + } + public ASN1Encodable get(int i) { return (ASN1Encodable)v.elementAt(i); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java index 71009a0..d60c6a8 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java @@ -15,7 +15,7 @@ public class ASN1Integer super(value); } - public ASN1Integer(int value) + public ASN1Integer(long value) { super(value); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java index 5b52da8..84814c5 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java @@ -8,6 +8,9 @@ import java.io.IOException; public abstract class ASN1Null extends ASN1Primitive { + /** + * @deprecated use DERNull.INSTANCE + */ // BEGIN android-changed /*package*/ ASN1Null() { diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java index 8f785b8..f1ac6c7 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java @@ -110,10 +110,6 @@ abstract public class ASN1Set // in this case the parser returns a sequence, convert it // into a set. // - - - ASN1EncodableVector v = new ASN1EncodableVector(); - if (obj.getObject() instanceof ASN1Sequence) { ASN1Sequence s = (ASN1Sequence)obj.getObject(); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java index 33a09f8..341e46a 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java @@ -27,6 +27,18 @@ public class DERBMPString return (DERBMPString)obj; } + if (obj instanceof byte[]) + { + try + { + return (DERBMPString)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java index f7f2462..a7b02ec 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java @@ -159,17 +159,18 @@ public class DERBitString } public DERBitString( - ASN1Encodable obj) + int value) { - try - { - this.data = obj.toASN1Primitive().getEncoded(ASN1Encoding.DER); - this.padBits = 0; - } - catch (IOException e) - { - throw new IllegalArgumentException("Error processing object : " + e.toString()); - } + this.data = getBytes(value); + this.padBits = getPadBits(value); + } + + public DERBitString( + ASN1Encodable obj) + throws IOException + { + this.data = obj.toASN1Primitive().getEncoded(ASN1Encoding.DER); + this.padBits = 0; } public byte[] getBytes() diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERBoolean.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERBoolean.java index a519fa2..c8d7bd0 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERBoolean.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERBoolean.java @@ -40,7 +40,7 @@ public class DERBoolean } /** - * return a DERBoolean from the passed in boolean. + * return a ASN1Boolean from the passed in boolean. */ public static ASN1Boolean getInstance( boolean value) @@ -48,6 +48,15 @@ public class DERBoolean return (value ? TRUE : FALSE); } + /** + * return a ASN1Boolean from the passed in boolean. + */ + public static ASN1Boolean getInstance( + int value) + { + return (value != 0 ? TRUE : FALSE); + } + // BEGIN android-added /** * return a DERBoolean from the passed in array. @@ -108,6 +117,10 @@ public class DERBoolean } } + /** + * @deprecated use getInstance(boolean) method. + * @param value + */ // BEGIN android-changed protected DERBoolean( boolean value) diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DEREnumerated.java b/bcprov/src/main/java/org/bouncycastle/asn1/DEREnumerated.java index 2cf17f1..2f299ee 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DEREnumerated.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DEREnumerated.java @@ -28,6 +28,18 @@ public class DEREnumerated return new ASN1Enumerated(((DEREnumerated)obj).getValue()); } + if (obj instanceof byte[]) + { + try + { + return (ASN1Enumerated)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java index d7cd594..c6354f4 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java @@ -19,6 +19,18 @@ public class DERGeneralString return (DERGeneralString) obj; } + if (obj instanceof byte[]) + { + try + { + return (DERGeneralString)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java index bb3b575..43e4673 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java @@ -36,6 +36,18 @@ public class DERGeneralizedTime return new ASN1GeneralizedTime(((DERGeneralizedTime)obj).time); } + if (obj instanceof byte[]) + { + try + { + return (ASN1GeneralizedTime)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java index abb2811..631672e 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java @@ -27,6 +27,18 @@ public class DERIA5String return (DERIA5String)obj; } + if (obj instanceof byte[]) + { + try + { + return (DERIA5String)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERInteger.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERInteger.java index d5e826d..3804450 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERInteger.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERInteger.java @@ -27,6 +27,18 @@ public class DERInteger return new ASN1Integer((((DERInteger)obj).getValue())); } + if (obj instanceof byte[]) + { + try + { + return (ASN1Integer)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } @@ -56,7 +68,7 @@ public class DERInteger } public DERInteger( - int value) + long value) { bytes = BigInteger.valueOf(value).toByteArray(); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java index 9bbc826..7df2acf 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java @@ -12,6 +12,9 @@ public class DERNull private static final byte[] zeroBytes = new byte[0]; + /** + * @deprecated use DERNull.INSTANCE + */ // BEGIN android-changed protected DERNull() // END android-changed diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java index fae4063..eca4eea 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java @@ -27,6 +27,18 @@ public class DERNumericString return (DERNumericString)obj; } + if (obj instanceof byte[]) + { + try + { + return (DERNumericString)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERObjectIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERObjectIdentifier.java index 02a0945..8e2ee4e 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERObjectIdentifier.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERObjectIdentifier.java @@ -31,6 +31,16 @@ public class DERObjectIdentifier return new ASN1ObjectIdentifier(((DERObjectIdentifier)obj).getId()); } + if (obj instanceof ASN1Encodable && ((ASN1Encodable)obj).toASN1Primitive() instanceof ASN1ObjectIdentifier) + { + return (ASN1ObjectIdentifier)((ASN1Encodable)obj).toASN1Primitive(); + } + + if (obj instanceof byte[]) + { + return ASN1ObjectIdentifier.fromOctetString((byte[])obj); + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } @@ -59,6 +69,8 @@ public class DERObjectIdentifier } } + private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f; + DERObjectIdentifier( byte[] bytes) { @@ -71,26 +83,27 @@ public class DERObjectIdentifier { int b = bytes[i] & 0xff; - if (value < 0x80000000000000L) + if (value <= LONG_LIMIT) { - value = value * 128 + (b & 0x7f); + value += (b & 0x7f); if ((b & 0x80) == 0) // end of number reached { if (first) { - switch ((int)value / 40) - { - case 0: - objId.append('0'); - break; - case 1: - objId.append('1'); + if (value < 40) + { + objId.append('0'); + } + else if (value < 80) + { + objId.append('1'); value -= 40; - break; - default: - objId.append('2'); + } + else + { + objId.append('2'); value -= 80; - } + } first = false; } @@ -98,6 +111,10 @@ public class DERObjectIdentifier objId.append(value); value = 0; } + else + { + value <<= 7; + } } else { @@ -105,15 +122,25 @@ public class DERObjectIdentifier { bigValue = BigInteger.valueOf(value); } - bigValue = bigValue.shiftLeft(7); bigValue = bigValue.or(BigInteger.valueOf(b & 0x7f)); if ((b & 0x80) == 0) { + if (first) + { + objId.append('2'); + bigValue = bigValue.subtract(BigInteger.valueOf(80)); + first = false; + } + objId.append('.'); objId.append(bigValue); bigValue = null; value = 0; } + else + { + bigValue = bigValue.shiftLeft(7); + } } } @@ -124,6 +151,7 @@ public class DERObjectIdentifier */ this.identifier = objId.toString().intern(); // END android-changed + this.body = Arrays.clone(bytes); } public DERObjectIdentifier( @@ -188,16 +216,23 @@ public class DERObjectIdentifier private void doOutput(ByteArrayOutputStream aOut) { - OIDTokenizer tok = new OIDTokenizer(identifier); - - writeField(aOut, - Integer.parseInt(tok.nextToken()) * 40 - + Integer.parseInt(tok.nextToken())); + OIDTokenizer tok = new OIDTokenizer(identifier); + int first = Integer.parseInt(tok.nextToken()) * 40; + + String secondToken = tok.nextToken(); + if (secondToken.length() <= 18) + { + writeField(aOut, first + Long.parseLong(secondToken)); + } + else + { + writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first))); + } while (tok.hasMoreTokens()) { String token = tok.nextToken(); - if (token.length() < 18) + if (token.length() <= 18) { writeField(aOut, Long.parseLong(token)); } @@ -208,7 +243,7 @@ public class DERObjectIdentifier } } - protected byte[] getBody() + protected synchronized byte[] getBody() { if (body == null) { @@ -287,6 +322,7 @@ public class DERObjectIdentifier { char ch = identifier.charAt(i); + // TODO Leading zeroes? if ('0' <= ch && ch <= '9') { periodAllowed = true; @@ -310,7 +346,7 @@ public class DERObjectIdentifier return periodAllowed; } - private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[255][]; + private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[256][]; static ASN1ObjectIdentifier fromOctetString(byte[] enc) { @@ -320,42 +356,23 @@ public class DERObjectIdentifier } int idx1 = enc[enc.length - 2] & 0xff; - ASN1ObjectIdentifier[] first = cache[idx1]; - - if (first == null) - { - first = cache[idx1] = new ASN1ObjectIdentifier[255]; - } + // in this case top bit is always zero + int idx2 = enc[enc.length - 1] & 0x7f; - int idx2 = enc[enc.length - 1] & 0xff; - - ASN1ObjectIdentifier possibleMatch = first[idx2]; - - if (possibleMatch == null) - { - possibleMatch = first[idx2] = new ASN1ObjectIdentifier(enc); - return possibleMatch; - } + ASN1ObjectIdentifier possibleMatch; - if (Arrays.areEqual(enc, possibleMatch.getBody())) - { - return possibleMatch; - } - else + synchronized (cache) { - idx1 = (idx1 + 1) % 256; - first = cache[idx1]; - if (first == null) + ASN1ObjectIdentifier[] first = cache[idx1]; + if (first == null) { - first = cache[idx1] = new ASN1ObjectIdentifier[255]; + first = cache[idx1] = new ASN1ObjectIdentifier[128]; } possibleMatch = first[idx2]; - if (possibleMatch == null) { - possibleMatch = first[idx2] = new ASN1ObjectIdentifier(enc); - return possibleMatch; + return first[idx2] = new ASN1ObjectIdentifier(enc); } if (Arrays.areEqual(enc, possibleMatch.getBody())) @@ -363,19 +380,35 @@ public class DERObjectIdentifier return possibleMatch; } - idx2 = (idx2 + 1) % 256; - possibleMatch = first[idx2]; + idx1 = (idx1 + 1) & 0xff; + first = cache[idx1]; + if (first == null) + { + first = cache[idx1] = new ASN1ObjectIdentifier[128]; + } + possibleMatch = first[idx2]; if (possibleMatch == null) { - possibleMatch = first[idx2] = new ASN1ObjectIdentifier(enc); - return possibleMatch; + return first[idx2] = new ASN1ObjectIdentifier(enc); } if (Arrays.areEqual(enc, possibleMatch.getBody())) { return possibleMatch; } + + idx2 = (idx2 + 1) & 0x7f; + possibleMatch = first[idx2]; + if (possibleMatch == null) + { + return first[idx2] = new ASN1ObjectIdentifier(enc); + } + } + + if (Arrays.areEqual(enc, possibleMatch.getBody())) + { + return possibleMatch; } return new ASN1ObjectIdentifier(enc); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java index 6c56e83..59d0110 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java @@ -29,6 +29,18 @@ public class DERPrintableString return (DERPrintableString)obj; } + if (obj instanceof byte[]) + { + try + { + return (DERPrintableString)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java index ee2979b..956b9c7 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java @@ -27,6 +27,18 @@ public class DERT61String return (DERT61String)obj; } + if (obj instanceof byte[]) + { + try + { + return (DERT61String)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } @@ -70,12 +82,16 @@ public class DERT61String public DERT61String( String string) { + // BEGIN android-changed this.string = Strings.toByteArray(string); + // END android-changed } public String getString() { + // BEGIN android-changed return Strings.fromByteArray(string); + // END android-changed } public String toString() diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERUTCTime.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERUTCTime.java index a5bdef1..c5bd536 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERUTCTime.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERUTCTime.java @@ -35,6 +35,18 @@ public class DERUTCTime return new ASN1UTCTime(((DERUTCTime)obj).time); } + if (obj instanceof byte[]) + { + try + { + return (ASN1UTCTime)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java index f46f558..fa34b22 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java @@ -27,6 +27,18 @@ public class DERUTF8String return (DERUTF8String)obj; } + if (obj instanceof byte[]) + { + try + { + return (DERUTF8String)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java index 4fe82f0..51b0799 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java @@ -28,6 +28,18 @@ public class DERUniversalString return (DERUniversalString)obj; } + if (obj instanceof byte[]) + { + try + { + return (DERUniversalString)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java index 1c385b7..18e7d73 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java @@ -27,6 +27,18 @@ public class DERVisibleString return (DERVisibleString)obj; } + if (obj instanceof byte[]) + { + try + { + return (DERVisibleString)fromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); + } + } + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java index 3f6ce22..3785174 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java @@ -17,7 +17,6 @@ class DefiniteLengthInputStream DefiniteLengthInputStream( InputStream in, int length) - throws IOException { super(in, length); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java index 4c88c7b..f114623 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java @@ -44,6 +44,12 @@ public class AttributeTable } public AttributeTable( + Attribute attr) + { + addAttribute(attr.getAttrType(), attr); + } + + public AttributeTable( Attributes attrs) { this(ASN1Set.getInstance(attrs.toASN1Primitive())); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java index 2aa2fae..acbe04a 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java @@ -37,13 +37,10 @@ public class EncryptedPrivateKeyInfo public static EncryptedPrivateKeyInfo getInstance( Object obj) { - // BEGIN android-changed - // fix copy and paste error in instanceof call if (obj instanceof EncryptedPrivateKeyInfo) { return (EncryptedPrivateKeyInfo)obj; } - // END android-changed else if (obj != null) { return new EncryptedPrivateKeyInfo(ASN1Sequence.getInstance(obj)); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java index bb94440..6cbf907 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java @@ -24,15 +24,15 @@ public class IssuerAndSerialNumber { return (IssuerAndSerialNumber)obj; } - else if (obj instanceof ASN1Sequence) + else if (obj != null) { - return new IssuerAndSerialNumber((ASN1Sequence)obj); + return new IssuerAndSerialNumber(ASN1Sequence.getInstance(obj)); } - throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); + return null; } - public IssuerAndSerialNumber( + private IssuerAndSerialNumber( ASN1Sequence seq) { this.name = X500Name.getInstance(seq.getObjectAt(0)); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java index fa4c20e..8ca8dc3 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java @@ -60,6 +60,7 @@ public interface PKCSObjectIdentifiers static final ASN1ObjectIdentifier des_EDE3_CBC = encryptionAlgorithm.branch("7"); static final ASN1ObjectIdentifier RC2_CBC = encryptionAlgorithm.branch("2"); + static final ASN1ObjectIdentifier rc4 = encryptionAlgorithm.branch("4"); // // object identifiers for digests diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java index 25ff98d..515b515 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java @@ -19,9 +19,7 @@ public class RSAESOAEPparams private AlgorithmIdentifier maskGenAlgorithm; private AlgorithmIdentifier pSourceAlgorithm; - // BEGIN android-changed public final static AlgorithmIdentifier DEFAULT_HASH_ALGORITHM = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); - // END android-changed public final static AlgorithmIdentifier DEFAULT_MASK_GEN_FUNCTION = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, DEFAULT_HASH_ALGORITHM); public final static AlgorithmIdentifier DEFAULT_P_SOURCE_ALGORITHM = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java index 73cfcdc..dc91c9c 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java @@ -22,9 +22,7 @@ public class RSASSAPSSparams private ASN1Integer saltLength; private ASN1Integer trailerField; - // BEGIN android-changed public final static AlgorithmIdentifier DEFAULT_HASH_ALGORITHM = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); - // END android-changed public final static AlgorithmIdentifier DEFAULT_MASK_GEN_FUNCTION = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, DEFAULT_HASH_ALGORITHM); public final static ASN1Integer DEFAULT_SALT_LENGTH = new ASN1Integer(20); public final static ASN1Integer DEFAULT_TRAILER_FIELD = new ASN1Integer(1); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java index 234eb2e..3d3089b 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java @@ -8,6 +8,7 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -73,9 +74,9 @@ public class SignedData // an interesting feature of SignedData is that there appear to be varying implementations... // for the moment we ignore anything which doesn't fit. // - if (o instanceof DERTaggedObject) + if (o instanceof ASN1TaggedObject) { - DERTaggedObject tagged = (DERTaggedObject)o; + ASN1TaggedObject tagged = (ASN1TaggedObject)o; switch (tagged.getTagNo()) { diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java b/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java index 976f556..9886b73 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java @@ -10,8 +10,10 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERApplicationSpecific; import org.bouncycastle.asn1.BERConstructedOctetString; +import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.BERTaggedObject; @@ -25,12 +27,9 @@ import org.bouncycastle.asn1.DERExternal; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERT61String; -import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.DERVisibleString; @@ -78,9 +77,7 @@ public class ASN1Dump { Object o = e.nextElement(); - // BEGIN android-changed if (o == null || o.equals(DERNull.INSTANCE)) - // END android-changed { buf.append(tab); buf.append("NULL"); @@ -96,7 +93,7 @@ public class ASN1Dump } } } - else if (obj instanceof DERTaggedObject) + else if (obj instanceof ASN1TaggedObject) { String tab = indent + TAB; @@ -110,7 +107,7 @@ public class ASN1Dump buf.append("Tagged ["); } - DERTaggedObject o = (DERTaggedObject)obj; + ASN1TaggedObject o = (ASN1TaggedObject)obj; buf.append(Integer.toString(o.getTagNo())); buf.append(']'); @@ -133,42 +130,22 @@ public class ASN1Dump _dumpAsString(tab, verbose, o.getObject(), buf); } } - else if (obj instanceof BERSet) + else if (obj instanceof ASN1Set) { Enumeration e = ((ASN1Set)obj).getObjects(); String tab = indent + TAB; buf.append(indent); - buf.append("BER Set"); - buf.append(nl); - while (e.hasMoreElements()) + if (obj instanceof BERSet) { - Object o = e.nextElement(); - - if (o == null) - { - buf.append(tab); - buf.append("NULL"); - buf.append(nl); - } - else if (o instanceof ASN1Primitive) - { - _dumpAsString(tab, verbose, (ASN1Primitive)o, buf); - } - else - { - _dumpAsString(tab, verbose, ((ASN1Encodable)o).toASN1Primitive(), buf); - } + buf.append("BER Set"); + } + else + { + buf.append("DER Set"); } - } - else if (obj instanceof DERSet) - { - Enumeration e = ((ASN1Set)obj).getObjects(); - String tab = indent + TAB; - buf.append(indent); - buf.append("DER Set"); buf.append(nl); while (e.hasMoreElements()) @@ -191,34 +168,18 @@ public class ASN1Dump } } } - else if (obj instanceof ASN1ObjectIdentifier) - { - buf.append(indent + "ObjectIdentifier(" + ((ASN1ObjectIdentifier)obj).getId() + ")" + nl); - } - else if (obj instanceof DERBoolean) - { - buf.append(indent + "Boolean(" + ((DERBoolean)obj).isTrue() + ")" + nl); - } - else if (obj instanceof ASN1Integer) - { - buf.append(indent + "Integer(" + ((ASN1Integer)obj).getValue() + ")" + nl); - } - else if (obj instanceof BERConstructedOctetString) + else if (obj instanceof ASN1OctetString) { ASN1OctetString oct = (ASN1OctetString)obj; - buf.append(indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] "); - if (verbose) + + if (obj instanceof BEROctetString || obj instanceof BERConstructedOctetString) { - buf.append(dumpBinaryDataAsString(indent, oct.getOctets())); + buf.append(indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] "); } - else{ - buf.append(nl); + else + { + buf.append(indent + "DER Octet String" + "[" + oct.getOctets().length + "] "); } - } - else if (obj instanceof DEROctetString) - { - ASN1OctetString oct = (ASN1OctetString)obj; - buf.append(indent + "DER Octet String" + "[" + oct.getOctets().length + "] "); if (verbose) { buf.append(dumpBinaryDataAsString(indent, oct.getOctets())); @@ -227,6 +188,18 @@ public class ASN1Dump buf.append(nl); } } + else if (obj instanceof ASN1ObjectIdentifier) + { + buf.append(indent + "ObjectIdentifier(" + ((ASN1ObjectIdentifier)obj).getId() + ")" + nl); + } + else if (obj instanceof DERBoolean) + { + buf.append(indent + "Boolean(" + ((DERBoolean)obj).isTrue() + ")" + nl); + } + else if (obj instanceof ASN1Integer) + { + buf.append(indent + "Integer(" + ((ASN1Integer)obj).getValue() + ")" + nl); + } else if (obj instanceof DERBitString) { DERBitString bt = (DERBitString)obj; diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java index 30e871c..7c9506a 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java @@ -4,12 +4,18 @@ import java.util.Vector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.x500.style.BCStyle; public class X500NameBuilder { private X500NameStyle template; private Vector rdns = new Vector(); + public X500NameBuilder() + { + this(BCStyle.INSTANCE); + } + public X500NameBuilder(X500NameStyle template) { this.template = template; diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStrictStyle.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStrictStyle.java index af10fef..eb627c0 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStrictStyle.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStrictStyle.java @@ -2,6 +2,7 @@ package org.bouncycastle.asn1.x500.style; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.X500NameStyle; /** * Variation of BCStyle that insists on strict ordering for equality @@ -10,6 +11,8 @@ import org.bouncycastle.asn1.x500.X500Name; public class BCStrictStyle extends BCStyle { + public static final X500NameStyle INSTANCE = new BCStrictStyle(); + public boolean areEqual(X500Name name1, X500Name name2) { RDN[] rdns1 = name1.getRDNs(); @@ -22,7 +25,7 @@ public class BCStrictStyle for (int i = 0; i != rdns1.length; i++) { - if (rdnAreEqual(rdns1[i], rdns2[i])) + if (!rdnAreEqual(rdns1[i], rdns2[i])) { return false; } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java index 32f93ff..777cc56 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java @@ -4,8 +4,8 @@ import java.io.IOException; import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERUTF8String; @@ -303,7 +303,7 @@ public class BCStyle } else if (oid.equals(DATE_OF_BIRTH)) // accept time string as well as # (for compatibility) { - return new DERGeneralizedTime(value); + return new ASN1GeneralizedTime(value); } else if (oid.equals(C) || oid.equals(SN) || oid.equals(DN_QUALIFIER) || oid.equals(TELEPHONE_NUMBER)) @@ -378,80 +378,7 @@ public class BCStyle protected boolean rdnAreEqual(RDN rdn1, RDN rdn2) { - if (rdn1.isMultiValued()) - { - if (rdn2.isMultiValued()) - { - AttributeTypeAndValue[] atvs1 = rdn1.getTypesAndValues(); - AttributeTypeAndValue[] atvs2 = rdn2.getTypesAndValues(); - - if (atvs1.length != atvs2.length) - { - return false; - } - - for (int i = 0; i != atvs1.length; i++) - { - if (!atvAreEqual(atvs1[i], atvs2[i])) - { - return false; - } - } - } - else - { - return false; - } - } - else - { - if (!rdn2.isMultiValued()) - { - return atvAreEqual(rdn1.getFirst(), rdn2.getFirst()); - } - else - { - return false; - } - } - - return true; - } - - private boolean atvAreEqual(AttributeTypeAndValue atv1, AttributeTypeAndValue atv2) - { - if (atv1 == atv2) - { - return true; - } - - if (atv1 == null) - { - return false; - } - - if (atv2 == null) - { - return false; - } - - ASN1ObjectIdentifier o1 = atv1.getType(); - ASN1ObjectIdentifier o2 = atv2.getType(); - - if (!o1.equals(o2)) - { - return false; - } - - String v1 = IETFUtils.canonicalize(IETFUtils.valueToString(atv1.getValue())); - String v2 = IETFUtils.canonicalize(IETFUtils.valueToString(atv2.getValue())); - - if (!v1.equals(v2)) - { - return false; - } - - return true; + return IETFUtils.rDNAreEqual(rdn1, rdn2); } public RDN[] fromString(String dirName) @@ -514,29 +441,7 @@ public class BCStyle buf.append(','); } - if (rdns[i].isMultiValued()) - { - AttributeTypeAndValue[] atv = rdns[i].getTypesAndValues(); - boolean firstAtv = true; - - for (int j = 0; j != atv.length; j++) - { - if (firstAtv) - { - firstAtv = false; - } - else - { - buf.append('+'); - } - - IETFUtils.appendTypeAndValue(buf, atv[j], DefaultSymbols); - } - } - else - { - IETFUtils.appendTypeAndValue(buf, rdns[i].getFirst(), DefaultSymbols); - } + IETFUtils.appendRDN(buf, rdns[i], DefaultSymbols); } return buf.toString(); 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 5c60c89..861108d 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 @@ -151,6 +151,36 @@ public class IETFUtils return ASN1Primitive.fromByteArray(data); } + public static void appendRDN( + StringBuffer buf, + RDN rdn, + Hashtable oidSymbols) + { + if (rdn.isMultiValued()) + { + AttributeTypeAndValue[] atv = rdn.getTypesAndValues(); + boolean firstAtv = true; + + for (int j = 0; j != atv.length; j++) + { + if (firstAtv) + { + firstAtv = false; + } + else + { + buf.append('+'); + } + + IETFUtils.appendTypeAndValue(buf, atv[j], oidSymbols); + } + } + else + { + IETFUtils.appendTypeAndValue(buf, rdn.getFirst(), oidSymbols); + } + } + public static void appendTypeAndValue( StringBuffer buf, AttributeTypeAndValue typeAndValue, @@ -298,4 +328,82 @@ public class IETFUtils return res.toString(); } + + public static boolean rDNAreEqual(RDN rdn1, RDN rdn2) + { + if (rdn1.isMultiValued()) + { + if (rdn2.isMultiValued()) + { + AttributeTypeAndValue[] atvs1 = rdn1.getTypesAndValues(); + AttributeTypeAndValue[] atvs2 = rdn2.getTypesAndValues(); + + if (atvs1.length != atvs2.length) + { + return false; + } + + for (int i = 0; i != atvs1.length; i++) + { + if (!atvAreEqual(atvs1[i], atvs2[i])) + { + return false; + } + } + } + else + { + return false; + } + } + else + { + if (!rdn2.isMultiValued()) + { + return atvAreEqual(rdn1.getFirst(), rdn2.getFirst()); + } + else + { + return false; + } + } + + return true; + } + + private static boolean atvAreEqual(AttributeTypeAndValue atv1, AttributeTypeAndValue atv2) + { + if (atv1 == atv2) + { + return true; + } + + if (atv1 == null) + { + return false; + } + + if (atv2 == null) + { + return false; + } + + ASN1ObjectIdentifier o1 = atv1.getType(); + ASN1ObjectIdentifier o2 = atv2.getType(); + + if (!o1.equals(o2)) + { + return false; + } + + String v1 = IETFUtils.canonicalize(IETFUtils.valueToString(atv1.getValue())); + String v2 = IETFUtils.canonicalize(IETFUtils.valueToString(atv2.getValue())); + + if (!v1.equals(v2)) + { + return false; + } + + return true; + } } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java index 63f1a25..430d379 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java @@ -267,80 +267,7 @@ public class RFC4519Style protected boolean rdnAreEqual(RDN rdn1, RDN rdn2) { - if (rdn1.isMultiValued()) - { - if (rdn2.isMultiValued()) - { - AttributeTypeAndValue[] atvs1 = rdn1.getTypesAndValues(); - AttributeTypeAndValue[] atvs2 = rdn2.getTypesAndValues(); - - if (atvs1.length != atvs2.length) - { - return false; - } - - for (int i = 0; i != atvs1.length; i++) - { - if (!atvAreEqual(atvs1[i], atvs2[i])) - { - return false; - } - } - } - else - { - return false; - } - } - else - { - if (!rdn2.isMultiValued()) - { - return atvAreEqual(rdn1.getFirst(), rdn2.getFirst()); - } - else - { - return false; - } - } - - return true; - } - - private boolean atvAreEqual(AttributeTypeAndValue atv1, AttributeTypeAndValue atv2) - { - if (atv1 == atv2) - { - return true; - } - - if (atv1 == null) - { - return false; - } - - if (atv2 == null) - { - return false; - } - - ASN1ObjectIdentifier o1 = atv1.getType(); - ASN1ObjectIdentifier o2 = atv2.getType(); - - if (!o1.equals(o2)) - { - return false; - } - - String v1 = IETFUtils.canonicalize(IETFUtils.valueToString(atv1.getValue())); - String v2 = IETFUtils.canonicalize(IETFUtils.valueToString(atv2.getValue())); - - if (!v1.equals(v2)) - { - return false; - } - - return true; + return IETFUtils.rDNAreEqual(rdn1, rdn2); } // parse backwards @@ -413,29 +340,7 @@ public class RFC4519Style buf.append(','); } - if (rdns[i].isMultiValued()) - { - AttributeTypeAndValue[] atv = rdns[i].getTypesAndValues(); - boolean firstAtv = true; - - for (int j = 0; j != atv.length; j++) - { - if (firstAtv) - { - firstAtv = false; - } - else - { - buf.append('+'); - } - - IETFUtils.appendTypeAndValue(buf, atv[j], DefaultSymbols); - } - } - else - { - IETFUtils.appendTypeAndValue(buf, rdns[i].getFirst(), DefaultSymbols); - } + IETFUtils.appendRDN(buf, rdns[i], DefaultSymbols); } return buf.toString(); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java index 7549a72..a02295a 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java @@ -10,7 +10,7 @@ class X500NameTokenizer { private String value; private int index; - private char seperator; + private char separator; private StringBuffer buf = new StringBuffer(); public X500NameTokenizer( @@ -21,11 +21,11 @@ class X500NameTokenizer public X500NameTokenizer( String oid, - char seperator) + char separator) { this.value = oid; this.index = -1; - this.seperator = seperator; + this.separator = separator; } public boolean hasMoreTokens() @@ -58,6 +58,14 @@ class X500NameTokenizer } else { + if (c == '#' && buf.charAt(buf.length() - 1) == '=') + { + buf.append('\\'); + } + else if (c == '+' && separator != '+') + { + buf.append('\\'); + } buf.append(c); } escaped = false; @@ -70,7 +78,7 @@ class X500NameTokenizer { buf.append('\\'); } - else if (c == '+' && seperator != '+') + else if (c == '+' && separator != '+') { buf.append('\\'); } @@ -81,7 +89,7 @@ class X500NameTokenizer { escaped = true; } - else if (c == seperator) + else if (c == separator) { break; } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java index e157b66..2f78156 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java @@ -1,17 +1,17 @@ package org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERSequence; public class AttCertValidityPeriod extends ASN1Object { - DERGeneralizedTime notBeforeTime; - DERGeneralizedTime notAfterTime; + ASN1GeneralizedTime notBeforeTime; + ASN1GeneralizedTime notAfterTime; public static AttCertValidityPeriod getInstance( Object obj) @@ -37,8 +37,8 @@ public class AttCertValidityPeriod + seq.size()); } - notBeforeTime = DERGeneralizedTime.getInstance(seq.getObjectAt(0)); - notAfterTime = DERGeneralizedTime.getInstance(seq.getObjectAt(1)); + notBeforeTime = ASN1GeneralizedTime.getInstance(seq.getObjectAt(0)); + notAfterTime = ASN1GeneralizedTime.getInstance(seq.getObjectAt(1)); } /** @@ -46,19 +46,19 @@ public class AttCertValidityPeriod * @param notAfterTime */ public AttCertValidityPeriod( - DERGeneralizedTime notBeforeTime, - DERGeneralizedTime notAfterTime) + ASN1GeneralizedTime notBeforeTime, + ASN1GeneralizedTime notAfterTime) { this.notBeforeTime = notBeforeTime; this.notAfterTime = notAfterTime; } - public DERGeneralizedTime getNotBeforeTime() + public ASN1GeneralizedTime getNotBeforeTime() { return notBeforeTime; } - public DERGeneralizedTime getNotAfterTime() + public ASN1GeneralizedTime getNotAfterTime() { return notAfterTime; } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java index 84ef3da..3746f9e 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java @@ -61,6 +61,11 @@ public class AuthorityKeyIdentifier return null; } + public static AuthorityKeyIdentifier fromExtensions(Extensions extensions) + { + return AuthorityKeyIdentifier.getInstance(extensions.getExtensionParsedValue(Extension.authorityKeyIdentifier)); + } + protected AuthorityKeyIdentifier( ASN1Sequence seq) { diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java index 19fa762..4a16bd4 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java @@ -2,6 +2,7 @@ package org.bouncycastle.asn1.x509; import java.math.BigInteger; +import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; @@ -14,9 +15,7 @@ import org.bouncycastle.asn1.DERSequence; public class BasicConstraints extends ASN1Object { - // BEGIN android-changed - DERBoolean cA = DERBoolean.FALSE; - // END android-changed + ASN1Boolean cA = ASN1Boolean.getInstance(false); ASN1Integer pathLenConstraint = null; public static BasicConstraints getInstance( @@ -44,7 +43,12 @@ public class BasicConstraints return null; } - + + public static BasicConstraints fromExtensions(Extensions extensions) + { + return BasicConstraints.getInstance(extensions.getExtensionParsedValue(Extension.basicConstraints)); + } + private BasicConstraints( ASN1Sequence seq) { @@ -83,9 +87,7 @@ public class BasicConstraints { if (cA) { - // BEGIN android-changed - this.cA = DERBoolean.TRUE; - // END android-changed + this.cA = ASN1Boolean.getInstance(true); } else { @@ -102,9 +104,7 @@ public class BasicConstraints public BasicConstraints( int pathLenConstraint) { - // BEGIN android-changed - this.cA = DERBoolean.TRUE; - // END android-changed + this.cA = ASN1Boolean.getInstance(true); this.pathLenConstraint = new ASN1Integer(pathLenConstraint); } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLReason.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLReason.java index 621b5c8..ecc6872 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLReason.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLReason.java @@ -6,6 +6,7 @@ import java.util.Hashtable; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.util.Integers; /** * The CRLReason enumeration. @@ -138,9 +139,7 @@ public class CRLReason public static CRLReason lookup(int value) { - // BEGIN android-changed - Integer idx = Integer.valueOf(value); - // END android-changed + Integer idx = Integers.valueOf(value); if (!table.containsKey(idx)) { diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DSAParameter.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DSAParameter.java index 853bd35..056798c 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DSAParameter.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DSAParameter.java @@ -26,17 +26,17 @@ public class DSAParameter public static DSAParameter getInstance( Object obj) { - if(obj == null || obj instanceof DSAParameter) + if (obj instanceof DSAParameter) { return (DSAParameter)obj; } - if(obj instanceof ASN1Sequence) + if(obj != null) { - return new DSAParameter((ASN1Sequence)obj); + return new DSAParameter(ASN1Sequence.getInstance(obj)); } - throw new IllegalArgumentException("Invalid DSAParameter: " + obj.getClass().getName()); + return null; } public DSAParameter( @@ -49,7 +49,7 @@ public class DSAParameter this.g = new ASN1Integer(g); } - public DSAParameter( + private DSAParameter( ASN1Sequence seq) { if (seq.size() != 3) diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java index 97f1c54..dcc1b1f 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java @@ -4,6 +4,7 @@ import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; +import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; @@ -38,8 +39,7 @@ public class ExtendedKeyUsage { return (ExtendedKeyUsage)obj; } - - if (obj != null) + else if (obj != null) { return new ExtendedKeyUsage(ASN1Sequence.getInstance(obj)); } @@ -47,6 +47,11 @@ public class ExtendedKeyUsage return null; } + public static ExtendedKeyUsage fromExtensions(Extensions extensions) + { + return ExtendedKeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.extendedKeyUsage)); + } + public ExtendedKeyUsage( KeyPurposeId usage) { @@ -55,7 +60,7 @@ public class ExtendedKeyUsage this.usageTable.put(usage, usage); } - public ExtendedKeyUsage( + private ExtendedKeyUsage( ASN1Sequence seq) { this.seq = seq; @@ -64,8 +69,8 @@ public class ExtendedKeyUsage while (e.hasMoreElements()) { - Object o = e.nextElement(); - if (!(o instanceof ASN1ObjectIdentifier)) + ASN1Encodable o = (ASN1Encodable)e.nextElement(); + if (!(o.toASN1Primitive() instanceof ASN1ObjectIdentifier)) { throw new IllegalArgumentException("Only ASN1ObjectIdentifiers allowed in ExtendedKeyUsage."); } @@ -74,7 +79,24 @@ public class ExtendedKeyUsage } public ExtendedKeyUsage( - Vector usages) + KeyPurposeId[] usages) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + for (int i = 0; i != usages.length; i++) + { + v.add(usages[i]); + this.usageTable.put(usages[i], usages[i]); + } + + this.seq = new DERSequence(v); + } + + /** + * @deprecated use KeyPurposeId[] constructor. + */ + public ExtendedKeyUsage( + Vector usages) { ASN1EncodableVector v = new ASN1EncodableVector(); Enumeration e = usages.elements(); @@ -98,15 +120,17 @@ public class ExtendedKeyUsage /** * Returns all extended key usages. - * The returned vector contains ASN1ObjectIdentifiers. - * @return A vector with all key purposes. + * The returned vector contains DERObjectIdentifiers. + * @return An array with all key purposes. */ - public Vector getUsages() + public KeyPurposeId[] getUsages() { - Vector temp = new Vector(); - for (Enumeration it = usageTable.elements(); it.hasMoreElements();) + KeyPurposeId[] temp = new KeyPurposeId[seq.size()]; + + int i = 0; + for (Enumeration it = seq.getObjects(); it.hasMoreElements();) { - temp.addElement(it.nextElement()); + temp[i++] = KeyPurposeId.getInstance(it.nextElement()); } return temp; } 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 1b93305..33175db 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java @@ -5,6 +5,7 @@ import java.util.Hashtable; import java.util.Vector; import org.bouncycastle.asn1.ASN1Boolean; +import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; @@ -75,6 +76,18 @@ public class Extensions /** * Base Constructor + * + * @param extension a single extension. + */ + public Extensions( + Extension extension) + { + this.ordering.addElement(extension.getExtnId()); + this.extensions.put(extension.getExtnId(), extension); + } + + /** + * Base Constructor * * @param extensions an array of extensions. */ @@ -111,6 +124,24 @@ public class Extensions } /** + * return the parsed value of the extension represented by the object identifier + * passed in. + * + * @return the parsed value of the extension if it's present, null otherwise. + */ + public ASN1Encodable getExtensionParsedValue(ASN1ObjectIdentifier oid) + { + Extension ext = this.getExtension(oid); + + if (ext != null) + { + return ext.getParsedValue(); + } + + return null; + } + + /** * <pre> * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension * diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java index bd45407..7118d10 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java @@ -1,6 +1,7 @@ package org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; @@ -34,6 +35,11 @@ public class GeneralNames return getInstance(ASN1Sequence.getInstance(obj, explicit)); } + public static GeneralNames fromExtensions(Extensions extensions, ASN1ObjectIdentifier extOID) + { + return GeneralNames.getInstance(extensions.getExtensionParsedValue(extOID)); + } + /** * Construct a GeneralNames object containing one GeneralName. * diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java index d082a9d..8d3036b 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java @@ -1,5 +1,7 @@ package org.bouncycastle.asn1.x509; +import java.math.BigInteger; + import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; @@ -19,17 +21,17 @@ public class IssuerSerial public static IssuerSerial getInstance( Object obj) { - if (obj == null || obj instanceof IssuerSerial) + if (obj instanceof IssuerSerial) { return (IssuerSerial)obj; } - if (obj instanceof ASN1Sequence) + if (obj != null) { - return new IssuerSerial((ASN1Sequence)obj); + return new IssuerSerial(ASN1Sequence.getInstance(obj)); } - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); + return null; } public static IssuerSerial getInstance( @@ -39,7 +41,7 @@ public class IssuerSerial return getInstance(ASN1Sequence.getInstance(obj, explicit)); } - public IssuerSerial( + private IssuerSerial( ASN1Sequence seq) { if (seq.size() != 2 && seq.size() != 3) @@ -55,7 +57,14 @@ public class IssuerSerial issuerUID = DERBitString.getInstance(seq.getObjectAt(2)); } } - + + public IssuerSerial( + GeneralNames issuer, + BigInteger serial) + { + this(issuer, new ASN1Integer(serial)); + } + public IssuerSerial( GeneralNames issuer, ASN1Integer serial) diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java index e31471c..1f29162 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java @@ -1,11 +1,11 @@ package org.bouncycastle.asn1.x509; +import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DERBoolean; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -96,15 +96,11 @@ public class IssuingDistributionPoint } if (onlyContainsUserCerts) { - // BEGIN android-changed - vec.add(new DERTaggedObject(false, 1, DERBoolean.TRUE)); - // END android-changed + vec.add(new DERTaggedObject(false, 1, ASN1Boolean.getInstance(true))); } if (onlyContainsCACerts) { - // BEGIN android-changed - vec.add(new DERTaggedObject(false, 2, DERBoolean.TRUE)); - // END android-changed + vec.add(new DERTaggedObject(false, 2, ASN1Boolean.getInstance(true))); } if (onlySomeReasons != null) { @@ -112,15 +108,11 @@ public class IssuingDistributionPoint } if (indirectCRL) { - // BEGIN android-changed - vec.add(new DERTaggedObject(false, 4, DERBoolean.TRUE)); - // END android-changed + vec.add(new DERTaggedObject(false, 4, ASN1Boolean.getInstance(true))); } if (onlyContainsAttributeCerts) { - // BEGIN android-changed - vec.add(new DERTaggedObject(false, 5, DERBoolean.TRUE)); - // END android-changed + vec.add(new DERTaggedObject(false, 5, ASN1Boolean.getInstance(true))); } seq = new DERSequence(vec); @@ -163,19 +155,19 @@ public class IssuingDistributionPoint distributionPoint = DistributionPointName.getInstance(o, true); break; case 1: - onlyContainsUserCerts = DERBoolean.getInstance(o, false).isTrue(); + onlyContainsUserCerts = ASN1Boolean.getInstance(o, false).isTrue(); break; case 2: - onlyContainsCACerts = DERBoolean.getInstance(o, false).isTrue(); + onlyContainsCACerts = ASN1Boolean.getInstance(o, false).isTrue(); break; case 3: onlySomeReasons = new ReasonFlags(ReasonFlags.getInstance(o, false)); break; case 4: - indirectCRL = DERBoolean.getInstance(o, false).isTrue(); + indirectCRL = ASN1Boolean.getInstance(o, false).isTrue(); break; case 5: - onlyContainsAttributeCerts = DERBoolean.getInstance(o, false).isTrue(); + onlyContainsAttributeCerts = ASN1Boolean.getInstance(o, false).isTrue(); break; default: throw new IllegalArgumentException( diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java index 542a26b..3955fb7 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java @@ -1,6 +1,8 @@ package org.bouncycastle.asn1.x509; +import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Primitive; /** * The KeyPurposeId object. @@ -13,101 +15,91 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; * </pre> */ public class KeyPurposeId - extends ASN1ObjectIdentifier + extends ASN1Object { - private static final String id_kp = "1.3.6.1.5.5.7.3"; - - /** - * Create a KeyPurposeId from an OID string - * - * @param id OID String. E.g. "1.3.6.1.5.5.7.3.1" - */ - public KeyPurposeId( - String id) - { - super(id); - } + private static final ASN1ObjectIdentifier id_kp = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.3"); /** * { 2 5 29 37 0 } */ - public static final KeyPurposeId anyExtendedKeyUsage = new KeyPurposeId(X509Extensions.ExtendedKeyUsage.getId() + ".0"); + public static final KeyPurposeId anyExtendedKeyUsage = new KeyPurposeId(Extension.extendedKeyUsage.branch("0")); + /** * { id-kp 1 } */ - public static final KeyPurposeId id_kp_serverAuth = new KeyPurposeId(id_kp + ".1"); + public static final KeyPurposeId id_kp_serverAuth = new KeyPurposeId(id_kp.branch("1")); /** * { id-kp 2 } */ - public static final KeyPurposeId id_kp_clientAuth = new KeyPurposeId(id_kp + ".2"); + public static final KeyPurposeId id_kp_clientAuth = new KeyPurposeId(id_kp.branch("2")); /** * { id-kp 3 } */ - public static final KeyPurposeId id_kp_codeSigning = new KeyPurposeId(id_kp + ".3"); + public static final KeyPurposeId id_kp_codeSigning = new KeyPurposeId(id_kp.branch("3")); /** * { id-kp 4 } */ - public static final KeyPurposeId id_kp_emailProtection = new KeyPurposeId(id_kp + ".4"); + public static final KeyPurposeId id_kp_emailProtection = new KeyPurposeId(id_kp.branch("4")); /** * Usage deprecated by RFC4945 - was { id-kp 5 } */ - public static final KeyPurposeId id_kp_ipsecEndSystem = new KeyPurposeId(id_kp + ".5"); + public static final KeyPurposeId id_kp_ipsecEndSystem = new KeyPurposeId(id_kp.branch("5")); /** * Usage deprecated by RFC4945 - was { id-kp 6 } */ - public static final KeyPurposeId id_kp_ipsecTunnel = new KeyPurposeId(id_kp + ".6"); + public static final KeyPurposeId id_kp_ipsecTunnel = new KeyPurposeId(id_kp.branch("6")); /** * Usage deprecated by RFC4945 - was { idkp 7 } */ - public static final KeyPurposeId id_kp_ipsecUser = new KeyPurposeId(id_kp + ".7"); + public static final KeyPurposeId id_kp_ipsecUser = new KeyPurposeId(id_kp.branch("7")); /** * { id-kp 8 } */ - public static final KeyPurposeId id_kp_timeStamping = new KeyPurposeId(id_kp + ".8"); + public static final KeyPurposeId id_kp_timeStamping = new KeyPurposeId(id_kp.branch("8")); /** * { id-kp 9 } */ - public static final KeyPurposeId id_kp_OCSPSigning = new KeyPurposeId(id_kp + ".9"); + public static final KeyPurposeId id_kp_OCSPSigning = new KeyPurposeId(id_kp.branch("9")); /** * { id-kp 10 } */ - public static final KeyPurposeId id_kp_dvcs = new KeyPurposeId(id_kp + ".10"); + public static final KeyPurposeId id_kp_dvcs = new KeyPurposeId(id_kp.branch("10")); /** * { id-kp 11 } */ - public static final KeyPurposeId id_kp_sbgpCertAAServerAuth = new KeyPurposeId(id_kp + ".11"); + public static final KeyPurposeId id_kp_sbgpCertAAServerAuth = new KeyPurposeId(id_kp.branch("11")); /** * { id-kp 12 } */ - public static final KeyPurposeId id_kp_scvp_responder = new KeyPurposeId(id_kp + ".12"); + public static final KeyPurposeId id_kp_scvp_responder = new KeyPurposeId(id_kp.branch("12")); /** * { id-kp 13 } */ - public static final KeyPurposeId id_kp_eapOverPPP = new KeyPurposeId(id_kp + ".13"); + public static final KeyPurposeId id_kp_eapOverPPP = new KeyPurposeId(id_kp.branch("13")); /** * { id-kp 14 } */ - public static final KeyPurposeId id_kp_eapOverLAN = new KeyPurposeId(id_kp + ".14"); + public static final KeyPurposeId id_kp_eapOverLAN = new KeyPurposeId(id_kp.branch("14")); /** * { id-kp 15 } */ - public static final KeyPurposeId id_kp_scvpServer = new KeyPurposeId(id_kp + ".15"); + public static final KeyPurposeId id_kp_scvpServer = new KeyPurposeId(id_kp.branch("15")); /** * { id-kp 16 } */ - public static final KeyPurposeId id_kp_scvpClient = new KeyPurposeId(id_kp + ".16"); + public static final KeyPurposeId id_kp_scvpClient = new KeyPurposeId(id_kp.branch("16")); /** * { id-kp 17 } */ - public static final KeyPurposeId id_kp_ipsecIKE = new KeyPurposeId(id_kp + ".17"); + public static final KeyPurposeId id_kp_ipsecIKE = new KeyPurposeId(id_kp.branch("17")); /** * { id-kp 18 } */ - public static final KeyPurposeId id_kp_capwapAC = new KeyPurposeId(id_kp + ".18"); + public static final KeyPurposeId id_kp_capwapAC = new KeyPurposeId(id_kp.branch("18")); /** * { id-kp 19 } */ - public static final KeyPurposeId id_kp_capwapWTP = new KeyPurposeId(id_kp + ".19"); + public static final KeyPurposeId id_kp_capwapWTP = new KeyPurposeId(id_kp.branch("19")); // // microsoft key purpose ids @@ -115,5 +107,45 @@ public class KeyPurposeId /** * { 1 3 6 1 4 1 311 20 2 2 } */ - public static final KeyPurposeId id_kp_smartcardlogon = new KeyPurposeId("1.3.6.1.4.1.311.20.2.2"); + public static final KeyPurposeId id_kp_smartcardlogon = new KeyPurposeId(new ASN1ObjectIdentifier("1.3.6.1.4.1.311.20.2.2")); + + private ASN1ObjectIdentifier id; + + private KeyPurposeId(ASN1ObjectIdentifier id) + { + this.id = id; + } + + /** + * @deprecated use getInstance and an OID or one of the constants above. + * @param id string representation of an OID. + */ + public KeyPurposeId(String id) + { + this(new ASN1ObjectIdentifier(id)); + } + + public static KeyPurposeId getInstance(Object o) + { + if (o instanceof KeyPurposeId) + { + return (KeyPurposeId)o; + } + else if (o != null) + { + return new KeyPurposeId(ASN1ObjectIdentifier.getInstance(o)); + } + + return null; + } + + public ASN1Primitive toASN1Primitive() + { + return id; + } + + public String getId() + { + return id.getId(); + } } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyUsage.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyUsage.java index 3ffd94b..2943c0b 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyUsage.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyUsage.java @@ -1,5 +1,7 @@ package org.bouncycastle.asn1.x509; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERBitString; /** @@ -20,7 +22,7 @@ import org.bouncycastle.asn1.DERBitString; * </pre> */ public class KeyUsage - extends DERBitString + extends ASN1Object { public static final int digitalSignature = (1 << 7); public static final int nonRepudiation = (1 << 6); @@ -32,21 +34,27 @@ public class KeyUsage public static final int encipherOnly = (1 << 0); public static final int decipherOnly = (1 << 15); - public static DERBitString getInstance(Object obj) // needs to be DERBitString for other VMs + private DERBitString bitString; + + public static KeyUsage getInstance(Object obj) // needs to be DERBitString for other VMs { if (obj instanceof KeyUsage) { return (KeyUsage)obj; } - - if (obj instanceof X509Extension) + else if (obj != null) { - return new KeyUsage(DERBitString.getInstance(X509Extension.convertValueToObject((X509Extension)obj))); + return new KeyUsage(DERBitString.getInstance(obj)); } - return new KeyUsage(DERBitString.getInstance(obj)); + return null; + } + + public static KeyUsage fromExtensions(Extensions extensions) + { + return KeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.keyUsage)); } - + /** * Basic constructor. * @@ -57,21 +65,38 @@ public class KeyUsage public KeyUsage( int usage) { - super(getBytes(usage), getPadBits(usage)); + this.bitString = new DERBitString(usage); } - public KeyUsage( - DERBitString usage) + private KeyUsage( + DERBitString bitString) { - super(usage.getBytes(), usage.getPadBits()); + this.bitString = bitString; + } + + public byte[] getBytes() + { + return bitString.getBytes(); + } + + public int getPadBits() + { + return bitString.getPadBits(); } public String toString() { + byte[] data = bitString.getBytes(); + if (data.length == 1) { return "KeyUsage: 0x" + Integer.toHexString(data[0] & 0xff); } return "KeyUsage: 0x" + Integer.toHexString((data[1] & 0xff) << 8 | (data[0] & 0xff)); } + + public ASN1Primitive toASN1Primitive() + { + return bitString; + } } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java index 02096f2..0a923a8 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java @@ -1,7 +1,6 @@ package org.bouncycastle.asn1.x509; import java.util.Enumeration; -import java.util.Vector; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; @@ -14,7 +13,7 @@ import org.bouncycastle.asn1.DERTaggedObject; public class NameConstraints extends ASN1Object { - private ASN1Sequence permitted, excluded; + private GeneralSubtree[] permitted, excluded; public static NameConstraints getInstance(Object obj) { @@ -38,12 +37,12 @@ public class NameConstraints ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement()); switch (o.getTagNo()) { - case 0: - permitted = ASN1Sequence.getInstance(o, false); - break; - case 1: - excluded = ASN1Sequence.getInstance(o, false); - break; + case 0: + permitted = createArray(ASN1Sequence.getInstance(o, false)); + break; + case 1: + excluded = createArray(ASN1Sequence.getInstance(o, false)); + break; } } } @@ -52,7 +51,7 @@ public class NameConstraints * Constructor from a given details. * * <p> - * permitted and excluded are Vectors of GeneralSubtree objects. + * permitted and excluded are arrays of GeneralSubtree objects. * * @param permitted * Permitted subtrees @@ -60,37 +59,38 @@ public class NameConstraints * Excludes subtrees */ public NameConstraints( - Vector permitted, - Vector excluded) + GeneralSubtree[] permitted, + GeneralSubtree[] excluded) { if (permitted != null) { - this.permitted = createSequence(permitted); + this.permitted = permitted; } + if (excluded != null) { - this.excluded = createSequence(excluded); + this.excluded = excluded; } } - private DERSequence createSequence(Vector subtree) + private GeneralSubtree[] createArray(ASN1Sequence subtree) { - ASN1EncodableVector vec = new ASN1EncodableVector(); - Enumeration e = subtree.elements(); - while (e.hasMoreElements()) + GeneralSubtree[] ar = new GeneralSubtree[subtree.size()]; + + for (int i = 0; i != ar.length; i++) { - vec.add((GeneralSubtree)e.nextElement()); + ar[i] = GeneralSubtree.getInstance(subtree.getObjectAt(i)); } - - return new DERSequence(vec); + + return ar; } - public ASN1Sequence getPermittedSubtrees() + public GeneralSubtree[] getPermittedSubtrees() { return permitted; } - public ASN1Sequence getExcludedSubtrees() + public GeneralSubtree[] getExcludedSubtrees() { return excluded; } @@ -103,14 +103,14 @@ public class NameConstraints { ASN1EncodableVector v = new ASN1EncodableVector(); - if (permitted != null) + if (permitted != null) { - v.add(new DERTaggedObject(false, 0, permitted)); + v.add(new DERTaggedObject(false, 0, new DERSequence(permitted))); } - if (excluded != null) + if (excluded != null) { - v.add(new DERTaggedObject(false, 1, excluded)); + v.add(new DERTaggedObject(false, 1, new DERSequence(excluded))); } return new DERSequence(v); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java index 7a2d77e..c4668b7 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java @@ -8,7 +8,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERBitString; -import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERSequence; /** @@ -118,7 +117,7 @@ public class ObjectDigestInfo + seq.size()); } - digestedObjectType = DEREnumerated.getInstance(seq.getObjectAt(0)); + digestedObjectType = ASN1Enumerated.getInstance(seq.getObjectAt(0)); int offset = 0; @@ -133,7 +132,7 @@ public class ObjectDigestInfo objectDigest = DERBitString.getInstance(seq.getObjectAt(2 + offset)); } - public DEREnumerated getDigestedObjectType() + public ASN1Enumerated getDigestedObjectType() { return digestedObjectType; } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java index e56d89f..1a9400d 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java @@ -43,6 +43,11 @@ public class SubjectKeyIdentifier return null; } + public static SubjectKeyIdentifier fromExtensions(Extensions extensions) + { + return SubjectKeyIdentifier.getInstance(extensions.getExtensionParsedValue(Extension.subjectKeyIdentifier)); + } + public SubjectKeyIdentifier( byte[] keyid) { diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java index 660ca05..9e09cd7 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java @@ -50,6 +50,7 @@ public class SubjectPublicKeyInfo public SubjectPublicKeyInfo( AlgorithmIdentifier algId, ASN1Encodable publicKey) + throws IOException { this.keyData = new DERBitString(publicKey); this.algId = algId; diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java index 437d6c0..fe4cb5e 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java @@ -2,9 +2,9 @@ package org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1UTCTime; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; -import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.asn1.x500.X500Name; /** @@ -71,7 +71,7 @@ public class V1TBSCertificateGenerator } public void setStartDate( - DERUTCTime startDate) + ASN1UTCTime startDate) { this.startDate = new Time(startDate); } @@ -83,12 +83,12 @@ public class V1TBSCertificateGenerator } public void setEndDate( - DERUTCTime endDate) + ASN1UTCTime endDate) { this.endDate = new Time(endDate); } - /** + /** * @deprecated use X500Name method */ public void setSubject( diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java index 5e9bb46..c72e3cc 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java @@ -289,6 +289,7 @@ public class X509Extensions * Constructor from a table of extensions with ordering. * <p> * It's is assumed the table contains OID/String pairs. + * @deprecated use Extensions */ public X509Extensions( Vector ordering, @@ -326,6 +327,7 @@ public class X509Extensions * * @param objectIDs a vector of the object identifiers. * @param values a vector of the extension values. + * @deprecated use Extensions */ public X509Extensions( Vector objectIDs, @@ -408,9 +410,7 @@ public class X509Extensions if (ext.isCritical()) { - // BEGIN android-changed v.add(DERBoolean.TRUE); - // END android-changed } v.add(ext.getValue()); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Name.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Name.java index 2dc630f..d1c7d8e 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Name.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Name.java @@ -706,9 +706,7 @@ public class X509Name if (index == -1) { - // BEGIN android-changed throw new IllegalArgumentException("badly formatted directory string"); - // END android-changed } String name = token.substring(0, index); diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameTokenizer.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameTokenizer.java index 32e9346..ceca1ec 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameTokenizer.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameTokenizer.java @@ -5,12 +5,13 @@ package org.bouncycastle.asn1.x509; * java.util.StringTokenizer. We need this class as some of the * lightweight Java environment don't support classes like * StringTokenizer. + * @deprecated use X500NameTokenizer */ public class X509NameTokenizer { private String value; private int index; - private char seperator; + private char separator; private StringBuffer buf = new StringBuffer(); public X509NameTokenizer( @@ -21,11 +22,11 @@ public class X509NameTokenizer public X509NameTokenizer( String oid, - char seperator) + char separator) { this.value = oid; this.index = -1; - this.seperator = seperator; + this.separator = separator; } public boolean hasMoreTokens() @@ -58,17 +59,14 @@ public class X509NameTokenizer } else { - // BEGIN android-added - // copied from a newer version of BouncyCastle if (c == '#' && buf.charAt(buf.length() - 1) == '=') { buf.append('\\'); } - else if (c == '+' && seperator != '+') + else if (c == '+' && separator != '+') { buf.append('\\'); } - // END android-added buf.append(c); } escaped = false; @@ -81,7 +79,7 @@ public class X509NameTokenizer { buf.append('\\'); } - else if (c == '+' && seperator != '+') + else if (c == '+' && separator != '+') { buf.append('\\'); } @@ -92,12 +90,23 @@ public class X509NameTokenizer { escaped = true; } - else if (c == seperator) + else if (c == separator) { break; } else { + // BEGIN android-added + // copied from a newer version of BouncyCastle + if (c == '#' && buf.charAt(buf.length() - 1) == '=') + { + buf.append('\\'); + } + else if (c == '+' && separator != '+') + { + buf.append('\\'); + } + // END android-added buf.append(c); } } diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java index 06e47b6..764017e 100644 --- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java +++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java @@ -170,7 +170,7 @@ public class X962NamedCurves c2m163v1.decodePoint( Hex.decode("0307AF69989546103D79329FCC3D74880F33BBE803CB")), c2m163v1n, c2m163v1h, - Hex.decode("D2COFB15760860DEF1EEF4D696E6768756151754")); + Hex.decode("D2C0FB15760860DEF1EEF4D696E6768756151754")); } }; diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/AsymmetricCipherKeyPair.java b/bcprov/src/main/java/org/bouncycastle/crypto/AsymmetricCipherKeyPair.java index 85bec73..ddee701 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/AsymmetricCipherKeyPair.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/AsymmetricCipherKeyPair.java @@ -1,12 +1,14 @@ package org.bouncycastle.crypto; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; + /** * a holding class for public/private parameter pairs. */ public class AsymmetricCipherKeyPair { - private CipherParameters publicParam; - private CipherParameters privateParam; + private AsymmetricKeyParameter publicParam; + private AsymmetricKeyParameter privateParam; /** * basic constructor. @@ -15,19 +17,34 @@ public class AsymmetricCipherKeyPair * @param privateParam the corresponding private key parameters. */ public AsymmetricCipherKeyPair( - CipherParameters publicParam, - CipherParameters privateParam) + AsymmetricKeyParameter publicParam, + AsymmetricKeyParameter privateParam) { this.publicParam = publicParam; this.privateParam = privateParam; } /** + * basic constructor. + * + * @param publicParam a public key parameters object. + * @param privateParam the corresponding private key parameters. + * @deprecated use AsymmetricKeyParameter + */ + public AsymmetricCipherKeyPair( + CipherParameters publicParam, + CipherParameters privateParam) + { + this.publicParam = (AsymmetricKeyParameter)publicParam; + this.privateParam = (AsymmetricKeyParameter)privateParam; + } + + /** * return the public key parameters. * * @return the public key parameters. */ - public CipherParameters getPublic() + public AsymmetricKeyParameter getPublic() { return publicParam; } @@ -37,7 +54,7 @@ public class AsymmetricCipherKeyPair * * @return the private key parameters. */ - public CipherParameters getPrivate() + public AsymmetricKeyParameter getPrivate() { return privateParam; } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/BasicAgreement.java b/bcprov/src/main/java/org/bouncycastle/crypto/BasicAgreement.java index 4907427..8e5ff0d 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/BasicAgreement.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/BasicAgreement.java @@ -11,11 +11,16 @@ public interface BasicAgreement /** * initialise the agreement engine. */ - public void init(CipherParameters param); + void init(CipherParameters param); + + /** + * return the field size for the agreement algorithm in bytes. + */ + int getFieldSize(); /** * given a public key from a given party calculate the next * message in the agreement sequence. */ - public BigInteger calculateAgreement(CipherParameters pubKey); + BigInteger calculateAgreement(CipherParameters pubKey); } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java index 4878786..bdb694d 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java @@ -201,7 +201,7 @@ public class BufferedBlockCipher { if ((outOff + length) > out.length) { - throw new DataLengthException("output buffer too short"); + throw new OutputLengthException("output buffer too short"); } } @@ -265,7 +265,7 @@ public class BufferedBlockCipher if (outOff + bufOff > out.length) { - throw new DataLengthException("output buffer too short for doFinal()"); + throw new OutputLengthException("output buffer too short for doFinal()"); } if (bufOff != 0) diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/InvalidCipherTextException.java b/bcprov/src/main/java/org/bouncycastle/crypto/InvalidCipherTextException.java index 59e4b26..21c150d 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/InvalidCipherTextException.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/InvalidCipherTextException.java @@ -24,4 +24,17 @@ public class InvalidCipherTextException { super(message); } + + /** + * create a InvalidCipherTextException with the given message. + * + * @param message the message to be carried with the exception. + * @param cause the root cause of the exception. + */ + public InvalidCipherTextException( + String message, + Throwable cause) + { + super(message, cause); + } } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/OutputLengthException.java b/bcprov/src/main/java/org/bouncycastle/crypto/OutputLengthException.java new file mode 100644 index 0000000..62811a2 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/crypto/OutputLengthException.java @@ -0,0 +1,10 @@ +package org.bouncycastle.crypto; + +public class OutputLengthException + extends DataLengthException +{ + public OutputLengthException(String msg) + { + super(msg); + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java index dbf550d..2543b59 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java @@ -103,14 +103,21 @@ public abstract class PBEParametersGenerator public static byte[] PKCS5PasswordToBytes( char[] password) { - byte[] bytes = new byte[password.length]; + if (password != null) + { + byte[] bytes = new byte[password.length]; - for (int i = 0; i != bytes.length; i++) + for (int i = 0; i != bytes.length; i++) + { + bytes[i] = (byte)password[i]; + } + + return bytes; + } + else { - bytes[i] = (byte)password[i]; + return new byte[0]; } - - return bytes; } /** @@ -136,7 +143,6 @@ public abstract class PBEParametersGenerator public static byte[] PKCS12PasswordToBytes( char[] password) { - // BEGIN android-changed if (password != null && password.length > 0) { // +1 for extra 2 pad bytes. @@ -154,6 +160,5 @@ public abstract class PBEParametersGenerator { return new byte[0]; } - // END android-changed } } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java index 40893bf..d2e2a09 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java @@ -4,10 +4,10 @@ import java.math.BigInteger; import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; -import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; /** @@ -47,6 +47,11 @@ public class DHBasicAgreement this.dhParams = key.getParameters(); } + public int getFieldSize() + { + return (key.getParameters().getP().bitLength() + 7) / 8; + } + /** * given a short term public key from a given party calculate the next * message in the agreement sequence. diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java index 3ad3e1c..59944e0 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java @@ -2,12 +2,11 @@ package org.bouncycastle.crypto.agreement; import java.math.BigInteger; -import org.bouncycastle.math.ec.ECPoint; - import org.bouncycastle.crypto.BasicAgreement; import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.math.ec.ECPoint; /** * P1363 7.2.1 ECSVDP-DH @@ -34,6 +33,11 @@ public class ECDHBasicAgreement this.key = (ECPrivateKeyParameters)key; } + public int getFieldSize() + { + return (key.getParameters().getCurve().getFieldSize() + 7) / 8; + } + public BigInteger calculateAgreement( CipherParameters pubKey) { diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/AndroidDigestFactory.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/AndroidDigestFactory.java index 1a82a46..3dc7059 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/AndroidDigestFactory.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/AndroidDigestFactory.java @@ -33,11 +33,13 @@ public final class AndroidDigestFactory { Class factoryImplementationClass; try { factoryImplementationClass = Class.forName(OpenSSLFactoryClassName); + // Double check for NativeCrypto in case we are running on RI for testing + Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto"); } catch (ClassNotFoundException e1) { try { factoryImplementationClass = Class.forName(BouncyCastleFactoryClassName); } catch (ClassNotFoundException e2) { - throw new AssertionError("Failed to find AndroidDigestFactoryInterface " + throw new AssertionError("Failed to load AndroidDigestFactoryInterface " + "implementation. Looked for " + OpenSSLFactoryClassName + " and " + BouncyCastleFactoryClassName); diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/OpenSSLDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/OpenSSLDigest.java index d2f9f25..3e7c0e7 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/OpenSSLDigest.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/OpenSSLDigest.java @@ -32,7 +32,7 @@ public class OpenSSLDigest implements ExtendedDigest { /** * Holds the EVP_MD for the hashing algorithm, e.g. EVP_get_digestbyname("sha1"); */ - private final int evp_md; + private final long evp_md; /** * Holds the output size of the message digest. @@ -49,7 +49,7 @@ public class OpenSSLDigest implements ExtendedDigest { * lazily initialized to avoid having to reallocate on reset when * its unlikely to be reused. */ - private int ctx; + private long ctx; /** * Holds a dummy buffer for writing single bytes to the digest. @@ -60,7 +60,7 @@ public class OpenSSLDigest implements ExtendedDigest { * Creates a new OpenSSLMessageDigest instance for the given algorithm * name. */ - private OpenSSLDigest(String algorithm, int evp_md, int size, int blockSize) { + private OpenSSLDigest(String algorithm, long evp_md, int size, int blockSize) { this.algorithm = algorithm; this.evp_md = evp_md; this.size = size; @@ -99,7 +99,7 @@ public class OpenSSLDigest implements ExtendedDigest { return i; } - private int getCtx() { + private long getCtx() { if (ctx == 0) { ctx = NativeCrypto.EVP_DigestInit(evp_md); } @@ -123,35 +123,35 @@ public class OpenSSLDigest implements ExtendedDigest { } public static class MD5 extends OpenSSLDigest { - private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("md5"); + private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("md5"); private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); private static final int BLOCK_SIZE = NativeCrypto.EVP_MD_block_size(EVP_MD); public MD5() { super("MD5", EVP_MD, SIZE, BLOCK_SIZE); } } public static class SHA1 extends OpenSSLDigest { - private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1"); + private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1"); private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); private static final int BLOCK_SIZE = NativeCrypto.EVP_MD_block_size(EVP_MD); public SHA1() { super("SHA-1", EVP_MD, SIZE, BLOCK_SIZE); } } public static class SHA256 extends OpenSSLDigest { - private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256"); + private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256"); private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); private static final int BLOCK_SIZE = NativeCrypto.EVP_MD_block_size(EVP_MD); public SHA256() { super("SHA-256", EVP_MD, SIZE, BLOCK_SIZE); } } public static class SHA384 extends OpenSSLDigest { - private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384"); + private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384"); private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); private static final int BLOCK_SIZE = NativeCrypto.EVP_MD_block_size(EVP_MD); public SHA384() { super("SHA-384", EVP_MD, SIZE, BLOCK_SIZE); } } public static class SHA512 extends OpenSSLDigest { - private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512"); + private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512"); private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); private static final int BLOCK_SIZE = NativeCrypto.EVP_MD_block_size(EVP_MD); public SHA512() { super("SHA-512", EVP_MD, SIZE, BLOCK_SIZE); } 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 8bcfe26..d8ec62b 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java @@ -201,10 +201,20 @@ public class PKCS1Encoding } byte type = block[0]; - - if (type != 1 && type != 2) + + if (forPrivateKey) + { + if (type != 2) + { + throw new InvalidCipherTextException("unknown block type"); + } + } + else { - throw new InvalidCipherTextException("unknown block type"); + if (type != 1) + { + throw new InvalidCipherTextException("unknown block type"); + } } // BEGIN android-added if ((type == 1 && forPrivateKey) || (type == 2 && !forPrivateKey)) diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java index d9bb482..1bc9aae 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java @@ -219,9 +219,7 @@ private static final int[] Tinv0 = 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0}; - private int shift( - int r, - int shift) + private static int shift(int r, int shift) { return (r >>> shift) | (r << -shift); } @@ -232,7 +230,7 @@ private static final int[] Tinv0 = private static final int m2 = 0x7f7f7f7f; private static final int m3 = 0x0000001b; - private int FFmulX(int x) + private static int FFmulX(int x) { return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3)); } @@ -247,7 +245,7 @@ private static final int[] Tinv0 = */ - private int inv_mcol(int x) + private static int inv_mcol(int x) { int f2 = FFmulX(x); int f4 = FFmulX(f2); @@ -257,7 +255,7 @@ private static final int[] Tinv0 = return f2 ^ f4 ^ f8 ^ shift(f2 ^ f9, 8) ^ shift(f4 ^ f9, 16) ^ shift(f9, 24); } - private int subWord(int x) + private static int subWord(int x) { return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24); } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java index 2374be1..7e91973 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java @@ -3,6 +3,9 @@ package org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; +// BEGIN android-added +import org.bouncycastle.crypto.OutputLengthException; +// END android-added import org.bouncycastle.crypto.params.KeyParameter; /** @@ -549,9 +552,7 @@ public class AESFastEngine 0xd89ce4b4, 0x6490c156, 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8}; - private int shift( - int r, - int shift) + private static int shift(int r, int shift) { return (r >>> shift) | (r << -shift); } @@ -562,7 +563,7 @@ public class AESFastEngine private static final int m2 = 0x7f7f7f7f; private static final int m3 = 0x0000001b; - private int FFmulX(int x) + private static int FFmulX(int x) { return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3)); } @@ -577,7 +578,7 @@ public class AESFastEngine */ - private int inv_mcol(int x) + private static int inv_mcol(int x) { int f2 = FFmulX(x); int f4 = FFmulX(f2); @@ -588,7 +589,7 @@ public class AESFastEngine } - private int subWord(int x) + private static int subWord(int x) { return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24); } @@ -725,7 +726,9 @@ public class AESFastEngine if ((outOff + (32 / 2)) > out.length) { - throw new DataLengthException("output buffer too short"); + // BEGIN android-changed + throw new OutputLengthException("output buffer too short"); + // END android-changed } if (forEncryption) diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeEngine.java index d1935ec..c908218 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeEngine.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeEngine.java @@ -2,6 +2,9 @@ package org.bouncycastle.crypto.engines; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; +// BEGIN android-added +import org.bouncycastle.crypto.OutputLengthException; +// END android-added import org.bouncycastle.crypto.params.KeyParameter; /** @@ -99,7 +102,9 @@ public class DESedeEngine if ((outOff + BLOCK_SIZE) > out.length) { - throw new DataLengthException("output buffer too short"); + // BEGIN android-changed + throw new OutputLengthException("output buffer too short"); + // END android-changed } byte[] temp = new byte[BLOCK_SIZE]; diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/macs/HMac.java b/bcprov/src/main/java/org/bouncycastle/crypto/macs/HMac.java index c0c8333..f5b931d 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/macs/HMac.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/macs/HMac.java @@ -7,6 +7,7 @@ import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.ExtendedDigest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.util.Integers; /** * HMAC implementation based on RFC2104 @@ -33,29 +34,29 @@ public class HMac blockLengths = new Hashtable(); // BEGIN android-removed - // blockLengths.put("GOST3411", Integer.valueOf(32)); + // blockLengths.put("GOST3411", Integers.valueOf(32)); // - // blockLengths.put("MD2", Integer.valueOf(16)); - // blockLengths.put("MD4", Integer.valueOf(64)); + // blockLengths.put("MD2", Integers.valueOf(16)); + // blockLengths.put("MD4", Integers.valueOf(64)); // END android-removed - blockLengths.put("MD5", Integer.valueOf(64)); + blockLengths.put("MD5", Integers.valueOf(64)); // BEGIN android-removed - // blockLengths.put("RIPEMD128", Integer.valueOf(64)); - // blockLengths.put("RIPEMD160", Integer.valueOf(64)); + // blockLengths.put("RIPEMD128", Integers.valueOf(64)); + // blockLengths.put("RIPEMD160", Integers.valueOf(64)); // END android-removed - blockLengths.put("SHA-1", Integer.valueOf(64)); + blockLengths.put("SHA-1", Integers.valueOf(64)); // BEGIN android-removed - // blockLengths.put("SHA-224", Integer.valueOf(64)); + // blockLengths.put("SHA-224", Integers.valueOf(64)); // END android-removed - blockLengths.put("SHA-256", Integer.valueOf(64)); - blockLengths.put("SHA-384", Integer.valueOf(128)); - blockLengths.put("SHA-512", Integer.valueOf(128)); + blockLengths.put("SHA-256", Integers.valueOf(64)); + blockLengths.put("SHA-384", Integers.valueOf(128)); + blockLengths.put("SHA-512", Integers.valueOf(128)); // BEGIN android-removed - // blockLengths.put("Tiger", Integer.valueOf(64)); - // blockLengths.put("Whirlpool", Integer.valueOf(64)); + // blockLengths.put("Tiger", Integers.valueOf(64)); + // blockLengths.put("Whirlpool", Integers.valueOf(64)); // END android-removed } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADBlockCipher.java index 3c3bf34..71b7595 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADBlockCipher.java @@ -36,6 +36,24 @@ public interface AEADBlockCipher public BlockCipher getUnderlyingCipher(); /** + * Add a single byte to the associated data check. + * <br>If the implementation supports it, this will be an online operation and will not retain the associated data. + * + * @param in the byte to be processed. + */ + public void processAADByte(byte in); + + /** + * Add a sequence of bytes to the associated data check. + * <br>If the implementation supports it, this will be an online operation and will not retain the associated data. + * + * @param in the input byte array. + * @param inOff the offset into the in array where the data to be processed starts. + * @param len the number of bytes to be processed. + */ + public void processAADBytes(byte[] in, int inOff, int len); + + /** * encrypt/decrypt a single byte. * * @param in the byte to be processed. diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CBCBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CBCBlockCipher.java index 1219f6d..d4800e6 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CBCBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CBCBlockCipher.java @@ -93,7 +93,7 @@ public class CBCBlockCipher { reset(); - // if it;s null key is to be reused. + // if it's null, key is to be reused. if (params != null) { cipher.init(encrypting, params); diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java index bedc3d1..18a3425 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java @@ -25,10 +25,11 @@ public class CCMBlockCipher private int blockSize; private boolean forEncryption; private byte[] nonce; - private byte[] associatedText; + private byte[] initialAssociatedText; private int macSize; private CipherParameters keyParam; private byte[] macBlock; + private ByteArrayOutputStream associatedText = new ByteArrayOutputStream(); private ByteArrayOutputStream data = new ByteArrayOutputStream(); /** @@ -69,7 +70,7 @@ public class CCMBlockCipher AEADParameters param = (AEADParameters)params; nonce = param.getNonce(); - associatedText = param.getAssociatedText(); + initialAssociatedText = param.getAssociatedText(); macSize = param.getMacSize() / 8; keyParam = param.getKey(); } @@ -78,7 +79,7 @@ public class CCMBlockCipher ParametersWithIV param = (ParametersWithIV)params; nonce = param.getIV(); - associatedText = null; + initialAssociatedText = null; macSize = macBlock.length / 2; keyParam = param.getParameters(); } @@ -93,6 +94,17 @@ public class CCMBlockCipher return cipher.getAlgorithmName() + "/CCM"; } + public void processAADByte(byte in) + { + associatedText.write(in); + } + + public void processAADBytes(byte[] in, int inOff, int len) + { + // TODO: Process AAD online + associatedText.write(in, inOff, len); + } + public int processByte(byte in, byte[] out, int outOff) throws DataLengthException, IllegalStateException { @@ -125,6 +137,7 @@ public class CCMBlockCipher public void reset() { cipher.reset(); + associatedText.reset(); data.reset(); } @@ -150,60 +163,62 @@ public class CCMBlockCipher public int getOutputSize(int len) { + int totalData = len + data.size(); + if (forEncryption) { - return data.size() + len + macSize; - } - else - { - return data.size() + len - macSize; + return totalData + macSize; } + + return totalData < macSize ? 0 : totalData - macSize; } public byte[] processPacket(byte[] in, int inOff, int inLen) throws IllegalStateException, InvalidCipherTextException { + // TODO: handle null keyParam (e.g. via RepeatedKeySpec) + // Need to keep the CTR and CBC Mac parts around and reset if (keyParam == null) { throw new IllegalStateException("CCM cipher unitialized."); } - + BlockCipher ctrCipher = new SICBlockCipher(cipher); byte[] iv = new byte[blockSize]; byte[] out; iv[0] = (byte)(((15 - nonce.length) - 1) & 0x7); - + System.arraycopy(nonce, 0, iv, 1, nonce.length); - + ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv)); - + if (forEncryption) { int index = inOff; int outOff = 0; - + out = new byte[inLen + macSize]; - + calculateMac(in, inOff, inLen, macBlock); - + ctrCipher.processBlock(macBlock, 0, macBlock, 0); // S0 - + while (index < inLen - blockSize) // S1... { ctrCipher.processBlock(in, index, out, outOff); outOff += blockSize; index += blockSize; } - + byte[] block = new byte[blockSize]; - + System.arraycopy(in, index, block, 0, inLen - index); - + ctrCipher.processBlock(block, 0, block, 0); - + System.arraycopy(block, 0, out, outOff, inLen - index); - + outOff += inLen - index; System.arraycopy(macBlock, 0, out, outOff, out.length - outOff); @@ -212,49 +227,49 @@ public class CCMBlockCipher { int index = inOff; int outOff = 0; - + out = new byte[inLen - macSize]; - + System.arraycopy(in, inOff + inLen - macSize, macBlock, 0, macSize); - + ctrCipher.processBlock(macBlock, 0, macBlock, 0); - + for (int i = macSize; i != macBlock.length; i++) { macBlock[i] = 0; } - + while (outOff < out.length - blockSize) { ctrCipher.processBlock(in, index, out, outOff); outOff += blockSize; index += blockSize; } - + byte[] block = new byte[blockSize]; - + System.arraycopy(in, index, block, 0, out.length - outOff); - + ctrCipher.processBlock(block, 0, block, 0); - + System.arraycopy(block, 0, out, outOff, out.length - outOff); - + byte[] calculatedMacBlock = new byte[blockSize]; - + calculateMac(out, 0, out.length, calculatedMacBlock); - + if (!Arrays.constantTimeAreEqual(macBlock, calculatedMacBlock)) { throw new InvalidCipherTextException("mac check in CCM failed"); } } - + return out; } - + private int calculateMac(byte[] data, int dataOff, int dataLen, byte[] macBlock) { - Mac cMac = new CBCBlockCipherMac(cipher, macSize * 8); + Mac cMac = new CBCBlockCipherMac(cipher, macSize * 8); cMac.init(keyParam); @@ -292,10 +307,11 @@ public class CCMBlockCipher { int extra; - if (associatedText.length < ((1 << 16) - (1 << 8))) + int textLength = getAssociatedTextLength(); + if (textLength < ((1 << 16) - (1 << 8))) { - cMac.update((byte)(associatedText.length >> 8)); - cMac.update((byte)associatedText.length); + cMac.update((byte)(textLength >> 8)); + cMac.update((byte)textLength); extra = 2; } @@ -303,17 +319,25 @@ public class CCMBlockCipher { cMac.update((byte)0xff); cMac.update((byte)0xfe); - cMac.update((byte)(associatedText.length >> 24)); - cMac.update((byte)(associatedText.length >> 16)); - cMac.update((byte)(associatedText.length >> 8)); - cMac.update((byte)associatedText.length); + cMac.update((byte)(textLength >> 24)); + cMac.update((byte)(textLength >> 16)); + cMac.update((byte)(textLength >> 8)); + cMac.update((byte)textLength); extra = 6; } - - cMac.update(associatedText, 0, associatedText.length); - - extra = (extra + associatedText.length) % 16; + + if (initialAssociatedText != null) + { + cMac.update(initialAssociatedText, 0, initialAssociatedText.length); + } + if (associatedText.size() > 0) + { + byte[] tmp = associatedText.toByteArray(); + cMac.update(tmp, 0, tmp.length); + } + + extra = (extra + textLength) % 16; if (extra != 0) { for (int i = 0; i != 16 - extra; i++) @@ -331,8 +355,13 @@ public class CCMBlockCipher return cMac.doFinal(macBlock, 0); } + private int getAssociatedTextLength() + { + return associatedText.size() + ((initialAssociatedText == null) ? 0 : initialAssociatedText.length); + } + private boolean hasAssociatedText() { - return associatedText != null && associatedText.length != 0; + return getAssociatedTextLength() > 0; } } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java index 0af49f4..d0fb9bb 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java @@ -68,36 +68,40 @@ public class CFBBlockCipher if (params instanceof ParametersWithIV) { - ParametersWithIV ivParam = (ParametersWithIV)params; - byte[] iv = ivParam.getIV(); + ParametersWithIV ivParam = (ParametersWithIV)params; + byte[] iv = ivParam.getIV(); - if (iv.length < IV.length) + if (iv.length < IV.length) + { + // prepend the supplied IV with zeros (per FIPS PUB 81) + System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length); + for (int i = 0; i < IV.length - iv.length; i++) { - // prepend the supplied IV with zeros (per FIPS PUB 81) - System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length); - for (int i = 0; i < IV.length - iv.length; i++) - { - IV[i] = 0; - } - } - else - { - System.arraycopy(iv, 0, IV, 0, IV.length); + IV[i] = 0; } + } + else + { + System.arraycopy(iv, 0, IV, 0, IV.length); + } - reset(); + reset(); - // if null it's an IV changed only. - if (ivParam.getParameters() != null) - { - cipher.init(true, ivParam.getParameters()); - } + // if null it's an IV changed only. + if (ivParam.getParameters() != null) + { + cipher.init(true, ivParam.getParameters()); + } } else { - reset(); + reset(); + // if it's null, key is to be reused. + if (params != null) + { cipher.init(true, params); + } } } 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 7c98efa..9e617ec 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java @@ -4,7 +4,9 @@ import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.modes.gcm.GCMExponentiator; import org.bouncycastle.crypto.modes.gcm.GCMMultiplier; +import org.bouncycastle.crypto.modes.gcm.Tables1kGCMExponentiator; import org.bouncycastle.crypto.modes.gcm.Tables8kGCMMultiplier; import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; @@ -20,28 +22,31 @@ public class GCMBlockCipher implements AEADBlockCipher { private static final int BLOCK_SIZE = 16; - private static final byte[] ZEROES = new byte[BLOCK_SIZE]; // not final due to a compiler bug private BlockCipher cipher; private GCMMultiplier multiplier; + private GCMExponentiator exp; // These fields are set by init and not modified by processing private boolean forEncryption; private int macSize; private byte[] nonce; - private byte[] A; + private byte[] initialAssociatedText; private byte[] H; - private byte[] initS; private byte[] J0; // These fields are modified during processing private byte[] bufBlock; private byte[] macBlock; - private byte[] S; + private byte[] S, S_at, S_atPre; private byte[] counter; private int bufOff; private long totalLength; + private byte[] atBlock; + private int atBlockPos; + private long atLength; + private long atLengthPre; public GCMBlockCipher(BlockCipher c) { @@ -82,14 +87,14 @@ public class GCMBlockCipher this.forEncryption = forEncryption; this.macBlock = null; - KeyParameter keyParam; + KeyParameter keyParam; if (params instanceof AEADParameters) { AEADParameters param = (AEADParameters)params; nonce = param.getNonce(); - A = param.getAssociatedText(); + initialAssociatedText = param.getAssociatedText(); int macSizeBits = param.getMacSize(); if (macSizeBits < 96 || macSizeBits > 128 || macSizeBits % 8 != 0) @@ -105,7 +110,7 @@ public class GCMBlockCipher ParametersWithIV param = (ParametersWithIV)params; nonce = param.getIV(); - A = null; + initialAssociatedText = null; macSize = 16; keyParam = (KeyParameter)param.getParameters(); } @@ -122,48 +127,54 @@ public class GCMBlockCipher throw new IllegalArgumentException("IV must be at least 1 byte"); } - if (A == null) - { - // Avoid lots of null checks - A = new byte[0]; - } + // TODO This should be configurable by init parameters + // (but must be 16 if nonce length not 12) (BLOCK_SIZE?) +// this.tagLength = 16; // Cipher always used in forward mode // if keyParam is null we're reusing the last key. if (keyParam != null) { cipher.init(true, keyParam); - } - // TODO This should be configurable by init parameters - // (but must be 16 if nonce length not 12) (BLOCK_SIZE?) -// this.tagLength = 16; + this.H = new byte[BLOCK_SIZE]; + cipher.processBlock(H, 0, H, 0); - this.H = new byte[BLOCK_SIZE]; - cipher.processBlock(ZEROES, 0, H, 0); - multiplier.init(H); + // GCMMultiplier tables don't change unless the key changes (and are expensive to init) + multiplier.init(H); + exp = null; + } - this.initS = gHASH(A); + this.J0 = new byte[BLOCK_SIZE]; if (nonce.length == 12) { - this.J0 = new byte[16]; System.arraycopy(nonce, 0, J0, 0, nonce.length); - this.J0[15] = 0x01; + this.J0[BLOCK_SIZE - 1] = 0x01; } else { - this.J0 = gHASH(nonce); - byte[] X = new byte[16]; - packLength((long)nonce.length * 8, X, 8); - xor(this.J0, X); - multiplier.multiplyH(this.J0); + gHASH(J0, nonce, nonce.length); + byte[] X = new byte[BLOCK_SIZE]; + Pack.longToBigEndian((long)nonce.length * 8, X, 8); + gHASHBlock(J0, X); } - this.S = Arrays.clone(initS); + this.S = new byte[BLOCK_SIZE]; + this.S_at = new byte[BLOCK_SIZE]; + this.S_atPre = new byte[BLOCK_SIZE]; + this.atBlock = new byte[BLOCK_SIZE]; + this.atBlockPos = 0; + this.atLength = 0; + this.atLengthPre = 0; this.counter = Arrays.clone(J0); this.bufOff = 0; this.totalLength = 0; + + if (initialAssociatedText != null) + { + processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); + } } public byte[] getMac() @@ -173,23 +184,88 @@ public class GCMBlockCipher public int getOutputSize(int len) { + int totalData = len + bufOff; + if (forEncryption) { - return len + bufOff + macSize; + return totalData + macSize; } - return len + bufOff - macSize; + return totalData < macSize ? 0 : totalData - macSize; } public int getUpdateOutputSize(int len) { - return ((len + bufOff) / BLOCK_SIZE) * BLOCK_SIZE; + int totalData = len + bufOff; + if (!forEncryption) + { + if (totalData < macSize) + { + return 0; + } + totalData -= macSize; + } + return totalData - totalData % BLOCK_SIZE; + } + + public void processAADByte(byte in) + { + atBlock[atBlockPos] = in; + if (++atBlockPos == BLOCK_SIZE) + { + // Hash each block as it fills + gHASHBlock(S_at, atBlock); + atBlockPos = 0; + atLength += BLOCK_SIZE; + } + } + + public void processAADBytes(byte[] in, int inOff, int len) + { + for (int i = 0; i < len; ++i) + { + atBlock[atBlockPos] = in[inOff + i]; + if (++atBlockPos == BLOCK_SIZE) + { + // Hash each block as it fills + gHASHBlock(S_at, atBlock); + atBlockPos = 0; + atLength += BLOCK_SIZE; + } + } + } + + private void initCipher() + { + if (atLength > 0) + { + System.arraycopy(S_at, 0, S_atPre, 0, BLOCK_SIZE); + atLengthPre = atLength; + } + + // Finish hash for partial AAD block + if (atBlockPos > 0) + { + gHASHPartial(S_atPre, atBlock, 0, atBlockPos); + atLengthPre += atBlockPos; + } + + if (atLengthPre > 0) + { + System.arraycopy(S_atPre, 0, S, 0, BLOCK_SIZE); + } } public int processByte(byte in, byte[] out, int outOff) throws DataLengthException { - return process(in, out, outOff); + bufBlock[bufOff] = in; + if (++bufOff == bufBlock.length) + { + outputBlock(out, outOff); + return BLOCK_SIZE; + } + return 0; } public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) @@ -197,21 +273,12 @@ public class GCMBlockCipher { int resultLen = 0; - for (int i = 0; i != len; i++) + for (int i = 0; i < len; ++i) { -// resultLen += process(in[inOff + i], out, outOff + resultLen); - bufBlock[bufOff++] = in[inOff + i]; - - if (bufOff == bufBlock.length) + bufBlock[bufOff] = in[inOff + i]; + if (++bufOff == bufBlock.length) { - gCTRBlock(bufBlock, BLOCK_SIZE, out, outOff + resultLen); - if (!forEncryption) - { - System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize); - } -// bufOff = 0; - bufOff = bufBlock.length - BLOCK_SIZE; -// return bufBlock.Length; + outputBlock(out, outOff + resultLen); resultLen += BLOCK_SIZE; } } @@ -219,30 +286,32 @@ public class GCMBlockCipher return resultLen; } - private int process(byte in, byte[] out, int outOff) - throws DataLengthException + private void outputBlock(byte[] output, int offset) { - bufBlock[bufOff++] = in; - - if (bufOff == bufBlock.length) + if (totalLength == 0) { - gCTRBlock(bufBlock, BLOCK_SIZE, out, outOff); - if (!forEncryption) - { - System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize); - } -// bufOff = 0; - bufOff = bufBlock.length - BLOCK_SIZE; -// return bufBlock.length; - return BLOCK_SIZE; + initCipher(); + } + gCTRBlock(bufBlock, output, offset); + if (forEncryption) + { + bufOff = 0; + } + else + { + System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize); + bufOff = macSize; } - - return 0; } public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException { + if (totalLength == 0) + { + initCipher(); + } + int extra = bufOff; if (!forEncryption) { @@ -255,18 +324,57 @@ public class GCMBlockCipher if (extra > 0) { - byte[] tmp = new byte[BLOCK_SIZE]; - System.arraycopy(bufBlock, 0, tmp, 0, extra); - gCTRBlock(tmp, extra, out, outOff); + gCTRPartial(bufBlock, 0, extra, out, outOff); + } + + atLength += atBlockPos; + + if (atLength > atLengthPre) + { + /* + * Some AAD was sent after the cipher started. We determine the difference b/w the hash value + * we actually used when the cipher started (S_atPre) and the final hash value calculated (S_at). + * Then we carry this difference forward by multiplying by H^c, where c is the number of (full or + * partial) cipher-text blocks produced, and adjust the current hash. + */ + + // Finish hash for partial AAD block + if (atBlockPos > 0) + { + gHASHPartial(S_at, atBlock, 0, atBlockPos); + } + + // Find the difference between the AAD hashes + if (atLengthPre > 0) + { + xor(S_at, S_atPre); + } + + // Number of cipher-text blocks produced + long c = ((totalLength * 8) + 127) >>> 7; + + // Calculate the adjustment factor + byte[] H_c = new byte[16]; + if (exp == null) + { + exp = new Tables1kGCMExponentiator(); + exp.init(H); + } + exp.exponentiateX(c, H_c); + + // Carry the difference forward + multiply(S_at, H_c); + + // Adjust the current hash + xor(S, S_at); } // Final gHASH - byte[] X = new byte[16]; - packLength((long)A.length * 8, X, 0); - packLength(totalLength * 8, X, 8); + byte[] X = new byte[BLOCK_SIZE]; + Pack.longToBigEndian(atLength * 8, X, 0); + Pack.longToBigEndian(totalLength * 8, X, 8); - xor(S, X); - multiplier.multiplyH(S); + gHASHBlock(S, X); // TODO Fix this if tagLength becomes configurable // T = MSBt(GCTRk(J0,S)) @@ -310,7 +418,15 @@ public class GCMBlockCipher private void reset( boolean clearMac) { - S = Arrays.clone(initS); + cipher.reset(); + + S = new byte[BLOCK_SIZE]; + S_at = new byte[BLOCK_SIZE]; + S_atPre = new byte[BLOCK_SIZE]; + atBlock = new byte[BLOCK_SIZE]; + atBlockPos = 0; + atLength = 0; + atLengthPre = 0; counter = Arrays.clone(J0); bufOff = 0; totalLength = 0; @@ -325,12 +441,59 @@ public class GCMBlockCipher macBlock = null; } - cipher.reset(); + if (initialAssociatedText != null) + { + processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); + } + } + + private void gCTRBlock(byte[] block, byte[] out, int outOff) + { + byte[] tmp = getNextCounterBlock(); + + xor(tmp, block); + System.arraycopy(tmp, 0, out, outOff, BLOCK_SIZE); + + gHASHBlock(S, forEncryption ? tmp : block); + + totalLength += BLOCK_SIZE; + } + + private void gCTRPartial(byte[] buf, int off, int len, byte[] out, int outOff) + { + byte[] tmp = getNextCounterBlock(); + + xor(tmp, buf, off, len); + System.arraycopy(tmp, 0, out, outOff, len); + + gHASHPartial(S, forEncryption ? tmp : buf, 0, len); + + totalLength += len; + } + + private void gHASH(byte[] Y, byte[] b, int len) + { + for (int pos = 0; pos < len; pos += BLOCK_SIZE) + { + int num = Math.min(len - pos, BLOCK_SIZE); + gHASHPartial(Y, b, pos, num); + } + } + + private void gHASHBlock(byte[] Y, byte[] b) + { + xor(Y, b); + multiplier.multiplyH(Y); + } + + private void gHASHPartial(byte[] Y, byte[] b, int off, int len) + { + xor(Y, b, off, len); + multiplier.multiplyH(Y); } - private void gCTRBlock(byte[] buf, int bufCount, byte[] out, int outOff) + private byte[] getNextCounterBlock() { -// inc(counter); for (int i = 15; i >= 12; --i) { byte b = (byte)((counter[i] + 1) & 0xff); @@ -343,68 +506,56 @@ public class GCMBlockCipher } byte[] tmp = new byte[BLOCK_SIZE]; + // TODO Sure would be nice if ciphers could operate on int[] cipher.processBlock(counter, 0, tmp, 0); + return tmp; + } - byte[] hashBytes; - if (forEncryption) - { - System.arraycopy(ZEROES, bufCount, tmp, bufCount, BLOCK_SIZE - bufCount); - hashBytes = tmp; - } - else - { - hashBytes = buf; - } + private static void multiply(byte[] block, byte[] val) + { + byte[] tmp = Arrays.clone(block); + byte[] c = new byte[16]; - for (int i = bufCount - 1; i >= 0; --i) + for (int i = 0; i < 16; ++i) { - tmp[i] ^= buf[i]; - out[outOff + i] = tmp[i]; - } + byte bits = val[i]; + for (int j = 7; j >= 0; --j) + { + if ((bits & (1 << j)) != 0) + { + xor(c, tmp); + } -// gHASHBlock(hashBytes); - xor(S, hashBytes); - multiplier.multiplyH(S); + boolean lsb = (tmp[15] & 1) != 0; + shiftRight(tmp); + if (lsb) + { + // R = new byte[]{ 0xe1, ... }; +// xor(v, R); + tmp[0] ^= (byte)0xe1; + } + } + } - totalLength += bufCount; + System.arraycopy(c, 0, block, 0, 16); } - private byte[] gHASH(byte[] b) + private static void shiftRight(byte[] block) { - byte[] Y = new byte[16]; - - for (int pos = 0; pos < b.length; pos += 16) + int i = 0; + int bit = 0; + for (;;) { - byte[] X = new byte[16]; - int num = Math.min(b.length - pos, 16); - System.arraycopy(b, pos, X, 0, num); - xor(Y, X); - multiplier.multiplyH(Y); + int b = block[i] & 0xff; + block[i] = (byte) ((b >>> 1) | bit); + if (++i == 16) + { + break; + } + bit = (b & 1) << 7; } - - return Y; } -// private void gHASHBlock(byte[] block) -// { -// xor(S, block); -// multiplier.multiplyH(S); -// } - -// private static void inc(byte[] block) -// { -// for (int i = 15; i >= 12; --i) -// { -// byte b = (byte)((block[i] + 1) & 0xff); -// block[i] = b; -// -// if (b != 0) -// { -// break; -// } -// } -// } - private static void xor(byte[] block, byte[] val) { for (int i = 15; i >= 0; --i) @@ -413,9 +564,11 @@ public class GCMBlockCipher } } - private static void packLength(long count, byte[] bs, int off) + private static void xor(byte[] block, byte[] val, int off, int len) { - Pack.intToBigEndian((int)(count >>> 32), bs, off); - Pack.intToBigEndian((int)count, bs, off + 4); + while (len-- > 0) + { + block[len] ^= val[off + len]; + } } } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java index 728a2e7..5297698 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java @@ -65,36 +65,40 @@ public class OFBBlockCipher { if (params instanceof ParametersWithIV) { - ParametersWithIV ivParam = (ParametersWithIV)params; - byte[] iv = ivParam.getIV(); - - if (iv.length < IV.length) - { - // prepend the supplied IV with zeros (per FIPS PUB 81) - System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length); - for (int i = 0; i < IV.length - iv.length; i++) - { - IV[i] = 0; - } - } - else - { - System.arraycopy(iv, 0, IV, 0, IV.length); - } - - reset(); - - // if null it's an IV changed only. - if (ivParam.getParameters() != null) + ParametersWithIV ivParam = (ParametersWithIV)params; + byte[] iv = ivParam.getIV(); + + if (iv.length < IV.length) + { + // prepend the supplied IV with zeros (per FIPS PUB 81) + System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length); + for (int i = 0; i < IV.length - iv.length; i++) { - cipher.init(true, ivParam.getParameters()); + IV[i] = 0; } + } + else + { + System.arraycopy(iv, 0, IV, 0, IV.length); + } + + reset(); + + // if null it's an IV changed only. + if (ivParam.getParameters() != null) + { + cipher.init(true, ivParam.getParameters()); + } } else { - reset(); + reset(); + // if it's null, key is to be reused. + if (params != null) + { cipher.init(true, params); + } } } 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 af9f18d..da8c4ae 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java @@ -9,7 +9,8 @@ import org.bouncycastle.crypto.params.ParametersWithIV; * Implements the Segmented Integer Counter (SIC) mode on top of a simple * block cipher. This mode is also known as CTR mode. */ -public class SICBlockCipher implements BlockCipher +public class SICBlockCipher + implements BlockCipher { private final BlockCipher cipher; private final int blockSize; @@ -94,22 +95,10 @@ public class SICBlockCipher implements BlockCipher out[outOff + i] = (byte)(counterOut[i] ^ in[inOff + i]); } - int carry = 1; - - for (int i = counter.length - 1; i >= 0; i--) + // increment counter by 1. + for (int i = counter.length - 1; i >= 0 && ++counter[i] == 0; i--) { - int x = (counter[i] & 0xff) + carry; - - if (x > 0xff) - { - carry = 1; - } - else - { - carry = 0; - } - - counter[i] = (byte)x; + ; // do nothing - pre-increment and test for 0 in counter does the job. } return counter.length; diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMExponentiator.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMExponentiator.java new file mode 100644 index 0000000..e1cc5c7 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMExponentiator.java @@ -0,0 +1,7 @@ +package org.bouncycastle.crypto.modes.gcm; + +public interface GCMExponentiator +{ + void init(byte[] x); + void exponentiateX(long pow, byte[] output); +} 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 ce02be4..4875301 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 @@ -19,14 +19,23 @@ abstract class GCMUtil return tmp; } + static byte[] asBytes(int[] ns) + { + byte[] output = new byte[16]; + Pack.intToBigEndian(ns, output, 0); + return output; + } + static int[] asInts(byte[] bs) { - int[] us = new int[4]; - us[0] = Pack.bigEndianToInt(bs, 0); - us[1] = Pack.bigEndianToInt(bs, 4); - us[2] = Pack.bigEndianToInt(bs, 8); - us[3] = Pack.bigEndianToInt(bs, 12); - return us; + int[] output = new int[4]; + Pack.bigEndianToInt(bs, 0, output); + return output; + } + + static void asInts(byte[] bs, int[] output) + { + Pack.bigEndianToInt(bs, 0, output); } static void multiply(byte[] block, byte[] val) @@ -71,6 +80,17 @@ abstract class GCMUtil } } + static void multiplyP(int[] x, int[] output) + { + boolean lsb = (x[3] & 1) != 0; + shiftRight(x, output); + if (lsb) + { + output[0] ^= 0xe1000000; + } + } + + // P is the value with only bit i=1 set static void multiplyP8(int[] x) { // for (int i = 8; i != 0; --i) @@ -89,6 +109,19 @@ abstract class GCMUtil } } + static void multiplyP8(int[] x, int[] output) + { + int lsw = x[3]; + shiftRightN(x, 8, output); + for (int i = 7; i >= 0; --i) + { + if ((lsw & (1 << i)) != 0) + { + output[0] ^= (0xe1000000 >>> (7 - i)); + } + } + } + static void shiftRight(byte[] block) { int i = 0; @@ -105,6 +138,22 @@ abstract class GCMUtil } } + static void shiftRight(byte[] block, byte[] output) + { + int i = 0; + int bit = 0; + for (;;) + { + int b = block[i] & 0xff; + output[i] = (byte) ((b >>> 1) | bit); + if (++i == 16) + { + break; + } + bit = (b & 1) << 7; + } + } + static void shiftRight(int[] block) { int i = 0; @@ -121,6 +170,22 @@ abstract class GCMUtil } } + static void shiftRight(int[] block, int[] output) + { + int i = 0; + int bit = 0; + for (;;) + { + int b = block[i]; + output[i] = (b >>> 1) | bit; + if (++i == 4) + { + break; + } + bit = b << 31; + } + } + static void shiftRightN(int[] block, int n) { int i = 0; @@ -137,6 +202,22 @@ abstract class GCMUtil } } + static void shiftRightN(int[] block, int n, int[] output) + { + int i = 0; + int bits = 0; + for (;;) + { + int b = block[i]; + output[i] = (b >>> n) | bits; + if (++i == 4) + { + break; + } + bits = b << (32 - n); + } + } + static void xor(byte[] block, byte[] val) { for (int i = 15; i >= 0; --i) @@ -145,6 +226,22 @@ abstract class GCMUtil } } + static void xor(byte[] block, byte[] val, int off, int len) + { + while (len-- > 0) + { + block[len] ^= val[off + len]; + } + } + + static void xor(byte[] block, byte[] val, byte[] output) + { + for (int i = 15; i >= 0; --i) + { + output[i] = (byte)(block[i] ^ val[i]); + } + } + static void xor(int[] block, int[] val) { for (int i = 3; i >= 0; --i) @@ -152,4 +249,12 @@ abstract class GCMUtil block[i] ^= val[i]; } } + + static void xor(int[] block, int[] val, int[] output) + { + for (int i = 3; i >= 0; --i) + { + output[i] = block[i] ^ val[i]; + } + } } diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java new file mode 100644 index 0000000..a051208 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java @@ -0,0 +1,57 @@ +package org.bouncycastle.crypto.modes.gcm; + +import java.util.Vector; + +import org.bouncycastle.util.Arrays; + +public class Tables1kGCMExponentiator implements GCMExponentiator +{ + // A lookup table of the power-of-two powers of 'x' + // - lookupPowX2[i] = x^(2^i) + private Vector lookupPowX2; + + public void init(byte[] x) + { + if (lookupPowX2 != null && Arrays.areEqual(x, (byte[])lookupPowX2.elementAt(0))) + { + return; + } + + lookupPowX2 = new Vector(8); + lookupPowX2.addElement(Arrays.clone(x)); + } + + public void exponentiateX(long pow, byte[] output) + { + byte[] y = GCMUtil.oneAsBytes(); + int bit = 0; + while (pow > 0) + { + if ((pow & 1L) != 0) + { + ensureAvailable(bit); + GCMUtil.multiply(y, (byte[])lookupPowX2.elementAt(bit)); + } + ++bit; + pow >>>= 1; + } + + System.arraycopy(y, 0, output, 0, 16); + } + + private void ensureAvailable(int bit) + { + int count = lookupPowX2.size(); + if (count <= bit) + { + byte[] tmp = (byte[])lookupPowX2.elementAt(count - 1); + do + { + tmp = Arrays.clone(tmp); + GCMUtil.multiply(tmp, tmp); + lookupPowX2.addElement(tmp); + } + while (++count <= bit); + } + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java index 9d21cf0..8535db5 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java @@ -1,41 +1,40 @@ package org.bouncycastle.crypto.modes.gcm; import org.bouncycastle.crypto.util.Pack; +import org.bouncycastle.util.Arrays; -public class Tables8kGCMMultiplier implements GCMMultiplier +public class Tables8kGCMMultiplier implements GCMMultiplier { - private final int[][][] M = new int[32][16][]; + private byte[] H; + private int[][][] M; public void init(byte[] H) { - M[0][0] = new int[4]; - M[1][0] = new int[4]; - M[1][8] = GCMUtil.asInts(H); - - for (int j = 4; j >= 1; j >>= 1) + if (M == null) { - int[] tmp = new int[4]; - System.arraycopy(M[1][j + j], 0, tmp, 0, 4); - - GCMUtil.multiplyP(tmp); - M[1][j] = tmp; + M = new int[32][16][4]; } - + else if (Arrays.areEqual(this.H, H)) { - int[] tmp = new int[4]; - System.arraycopy(M[1][1], 0, tmp, 0, 4); - - GCMUtil.multiplyP(tmp); - M[0][8] = tmp; + return; } + this.H = Arrays.clone(H); + + // M[0][0] is ZEROES; + // M[1][0] is ZEROES; + GCMUtil.asInts(H, M[1][8]); + for (int j = 4; j >= 1; j >>= 1) { - int[] tmp = new int[4]; - System.arraycopy(M[0][j + j], 0, tmp, 0, 4); + GCMUtil.multiplyP(M[1][j + j], M[1][j]); + } + + GCMUtil.multiplyP(M[1][1], M[0][8]); - GCMUtil.multiplyP(tmp); - M[0][j] = tmp; + for (int j = 4; j >= 1; j >>= 1) + { + GCMUtil.multiplyP(M[0][j + j], M[0][j]); } int i = 0; @@ -45,11 +44,7 @@ public class Tables8kGCMMultiplier implements GCMMultiplier { for (int k = 1; k < j; ++k) { - int[] tmp = new int[4]; - System.arraycopy(M[i][j], 0, tmp, 0, 4); - - GCMUtil.xor(tmp, M[i][k]); - M[i][j + k] = tmp; + GCMUtil.xor(M[i][j], M[i][k], M[i][j + k]); } } @@ -60,14 +55,10 @@ public class Tables8kGCMMultiplier implements GCMMultiplier if (i > 1) { - M[i][0] = new int[4]; + // M[i][0] is ZEROES; for(int j = 8; j > 0; j >>= 1) { - int[] tmp = new int[4]; - System.arraycopy(M[i - 2][j], 0, tmp, 0, 4); - - GCMUtil.multiplyP8(tmp); - M[i][j] = tmp; + GCMUtil.multiplyP8(M[i - 2][j], M[i][j]); } } } @@ -96,4 +87,4 @@ public class Tables8kGCMMultiplier implements GCMMultiplier Pack.intToBigEndian(z, x, 0); } -} +}
\ No newline at end of file diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java index ec412b9..ee3fd60 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java @@ -5,6 +5,7 @@ import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.params.ParametersWithRandom; /** @@ -191,7 +192,7 @@ public class PaddedBufferedBlockCipher { if ((outOff + length) > out.length) { - throw new DataLengthException("output buffer too short"); + throw new OutputLengthException("output buffer too short"); } } @@ -254,7 +255,7 @@ public class PaddedBufferedBlockCipher { reset(); - throw new DataLengthException("output buffer too short"); + throw new OutputLengthException("output buffer too short"); } resultLen = cipher.processBlock(buf, 0, out, outOff); diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/AEADParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/AEADParameters.java index b60ef40..9a9272b 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/params/AEADParameters.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/AEADParameters.java @@ -16,7 +16,19 @@ public class AEADParameters * @param key key to be used by underlying cipher * @param macSize macSize in bits * @param nonce nonce to be used - * @param associatedText associated text, if any + */ + public AEADParameters(KeyParameter key, int macSize, byte[] nonce) + { + this(key, macSize, nonce, null); + } + + /** + * Base constructor. + * + * @param key key to be used by underlying cipher + * @param macSize macSize in bits + * @param nonce nonce to be used + * @param associatedText initial associated text, if any */ public AEADParameters(KeyParameter key, int macSize, byte[] nonce, byte[] associatedText) { diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java b/bcprov/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java index 8ddfac8..394f2c2 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java @@ -6,10 +6,10 @@ import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.nist.NISTNamedCurves; // BEGIN android-removed // import org.bouncycastle.asn1.oiw.ElGamalParameter; @@ -98,7 +98,7 @@ public class PrivateKeyFactory else if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.dhKeyAgreement)) { DHParameter params = DHParameter.getInstance(algId.getParameters()); - DERInteger derX = (DERInteger)keyInfo.parsePrivateKey(); + ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey(); BigInteger lVal = params.getL(); int l = lVal == null ? 0 : lVal.intValue(); @@ -110,7 +110,7 @@ public class PrivateKeyFactory // else if (algId.getAlgorithm().equals(OIWObjectIdentifiers.elGamalAlgorithm)) // { // ElGamalParameter params = new ElGamalParameter((ASN1Sequence)algId.getParameters()); - // DERInteger derX = (DERInteger)keyInfo.parsePrivateKey(); + // ASN1Integer = (ASN1Integer)keyInfo.parsePrivateKey(); // // return new ElGamalPrivateKeyParameters(derX.getValue(), new ElGamalParameters( // params.getP(), params.getG())); @@ -118,7 +118,7 @@ public class PrivateKeyFactory // END android-removed else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_dsa)) { - DERInteger derX = (DERInteger)keyInfo.parsePrivateKey(); + ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey(); ASN1Encodable de = algId.getParameters(); DSAParameters parameters = null; diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java b/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java index 05520f0..6a5c88e 100644 --- a/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java +++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java @@ -6,11 +6,11 @@ import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.nist.NISTNamedCurves; // BEGIN android-removed @@ -133,7 +133,7 @@ public class PublicKeyFactory else if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.dhKeyAgreement)) { DHParameter params = DHParameter.getInstance(algId.getParameters()); - DERInteger derY = (DERInteger)keyInfo.parsePublicKey(); + ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); BigInteger lVal = params.getL(); int l = lVal == null ? 0 : lVal.intValue(); @@ -145,7 +145,7 @@ public class PublicKeyFactory // else if (algId.getAlgorithm().equals(OIWObjectIdentifiers.elGamalAlgorithm)) // { // ElGamalParameter params = new ElGamalParameter((ASN1Sequence)algId.getParameters()); - // DERInteger derY = (DERInteger)keyInfo.parsePublicKey(); + // ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); // // return new ElGamalPublicKeyParameters(derY.getValue(), new ElGamalParameters( // params.getP(), params.getG())); @@ -154,7 +154,7 @@ public class PublicKeyFactory else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_dsa) || algId.getAlgorithm().equals(OIWObjectIdentifiers.dsaWithSHA1)) { - DERInteger derY = (DERInteger)keyInfo.parsePublicKey(); + ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); ASN1Encodable de = algId.getParameters(); DSAParameters parameters = null; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/DefaultJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/DefaultJcaJceHelper.java index 807bdfd..6a7b4e2 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/DefaultJcaJceHelper.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/DefaultJcaJceHelper.java @@ -15,6 +15,7 @@ import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKeyFactory; public class DefaultJcaJceHelper implements JcaJceHelper @@ -62,6 +63,12 @@ public class DefaultJcaJceHelper return KeyFactory.getInstance(algorithm); } + public SecretKeyFactory createSecretKeyFactory(String algorithm) + throws NoSuchAlgorithmException + { + return SecretKeyFactory.getInstance(algorithm); + } + public KeyPairGenerator createKeyPairGenerator(String algorithm) throws NoSuchAlgorithmException { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/JcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/JcaJceHelper.java index d8a4900..645b440 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/JcaJceHelper.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/JcaJceHelper.java @@ -16,6 +16,7 @@ import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKeyFactory; public interface JcaJceHelper { @@ -41,6 +42,9 @@ public interface JcaJceHelper KeyFactory createKeyFactory(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; + SecretKeyFactory createSecretKeyFactory(String algorithm) + throws NoSuchAlgorithmException, NoSuchProviderException; + KeyPairGenerator createKeyPairGenerator(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException; diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/NamedJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/NamedJcaJceHelper.java index 9abf52d..03f1006 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/NamedJcaJceHelper.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/NamedJcaJceHelper.java @@ -16,6 +16,7 @@ import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKeyFactory; public class NamedJcaJceHelper implements JcaJceHelper @@ -70,6 +71,12 @@ public class NamedJcaJceHelper return KeyFactory.getInstance(algorithm, providerName); } + public SecretKeyFactory createSecretKeyFactory(String algorithm) + throws NoSuchAlgorithmException, NoSuchProviderException + { + return SecretKeyFactory.getInstance(algorithm, providerName); + } + public KeyPairGenerator createKeyPairGenerator(String algorithm) throws NoSuchAlgorithmException, NoSuchProviderException { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/ProviderJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/ProviderJcaJceHelper.java index 83ff765..90a8f68 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/ProviderJcaJceHelper.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/ProviderJcaJceHelper.java @@ -16,6 +16,7 @@ import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKeyFactory; public class ProviderJcaJceHelper implements JcaJceHelper @@ -70,6 +71,12 @@ public class ProviderJcaJceHelper return KeyFactory.getInstance(algorithm, provider); } + public SecretKeyFactory createSecretKeyFactory(String algorithm) + throws NoSuchAlgorithmException + { + return SecretKeyFactory.getInstance(algorithm, provider); + } + public KeyPairGenerator createKeyPairGenerator(String algorithm) throws NoSuchAlgorithmException { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java index 8055576..ba7dd80 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java @@ -31,6 +31,14 @@ public class DH provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.DIFFIEHELLMAN", "DH"); provider.addAlgorithm("AlgorithmParameterGenerator.DH", PREFIX + "AlgorithmParameterGeneratorSpi"); + + // BEGIN android-removed + // provider.addAlgorithm("Cipher.DHIES", PREFIX + "IESCipher$IES"); + // provider.addAlgorithm("Cipher.DHIESwithAES", PREFIX + "IESCipher$IESwithAES"); + // provider.addAlgorithm("Cipher.DHIESWITHAES", PREFIX + "IESCipher$IESwithAES"); + // provider.addAlgorithm("Cipher.DHIESWITHDESEDE", PREFIX + "IESCipher$IESwithDESede"); + // provider.addAlgorithm("KeyPairGenerator.IES", PREFIX + "KeyPairGeneratorSpi"); + // END android-removed } } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DSA.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DSA.java index 830334b..b908f58 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DSA.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DSA.java @@ -53,6 +53,7 @@ public class DSA provider.addAlgorithm("Alg.Alias.Signature.DSAWITHSHA1", "SHA1withDSA"); provider.addAlgorithm("Alg.Alias.Signature.SHA1WithDSA", "SHA1withDSA"); provider.addAlgorithm("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA"); + provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA"); // END android-changed @@ -60,6 +61,10 @@ public class DSA for (int i = 0; i != DSAUtil.dsaOids.length; i++) { + // BEGIN android-changed + provider.addAlgorithm("Alg.Alias.Signature." + DSAUtil.dsaOids[i], "SHA1withDSA"); + // END android-changed + registerOid(provider, DSAUtil.dsaOids[i], "DSA", keyFact); registerOidAlgorithmParameters(provider, DSAUtil.dsaOids[i], "DSA"); } 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 bacb6d6..8f93a68 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 @@ -59,6 +59,12 @@ public class EC // provider.addAlgorithm("KeyPairGenerator.ECDHC", PREFIX + "KeyPairGeneratorSpi$ECDHC"); // provider.addAlgorithm("KeyPairGenerator.ECIES", PREFIX + "KeyPairGeneratorSpi$ECDH"); // provider.addAlgorithm("KeyPairGenerator.ECMQV", PREFIX + "KeyPairGeneratorSpi$ECMQV"); + // + // provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES"); + // provider.addAlgorithm("Cipher.ECIESwithAES", PREFIX + "IESCipher$ECIESwithAES"); + // provider.addAlgorithm("Cipher.ECIESWITHAES", PREFIX + "IESCipher$ECIESwithAES"); + // provider.addAlgorithm("Cipher.ECIESwithDESEDE", PREFIX + "IESCipher$ECIESwithDESede"); + // provider.addAlgorithm("Cipher.ECIESWITHDESEDE", PREFIX + "IESCipher$ECIESwithDESede"); // END android-removed provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA"); 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 3037069..d570cf6 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 @@ -122,17 +122,13 @@ public class RSA // addDigestSignature(provider, "MD2", PREFIX + "DigestSignatureSpi$MD2", PKCSObjectIdentifiers.md2WithRSAEncryption); // } // - // // BEGIN android-changed // if (provider.hasAlgorithm("MessageDigest", "MD4")) - // // END android-changed // { // addDigestSignature(provider, "MD4", PREFIX + "DigestSignatureSpi$MD4", PKCSObjectIdentifiers.md4WithRSAEncryption); // } // END android-removed - // BEGIN android-changed if (provider.hasAlgorithm("MessageDigest", "MD5")) - // END android-changed { addDigestSignature(provider, "MD5", PREFIX + "DigestSignatureSpi$MD5", PKCSObjectIdentifiers.md5WithRSAEncryption); // BEGIN android-removed diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java index 332e2eb..d5516dc 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java @@ -15,7 +15,6 @@ import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.DHParameter; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; @@ -180,7 +179,7 @@ public class BCDHPrivateKey } public ASN1Encodable getBagAttribute( - DERObjectIdentifier oid) + ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java index 5a66ffb..c9462a6 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java @@ -16,6 +16,7 @@ import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.crypto.params.DESParameters; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.Strings; /** @@ -35,12 +36,10 @@ public class KeyAgreementSpi static { - // BEGIN android-changed - Integer i64 = Integer.valueOf(64); - Integer i192 = Integer.valueOf(192); - Integer i128 = Integer.valueOf(128); - Integer i256 = Integer.valueOf(256); - // END android-changed + Integer i64 = Integers.valueOf(64); + Integer i192 = Integers.valueOf(192); + Integer i128 = Integers.valueOf(128); + Integer i256 = Integers.valueOf(256); algorithms.put("DES", i64); algorithms.put("DESEDE", i192); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java index 69d5703..48da020 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java @@ -16,11 +16,13 @@ import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.Integers; public class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { private static Hashtable params = new Hashtable(); + private static Object lock = new Object(); DHKeyGenerationParameters param; DHBasicKeyPairGenerator engine = new DHBasicKeyPairGenerator(); @@ -63,9 +65,7 @@ public class KeyPairGeneratorSpi { if (!initialised) { - // BEGIN android-changed - Integer paramStrength = Integer.valueOf(strength); - // END android-changed + Integer paramStrength = Integers.valueOf(strength); if (params.containsKey(paramStrength)) { @@ -73,21 +73,34 @@ public class KeyPairGeneratorSpi } else { - DHParameterSpec dhParams = BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(); + DHParameterSpec dhParams = BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(strength); - if (dhParams != null && dhParams.getP().bitLength() == strength) + if (dhParams != null) { param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL())); } else { - DHParametersGenerator pGen = new DHParametersGenerator(); - - pGen.init(strength, certainty, random); - - param = new DHKeyGenerationParameters(random, pGen.generateParameters()); - - params.put(paramStrength, param); + synchronized (lock) + { + // we do the check again in case we were blocked by a generator for + // our key size. + if (params.containsKey(paramStrength)) + { + param = (DHKeyGenerationParameters)params.get(paramStrength); + } + else + { + + DHParametersGenerator pGen = new DHParametersGenerator(); + + pGen.init(strength, certainty, random); + + param = new DHKeyGenerationParameters(random, pGen.generateParameters()); + + params.put(paramStrength, param); + } + } } } 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 6dfb8fb..1ddb815 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 @@ -97,7 +97,7 @@ public class AlgorithmParametersSpi { try { - DSAParameter dsaP = new DSAParameter((ASN1Sequence)ASN1Primitive.fromByteArray(params)); + DSAParameter dsaP = DSAParameter.getInstance(ASN1Primitive.fromByteArray(params)); currentSpec = new DSAParameterSpec(dsaP.getP(), dsaP.getQ(), dsaP.getG()); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPrivateKey.java index f67d12d..0fb4bd9 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPrivateKey.java @@ -13,7 +13,6 @@ import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; @@ -135,7 +134,7 @@ public class BCDSAPrivateKey } public ASN1Encodable getBagAttribute( - DERObjectIdentifier oid) + ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } 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 d3f1675..f34f482 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 @@ -417,7 +417,7 @@ public class BCECPrivateKey } public ASN1Encodable getBagAttribute( - DERObjectIdentifier oid) + ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java index 80ff2af..820bf4b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java @@ -9,10 +9,12 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; // import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; // END android-removed import org.bouncycastle.asn1.nist.NISTNamedCurves; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.sec.SECNamedCurves; // BEGIN android-removed // import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; // END android-removed +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962NamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; @@ -132,6 +134,30 @@ public class ECUtil EC5Util.convertPoint(pubKey.getParams(), pubKey.getW(), false), new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); } + else + { + // see if we can build a key from key.getEncoded() + try + { + byte[] bytes = key.getEncoded(); + + if (bytes == null) + { + throw new InvalidKeyException("no encoding for EC public key"); + } + + PublicKey publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); + + if (publicKey instanceof java.security.interfaces.ECPublicKey) + { + return ECUtil.generatePublicKeyParameter(publicKey); + } + } + catch (Exception e) + { + throw new InvalidKeyException("cannot identify EC public key: " + e.toString()); + } + } throw new InvalidKeyException("cannot identify EC public key."); } @@ -154,7 +180,39 @@ public class ECUtil k.getD(), new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); } - + else if (key instanceof java.security.interfaces.ECPrivateKey) + { + java.security.interfaces.ECPrivateKey privKey = (java.security.interfaces.ECPrivateKey)key; + ECParameterSpec s = EC5Util.convertSpec(privKey.getParams(), false); + return new ECPrivateKeyParameters( + privKey.getS(), + new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); + } + else + { + // see if we can build a key from key.getEncoded() + try + { + byte[] bytes = key.getEncoded(); + + if (bytes == null) + { + throw new InvalidKeyException("no encoding for EC private key"); + } + + PrivateKey privateKey = BouncyCastleProvider.getPrivateKey(PrivateKeyInfo.getInstance(bytes)); + + if (privateKey instanceof java.security.interfaces.ECPrivateKey) + { + return ECUtil.generatePrivateKeyParameter(privateKey); + } + } + catch (Exception e) + { + throw new InvalidKeyException("cannot identify EC private key: " + e.toString()); + } + } + throw new InvalidKeyException("can't identify EC private key."); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java index 38a7143..cade228 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java @@ -43,6 +43,7 @@ import org.bouncycastle.jce.interfaces.ECPublicKey; // import org.bouncycastle.jce.interfaces.MQVPrivateKey; // import org.bouncycastle.jce.interfaces.MQVPublicKey; // END android-removed +import org.bouncycastle.util.Integers; /** * Diffie-Hellman key agreement using elliptic curve keys, ala IEEE P1363 @@ -58,11 +59,9 @@ public class KeyAgreementSpi static { - // BEGIN android-changed - Integer i128 = Integer.valueOf(128); - Integer i192 = Integer.valueOf(192); - Integer i256 = Integer.valueOf(256); - // END android-changed + Integer i128 = Integers.valueOf(128); + Integer i192 = Integers.valueOf(192); + Integer i256 = Integers.valueOf(256); algorithms.put(NISTObjectIdentifiers.id_aes128_CBC.getId(), i128); algorithms.put(NISTObjectIdentifiers.id_aes192_CBC.getId(), i192); @@ -137,7 +136,7 @@ public class KeyAgreementSpi // else // END android-removed { - if (!(key instanceof ECPublicKey)) + if (!(key instanceof PublicKey)) { throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + getSimpleName(ECPublicKey.class) + " for doPhase"); @@ -222,6 +221,12 @@ public class KeyAgreementSpi SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + // BEGIN android-added + if (params != null) + { + throw new InvalidAlgorithmParameterException("No algorithm parameters supported"); + } + // END android-added initFromKey(key); } @@ -268,7 +273,7 @@ public class KeyAgreementSpi // else // END android-removed { - if (!(key instanceof ECPrivateKey)) + if (!(key instanceof PrivateKey)) { throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + getSimpleName(ECPrivateKey.class) + " for initialisation"); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java index 31090ae..4cbefb6 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java @@ -30,6 +30,7 @@ import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.util.Integers; public abstract class KeyPairGeneratorSpi extends java.security.KeyPairGenerator @@ -57,15 +58,13 @@ public abstract class KeyPairGeneratorSpi static { ecParameters = new Hashtable(); - // BEGIN android-changed - ecParameters.put(Integer.valueOf(192), new ECGenParameterSpec("prime192v1")); // a.k.a P-192 - ecParameters.put(Integer.valueOf(239), new ECGenParameterSpec("prime239v1")); - ecParameters.put(Integer.valueOf(256), new ECGenParameterSpec("prime256v1")); // a.k.a P-256 + ecParameters.put(Integers.valueOf(192), new ECGenParameterSpec("prime192v1")); // a.k.a P-192 + ecParameters.put(Integers.valueOf(239), new ECGenParameterSpec("prime239v1")); + ecParameters.put(Integers.valueOf(256), new ECGenParameterSpec("prime256v1")); // a.k.a P-256 - ecParameters.put(Integer.valueOf(224), new ECGenParameterSpec("P-224")); - ecParameters.put(Integer.valueOf(384), new ECGenParameterSpec("P-384")); - ecParameters.put(Integer.valueOf(521), new ECGenParameterSpec("P-521")); - // END android-changed + ecParameters.put(Integers.valueOf(224), new ECGenParameterSpec("P-224")); + ecParameters.put(Integers.valueOf(384), new ECGenParameterSpec("P-384")); + ecParameters.put(Integers.valueOf(521), new ECGenParameterSpec("P-521")); } public EC() @@ -96,9 +95,7 @@ public abstract class KeyPairGeneratorSpi // BEGIN android-added } // END android-added - // BEGIN android-changed - ECGenParameterSpec ecParams = (ECGenParameterSpec)ecParameters.get(Integer.valueOf(strength)); - // END android-changed + ECGenParameterSpec ecParams = (ECGenParameterSpec)ecParameters.get(Integers.valueOf(strength)); if (ecParams != null) { @@ -252,15 +249,7 @@ public abstract class KeyPairGeneratorSpi { if (!initialised) { - // BEGIN android-removed - // throw new IllegalStateException("EC Key Pair Generator not initialised"); - // END android-removed - // BEGIN android-added - /* - * KeyPairGenerator documentation says that a default initialization must be provided - */ - initialize(192, random); - // END android-added + initialize(strength, new SecureRandom()); } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java index a92b7da..86a407c 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java @@ -5,7 +5,6 @@ import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; -import java.security.interfaces.ECPublicKey; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; @@ -13,7 +12,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Digest; @@ -36,8 +34,6 @@ import org.bouncycastle.crypto.signers.ECDSASigner; // END android-removed import org.bouncycastle.jcajce.provider.asymmetric.util.DSABase; import org.bouncycastle.jcajce.provider.asymmetric.util.DSAEncoder; -import org.bouncycastle.jce.interfaces.ECKey; -import org.bouncycastle.jce.provider.BouncyCastleProvider; public class SignatureSpi extends DSABase @@ -50,34 +46,7 @@ public class SignatureSpi protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { - CipherParameters param; - - if (publicKey instanceof ECPublicKey) - { - param = ECUtil.generatePublicKeyParameter(publicKey); - } - else - { - try - { - byte[] bytes = publicKey.getEncoded(); - - publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); - - if (publicKey instanceof ECPublicKey) - { - param = ECUtil.generatePublicKeyParameter(publicKey); - } - else - { - throw new InvalidKeyException("can't recognise key type in ECDSA based signer"); - } - } - catch (Exception e) - { - throw new InvalidKeyException("can't recognise key type in ECDSA based signer"); - } - } + CipherParameters param = ECUtil.generatePublicKeyParameter(publicKey); digest.reset(); signer.init(false, param); @@ -87,16 +56,7 @@ public class SignatureSpi PrivateKey privateKey) throws InvalidKeyException { - CipherParameters param; - - if (privateKey instanceof ECKey) - { - param = ECUtil.generatePrivateKeyParameter(privateKey); - } - else - { - throw new InvalidKeyException("can't recognise key type in ECDSA based signer"); - } + CipherParameters param = ECUtil.generatePrivateKeyParameter(privateKey); digest.reset(); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java index 99ac36c..baee6d5 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java @@ -55,15 +55,11 @@ public abstract class AlgorithmParametersSpi { AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier( DigestFactory.getOID(currentSpec.getDigestAlgorithm()), - // BEGIN android-changed DERNull.INSTANCE); - // END android-changed MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)currentSpec.getMGFParameters(); AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier( PKCSObjectIdentifiers.id_mgf1, - // BEGIN android-changed new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE)); - // END android-changed PSource.PSpecified pSource = (PSource.PSpecified)currentSpec.getPSource(); AlgorithmIdentifier pSourceAlgorithm = new AlgorithmIdentifier( PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(pSource.getValue())); @@ -174,15 +170,11 @@ public abstract class AlgorithmParametersSpi PSSParameterSpec pssSpec = currentSpec; AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier( DigestFactory.getOID(pssSpec.getDigestAlgorithm()), - // BEGIN android-changed DERNull.INSTANCE); - // END android-changed MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters(); AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier( PKCSObjectIdentifiers.id_mgf1, - // BEGIN android-changed new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE)); - // END android-changed RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField())); return pssP.getEncoded("DER"); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java index b0aa66e..9b70d74 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java @@ -127,9 +127,7 @@ public class BCRSAPrivateCrtKey */ public byte[] getEncoded() { - // BEGIN android-changed return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient())); - // END android-changed } /** diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java index 6643f13..0aa81b4 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java @@ -11,7 +11,6 @@ import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.RSAKeyParameters; @@ -78,9 +77,7 @@ public class BCRSAPrivateKey public byte[] getEncoded() { - // BEGIN android-changed return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO)); - // END android-changed } public boolean equals(Object o) @@ -114,7 +111,7 @@ public class BCRSAPrivateKey } public ASN1Encodable getBagAttribute( - DERObjectIdentifier oid) + ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java index e57da4a..ce0e603 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java @@ -89,9 +89,7 @@ public class BCRSAPublicKey public byte[] getEncoded() { - // BEGIN android-changed return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new org.bouncycastle.asn1.pkcs.RSAPublicKey(getModulus(), getPublicExponent())); - // END android-changed } public int hashCode() 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 1f53f5a..d0a60f6 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 @@ -328,6 +328,8 @@ public class CipherSpi } } + bOut.reset(); + switch (opmode) { case Cipher.ENCRYPT_MODE: @@ -510,7 +512,6 @@ public class CipherSpi try { byte[] bytes = bOut.toByteArray(); - bOut.reset(); out = cipher.processBlock(bytes, 0, bytes.length); } @@ -518,6 +519,10 @@ public class CipherSpi { throw new BadPaddingException(e.getMessage()); } + finally + { + bOut.reset(); + } for (int i = 0; i != out.length; i++) { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java index 621069a..490bf4e 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java @@ -27,9 +27,7 @@ public abstract class BaseKeyFactorySpi { return generatePrivate(PrivateKeyInfo.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded())); } - // BEGIN android-changed catch (Exception e) - // END android-changed { throw new InvalidKeySpecException("encoded key spec not recognised"); } @@ -50,9 +48,7 @@ public abstract class BaseKeyFactorySpi { return generatePublic(SubjectPublicKeyInfo.getInstance(((X509EncodedKeySpec)keySpec).getEncoded())); } - // BEGIN android-changed catch (Exception e) - // END android-changed { throw new InvalidKeySpecException("encoded key spec not recognised"); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java index 06ccd66..532554d 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java @@ -48,7 +48,7 @@ public class PKCS12BagAttributeCarrierImpl } public ASN1Encodable getBagAttribute( - DERObjectIdentifier oid) + ASN1ObjectIdentifier oid) { return (ASN1Encodable)pkcs12Attributes.get(oid); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java index 33f3db7..5b79864 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java @@ -22,8 +22,8 @@ import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.SignedData; +import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.CertificateList; -import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.jce.provider.X509CRLObject; import org.bouncycastle.jce.provider.X509CertificateObject; @@ -67,7 +67,7 @@ public class CertificateFactory } return new X509CertificateObject( - X509CertificateStructure.getInstance(seq)); + Certificate.getInstance(seq)); } private java.security.cert.Certificate getCertificate() @@ -82,7 +82,7 @@ public class CertificateFactory if (obj instanceof ASN1Sequence) { return new X509CertificateObject( - X509CertificateStructure.getInstance(obj)); + Certificate.getInstance(obj)); } } } @@ -99,7 +99,7 @@ public class CertificateFactory if (seq != null) { return new X509CertificateObject( - X509CertificateStructure.getInstance(seq)); + Certificate.getInstance(seq)); } return null; @@ -334,7 +334,9 @@ public class CertificateFactory public Iterator engineGetCertPathEncodings() { - return null; // TODO: PKIXCertPath.certPathEncodings.iterator(); + // BEGIN android-changed + return PKIXCertPath.certPathEncodings.iterator(); + // END android-changed } public CertPath engineGenerateCertPath( 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 e13412d..9b14731 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 @@ -53,7 +53,9 @@ public class PKIXCertPath { List encodings = new ArrayList(); encodings.add("PkiPath"); - encodings.add("PEM"); + // BEGIN android-removed + // encodings.add("PEM"); + // END android-removed encodings.add("PKCS7"); certPathEncodings = Collections.unmodifiableList(encodings); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java index 692b0d7..c3f148b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java @@ -36,6 +36,4 @@ public interface ConfigurableProvider boolean hasAlgorithm(String type, String name); void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter); - - AsymmetricKeyInfoConverter getConverter(ASN1ObjectIdentifier oid); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java index 2b7efe9..2d99ed9 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java @@ -8,5 +8,5 @@ public interface ProviderConfiguration { ECParameterSpec getEcImplicitlyCa(); - DHParameterSpec getDHDefaultParameters(); + DHParameterSpec getDHDefaultParameters(int keySize); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java index 7f5d3c9..9c4c831 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java @@ -3,7 +3,7 @@ package org.bouncycastle.jcajce.provider.symmetric.util; import javax.crypto.interfaces.PBEKey; import javax.crypto.spec.PBEKeySpec; -import org.bouncycastle.asn1.DERObjectIdentifier; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; @@ -13,7 +13,7 @@ public class BCPBEKey implements PBEKey { String algorithm; - DERObjectIdentifier oid; + ASN1ObjectIdentifier oid; int type; int digest; int keySize; @@ -27,7 +27,7 @@ public class BCPBEKey */ public BCPBEKey( String algorithm, - DERObjectIdentifier oid, + ASN1ObjectIdentifier oid, int type, int digest, int keySize, @@ -134,7 +134,7 @@ public class BCPBEKey return pbeKeySpec.getIterationCount(); } - public DERObjectIdentifier getOID() + public ASN1ObjectIdentifier getOID() { return oid; } 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 ce54655..26a73cd 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 @@ -26,6 +26,7 @@ import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.modes.AEADBlockCipher; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.modes.CCMBlockCipher; @@ -726,29 +727,23 @@ public class BaseBlockCipher int inputOffset, int inputLen, byte[] output, - int outputOffset) + int outputOffset) throws IllegalBlockSizeException, BadPaddingException, ShortBufferException { - // BEGIN android-note - // added ShortBufferException to the throws statement - // END android-note - int len = 0; + try + { + int len = 0; - // BEGIN android-added - int outputLen = cipher.getOutputSize(inputLen); + if (inputLen != 0) + { + len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); + } - if (outputLen + outputOffset > output.length) { - throw new ShortBufferException("need at least " + outputLen + " bytes"); - } - // BEGIN android-added - if (inputLen != 0) - { - len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); + return (len + cipher.doFinal(output, outputOffset + len)); } - - try + catch (OutputLengthException e) { - return (len + cipher.doFinal(output, outputOffset + len)); + throw new ShortBufferException(e.getMessage()); } catch (DataLengthException e) { diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java index 0e190d3..12d2b85 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java @@ -56,11 +56,10 @@ public class BaseKeyGenerator { try { - // BEGIN android-added - if (random == null) { + if (random == null) + { random = new SecureRandom(); } - // END android-added engine.init(new KeyGenerationParameters(random, keySize)); uninitialised = false; } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java index 23e7b19..9c59b1b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java @@ -11,7 +11,7 @@ import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; -import org.bouncycastle.asn1.DERObjectIdentifier; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.DESParameters; import org.bouncycastle.crypto.params.KeyParameter; @@ -22,11 +22,11 @@ public class BaseSecretKeyFactory implements PBE { protected String algName; - protected DERObjectIdentifier algOid; + protected ASN1ObjectIdentifier algOid; protected BaseSecretKeyFactory( String algName, - DERObjectIdentifier algOid) + ASN1ObjectIdentifier algOid) { this.algName = algName; this.algOid = algOid; @@ -114,7 +114,7 @@ public class BaseSecretKeyFactory public DESPBEKeyFactory( String algorithm, - DERObjectIdentifier oid, + ASN1ObjectIdentifier oid, boolean forCipher, int scheme, int digest, 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 2800a7f..98e5771 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 @@ -307,12 +307,7 @@ public abstract class BaseWrapCipher byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) - // BEGIN android-removed - // throws InvalidKeyException - // END android-removed - // BEGIN android-added throws InvalidKeyException, NoSuchAlgorithmException - // END android-added { byte[] encoded; try @@ -346,9 +341,9 @@ public abstract class BaseWrapCipher else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY) { /* - * The caller doesn't know the algorithm as it is part of - * the encrypted data. - */ + * The caller doesn't know the algorithm as it is part of + * the encrypted data. + */ try { PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded); @@ -388,12 +383,6 @@ public abstract class BaseWrapCipher { throw new InvalidKeyException("Unknown key type " + e.getMessage()); } - // BEGIN android-removed - // catch (NoSuchAlgorithmException e) - // { - // throw new InvalidKeyException("Unknown key type " + e.getMessage()); - // } - // END android-removed catch (InvalidKeySpecException e2) { throw new InvalidKeyException("Unknown key type " + e2.getMessage()); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java index e9fb8dd..1074e11 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java @@ -8,6 +8,7 @@ import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.PBEParametersGenerator; // BEGIN android-removed +// import org.bouncycastle.crypto.digests.GOST3411Digest; // import org.bouncycastle.crypto.digests.MD2Digest; // import org.bouncycastle.crypto.digests.MD5Digest; // import org.bouncycastle.crypto.digests.RIPEMD160Digest; @@ -40,6 +41,7 @@ public interface PBE static final int SHA256 = 4; // BEGIN android-removed // static final int MD2 = 5; + // static final int GOST3411 = 6; // END android-removed static final int PKCS5S1 = 0; @@ -117,6 +119,11 @@ public interface PBE generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA256()); // END android-changed break; + // BEGIN android-removed + // case GOST3411: + // generator = new PKCS12ParametersGenerator(new GOST3411Digest()); + // break; + // END android-removed default: throw new IllegalStateException("unknown digest scheme for PBE encryption."); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBESecretKeyFactory.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBESecretKeyFactory.java index f00ad36..434f6bb 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBESecretKeyFactory.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBESecretKeyFactory.java @@ -6,7 +6,7 @@ import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.spec.PBEKeySpec; -import org.bouncycastle.asn1.DERObjectIdentifier; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.crypto.CipherParameters; public class PBESecretKeyFactory @@ -21,7 +21,7 @@ public class PBESecretKeyFactory public PBESecretKeyFactory( String algorithm, - DERObjectIdentifier oid, + ASN1ObjectIdentifier oid, boolean forCipher, int scheme, int digest, diff --git a/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java b/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java index e09bb65..f3a3849 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java @@ -213,31 +213,21 @@ public class PKCS10CertificationRequest // // explicit params // - // BEGIN android-changed AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); - // END android-changed params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20)); // BEGIN android-removed - // // BEGIN android-changed // AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE); - // // END android-changed // params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28)); // END android-removed - // BEGIN android-changed AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE); - // END android-changed params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32)); - // BEGIN android-changed AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE); - // END android-changed params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48)); - // BEGIN android-changed AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE); - // END android-changed params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64)); } @@ -441,20 +431,21 @@ public class PKCS10CertificationRequest InvalidKeyException { SubjectPublicKeyInfo subjectPKInfo = reqInfo.getSubjectPublicKeyInfo(); - X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getBytes()); - AlgorithmIdentifier keyAlg = subjectPKInfo.getAlgorithmId(); + try { + X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getBytes()); + AlgorithmIdentifier keyAlg = subjectPKInfo.getAlgorithm(); try { if (provider == null) { - return KeyFactory.getInstance(keyAlg.getObjectId().getId()).generatePublic(xspec); + return KeyFactory.getInstance(keyAlg.getAlgorithm().getId()).generatePublic(xspec); } else { - return KeyFactory.getInstance(keyAlg.getObjectId().getId(), provider).generatePublic(xspec); + return KeyFactory.getInstance(keyAlg.getAlgorithm().getId(), provider).generatePublic(xspec); } } catch (NoSuchAlgorithmException e) @@ -483,6 +474,10 @@ public class PKCS10CertificationRequest { throw new InvalidKeyException("error decoding public key"); } + catch (IOException e) + { + throw new InvalidKeyException("error decoding public key"); + } } /** diff --git a/bcprov/src/main/java/org/bouncycastle/jce/interfaces/PKCS12BagAttributeCarrier.java b/bcprov/src/main/java/org/bouncycastle/jce/interfaces/PKCS12BagAttributeCarrier.java index cbc9f44..b8ebee7 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/interfaces/PKCS12BagAttributeCarrier.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/interfaces/PKCS12BagAttributeCarrier.java @@ -4,7 +4,6 @@ import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DERObjectIdentifier; /** * allow us to set attributes on objects that can go into a PKCS12 store. @@ -16,7 +15,7 @@ public interface PKCS12BagAttributeCarrier ASN1Encodable attribute); ASN1Encodable getBagAttribute( - DERObjectIdentifier oid); + ASN1ObjectIdentifier oid); Enumeration getBagAttributeKeys(); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java b/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java index 4bfb9d9..39dd35a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java @@ -143,7 +143,14 @@ public class NetscapeCertRequest //content_der.add(new SubjectPublicKeyInfo(sigAlg, new RSAPublicKeyStructure(pubkey.getModulus(), pubkey.getPublicExponent()).getDERObject())); content_der.add(new DERIA5String(challenge)); - content = new DERBitString(new DERSequence(content_der)); + try + { + content = new DERBitString(new DERSequence(content_der)); + } + catch (IOException e) + { + throw new InvalidKeySpecException("exception encoding key: " + e.toString()); + } } public String getChallenge() 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 5ed4df9..cc6510a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java @@ -11,6 +11,9 @@ import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +// BEGIN android-removed +// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; +// END android-removed import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; @@ -46,7 +49,7 @@ import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; public final class BouncyCastleProvider extends Provider implements ConfigurableProvider { - private static String info = "BouncyCastle Security Provider v1.47"; + private static String info = "BouncyCastle Security Provider v1.48"; // BEGIN android-changed // this constant should be final @@ -88,7 +91,7 @@ public final class BouncyCastleProvider extends Provider private static final String[] ASYMMETRIC_CIPHERS = { // BEGIN android-removed - // "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal" + // "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145" // END android-removed // BEGIN android-added "DSA", "DH", "EC", "RSA", @@ -102,7 +105,7 @@ public final class BouncyCastleProvider extends Provider private static final String[] DIGESTS = { // BEGIN android-removed - // "GOST3411", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", "SHA256", "SHA384", "SHA512", "Tiger", "Whirlpool" + // "GOST3411", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "Tiger", "Whirlpool" // END android-removed // BEGIN android-added "MD5", "SHA1", "SHA256", "SHA384", "SHA512", @@ -116,7 +119,7 @@ public final class BouncyCastleProvider extends Provider */ public BouncyCastleProvider() { - super(PROVIDER_NAME, 1.47, info); + super(PROVIDER_NAME, 1.48, info); AccessController.doPrivileged(new PrivilegedAction() { @@ -277,11 +280,8 @@ public final class BouncyCastleProvider extends Provider // cipher engines // put("Alg.Alias.Cipher.PBEWithSHAAnd3KeyTripleDES", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); - // BEGIN android-removed - // put("Cipher.ECIES", "org.bouncycastle.jce.provider.JCEIESCipher$ECIES"); - // put("Cipher.BrokenECIES", "org.bouncycastle.jce.provider.JCEIESCipher$BrokenECIES"); // put("Cipher.IES", "org.bouncycastle.jce.provider.JCEIESCipher$IES"); // put("Cipher.BrokenIES", "org.bouncycastle.jce.provider.JCEIESCipher$BrokenIES"); // END android-removed @@ -416,6 +416,8 @@ public final class BouncyCastleProvider extends Provider put("SecretKeyFactory.PBEWITHMD5AND256BITAES-CBC-OPENSSL", "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD5And256BitAESCBCOpenSSL"); // BEGIN android-removed + // put("SecretKeyFactory." + CryptoProObjectIdentifiers.gostR3411, "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithGOST3411"); + // // put("Alg.Alias.SecretKeyFactory.PBE", "PBE/PKCS5"); // // put("Alg.Alias.SecretKeyFactory.BROKENPBEWITHMD5ANDDES", "PBE/PKCS5"); @@ -530,7 +532,6 @@ public final class BouncyCastleProvider extends Provider } catch (Exception e) { // this should never ever happen!! -e.printStackTrace(); throw new InternalError("cannot create instance of " + packageName + names[i] + "$Mappings : " + e); } @@ -595,11 +596,6 @@ e.printStackTrace(); keyInfoConverters.put(oid, keyInfoConverter); } - public AsymmetricKeyInfoConverter getConverter(ASN1ObjectIdentifier oid) - { - return (AsymmetricKeyInfoConverter)keyInfoConverters.get(oid); - } - public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo) throws IOException { diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java index b370ea9..8fb1616 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java @@ -26,7 +26,7 @@ class BouncyCastleProviderConfiguration private ThreadLocal dhThreadSpec = new ThreadLocal(); private volatile ECParameterSpec ecImplicitCaParams; - private volatile DHParameterSpec dhDefaultParams; + private volatile Object dhDefaultParams; void setParameter(String parameterName, Object parameter) { @@ -77,16 +77,16 @@ class BouncyCastleProviderConfiguration } else if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS)) { - DHParameterSpec dhSpec; + Object dhSpec; if (securityManager != null) { securityManager.checkPermission(BC_DH_LOCAL_PERMISSION); } - if (parameter instanceof DHParameterSpec || parameter == null) + if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null) { - dhSpec = (DHParameterSpec)parameter; + dhSpec = parameter; } else { @@ -109,13 +109,13 @@ class BouncyCastleProviderConfiguration securityManager.checkPermission(BC_DH_PERMISSION); } - if (parameter instanceof DHParameterSpec || parameter == null) + if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null) { - dhDefaultParams = (DHParameterSpec)parameter; + dhDefaultParams = parameter; } else { - throw new IllegalArgumentException("not a valid DHParameterSpec"); + throw new IllegalArgumentException("not a valid DHParameterSpec or DHParameterSpec[]"); } } } @@ -132,15 +132,36 @@ class BouncyCastleProviderConfiguration return ecImplicitCaParams; } - public DHParameterSpec getDHDefaultParameters() + public DHParameterSpec getDHDefaultParameters(int keySize) { - DHParameterSpec spec = (DHParameterSpec)dhThreadSpec.get(); + Object params = dhThreadSpec.get(); + if (params == null) + { + params = dhDefaultParams; + } - if (spec != null) + if (params instanceof DHParameterSpec) { - return spec; + DHParameterSpec spec = (DHParameterSpec)params; + + if (spec.getP().bitLength() == keySize) + { + return spec; + } + } + else if (params instanceof DHParameterSpec[]) + { + DHParameterSpec[] specs = (DHParameterSpec[])params; + + for (int i = 0; i != specs.length; i++) + { + if (specs[i].getP().bitLength() == keySize) + { + return specs[i]; + } + } } - return dhDefaultParams; + return null; } } 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 f8f6cb4..a76aff7 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java @@ -55,16 +55,17 @@ 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.PolicyInformation; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extension; -import org.bouncycastle.asn1.x509.X509Extensions; // BEGIN android-removed // import org.bouncycastle.jce.X509LDAPCertStoreParameters; // END android-removed import org.bouncycastle.jce.exception.ExtCertPathValidatorException; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.Selector; import org.bouncycastle.util.StoreException; import org.bouncycastle.x509.ExtendedPKIXBuilderParameters; @@ -81,23 +82,23 @@ public class CertPathValidatorUtilities { protected static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil(); - protected static final String CERTIFICATE_POLICIES = X509Extensions.CertificatePolicies.getId(); - protected static final String BASIC_CONSTRAINTS = X509Extensions.BasicConstraints.getId(); - protected static final String POLICY_MAPPINGS = X509Extensions.PolicyMappings.getId(); - protected static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName.getId(); - protected static final String NAME_CONSTRAINTS = X509Extensions.NameConstraints.getId(); - protected static final String KEY_USAGE = X509Extensions.KeyUsage.getId(); - protected static final String INHIBIT_ANY_POLICY = X509Extensions.InhibitAnyPolicy.getId(); - protected static final String ISSUING_DISTRIBUTION_POINT = X509Extensions.IssuingDistributionPoint.getId(); - protected static final String DELTA_CRL_INDICATOR = X509Extensions.DeltaCRLIndicator.getId(); - protected static final String POLICY_CONSTRAINTS = X509Extensions.PolicyConstraints.getId(); - protected static final String FRESHEST_CRL = X509Extensions.FreshestCRL.getId(); - protected static final String CRL_DISTRIBUTION_POINTS = X509Extensions.CRLDistributionPoints.getId(); - protected static final String AUTHORITY_KEY_IDENTIFIER = X509Extensions.AuthorityKeyIdentifier.getId(); + protected static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId(); + protected static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId(); + protected static final String POLICY_MAPPINGS = Extension.policyMappings.getId(); + protected static final String SUBJECT_ALTERNATIVE_NAME = Extension.subjectAlternativeName.getId(); + protected static final String NAME_CONSTRAINTS = Extension.nameConstraints.getId(); + protected static final String KEY_USAGE = Extension.keyUsage.getId(); + protected static final String INHIBIT_ANY_POLICY = Extension.inhibitAnyPolicy.getId(); + protected static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId(); + protected static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId(); + protected static final String POLICY_CONSTRAINTS = Extension.policyConstraints.getId(); + protected static final String FRESHEST_CRL = Extension.freshestCRL.getId(); + protected static final String CRL_DISTRIBUTION_POINTS = Extension.cRLDistributionPoints.getId(); + protected static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId(); protected static final String ANY_POLICY = "2.5.29.32.0"; - protected static final String CRL_NUMBER = X509Extensions.CRLNumber.getId(); + protected static final String CRL_NUMBER = Extension.cRLNumber.getId(); /* * key usage bits @@ -251,9 +252,7 @@ public class CertPathValidatorUtilities { // look for URI List list = (List)it.next(); - // BEGIN android-changed - if (list.get(0).equals(Integer.valueOf(GeneralName.uniformResourceIdentifier))) - // END android-changed + if (list.get(0).equals(Integers.valueOf(GeneralName.uniformResourceIdentifier))) { // found String temp = (String)list.get(1); diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEBlockCipher.java index 2205a26..6f4d129 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEBlockCipher.java @@ -5,9 +5,15 @@ import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; 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; @@ -22,17 +28,17 @@ import javax.crypto.spec.PBEParameterSpec; // 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.BlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.OutputLengthException; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.engines.DESEngine; -// BEGIN android-removed -// import org.bouncycastle.crypto.engines.GOST28147Engine; -// END android-removed import org.bouncycastle.crypto.engines.RC2Engine; import org.bouncycastle.crypto.engines.TwofishEngine; import org.bouncycastle.crypto.modes.AEADBlockCipher; @@ -738,30 +744,23 @@ public class JCEBlockCipher int inputOffset, int inputLen, byte[] output, - int outputOffset) + int outputOffset) throws IllegalBlockSizeException, BadPaddingException, ShortBufferException { - // BEGIN android-note - // added ShortBufferException to the throws statement - // END android-note - int len = 0; - - // BEGIN android-added - int outputLen = cipher.getOutputSize(inputLen); + try + { + int len = 0; - if (outputLen + outputOffset > output.length) { - throw new ShortBufferException("need at least " + outputLen + " bytes"); - } - // BEGIN android-added + if (inputLen != 0) + { + len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); + } - if (inputLen != 0) - { - len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); + return (len + cipher.doFinal(output, outputOffset + len)); } - - try + catch (OutputLengthException e) { - return (len + cipher.doFinal(output, outputOffset + len)); + throw new ShortBufferException(e.getMessage()); } catch (DataLengthException e) { @@ -779,80 +778,111 @@ public class JCEBlockCipher return "CCM".equals(modeName) || "EAX".equals(modeName) || "GCM".equals(modeName); } - /* - * The ciphers that inherit from us. - */ + protected byte[] engineWrap( + Key key) + throws IllegalBlockSizeException, InvalidKeyException + { + byte[] encoded = key.getEncoded(); + if (encoded == null) + { + throw new InvalidKeyException("Cannot wrap key, null encoding."); + } - /** - * DES - */ - static public class DES - extends JCEBlockCipher + 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 { - public DES() + byte[] encoded; + try + { + encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); + } + catch (BadPaddingException e) + { + throw new InvalidKeyException(e.getMessage()); + } + catch (IllegalBlockSizeException e2) { - super(new DESEngine()); + 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); } } - // BEGIN android-removed - // /** - // * DESCBC - // */ - // static public class DESCBC - // extends JCEBlockCipher - // { - // public DESCBC() - // { - // super(new CBCBlockCipher(new DESEngine()), 64); - // } - // } - // - // /** - // * GOST28147 - // */ - // static public class GOST28147 - // extends JCEBlockCipher - // { - // public GOST28147() - // { - // super(new GOST28147Engine()); - // } - // } - // - // static public class GOST28147cbc - // extends JCEBlockCipher - // { - // public GOST28147cbc() - // { - // super(new CBCBlockCipher(new GOST28147Engine()), 64); - // } - // } - // - // /** - // * RC2 - // */ - // static public class RC2 - // extends JCEBlockCipher - // { - // public RC2() - // { - // super(new RC2Engine()); - // } - // } - // - // /** - // * RC2CBC - // */ - // static public class RC2CBC - // extends JCEBlockCipher - // { - // public RC2CBC() - // { - // super(new CBCBlockCipher(new RC2Engine()), 64); - // } - // } - // END android-removed + /* + * The ciphers that inherit from us. + */ /** * PBEWithMD5AndDES diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEDHPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEDHPrivateKey.java index 46295c5..b38f60b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEDHPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEDHPrivateKey.java @@ -176,7 +176,7 @@ public class JCEDHPrivateKey } public ASN1Encodable getBagAttribute( - DERObjectIdentifier oid) + ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java index 1ff5b80..9aaca5b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java @@ -398,7 +398,7 @@ public class JCEECPrivateKey } public ASN1Encodable getBagAttribute( - DERObjectIdentifier oid) + ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java index 15a2996..863f9d3 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java @@ -364,7 +364,14 @@ public class JCEECPublicKey // extractBytes(encKey, 0, bX); // extractBytes(encKey, 32, bY); // - // info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params), new DEROctetString(encKey)); + // try + // { + // info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params), new DEROctetString(encKey)); + // } + // catch (IOException e) + // { + // return null; + // } // } // else // END android-removed diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java index c4c5b61..f9bb5dd 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java @@ -127,9 +127,7 @@ public class JCERSAPrivateCrtKey */ public byte[] getEncoded() { - // BEGIN android-changed return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient())); - // END android-changed } /** diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateKey.java index 6277415..cacedd4 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateKey.java @@ -11,7 +11,6 @@ import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.RSAKeyParameters; @@ -78,9 +77,7 @@ public class JCERSAPrivateKey public byte[] getEncoded() { - // BEGIN android-changed return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO)); - // END android-changed } public boolean equals(Object o) @@ -114,7 +111,7 @@ public class JCERSAPrivateKey } public ASN1Encodable getBagAttribute( - DERObjectIdentifier oid) + ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java index 8d74351..a09295d 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java @@ -91,9 +91,7 @@ public class JCERSAPublicKey public byte[] getEncoded() { - // BEGIN android-changed return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKeyStructure(getModulus(), getPublicExponent())); - // END android-changed } public int hashCode() diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCESecretKeyFactory.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCESecretKeyFactory.java index 7d70734..faf0ead 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCESecretKeyFactory.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCESecretKeyFactory.java @@ -11,7 +11,7 @@ import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; -import org.bouncycastle.asn1.DERObjectIdentifier; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.DESParameters; @@ -25,11 +25,11 @@ public class JCESecretKeyFactory implements PBE { protected String algName; - protected DERObjectIdentifier algOid; + protected ASN1ObjectIdentifier algOid; protected JCESecretKeyFactory( String algName, - DERObjectIdentifier algOid) + ASN1ObjectIdentifier algOid) { this.algName = algName; this.algOid = algOid; @@ -115,7 +115,7 @@ public class JCESecretKeyFactory public PBEKeyFactory( String algorithm, - DERObjectIdentifier oid, + ASN1ObjectIdentifier oid, boolean forCipher, int scheme, int digest, @@ -172,7 +172,7 @@ public class JCESecretKeyFactory public DESPBEKeyFactory( String algorithm, - DERObjectIdentifier oid, + ASN1ObjectIdentifier oid, boolean forCipher, int scheme, int digest, diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEStreamCipher.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEStreamCipher.java index 16a14ec..4600679 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEStreamCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEStreamCipher.java @@ -4,11 +4,20 @@ 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; @@ -18,7 +27,9 @@ import javax.crypto.spec.PBEParameterSpec; // 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.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; @@ -347,7 +358,8 @@ public class JCEStreamCipher protected byte[] engineDoFinal( byte[] input, int inputOffset, - int inputLen) + int inputLen) + throws BadPaddingException, IllegalBlockSizeException { if (inputLen != 0) { @@ -368,7 +380,8 @@ public class JCEStreamCipher int inputOffset, int inputLen, byte[] output, - int outputOffset) + int outputOffset) + throws BadPaddingException { if (inputLen != 0) { @@ -380,6 +393,108 @@ public class JCEStreamCipher 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. */ diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPrivateKey.java index 379120e..50a714c 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPrivateKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPrivateKey.java @@ -16,7 +16,6 @@ import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; -import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; @@ -57,7 +56,7 @@ public class JDKDSAPrivateKey PrivateKeyInfo info) throws IOException { - DSAParameter params = new DSAParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); + DSAParameter params = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters()); DERInteger derX = ASN1Integer.getInstance(info.parsePrivateKey()); this.x = derX.getValue(); @@ -146,7 +145,7 @@ public class JDKDSAPrivateKey } public ASN1Encodable getBagAttribute( - DERObjectIdentifier oid) + ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java index 16a964d..85a39a4 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java @@ -74,9 +74,9 @@ public class JDKDSAPublicKey this.y = derY.getValue(); - if (isNotNull(info.getAlgorithmId().getParameters())) + if (isNotNull(info.getAlgorithm().getParameters())) { - DSAParameter params = new DSAParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); + DSAParameter params = DSAParameter.getInstance(info.getAlgorithm().getParameters()); this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG()); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java index 2d9f683..e4176fa 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java @@ -45,7 +45,7 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; -import org.bouncycastle.asn1.BERConstructedOctetString; +import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BEROutputStream; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERNull; @@ -66,9 +66,9 @@ import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.DigestInfo; +import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; import org.bouncycastle.jce.interfaces.BCKeyStore; @@ -260,14 +260,6 @@ public class JDKPKCS12KeyStore chainCerts.remove(new CertId(c.getPublicKey())); } } - - // BEGIN android-removed - // Only throw if there is a problem removing, not if missing - // if (c == null && k == null) - // { - // throw new KeyStoreException("no such entry as " + alias); - // } - // END android-removed } /** @@ -360,7 +352,7 @@ public class JDKPKCS12KeyStore X509Certificate x509c = (X509Certificate)c; Certificate nextC = null; - byte[] bytes = x509c.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); + byte[] bytes = x509c.getExtensionValue(Extension.authorityKeyIdentifier.getId()); if (bytes != null) { try @@ -370,7 +362,7 @@ public class JDKPKCS12KeyStore byte[] authBytes = ((ASN1OctetString)aIn.readObject()).getOctets(); aIn = new ASN1InputStream(authBytes); - AuthorityKeyIdentifier id = AuthorityKeyIdentifier.getInstance((ASN1Sequence)aIn.readObject()); + AuthorityKeyIdentifier id = AuthorityKeyIdentifier.getInstance(aIn.readObject()); if (id.getKeyIdentifier() != null) { nextC = (Certificate)chainCerts.get(new CertId(id.getKeyIdentifier())); @@ -442,14 +434,14 @@ public class JDKPKCS12KeyStore public Date engineGetCreationDate(String alias) { - // BEGIN android-added - if (alias == null) { + if (alias == null) + { throw new NullPointerException("alias == null"); } - if (keys.get(alias) == null && certs.get(alias) == null) { + if (keys.get(alias) == null && certs.get(alias) == null) + { return null; } - // END android-added return new Date(); } @@ -508,11 +500,11 @@ public class JDKPKCS12KeyStore Certificate[] chain) throws KeyStoreException { - // BEGIN android-added - if (!(key instanceof PrivateKey)) { + if (!(key instanceof PrivateKey)) + { throw new KeyStoreException("PKCS12 does not support non-PrivateKeys"); } - // END android-added + if ((key instanceof PrivateKey) && (chain == null)) { throw new KeyStoreException("no certificate chain for private key"); @@ -524,18 +516,15 @@ public class JDKPKCS12KeyStore } keys.put(alias, key); - // BEGIN android-added - if (chain != null) { - // END android-added - certs.put(alias, chain[0]); - - for (int i = 0; i != chain.length; i++) + if (chain != null) { - chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]); - } - // BEGIN android-added + certs.put(alias, chain[0]); + + for (int i = 0; i != chain.length; i++) + { + chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]); + } } - // END android-added } public int engineSize() @@ -1244,7 +1233,7 @@ public class JDKPKCS12KeyStore } byte[] keySEncoded = new DERSequence(keyS).getEncoded(ASN1Encoding.DER); - BERConstructedOctetString keyString = new BERConstructedOctetString(keySEncoded); + BEROctetString keyString = new BEROctetString(keySEncoded); // // certificate processing @@ -1468,7 +1457,7 @@ public class JDKPKCS12KeyStore byte[] certSeqEncoded = new DERSequence(certSeq).getEncoded(ASN1Encoding.DER); byte[] certBytes = cryptData(true, cAlgId, password, false, certSeqEncoded); - EncryptedData cInfo = new EncryptedData(data, cAlgId, new BERConstructedOctetString(certBytes)); + EncryptedData cInfo = new EncryptedData(data, cAlgId, new BEROctetString(certBytes)); ContentInfo[] info = new ContentInfo[] { @@ -1493,7 +1482,7 @@ public class JDKPKCS12KeyStore byte[] pkg = bOut.toByteArray(); - ContentInfo mainInfo = new ContentInfo(data, new BERConstructedOctetString(pkg)); + ContentInfo mainInfo = new ContentInfo(data, new BEROctetString(pkg)); // // create the mac @@ -1511,9 +1500,7 @@ public class JDKPKCS12KeyStore { byte[] res = calculatePbeMac(id_SHA1, mSalt, itCount, password, false, data); - // BEGIN android-changed AlgorithmIdentifier algId = new AlgorithmIdentifier(id_SHA1, DERNull.INSTANCE); - // END android-changed DigestInfo dInfo = new DigestInfo(algId, res); mData = new MacData(dInfo, mSalt, itCount); @@ -1606,9 +1593,7 @@ public class JDKPKCS12KeyStore public void put(String key, Object value) { - // BEGIN android-changed String lower = (key == null) ? null : Strings.toLowerCase(key); - // END android-changed String k = (String)keys.get(lower); if (k != null) { @@ -1626,9 +1611,7 @@ public class JDKPKCS12KeyStore public Object remove(String alias) { - // BEGIN android-changed String k = (String)keys.remove(alias == null ? null : Strings.toLowerCase(alias)); - // END android-changed if (k == null) { return null; @@ -1639,9 +1622,7 @@ public class JDKPKCS12KeyStore public Object get(String alias) { - // BEGIN android-changed String k = (String)keys.get(alias == null ? null : Strings.toLowerCase(alias)); - // END android-changed if (k == null) { return null; 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 ddf7462..7ecc486 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java @@ -2,7 +2,6 @@ package org.bouncycastle.jce.provider; import java.util.Collection; import java.util.Collections; -import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -15,6 +14,7 @@ import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.Strings; public class PKIXNameConstraintValidator @@ -1518,6 +1518,11 @@ public class PKIXNameConstraintValidator } } + public void intersectPermittedSubtree(GeneralSubtree permitted) + { + intersectPermittedSubtree(new GeneralSubtree[] { permitted }); + } + /** * Updates the permitted set of these name constraints with the intersection * with the given subtree. @@ -1525,17 +1530,15 @@ public class PKIXNameConstraintValidator * @param permitted The permitted subtrees */ - public void intersectPermittedSubtree(ASN1Sequence permitted) + public void intersectPermittedSubtree(GeneralSubtree[] permitted) { Map subtreesMap = new HashMap(); // group in sets in a map ordered by tag no. - for (Enumeration e = permitted.getObjects(); e.hasMoreElements();) + for (int i = 0; i != permitted.length; i++) { - GeneralSubtree subtree = GeneralSubtree.getInstance(e.nextElement()); - // BEGIN android-changed - Integer tagNo = Integer.valueOf(subtree.getBase().getTagNo()); - // END android-changed + GeneralSubtree subtree = permitted[i]; + Integer tagNo = Integers.valueOf(subtree.getBase().getTagNo()); if (subtreesMap.get(tagNo) == null) { subtreesMap.put(tagNo, new HashSet()); 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 7357894..415f840 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java @@ -1669,7 +1669,7 @@ public class RFC3280CertPathUtilities // // (g) (1) permitted subtrees // - ASN1Sequence permitted = nc.getPermittedSubtrees(); + GeneralSubtree[] permitted = nc.getPermittedSubtrees(); if (permitted != null) { try @@ -1686,17 +1686,13 @@ public class RFC3280CertPathUtilities // // (g) (2) excluded subtrees // - ASN1Sequence excluded = nc.getExcludedSubtrees(); + GeneralSubtree[] excluded = nc.getExcludedSubtrees(); if (excluded != null) { - Enumeration e = excluded.getObjects(); + for (int i = 0; i != excluded.length; i++) try { - while (e.hasMoreElements()) - { - GeneralSubtree subtree = GeneralSubtree.getInstance(e.nextElement()); - nameConstraintValidator.addExcludedSubtree(subtree); - } + nameConstraintValidator.addExcludedSubtree(excluded[i]); } catch (Exception ex) { @@ -2203,7 +2199,7 @@ public class RFC3280CertPathUtilities } if (!criticalExtensions.isEmpty()) { - throw new ExtCertPathValidatorException("Certificate has unsupported critical extension.", null, certPath, + throw new ExtCertPathValidatorException("Certificate has unsupported critical extension: " + criticalExtensions, null, certPath, index); } } @@ -2384,7 +2380,7 @@ public class RFC3280CertPathUtilities if (!criticalExtensions.isEmpty()) { - throw new ExtCertPathValidatorException("Certificate has unsupported critical extension", null, certPath, + throw new ExtCertPathValidatorException("Certificate has unsupported critical extension: " + criticalExtensions, null, certPath, index); } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java index da7ee11..d5c3700 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java @@ -12,9 +12,9 @@ import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLReason; @@ -24,7 +24,6 @@ import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.asn1.x509.X509Extension; -import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * The following extensions are listed in RFC 2459 as relevant to CRL Entries @@ -90,7 +89,7 @@ public class X509CRLEntryObject extends X509CRLEntry return null; } - byte[] ext = getExtensionValue(X509Extension.certificateIssuer.getId()); + Extension ext = getExtension(Extension.certificateIssuer); if (ext == null) { return previousCertificateIssuer; @@ -98,8 +97,7 @@ public class X509CRLEntryObject extends X509CRLEntry try { - GeneralName[] names = GeneralNames.getInstance( - X509ExtensionUtil.fromExtensionValue(ext)).getNames(); + GeneralName[] names = GeneralNames.getInstance(ext.getParsedValue()).getNames(); for (int i = 0; i < names.length; i++) { if (names[i].getTagNo() == GeneralName.directoryName) @@ -109,7 +107,7 @@ public class X509CRLEntryObject extends X509CRLEntry } return null; } - catch (IOException e) + catch (Exception e) { return null; } @@ -167,24 +165,31 @@ public class X509CRLEntryObject extends X509CRLEntry return getExtensionOIDs(false); } - public byte[] getExtensionValue(String oid) + private Extension getExtension(ASN1ObjectIdentifier oid) { Extensions exts = c.getExtensions(); if (exts != null) { - Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); + return exts.getExtension(oid); + } + + return null; + } + + public byte[] getExtensionValue(String oid) + { + Extension ext = getExtension(new ASN1ObjectIdentifier(oid)); - if (ext != null) + if (ext != null) + { + try { - try - { - return ext.getExtnValue().getEncoded(); - } - catch (Exception e) - { - throw new RuntimeException("error encoding " + e.toString()); - } + return ext.getExtnValue().getEncoded(); + } + catch (Exception e) + { + throw new RuntimeException("error encoding " + e.toString()); } } @@ -265,7 +270,7 @@ public class X509CRLEntryObject extends X509CRLEntry { if (oid.equals(X509Extension.reasonCode)) { - buf.append(CRLReason.getInstance(DEREnumerated.getInstance(dIn.readObject()))).append(nl); + buf.append(CRLReason.getInstance(ASN1Enumerated.getInstance(dIn.readObject()))).append(nl); } else if (oid.equals(X509Extension.certificateIssuer)) { 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 4c87114..cd83211 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java @@ -27,8 +27,9 @@ import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DERInteger; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLDistPoint; @@ -41,7 +42,6 @@ import org.bouncycastle.asn1.x509.IssuingDistributionPoint; import org.bouncycastle.asn1.x509.TBSCertList; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.encoders.Hex; -import org.bouncycastle.x509.extension.X509ExtensionUtil; /** * The following extensions are listed in RFC 2459 as relevant to CRLs @@ -67,7 +67,7 @@ public class X509CRLObject { byte[] idp = crl.getExtensionValue(Extension.issuingDistributionPoint.getId()); return idp != null - && IssuingDistributionPoint.getInstance(X509ExtensionUtil.fromExtensionValue(idp)).isIndirectCRL(); + && IssuingDistributionPoint.getInstance(ASN1OctetString.getInstance(idp).getOctets()).isIndirectCRL(); } catch (Exception e) { @@ -444,7 +444,7 @@ public class X509CRLObject if (oid.equals(Extension.cRLNumber)) { buf.append( - new CRLNumber(DERInteger.getInstance( + new CRLNumber(ASN1Integer.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } @@ -452,7 +452,7 @@ public class X509CRLObject { buf.append( "Base CRL: " - + new CRLNumber(DERInteger.getInstance( + + new CRLNumber(ASN1Integer.getInstance( dIn.readObject()).getPositiveValue())) .append(nl); } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java index e529836..0ae61d2 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java @@ -3,6 +3,8 @@ package org.bouncycastle.jce.provider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; @@ -20,6 +22,7 @@ import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; @@ -36,33 +39,39 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DERObjectIdentifier; +import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.misc.NetscapeCertType; import org.bouncycastle.asn1.misc.NetscapeRevocationURL; import org.bouncycastle.asn1.misc.VerisignCzagExtension; import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.style.RFC4519Style; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.Extensions; +import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.KeyUsage; -import org.bouncycastle.asn1.x509.X509CertificateStructure; -import org.bouncycastle.asn1.x509.X509Extension; -import org.bouncycastle.asn1.x509.X509Extensions; +// BEGIN android-added +import org.bouncycastle.asn1.x509.X509Name; +// END android-added import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; import org.bouncycastle.util.encoders.Hex; public class X509CertificateObject extends X509Certificate implements PKCS12BagAttributeCarrier { - private X509CertificateStructure c; + private org.bouncycastle.asn1.x509.Certificate c; private BasicConstraints basicConstraints; private boolean[] keyUsage; private boolean hashValueSet; @@ -71,7 +80,7 @@ public class X509CertificateObject private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl(); public X509CertificateObject( - X509CertificateStructure c) + org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException { this.c = c; @@ -141,7 +150,7 @@ public class X509CertificateObject public int getVersion() { - return c.getVersion(); + return c.getVersionNumber(); } public BigInteger getSerialNumber() @@ -268,7 +277,7 @@ public class X509CertificateObject */ public String getSigAlgOID() { - return c.getSignatureAlgorithm().getObjectId().getId(); + return c.getSignatureAlgorithm().getAlgorithm().getId(); } /** @@ -353,7 +362,7 @@ public class X509CertificateObject for (int i = 0; i != seq.size(); i++) { - list.add(((DERObjectIdentifier)seq.getObjectAt(i)).getId()); + list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId()); } return Collections.unmodifiableList(list); @@ -391,12 +400,24 @@ public class X509CertificateObject return -1; } + public Collection getSubjectAlternativeNames() + throws CertificateParsingException + { + return getAlternativeNames(getExtensionBytes(Extension.subjectAlternativeName.getId())); + } + + public Collection getIssuerAlternativeNames() + throws CertificateParsingException + { + return getAlternativeNames(getExtensionBytes(Extension.issuerAlternativeName.getId())); + } + public Set getCriticalExtensionOIDs() { if (this.getVersion() == 3) { Set set = new HashSet(); - X509Extensions extensions = c.getTBSCertificate().getExtensions(); + Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { @@ -404,8 +425,8 @@ public class X509CertificateObject while (e.hasMoreElements()) { - DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); - X509Extension ext = extensions.getExtension(oid); + ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); + Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { @@ -422,14 +443,14 @@ public class X509CertificateObject private byte[] getExtensionBytes(String oid) { - X509Extensions exts = c.getTBSCertificate().getExtensions(); + Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { - X509Extension ext = exts.getExtension(new DERObjectIdentifier(oid)); + Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { - return ext.getValue().getOctets(); + return ext.getExtnValue().getOctets(); } } @@ -438,17 +459,17 @@ public class X509CertificateObject public byte[] getExtensionValue(String oid) { - X509Extensions exts = c.getTBSCertificate().getExtensions(); + Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { - X509Extension ext = exts.getExtension(new DERObjectIdentifier(oid)); + Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid)); if (ext != null) { try { - return ext.getValue().getEncoded(); + return ext.getExtnValue().getEncoded(); } catch (Exception e) { @@ -465,7 +486,7 @@ public class X509CertificateObject if (this.getVersion() == 3) { Set set = new HashSet(); - X509Extensions extensions = c.getTBSCertificate().getExtensions(); + Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { @@ -473,8 +494,8 @@ public class X509CertificateObject while (e.hasMoreElements()) { - DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); - X509Extension ext = extensions.getExtension(oid); + ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); + Extension ext = extensions.getExtension(oid); if (!ext.isCritical()) { @@ -493,7 +514,7 @@ public class X509CertificateObject { if (this.getVersion() == 3) { - X509Extensions extensions = c.getTBSCertificate().getExtensions(); + Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { @@ -501,7 +522,7 @@ public class X509CertificateObject while (e.hasMoreElements()) { - DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); + ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); String oidId = oid.getId(); if (oidId.equals(RFC3280CertPathUtilities.KEY_USAGE) @@ -519,7 +540,7 @@ public class X509CertificateObject continue; } - X509Extension ext = extensions.getExtension(oid); + Extension ext = extensions.getExtension(oid); if (ext.isCritical()) { @@ -630,7 +651,7 @@ public class X509CertificateObject } public ASN1Encodable getBagAttribute( - DERObjectIdentifier oid) + ASN1ObjectIdentifier oid) { return attrCarrier.getBagAttribute(oid); } @@ -669,7 +690,7 @@ public class X509CertificateObject } } - X509Extensions extensions = c.getTBSCertificate().getExtensions(); + Extensions extensions = c.getTBSCertificate().getExtensions(); if (extensions != null) { @@ -682,23 +703,23 @@ public class X509CertificateObject while (e.hasMoreElements()) { - DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); - X509Extension ext = extensions.getExtension(oid); + ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); + Extension ext = extensions.getExtension(oid); - if (ext.getValue() != null) + if (ext.getExtnValue() != null) { - byte[] octs = ext.getValue().getOctets(); + byte[] octs = ext.getExtnValue().getOctets(); ASN1InputStream dIn = new ASN1InputStream(octs); buf.append(" critical(").append(ext.isCritical()).append(") "); try { - if (oid.equals(X509Extension.basicConstraints)) + if (oid.equals(Extension.basicConstraints)) { buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl); } - else if (oid.equals(X509Extension.keyUsage)) + else if (oid.equals(Extension.keyUsage)) { - buf.append(new KeyUsage((DERBitString)dIn.readObject())).append(nl); + buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl); } else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) { @@ -722,7 +743,7 @@ public class X509CertificateObject catch (Exception ex) { buf.append(oid.getId()); - // buf.append(" value = ").append(new String(Hex.encode(ext.getValue().getOctets()))).append(nl); + // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl); buf.append(" value = ").append("*****").append(nl); } } @@ -796,7 +817,7 @@ public class X509CertificateObject private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) { - if (!id1.getObjectId().equals(id2.getObjectId())) + if (!id1.getAlgorithm().equals(id2.getAlgorithm())) { return false; } @@ -823,4 +844,71 @@ public class X509CertificateObject return id1.getParameters().equals(id2.getParameters()); } + + private static Collection getAlternativeNames(byte[] extVal) + throws CertificateParsingException + { + if (extVal == null) + { + return null; + } + try + { + Collection temp = new ArrayList(); + Enumeration it = ASN1Sequence.getInstance(extVal).getObjects(); + while (it.hasMoreElements()) + { + GeneralName genName = GeneralName.getInstance(it.nextElement()); + List list = new ArrayList(); + list.add(Integers.valueOf(genName.getTagNo())); + switch (genName.getTagNo()) + { + case GeneralName.ediPartyName: + case GeneralName.x400Address: + case GeneralName.otherName: + list.add(genName.getEncoded()); + break; + case GeneralName.directoryName: + // BEGIN android-changed + list.add(X509Name.getInstance(genName.getName()).toString(true, X509Name.DefaultSymbols)); + // END android-changed + break; + case GeneralName.dNSName: + case GeneralName.rfc822Name: + case GeneralName.uniformResourceIdentifier: + list.add(((ASN1String)genName.getName()).getString()); + break; + case GeneralName.registeredID: + list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId()); + break; + case GeneralName.iPAddress: + byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets(); + final String addr; + try + { + addr = InetAddress.getByAddress(addrBytes).getHostAddress(); + } + catch (UnknownHostException e) + { + continue; + } + list.add(addr); + break; + default: + throw new IOException("Bad tag number: " + genName.getTagNo()); + } + + temp.add(Collections.unmodifiableList(list)); + } + if (temp.size() == 0) + { + return null; + } + return Collections.unmodifiableCollection(temp); + } + catch (Exception e) + { + throw new CertificateParsingException(e.getMessage()); + } + } } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509SignatureUtil.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509SignatureUtil.java index 8e492dc..3e2b1ce 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509SignatureUtil.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509SignatureUtil.java @@ -27,9 +27,7 @@ import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; class X509SignatureUtil { - // BEGIN android-changed private static final ASN1Null derNull = DERNull.INSTANCE; - // END android-changed static void setSignatureParameters( Signature signature, diff --git a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java index 4564b68..d1c3111 100644 --- a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java +++ b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java @@ -238,7 +238,17 @@ public final class Arrays array[i] = value; } } - + + public static void fill( + char[] array, + char value) + { + for (int i = 0; i < array.length; i++) + { + array[i] = value; + } + } + public static void fill( long[] array, long value) @@ -307,6 +317,18 @@ public final class Arrays return hc; } + public static int hashCode(int[][] ints) + { + int hc = 0; + + for (int i = 0; i != ints.length; i++) + { + hc = hc * 257 + hashCode(ints[i]); + } + + return hc; + } + public static int hashCode(int[] data) { if (data == null) @@ -326,6 +348,49 @@ public final class Arrays return hc; } + public static int hashCode(short[][][] shorts) + { + int hc = 0; + + for (int i = 0; i != shorts.length; i++) + { + hc = hc * 257 + hashCode(shorts[i]); + } + + return hc; + } + + public static int hashCode(short[][] shorts) + { + int hc = 0; + + for (int i = 0; i != shorts.length; i++) + { + hc = hc * 257 + hashCode(shorts[i]); + } + + return hc; + } + + public static int hashCode(short[] data) + { + if (data == null) + { + return 0; + } + + int i = data.length; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= (data[i] & 0xff); + } + + return hc; + } + public static int hashCode(BigInteger[] data) { if (data == null) @@ -371,6 +436,19 @@ public final class Arrays return copy; } + public static short[] clone(short[] data) + { + if (data == null) + { + return null; + } + short[] copy = new short[data.length]; + + System.arraycopy(data, 0, copy, 0, data.length); + + return copy; + } + public static BigInteger[] clone(BigInteger[] data) { if (data == null) @@ -400,6 +478,22 @@ public final class Arrays return tmp; } + public static char[] copyOf(char[] data, int newLength) + { + char[] tmp = new char[newLength]; + + if (newLength < data.length) + { + System.arraycopy(data, 0, tmp, 0, newLength); + } + else + { + System.arraycopy(data, 0, tmp, 0, data.length); + } + + return tmp; + } + public static int[] copyOf(int[] data, int newLength) { int[] tmp = new int[newLength]; @@ -525,7 +619,9 @@ public final class Arrays int newLength = to - from; if (newLength < 0) { - throw new IllegalArgumentException(from + " > " + to); + StringBuffer sb = new StringBuffer(from); + sb.append(" > ").append(to); + throw new IllegalArgumentException(sb.toString()); } return newLength; } diff --git a/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java b/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java index 2115799..e2fe590 100644 --- a/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java +++ b/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java @@ -35,6 +35,51 @@ public final class BigIntegers } /** + * Return the passed in value as an unsigned byte array. + * + * @param value value to be converted. + * @return a byte array without a leading zero byte if present in the signed encoding. + */ + public static byte[] asUnsignedByteArray( + int length, + BigInteger value) + { + byte[] bytes = value.toByteArray(); + + if (bytes[0] == 0) + { + if (bytes.length - 1 > length) + { + throw new IllegalArgumentException("standard length exceeded for value"); + } + + byte[] tmp = new byte[length]; + + System.arraycopy(bytes, 1, tmp, tmp.length - (bytes.length - 1), bytes.length - 1); + + return tmp; + } + else + { + if (bytes.length == length) + { + return bytes; + } + + if (bytes.length > length) + { + throw new IllegalArgumentException("standard length exceeded for value"); + } + + byte[] tmp = new byte[length]; + + System.arraycopy(bytes, 0, tmp, tmp.length - bytes.length, bytes.length); + + return tmp; + } + } + + /** * Return a random BigInteger not less than 'min' and not greater than 'max' * * @param min the least value that may be generated diff --git a/bcprov/src/main/java/org/bouncycastle/util/Integers.java b/bcprov/src/main/java/org/bouncycastle/util/Integers.java new file mode 100644 index 0000000..599a9e0 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/util/Integers.java @@ -0,0 +1,9 @@ +package org.bouncycastle.util; + +public class Integers +{ + public static Integer valueOf(int value) + { + return Integer.valueOf(value); + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64.java index 93fed64..742a961 100644 --- a/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64.java +++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64.java @@ -23,9 +23,9 @@ public class Base64 { encoder.encode(data, 0, data.length, bOut); } - catch (IOException e) + catch (Exception e) { - throw new RuntimeException("exception encoding base64 string: " + e); + throw new EncoderException("exception encoding base64 string: " + e.getMessage(), e); } return bOut.toByteArray(); @@ -74,9 +74,9 @@ public class Base64 { encoder.decode(data, 0, data.length, bOut); } - catch (IOException e) + catch (Exception e) { - throw new RuntimeException("exception decoding base64 string: " + e); + throw new DecoderException("unable to decode base64 data: " + e.getMessage(), e); } return bOut.toByteArray(); @@ -97,9 +97,9 @@ public class Base64 { encoder.decode(data, bOut); } - catch (IOException e) + catch (Exception e) { - throw new RuntimeException("exception decoding base64 string: " + e); + throw new DecoderException("unable to decode base64 string: " + e.getMessage(), e); } return bOut.toByteArray(); diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java index 3edc068..1ef8f51 100644 --- a/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java +++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java @@ -31,6 +31,11 @@ public class Base64Encoder protected void initialiseDecodingTable() { + for (int i = 0; i < decodingTable.length; i++) + { + decodingTable[i] = (byte)0xff; + } + for (int i = 0; i < encodingTable.length; i++) { decodingTable[encodingTable[i]] = (byte)i; @@ -163,6 +168,11 @@ public class Base64Encoder b4 = decodingTable[data[i++]]; + if ((b1 | b2 | b3 | b4) < 0) + { + throw new IOException("invalid characters encountered in base64 data"); + } + out.write((b1 << 2) | (b2 >> 4)); out.write((b2 << 4) | (b3 >> 2)); out.write((b3 << 6) | b4); @@ -233,6 +243,11 @@ public class Base64Encoder b4 = decodingTable[data.charAt(i++)]; + if ((b1 | b2 | b3 | b4) < 0) + { + throw new IOException("invalid characters encountered in base64 data"); + } + out.write((b1 << 2) | (b2 >> 4)); out.write((b2 << 4) | (b3 >> 2)); out.write((b3 << 6) | b4); @@ -257,6 +272,11 @@ public class Base64Encoder b1 = decodingTable[c1]; b2 = decodingTable[c2]; + if ((b1 | b2) < 0) + { + throw new IOException("invalid characters encountered at end of base64 data"); + } + out.write((b1 << 2) | (b2 >> 4)); return 1; @@ -267,6 +287,11 @@ public class Base64Encoder b2 = decodingTable[c2]; b3 = decodingTable[c3]; + if ((b1 | b2 | b3) < 0) + { + throw new IOException("invalid characters encountered at end of base64 data"); + } + out.write((b1 << 2) | (b2 >> 4)); out.write((b2 << 4) | (b3 >> 2)); @@ -279,6 +304,11 @@ public class Base64Encoder b3 = decodingTable[c3]; b4 = decodingTable[c4]; + if ((b1 | b2 | b3 | b4) < 0) + { + throw new IOException("invalid characters encountered at end of base64 data"); + } + out.write((b1 << 2) | (b2 >> 4)); out.write((b2 << 4) | (b3 >> 2)); out.write((b3 << 6) | b4); diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/DecoderException.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/DecoderException.java new file mode 100644 index 0000000..d9914a2 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/DecoderException.java @@ -0,0 +1,19 @@ +package org.bouncycastle.util.encoders; + +public class DecoderException + extends IllegalStateException +{ + private Throwable cause; + + DecoderException(String msg, Throwable cause) + { + super(msg); + + this.cause = cause; + } + + public Throwable getCause() + { + return cause; + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/EncoderException.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/EncoderException.java new file mode 100644 index 0000000..2d09a63 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/EncoderException.java @@ -0,0 +1,19 @@ +package org.bouncycastle.util.encoders; + +public class EncoderException + extends IllegalStateException +{ + private Throwable cause; + + EncoderException(String msg, Throwable cause) + { + super(msg); + + this.cause = cause; + } + + public Throwable getCause() + { + return cause; + } +} diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/Hex.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/Hex.java index d69f773..3d058aa 100644 --- a/bcprov/src/main/java/org/bouncycastle/util/encoders/Hex.java +++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/Hex.java @@ -35,9 +35,9 @@ public class Hex { encoder.encode(data, off, length, bOut); } - catch (IOException e) + catch (Exception e) { - throw new RuntimeException("exception encoding Hex string: " + e); + throw new EncoderException("exception encoding Hex string: " + e.getMessage(), e); } return bOut.toByteArray(); @@ -85,9 +85,9 @@ public class Hex { encoder.decode(data, 0, data.length, bOut); } - catch (IOException e) + catch (Exception e) { - throw new RuntimeException("exception decoding Hex string: " + e); + throw new DecoderException("exception decoding Hex data: " + e.getMessage(), e); } return bOut.toByteArray(); @@ -107,9 +107,9 @@ public class Hex { encoder.decode(data, bOut); } - catch (IOException e) + catch (Exception e) { - throw new RuntimeException("exception decoding Hex string: " + e); + throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e); } return bOut.toByteArray(); diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java index 0dcae29..3bb594b 100644 --- a/bcprov/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java +++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java @@ -19,6 +19,11 @@ public class HexEncoder protected void initialiseDecodingTable() { + for (int i = 0; i < decodingTable.length; i++) + { + decodingTable[i] = (byte)0xff; + } + for (int i = 0; i < encodingTable.length; i++) { decodingTable[encodingTable[i]] = (byte)i; @@ -60,12 +65,12 @@ public class HexEncoder return length * 2; } - private boolean ignore( + private static boolean ignore( char c) { - return (c == '\n' || c =='\r' || c == '\t' || c == ' '); + return c == '\n' || c =='\r' || c == '\t' || c == ' '; } - + /** * decode the Hex encoded byte data writing it to the given output stream, * whitespace characters will be ignored. @@ -111,6 +116,11 @@ public class HexEncoder b2 = decodingTable[data[i++]]; + if ((b1 | b2) < 0) + { + throw new IOException("invalid characters encountered in Hex data"); + } + out.write((b1 << 4) | b2); outLen++; @@ -162,6 +172,11 @@ public class HexEncoder b2 = decodingTable[data.charAt(i++)]; + if ((b1 | b2) < 0) + { + throw new IOException("invalid characters encountered in Hex string"); + } + out.write((b1 << 4) | b2); length++; diff --git a/bcprov/src/main/java/org/bouncycastle/x509/X509Util.java b/bcprov/src/main/java/org/bouncycastle/x509/X509Util.java index 13426c1..53b21af 100644 --- a/bcprov/src/main/java/org/bouncycastle/x509/X509Util.java +++ b/bcprov/src/main/java/org/bouncycastle/x509/X509Util.java @@ -135,31 +135,21 @@ class X509Util // // explicit params // - // BEGIN android-changed AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); - // END android-changed params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20)); // BEGIN android-removed - // // BEGIN android-changed // AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE); - // // END android-changed // params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28)); // END android-removed - // BEGIN android-changed AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE); - // END android-changed params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32)); - // BEGIN android-changed AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE); - // END android-changed params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48)); - // BEGIN android-changed AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE); - // END android-changed params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64)); } @@ -202,9 +192,7 @@ class X509Util } else { - // BEGIN android-changed return new AlgorithmIdentifier(sigOid, DERNull.INSTANCE); - // END android-changed } } diff --git a/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java b/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java index 5703dc8..ac44d73 100644 --- a/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java +++ b/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java @@ -27,11 +27,11 @@ import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator; -import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.X509CertificateObject; @@ -357,7 +357,7 @@ public class X509V1CertificateGenerator try { - return new X509CertificateObject(new X509CertificateStructure(new DERSequence(v))); + return new X509CertificateObject(Certificate.getInstance(new DERSequence(v))); } catch (CertificateParsingException e) { diff --git a/bcprov/src/main/java/org/bouncycastle/x509/X509V3CertificateGenerator.java b/bcprov/src/main/java/org/bouncycastle/x509/X509V3CertificateGenerator.java index 870ba4f..d216295 100644 --- a/bcprov/src/main/java/org/bouncycastle/x509/X509V3CertificateGenerator.java +++ b/bcprov/src/main/java/org/bouncycastle/x509/X509V3CertificateGenerator.java @@ -27,11 +27,11 @@ import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; -import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509ExtensionsGenerator; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.X509Principal; @@ -512,7 +512,7 @@ public class X509V3CertificateGenerator v.add(sigAlgId); v.add(new DERBitString(signature)); - return new X509CertificateObject(new X509CertificateStructure(new DERSequence(v))); + return new X509CertificateObject(Certificate.getInstance(new DERSequence(v))); } /** diff --git a/bcprov/src/main/java/org/bouncycastle/x509/extension/X509ExtensionUtil.java b/bcprov/src/main/java/org/bouncycastle/x509/extension/X509ExtensionUtil.java index 048f31b..2e4d14d 100644 --- a/bcprov/src/main/java/org/bouncycastle/x509/extension/X509ExtensionUtil.java +++ b/bcprov/src/main/java/org/bouncycastle/x509/extension/X509ExtensionUtil.java @@ -18,6 +18,7 @@ import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509Extension; +import org.bouncycastle.util.Integers; public class X509ExtensionUtil @@ -62,9 +63,7 @@ public class X509ExtensionUtil { GeneralName genName = GeneralName.getInstance(it.nextElement()); List list = new ArrayList(); - // BEGIN android-changed - list.add(Integer.valueOf(genName.getTagNo())); - // END android-changed + list.add(Integers.valueOf(genName.getTagNo())); switch (genName.getTagNo()) { case GeneralName.ediPartyName: |