am a5e1ef4e: am 9576bbd3: (-s ours) am 810a7295: (-s ours) Reconcile with jb-mr1-release - do not merge

* commit 'a5e1ef4ee0f02d186c96f40690f880e949d10b73':
diff --git a/Android.mk b/Android.mk
index 71dd898..1a8345c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -82,8 +82,6 @@
     LOCAL_MODULE_TAGS := optional
     LOCAL_SRC_FILES := $(android_bcprov_src_files)
     LOCAL_JAVACFLAGS := -encoding UTF-8
-    LOCAL_JAVA_LIBRARIES := core-hostdex
-    LOCAL_NO_STANDARD_LIBRARIES := true
     LOCAL_BUILD_HOST_DEX := true
     LOCAL_MODULE_TAGS := optional
     LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
diff --git a/README.android b/README.android
index ec227bb..3dfa8bf 100644
--- a/README.android
+++ b/README.android
@@ -76,9 +76,33 @@
        libcore/luni/src/test/java/tests/security/cert/CertStore2Test.java
        libcore/luni/src/test/java/tests/security/cert/CertStore1Test.java
        libcore/luni/src/test/java/tests/security/cert/CertStoreExceptionTest.java
+     - java.security.cert.Certificate
+       libcore/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
+       libcore/luni/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateCertificateRepTest.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateTest.java
+       libcore/luni/src/test/java/tests/security/cert/X509Certificate2Test.java
+       libcore/luni/src/test/java/tests/targets/security/cert/CertificateTest.java
      - java.security.cert.CertificateFactory
        libcore/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateFactory1Test.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateFactory2Test.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateFactory3Test.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateFactory4Test.java
        libcore/luni/src/test/java/tests/targets/security/cert/CertificateFactoryTestX509.java
+     - java.security.cert.CertificateFactorySpi
+       libcore/luni/src/test/java/tests/security/cert/CertificateFactorySpiTest.java
+     - java.security.cert.CRL
+       libcore/luni/src/test/java/libcore/java/security/cert/X509CRLSelectorTest.java
+       libcore/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
+       libcore/luni/src/test/java/tests/security/cert/CRLTest.java
+       libcore/luni/src/test/java/tests/security/cert/X509CRL2Test.java
+       libcore/luni/src/test/java/tests/security/cert/X509CRLEntryTest.java
+       libcore/luni/src/test/java/tests/security/cert/X509CRLSelector2Test.java
+       libcore/luni/src/test/java/tests/security/cert/X509CRLSelectorTest.java
+       libcore/luni/src/test/java/tests/security/cert/X509CRLTest.java
+     - javax.security.cert.Certificate
+       libcore/luni/src/test/java/tests/api/javax/security/cert/CertificateTest.java
      - java.security.CodeSigner
        libcore/luni/src/test/java/org/apache/harmony/security/tests/java/security/CodeSignerTest.java
      - javax.crypto.Cipher
@@ -222,6 +246,19 @@
        libcore/luni/src/test/java/org/apache/harmony/security/tests/java/security/SignatureExceptionTest.java
        libcore/luni/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableEntryExceptionTest.java
        libcore/luni/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableKeyExceptionTest.java
+       libcore/luni/src/test/java/tests/api/javax/security/cert/CertificateEncodingExceptionTest.java
+       libcore/luni/src/test/java/tests/api/javax/security/cert/CertificateExceptionTest.java
+       libcore/luni/src/test/java/tests/api/javax/security/cert/CertificateExpiredExceptionTest.java
+       libcore/luni/src/test/java/tests/api/javax/security/cert/CertificateNotYetValidExceptionTest.java
+       libcore/luni/src/test/java/tests/api/javax/security/cert/CertificateParsingExceptionTest.java
+       libcore/luni/src/test/java/tests/security/cert/CRLExceptionTest.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateEncodingException2Test.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateEncodingExceptionTest.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateException2Test.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateExceptionTest.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateExpiredExceptionTest.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateNotYetValidExceptionTest.java
+       libcore/luni/src/test/java/tests/security/cert/CertificateParsingExceptionTest.java
 
 
 8) Do a full build before checking in:
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java
index f354bc7..074d3fc 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java
@@ -261,7 +261,7 @@
 
     public Object clone()
     {
-        return new AttributeCertificateHolder((ASN1Sequence)holder.toASN1Object());
+        return new AttributeCertificateHolder((ASN1Sequence)holder.toASN1Primitive());
     }
 
     public boolean match(Object obj)
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java b/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java
index e3c2079..9e2e488 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java
@@ -13,9 +13,10 @@
 
 import org.bouncycastle.asn1.ASN1Encodable;
 import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1GeneralizedTime;
 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.DERBitString;
-import org.bouncycastle.asn1.DERGeneralizedTime;
+import org.bouncycastle.asn1.DERNull;
 import org.bouncycastle.asn1.DEROutputStream;
 import org.bouncycastle.asn1.DERSequence;
 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
@@ -199,7 +200,7 @@
         return null;
     }
 
-    static Date recoverDate(DERGeneralizedTime time)
+    static Date recoverDate(ASN1GeneralizedTime time)
     {
         try
         {
@@ -210,4 +211,34 @@
             throw new IllegalStateException("unable to recover date: " + e.getMessage());
         }
     }
+
+    static boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
+    {
+        if (!id1.getAlgorithm().equals(id2.getAlgorithm()))
+        {
+            return false;
+        }
+
+        if (id1.getParameters() == null)
+        {
+            if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        if (id2.getParameters() == null)
+        {
+            if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        return id1.getParameters().equals(id2.getParameters());
+    }
 }
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java
index e2ce015..a34b3b3 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java
@@ -213,6 +213,16 @@
     }
 
     /**
+     * Return the extensions block associated with this certificate if there is one.
+     *
+     * @return the extensions block, null otherwise.
+     */
+    public Extensions getExtensions()
+    {
+        return extensions;
+    }
+
+    /**
      * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the
      * extensions contained in this holder's attribute certificate.
      *
@@ -305,7 +315,7 @@
     {
         AttributeCertificateInfo acinfo = attrCert.getAcinfo();
 
-        if (!acinfo.getSignature().equals(attrCert.getSignatureAlgorithm()))
+        if (!CertUtils.isAlgIdEqual(acinfo.getSignature(), attrCert.getSignatureAlgorithm()))
         {
             throw new CertException("signature invalid - algorithm identifier mismatch");
         }
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLEntryHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLEntryHolder.java
index c6b4d3d..a10f014 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLEntryHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLEntryHolder.java
@@ -100,6 +100,16 @@
     }
 
     /**
+     * Return the extensions block associated with this CRL entry if there is one.
+     *
+     * @return the extensions block, null otherwise.
+     */
+    public Extensions getExtensions()
+    {
+        return entry.getExtensions();
+    }
+
+    /**
      * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the
      * extensions contained in this holder's CRL entry.
      *
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
index 3bb2327..b3723f3 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
@@ -202,6 +202,16 @@
     }
 
     /**
+     * Return the extensions block associated with this CRL if there is one.
+     *
+     * @return the extensions block, null otherwise.
+     */
+    public Extensions getExtensions()
+    {
+        return extensions;
+    }
+
+    /**
      * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the
      * extensions contained in this holder's CRL.
      *
@@ -256,7 +266,7 @@
     {
         TBSCertList tbsCRL = x509CRL.getTBSCertList();
 
-        if (!tbsCRL.getSignature().equals(x509CRL.getSignatureAlgorithm()))
+        if (!CertUtils.isAlgIdEqual(tbsCRL.getSignature(), x509CRL.getSignatureAlgorithm()))
         {
             throw new CertException("signature invalid - algorithm identifier mismatch");
         }
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
index 52d5bcf..1081d93 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
@@ -109,6 +109,16 @@
     }
 
     /**
+     * Return the extensions block associated with this certificate if there is one.
+     *
+     * @return the extensions block, null otherwise.
+     */
+    public Extensions getExtensions()
+    {
+        return extensions;
+    }
+
+    /**
      * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the
      * extensions contained in this holder's certificate.
      *
@@ -254,7 +264,7 @@
     {
         TBSCertificate tbsCert = x509Certificate.getTBSCertificate();
 
-        if (!tbsCert.getSignature().equals(x509Certificate.getSignatureAlgorithm()))
+        if (!CertUtils.isAlgIdEqual(tbsCert.getSignature(), x509Certificate.getSignatureAlgorithm()))
         {
             throw new CertException("signature invalid - algorithm identifier mismatch");
         }
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSProcessableByteArray.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSProcessableByteArray.java
index 2b2c354..1c79a94 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSProcessableByteArray.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSProcessableByteArray.java
@@ -7,6 +7,7 @@
 
 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
+import org.bouncycastle.util.Arrays;
 
 /**
  * a holding class for a byte array of data to be processed.
@@ -44,7 +45,7 @@
 
     public Object getContent()
     {
-        return bytes.clone();
+        return Arrays.clone(bytes);
     }
 
     public ASN1ObjectIdentifier getContentType()
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
index 7a8adeb..c976dfe 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
@@ -2,6 +2,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.Provider;
@@ -74,7 +75,7 @@
     
     SignedData              signedData;
     ContentInfo             contentInfo;
-    CMSProcessable          signedContent;
+    CMSTypedData            signedContent;
     SignerInformationStore  signerInfoStore;
     X509Store               attributeStore;
     X509Store               certificateStore;
@@ -144,11 +145,36 @@
     }
 
     public CMSSignedData(
-        CMSProcessable  signedContent,
+        final CMSProcessable  signedContent,
         ContentInfo     sigData)
         throws CMSException
     {
-        this.signedContent = signedContent;
+        if (signedContent instanceof CMSTypedData)
+        {
+            this.signedContent = (CMSTypedData)signedContent;
+        }
+        else
+        {
+            this.signedContent = new CMSTypedData()
+            {
+                public ASN1ObjectIdentifier getContentType()
+                {
+                    return signedData.getEncapContentInfo().getContentType();
+                }
+
+                public void write(OutputStream out)
+                    throws IOException, CMSException
+                {
+                    signedContent.write(out);
+                }
+
+                public Object getContent()
+                {
+                    return signedContent.getContent();
+                }
+            };
+        }
+
         this.contentInfo = sigData;
         this.signedData = getSignedData();
     }
@@ -176,7 +202,7 @@
         //
         if (signedData.getEncapContentInfo().getContent() != null)
         {
-            this.signedContent = new CMSProcessableByteArray(
+            this.signedContent = new CMSProcessableByteArray(signedData.getEncapContentInfo().getContentType(),
                     ((ASN1OctetString)(signedData.getEncapContentInfo()
                                                 .getContent())).getOctets());
         }
@@ -498,7 +524,7 @@
         return signedData.getEncapContentInfo().getContentType().getId();
     }
     
-    public CMSProcessable getSignedContent()
+    public CMSTypedData getSignedContent()
     {
         return signedContent;
     }
@@ -604,6 +630,7 @@
      * @param certsAndCrls the new certificates and CRLs to be used.
      * @return a new signed data object.
      * @exception CMSException if there is an error processing the CertStore
+     * @deprecated use method taking Store arguments.
      */
     public static CMSSignedData replaceCertificatesAndCRLs(
         CMSSignedData   signedData,
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java
index d269345..365522d 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java
@@ -15,9 +15,9 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.ASN1Primitive;
 import org.bouncycastle.asn1.ASN1Set;
-import org.bouncycastle.asn1.DERObjectIdentifier;
 import org.bouncycastle.asn1.DERSet;
 import org.bouncycastle.asn1.DERTaggedObject;
 import org.bouncycastle.asn1.cms.AttributeTable;
@@ -168,7 +168,7 @@
         return encOID;
     }
 
-    protected Map getBaseParameters(DERObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
+    protected Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
     {
         Map param = new HashMap();
         param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType);
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java
index 192704f..457a97e 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java
@@ -17,12 +17,12 @@
 import java.util.Map;
 
 import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.ASN1Primitive;
 import org.bouncycastle.asn1.ASN1Sequence;
 import org.bouncycastle.asn1.ASN1Set;
 import org.bouncycastle.asn1.ASN1TaggedObject;
 import org.bouncycastle.asn1.DERNull;
-import org.bouncycastle.asn1.DERObjectIdentifier;
 // BEGIN android-removed
 // import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
 // END android-removed
@@ -47,7 +47,7 @@
     private static final Map     digestAlgs = new HashMap();
     private static final Map     digestAliases = new HashMap();
 
-    private static void addEntries(DERObjectIdentifier alias, String digest, String encryption)
+    private static void addEntries(ASN1ObjectIdentifier alias, String digest, String encryption)
     {
         digestAlgs.put(alias.getId(), digest);
         encryptionAlgs.put(alias.getId(), encryption);
@@ -405,18 +405,18 @@
     {
         if (algId.getParameters() == null)
         {
-            return new AlgorithmIdentifier(algId.getObjectId(), DERNull.INSTANCE);
+            return new AlgorithmIdentifier(algId.getAlgorithm(), DERNull.INSTANCE);
         }
 
         return algId;
     }
 
-    void setSigningEncryptionAlgorithmMapping(DERObjectIdentifier oid, String algorithmName)
+    void setSigningEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName)
     {
         encryptionAlgs.put(oid.getId(), algorithmName);
     }
 
-    void setSigningDigestAlgorithmMapping(DERObjectIdentifier oid, String algorithmName)
+    void setSigningDigestAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName)
     {
         digestAlgs.put(oid.getId(), algorithmName);
     }
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
index 75c6beb..907fcc0 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
@@ -28,9 +28,9 @@
 import org.bouncycastle.asn1.DERTaggedObject;
 import org.bouncycastle.asn1.cms.ContentInfo;
 import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
+import org.bouncycastle.asn1.x509.Certificate;
 import org.bouncycastle.asn1.x509.CertificateList;
-import org.bouncycastle.asn1.x509.TBSCertificateStructure;
-import org.bouncycastle.asn1.x509.X509CertificateStructure;
+import org.bouncycastle.asn1.x509.TBSCertificate;
 import org.bouncycastle.cert.X509AttributeCertificateHolder;
 import org.bouncycastle.cert.X509CRLHolder;
 import org.bouncycastle.cert.X509CertificateHolder;
@@ -69,8 +69,7 @@
             {
                 X509Certificate c = (X509Certificate)it.next();
 
-                certs.add(X509CertificateStructure.getInstance(
-                                                       ASN1Primitive.fromByteArray(c.getEncoded())));
+                certs.add(Certificate.getInstance(ASN1Primitive.fromByteArray(c.getEncoded())));
             }
 
             return certs;
@@ -222,12 +221,12 @@
         return octGen.getOctetOutputStream();
     }
 
-    static TBSCertificateStructure getTBSCertificateStructure(
+    static TBSCertificate getTBSCertificateStructure(
         X509Certificate cert)
     {
         try
         {
-            return TBSCertificateStructure.getInstance(
+            return TBSCertificate.getInstance(
                 ASN1Primitive.fromByteArray(cert.getTBSCertificate()));
         }
         catch (Exception e)
@@ -239,7 +238,7 @@
 
     static IssuerAndSerialNumber getIssuerAndSerialNumber(X509Certificate cert)
     {
-        TBSCertificateStructure tbsCert = getTBSCertificateStructure(cert);
+        TBSCertificate tbsCert = getTBSCertificateStructure(cert);
         return new IssuerAndSerialNumber(tbsCert.getIssuer(), tbsCert.getSerialNumber().getValue());
     }
 
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
index 965d121..8ba3686 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
@@ -4,7 +4,7 @@
 import java.util.Hashtable;
 import java.util.Map;
 
-import org.bouncycastle.asn1.DERObjectIdentifier;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.DEROctetString;
 import org.bouncycastle.asn1.DERSet;
 import org.bouncycastle.asn1.cms.Attribute;
@@ -63,8 +63,8 @@
 
         if (!std.containsKey(CMSAttributes.contentType))
         {
-            DERObjectIdentifier contentType = (DERObjectIdentifier)
-                parameters.get(CMSAttributeTableGenerator.CONTENT_TYPE);
+            ASN1ObjectIdentifier contentType = ASN1ObjectIdentifier.getInstance(
+                parameters.get(CMSAttributeTableGenerator.CONTENT_TYPE));
 
             // contentType will be null if we're trying to generate a counter signature.
             if (contentType != null)
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
index 06470c3..f5ac174 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
@@ -7,9 +7,9 @@
 import java.util.Map;
 
 import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.ASN1Integer;
 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.ASN1Set;
-import org.bouncycastle.asn1.DERObjectIdentifier;
 import org.bouncycastle.asn1.DEROctetString;
 import org.bouncycastle.asn1.DERSet;
 import org.bouncycastle.asn1.cms.AttributeTable;
@@ -121,6 +121,16 @@
         this.sigEncAlgFinder = sigEncAlgFinder;
     }
 
+    public SignerIdentifier getSID()
+    {
+    	return signerIdentifier;
+    }
+
+    public ASN1Integer getGeneratedVersion()
+    {
+    	return new ASN1Integer(signerIdentifier.isTagged() ? 3 : 1);
+    }
+
     public boolean hasAssociatedCertificate()
     {
         return certHolder != null;
@@ -245,7 +255,7 @@
         return null;
     }
 
-    private Map getBaseParameters(DERObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
+    private Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
     {
         Map param = new HashMap();
 
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
index 4526a2e..bd9703a 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
@@ -21,7 +21,7 @@
 import org.bouncycastle.asn1.ASN1OctetString;
 import org.bouncycastle.asn1.ASN1Primitive;
 import org.bouncycastle.asn1.ASN1Set;
-import org.bouncycastle.asn1.DERObjectIdentifier;
+import org.bouncycastle.asn1.DERNull;
 import org.bouncycastle.asn1.DERSet;
 import org.bouncycastle.asn1.cms.Attribute;
 import org.bouncycastle.asn1.cms.AttributeTable;
@@ -41,6 +41,7 @@
 import org.bouncycastle.operator.RawContentVerifier;
 import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
 import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.io.TeeOutputStream;
 
 /**
  * an expanded SignerInfo block from a CMS Signed message
@@ -143,7 +144,7 @@
      */
     public String getDigestAlgOID()
     {
-        return digestAlgorithm.getObjectId().getId();
+        return digestAlgorithm.getAlgorithm().getId();
     }
 
     /**
@@ -179,7 +180,7 @@
      */
     public String getEncryptionAlgOID()
     {
-        return encryptionAlgorithm.getObjectId().getId();
+        return encryptionAlgorithm.getAlgorithm().getId();
     }
 
     /**
@@ -358,9 +359,21 @@
         throws CMSException
     {
         String          encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID());
+        ContentVerifier contentVerifier;
 
         try
         {
+            contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, info.getDigestAlgorithm());
+        }
+        catch (OperatorCreationException e)
+        {
+            throw new CMSException("can't create content verifier: " + e.getMessage(), e);
+        }
+
+        try
+        {
+            OutputStream sigOut = contentVerifier.getOutputStream();
+
             if (resultDigest == null)
             {
                 DigestCalculator calc = verifier.getDigestCalculator(this.getDigestAlgorithmID());
@@ -368,11 +381,34 @@
                 {
                     OutputStream      digOut = calc.getOutputStream();
 
-                    content.write(digOut);
+                    if (signedAttributeSet == null)
+                    {
+                        if (contentVerifier instanceof RawContentVerifier)
+                        {
+                            content.write(digOut);
+                        }
+                        else
+                        {
+                            OutputStream cOut = new TeeOutputStream(digOut, sigOut);
+
+                            content.write(cOut);
+
+                            cOut.close();
+                        }
+                    }
+                    else
+                    {
+                        content.write(digOut);
+                        sigOut.write(this.getEncodedSignedAttributes());
+                    }
 
                     digOut.close();
                 }
-                else if (signedAttributeSet == null)
+                else if (signedAttributeSet != null)
+                {
+                    sigOut.write(this.getEncodedSignedAttributes());
+                }
+                else
                 {
                     // TODO Get rid of this exception and just treat content==null as empty not missing?
                     throw new CMSException("data not encapsulated in signature - use detached constructor.");
@@ -380,6 +416,22 @@
 
                 resultDigest = calc.getDigest();
             }
+            else
+            {
+                if (signedAttributeSet == null)
+                {
+                    if (content != null)
+                    {
+                        content.write(sigOut);
+                    }
+                }
+                else
+                {
+                    sigOut.write(this.getEncodedSignedAttributes());
+                }
+            }
+
+            sigOut.close();
         }
         catch (IOException e)
         {
@@ -408,12 +460,12 @@
                     throw new CMSException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
                 }
 
-                if (!(validContentType instanceof DERObjectIdentifier))
+                if (!(validContentType instanceof ASN1ObjectIdentifier))
                 {
                     throw new CMSException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
                 }
 
-                DERObjectIdentifier signedContentType = (DERObjectIdentifier)validContentType;
+                ASN1ObjectIdentifier signedContentType = (ASN1ObjectIdentifier)validContentType;
 
                 if (!signedContentType.equals(contentType))
                 {
@@ -477,41 +529,22 @@
 
         try
         {
-            ContentVerifier contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, info.getDigestAlgorithm());
-            OutputStream sigOut = contentVerifier.getOutputStream();
-
-            if (signedAttributeSet == null)
+            if (signedAttributeSet == null && resultDigest != null)
             {
-                if (resultDigest != null)
+                if (contentVerifier instanceof RawContentVerifier)
                 {
-                    if (contentVerifier instanceof RawContentVerifier)
-                    {           
-                        RawContentVerifier rawVerifier = (RawContentVerifier)contentVerifier;
+                    RawContentVerifier rawVerifier = (RawContentVerifier)contentVerifier;
 
-                        if (encName.equals("RSA"))
-                        {
-                            DigestInfo digInfo = new DigestInfo(digestAlgorithm, resultDigest);
+                    if (encName.equals("RSA"))
+                    {
+                        DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest);
 
-                            return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature());
-                        }
-
-                        return rawVerifier.verify(resultDigest, this.getSignature());
+                        return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature());
                     }
 
-                    throw new CMSException("verifier unable to process raw signature");
-                }
-                else if (content != null)
-                {
-                    // TODO Use raw signature of the hash value instead
-                    content.write(sigOut);
+                    return rawVerifier.verify(resultDigest, this.getSignature());
                 }
             }
-            else
-            {
-                sigOut.write(this.getEncodedSignedAttributes());
-            }
-
-            sigOut.close();
 
             return contentVerifier.verify(this.getSignature());
         }
@@ -519,10 +552,6 @@
         {
             throw new CMSException("can't process mime object to create signature.", e);
         }
-        catch (OperatorCreationException e)
-        {
-            throw new CMSException("can't create content verifier: " + e.getMessage(), e);
-        }
     }
 
     /**
@@ -764,7 +793,7 @@
 
         for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext();)
         {
-            sigs.add(((SignerInformation)it.next()).toSignerInfo());
+            sigs.add(((SignerInformation)it.next()).toASN1Structure());
         }
 
         v.add(new Attribute(CMSAttributes.counterSignature, new DERSet(sigs)));
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
index 82a43a0..8e4d2b7 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
@@ -100,13 +100,11 @@
 
         if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
         {
-            digAlgId = ((RSASSAPSSparams)sigAlgId.getParameters()).getHashAlgorithm();
+            digAlgId = RSASSAPSSparams.getInstance(sigAlgId.getParameters()).getHashAlgorithm();
         }
         else
         {
-            // BEGIN android-changed
             digAlgId = new AlgorithmIdentifier((ASN1ObjectIdentifier)digestOids.get(sigAlgId.getAlgorithm()), DERNull.INSTANCE);
-            // END android-changed
         }
 
         return digAlgId;
@@ -114,8 +112,6 @@
 
     public AlgorithmIdentifier find(String digAlgName)
     {
-        // BEGIN android-changed
         return new AlgorithmIdentifier((ASN1ObjectIdentifier)digestNameToOids.get(digAlgName), DERNull.INSTANCE);
-        // END android-changed
     }
-}
+}
\ No newline at end of file
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
index be3567f..b73c5ce 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
@@ -144,31 +144,21 @@
         //
         // explicit params
         //
-        // BEGIN android-changed
         AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
-        // END android-changed
         params.put("SHA1WITHRSAANDMGF1", createPSSParams(sha1AlgId, 20));
 
         // BEGIN android-removed
-        // // BEGIN android-changed
         // AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE);
-        // // END android-changed
         // params.put("SHA224WITHRSAANDMGF1", createPSSParams(sha224AlgId, 28));
         // END android-removed
 
-        // BEGIN android-changed
         AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);
-        // END android-changed
         params.put("SHA256WITHRSAANDMGF1", createPSSParams(sha256AlgId, 32));
 
-        // BEGIN android-changed
         AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE);
-        // END android-changed
         params.put("SHA384WITHRSAANDMGF1", createPSSParams(sha384AlgId, 48));
 
-        // BEGIN android-changed
         AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE);
-        // END android-changed
         params.put("SHA512WITHRSAANDMGF1", createPSSParams(sha512AlgId, 64));
 
         //
@@ -223,9 +213,7 @@
 
         if (pkcs15RsaEncryption.contains(sigOID))
         {
-            // BEGIN android-changed
             encAlgId = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
-            // END android-changed
         }
         else
         {
@@ -238,9 +226,7 @@
         }
         else
         {
-            // BEGIN android-changed
             digAlgId = new AlgorithmIdentifier((ASN1ObjectIdentifier)digestOids.get(sigOID), DERNull.INSTANCE);
-            // END android-changed
         }
 
         return sigAlgId;
@@ -259,4 +245,4 @@
     {
         return generate(sigAlgName);
     }
-}
+}
\ No newline at end of file
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/RuntimeOperatorException.java b/bcpkix/src/main/java/org/bouncycastle/operator/RuntimeOperatorException.java
index 2918b4d..58242b2 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/RuntimeOperatorException.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/RuntimeOperatorException.java
@@ -5,6 +5,11 @@
 {
     private Throwable cause;
 
+    public RuntimeOperatorException(String msg)
+    {
+        super(msg);
+    }
+
     public RuntimeOperatorException(String msg, Throwable cause)
     {
         super(msg);
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
index 28221f4..2520f95 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
@@ -79,6 +79,15 @@
         // END android-removed
         oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA");
 
+        oids.put(OIWObjectIdentifiers.idSHA1, "SHA-1");
+        oids.put(NISTObjectIdentifiers.id_sha224, "SHA-224");
+        oids.put(NISTObjectIdentifiers.id_sha256, "SHA-256");
+        oids.put(NISTObjectIdentifiers.id_sha384, "SHA-384");
+        oids.put(NISTObjectIdentifiers.id_sha512, "SHA-512");
+        oids.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD-128");
+        oids.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD-160");
+        oids.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD-256");
+
         asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding");
 
         symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWrap");
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 @@
         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 @@
         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 @@
 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 @@
                 // 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 @@
             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 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 @@
     }
 
     /**
-     * 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 @@
         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 @@
         }
     }
 
+    /**
+     * @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 @@
             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 @@
             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 @@
             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 @@
             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 @@
             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 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 @@
 
     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 @@
             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 @@
             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 @@
         }
     }
 
+    private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f;
+
     DERObjectIdentifier(
         byte[]  bytes)
     {
@@ -71,26 +83,27 @@
         {
             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 @@
                     objId.append(value);
                     value = 0;
                 }
+                else
+                {
+                    value <<= 7;
+                }
             } 
             else 
             {
@@ -105,15 +122,25 @@
                 {
                     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 @@
          */
         this.identifier = objId.toString().intern();
         // END android-changed
+        this.body = Arrays.clone(bytes);
     }
 
     public DERObjectIdentifier(
@@ -188,16 +216,23 @@
 
     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 @@
         }
     }
 
-    protected byte[] getBody()
+    protected synchronized byte[] getBody()
     {
         if (body == null)
         {
@@ -287,6 +322,7 @@
         {
             char ch = identifier.charAt(i);
 
+            // TODO Leading zeroes?
             if ('0' <= ch && ch <= '9')
             {
                 periodAllowed = true;
@@ -310,7 +346,7 @@
         return periodAllowed;
     }
 
-    private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[255][];
+    private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[256][];
 
     static ASN1ObjectIdentifier fromOctetString(byte[] enc)
     {
@@ -320,63 +356,60 @@
         }
 
         int idx1 = enc[enc.length - 2] & 0xff;
-        ASN1ObjectIdentifier[] first = cache[idx1];
+        // in this case top bit is always zero
+        int idx2 = enc[enc.length - 1] & 0x7f;
 
-        if (first == null)
+        ASN1ObjectIdentifier possibleMatch;
+
+        synchronized (cache)
         {
-            first = cache[idx1] = new ASN1ObjectIdentifier[255];
-        }
+            ASN1ObjectIdentifier[] first = cache[idx1];
+                if (first == null)
+            {
+                first = cache[idx1] = new ASN1ObjectIdentifier[128];
+            }
 
-        int idx2 = enc[enc.length - 1] & 0xff;
+            possibleMatch = first[idx2];
+            if (possibleMatch == null)
+            {
+                return first[idx2] = new ASN1ObjectIdentifier(enc);
+            }
 
-        ASN1ObjectIdentifier possibleMatch = first[idx2];
+            if (Arrays.areEqual(enc, possibleMatch.getBody()))
+            {
+                return possibleMatch;
+            }
 
-        if (possibleMatch == null)
-        {
-            possibleMatch = first[idx2] = new ASN1ObjectIdentifier(enc);
-            return possibleMatch;
+            idx1 = (idx1 + 1) & 0xff;
+            first = cache[idx1];
+            if (first == null)
+            {
+                first = cache[idx1] = new ASN1ObjectIdentifier[128];
+            }
+
+            possibleMatch = first[idx2];
+            if (possibleMatch == null)
+            {
+                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;
         }
-        else
-        {
-            idx1 = (idx1 + 1) % 256;
-            first = cache[idx1];
-            if (first == null)
-            {
-                first = cache[idx1] = new ASN1ObjectIdentifier[255];
-            }
-
-            possibleMatch = first[idx2];
-
-            if (possibleMatch == null)
-            {
-                possibleMatch = first[idx2] = new ASN1ObjectIdentifier(enc);
-                return possibleMatch;
-            }
-
-            if (Arrays.areEqual(enc, possibleMatch.getBody()))
-            {
-                return possibleMatch;
-            }
-
-            idx2 = (idx2 + 1) % 256;
-            possibleMatch = first[idx2];
-
-            if (possibleMatch == null)
-            {
-                possibleMatch = first[idx2] = new ASN1ObjectIdentifier(enc);
-                return possibleMatch;
-            }
-
-            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 @@
             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..bb4e9a8 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 @@
             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,12 @@
     public DERT61String(
         String   string)
     {
-        this.string = Strings.toByteArray(string);
+        this.string = Strings.toUTF8ByteArray(string);
     }
 
     public String getString()
     {
-        return Strings.fromByteArray(string);
+        return Strings.fromUTF8ByteArray(string);
     }
 
     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 @@
             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 @@
             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 @@
             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 @@
             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 @@
     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 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 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 @@
         {
             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 @@
 
     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 @@
     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 @@
     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.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 @@
             // 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.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.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 @@
             {
                 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 @@
                 }
             }
         }
-        else if (obj instanceof DERTaggedObject)
+        else if (obj instanceof ASN1TaggedObject)
         {
             String          tab = indent + TAB;
 
@@ -110,7 +107,7 @@
                 buf.append("Tagged [");
             }
 
-            DERTaggedObject o = (DERTaggedObject)obj;
+            ASN1TaggedObject o = (ASN1TaggedObject)obj;
 
             buf.append(Integer.toString(o.getTagNo()));
             buf.append(']');
@@ -133,13 +130,22 @@
                 _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");
+
+            if (obj instanceof BERSet)
+            {
+                buf.append("BER Set");
+            }
+            else
+            {
+                buf.append("DER Set");
+            }
+
             buf.append(nl);
 
             while (e.hasMoreElements())
@@ -162,33 +168,24 @@
                 }
             }
         }
-        else if (obj instanceof DERSet)
+        else if (obj instanceof ASN1OctetString)
         {
-            Enumeration     e = ((ASN1Set)obj).getObjects();
-            String          tab = indent + TAB;
+            ASN1OctetString oct = (ASN1OctetString)obj;
 
-            buf.append(indent);
-            buf.append("DER Set");
-            buf.append(nl);
-
-            while (e.hasMoreElements())
+            if (obj instanceof BEROctetString || obj instanceof  BERConstructedOctetString)
             {
-                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(indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] ");
+            }
+            else
+            {
+                buf.append(indent + "DER Octet String" + "[" + oct.getOctets().length + "] ");
+            }
+            if (verbose)
+            {
+                buf.append(dumpBinaryDataAsString(indent, oct.getOctets()));
+            }
+            else{
+                buf.append(nl);
             }
         }
         else if (obj instanceof ASN1ObjectIdentifier)
@@ -203,30 +200,6 @@
         {
             buf.append(indent + "Integer(" + ((ASN1Integer)obj).getValue() + ")" + nl);
         }
-        else if (obj instanceof BERConstructedOctetString)
-        {
-            ASN1OctetString oct = (ASN1OctetString)obj;
-            buf.append(indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] ");
-            if (verbose)
-            {
-                buf.append(dumpBinaryDataAsString(indent, oct.getOctets()));
-            }
-            else{
-                buf.append(nl);
-            }
-        }
-        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()));
-            }
-            else{
-                buf.append(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 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 @@
 
 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 @@
 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 @@
 
         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.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 @@
             }
             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 @@
 
     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 @@
                 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 @@
         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 @@
 
         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 @@
 
     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 @@
                 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 @@
 {
     private String          value;
     private int             index;
-    private char            seperator;
+    private char            separator;
     private StringBuffer    buf = new StringBuffer();
 
     public X500NameTokenizer(
@@ -21,11 +21,11 @@
     
     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 @@
                 }
                 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 @@
                     {
                         buf.append('\\');
                     }
-                    else if (c == '+' && seperator != '+')
+                    else if (c == '+' && separator != '+')
                     {
                         buf.append('\\');
                     }
@@ -81,7 +89,7 @@
                 {
                     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 @@
                     + 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 @@
      * @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 @@
         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 @@
 
 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 @@
 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 @@
 
         return null;
     }
-    
+
+    public static BasicConstraints fromExtensions(Extensions extensions)
+    {
+        return BasicConstraints.getInstance(extensions.getExtensionParsedValue(Extension.basicConstraints));
+    }
+
     private BasicConstraints(
         ASN1Sequence   seq)
     {
@@ -83,9 +87,7 @@
     {
         if (cA)
         {
-            // BEGIN android-changed
-            this.cA = DERBoolean.TRUE;
-            // END android-changed
+            this.cA = ASN1Boolean.getInstance(true);
         }
         else
         {
@@ -102,9 +104,7 @@
     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 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 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 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 @@
         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.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 @@
         {
             return (ExtendedKeyUsage)obj;
         }
-        
-        if (obj != null)
+        else if (obj != null)
         {
             return new ExtendedKeyUsage(ASN1Sequence.getInstance(obj));
         }
@@ -47,6 +47,11 @@
         return null;
     }
 
+    public static ExtendedKeyUsage fromExtensions(Extensions extensions)
+    {
+        return ExtendedKeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.extendedKeyUsage));
+    }
+
     public ExtendedKeyUsage(
         KeyPurposeId  usage)
     {
@@ -55,7 +60,7 @@
         this.usageTable.put(usage, usage);
     }
     
-    public ExtendedKeyUsage(
+    private ExtendedKeyUsage(
         ASN1Sequence  seq)
     {
         this.seq = seq;
@@ -64,8 +69,8 @@
 
         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 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 @@
     
     /**
      * 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.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 @@
 
     /**
      * 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 @@
     }
 
     /**
+     * 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 @@
         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 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 @@
         return getInstance(ASN1Sequence.getInstance(obj, explicit));
     }
     
-    public IssuerSerial(
+    private IssuerSerial(
         ASN1Sequence    seq)
     {
         if (seq.size() != 2 && seq.size() != 3)
@@ -55,7 +57,14 @@
             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 @@
         }
         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 @@
         }
         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 @@
                 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 @@
  * </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 @@
     /**
      * { 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 @@
  * </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 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 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 @@
 public class NameConstraints
     extends ASN1Object
 {
-    private ASN1Sequence permitted, excluded;
+    private GeneralSubtree[] permitted, excluded;
 
     public static NameConstraints getInstance(Object obj)
     {
@@ -38,12 +37,12 @@
             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 @@
      * 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 @@
      *            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 @@
     {
         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.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 @@
                 + seq.size());
         }
 
-        digestedObjectType = DEREnumerated.getInstance(seq.getObjectAt(0));
+        digestedObjectType = ASN1Enumerated.getInstance(seq.getObjectAt(0));
 
         int offset = 0;
 
@@ -133,7 +132,7 @@
         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 @@
         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 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 @@
 
 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 void setStartDate(
-        DERUTCTime startDate)
+        ASN1UTCTime startDate)
     {
         this.startDate = new Time(startDate);
     }
@@ -83,12 +83,12 @@
     }
 
     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 @@
      * 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 @@
      * 
      * @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 @@
 
             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 @@
 
             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 @@
  * 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 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 @@
                 }
                 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 @@
                     {
                         buf.append('\\');
                     }
-                    else if (c == '+' && seperator != '+')
+                    else if (c == '+' && separator != '+')
                     {
                         buf.append('\\');
                     }
@@ -92,12 +90,23 @@
                 {
                     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 @@
                 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 @@
      * @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 @@
      *
      * @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 @@
     /**
      * 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 @@
         {
             if ((outOff + length) > out.length)
             {
-                throw new DataLengthException("output buffer too short");
+                throw new OutputLengthException("output buffer too short");
             }
         }
 
@@ -265,7 +265,7 @@
 
             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 @@
     {
         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 static byte[] PKCS5PasswordToBytes(
         char[]  password)
     {
-        byte[]  bytes = new byte[password.length];
-
-        for (int i = 0; i != bytes.length; i++)
+        if (password != null)
         {
-            bytes[i] = (byte)password[i];
-        }
+            byte[]  bytes = new byte[password.length];
 
-        return bytes;
+            for (int i = 0; i != bytes.length; i++)
+            {
+                bytes[i] = (byte)password[i];
+            }
+
+            return bytes;
+        }
+        else
+        {
+            return new byte[0];
+        }
     }
 
     /**
@@ -136,7 +143,6 @@
     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 @@
         {
             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 org.bouncycastle.crypto.BasicAgreement;
 import org.bouncycastle.crypto.CipherParameters;
-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.DHParameters;
+import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
+import org.bouncycastle.crypto.params.DHPublicKeyParameters;
 import org.bouncycastle.crypto.params.ParametersWithRandom;
 
 /**
@@ -47,6 +47,11 @@
         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 @@
 
 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 @@
         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/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 @@
     /**
      * 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 @@
      * 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 @@
      * 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 @@
         return i;
     }
 
-    private int getCtx() {
+    private long getCtx() {
         if (ctx == 0) {
             ctx = NativeCrypto.EVP_DigestInit(evp_md);
         }
@@ -123,35 +123,35 @@
     }
 
     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 @@
         }
 
         byte type = block[0];
-        
-        if (type != 1 && type != 2)
+
+        if (forPrivateKey)
         {
-            throw new InvalidCipherTextException("unknown block type");
+            if (type != 2)
+            {
+                throw new InvalidCipherTextException("unknown block type");
+            }
+        }
+        else
+        {
+            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 @@
      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 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 int inv_mcol(int x)
+    private static int inv_mcol(int x)
     {
         int f2 = FFmulX(x);
         int f4 = FFmulX(f2);
@@ -257,7 +255,7 @@
         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 @@
 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 @@
      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 @@
     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 @@
 
     */
 
-    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 @@
     }
 
 
-    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 @@
 
         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 @@
 
 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 @@
 
         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.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 @@
         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 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 @@
         {
             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 @@
     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 @@
             AEADParameters param = (AEADParameters)params;
 
             nonce = param.getNonce();
-            associatedText = param.getAssociatedText();
+            initialAssociatedText = param.getAssociatedText();
             macSize = param.getMacSize() / 8;
             keyParam = param.getKey();
         }
@@ -78,7 +79,7 @@
             ParametersWithIV param = (ParametersWithIV)params;
 
             nonce = param.getIV();
-            associatedText = null;
+            initialAssociatedText = null;
             macSize = macBlock.length / 2;
             keyParam = param.getParameters();
         }
@@ -93,6 +94,17 @@
         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 void reset()
     {
         cipher.reset();
+        associatedText.reset();
         data.reset();
     }
 
@@ -150,60 +163,62 @@
 
     public int getOutputSize(int len)
     {
+        int totalData = len + data.size();
+
         if (forEncryption)
         {
-            return data.size() + len + macSize;
+             return totalData + macSize;
         }
-        else
-        {
-            return data.size() + len - 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 @@
         {
             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 @@
         {
             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 @@
             {
                 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 @@
         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 @@
         
         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;
-                    }
+                    IV[i] = 0;
                 }
-                else
-                {
-                    System.arraycopy(iv, 0, IV, 0, IV.length);
-                }
+            }
+            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.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 @@
     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 @@
         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 @@
             ParametersWithIV param = (ParametersWithIV)params;
 
             nonce = param.getIV();
-            A = null;
+            initialAssociatedText  = null;
             macSize = 16;
             keyParam = (KeyParameter)param.getParameters();
         }
@@ -122,48 +127,54 @@
             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);
+
+            this.H = new byte[BLOCK_SIZE];
+            cipher.processBlock(H, 0, H, 0);
+
+            // GCMMultiplier tables don't change unless the key changes (and are expensive to init)
+            multiplier.init(H);
+            exp = null;
         }
 
-        // 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(ZEROES, 0, H, 0);
-        multiplier.init(H);
-
-        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 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 @@
     {
         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 @@
         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();
         }
-
-        return 0;
+        gCTRBlock(bufBlock, output, offset);
+        if (forEncryption)
+        {
+            bufOff = 0;
+        }
+        else
+        {
+            System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize);
+            bufOff = macSize;
+        }
     }
 
     public int doFinal(byte[] out, int outOff)
         throws IllegalStateException, InvalidCipherTextException
     {
+        if (totalLength == 0)
+        {
+            initCipher();
+        }
+
         int extra = bufOff;
         if (!forEncryption)
         {
@@ -255,18 +324,57 @@
 
         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 @@
     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 @@
             macBlock = null;
         }
 
-        cipher.reset();
+        if (initialAssociatedText != null)
+        {
+            processAADBytes(initialAssociatedText, 0, initialAssociatedText.length);
+        }
     }
 
-    private void gCTRBlock(byte[] buf, int bufCount, byte[] out, int outOff)
+    private void gCTRBlock(byte[] block, byte[] out, int outOff)
     {
-//        inc(counter);
+        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 byte[] getNextCounterBlock()
+    {
         for (int i = 15; i >= 12; --i)
         {
             byte b = (byte)((counter[i] + 1) & 0xff);
@@ -343,67 +506,55 @@
         }
 
         byte[] tmp = new byte[BLOCK_SIZE];
+        // TODO Sure would be nice if ciphers could operate on int[]
         cipher.processBlock(counter, 0, tmp, 0);
-
-        byte[] hashBytes;
-        if (forEncryption)
-        {
-            System.arraycopy(ZEROES, bufCount, tmp, bufCount, BLOCK_SIZE - bufCount);
-            hashBytes = tmp;
-        }
-        else
-        {
-            hashBytes = buf;
-        }
-
-        for (int i = bufCount - 1; i >= 0; --i)
-        {
-            tmp[i] ^= buf[i];
-            out[outOff + i] = tmp[i];
-        }
-
-//        gHASHBlock(hashBytes);
-        xor(S, hashBytes);
-        multiplier.multiplyH(S);
-
-        totalLength += bufCount;
+        return tmp;
     }
 
-    private byte[] gHASH(byte[] b)
+    private static void multiply(byte[] block, byte[] val)
     {
-        byte[] Y = new byte[16];
+        byte[] tmp = Arrays.clone(block);
+        byte[] c = new byte[16];
 
-        for (int pos = 0; pos < b.length; pos += 16)
+        for (int i = 0; i < 16; ++i)
         {
-            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);
+            byte bits = val[i];
+            for (int j = 7; j >= 0; --j)
+            {
+                if ((bits & (1 << j)) != 0)
+                {
+                    xor(c, tmp);
+                }
+
+                boolean lsb = (tmp[15] & 1) != 0;
+                shiftRight(tmp);
+                if (lsb)
+                {
+                    // R = new byte[]{ 0xe1, ... };
+//                    xor(v, R);
+                    tmp[0] ^= (byte)0xe1;
+                }
+            }
         }
 
-        return Y;
+        System.arraycopy(c, 0, block, 0, 16);
     }
 
-//    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 shiftRight(byte[] block)
+    {
+        int i = 0;
+        int bit = 0;
+        for (;;)
+        {
+            int b = block[i] & 0xff;
+            block[i] = (byte) ((b >>> 1) | bit);
+            if (++i == 16)
+            {
+                break;
+            }
+            bit = (b & 1) << 7;
+        }
+    }
 
     private static void xor(byte[] block, byte[] val)
     {
@@ -413,9 +564,11 @@
         }
     }
 
-    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 @@
     {
         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;
-                    }
+                    IV[i] = 0;
                 }
-                else
-                {
-                    System.arraycopy(iv, 0, IV, 0, IV.length);
-                }
+            }
+            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/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 @@
  * 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 @@
           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 @@
         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 @@
         }
     }
 
+    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 @@
         }
     }
 
+    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 @@
         }
     }
 
+    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 @@
         }
     }
 
+    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 @@
         }
     }
 
+    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 @@
         }
     }
 
+    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 @@
             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);
+        if (M == null)
+        {
+            M = new int[32][16][4];
+        }
+        else if (Arrays.areEqual(this.H, H))
+        {
+            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[1][j + j], 0, tmp, 0, 4);
-
-            GCMUtil.multiplyP(tmp);
-            M[1][j] = tmp;
+            GCMUtil.multiplyP(M[1][j + j], M[1][j]);
         }
 
-        {
-            int[] tmp = new int[4];
-            System.arraycopy(M[1][1], 0, tmp, 0, 4);
-
-            GCMUtil.multiplyP(tmp);
-            M[0][8] = tmp;
-        }
+        GCMUtil.multiplyP(M[1][1], M[0][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(tmp);
-            M[0][j] = tmp;
+            GCMUtil.multiplyP(M[0][j + j], M[0][j]);
         }
 
         int i = 0;
@@ -45,11 +44,7 @@
             {
                 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 @@
 
             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 @@
 
         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.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 @@
         {
             if ((outOff + length) > out.length)
             {
-                throw new DataLengthException("output buffer too short");
+                throw new OutputLengthException("output buffer too short");
             }
         }
 
@@ -254,7 +255,7 @@
                 {
                     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 @@
      * @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 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 @@
         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 @@
         // 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 @@
         // 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 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 @@
         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 @@
         // 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 @@
         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.KeyGenerator;
 import javax.crypto.Mac;
 import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKeyFactory;
 
 public class DefaultJcaJceHelper
     implements JcaJceHelper
@@ -62,6 +63,12 @@
         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.KeyGenerator;
 import javax.crypto.Mac;
 import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKeyFactory;
 
 public interface JcaJceHelper
 {
@@ -41,6 +42,9 @@
     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.KeyGenerator;
 import javax.crypto.Mac;
 import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKeyFactory;
 
 public class NamedJcaJceHelper
     implements JcaJceHelper
@@ -70,6 +71,12 @@
         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.KeyGenerator;
 import javax.crypto.Mac;
 import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKeyFactory;
 
 public class ProviderJcaJceHelper
     implements JcaJceHelper
@@ -70,6 +71,12 @@
         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 @@
             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 @@
             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 @@
 
             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 @@
             // 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 @@
             //     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.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 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.SecretKeySpec;
 
 import org.bouncycastle.crypto.params.DESParameters;
+import org.bouncycastle.util.Integers;
 import org.bouncycastle.util.Strings;
 
 /**
@@ -35,12 +36,10 @@
 
     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.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 @@
     {
         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 @@
             }
             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();
+                    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
+                        {
 
-                    pGen.init(strength, certainty, random);
+                            DHParametersGenerator pGen = new DHParametersGenerator();
 
-                    param = new DHKeyGenerationParameters(random, pGen.generateParameters());
+                            pGen.init(strength, certainty, random);
 
-                    params.put(paramStrength, param);
+                            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 @@
     {
         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 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 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 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.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 @@
                 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 @@
                             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..cc9b2db 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.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 @@
 
     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 @@
         // else
         // END android-removed
         {
-            if (!(key instanceof ECPublicKey))
+            if (!(key instanceof PublicKey))
             {
                 throw new InvalidKeyException(kaAlgorithm + " key agreement requires "
                     + getSimpleName(ECPublicKey.class) + " for doPhase");
@@ -268,7 +267,7 @@
         // 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.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 @@
         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 @@
             // 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 @@
         {
             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.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.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 @@
 // 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 @@
     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 @@
         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 @@
         {
             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 @@
             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 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 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 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 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 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 @@
             }
         }
 
+        bOut.reset();
+
         switch (opmode)
         {
         case Cipher.ENCRYPT_MODE:
@@ -510,7 +512,6 @@
         try
         {
             byte[]  bytes = bOut.toByteArray();
-            bOut.reset();
 
             out = cipher.processBlock(bytes, 0, bytes.length);
         }
@@ -518,6 +519,10 @@
         {
             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 @@
             {
                 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 @@
             {
                 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 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.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 @@
         }
 
         return new X509CertificateObject(
-                            X509CertificateStructure.getInstance(seq));
+                            Certificate.getInstance(seq));
     }
 
     private java.security.cert.Certificate getCertificate()
@@ -82,7 +82,7 @@
                 if (obj instanceof ASN1Sequence)
                 {
                    return new X509CertificateObject(
-                                    X509CertificateStructure.getInstance(obj));
+                                    Certificate.getInstance(obj));
                 }
             }
         }
@@ -99,7 +99,7 @@
         if (seq != null)
         {
             return new X509CertificateObject(
-                            X509CertificateStructure.getInstance(seq));
+                            Certificate.getInstance(seq));
         }
 
         return null;
@@ -334,7 +334,9 @@
 
     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 @@
     {
         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 @@
     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 @@
 {
     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 @@
 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 @@
     implements PBEKey
 {
     String              algorithm;
-    DERObjectIdentifier oid;
+    ASN1ObjectIdentifier oid;
     int                 type;
     int                 digest;
     int                 keySize;
@@ -27,7 +27,7 @@
      */
     public BCPBEKey(
         String algorithm,
-        DERObjectIdentifier oid,
+        ASN1ObjectIdentifier oid,
         int type,
         int digest,
         int keySize,
@@ -134,7 +134,7 @@
         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.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,30 +727,24 @@
         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);
-
-        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);
-        }
-
         try
         {
+            int     len = 0;
+
+            if (inputLen != 0)
+            {
+                    len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
+            }
+
             return (len + cipher.doFinal(output, outputOffset + len));
         }
+        catch (OutputLengthException e)
+        {
+            throw new ShortBufferException(e.getMessage());
+        }
         catch (DataLengthException e)
         {
             throw new IllegalBlockSizeException(e.getMessage());
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 @@
     {
         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.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 @@
     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 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 @@
         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 @@
         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 @@
             {
                 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 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 @@
     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 @@
                     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 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 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 @@
         //
         // 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 @@
                 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 @@
         {
             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 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 @@
         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 @@
         //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 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 @@
 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 @@
     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 @@
     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 BouncyCastleProvider()
     {
-        super(PROVIDER_NAME, 1.47, info);
+        super(PROVIDER_NAME, 1.48, info);
 
         AccessController.doPrivileged(new PrivilegedAction()
         {
@@ -277,11 +280,8 @@
         // 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 @@
         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 @@
                 }
                 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 @@
         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 @@
     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 @@
         }
         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 @@
                 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 @@
         return ecImplicitCaParams;
     }
 
-    public DHParameterSpec getDHDefaultParameters()
+    public DHParameterSpec getDHDefaultParameters(int keySize)
     {
-        DHParameterSpec spec = (DHParameterSpec)dhThreadSpec.get();
-
-        if (spec != null)
+        Object params = dhThreadSpec.get();
+        if (params == null)
         {
-            return spec;
+            params = dhDefaultParams;
         }
 
-        return dhDefaultParams;
+        if (params instanceof DHParameterSpec)
+        {
+            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 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.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 @@
 {
     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 @@
             {
                 // 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.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.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,31 +744,24 @@
         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);
-
-        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);
-        }
-
         try
         {
+            int     len = 0;
+
+            if (inputLen != 0)
+            {
+                    len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
+            }
+
             return (len + cipher.doFinal(output, outputOffset + len));
         }
+        catch (OutputLengthException e)
+        {
+            throw new ShortBufferException(e.getMessage());
+        }
         catch (DataLengthException e)
         {
             throw new IllegalBlockSizeException(e.getMessage());
@@ -779,80 +778,111 @@
         return "CCM".equals(modeName) || "EAX".equals(modeName) || "GCM".equals(modeName);
     }
 
-    /*
-     * The ciphers that inherit from us.
-     */
-
-    /**
-     * DES
-     */
-    static public class DES
-        extends JCEBlockCipher
+    protected byte[] engineWrap(
+        Key     key)
+    throws IllegalBlockSizeException, InvalidKeyException
     {
-        public DES()
+        byte[] encoded = key.getEncoded();
+        if (encoded == null)
         {
-            super(new DESEngine());
+            throw new InvalidKeyException("Cannot wrap key, null encoding.");
+        }
+
+        try
+        {
+            return engineDoFinal(encoded, 0, encoded.length);
+        }
+        catch (BadPaddingException e)
+        {
+            throw new IllegalBlockSizeException(e.getMessage());
         }
     }
 
-    // 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
+    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.
+     */
 
     /**
      * 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 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 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 @@
         //     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 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 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 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 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 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.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 @@
     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 PBEKeyFactory(
             String              algorithm,
-            DERObjectIdentifier oid,
+            ASN1ObjectIdentifier oid,
             boolean             forCipher,
             int                 scheme,
             int                 digest,
@@ -172,7 +172,7 @@
         
         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.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.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 @@
     protected byte[] engineDoFinal(
         byte[]  input,
         int     inputOffset,
-        int     inputLen) 
+        int     inputLen)
+        throws BadPaddingException, IllegalBlockSizeException
     {
         if (inputLen != 0)
         {
@@ -368,7 +380,8 @@
         int     inputOffset,
         int     inputLen,
         byte[]  output,
-        int     outputOffset) 
+        int     outputOffset)
+        throws BadPaddingException
     {
         if (inputLen != 0)
         {
@@ -380,6 +393,108 @@
         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.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 @@
         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 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 @@
 
         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.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.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 @@
                 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 @@
                 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 @@
                         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 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 @@
         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 @@
         }
 
         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]);
+            certs.put(alias, chain[0]);
+
+            for (int i = 0; i != chain.length; i++)
+            {
+                chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]);
+            }
         }
-        // BEGIN android-added
-        }
-        // END android-added
     }
 
     public int engineSize() 
@@ -1244,7 +1233,7 @@
         }
 
         byte[]                    keySEncoded = new DERSequence(keyS).getEncoded(ASN1Encoding.DER);
-        BERConstructedOctetString keyString = new BERConstructedOctetString(keySEncoded);
+        BEROctetString keyString = new BEROctetString(keySEncoded);
 
         //
         // certificate processing
@@ -1468,7 +1457,7 @@
 
         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 @@
 
         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 @@
         {
             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 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 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 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 @@
 
 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.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 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 @@
      * @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 @@
             //
             // (g) (1) permitted subtrees
             //
-            ASN1Sequence permitted = nc.getPermittedSubtrees();
+            GeneralSubtree[] permitted = nc.getPermittedSubtrees();
             if (permitted != null)
             {
                 try
@@ -1686,17 +1686,13 @@
             //
             // (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 @@
         }
         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 @@
 
         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 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.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 @@
             return null;
         }
 
-        byte[] ext = getExtensionValue(X509Extension.certificateIssuer.getId());
+        Extension ext = getExtension(Extension.certificateIssuer);
         if (ext == null)
         {
             return previousCertificateIssuer;
@@ -98,8 +97,7 @@
 
         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 @@
             }
             return null;
         }
-        catch (IOException e)
+        catch (Exception e)
         {
             return null;
         }
@@ -167,24 +165,31 @@
         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);
+        }
 
-            if (ext != null)
+        return null;
+    }
+
+    public byte[] getExtensionValue(String oid)
+    {
+        Extension ext = getExtension(new ASN1ObjectIdentifier(oid));
+
+        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 @@
                         {
                             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 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.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 @@
         {
             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 @@
                         if (oid.equals(Extension.cRLNumber))
                         {
                             buf.append(
-                                new CRLNumber(DERInteger.getInstance(
+                                new CRLNumber(ASN1Integer.getInstance(
                                     dIn.readObject()).getPositiveValue()))
                                 .append(nl);
                         }
@@ -452,7 +452,7 @@
                         {
                             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 @@
 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.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.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 @@
     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 int getVersion()
     {
-        return c.getVersion();
+        return c.getVersionNumber();
     }
 
     public BigInteger getSerialNumber()
@@ -268,7 +277,7 @@
      */
     public String getSigAlgOID()
     {
-        return c.getSignatureAlgorithm().getObjectId().getId();
+        return c.getSignatureAlgorithm().getAlgorithm().getId();
     }
 
     /**
@@ -353,7 +362,7 @@
 
                 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 @@
         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 @@
 
                 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 @@
 
     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 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 @@
         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 @@
 
                 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 @@
     {
         if (this.getVersion() == 3)
         {
-            X509Extensions  extensions = c.getTBSCertificate().getExtensions();
+            Extensions  extensions = c.getTBSCertificate().getExtensions();
 
             if (extensions != null)
             {
@@ -501,7 +522,7 @@
 
                 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 @@
                         continue;
                     }
 
-                    X509Extension       ext = extensions.getExtension(oid);
+                    Extension       ext = extensions.getExtension(oid);
 
                     if (ext.isCritical())
                     {
@@ -630,7 +651,7 @@
     }
 
     public ASN1Encodable getBagAttribute(
-        DERObjectIdentifier oid)
+        ASN1ObjectIdentifier oid)
     {
         return attrCarrier.getBagAttribute(oid);
     }
@@ -669,7 +690,7 @@
             }
         }
 
-        X509Extensions  extensions = c.getTBSCertificate().getExtensions();
+        Extensions extensions = c.getTBSCertificate().getExtensions();
 
         if (extensions != null)
         {
@@ -682,23 +703,23 @@
 
             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 @@
                     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 @@
 
     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 @@
         
         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 @@
 
 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 @@
             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 @@
         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 @@
         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 @@
         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 @@
         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 @@
         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 @@
     }
 
     /**
+     * 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 @@
         {
             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 @@
         {
             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 @@
         {
             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 @@
 
     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 @@
             
             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 @@
             
             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 @@
             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 @@
             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 @@
             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 @@
         {
             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 @@
         {
             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 @@
         {
             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 @@
 
     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 @@
         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 @@
             
             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 @@
             
             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 @@
         //
         // 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 @@
         }
         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.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 @@
 
         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.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 @@
         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.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 @@
             {
                 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:
diff --git a/bouncycastle.config b/bouncycastle.config
index 7ee682e..3ebc43c 100644
--- a/bouncycastle.config
+++ b/bouncycastle.config
@@ -16,6 +16,7 @@
 org/bouncycastle/asn1/x509/qualified \
 org/bouncycastle/asn1/x509/sigi \
 org/bouncycastle/crypto/agreement/kdf \
+org/bouncycastle/crypto/agreement/jpake \
 org/bouncycastle/crypto/agreement/srp \
 org/bouncycastle/crypto/examples \
 org/bouncycastle/crypto/prng \
@@ -23,11 +24,13 @@
 org/bouncycastle/i18n/ \
 org/bouncycastle/jcajce/provider/asymmetric/ecgost \
 org/bouncycastle/jcajce/provider/asymmetric/elgamal \
+org/bouncycastle/jcajce/provider/asymmetric/dstu \
 org/bouncycastle/jcajce/provider/asymmetric/gost \
 org/bouncycastle/jce/examples \
 org/bouncycastle/jce/provider/test \
 org/bouncycastle/math/ntru \
 org/bouncycastle/ocsp \
+org/bouncycastle/pqc \
 org/bouncycastle/util/test \
 org/bouncycastle/x509/examples \
 "
@@ -45,6 +48,7 @@
 org/bouncycastle/asn1/cms/CompressedData.java \
 org/bouncycastle/asn1/cms/CompressedDataParser.java \
 org/bouncycastle/asn1/cms/ContentInfoParser.java \
+org/bouncycastle/asn1/cms/DigestedData.java \
 org/bouncycastle/asn1/cms/EncryptedContentInfo.java \
 org/bouncycastle/asn1/cms/EncryptedContentInfoParser.java \
 org/bouncycastle/asn1/cms/EncryptedData.java \
@@ -73,20 +77,20 @@
 org/bouncycastle/asn1/cms/TimeStampedData.java \
 org/bouncycastle/asn1/cms/TimeStampedDataParser.java \
 org/bouncycastle/asn1/cms/package.html \
-org/bouncycastle/asn1/eac/CertificationAuthorityReference.java \
-org/bouncycastle/asn1/eac/Flags.java \
 org/bouncycastle/asn1/eac/BidirectionalMap.java \
-org/bouncycastle/asn1/eac/CertificateBody.java \
-org/bouncycastle/asn1/eac/UnsignedInteger.java \
 org/bouncycastle/asn1/eac/CVCertificate.java \
-org/bouncycastle/asn1/eac/CertificateHolderAuthorization.java \
-org/bouncycastle/asn1/eac/PublicKeyDataObject.java \
-org/bouncycastle/asn1/eac/ECDSAPublicKey.java \
-org/bouncycastle/asn1/eac/CertificateHolderReference.java \
 org/bouncycastle/asn1/eac/CVCertificateRequest.java \
-org/bouncycastle/asn1/eac/RSAPublicKey.java \
+org/bouncycastle/asn1/eac/CertificateBody.java \
+org/bouncycastle/asn1/eac/CertificateHolderAuthorization.java \
+org/bouncycastle/asn1/eac/CertificateHolderReference.java \
+org/bouncycastle/asn1/eac/CertificationAuthorityReference.java \
 org/bouncycastle/asn1/eac/EACTags.java \
+org/bouncycastle/asn1/eac/ECDSAPublicKey.java \
+org/bouncycastle/asn1/eac/Flags.java \
 org/bouncycastle/asn1/eac/PackedDate.java \
+org/bouncycastle/asn1/eac/PublicKeyDataObject.java \
+org/bouncycastle/asn1/eac/RSAPublicKey.java \
+org/bouncycastle/asn1/eac/UnsignedInteger.java \
 org/bouncycastle/asn1/isismtt/ocsp/CertHash.java \
 org/bouncycastle/asn1/isismtt/ocsp/RequestedCertificate.java \
 org/bouncycastle/asn1/isismtt/x509/AdditionalInformationSyntax.java \
@@ -112,6 +116,13 @@
 org/bouncycastle/asn1/sec/package.html \
 org/bouncycastle/asn1/teletrust/TeleTrusTNamedCurves.java \
 org/bouncycastle/asn1/teletrust/package.html \
+org/bouncycastle/asn1/ua/DSTU4145BinaryField.java \
+org/bouncycastle/asn1/ua/DSTU4145ECBinary.java \
+org/bouncycastle/asn1/ua/DSTU4145NamedCurves.java \
+org/bouncycastle/asn1/ua/DSTU4145Params.java \
+org/bouncycastle/asn1/ua/DSTU4145PointEncoder.java \
+org/bouncycastle/asn1/ua/DSTU4145PublicKey.java \
+org/bouncycastle/asn1/ua/UAObjectIdentifiers.java \
 org/bouncycastle/asn1/util/DERDump.java \
 org/bouncycastle/asn1/util/Dump.java \
 org/bouncycastle/asn1/util/package.html \
@@ -141,6 +152,9 @@
 org/bouncycastle/asn1/x9/OtherInfo.java \
 org/bouncycastle/asn1/x9/package.html \
 org/bouncycastle/crypto/BufferedAsymmetricBlockCipher.java \
+org/bouncycastle/crypto/EphemeralKeyPair.java \
+org/bouncycastle/crypto/KeyEncoder.java \
+org/bouncycastle/crypto/KeyParser.java \
 org/bouncycastle/crypto/MaxBytesExceededException.java \
 org/bouncycastle/crypto/agreement/DHAgreement.java \
 org/bouncycastle/crypto/agreement/ECDHCBasicAgreement.java \
@@ -154,6 +168,7 @@
 org/bouncycastle/crypto/digests/RIPEMD256Digest.java \
 org/bouncycastle/crypto/digests/RIPEMD320Digest.java \
 org/bouncycastle/crypto/digests/SHA224Digest.java \
+org/bouncycastle/crypto/digests/SHA3Digest.java \
 org/bouncycastle/crypto/digests/ShortenedDigest.java \
 org/bouncycastle/crypto/digests/TigerDigest.java \
 org/bouncycastle/crypto/digests/WhirlpoolDigest.java \
@@ -200,10 +215,13 @@
 org/bouncycastle/crypto/engines/package.html \
 org/bouncycastle/crypto/generators/BaseKDFBytesGenerator.java \
 org/bouncycastle/crypto/generators/DHKeyPairGenerator.java \
+org/bouncycastle/crypto/generators/DSTU4145KeyPairGenerator.java \
 org/bouncycastle/crypto/generators/ElGamalKeyPairGenerator.java \
 org/bouncycastle/crypto/generators/ElGamalParametersGenerator.java \
+org/bouncycastle/crypto/generators/EphemeralKeyPairGenerator.java \
 org/bouncycastle/crypto/generators/GOST3410KeyPairGenerator.java \
 org/bouncycastle/crypto/generators/GOST3410ParametersGenerator.java \
+org/bouncycastle/crypto/generators/HKDFBytesGenerator.java \
 org/bouncycastle/crypto/generators/KDF1BytesGenerator.java \
 org/bouncycastle/crypto/generators/KDF2BytesGenerator.java \
 org/bouncycastle/crypto/generators/MGF1BytesGenerator.java \
@@ -231,8 +249,6 @@
 org/bouncycastle/crypto/modes/PaddedBlockCipher.java \
 org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java \
 org/bouncycastle/crypto/modes/gcm/BasicGCMMultiplier.java \
-org/bouncycastle/crypto/modes/gcm/GCMExponentiator.java \
-org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java \
 org/bouncycastle/crypto/modes/gcm/Tables64kGCMMultiplier.java \
 org/bouncycastle/crypto/modes/package.html \
 org/bouncycastle/crypto/package.html \
@@ -249,6 +265,7 @@
 org/bouncycastle/crypto/params/GOST3410PrivateKeyParameters.java \
 org/bouncycastle/crypto/params/GOST3410PublicKeyParameters.java \
 org/bouncycastle/crypto/params/GOST3410ValidationParameters.java \
+org/bouncycastle/crypto/params/HKDFParameters.java \
 org/bouncycastle/crypto/params/IESParameters.java \
 org/bouncycastle/crypto/params/IESWithCipherParameters.java \
 org/bouncycastle/crypto/params/ISO18033KDFParameters.java \
@@ -274,7 +291,10 @@
 org/bouncycastle/crypto/params/RC5Parameters.java \
 org/bouncycastle/crypto/params/RSABlindingParameters.java \
 org/bouncycastle/crypto/params/package.html \
+org/bouncycastle/crypto/parsers/DHIESPublicKeyParser.java \
+org/bouncycastle/crypto/parsers/ECIESPublicKeyParser.java \
 org/bouncycastle/crypto/signers/DSADigestSigner.java \
+org/bouncycastle/crypto/signers/DSTU4145Signer.java \
 org/bouncycastle/crypto/signers/ECGOST3410Signer.java \
 org/bouncycastle/crypto/signers/ECNRSigner.java \
 org/bouncycastle/crypto/signers/GOST3410Signer.java \
@@ -285,12 +305,18 @@
 org/bouncycastle/crypto/signers/NTRUSignerPrng.java \
 org/bouncycastle/crypto/signers/PSSSigner.java \
 org/bouncycastle/crypto/signers/package.html \
+org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java \
+org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java \
 org/bouncycastle/crypto/util/package.html \
+org/bouncycastle/jcajce/provider/asymmetric/DSTU4145.java \
 org/bouncycastle/jcajce/provider/asymmetric/ECGOST.java \
 org/bouncycastle/jcajce/provider/asymmetric/ElGamal.java \
 org/bouncycastle/jcajce/provider/asymmetric/GOST.java \
+org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java \
+org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java \
 org/bouncycastle/jcajce/provider/asymmetric/rsa/ISOSignatureSpi.java \
 org/bouncycastle/jcajce/provider/asymmetric/rsa/PSSSignatureSpi.java \
+org/bouncycastle/jcajce/provider/asymmetric/util/IESUtil.java \
 org/bouncycastle/jcajce/provider/digest/GOST3411.java \
 org/bouncycastle/jcajce/provider/digest/MD2.java \
 org/bouncycastle/jcajce/provider/digest/MD4.java \
@@ -299,6 +325,7 @@
 org/bouncycastle/jcajce/provider/digest/RIPEMD256.java \
 org/bouncycastle/jcajce/provider/digest/RIPEMD320.java \
 org/bouncycastle/jcajce/provider/digest/SHA224.java \
+org/bouncycastle/jcajce/provider/digest/SHA3.java \
 org/bouncycastle/jcajce/provider/digest/Tiger.java \
 org/bouncycastle/jcajce/provider/digest/Whirlpool.java \
 org/bouncycastle/jcajce/provider/symmetric/CAST5.java \
@@ -417,6 +444,7 @@
 # directories
 UNNEEDED_BCPKIX_SOURCES=" \
 docs \
+org/bouncycastle/cert/bc \
 org/bouncycastle/cert/cmp \
 org/bouncycastle/cert/crmf \
 org/bouncycastle/cert/ocsp \
@@ -475,6 +503,7 @@
 org/bouncycastle/cms/CMSCompressedDataStreamGenerator.java \
 org/bouncycastle/cms/CMSConfig.java \
 org/bouncycastle/cms/CMSContentInfoParser.java \
+org/bouncycastle/cms/CMSDigestedData.java \
 org/bouncycastle/cms/CMSEncryptedData.java \
 org/bouncycastle/cms/CMSEncryptedDataGenerator.java \
 org/bouncycastle/cms/CMSEncryptedGenerator.java \
@@ -569,16 +598,28 @@
 org/bouncycastle/operator/OutputEncryptor.java \
 org/bouncycastle/operator/SymmetricKeyUnwrapper.java \
 org/bouncycastle/operator/SymmetricKeyWrapper.java \
+org/bouncycastle/operator/bc/AESUtil.java \
+org/bouncycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java \
+org/bouncycastle/operator/bc/BcAESSymmetricKeyWrapper.java \
+org/bouncycastle/operator/bc/BcAsymmetricKeyUnwrapper.java \
 org/bouncycastle/operator/bc/BcAsymmetricKeyWrapper.java \
 org/bouncycastle/operator/bc/BcContentSignerBuilder.java \
 org/bouncycastle/operator/bc/BcContentVerifierProviderBuilder.java \
+org/bouncycastle/operator/bc/BcDSAContentSignerBuilder.java \
+org/bouncycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java \
+org/bouncycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java \
 org/bouncycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java \
 org/bouncycastle/operator/bc/BcRSAContentSignerBuilder.java \
 org/bouncycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java \
 org/bouncycastle/operator/bc/BcSignerOutputStream.java \
+org/bouncycastle/operator/bc/BcSymmetricKeyUnwrapper.java \
+org/bouncycastle/operator/bc/BcSymmetricKeyWrapper.java \
+org/bouncycastle/operator/bc/CamelliaUtil.java \
 org/bouncycastle/operator/bc/OperatorUtils.java \
+org/bouncycastle/operator/bc/SEEDUtil.java \
 org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java \
 org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java \
+org/bouncycastle/operator/jcajce/JceGenericKey.java \
 org/bouncycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java \
 org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java \
 org/bouncycastle/operator/jcajce/OperatorUtils.java \
diff --git a/bouncycastle.version b/bouncycastle.version
index a9eb1be..1482783 100644
--- a/bouncycastle.version
+++ b/bouncycastle.version
@@ -1,2 +1,2 @@
 BOUNCYCASTLE_JDK=15on
-BOUNCYCASTLE_VERSION=147
+BOUNCYCASTLE_VERSION=148
diff --git a/import_bouncycastle.sh b/import_bouncycastle.sh
index 6d76099..52f65f3 100755
--- a/import_bouncycastle.sh
+++ b/import_bouncycastle.sh
@@ -155,6 +155,21 @@
   generatepatch $patch $bouncycastle_dir $bouncycastle_dir_orig
 }
 
+function update_timestamps() {
+  declare -r git_dir="$1"
+  declare -r target_dir="$2"
+
+  echo -n "Restoring timestamps for ${target_dir}... "
+
+  find "$git_dir" -type f -print0 | while IFS= read -r -d $'\0' file; do
+    file_rev="$(git rev-list -n 1 HEAD "$file")"
+    file_time="$(git show --pretty=format:%ai --abbrev-commit "$file_rev" | head -n 1)"
+    touch -d "$file_time" "${target_dir}${file#$git_dir}"
+  done
+
+  echo "done."
+}
+
 function generate() {
   declare -r patch=$1
   declare -r bouncycastle_source=$2
@@ -172,6 +187,7 @@
     echo "Restoring $i"
     rm -r $bouncycastle_dir/$i
     cp -rf $bouncycastle_out_dir/src/main/java/$i $bouncycastle_dir/$i
+    update_timestamps $bouncycastle_out_dir/src/main/java/$i $bouncycastle_dir/$i
   done
 
   generatepatch $patch $bouncycastle_dir $bouncycastle_dir_orig
@@ -219,7 +235,7 @@
   # Apply appropriate patches
   for i in $bouncycastle_patches; do
     echo "Applying patch $i"
-    patch -p1 < ../$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate patches/$i"
+    patch -p1 --merge < ../$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate $i"
 
     # make sure no unneeded sources got into the patch
     problem=0
diff --git a/patches/README b/patches/README
index 1389c8d..522ff97 100644
--- a/patches/README
+++ b/patches/README
@@ -15,20 +15,15 @@
 Other performance (both speed and memory) and correctness changes:
 - singleton DERNull (BouncyCastle now does this but we make constructor private to be sure)
 - similarly made DERBoolean constructor private and moved to DERBoolean.{getInstance,TRUE,FALSE}
-- removed use of Boolean constructor
+- removed use of Boolean constructor (not-upstreamable due to J2ME requirement upstream)
 - DERObjectIdentifier interns its internal String indentifer value
-- changed uses of 'new Integer' to 'Integer.valueOf'
+- changed uses of 'new Integer' to 'Integers.valueOf'
 - X509CertificateObject.getEncoded caches its result
 - removed references to SecretKeyFactory.PBE/PKCS5 SecretKeyFactory.PBE/PKCS12
 - OpenSSLDigest uses NativeCrypto JNI API
-- KeyStoreSpis made more tolerant of non-existant and null aliases
-- PKCS12 KeyStore.getCreationDate tries to mimic RI behavior on null and missing aliases
-- Make PKCS12 KeyStore throw error when setting non-PrivateKey, instead of on get
-- Make PKCS12 KeyStore tolerate setting with an empty certificate chain
-- Fixed cut & paste instanceof error in EncryptedPrivateKeyInfo
+- JDKKeyStore made more tolerant of non-existant aliases
 - Make BouncyCastleProvider.PROVIDER_NAME final
 - Added wrapper for SecretKeyFactory.PBKDF2WithHmacSHA1
-- Fixed BaseKeyFactorySpi to convert all Exceptions to InvalidKeySpecException for KeyRepTest
 
 Other security changes:
 - Blacklist fraudulent Comodo certificates in PKIXCertPathValidatorSpi
diff --git a/patches/bcpkix.patch b/patches/bcpkix.patch
index db8fdbf..77cee43 100644
--- a/patches/bcpkix.patch
+++ b/patches/bcpkix.patch
@@ -1,6 +1,6 @@
-diff -Naur bcpkix-jdk15on-147.orig/org/bouncycastle/cms/CMSSignedGenerator.java bcpkix-jdk15on-147/org/bouncycastle/cms/CMSSignedGenerator.java
---- bcpkix-jdk15on-147.orig/org/bouncycastle/cms/CMSSignedGenerator.java	2012-03-20 22:55:58.000000000 +0000
-+++ bcpkix-jdk15on-147/org/bouncycastle/cms/CMSSignedGenerator.java	2012-09-19 21:25:32.000000000 +0000
+diff -Naur bcpkix-jdk15on-148.orig/org/bouncycastle/cms/CMSSignedGenerator.java bcpkix-jdk15on-148/org/bouncycastle/cms/CMSSignedGenerator.java
+--- bcpkix-jdk15on-148.orig/org/bouncycastle/cms/CMSSignedGenerator.java	2013-02-08 17:54:18.000000000 +0000
++++ bcpkix-jdk15on-148/org/bouncycastle/cms/CMSSignedGenerator.java	2013-01-31 02:26:40.000000000 +0000
 @@ -22,7 +22,9 @@
  import org.bouncycastle.asn1.DERTaggedObject;
  import org.bouncycastle.asn1.cms.AttributeTable;
@@ -110,13 +110,13 @@
          
          return encOID;
      }
-diff -Naur bcpkix-jdk15on-147.orig/org/bouncycastle/cms/CMSSignedHelper.java bcpkix-jdk15on-147/org/bouncycastle/cms/CMSSignedHelper.java
---- bcpkix-jdk15on-147.orig/org/bouncycastle/cms/CMSSignedHelper.java	2012-03-20 22:55:58.000000000 +0000
-+++ bcpkix-jdk15on-147/org/bouncycastle/cms/CMSSignedHelper.java	2012-09-19 21:25:32.000000000 +0000
+diff -Naur bcpkix-jdk15on-148.orig/org/bouncycastle/cms/CMSSignedHelper.java bcpkix-jdk15on-148/org/bouncycastle/cms/CMSSignedHelper.java
+--- bcpkix-jdk15on-148.orig/org/bouncycastle/cms/CMSSignedHelper.java	2013-02-08 17:54:18.000000000 +0000
++++ bcpkix-jdk15on-148/org/bouncycastle/cms/CMSSignedHelper.java	2013-01-31 02:26:40.000000000 +0000
 @@ -23,7 +23,9 @@
+ import org.bouncycastle.asn1.ASN1Set;
  import org.bouncycastle.asn1.ASN1TaggedObject;
  import org.bouncycastle.asn1.DERNull;
- import org.bouncycastle.asn1.DERObjectIdentifier;
 -import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
 +// BEGIN android-removed
 +// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
@@ -232,9 +232,9 @@
          digestAliases.put("SHA256", new String[] { "SHA-256" });
          digestAliases.put("SHA384", new String[] { "SHA-384" });
          digestAliases.put("SHA512", new String[] { "SHA-512" });
-diff -Naur bcpkix-jdk15on-147.orig/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java bcpkix-jdk15on-147/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
---- bcpkix-jdk15on-147.orig/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java	2012-03-20 22:55:58.000000000 +0000
-+++ bcpkix-jdk15on-147/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java	2012-09-19 21:25:32.000000000 +0000
+diff -Naur bcpkix-jdk15on-148.orig/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java bcpkix-jdk15on-148/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
+--- bcpkix-jdk15on-148.orig/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java	2013-02-08 17:54:18.000000000 +0000
++++ bcpkix-jdk15on-148/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java	2012-09-17 23:04:47.000000000 +0000
 @@ -4,7 +4,9 @@
  import java.util.Map;
  
@@ -346,9 +346,9 @@
      }
  
      /**
-diff -Naur bcpkix-jdk15on-147.orig/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java bcpkix-jdk15on-147/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
---- bcpkix-jdk15on-147.orig/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java	2012-03-20 22:55:58.000000000 +0000
-+++ bcpkix-jdk15on-147/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java	2012-09-19 21:25:32.000000000 +0000
+diff -Naur bcpkix-jdk15on-148.orig/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java bcpkix-jdk15on-148/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
+--- bcpkix-jdk15on-148.orig/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java	2013-02-08 17:54:18.000000000 +0000
++++ bcpkix-jdk15on-148/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java	2012-09-17 23:04:47.000000000 +0000
 @@ -16,21 +16,29 @@
  
      static
@@ -387,9 +387,9 @@
      }
  
      public AlgorithmIdentifier findEncryptionAlgorithm(AlgorithmIdentifier signatureAlgorithm)
-diff -Naur bcpkix-jdk15on-147.orig/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java bcpkix-jdk15on-147/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
---- bcpkix-jdk15on-147.orig/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java	2012-03-20 22:55:58.000000000 +0000
-+++ bcpkix-jdk15on-147/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java	2012-09-19 21:25:32.000000000 +0000
+diff -Naur bcpkix-jdk15on-148.orig/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java bcpkix-jdk15on-148/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
+--- bcpkix-jdk15on-148.orig/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java	2013-02-08 17:54:18.000000000 +0000
++++ bcpkix-jdk15on-148/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java	2013-01-31 02:26:40.000000000 +0000
 @@ -5,7 +5,9 @@
  
  import org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -494,32 +494,9 @@
      }
  
      public AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId)
-@@ -84,7 +104,9 @@
-         }
-         else
-         {
--            digAlgId = new AlgorithmIdentifier((ASN1ObjectIdentifier)digestOids.get(sigAlgId.getAlgorithm()), new DERNull());
-+            // BEGIN android-changed
-+            digAlgId = new AlgorithmIdentifier((ASN1ObjectIdentifier)digestOids.get(sigAlgId.getAlgorithm()), DERNull.INSTANCE);
-+            // END android-changed
-         }
- 
-         return digAlgId;
-@@ -92,6 +114,8 @@
- 
-     public AlgorithmIdentifier find(String digAlgName)
-     {
--        return new AlgorithmIdentifier((ASN1ObjectIdentifier)digestNameToOids.get(digAlgName), new DERNull());
-+        // BEGIN android-changed
-+        return new AlgorithmIdentifier((ASN1ObjectIdentifier)digestNameToOids.get(digAlgName), DERNull.INSTANCE);
-+        // END android-changed
-     }
--}
-\ No newline at end of file
-+}
-diff -Naur bcpkix-jdk15on-147.orig/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java bcpkix-jdk15on-147/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
---- bcpkix-jdk15on-147.orig/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java	2012-03-20 22:55:58.000000000 +0000
-+++ bcpkix-jdk15on-147/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java	2012-09-19 21:25:32.000000000 +0000
+diff -Naur bcpkix-jdk15on-148.orig/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java bcpkix-jdk15on-148/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
+--- bcpkix-jdk15on-148.orig/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java	2013-02-08 17:54:18.000000000 +0000
++++ bcpkix-jdk15on-148/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java	2013-01-31 02:26:40.000000000 +0000
 @@ -9,7 +9,9 @@
  import org.bouncycastle.asn1.ASN1Integer;
  import org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -639,7 +616,7 @@
          noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
          noParams.add(NISTObjectIdentifiers.dsa_with_sha384);
          noParams.add(NISTObjectIdentifiers.dsa_with_sha512);
-@@ -98,55 +120,79 @@
+@@ -98,20 +120,26 @@
          //
          // RFC 4491
          //
@@ -672,41 +649,20 @@
  
          //
          // explicit params
-         //
--        AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull());
-+        // BEGIN android-changed
-+        AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
-+        // END android-changed
+@@ -119,8 +147,10 @@
+         AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
          params.put("SHA1WITHRSAANDMGF1", createPSSParams(sha1AlgId, 20));
  
--        AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, new DERNull());
+-        AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE);
 -        params.put("SHA224WITHRSAANDMGF1", createPSSParams(sha224AlgId, 28));
--
--        AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, new DERNull());
 +        // BEGIN android-removed
-+        // // BEGIN android-changed
 +        // AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE);
-+        // // END android-changed
 +        // params.put("SHA224WITHRSAANDMGF1", createPSSParams(sha224AlgId, 28));
 +        // END android-removed
-+
-+        // BEGIN android-changed
-+        AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);
-+        // END android-changed
+ 
+         AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);
          params.put("SHA256WITHRSAANDMGF1", createPSSParams(sha256AlgId, 32));
- 
--        AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, new DERNull());
-+        // BEGIN android-changed
-+        AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE);
-+        // END android-changed
-         params.put("SHA384WITHRSAANDMGF1", createPSSParams(sha384AlgId, 48));
- 
--        AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, new DERNull());
-+        // BEGIN android-changed
-+        AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE);
-+        // END android-changed
-         params.put("SHA512WITHRSAANDMGF1", createPSSParams(sha512AlgId, 64));
- 
+@@ -134,19 +164,25 @@
          //
          // digests
          //
@@ -740,38 +696,9 @@
      }
  
      private static AlgorithmIdentifier generate(String signatureAlgorithm)
-@@ -177,7 +223,9 @@
- 
-         if (pkcs15RsaEncryption.contains(sigOID))
-         {
--            encAlgId = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, new DERNull());
-+            // BEGIN android-changed
-+            encAlgId = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
-+            // END android-changed
-         }
-         else
-         {
-@@ -190,7 +238,9 @@
-         }
-         else
-         {
--            digAlgId = new AlgorithmIdentifier((ASN1ObjectIdentifier)digestOids.get(sigOID), new DERNull());
-+            // BEGIN android-changed
-+            digAlgId = new AlgorithmIdentifier((ASN1ObjectIdentifier)digestOids.get(sigOID), DERNull.INSTANCE);
-+            // END android-changed
-         }
- 
-         return sigAlgId;
-@@ -209,4 +259,4 @@
-     {
-         return generate(sigAlgName);
-     }
--}
-\ No newline at end of file
-+}
-diff -Naur bcpkix-jdk15on-147.orig/org/bouncycastle/operator/bc/BcUtil.java bcpkix-jdk15on-147/org/bouncycastle/operator/bc/BcUtil.java
---- bcpkix-jdk15on-147.orig/org/bouncycastle/operator/bc/BcUtil.java	2012-03-20 22:55:58.000000000 +0000
-+++ bcpkix-jdk15on-147/org/bouncycastle/operator/bc/BcUtil.java	2012-09-19 21:25:32.000000000 +0000
+diff -Naur bcpkix-jdk15on-148.orig/org/bouncycastle/operator/bc/BcUtil.java bcpkix-jdk15on-148/org/bouncycastle/operator/bc/BcUtil.java
+--- bcpkix-jdk15on-148.orig/org/bouncycastle/operator/bc/BcUtil.java	2013-02-08 17:54:18.000000000 +0000
++++ bcpkix-jdk15on-148/org/bouncycastle/operator/bc/BcUtil.java	2012-09-17 23:04:47.000000000 +0000
 @@ -1,21 +1,29 @@
  package org.bouncycastle.operator.bc;
  
@@ -884,9 +811,9 @@
          else
          {
              throw new OperatorCreationException("cannot recognise digest");
-diff -Naur bcpkix-jdk15on-147.orig/org/bouncycastle/operator/jcajce/OperatorHelper.java bcpkix-jdk15on-147/org/bouncycastle/operator/jcajce/OperatorHelper.java
---- bcpkix-jdk15on-147.orig/org/bouncycastle/operator/jcajce/OperatorHelper.java	2012-03-20 22:55:58.000000000 +0000
-+++ bcpkix-jdk15on-147/org/bouncycastle/operator/jcajce/OperatorHelper.java	2012-09-19 21:25:32.000000000 +0000
+diff -Naur bcpkix-jdk15on-148.orig/org/bouncycastle/operator/jcajce/OperatorHelper.java bcpkix-jdk15on-148/org/bouncycastle/operator/jcajce/OperatorHelper.java
+--- bcpkix-jdk15on-148.orig/org/bouncycastle/operator/jcajce/OperatorHelper.java	2013-02-08 17:54:18.000000000 +0000
++++ bcpkix-jdk15on-148/org/bouncycastle/operator/jcajce/OperatorHelper.java	2013-01-31 02:26:40.000000000 +0000
 @@ -20,7 +20,9 @@
  import org.bouncycastle.asn1.ASN1Encodable;
  import org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -938,8 +865,8 @@
 +        // END android-removed
          oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA");
  
-         asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding");
-@@ -296,10 +308,12 @@
+         oids.put(OIWObjectIdentifiers.idSHA1, "SHA-1");
+@@ -305,10 +317,12 @@
          {
              return "SHA1";
          }
@@ -956,7 +883,7 @@
          else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID))
          {
              return "SHA256";
-@@ -312,22 +326,24 @@
+@@ -321,22 +335,24 @@
          {
              return "SHA512";
          }
diff --git a/patches/bcprov.patch b/patches/bcprov.patch
index 477c392..c1d1bcc 100644
--- a/patches/bcprov.patch
+++ b/patches/bcprov.patch
@@ -1,10 +1,10 @@
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/ASN1Null.java bcprov-jdk15on-147/org/bouncycastle/asn1/ASN1Null.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/ASN1Null.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/ASN1Null.java	2013-01-23 01:01:51.774746500 +0000
-@@ -8,9 +8,11 @@
- public abstract class ASN1Null
-     extends ASN1Primitive
- {
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/asn1/ASN1Null.java bcprov-jdk15on-148/org/bouncycastle/asn1/ASN1Null.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/asn1/ASN1Null.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/asn1/ASN1Null.java	2013-01-31 02:26:40.000000000 +0000
+@@ -11,9 +11,11 @@
+     /**
+      * @deprecated use DERNull.INSTANCE
+      */
 -    public ASN1Null()
 +    // BEGIN android-changed
 +    /*package*/ ASN1Null()
@@ -14,9 +14,9 @@
  
      public static ASN1Null getInstance(Object o)
      {
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/DERBoolean.java bcprov-jdk15on-147/org/bouncycastle/asn1/DERBoolean.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/DERBoolean.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/DERBoolean.java	2013-01-23 01:01:51.764746324 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/asn1/DERBoolean.java bcprov-jdk15on-148/org/bouncycastle/asn1/DERBoolean.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/asn1/DERBoolean.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/asn1/DERBoolean.java	2013-01-31 02:26:40.000000000 +0000
 @@ -10,7 +10,9 @@
      private static final byte[] TRUE_VALUE = new byte[] { (byte)0xff };
      private static final byte[] FALSE_VALUE = new byte[] { 0 };
@@ -28,8 +28,8 @@
  
      public static final ASN1Boolean FALSE = new ASN1Boolean(false);
      public static final ASN1Boolean TRUE  = new ASN1Boolean(true);
-@@ -46,6 +48,17 @@
-         return (value ? TRUE : FALSE);
+@@ -55,6 +57,17 @@
+         return (value != 0 ? TRUE : FALSE);
      }
  
 +    // BEGIN android-added
@@ -46,7 +46,7 @@
      /**
       * return a Boolean from a tagged object.
       *
-@@ -71,7 +84,9 @@
+@@ -80,7 +93,9 @@
          }
      }
      
@@ -57,10 +57,10 @@
          byte[]       value)
      {
          if (value.length != 1)
-@@ -93,8 +108,10 @@
-         }
-     }
- 
+@@ -106,8 +121,10 @@
+      * @deprecated use getInstance(boolean) method.
+      * @param value
+      */
 -    public DERBoolean(
 +    // BEGIN android-changed
 +    protected DERBoolean(
@@ -69,13 +69,13 @@
      {
          this.value = (value) ? TRUE_VALUE : FALSE_VALUE;
      }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/DERNull.java bcprov-jdk15on-147/org/bouncycastle/asn1/DERNull.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/DERNull.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/DERNull.java	2013-01-23 01:01:51.774746500 +0000
-@@ -12,7 +12,9 @@
- 
-     private static final byte[]  zeroBytes = new byte[0];
- 
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/asn1/DERNull.java bcprov-jdk15on-148/org/bouncycastle/asn1/DERNull.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/asn1/DERNull.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/asn1/DERNull.java	2013-01-31 02:26:40.000000000 +0000
+@@ -15,7 +15,9 @@
+     /**
+      * @deprecated use DERNull.INSTANCE
+      */
 -    public DERNull()
 +    // BEGIN android-changed
 +    protected DERNull()
@@ -83,10 +83,10 @@
      {
      }
  
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/DERObjectIdentifier.java bcprov-jdk15on-147/org/bouncycastle/asn1/DERObjectIdentifier.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/DERObjectIdentifier.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/DERObjectIdentifier.java	2013-01-23 01:01:51.784746676 +0000
-@@ -117,7 +117,13 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/asn1/DERObjectIdentifier.java bcprov-jdk15on-148/org/bouncycastle/asn1/DERObjectIdentifier.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/asn1/DERObjectIdentifier.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/asn1/DERObjectIdentifier.java	2013-01-31 02:26:40.000000000 +0000
+@@ -144,7 +144,13 @@
              }
          }
  
@@ -98,10 +98,10 @@
 +         */
 +        this.identifier = objId.toString().intern();
 +        // END android-changed
+         this.body = Arrays.clone(bytes);
      }
  
-     public DERObjectIdentifier(
-@@ -128,7 +134,13 @@
+@@ -156,7 +162,13 @@
              throw new IllegalArgumentException("string " + identifier + " not an OID");
          }
  
@@ -116,9 +116,9 @@
      }
  
      public String getId()
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/DERPrintableString.java bcprov-jdk15on-147/org/bouncycastle/asn1/DERPrintableString.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/DERPrintableString.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/DERPrintableString.java	2013-01-23 01:01:51.854747908 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/asn1/DERPrintableString.java bcprov-jdk15on-148/org/bouncycastle/asn1/DERPrintableString.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/asn1/DERPrintableString.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/asn1/DERPrintableString.java	2013-01-31 02:26:40.000000000 +0000
 @@ -12,7 +12,9 @@
      extends ASN1Primitive
      implements ASN1String
@@ -130,9 +130,9 @@
  
      /**
       * return a printable string from the passed in object.
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/cms/ContentInfo.java bcprov-jdk15on-147/org/bouncycastle/asn1/cms/ContentInfo.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/cms/ContentInfo.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/cms/ContentInfo.java	2013-01-23 01:01:51.874748260 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/asn1/cms/ContentInfo.java bcprov-jdk15on-148/org/bouncycastle/asn1/cms/ContentInfo.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/asn1/cms/ContentInfo.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/asn1/cms/ContentInfo.java	2012-09-17 23:04:47.000000000 +0000
 @@ -12,7 +12,9 @@
  
  public class ContentInfo
@@ -144,27 +144,9 @@
  {
      private ASN1ObjectIdentifier contentType;
      private ASN1Encodable        content;
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java bcprov-jdk15on-147/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java	2013-01-23 01:01:51.774746500 +0000
-@@ -37,10 +37,13 @@
-     public static EncryptedPrivateKeyInfo getInstance(
-         Object  obj)
-     {
--        if (obj instanceof EncryptedData)
-+        // 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 -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java bcprov-jdk15on-147/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java	2013-01-23 01:01:51.774746500 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java bcprov-jdk15on-148/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java	2013-01-31 02:26:40.000000000 +0000
 @@ -10,8 +10,10 @@
      //
      static final ASN1ObjectIdentifier    pkcs_1                    = new ASN1ObjectIdentifier("1.2.840.113549.1.1");
@@ -189,7 +171,7 @@
  
      //
      // pkcs-3 OBJECT IDENTIFIER ::= {
-@@ -65,13 +69,17 @@
+@@ -66,13 +70,17 @@
      // md2 OBJECT IDENTIFIER ::=
      //      {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 2}
      //
@@ -209,7 +191,7 @@
  
      //
      // md5 OBJECT IDENTIFIER ::=
-@@ -80,7 +88,9 @@
+@@ -81,7 +89,9 @@
      static final ASN1ObjectIdentifier    md5                     = digestAlgorithm.branch("5");
  
      static final ASN1ObjectIdentifier    id_hmacWithSHA1         = digestAlgorithm.branch("7");
@@ -220,63 +202,9 @@
      static final ASN1ObjectIdentifier    id_hmacWithSHA256       = digestAlgorithm.branch("9");
      static final ASN1ObjectIdentifier    id_hmacWithSHA384       = digestAlgorithm.branch("10");
      static final ASN1ObjectIdentifier    id_hmacWithSHA512       = digestAlgorithm.branch("11");
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java bcprov-jdk15on-147/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java	2013-01-23 01:01:51.774746500 +0000
-@@ -19,7 +19,9 @@
-     private AlgorithmIdentifier maskGenAlgorithm;
-     private AlgorithmIdentifier pSourceAlgorithm;
-     
--    public final static AlgorithmIdentifier DEFAULT_HASH_ALGORITHM = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull());
-+    // 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 -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java bcprov-jdk15on-147/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java	2013-01-23 01:01:51.774746500 +0000
-@@ -22,7 +22,9 @@
-     private ASN1Integer          saltLength;
-     private ASN1Integer          trailerField;
-     
--    public final static AlgorithmIdentifier DEFAULT_HASH_ALGORITHM = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull());
-+    // 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 -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/util/ASN1Dump.java bcprov-jdk15on-147/org/bouncycastle/asn1/util/ASN1Dump.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/util/ASN1Dump.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/util/ASN1Dump.java	2013-01-23 01:01:51.874748260 +0000
-@@ -78,7 +78,9 @@
-             {
-                 Object  o = e.nextElement();
- 
--                if (o == null || o.equals(new DERNull()))
-+                // BEGIN android-changed
-+                if (o == null || o.equals(DERNull.INSTANCE))
-+                // END android-changed
-                 {
-                     buf.append(tab);
-                     buf.append("NULL");
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/AttCertIssuer.java bcprov-jdk15on-147/org/bouncycastle/asn1/x509/AttCertIssuer.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/AttCertIssuer.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/x509/AttCertIssuer.java	2013-01-23 01:01:51.784746676 +0000
-@@ -46,7 +46,7 @@
-         ASN1TaggedObject obj,
-         boolean          explicit)
-     {
--        return getInstance(obj.getObject()); // must be explictly tagged
-+        return getInstance(obj.getObject()); // must be explicitly tagged
-     }
- 
-     /**
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java bcprov-jdk15on-147/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java	2013-01-23 01:01:51.804747028 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java bcprov-jdk15on-148/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java	2013-01-31 02:26:40.000000000 +0000
 @@ -14,7 +14,9 @@
  import org.bouncycastle.asn1.DERSequence;
  import org.bouncycastle.asn1.DERTaggedObject;
@@ -288,7 +216,7 @@
  
  /**
   * The AuthorityKeyIdentifier object.
-@@ -101,7 +103,9 @@
+@@ -106,7 +108,9 @@
      public AuthorityKeyIdentifier(
          SubjectPublicKeyInfo    spki)
      {
@@ -299,7 +227,7 @@
          byte[]  resBuf = new byte[digest.getDigestSize()];
  
          byte[] bytes = spki.getPublicKeyData().getBytes();
-@@ -119,7 +123,9 @@
+@@ -124,7 +128,9 @@
          GeneralNames            name,
          BigInteger              serialNumber)
      {
@@ -310,98 +238,9 @@
          byte[]  resBuf = new byte[digest.getDigestSize()];
  
          byte[] bytes = spki.getPublicKeyData().getBytes();
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/BasicConstraints.java bcprov-jdk15on-147/org/bouncycastle/asn1/x509/BasicConstraints.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/BasicConstraints.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/x509/BasicConstraints.java	2013-01-23 01:01:51.804747028 +0000
-@@ -14,7 +14,9 @@
- public class BasicConstraints
-     extends ASN1Object
- {
--    DERBoolean  cA = new DERBoolean(false);
-+    // BEGIN android-changed
-+    DERBoolean  cA = DERBoolean.FALSE;
-+    // END android-changed
-     ASN1Integer  pathLenConstraint = null;
- 
-     public static BasicConstraints getInstance(
-@@ -81,7 +83,9 @@
-     {
-         if (cA)
-         {
--            this.cA = new DERBoolean(true);
-+            // BEGIN android-changed
-+            this.cA = DERBoolean.TRUE;
-+            // END android-changed
-         }
-         else
-         {
-@@ -98,7 +102,9 @@
-     public BasicConstraints(
-         int     pathLenConstraint)
-     {
--        this.cA = new DERBoolean(true);
-+        // BEGIN android-changed
-+        this.cA = DERBoolean.TRUE;
-+        // END android-changed
-         this.pathLenConstraint = new ASN1Integer(pathLenConstraint);
-     }
- 
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/CRLReason.java bcprov-jdk15on-147/org/bouncycastle/asn1/x509/CRLReason.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/CRLReason.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/x509/CRLReason.java	2013-01-23 01:01:51.804747028 +0000
-@@ -138,7 +138,9 @@
- 
-     public static CRLReason lookup(int value)
-     {
--        Integer idx = new Integer(value);
-+        // BEGIN android-changed
-+        Integer idx = Integer.valueOf(value);
-+        // END android-changed
- 
-         if (!table.containsKey(idx))
-         {
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java bcprov-jdk15on-147/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java	2013-01-23 01:01:51.804747028 +0000
-@@ -96,11 +96,15 @@
-         }
-         if (onlyContainsUserCerts)
-         {
--            vec.add(new DERTaggedObject(false, 1, new DERBoolean(true)));
-+            // BEGIN android-changed
-+            vec.add(new DERTaggedObject(false, 1, DERBoolean.TRUE));
-+            // END android-changed
-         }
-         if (onlyContainsCACerts)
-         {
--            vec.add(new DERTaggedObject(false, 2, new DERBoolean(true)));
-+            // BEGIN android-changed
-+            vec.add(new DERTaggedObject(false, 2, DERBoolean.TRUE));
-+            // END android-changed
-         }
-         if (onlySomeReasons != null)
-         {
-@@ -108,11 +112,15 @@
-         }
-         if (indirectCRL)
-         {
--            vec.add(new DERTaggedObject(false, 4, new DERBoolean(true)));
-+            // BEGIN android-changed
-+            vec.add(new DERTaggedObject(false, 4, DERBoolean.TRUE));
-+            // END android-changed
-         }
-         if (onlyContainsAttributeCerts)
-         {
--            vec.add(new DERTaggedObject(false, 5, new DERBoolean(true)));
-+            // BEGIN android-changed
-+            vec.add(new DERTaggedObject(false, 5, DERBoolean.TRUE));
-+            // END android-changed
-         }
- 
-         seq = new DERSequence(vec);
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java bcprov-jdk15on-147/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java	2013-01-23 01:01:51.804747028 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java bcprov-jdk15on-148/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java	2013-01-31 02:26:40.000000000 +0000
 @@ -6,7 +6,9 @@
  import org.bouncycastle.asn1.ASN1TaggedObject;
  import org.bouncycastle.asn1.DEROctetString;
@@ -413,7 +252,7 @@
  
  /**
   * The SubjectKeyIdentifier object.
-@@ -119,7 +121,9 @@
+@@ -124,7 +126,9 @@
  
      private static byte[] getDigest(SubjectPublicKeyInfo spki)
      {
@@ -424,23 +263,9 @@
          byte[]  resBuf = new byte[digest.getDigestSize()];
  
          byte[] bytes = spki.getPublicKeyData().getBytes();
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/X509Extensions.java bcprov-jdk15on-147/org/bouncycastle/asn1/x509/X509Extensions.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/X509Extensions.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/x509/X509Extensions.java	2013-01-23 01:01:51.784746676 +0000
-@@ -408,7 +408,9 @@
- 
-             if (ext.isCritical())
-             {
--                v.add(new DERBoolean(true));
-+                // BEGIN android-changed
-+                v.add(DERBoolean.TRUE);
-+                // END android-changed
-             }
- 
-             v.add(ext.getValue());
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/X509Name.java bcprov-jdk15on-147/org/bouncycastle/asn1/x509/X509Name.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/X509Name.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/x509/X509Name.java	2013-01-23 01:01:51.794746852 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/asn1/x509/X509Name.java bcprov-jdk15on-148/org/bouncycastle/asn1/x509/X509Name.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/asn1/x509/X509Name.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/asn1/x509/X509Name.java	2013-01-31 02:26:40.000000000 +0000
 @@ -255,8 +255,10 @@
       */
      public static final Hashtable SymbolLookUp = DefaultLookUp;
@@ -465,21 +290,10 @@
              }
          }
      }
-@@ -702,7 +706,9 @@
- 
-             if (index == -1)
-             {
--                throw new IllegalArgumentException("badly formated directory string");
-+                // BEGIN android-changed
-+                throw new IllegalArgumentException("badly formatted directory string");
-+                // END android-changed
-             }
- 
-             String              name = token.substring(0, index);
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/X509NameTokenizer.java bcprov-jdk15on-147/org/bouncycastle/asn1/x509/X509NameTokenizer.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/asn1/x509/X509NameTokenizer.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/asn1/x509/X509NameTokenizer.java	2013-01-23 01:01:51.784746676 +0000
-@@ -58,6 +58,17 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/asn1/x509/X509NameTokenizer.java bcprov-jdk15on-148/org/bouncycastle/asn1/x509/X509NameTokenizer.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/asn1/x509/X509NameTokenizer.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/asn1/x509/X509NameTokenizer.java	2013-01-31 02:26:40.000000000 +0000
+@@ -96,6 +96,17 @@
                  }
                  else
                  {
@@ -489,37 +303,17 @@
 +                    {
 +                        buf.append('\\');
 +                    }
-+                    else if (c == '+' && seperator != '+')
++                    else if (c == '+' && separator != '+')
 +                    {
 +                        buf.append('\\');
 +                    }
 +                    // END android-added
                      buf.append(c);
                  }
-                 escaped = false;
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/PBEParametersGenerator.java bcprov-jdk15on-147/org/bouncycastle/crypto/PBEParametersGenerator.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/PBEParametersGenerator.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/PBEParametersGenerator.java	2013-01-23 01:01:51.934749316 +0000
-@@ -136,7 +136,8 @@
-     public static byte[] PKCS12PasswordToBytes(
-         char[]  password)
-     {
--        if (password.length > 0)
-+        // BEGIN android-changed
-+        if (password != null && password.length > 0)
-         {
-                                        // +1 for extra 2 pad bytes.
-             byte[]  bytes = new byte[(password.length + 1) * 2];
-@@ -153,5 +154,6 @@
-         {
-             return new byte[0];
-         }
-+        // END android-changed
-     }
- }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/digests/AndroidDigestFactory.java bcprov-jdk15on-147/org/bouncycastle/crypto/digests/AndroidDigestFactory.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/digests/AndroidDigestFactory.java	1970-01-01 00:00:00.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/digests/AndroidDigestFactory.java	2013-01-23 01:01:51.934749316 +0000
+             }
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/digests/AndroidDigestFactory.java bcprov-jdk15on-148/org/bouncycastle/crypto/digests/AndroidDigestFactory.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/digests/AndroidDigestFactory.java	1970-01-01 00:00:00.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/digests/AndroidDigestFactory.java	2012-09-17 23:04:47.000000000 +0000
 @@ -0,0 +1,78 @@
 +/*
 + * Copyright (C) 2012 The Android Open Source Project
@@ -599,9 +393,9 @@
 +        return FACTORY.getSHA512();
 +    }
 +}
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java bcprov-jdk15on-147/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java	1970-01-01 00:00:00.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java	2013-01-23 01:01:51.934749316 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java bcprov-jdk15on-148/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java	1970-01-01 00:00:00.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java	2012-09-17 23:04:47.000000000 +0000
 @@ -0,0 +1,37 @@
 +/*
 + * Copyright (C) 2012 The Android Open Source Project
@@ -640,9 +434,9 @@
 +        return new SHA512Digest();
 +    }
 +}
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java bcprov-jdk15on-147/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java	1970-01-01 00:00:00.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java	2013-01-23 01:01:51.934749316 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java bcprov-jdk15on-148/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java	1970-01-01 00:00:00.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java	2012-09-17 23:04:47.000000000 +0000
 @@ -0,0 +1,27 @@
 +/*
 + * Copyright (C) 2012 The Android Open Source Project
@@ -671,9 +465,9 @@
 +    public Digest getSHA384();
 +    public Digest getSHA512();
 +}
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java bcprov-jdk15on-147/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java	1970-01-01 00:00:00.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java	2013-01-23 01:01:51.934749316 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java bcprov-jdk15on-148/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java	1970-01-01 00:00:00.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java	2012-09-17 23:04:47.000000000 +0000
 @@ -0,0 +1,37 @@
 +/*
 + * Copyright (C) 2012 The Android Open Source Project
@@ -712,9 +506,9 @@
 +        return new OpenSSLDigest.SHA512();
 +    }
 +}
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/digests/OpenSSLDigest.java bcprov-jdk15on-147/org/bouncycastle/crypto/digests/OpenSSLDigest.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/digests/OpenSSLDigest.java	1970-01-01 00:00:00.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/digests/OpenSSLDigest.java	2013-01-23 01:01:51.934749316 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/digests/OpenSSLDigest.java bcprov-jdk15on-148/org/bouncycastle/crypto/digests/OpenSSLDigest.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/digests/OpenSSLDigest.java	1970-01-01 00:00:00.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/digests/OpenSSLDigest.java	2013-02-28 01:42:11.000000000 +0000
 @@ -0,0 +1,159 @@
 +/*
 + * Copyright (C) 2008 The Android Open Source Project
@@ -750,7 +544,7 @@
 +    /**
 +     * 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.
@@ -767,7 +561,7 @@
 +     * 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.
@@ -778,7 +572,7 @@
 +     * 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;
@@ -817,7 +611,7 @@
 +        return i;
 +    }
 +
-+    private int getCtx() {
++    private long getCtx() {
 +        if (ctx == 0) {
 +            ctx = NativeCrypto.EVP_DigestInit(evp_md);
 +        }
@@ -841,43 +635,43 @@
 +    }
 +
 +    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 -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/encodings/OAEPEncoding.java bcprov-jdk15on-147/org/bouncycastle/crypto/encodings/OAEPEncoding.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/encodings/OAEPEncoding.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/encodings/OAEPEncoding.java	2013-01-23 01:01:51.934749316 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/encodings/OAEPEncoding.java bcprov-jdk15on-148/org/bouncycastle/crypto/encodings/OAEPEncoding.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/encodings/OAEPEncoding.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/encodings/OAEPEncoding.java	2012-09-17 23:04:47.000000000 +0000
 @@ -4,7 +4,9 @@
  import org.bouncycastle.crypto.CipherParameters;
  import org.bouncycastle.crypto.Digest;
@@ -900,12 +694,12 @@
      }
      
      public OAEPEncoding(
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/encodings/PKCS1Encoding.java bcprov-jdk15on-147/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/encodings/PKCS1Encoding.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/encodings/PKCS1Encoding.java	2013-01-23 01:01:51.934749316 +0000
-@@ -206,6 +206,12 @@
-         {
-             throw new InvalidCipherTextException("unknown block type");
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/encodings/PKCS1Encoding.java bcprov-jdk15on-148/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/encodings/PKCS1Encoding.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/encodings/PKCS1Encoding.java	2013-01-31 02:26:40.000000000 +0000
+@@ -216,6 +216,12 @@
+                 throw new InvalidCipherTextException("unknown block type");
+             }
          }
 +        // BEGIN android-added
 +        if ((type == 1 && forPrivateKey) || (type == 2 && !forPrivateKey))
@@ -916,9 +710,57 @@
  
          if (useStrictLength && block.length != engine.getOutputBlockSize())
          {
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/engines/DESedeWrapEngine.java bcprov-jdk15on-147/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/engines/DESedeWrapEngine.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/engines/DESedeWrapEngine.java	2013-01-23 01:01:51.904748788 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/engines/AESFastEngine.java bcprov-jdk15on-148/org/bouncycastle/crypto/engines/AESFastEngine.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/engines/AESFastEngine.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/engines/AESFastEngine.java	2013-01-31 02:26:40.000000000 +0000
+@@ -3,6 +3,9 @@
+ 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;
+ 
+ /**
+@@ -723,7 +726,9 @@
+ 
+         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 -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/engines/DESedeEngine.java bcprov-jdk15on-148/org/bouncycastle/crypto/engines/DESedeEngine.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/engines/DESedeEngine.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/engines/DESedeEngine.java	2013-01-31 02:26:40.000000000 +0000
+@@ -2,6 +2,9 @@
+ 
+ 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 @@
+ 
+         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 -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/engines/DESedeWrapEngine.java bcprov-jdk15on-148/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/engines/DESedeWrapEngine.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/engines/DESedeWrapEngine.java	2012-09-17 23:04:47.000000000 +0000
 @@ -6,7 +6,9 @@
  import org.bouncycastle.crypto.Digest;
  import org.bouncycastle.crypto.InvalidCipherTextException;
@@ -941,9 +783,9 @@
      byte[]  digest = new byte[20];
  
     /**
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/generators/DHParametersHelper.java bcprov-jdk15on-147/org/bouncycastle/crypto/generators/DHParametersHelper.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/generators/DHParametersHelper.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/generators/DHParametersHelper.java	2013-01-23 01:01:51.934749316 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/generators/DHParametersHelper.java bcprov-jdk15on-148/org/bouncycastle/crypto/generators/DHParametersHelper.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/generators/DHParametersHelper.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/generators/DHParametersHelper.java	2012-09-17 23:04:47.000000000 +0000
 @@ -3,10 +3,17 @@
  import java.math.BigInteger;
  import java.security.SecureRandom;
@@ -994,9 +836,9 @@
  
          return new BigInteger[] { p, q };
      }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/generators/DSAParametersGenerator.java bcprov-jdk15on-147/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/generators/DSAParametersGenerator.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/generators/DSAParametersGenerator.java	2013-01-23 01:01:51.934749316 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/generators/DSAParametersGenerator.java bcprov-jdk15on-148/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/generators/DSAParametersGenerator.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/generators/DSAParametersGenerator.java	2012-09-17 23:04:47.000000000 +0000
 @@ -1,8 +1,9 @@
  package org.bouncycastle.crypto.generators;
  
@@ -1031,9 +873,9 @@
          int outlen = d.getDigestSize() * 8;
  
  // 1. Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2). If
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java bcprov-jdk15on-147/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java	2013-01-23 01:01:51.934749316 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java bcprov-jdk15on-148/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java	2012-09-17 23:04:47.000000000 +0000
 @@ -3,7 +3,9 @@
  import org.bouncycastle.crypto.CipherParameters;
  import org.bouncycastle.crypto.Digest;
@@ -1056,9 +898,9 @@
  
      /**
       * Construct a OpenSSL Parameters generator. 
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java bcprov-jdk15on-147/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java	2013-01-23 01:01:51.934749316 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java bcprov-jdk15on-148/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java	2012-09-17 23:04:47.000000000 +0000
 @@ -4,7 +4,9 @@
  import org.bouncycastle.crypto.Digest;
  import org.bouncycastle.crypto.Mac;
@@ -1081,58 +923,53 @@
      }
  
      public PKCS5S2ParametersGenerator(Digest digest)
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/macs/HMac.java bcprov-jdk15on-147/org/bouncycastle/crypto/macs/HMac.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/macs/HMac.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/macs/HMac.java	2013-01-23 01:01:51.934749316 +0000
-@@ -32,23 +32,31 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/macs/HMac.java bcprov-jdk15on-148/org/bouncycastle/crypto/macs/HMac.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/macs/HMac.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/macs/HMac.java	2013-01-31 02:26:40.000000000 +0000
+@@ -33,23 +33,31 @@
      {
          blockLengths = new Hashtable();
          
--        blockLengths.put("GOST3411", new Integer(32));
-+        // BEGIN android-removed
-+        // blockLengths.put("GOST3411", Integer.valueOf(32));
-+        //
-+        // blockLengths.put("MD2", Integer.valueOf(16));
-+        // blockLengths.put("MD4", Integer.valueOf(64));
-+        // END android-removed
-+        blockLengths.put("MD5", Integer.valueOf(64));
-         
--        blockLengths.put("MD2", new Integer(16));
--        blockLengths.put("MD4", new Integer(64));
--        blockLengths.put("MD5", new Integer(64));
-+        // BEGIN android-removed
-+        // blockLengths.put("RIPEMD128", Integer.valueOf(64));
-+        // blockLengths.put("RIPEMD160", Integer.valueOf(64));
-+        // END android-removed
-         
--        blockLengths.put("RIPEMD128", new Integer(64));
--        blockLengths.put("RIPEMD160", new Integer(64));
-+        blockLengths.put("SHA-1", Integer.valueOf(64));
-+        // BEGIN android-removed
-+        // blockLengths.put("SHA-224", Integer.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-1", new Integer(64));
--        blockLengths.put("SHA-224", new Integer(64));
--        blockLengths.put("SHA-256", new Integer(64));
--        blockLengths.put("SHA-384", new Integer(128));
--        blockLengths.put("SHA-512", new Integer(128));
+-        blockLengths.put("GOST3411", Integers.valueOf(32));
 -        
--        blockLengths.put("Tiger", new Integer(64));
--        blockLengths.put("Whirlpool", new Integer(64));
+-        blockLengths.put("MD2", Integers.valueOf(16));
+-        blockLengths.put("MD4", Integers.valueOf(64));
 +        // BEGIN android-removed
-+        // blockLengths.put("Tiger", Integer.valueOf(64));
-+        // blockLengths.put("Whirlpool", Integer.valueOf(64));
++        // blockLengths.put("GOST3411", Integers.valueOf(32));
++        //
++        // blockLengths.put("MD2", Integers.valueOf(16));
++        // blockLengths.put("MD4", Integers.valueOf(64));
++        // END android-removed
+         blockLengths.put("MD5", Integers.valueOf(64));
+         
+-        blockLengths.put("RIPEMD128", Integers.valueOf(64));
+-        blockLengths.put("RIPEMD160", Integers.valueOf(64));
++        // BEGIN android-removed
++        // blockLengths.put("RIPEMD128", Integers.valueOf(64));
++        // blockLengths.put("RIPEMD160", Integers.valueOf(64));
++        // END android-removed
+         
+         blockLengths.put("SHA-1", Integers.valueOf(64));
+-        blockLengths.put("SHA-224", Integers.valueOf(64));
++        // BEGIN android-removed
++        // blockLengths.put("SHA-224", Integers.valueOf(64));
++        // END android-removed
+         blockLengths.put("SHA-256", Integers.valueOf(64));
+         blockLengths.put("SHA-384", Integers.valueOf(128));
+         blockLengths.put("SHA-512", Integers.valueOf(128));
+         
+-        blockLengths.put("Tiger", Integers.valueOf(64));
+-        blockLengths.put("Whirlpool", Integers.valueOf(64));
++        // BEGIN android-removed
++        // blockLengths.put("Tiger", Integers.valueOf(64));
++        // blockLengths.put("Whirlpool", Integers.valueOf(64));
 +        // END android-removed
      }
      
      private static int getByteLength(
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/signers/RSADigestSigner.java bcprov-jdk15on-147/org/bouncycastle/crypto/signers/RSADigestSigner.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/signers/RSADigestSigner.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/signers/RSADigestSigner.java	2013-01-23 01:01:51.934749316 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/signers/RSADigestSigner.java bcprov-jdk15on-148/org/bouncycastle/crypto/signers/RSADigestSigner.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/signers/RSADigestSigner.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/signers/RSADigestSigner.java	2012-09-17 23:04:47.000000000 +0000
 @@ -39,18 +39,24 @@
       */
      static
@@ -1164,12 +1001,12 @@
          oidMap.put("MD5", PKCSObjectIdentifiers.md5);
      }
  
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/util/PrivateKeyFactory.java bcprov-jdk15on-147/org/bouncycastle/crypto/util/PrivateKeyFactory.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/util/PrivateKeyFactory.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/util/PrivateKeyFactory.java	2013-01-23 01:01:51.944749492 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/util/PrivateKeyFactory.java bcprov-jdk15on-148/org/bouncycastle/crypto/util/PrivateKeyFactory.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/util/PrivateKeyFactory.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/util/PrivateKeyFactory.java	2013-01-31 02:26:40.000000000 +0000
 @@ -11,7 +11,9 @@
+ import org.bouncycastle.asn1.ASN1Primitive;
  import org.bouncycastle.asn1.ASN1Sequence;
- import org.bouncycastle.asn1.DERInteger;
  import org.bouncycastle.asn1.nist.NISTNamedCurves;
 -import org.bouncycastle.asn1.oiw.ElGamalParameter;
 +// BEGIN android-removed
@@ -1209,7 +1046,7 @@
 -        else if (algId.getAlgorithm().equals(OIWObjectIdentifiers.elGamalAlgorithm))
 -        {
 -            ElGamalParameter params = new ElGamalParameter((ASN1Sequence)algId.getParameters());
--            DERInteger derX = (DERInteger)keyInfo.parsePrivateKey();
+-            ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
 -
 -            return new ElGamalPrivateKeyParameters(derX.getValue(), new ElGamalParameters(
 -                params.getP(), params.getG()));
@@ -1218,7 +1055,7 @@
 +        // 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()));
@@ -1226,7 +1063,7 @@
 +        // END android-removed
          else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_dsa))
          {
-             DERInteger derX = (DERInteger)keyInfo.parsePrivateKey();
+             ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
 @@ -140,10 +148,12 @@
                      {
                          x9 = NISTNamedCurves.getByOID(oid);
@@ -1244,11 +1081,11 @@
                      }
                  }
              }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/crypto/util/PublicKeyFactory.java bcprov-jdk15on-147/org/bouncycastle/crypto/util/PublicKeyFactory.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/crypto/util/PublicKeyFactory.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/crypto/util/PublicKeyFactory.java	2013-01-23 01:01:51.944749492 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/crypto/util/PublicKeyFactory.java bcprov-jdk15on-148/org/bouncycastle/crypto/util/PublicKeyFactory.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/crypto/util/PublicKeyFactory.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/crypto/util/PublicKeyFactory.java	2013-01-31 02:26:40.000000000 +0000
 @@ -13,13 +13,17 @@
- import org.bouncycastle.asn1.DERInteger;
+ import org.bouncycastle.asn1.ASN1Sequence;
  import org.bouncycastle.asn1.DEROctetString;
  import org.bouncycastle.asn1.nist.NISTNamedCurves;
 -import org.bouncycastle.asn1.oiw.ElGamalParameter;
@@ -1287,7 +1124,7 @@
 -        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()));
@@ -1296,7 +1133,7 @@
 +        // 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()));
@@ -1322,10 +1159,32 @@
                      }
                  }
              }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/DSA.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/DSA.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/DSA.java	2013-01-23 01:01:51.724745620 +0000
-@@ -27,26 +27,34 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/DH.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/DH.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/DH.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/DH.java	2013-01-31 02:26:40.000000000 +0000
+@@ -32,11 +32,13 @@
+ 
+             provider.addAlgorithm("AlgorithmParameterGenerator.DH", PREFIX + "AlgorithmParameterGeneratorSpi");
+             
+-            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");
++            // 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 -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/DSA.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/DSA.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/DSA.java	2013-01-31 02:26:40.000000000 +0000
+@@ -27,33 +27,43 @@
              provider.addAlgorithm("KeyPairGenerator.DSA", PREFIX + "KeyPairGeneratorSpi");
              provider.addAlgorithm("KeyFactory.DSA", PREFIX + "KeyFactorySpi");
  
@@ -1351,7 +1210,6 @@
 -            provider.addAlgorithm("Alg.Alias.Signature.DSAWITHSHA1", "DSA");
 -            provider.addAlgorithm("Alg.Alias.Signature.SHA1WithDSA", "DSA");
 -            provider.addAlgorithm("Alg.Alias.Signature.DSAWithSHA1", "DSA");
--            provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10040.4.3", "DSA");
 +            // BEGIN android-removed
 +            // addSignatureAlgorithm(provider, "SHA224", "DSA", PREFIX + "DSASigner$dsa224", NISTObjectIdentifiers.dsa_with_sha224);
 +            // addSignatureAlgorithm(provider, "SHA256", "DSA", PREFIX + "DSASigner$dsa256", NISTObjectIdentifiers.dsa_with_sha256);
@@ -1371,14 +1229,25 @@
 +            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", "DSA");
 +            provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
 +            // END android-changed
  
              AsymmetricKeyInfoConverter keyFact = new KeyFactorySpi();
  
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/EC.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/EC.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/EC.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/EC.java	2013-01-23 01:01:51.674744740 +0000
+             for (int i = 0; i != DSAUtil.dsaOids.length; i++)
+             {
+-                provider.addAlgorithm("Alg.Alias.Signature." + DSAUtil.dsaOids[i], "DSA");
++                // 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 -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/EC.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/EC.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/EC.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/EC.java	2013-01-31 02:26:40.000000000 +0000
 @@ -1,7 +1,9 @@
  package org.bouncycastle.jcajce.provider.asymmetric;
  
@@ -1391,7 +1260,7 @@
  import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
  import org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi;
  import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
-@@ -21,33 +23,43 @@
+@@ -21,39 +23,49 @@
          public void configure(ConfigurableProvider provider)
          {
              provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH");
@@ -1444,17 +1313,29 @@
 -            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");
 +            // BEGIN android-removed
 +            // provider.addAlgorithm("KeyPairGenerator.ECDSA", PREFIX + "KeyPairGeneratorSpi$ECDSA");
 +            // provider.addAlgorithm("KeyPairGenerator.ECDH", PREFIX + "KeyPairGeneratorSpi$ECDH");
 +            // 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");
              provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone");
-@@ -59,23 +71,29 @@
+@@ -65,23 +77,29 @@
              provider.addAlgorithm("Alg.Alias.Signature.SHA1WithECDSA", "ECDSA");
              provider.addAlgorithm("Alg.Alias.Signature.ECDSAWithSHA1", "ECDSA");
              provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10045.4.1", "ECDSA");
@@ -1498,9 +1379,9 @@
          }
      }
  }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/RSA.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/RSA.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/RSA.java	2013-01-23 01:01:51.674744740 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/RSA.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/RSA.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/RSA.java	2013-01-31 02:26:40.000000000 +0000
 @@ -3,7 +3,9 @@
  import org.bouncycastle.asn1.ASN1ObjectIdentifier;
  import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
@@ -1592,7 +1473,7 @@
  
              provider.addAlgorithm("KeyFactory.RSA", PREFIX + "KeyFactorySpi");
              provider.addAlgorithm("KeyPairGenerator.RSA", PREFIX + "KeyPairGeneratorSpi");
-@@ -68,101 +78,117 @@
+@@ -68,101 +78,113 @@
              registerOid(provider, PKCSObjectIdentifiers.rsaEncryption, "RSA", keyFact);
              registerOid(provider, X509ObjectIdentifiers.id_ea_rsa, "RSA", keyFact);
              registerOid(provider, PKCSObjectIdentifiers.id_RSAES_OAEP, "RSA", keyFact);
@@ -1639,12 +1520,10 @@
 -                addDigestSignature(provider, "MD2", PREFIX + "DigestSignatureSpi$MD2", PKCSObjectIdentifiers.md2WithRSAEncryption);
 -            }
 -
--            if (provider.hasAlgorithm("MessageDigest", "MD2"))
+-            if (provider.hasAlgorithm("MessageDigest", "MD4"))
 -            {
 -                addDigestSignature(provider, "MD4", PREFIX + "DigestSignatureSpi$MD4", PKCSObjectIdentifiers.md4WithRSAEncryption);
 -            }
--
--            if (provider.hasAlgorithm("MessageDigest", "MD2"))
 +            // BEGIN android-removed
 +            // registerOid(provider, PKCSObjectIdentifiers.id_RSASSA_PSS, "RSA", keyFact);
 +            //
@@ -1689,17 +1568,13 @@
 +            //     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
+ 
+             if (provider.hasAlgorithm("MessageDigest", "MD5"))
              {
                  addDigestSignature(provider, "MD5", PREFIX + "DigestSignatureSpi$MD5", PKCSObjectIdentifiers.md5WithRSAEncryption);
 -                provider.addAlgorithm("Signature.MD5withRSA/ISO9796-2", PREFIX + "ISOSignatureSpi$MD5WithRSAEncryption");
@@ -1788,9 +1663,9 @@
          }
  
          private void addDigestSignature(
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/X509.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/X509.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/X509.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/X509.java	2013-01-23 01:01:51.724745620 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/X509.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/X509.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/X509.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/X509.java	2012-09-17 23:04:47.000000000 +0000
 @@ -18,8 +18,10 @@
  
          public void configure(ConfigurableProvider provider)
@@ -1804,43 +1679,9 @@
  
              //
              // certificate factories.
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java	2013-01-23 01:01:51.714745444 +0000
-@@ -35,10 +35,12 @@
- 
-     static
-     {
--        Integer i64 = new Integer(64);
--        Integer i192 = new Integer(192);
--        Integer i128 = new Integer(128);
--        Integer i256 = new Integer(256);
-+        // 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
- 
-         algorithms.put("DES", i64);
-         algorithms.put("DESEDE", i192);
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java	2013-01-23 01:01:51.704745268 +0000
-@@ -63,7 +63,9 @@
-     {
-         if (!initialised)
-         {
--            Integer paramStrength = new Integer(strength);
-+            // BEGIN android-changed
-+            Integer paramStrength = Integer.valueOf(strength);
-+            // END android-changed
- 
-             if (params.containsKey(paramStrength))
-             {
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java	2013-01-23 01:01:51.724745620 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java	2012-09-17 23:04:47.000000000 +0000
 @@ -23,11 +23,16 @@
  import org.bouncycastle.crypto.DSA;
  import org.bouncycastle.crypto.Digest;
@@ -1949,9 +1790,9 @@
  
      static public class noneDSA
          extends DSASigner
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java	2013-01-23 01:01:51.704745268 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java	2013-01-31 02:26:40.000000000 +0000
 @@ -19,8 +19,10 @@
  import org.bouncycastle.asn1.DERInteger;
  import org.bouncycastle.asn1.DERNull;
@@ -2023,10 +1864,10 @@
              {
  
                  info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params.toASN1Primitive()), keyStructure.toASN1Primitive());
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java	2013-01-23 01:01:51.704745268 +0000
-@@ -5,10 +5,14 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtil.java	2013-01-31 02:26:40.000000000 +0000
+@@ -5,11 +5,15 @@
  import java.security.PublicKey;
  
  import org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -2035,15 +1876,16 @@
 +// 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;
 -import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
 +// 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;
-@@ -166,14 +170,16 @@
+@@ -224,14 +228,16 @@
              {
                  oid = NISTNamedCurves.getOID(name);
              }
@@ -2068,7 +1910,7 @@
          }
  
          return oid;
-@@ -191,10 +197,12 @@
+@@ -249,10 +255,12 @@
              {
                  params = NISTNamedCurves.getByOID(oid);
              }
@@ -2085,7 +1927,7 @@
          }
  
          return params;
-@@ -212,14 +220,16 @@
+@@ -270,14 +278,16 @@
              {
                  name = NISTNamedCurves.getName(oid);
              }
@@ -2110,9 +1952,9 @@
          }
  
          return name;
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java	2013-01-23 01:01:51.704745268 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java	2013-01-31 02:26:40.000000000 +0000
 @@ -23,20 +23,26 @@
  import org.bouncycastle.crypto.CipherParameters;
  import org.bouncycastle.crypto.DerivationFunction;
@@ -2145,25 +1987,10 @@
 +// 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
-@@ -52,9 +58,11 @@
- 
-     static
-     {
--        Integer i128 = new Integer(128);
--        Integer i192 = new Integer(192);
--        Integer i256 = new Integer(256);
-+        // BEGIN android-changed
-+        Integer i128 = Integer.valueOf(128);
-+        Integer i192 = Integer.valueOf(192);
-+        Integer i256 = Integer.valueOf(256);
-+        // END android-changed
- 
-         algorithms.put(NISTObjectIdentifiers.id_aes128_CBC.getId(), i128);
-         algorithms.put(NISTObjectIdentifiers.id_aes192_CBC.getId(), i192);
-@@ -69,7 +77,9 @@
+@@ -70,7 +76,9 @@
      private BigInteger             result;
      private ECDomainParameters     parameters;
      private BasicAgreement         agreement;
@@ -2174,7 +2001,7 @@
  
      private byte[] bigIntToBytes(
          BigInteger    r)
-@@ -84,7 +94,9 @@
+@@ -85,7 +93,9 @@
      {
          this.kaAlgorithm = kaAlgorithm;
          this.agreement = agreement;
@@ -2185,7 +2012,7 @@
      }
  
      protected Key engineDoPhase(
-@@ -103,25 +115,27 @@
+@@ -104,25 +114,27 @@
          }
  
          CipherParameters pubKey;        
@@ -2230,9 +2057,9 @@
 +        // else
 +        // END android-removed
          {
-             if (!(key instanceof ECPublicKey))
+             if (!(key instanceof PublicKey))
              {
-@@ -142,11 +156,13 @@
+@@ -143,11 +155,13 @@
      protected byte[] engineGenerateSecret()
          throws IllegalStateException
      {
@@ -2251,7 +2078,7 @@
  
          return bigIntToBytes(result);
      }
-@@ -174,23 +190,25 @@
+@@ -175,23 +189,25 @@
      {
          byte[] secret = bigIntToBytes(result);
  
@@ -2294,7 +2121,7 @@
          {
              // TODO Should we be ensuring the key is the right length?
          }
-@@ -218,35 +236,37 @@
+@@ -219,35 +235,37 @@
      private void initFromKey(Key key)
          throws InvalidKeyException
      {
@@ -2359,9 +2186,9 @@
 +        // else
 +        // END android-removed
          {
-             if (!(key instanceof ECPrivateKey))
+             if (!(key instanceof PrivateKey))
              {
-@@ -277,39 +297,41 @@
+@@ -278,39 +296,41 @@
          }
      }
  
@@ -2438,9 +2265,9 @@
 +    // }
 +    // END android-removed
  }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java	2013-01-23 01:01:51.704745268 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java	2012-09-17 23:04:47.000000000 +0000
 @@ -200,14 +200,16 @@
          }
      }
@@ -2466,9 +2293,9 @@
  
      public static class ECDH
          extends KeyFactorySpi
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java	2013-01-23 01:01:51.704745268 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java	2013-01-31 02:26:40.000000000 +0000
 @@ -12,7 +12,9 @@
  import org.bouncycastle.asn1.ASN1ObjectIdentifier;
  import org.bouncycastle.asn1.nist.NISTNamedCurves;
@@ -2480,30 +2307,7 @@
  import org.bouncycastle.asn1.x9.X962NamedCurves;
  import org.bouncycastle.asn1.x9.X9ECParameters;
  import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-@@ -55,13 +57,15 @@
-         static {
-             ecParameters = new Hashtable();
- 
--            ecParameters.put(new Integer(192), new ECGenParameterSpec("prime192v1")); // a.k.a P-192
--            ecParameters.put(new Integer(239), new ECGenParameterSpec("prime239v1"));
--            ecParameters.put(new Integer(256), new ECGenParameterSpec("prime256v1")); // a.k.a P-256
--
--            ecParameters.put(new Integer(224), new ECGenParameterSpec("P-224"));
--            ecParameters.put(new Integer(384), new ECGenParameterSpec("P-384"));
--            ecParameters.put(new Integer(521), new ECGenParameterSpec("P-521"));
-+            // 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(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
-         }
- 
-         public EC()
-@@ -85,8 +89,16 @@
+@@ -86,7 +88,13 @@
              SecureRandom    random)
          {
              this.strength = strength;
@@ -2511,17 +2315,13 @@
 +            if (random != null) {
 +            // END android-added
              this.random = random;
--            ECGenParameterSpec ecParams = (ECGenParameterSpec)ecParameters.get(new Integer(strength));
 +            // 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)
-             {
-@@ -110,6 +122,11 @@
+@@ -111,6 +119,11 @@
              SecureRandom            random)
              throws InvalidAlgorithmParameterException
          {
@@ -2533,7 +2333,7 @@
              if (params instanceof ECParameterSpec)
              {
                  ECParameterSpec p = (ECParameterSpec)params;
-@@ -154,10 +171,12 @@
+@@ -155,10 +168,12 @@
                      {
                          ecP = NISTNamedCurves.getByName(curveName);
                      }
@@ -2550,7 +2350,7 @@
                      if (ecP == null)
                      {
                          // See if it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug)
-@@ -173,10 +192,12 @@
+@@ -174,10 +189,12 @@
                              {
                                  ecP = NISTNamedCurves.getByOID(oid);
                              }
@@ -2567,27 +2367,10 @@
                              if (ecP == null)
                              {
                                  throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName);
-@@ -231,7 +252,15 @@
-         {
-             if (!initialised)
-             {
--                throw new IllegalStateException("EC Key Pair Generator not 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
-             }
- 
-             AsymmetricCipherKeyPair     pair = engine.generateKeyPair();
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java	2013-01-23 01:01:51.704745268 +0000
-@@ -18,15 +18,22 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java	2013-01-31 02:26:40.000000000 +0000
+@@ -16,15 +16,22 @@
  import org.bouncycastle.crypto.DSA;
  import org.bouncycastle.crypto.Digest;
  import org.bouncycastle.crypto.digests.NullDigest;
@@ -2616,8 +2399,8 @@
 +// 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;
-@@ -108,7 +115,9 @@
+ 
+@@ -68,7 +75,9 @@
      {
          public ecDSA()
          {
@@ -2628,7 +2411,7 @@
          }
      }
  
-@@ -121,21 +130,25 @@
+@@ -81,21 +90,25 @@
          }
      }
  
@@ -2663,7 +2446,7 @@
          }
      }
  
-@@ -144,7 +157,9 @@
+@@ -104,7 +117,9 @@
      {
          public ecDSA384()
          {
@@ -2674,7 +2457,7 @@
          }
      }
  
-@@ -153,90 +168,94 @@
+@@ -113,90 +128,94 @@
      {
          public ecDSA512()
          {
@@ -2853,97 +2636,16 @@
  
      private static class StdDSAEncoder
          implements DSAEncoder
-@@ -330,4 +349,4 @@
+@@ -290,4 +309,4 @@
              return sig;
          }
      }
 -}
 \ No newline at end of file
 +}
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java	2013-01-23 01:01:51.694745092 +0000
-@@ -55,11 +55,15 @@
-         {
-             AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(
-                                                             DigestFactory.getOID(currentSpec.getDigestAlgorithm()),
--                                                            new DERNull());
-+                                                            // BEGIN android-changed
-+                                                            DERNull.INSTANCE);
-+                                                            // END android-changed
-             MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)currentSpec.getMGFParameters();
-             AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
-                                                             PKCSObjectIdentifiers.id_mgf1,
--                                                            new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), new DERNull()));
-+                                                            // 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()));
-@@ -170,11 +174,15 @@
-             PSSParameterSpec pssSpec = currentSpec;
-             AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(
-                                                 DigestFactory.getOID(pssSpec.getDigestAlgorithm()),
--                                                new DERNull());
-+                                                // BEGIN android-changed
-+                                                DERNull.INSTANCE);
-+                                                // END android-changed
-             MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters();
-             AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
-                                                 PKCSObjectIdentifiers.id_mgf1,
--                                                new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), new DERNull()));
-+                                                // 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 -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java	2013-01-23 01:01:51.694745092 +0000
-@@ -127,7 +127,9 @@
-      */
-     public byte[] getEncoded()
-     {
--        return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, new DERNull()), new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient()));
-+        // 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 -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java	2013-01-23 01:01:51.694745092 +0000
-@@ -78,7 +78,9 @@
- 
-     public byte[] getEncoded()
-     {
--        return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, new DERNull()), new org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO));
-+        // 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)
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java	2013-01-23 01:01:51.694745092 +0000
-@@ -89,7 +89,9 @@
- 
-     public byte[] getEncoded()
-     {
--        return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, new DERNull()), new org.bouncycastle.asn1.pkcs.RSAPublicKey(getModulus(), getPublicExponent()));
-+        // 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 -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java	2013-01-23 01:01:51.684744916 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java	2013-01-31 02:26:40.000000000 +0000
 @@ -26,7 +26,9 @@
  import org.bouncycastle.crypto.CipherParameters;
  import org.bouncycastle.crypto.Digest;
@@ -2989,7 +2691,7 @@
          else if (pad.equals("OAEPWITHSHA256ANDMGF1PADDING") || pad.equals("OAEPWITHSHA-256ANDMGF1PADDING"))
          {
              initFromSpec(new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
-@@ -534,48 +540,50 @@
+@@ -539,48 +545,50 @@
          }
      }
  
@@ -3084,9 +2786,9 @@
 +    // }
 +    // END android-removed
  }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java	2013-01-23 01:01:51.684744916 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java	2012-09-17 23:04:47.000000000 +0000
 @@ -17,24 +17,31 @@
  import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
  import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
@@ -3318,9 +3020,9 @@
 +    // }
 +    // END android-removed
  }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java	2013-01-23 01:01:51.724745620 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java	2012-09-17 23:04:47.000000000 +0000
 @@ -18,8 +18,10 @@
  import javax.crypto.NoSuchPaddingException;
  import javax.crypto.spec.IvParameterSpec;
@@ -3347,34 +3049,23 @@
                                      };
  
  
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java	2013-01-23 01:01:51.724745620 +0000
-@@ -27,7 +27,9 @@
-             {
-                 return generatePrivate(PrivateKeyInfo.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
-             }
--            catch (IOException e)
-+            // BEGIN android-changed
-+            catch (Exception e)
-+            // END android-changed
-             {
-                 throw new InvalidKeySpecException("encoded key spec not recognised");
-             }
-@@ -48,7 +50,9 @@
-             {
-                 return generatePublic(SubjectPublicKeyInfo.getInstance(((X509EncodedKeySpec)keySpec).getEncoded()));
-             }
--            catch (IOException e)
-+            // BEGIN android-changed
-+            catch (Exception e)
-+            // END android-changed
-             {
-                 throw new InvalidKeySpecException("encoded key spec not recognised");
-             }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java	2013-01-23 01:01:51.674744740 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java	2013-02-21 00:01:31.000000000 +0000
+@@ -334,7 +334,9 @@
+ 
+     public Iterator engineGetCertPathEncodings()
+     {
+-        return null; // TODO: PKIXCertPath.certPathEncodings.iterator();
++        // BEGIN android-changed
++        return PKIXCertPath.certPathEncodings.iterator();
++        // END android-changed
+     }
+ 
+     public CertPath engineGenerateCertPath(
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java	2013-02-21 00:01:31.000000000 +0000
 @@ -36,7 +36,9 @@
  import org.bouncycastle.asn1.pkcs.SignedData;
  import org.bouncycastle.jce.provider.BouncyCastleProvider;
@@ -3386,7 +3077,18 @@
  
  /**
   * CertPath implementation for X.509 certificates.
-@@ -298,27 +300,29 @@
+@@ -51,7 +53,9 @@
+     {
+         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);
+     }
+@@ -298,27 +302,29 @@
              return toDEREncoded(new ContentInfo(
                      PKCSObjectIdentifiers.signedData, sd));
          }
@@ -3437,9 +3139,9 @@
          else
          {
              throw new CertificateEncodingException("unsupported encoding: " + encoding);
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/AES.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/AES.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/AES.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/AES.java	2013-01-23 01:01:51.744745972 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/AES.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/AES.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/AES.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/AES.java	2012-09-17 23:04:47.000000000 +0000
 @@ -1,31 +1,43 @@
  package org.bouncycastle.jcajce.provider.symmetric;
  
@@ -3793,9 +3495,9 @@
          }
      }
  }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/ARC4.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/ARC4.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/ARC4.java	2013-01-23 01:01:51.744745972 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/ARC4.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/ARC4.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/ARC4.java	2012-09-17 23:04:47.000000000 +0000
 @@ -27,7 +27,9 @@
      {
          public KeyGen()
@@ -3807,9 +3509,9 @@
          }
      }
  
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java	2013-01-23 01:01:51.744745972 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java	2012-09-17 23:04:47.000000000 +0000
 @@ -64,7 +64,9 @@
          {
  
@@ -3821,9 +3523,9 @@
              provider.addAlgorithm("KeyGenerator.BLOWFISH", PREFIX + "$KeyGen");
              provider.addAlgorithm("Alg.Alias.KeyGenerator.1.3.6.1.4.1.3029.1.2", "BLOWFISH");
              provider.addAlgorithm("AlgorithmParameters.BLOWFISH", PREFIX + "$AlgParams");
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/DES.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/DES.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/DES.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/DES.java	2013-01-23 01:01:51.744745972 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/DES.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/DES.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/DES.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/DES.java	2012-09-17 23:04:47.000000000 +0000
 @@ -16,11 +16,15 @@
  import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
  import org.bouncycastle.crypto.KeyGenerationParameters;
@@ -4134,9 +3836,9 @@
          }
  
          private void addAlias(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name)
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/DESede.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/DESede.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/DESede.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/DESede.java	2013-01-23 01:01:51.744745972 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/DESede.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/DESede.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/DESede.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/DESede.java	2012-09-17 23:04:47.000000000 +0000
 @@ -1,30 +1,42 @@
  package org.bouncycastle.jcajce.provider.symmetric;
  
@@ -4447,9 +4149,9 @@
          }
      }
  }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java	2013-01-23 01:01:51.744745972 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java	2012-09-17 23:04:47.000000000 +0000
 @@ -7,13 +7,17 @@
  
  import javax.crypto.spec.IvParameterSpec;
@@ -4821,9 +4523,9 @@
  
      public static class PBKDF2
          extends BaseAlgorithmParameters
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java	2013-01-23 01:01:51.754746148 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java	2013-01-31 02:26:40.000000000 +0000
 @@ -17,8 +17,10 @@
  import javax.crypto.ShortBufferException;
  import javax.crypto.spec.IvParameterSpec;
@@ -4837,7 +4539,7 @@
  
  import org.bouncycastle.crypto.BufferedBlockCipher;
  import org.bouncycastle.crypto.CipherParameters;
-@@ -29,12 +31,18 @@
+@@ -30,12 +32,18 @@
  import org.bouncycastle.crypto.modes.CCMBlockCipher;
  import org.bouncycastle.crypto.modes.CFBBlockCipher;
  import org.bouncycastle.crypto.modes.CTSBlockCipher;
@@ -4860,7 +4562,7 @@
  import org.bouncycastle.crypto.modes.SICBlockCipher;
  import org.bouncycastle.crypto.paddings.BlockCipherPadding;
  import org.bouncycastle.crypto.paddings.ISO10126d2Padding;
-@@ -46,11 +54,17 @@
+@@ -47,11 +55,17 @@
  import org.bouncycastle.crypto.params.KeyParameter;
  import org.bouncycastle.crypto.params.ParametersWithIV;
  import org.bouncycastle.crypto.params.ParametersWithRandom;
@@ -4881,7 +4583,7 @@
  import org.bouncycastle.jce.spec.RepeatedSecretKeySpec;
  import org.bouncycastle.util.Strings;
  
-@@ -63,11 +77,15 @@
+@@ -64,11 +78,15 @@
      //
      private Class[]                 availableSpecs =
                                      {
@@ -4900,7 +4602,7 @@
                                      };
  
      private org.bouncycastle.crypto.BlockCipher baseEngine;
-@@ -222,20 +240,22 @@
+@@ -223,20 +241,22 @@
                          new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
              }
          }
@@ -4937,7 +4639,7 @@
          else if (modeName.startsWith("SIC"))
          {
              ivLength = baseEngine.getBlockSize();
-@@ -252,12 +272,14 @@
+@@ -253,12 +273,14 @@
              cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
                          new SICBlockCipher(baseEngine)));
          }
@@ -4958,7 +4660,7 @@
          else if (modeName.startsWith("CTS"))
          {
              ivLength = baseEngine.getBlockSize();
-@@ -268,11 +290,13 @@
+@@ -269,11 +291,13 @@
              ivLength = baseEngine.getBlockSize();
              cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine));
          }
@@ -4977,7 +4679,7 @@
          else if (modeName.startsWith("GCM"))
          {
              ivLength = baseEngine.getBlockSize();
-@@ -441,63 +465,65 @@
+@@ -442,63 +466,65 @@
                  param = new KeyParameter(key.getEncoded());
              }
          }
@@ -5100,46 +4802,9 @@
          else
          {
              throw new InvalidAlgorithmParameterException("unknown parameter type.");
-@@ -701,10 +727,20 @@
-         int     inputLen,
-         byte[]  output,
-         int     outputOffset) 
--        throws IllegalBlockSizeException, BadPaddingException
-+        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);
-+
-+        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);
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java	2013-01-23 01:01:51.744745972 +0000
-@@ -56,6 +56,11 @@
-     {
-         try
-         {
-+            // BEGIN android-added
-+            if (random == null) {
-+                random = new SecureRandom();
-+            }
-+            // END android-added
-             engine.init(new KeyGenerationParameters(random, keySize));
-             uninitialised = false;
-         }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java	2013-01-23 01:01:51.744745972 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java	2012-09-17 23:04:47.000000000 +0000
 @@ -11,25 +11,34 @@
  
  import org.bouncycastle.crypto.CipherParameters;
@@ -5635,9 +5300,9 @@
 +    // }
 +    // END android-removed
  }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java	2013-01-23 01:01:51.744745972 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java	2012-09-17 23:04:47.000000000 +0000
 @@ -13,8 +13,10 @@
  import javax.crypto.ShortBufferException;
  import javax.crypto.spec.IvParameterSpec;
@@ -5664,9 +5329,9 @@
                                          IvParameterSpec.class,
                                          PBEParameterSpec.class
                                      };
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java	2013-01-23 01:01:51.744745972 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java	2013-01-31 02:26:40.000000000 +0000
 @@ -22,8 +22,10 @@
  import javax.crypto.ShortBufferException;
  import javax.crypto.spec.IvParameterSpec;
@@ -5693,7 +5358,7 @@
                                      };
  
      protected int                     pbeType = PKCS12;
-@@ -258,16 +262,19 @@
+@@ -258,6 +262,8 @@
          return null;
      }
  
@@ -5702,11 +5367,7 @@
      protected int engineDoFinal(
          byte[]  input,
          int     inputOffset,
-         int     inputLen,
-         byte[]  output,
-         int     outputOffset)
--        throws IllegalBlockSizeException, BadPaddingException
-+        throws IllegalBlockSizeException, BadPaddingException, ShortBufferException
+@@ -268,6 +274,7 @@
      {
          return 0;
      }
@@ -5714,44 +5375,14 @@
  
      protected byte[] engineWrap(
          Key     key)
-@@ -300,7 +307,12 @@
-         byte[]  wrappedKey,
-         String  wrappedKeyAlgorithm,
-         int     wrappedKeyType)
--    throws InvalidKeyException
-+    // BEGIN android-removed
-+    // throws InvalidKeyException
-+    // END android-removed
-+    // BEGIN android-added
-+    throws InvalidKeyException, NoSuchAlgorithmException
-+    // END android-added
-     {
-         byte[] encoded;
-         try
-@@ -376,10 +388,12 @@
-             {
-                 throw new InvalidKeyException("Unknown key type " + e.getMessage());
-             }
--            catch (NoSuchAlgorithmException e)
--            {
--                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 -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java	2013-01-23 01:01:51.744745972 +0000
-@@ -7,12 +7,17 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java	2013-01-31 02:26:40.000000000 +0000
+@@ -7,13 +7,18 @@
  
  import org.bouncycastle.crypto.CipherParameters;
  import org.bouncycastle.crypto.PBEParametersGenerator;
+-import org.bouncycastle.crypto.digests.GOST3411Digest;
 -import org.bouncycastle.crypto.digests.MD2Digest;
 -import org.bouncycastle.crypto.digests.MD5Digest;
 -import org.bouncycastle.crypto.digests.RIPEMD160Digest;
@@ -5759,6 +5390,7 @@
 -import org.bouncycastle.crypto.digests.SHA256Digest;
 -import org.bouncycastle.crypto.digests.TigerDigest;
 +// 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;
@@ -5772,7 +5404,7 @@
  import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
  import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
  import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
-@@ -28,10 +33,14 @@
+@@ -29,11 +34,15 @@
      //
      static final int        MD5         = 0;
      static final int        SHA1        = 1;
@@ -5784,13 +5416,15 @@
 +    // END android-removed
      static final int        SHA256      = 4;
 -    static final int        MD2         = 5;
+-    static final int        GOST3411    = 6;
 +    // BEGIN android-removed
 +    // static final int        MD2         = 5;
++    // static final int        GOST3411    = 6;
 +    // END android-removed
  
      static final int        PKCS5S1     = 0;
      static final int        PKCS5S2     = 1;
-@@ -53,14 +62,20 @@
+@@ -55,14 +64,20 @@
              {
                  switch (hash)
                  {
@@ -5816,7 +5450,7 @@
                      break;
                  default:
                      throw new IllegalStateException("PKCS5 scheme 1 only supports MD2, MD5 and SHA1.");
-@@ -74,23 +89,33 @@
+@@ -76,27 +91,39 @@
              {
                  switch (hash)
                  {
@@ -5857,15 +5491,25 @@
 +                // END android-removed
                  case SHA256:
 -                    generator = new PKCS12ParametersGenerator(new SHA256Digest());
+-                    break;
+-                case GOST3411:
+-                    generator = new PKCS12ParametersGenerator(new GOST3411Digest());
+-                    break;
 +                    // BEGIN android-changed
 +                    generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA256());
 +                    // END android-changed
-                     break;
++                    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 -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/util/DigestFactory.java bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/util/DigestFactory.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jcajce/provider/util/DigestFactory.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jcajce/provider/util/DigestFactory.java	2013-01-23 01:01:51.754746148 +0000
+                 }
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/util/DigestFactory.java bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/util/DigestFactory.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jcajce/provider/util/DigestFactory.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jcajce/provider/util/DigestFactory.java	2012-09-17 23:04:47.000000000 +0000
 @@ -10,19 +10,26 @@
  import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
  import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -5991,9 +5635,9 @@
              || (sha256.contains(digest1) && sha256.contains(digest2))
              || (sha384.contains(digest1) && sha384.contains(digest2))
              || (sha512.contains(digest1) && sha512.contains(digest2))
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/ECNamedCurveTable.java bcprov-jdk15on-147/org/bouncycastle/jce/ECNamedCurveTable.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/ECNamedCurveTable.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/ECNamedCurveTable.java	2013-01-23 01:01:51.944749492 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/ECNamedCurveTable.java bcprov-jdk15on-148/org/bouncycastle/jce/ECNamedCurveTable.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/ECNamedCurveTable.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/ECNamedCurveTable.java	2012-09-17 23:04:47.000000000 +0000
 @@ -6,7 +6,9 @@
  import org.bouncycastle.asn1.ASN1ObjectIdentifier;
  import org.bouncycastle.asn1.nist.NISTNamedCurves;
@@ -6055,9 +5699,9 @@
  
          return v.elements();
      }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/PKCS10CertificationRequest.java bcprov-jdk15on-147/org/bouncycastle/jce/PKCS10CertificationRequest.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/PKCS10CertificationRequest.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/PKCS10CertificationRequest.java	2013-01-23 01:01:51.984750196 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/PKCS10CertificationRequest.java bcprov-jdk15on-148/org/bouncycastle/jce/PKCS10CertificationRequest.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/PKCS10CertificationRequest.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/PKCS10CertificationRequest.java	2013-01-31 02:26:40.000000000 +0000
 @@ -30,14 +30,18 @@
  import org.bouncycastle.asn1.DERBitString;
  import org.bouncycastle.asn1.DERNull;
@@ -6203,7 +5847,7 @@
          oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA");
          
          //
-@@ -161,35 +191,53 @@
+@@ -161,27 +191,35 @@
          // The parameters field SHALL be NULL for RSA based signature algorithms.
          //
          noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1);
@@ -6233,42 +5877,19 @@
          //
          // explicit params
          //
--        AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull());
-+        // BEGIN android-changed
-+        AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
-+        // END android-changed
+         AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
          params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20));
  
--        AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, new DERNull());
+-        AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE);
 -        params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28));
--
--        AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, new DERNull());
 +        // 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
+ 
+         AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);
          params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32));
- 
--        AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, new DERNull());
-+        // BEGIN android-changed
-+        AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE);
-+        // END android-changed
-         params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48));
- 
--        AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, new DERNull());
-+        // BEGIN android-changed
-+        AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE);
-+        // END android-changed
-         params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64));
-     }
- 
-@@ -595,10 +643,12 @@
+@@ -600,10 +638,12 @@
          {
              return "SHA1";
          }
@@ -6285,7 +5906,7 @@
          else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID))
          {
              return "SHA256";
-@@ -611,22 +661,24 @@
+@@ -616,22 +656,24 @@
          {
              return "SHA512";
          }
@@ -6326,12 +5947,23 @@
          else
          {
              return digestAlgOID.getId();            
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/BouncyCastleProvider.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/BouncyCastleProvider.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/BouncyCastleProvider.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/BouncyCastleProvider.java	2013-01-23 01:01:51.964749844 +0000
-@@ -48,7 +48,10 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/BouncyCastleProvider.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/BouncyCastleProvider.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/BouncyCastleProvider.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/BouncyCastleProvider.java	2013-01-31 02:26:40.000000000 +0000
+@@ -11,7 +11,9 @@
+ 
+ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+ import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
+-import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
++// 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;
+@@ -49,7 +51,10 @@
  {
-     private static String info = "BouncyCastle Security Provider v1.47";
+     private static String info = "BouncyCastle Security Provider v1.48";
  
 -    public static String PROVIDER_NAME = "BC";
 +    // BEGIN android-changed
@@ -6341,7 +5973,7 @@
  
      public static final ProviderConfiguration CONFIGURATION = new BouncyCastleProviderConfiguration();
  
-@@ -61,8 +64,13 @@
+@@ -62,8 +67,13 @@
      private static final String SYMMETRIC_CIPHER_PACKAGE = "org.bouncycastle.jcajce.provider.symmetric.";
      private static final String[] SYMMETRIC_CIPHERS =
      {
@@ -6357,13 +5989,13 @@
      };
  
       /*
-@@ -79,7 +87,12 @@
+@@ -80,7 +90,12 @@
  
      private static final String[] ASYMMETRIC_CIPHERS =
      {
--        "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal"
+-        "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145"
 +        // 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",
@@ -6371,13 +6003,13 @@
      };
  
      /*
-@@ -88,7 +101,12 @@
+@@ -89,7 +104,12 @@
      private static final String DIGEST_PACKAGE = "org.bouncycastle.jcajce.provider.digest.";
      private static final String[] DIGESTS =
      {
--        "GOST3411", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", "SHA256", "SHA384", "SHA512", "Tiger", "Whirlpool"
+-        "GOST3411", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "Tiger", "Whirlpool"
 +        // 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",
@@ -6385,7 +6017,7 @@
      };
  
      /**
-@@ -120,26 +138,28 @@
+@@ -121,26 +141,28 @@
  
          loadAlgorithms(ASYMMETRIC_CIPHER_PACKAGE, ASYMMETRIC_CIPHERS);
  
@@ -6434,7 +6066,7 @@
  
  
          //
-@@ -148,14 +168,24 @@
+@@ -149,14 +171,24 @@
          put("KeyStore.BKS", "org.bouncycastle.jce.provider.JDKKeyStore");
          put("KeyStore.BouncyCastle", "org.bouncycastle.jce.provider.JDKKeyStore$BouncyCastleStore");
          put("KeyStore.PKCS12", "org.bouncycastle.jce.provider.JDKPKCS12KeyStore$BCPKCS12KeyStore");
@@ -6467,7 +6099,7 @@
  
          put("Alg.Alias.KeyStore.UBER", "BouncyCastle");
          put("Alg.Alias.KeyStore.BOUNCYCASTLE", "BouncyCastle");
-@@ -164,29 +194,41 @@
+@@ -165,29 +197,41 @@
          //
          // algorithm parameters
          //
@@ -6519,7 +6151,7 @@
          put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.1", "PKCS12PBE");
          put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.2", "PKCS12PBE");
          put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.3", "PKCS12PBE");
-@@ -217,12 +259,14 @@
+@@ -218,12 +262,14 @@
          put("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC","PKCS12PBE");
          put("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC","PKCS12PBE");
          put("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC","PKCS12PBE");
@@ -6540,17 +6172,13 @@
          
          //
          // key agreement
-@@ -235,16 +279,22 @@
+@@ -235,14 +281,20 @@
+         //
          put("Alg.Alias.Cipher.PBEWithSHAAnd3KeyTripleDES",  "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
-         
  
--        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");
 +        // 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
@@ -6569,7 +6197,7 @@
          put("Cipher.PBEWITHSHA1ANDRC2", "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithSHA1AndRC2");
  
          put("Cipher.PBEWITHSHAAND128BITRC2-CBC", "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithSHAAnd128BitRC2");
-@@ -286,10 +336,12 @@
+@@ -284,10 +336,12 @@
          put("Cipher.PBEWITHMD5AND256BITAES-CBC-OPENSSL", "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithAESCBC");
          
          put("Cipher.PBEWITHSHAANDTWOFISH-CBC", "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithSHAAndTwofish");
@@ -6586,7 +6214,7 @@
          put("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES");
          put("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDDES");
          put("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES");
-@@ -326,16 +378,20 @@
+@@ -324,16 +378,20 @@
          //
          // secret key factories.
          //
@@ -6612,7 +6240,7 @@
          put("SecretKeyFactory.PBEWITHMD5ANDDES", "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD5AndDES");
          put("SecretKeyFactory.PBEWITHMD5ANDRC2", "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD5AndRC2");
          put("SecretKeyFactory.PBEWITHSHA1ANDDES", "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHA1AndDES");
-@@ -347,31 +403,39 @@
+@@ -345,33 +403,41 @@
          put("SecretKeyFactory.PBEWITHSHAAND128BITRC2-CBC", "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAnd128BitRC2");
          put("SecretKeyFactory.PBEWITHSHAAND40BITRC2-CBC", "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAnd40BitRC2");
          put("SecretKeyFactory.PBEWITHSHAANDTWOFISH-CBC", "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAndTwofish");
@@ -6630,6 +6258,8 @@
          put("SecretKeyFactory.PBEWITHMD5AND192BITAES-CBC-OPENSSL", "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD5And192BitAESCBCOpenSSL");
          put("SecretKeyFactory.PBEWITHMD5AND256BITAES-CBC-OPENSSL", "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD5And256BitAESCBCOpenSSL");
  
+-        put("SecretKeyFactory." + CryptoProObjectIdentifiers.gostR3411, "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithGOST3411");
+-
 -        put("Alg.Alias.SecretKeyFactory.PBE", "PBE/PKCS5");
 -
 -        put("Alg.Alias.SecretKeyFactory.BROKENPBEWITHMD5ANDDES", "PBE/PKCS5");
@@ -6642,6 +6272,8 @@
 -        put("Alg.Alias.SecretKeyFactory.PBEWITHMD2ANDDES-CBC", "PBEWITHMD2ANDDES");
 -        put("Alg.Alias.SecretKeyFactory.PBEWITHMD2ANDRC2-CBC", "PBEWITHMD2ANDRC2");
 +        // 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");
@@ -6667,7 +6299,7 @@
          put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES");
          put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDRC2");
          put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES");
-@@ -408,20 +472,31 @@
+@@ -408,20 +474,31 @@
          put("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.getId(), "PBEWITHSHA256AND128BITAES-CBC-BC");
          put("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.getId(), "PBEWITHSHA256AND192BITAES-CBC-BC");
          put("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.getId(), "PBEWITHSHA256AND256BITAES-CBC-BC");
@@ -6706,7 +6338,7 @@
      }
  
      private void loadAlgorithms(String packageName, String[] names)
-@@ -469,21 +544,25 @@
+@@ -468,21 +545,25 @@
      private void addMacAlgorithms()
      {
  
@@ -6744,9 +6376,9 @@
          put("Alg.Alias.Mac.1.3.14.3.2.26", "PBEWITHHMACSHA");
      }
  
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/CertBlacklist.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/CertBlacklist.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/CertBlacklist.java	1970-01-01 00:00:00.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/CertBlacklist.java	2013-01-23 01:01:51.974750020 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/CertBlacklist.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/CertBlacklist.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/CertBlacklist.java	1970-01-01 00:00:00.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/CertBlacklist.java	2013-01-16 01:38:43.000000000 +0000
 @@ -0,0 +1,224 @@
 +/*
 + * Copyright (C) 2012 The Android Open Source Project
@@ -6972,18 +6604,19 @@
 +    }
 +
 +}
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java	2013-01-23 01:01:51.954749668 +0000
-@@ -61,13 +61,17 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java	2013-01-31 02:26:40.000000000 +0000
+@@ -61,14 +61,18 @@
+ import org.bouncycastle.asn1.x509.PolicyInformation;
  import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
  import org.bouncycastle.asn1.x509.X509Extension;
- import org.bouncycastle.asn1.x509.X509Extensions;
 -import org.bouncycastle.jce.X509LDAPCertStoreParameters;
 +// 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;
@@ -6995,18 +6628,7 @@
  import org.bouncycastle.x509.X509AttributeCertificate;
  import org.bouncycastle.x509.X509CRLStoreSelector;
  import org.bouncycastle.x509.X509CertStoreSelector;
-@@ -247,7 +251,9 @@
-             {
-                 // look for URI
-                 List list = (List)it.next();
--                if (list.get(0).equals(new Integer(GeneralName.uniformResourceIdentifier)))
-+                // BEGIN android-changed
-+                if (list.get(0).equals(Integer.valueOf(GeneralName.uniformResourceIdentifier)))
-+                // END android-changed
-                 {
-                     // found
-                     String temp = (String)list.get(1);
-@@ -655,38 +661,40 @@
+@@ -656,38 +660,40 @@
          {
              try
              {
@@ -7079,7 +6701,7 @@
              }
              catch (Exception e)
              {
-@@ -751,33 +759,35 @@
+@@ -752,33 +758,35 @@
          return certs;
      }
  
@@ -7142,10 +6764,10 @@
  
      protected static void addAdditionalStoresFromCRLDistributionPoint(
          CRLDistPoint crldp, ExtendedPKIXParameters pkixParams)
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEBlockCipher.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEBlockCipher.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEBlockCipher.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEBlockCipher.java	2013-01-23 01:01:51.954749668 +0000
-@@ -18,8 +18,10 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCEBlockCipher.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCEBlockCipher.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCEBlockCipher.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCEBlockCipher.java	2013-01-31 02:26:40.000000000 +0000
+@@ -24,8 +24,10 @@
  import javax.crypto.ShortBufferException;
  import javax.crypto.spec.IvParameterSpec;
  import javax.crypto.spec.PBEParameterSpec;
@@ -7155,21 +6777,10 @@
 +// import javax.crypto.spec.RC2ParameterSpec;
 +// import javax.crypto.spec.RC5ParameterSpec;
 +// END android-removed
+ import javax.crypto.spec.SecretKeySpec;
  
- import org.bouncycastle.crypto.BlockCipher;
- import org.bouncycastle.crypto.BufferedBlockCipher;
-@@ -28,7 +30,9 @@
- import org.bouncycastle.crypto.InvalidCipherTextException;
- import org.bouncycastle.crypto.engines.AESFastEngine;
- import org.bouncycastle.crypto.engines.DESEngine;
--import org.bouncycastle.crypto.engines.GOST28147Engine;
-+// 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;
-@@ -36,12 +40,18 @@
+ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+@@ -44,12 +46,18 @@
  import org.bouncycastle.crypto.modes.CCMBlockCipher;
  import org.bouncycastle.crypto.modes.CFBBlockCipher;
  import org.bouncycastle.crypto.modes.CTSBlockCipher;
@@ -7192,7 +6803,7 @@
  import org.bouncycastle.crypto.modes.SICBlockCipher;
  import org.bouncycastle.crypto.paddings.BlockCipherPadding;
  import org.bouncycastle.crypto.paddings.ISO10126d2Padding;
-@@ -53,12 +63,16 @@
+@@ -61,12 +69,16 @@
  import org.bouncycastle.crypto.params.KeyParameter;
  import org.bouncycastle.crypto.params.ParametersWithIV;
  import org.bouncycastle.crypto.params.ParametersWithRandom;
@@ -7213,7 +6824,7 @@
  import org.bouncycastle.jce.spec.RepeatedSecretKeySpec;
  import org.bouncycastle.util.Strings;
  
-@@ -71,11 +85,15 @@
+@@ -79,11 +91,15 @@
      //
      private Class[]                 availableSpecs =
                                      {
@@ -7232,7 +6843,7 @@
                                      };
   
      private BlockCipher             baseEngine;
-@@ -232,20 +250,22 @@
+@@ -240,20 +256,22 @@
                          new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
              }
          }
@@ -7269,7 +6880,7 @@
          else if (modeName.startsWith("SIC"))
          {
              ivLength = baseEngine.getBlockSize();
-@@ -262,12 +282,14 @@
+@@ -270,12 +288,14 @@
              cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
                          new SICBlockCipher(baseEngine)));
          }
@@ -7290,7 +6901,7 @@
          else if (modeName.startsWith("CTS"))
          {
              ivLength = baseEngine.getBlockSize();
-@@ -278,11 +300,13 @@
+@@ -286,11 +306,13 @@
              ivLength = baseEngine.getBlockSize();
              cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine));
          }
@@ -7309,7 +6920,7 @@
          else if (modeName.startsWith("GCM"))
          {
              ivLength = baseEngine.getBlockSize();
-@@ -371,13 +395,15 @@
+@@ -379,13 +401,15 @@
              throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption.");
          }
          
@@ -7332,7 +6943,7 @@
  
          //
          // a note on iv's - if ivLength is zero the IV gets ignored (we don't use it).
-@@ -451,63 +477,65 @@
+@@ -459,63 +483,65 @@
                  param = new KeyParameter(key.getEncoded());
              }
          }
@@ -7455,153 +7066,9 @@
          else
          {
              throw new InvalidAlgorithmParameterException("unknown parameter type.");
-@@ -711,10 +739,21 @@
-         int     inputLen,
-         byte[]  output,
-         int     outputOffset) 
--        throws IllegalBlockSizeException, BadPaddingException
-+        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);
-+
-+        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);
-@@ -756,62 +795,64 @@
-         }
-     }
- 
--    /**
--     * 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);
--        }
--    }
-+    // 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
- 
-     /**
-      * PBEWithMD5AndDES
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEECPrivateKey.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEECPrivateKey.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEECPrivateKey.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEECPrivateKey.java	2013-01-23 01:01:51.964749844 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCEECPrivateKey.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCEECPrivateKey.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCEECPrivateKey.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCEECPrivateKey.java	2013-01-31 02:26:40.000000000 +0000
 @@ -20,8 +20,10 @@
  import org.bouncycastle.asn1.DERInteger;
  import org.bouncycastle.asn1.DERNull;
@@ -7673,9 +7140,9 @@
              {
  
                  info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params.toASN1Primitive()), keyStructure.toASN1Primitive());
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEECPublicKey.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEECPublicKey.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEECPublicKey.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEECPublicKey.java	2013-01-23 01:01:51.954749668 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCEECPublicKey.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCEECPublicKey.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCEECPublicKey.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCEECPublicKey.java	2013-01-31 02:26:40.000000000 +0000
 @@ -18,9 +18,11 @@
  import org.bouncycastle.asn1.DERBitString;
  import org.bouncycastle.asn1.DERNull;
@@ -7834,7 +7301,7 @@
          {
              X962Parameters params = new X962Parameters((ASN1Primitive)info.getAlgorithmId().getParameters());
              ECCurve                 curve;
-@@ -315,45 +327,47 @@
+@@ -315,52 +327,54 @@
          ASN1Encodable        params;
          SubjectPublicKeyInfo info;
  
@@ -7874,7 +7341,14 @@
 -            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
 +        // BEGIN android-removed
@@ -7914,16 +7388,23 @@
 +        //     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
          {
              if (ecSpec instanceof ECNamedCurveSpec)
              {
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEMac.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEMac.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEMac.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEMac.java	2013-01-23 01:01:51.964749844 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCEMac.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCEMac.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCEMac.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCEMac.java	2012-09-17 23:04:47.000000000 +0000
 @@ -11,24 +11,35 @@
  
  import org.bouncycastle.crypto.CipherParameters;
@@ -8462,51 +7943,9 @@
 +    // }
 +    // END android-removed
  }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java	2013-01-23 01:01:51.974750020 +0000
-@@ -127,7 +127,9 @@
-      */
-     public byte[] getEncoded()
-     {
--        return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, new DERNull()), new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient()));
-+        // 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 -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCERSAPrivateKey.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCERSAPrivateKey.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCERSAPrivateKey.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCERSAPrivateKey.java	2013-01-23 01:01:51.974750020 +0000
-@@ -78,7 +78,9 @@
- 
-     public byte[] getEncoded()
-     {
--        return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, new DERNull()), new org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO));
-+        // 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)
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCERSAPublicKey.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCERSAPublicKey.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCERSAPublicKey.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCERSAPublicKey.java	2013-01-23 01:01:51.974750020 +0000
-@@ -91,7 +91,9 @@
- 
-     public byte[] getEncoded()
-     {
--        return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, new DERNull()), new RSAPublicKeyStructure(getModulus(), getPublicExponent()));
-+        // BEGIN android-changed
-+        return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKeyStructure(getModulus(), getPublicExponent()));
-+        // END android-changed
-     }
- 
-     public int hashCode()
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCESecretKeyFactory.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCESecretKeyFactory.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCESecretKeyFactory.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCESecretKeyFactory.java	2013-01-23 01:01:51.974750020 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCESecretKeyFactory.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCESecretKeyFactory.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCESecretKeyFactory.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCESecretKeyFactory.java	2013-01-31 02:26:40.000000000 +0000
 @@ -252,29 +252,31 @@
          }
      }
@@ -8681,10 +8120,10 @@
 +    }
 +    // END android-added
  }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEStreamCipher.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEStreamCipher.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JCEStreamCipher.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JCEStreamCipher.java	2013-01-23 01:01:51.984750196 +0000
-@@ -14,20 +14,26 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCEStreamCipher.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCEStreamCipher.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JCEStreamCipher.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/JCEStreamCipher.java	2013-01-29 02:13:59.000000000 +0000
+@@ -23,8 +23,10 @@
  import javax.crypto.ShortBufferException;
  import javax.crypto.spec.IvParameterSpec;
  import javax.crypto.spec.PBEParameterSpec;
@@ -8694,9 +8133,10 @@
 +// import javax.crypto.spec.RC2ParameterSpec;
 +// import javax.crypto.spec.RC5ParameterSpec;
 +// END android-removed
+ import javax.crypto.spec.SecretKeySpec;
  
- import org.bouncycastle.crypto.BlockCipher;
- import org.bouncycastle.crypto.CipherParameters;
+ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+@@ -33,12 +35,16 @@
  import org.bouncycastle.crypto.DataLengthException;
  import org.bouncycastle.crypto.StreamBlockCipher;
  import org.bouncycastle.crypto.StreamCipher;
@@ -8718,7 +8158,7 @@
  import org.bouncycastle.crypto.modes.CFBBlockCipher;
  import org.bouncycastle.crypto.modes.OFBBlockCipher;
  import org.bouncycastle.crypto.params.KeyParameter;
-@@ -44,8 +50,10 @@
+@@ -55,8 +61,10 @@
      //
      private Class[]                 availableSpecs =
                                      {
@@ -8731,7 +8171,7 @@
                                          IvParameterSpec.class,
                                          PBEParameterSpec.class
                                      };
-@@ -376,125 +384,127 @@
+@@ -491,125 +499,127 @@
       * The ciphers that inherit from us.
       */
  
@@ -8978,9 +8418,9 @@
  
      /**
       * PBEWithSHAAnd128BitRC4
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java	2013-01-23 01:01:51.964749844 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java	2012-09-17 23:04:47.000000000 +0000
 @@ -17,7 +17,9 @@
  import org.bouncycastle.asn1.DERSequence;
  import org.bouncycastle.asn1.pkcs.PBKDF2Params;
@@ -9209,9 +8649,9 @@
 +    // }
 +    // END android-removed
  }
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JDKKeyStore.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JDKKeyStore.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JDKKeyStore.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JDKKeyStore.java	2013-01-23 01:01:51.974750020 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JDKKeyStore.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/JDKKeyStore.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JDKKeyStore.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/JDKKeyStore.java	2012-09-17 23:04:47.000000000 +0000
 @@ -39,7 +39,12 @@
  import org.bouncycastle.crypto.CipherParameters;
  import org.bouncycastle.crypto.Digest;
@@ -9296,85 +8736,10 @@
      
              this.saveStore(new TeeOutputStream(cOut, dgOut));
      
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java	2013-01-23 01:01:51.974750020 +0000
-@@ -261,10 +261,13 @@
-             }
-         }
- 
--        if (c == null && k == null)
--        {
--            throw new KeyStoreException("no such entry as " + alias);
--        }
-+        // 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
-     }
- 
-     /**
-@@ -439,6 +442,14 @@
-     
-     public Date engineGetCreationDate(String alias) 
-     {
-+        // BEGIN android-added
-+        if (alias == null) {
-+            throw new NullPointerException("alias == null");
-+        }
-+        if (keys.get(alias) == null && certs.get(alias) == null) {
-+            return null;
-+        }
-+        // END android-added
-         return new Date();
-     }
- 
-@@ -497,6 +508,11 @@
-         Certificate[]   chain) 
-         throws KeyStoreException
-     {
-+        // BEGIN android-added
-+        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");
-@@ -508,12 +524,18 @@
-         }
- 
-         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++)
-         {
-             chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]);
-         }
-+        // BEGIN android-added
-+        }
-+        // END android-added
-     }
- 
-     public int engineSize() 
-@@ -1489,7 +1511,9 @@
-         {
-             byte[] res = calculatePbeMac(id_SHA1, mSalt, itCount, password, false, data);
- 
--            AlgorithmIdentifier     algId = new AlgorithmIdentifier(id_SHA1, new DERNull());
-+            // 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);
-@@ -1546,32 +1570,34 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java	2013-01-31 02:26:40.000000000 +0000
+@@ -1557,32 +1557,34 @@
          }
      }
  
@@ -9435,42 +8800,9 @@
  
      private static class IgnoresCaseHashtable
      {
-@@ -1580,7 +1606,9 @@
- 
-         public void put(String key, Object value)
-         {
--            String lower = Strings.toLowerCase(key);
-+            // BEGIN android-changed
-+            String lower = (key == null) ? null : Strings.toLowerCase(key);
-+            // END android-changed
-             String k = (String)keys.get(lower);
-             if (k != null)
-             {
-@@ -1598,7 +1626,9 @@
- 
-         public Object remove(String alias)
-         {
--            String k = (String)keys.remove(Strings.toLowerCase(alias));
-+            // BEGIN android-changed
-+            String k = (String)keys.remove(alias == null ? null : Strings.toLowerCase(alias));
-+            // END android-changed
-             if (k == null)
-             {
-                 return null;
-@@ -1609,7 +1639,9 @@
- 
-         public Object get(String alias)
-         {
--            String k = (String)keys.get(Strings.toLowerCase(alias));
-+            // BEGIN android-changed
-+            String k = (String)keys.get(alias == null ? null : Strings.toLowerCase(alias));
-+            // END android-changed
-             if (k == null)
-             {
-                 return null;
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java	2013-01-23 01:01:51.984750196 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java	2012-09-17 23:04:47.000000000 +0000
 @@ -1,5 +1,8 @@
  package org.bouncycastle.jce.provider;
  
@@ -9529,24 +8861,20 @@
              // try
              // {
              //
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java	2013-01-23 01:01:51.984750196 +0000
-@@ -1533,7 +1533,9 @@
-         for (Enumeration e = permitted.getObjects(); e.hasMoreElements();)
-         {
-             GeneralSubtree subtree = GeneralSubtree.getInstance(e.nextElement());
--            Integer tagNo = new Integer(subtree.getBase().getTagNo());
-+            // BEGIN android-changed
-+            Integer tagNo = Integer.valueOf(subtree.getBase().getTagNo());
-+            // END android-changed
-             if (subtreesMap.get(tagNo) == null)
-             {
-                 subtreesMap.put(tagNo, new HashSet());
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/X509CertificateObject.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/X509CertificateObject.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/X509CertificateObject.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/X509CertificateObject.java	2013-01-23 01:01:51.954749668 +0000
-@@ -544,12 +544,20 @@
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/X509CertificateObject.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/X509CertificateObject.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/X509CertificateObject.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/X509CertificateObject.java	2013-01-31 02:26:40.000000000 +0000
+@@ -57,6 +57,9 @@
+ import org.bouncycastle.asn1.x509.Extensions;
+ import org.bouncycastle.asn1.x509.GeneralName;
+ import org.bouncycastle.asn1.x509.KeyUsage;
++// 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;
+@@ -562,12 +565,20 @@
          }
      }
  
@@ -9568,9 +8896,20 @@
          }
          catch (IOException e)
          {
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/X509SignatureUtil.java bcprov-jdk15on-147/org/bouncycastle/jce/provider/X509SignatureUtil.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/jce/provider/X509SignatureUtil.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/jce/provider/X509SignatureUtil.java	2013-01-23 01:01:51.984750196 +0000
+@@ -858,7 +869,9 @@
+                     list.add(genName.getEncoded());
+                     break;
+                 case GeneralName.directoryName:
+-                    list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString());
++                    // BEGIN android-changed
++                    list.add(X509Name.getInstance(genName.getName()).toString(true, X509Name.DefaultSymbols));
++                    // END android-changed
+                     break;
+                 case GeneralName.dNSName:
+                 case GeneralName.rfc822Name:
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/X509SignatureUtil.java bcprov-jdk15on-148/org/bouncycastle/jce/provider/X509SignatureUtil.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/jce/provider/X509SignatureUtil.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/jce/provider/X509SignatureUtil.java	2013-01-31 02:26:40.000000000 +0000
 @@ -14,7 +14,9 @@
  import org.bouncycastle.asn1.ASN1Sequence;
  import org.bouncycastle.asn1.DERNull;
@@ -9582,18 +8921,7 @@
  import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
  import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
  import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-@@ -25,7 +27,9 @@
- 
- class X509SignatureUtil
- {
--    private static final ASN1Null       derNull = new DERNull();
-+    // BEGIN android-changed
-+    private static final ASN1Null       derNull = DERNull.INSTANCE;
-+    // END android-changed
-     
-     static void setSignatureParameters(
-         Signature signature,
-@@ -66,12 +70,14 @@
+@@ -66,12 +68,14 @@
          
          if (params != null && !derNull.equals(params))
          {
@@ -9614,7 +8942,7 @@
              if (sigAlgId.getObjectId().equals(X9ObjectIdentifiers.ecdsa_with_SHA2))
              {
                  ASN1Sequence ecDsaParams = ASN1Sequence.getInstance(params);
-@@ -98,10 +104,12 @@
+@@ -98,10 +102,12 @@
          {
              return "SHA1";
          }
@@ -9631,7 +8959,7 @@
          else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID))
          {
              return "SHA256";
-@@ -114,22 +122,24 @@
+@@ -114,22 +120,24 @@
          {
              return "SHA512";
          }
@@ -9672,9 +9000,9 @@
          else
          {
              return digestAlgOID.getId();            
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/x509/X509Util.java bcprov-jdk15on-147/org/bouncycastle/x509/X509Util.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/x509/X509Util.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/x509/X509Util.java	2013-01-23 01:01:51.894748612 +0000
+diff -Naur bcprov-jdk15on-148.orig/org/bouncycastle/x509/X509Util.java bcprov-jdk15on-148/org/bouncycastle/x509/X509Util.java
+--- bcprov-jdk15on-148.orig/org/bouncycastle/x509/X509Util.java	2013-02-10 00:37:58.000000000 +0000
++++ bcprov-jdk15on-148/org/bouncycastle/x509/X509Util.java	2013-01-31 02:26:40.000000000 +0000
 @@ -25,12 +25,16 @@
  import org.bouncycastle.asn1.ASN1Integer;
  import org.bouncycastle.asn1.DERNull;
@@ -9793,7 +9121,7 @@
          noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
          noParams.add(NISTObjectIdentifiers.dsa_with_sha384);
          noParams.add(NISTObjectIdentifiers.dsa_with_sha512);
-@@ -105,25 +127,39 @@
+@@ -105,8 +127,10 @@
          //
          // RFC 4491
          //
@@ -9806,64 +9134,16 @@
  
          //
          // explicit params
-         //
--        AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull());
-+        // BEGIN android-changed
-+        AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
-+        // END android-changed
+@@ -114,8 +138,10 @@
+         AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
          params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20));
  
--        AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, new DERNull());
+-        AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE);
 -        params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28));
--
--        AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, new DERNull());
 +        // 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
+ 
+         AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);
          params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32));
- 
--        AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, new DERNull());
-+        // BEGIN android-changed
-+        AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE);
-+        // END android-changed
-         params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48));
- 
--        AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, new DERNull());
-+        // BEGIN android-changed
-+        AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE);
-+        // END android-changed
-         params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64));
-     }
- 
-@@ -166,7 +202,9 @@
-         }
-         else
-         {
--            return new AlgorithmIdentifier(sigOid, new DERNull());
-+            // BEGIN android-changed
-+            return new AlgorithmIdentifier(sigOid, DERNull.INSTANCE);
-+            // END android-changed
-         }
-     }
-     
-diff -Naur bcprov-jdk15on-147.orig/org/bouncycastle/x509/extension/X509ExtensionUtil.java bcprov-jdk15on-147/org/bouncycastle/x509/extension/X509ExtensionUtil.java
---- bcprov-jdk15on-147.orig/org/bouncycastle/x509/extension/X509ExtensionUtil.java	2012-03-22 15:11:48.000000000 +0000
-+++ bcprov-jdk15on-147/org/bouncycastle/x509/extension/X509ExtensionUtil.java	2013-01-23 01:01:51.884748436 +0000
-@@ -62,7 +62,9 @@
-             {
-                 GeneralName genName = GeneralName.getInstance(it.nextElement());
-                 List list = new ArrayList();
--                list.add(new Integer(genName.getTagNo()));
-+                // BEGIN android-changed
-+                list.add(Integer.valueOf(genName.getTagNo()));
-+                // END android-changed
-                 switch (genName.getTagNo())
-                 {
-                 case GeneralName.ediPartyName: