Merge "Add art's fuzzer to the visibility" into main
diff --git a/Android.bp b/Android.bp
index b7ed308..9e8eca6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -51,6 +51,9 @@
errorprone: {
javacflags: [
"-Xep:MissingOverride:OFF", // Ignore missing @Override.
+ "-Xep:BoxedPrimitiveEquality:WARN",
+ "-Xep:DoubleBraceInitialization:WARN",
+ "-Xep:HashtableContains:WARN",
],
},
}
@@ -65,13 +68,6 @@
lint: {
warning_checks: ["SuspiciousIndentation"],
},
- errorprone: {
- javacflags: [
- "-Xep:BoxedPrimitiveEquality:WARN",
- "-Xep:DoubleBraceInitialization:WARN",
- "-Xep:HashtableContains:WARN",
- ],
- },
}
// The src files for bouncycastle, used to generate core platform / intra-core
@@ -191,6 +187,7 @@
"//packages/apps/RemoteProvisioner/tests/unittests",
"//packages/modules/Connectivity/tests/cts/net",
"//packages/modules/RemoteKeyProvisioning/app/tests/unit",
+ "//packages/modules/Virtualization/tests/vm_attestation",
"//packages/modules/Wifi/service",
"//packages/modules/Wifi/service/tests/wifitests",
"//libcore",
@@ -342,6 +339,7 @@
//Excludes directories not needed.
java_library {
name: "bouncycastle-uwb",
+ defaults: ["bouncycastle-errorprone-defaults"],
visibility: [
"//packages/modules/Uwb/service",
],
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java
index d0b1259..df8b1d6 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java
@@ -323,9 +323,9 @@
digOut.close();
- if (!Arrays.areEqual(digCalc.getDigest(), getObjectDigest()))
+ if (Arrays.areEqual(digCalc.getDigest(), getObjectDigest()))
{
- return false;
+ return true;
}
}
catch (Exception e)
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java b/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java
index c71be36..55bc072 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java
@@ -12,6 +12,7 @@
import java.util.List;
import java.util.Set;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
@@ -19,9 +20,12 @@
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;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.AttributeCertificate;
import org.bouncycastle.asn1.x509.AttributeCertificateInfo;
@@ -77,28 +81,6 @@
}
}
- static X509CRLHolder generateFullCRL(ContentSigner signer, TBSCertList tbsCertList)
- {
- try
- {
- return new X509CRLHolder(generateCRLStructure(tbsCertList, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCertList)));
- }
- catch (IOException e)
- {
- throw new IllegalStateException("cannot produce certificate signature");
- }
- }
-
- private static byte[] generateSig(ContentSigner signer, ASN1Object tbsObj)
- throws IOException
- {
- OutputStream sOut = signer.getOutputStream();
- tbsObj.encodeTo(sOut, ASN1Encoding.DER);
- sOut.close();
-
- return signer.getSignature();
- }
-
private static Certificate generateStructure(TBSCertificate tbsCert, AlgorithmIdentifier sigAlgId, byte[] signature)
{
ASN1EncodableVector v = new ASN1EncodableVector();
@@ -197,12 +179,12 @@
}
}
- static boolean[] bitStringToBoolean(DERBitString bitString)
+ static boolean[] bitStringToBoolean(ASN1BitString bitString)
{
if (bitString != null)
{
- byte[] bytes = bitString.getBytes();
- boolean[] boolId = new boolean[bytes.length * 8 - bitString.getPadBits()];
+ byte[] bytes = bitString.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - bitString.getPadBits()];
for (int i = 0; i != boolId.length; i++)
{
@@ -234,40 +216,40 @@
return false;
}
- if (Properties.isOverrideSet("org.bouncycastle.x509.allow_absent_equiv_NULL"))
- {
- if (id1.getParameters() == null)
- {
- if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
- {
- return false;
- }
+ if (Properties.isOverrideSet("org.bouncycastle.x509.allow_absent_equiv_NULL"))
+ {
+ if (id1.getParameters() == null)
+ {
+ if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
+ {
+ return false;
+ }
- return true;
- }
+ return true;
+ }
- if (id2.getParameters() == null)
- {
- if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
- {
- return false;
- }
+ if (id2.getParameters() == null)
+ {
+ if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
+ {
+ return false;
+ }
- return true;
- }
- }
+ return true;
+ }
+ }
- if (id1.getParameters() != null)
- {
- return id1.getParameters().equals(id2.getParameters());
- }
+ if (id1.getParameters() != null)
+ {
+ return id1.getParameters().equals(id2.getParameters());
+ }
- if (id2.getParameters() != null)
- {
- return id2.getParameters().equals(id1.getParameters());
- }
+ if (id2.getParameters() != null)
+ {
+ return id2.getParameters().equals(id1.getParameters());
+ }
- return true;
+ return true;
}
static ExtensionsGenerator doReplaceExtension(ExtensionsGenerator extGenerator, Extension ext)
@@ -276,7 +258,7 @@
Extensions exts = extGenerator.generate();
extGenerator = new ExtensionsGenerator();
- for (Enumeration en = exts.oids(); en.hasMoreElements();)
+ for (Enumeration en = exts.oids(); en.hasMoreElements(); )
{
ASN1ObjectIdentifier extOid = (ASN1ObjectIdentifier)en.nextElement();
@@ -299,13 +281,13 @@
return extGenerator;
}
- static ExtensionsGenerator doRemoveExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid)
+ static ExtensionsGenerator doRemoveExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid)
{
boolean isRemoved = false;
Extensions exts = extGenerator.generate();
extGenerator = new ExtensionsGenerator();
- for (Enumeration en = exts.oids(); en.hasMoreElements();)
+ for (Enumeration en = exts.oids(); en.hasMoreElements(); )
{
ASN1ObjectIdentifier extOid = (ASN1ObjectIdentifier)en.nextElement();
@@ -326,4 +308,31 @@
return extGenerator;
}
+
+ private static byte[] generateSig(ContentSigner signer, ASN1Object tbsObj)
+ throws IOException
+ {
+ OutputStream sOut = signer.getOutputStream();
+ tbsObj.encodeTo(sOut, ASN1Encoding.DER);
+ sOut.close();
+
+ return signer.getSignature();
+ }
+
+ static ASN1TaggedObject trimExtensions(int tagNo, Extensions exts)
+ {
+ ASN1Sequence extSeq = ASN1Sequence.getInstance(exts.toASN1Primitive());
+ ASN1EncodableVector extV = new ASN1EncodableVector();
+ for (int i = 0; i != extSeq.size(); i++)
+ {
+ ASN1Sequence ext = ASN1Sequence.getInstance(extSeq.getObjectAt(i));
+
+ if (!Extension.altSignatureValue.equals(ext.getObjectAt(0)))
+ {
+ extV.add(ext);
+ }
+ }
+
+ return new DERTaggedObject(true, tagNo, new DERSequence(extV));
+ }
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/DeltaCertificateTool.java b/bcpkix/src/main/java/org/bouncycastle/cert/DeltaCertificateTool.java
new file mode 100644
index 0000000..f599a52
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/DeltaCertificateTool.java
@@ -0,0 +1,185 @@
+package org.bouncycastle.cert;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1BitString;
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERBitString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.x509.Certificate;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.ExtensionsGenerator;
+
+/**
+ * General tool for handling the extension described in: https://datatracker.ietf.org/doc/draft-bonnell-lamps-chameleon-certs/
+ */
+public class DeltaCertificateTool
+{
+ public static Extension makeDeltaCertificateExtension(boolean isCritical, X509CertificateHolder deltaCert)
+ throws IOException
+ {
+ ASN1EncodableVector deltaV = new ASN1EncodableVector();
+
+ deltaV.add(new ASN1Integer(deltaCert.getSerialNumber()));
+ deltaV.add(new DERTaggedObject(false, 0, deltaCert.getSignatureAlgorithm()));
+ deltaV.add(new DERTaggedObject(false, 1, deltaCert.getIssuer()));
+
+ ASN1EncodableVector validity = new ASN1EncodableVector(2);
+ validity.add(deltaCert.toASN1Structure().getStartDate());
+ validity.add(deltaCert.toASN1Structure().getEndDate());
+
+ deltaV.add(new DERTaggedObject(false, 2, new DERSequence(validity)));
+ deltaV.add(new DERTaggedObject(false, 3, deltaCert.getSubject()));
+ deltaV.add(deltaCert.getSubjectPublicKeyInfo());
+ if (deltaCert.getExtensions() != null)
+ {
+ deltaV.add(new DERTaggedObject(false, 4, deltaCert.getExtensions()));
+ }
+ deltaV.add(new DERBitString(deltaCert.getSignature()));
+
+ return new Extension(Extension.deltaCertificateDescriptor, isCritical, new DERSequence(deltaV).getEncoded(ASN1Encoding.DER));
+ }
+
+ public static X509CertificateHolder extractDeltaCertificate(X509CertificateHolder originCert)
+ {
+ ASN1ObjectIdentifier deltaExtOid = Extension.deltaCertificateDescriptor;
+ Extension deltaExt = originCert.getExtension(deltaExtOid);
+
+ ASN1Sequence seq = ASN1Sequence.getInstance(deltaExt.getParsedValue());
+// * version [ 0 ] Version DEFAULT v1(0),
+// * serialNumber CertificateSerialNumber,
+// * signature AlgorithmIdentifier,
+// * issuer Name,
+// * validity Validity,
+// * subject Name,
+// * subjectPublicKeyInfo SubjectPublicKeyInfo,
+// * issuerUniqueID [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
+// * subjectUniqueID [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
+// * extensions [ 3 ] Extensions OPTIONAL
+ ASN1Sequence originTbs = ASN1Sequence.getInstance(originCert.toASN1Structure().getTBSCertificate().toASN1Primitive());
+ int idx = 0;
+ ASN1Encodable[] extracted = originTbs.toArray();
+
+ extracted[0] = originTbs.getObjectAt(0);
+ extracted[1] = ASN1Integer.getInstance(seq.getObjectAt(idx++));
+
+ ASN1Encodable next = seq.getObjectAt(idx++);
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ extracted[2] = ASN1Sequence.getInstance(tagged, false);
+ break;
+ case 1:
+ extracted[3] = ASN1Sequence.getInstance(tagged, true); // issuer
+ break;
+ case 2:
+ extracted[4] = ASN1Sequence.getInstance(tagged, false);
+ break;
+ case 3:
+ extracted[5] = ASN1Sequence.getInstance((ASN1TaggedObject)next, true); // subject
+ break;
+ }
+ next = seq.getObjectAt(idx++);
+ }
+
+ extracted[6] = next; // subjectPublicKey
+
+ if (extracted[2] == null)
+ {
+ extracted[2] = originTbs.getObjectAt(2);
+ }
+
+ if (extracted[3] == null)
+ {
+ extracted[3] = originTbs.getObjectAt(3);
+ }
+
+ if (extracted[4] == null)
+ {
+ extracted[4] = originTbs.getObjectAt(4);
+ }
+
+ if (extracted[5] == null)
+ {
+ extracted[5] = originTbs.getObjectAt(5);
+ }
+
+ ExtensionsGenerator extGen = extractExtensions(originTbs);
+
+ if (idx < (seq.size() - 1)) // last element is the signature
+ {
+ next = seq.getObjectAt(idx++);
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ if (tagged.getTagNo() != 4)
+ {
+ throw new IllegalArgumentException("malformed delta extension");
+ }
+
+ ASN1Sequence deltaExts = ASN1Sequence.getInstance(tagged, false);
+
+ for (int i = 0; i != deltaExts.size(); i++)
+ {
+ Extension ext = Extension.getInstance(deltaExts.getObjectAt(i));
+
+ extGen.replaceExtension(ext);
+ }
+
+ extracted[7] = new DERTaggedObject(3, extGen.generate());
+ }
+ else
+ {
+ if (!extGen.isEmpty())
+ {
+ extracted[7] = new DERTaggedObject(3, extGen.generate());
+ }
+ else
+ {
+ extracted[7] = null;
+ }
+ }
+
+ ASN1EncodableVector tbsDeltaCertV = new ASN1EncodableVector(7);
+ for (int i = 0; i != extracted.length; i++)
+ {
+ if (extracted[i] != null)
+ {
+ tbsDeltaCertV.add(extracted[i]);
+ }
+ }
+
+ ASN1EncodableVector certV = new ASN1EncodableVector();
+ certV.add(new DERSequence(tbsDeltaCertV));
+ certV.add(ASN1Sequence.getInstance(extracted[2]));
+ certV.add(ASN1BitString.getInstance(seq.getObjectAt(seq.size() - 1)));
+
+ return new X509CertificateHolder(Certificate.getInstance(new DERSequence(certV)));
+ }
+
+ private static ExtensionsGenerator extractExtensions(ASN1Sequence originTbs)
+ {
+ ASN1ObjectIdentifier deltaExtOid = Extension.deltaCertificateDescriptor;
+ ASN1Sequence originExt = ASN1Sequence.getInstance(ASN1TaggedObject.getInstance(originTbs.getObjectAt(originTbs.size() - 1)), true);
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+
+ for (int i = 0; i != originExt.size(); i++)
+ {
+ Extension ext = Extension.getInstance(originExt.getObjectAt(i));
+ if (!deltaExtOid.equals(ext.getExtnId()))
+ {
+ extGen.addExtension(ext);
+ }
+ }
+
+ return extGen;
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
index 93b8645..7651bbe 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
@@ -15,11 +15,18 @@
import java.util.List;
import java.util.Set;
+import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
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.DERSequence;
import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.AltSignatureAlgorithm;
+import org.bouncycastle.asn1.x509.AltSignatureValue;
import org.bouncycastle.asn1.x509.CertificateList;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
@@ -39,7 +46,7 @@
implements Encodable, Serializable
{
private static final long serialVersionUID = 20170722001L;
-
+
private transient CertificateList x509CRL;
private transient boolean isIndirect;
private transient Extensions extensions;
@@ -162,7 +169,7 @@
public X509CRLEntryHolder getRevokedCertificate(BigInteger serialNumber)
{
GeneralNames currentCA = issuerName;
- for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements();)
+ for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements(); )
{
TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)en.nextElement();
@@ -197,7 +204,7 @@
List l = new ArrayList(entries.length);
GeneralNames currentCA = issuerName;
- for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements();)
+ for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements(); )
{
TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)en.nextElement();
X509CRLEntryHolder crlEntry = new X509CRLEntryHolder(entry, isIndirect, currentCA);
@@ -209,7 +216,7 @@
return l;
}
-
+
/**
* Return whether or not the holder's CRL contains extensions.
*
@@ -224,7 +231,6 @@
* Look up the extension associated with the passed in OID.
*
* @param oid the OID of the extension of interest.
- *
* @return the extension if present, null otherwise.
*/
public Extension getExtension(ASN1ObjectIdentifier oid)
@@ -325,6 +331,51 @@
return verifier.verify(x509CRL.getSignature().getOctets());
}
+ public boolean isAlternativeSignatureValid(ContentVerifierProvider verifierProvider)
+ throws CertException
+ {
+ TBSCertList tbsCrList = x509CRL.getTBSCertList();
+ AltSignatureAlgorithm altSigAlg = AltSignatureAlgorithm.fromExtensions(tbsCrList.getExtensions());
+ AltSignatureValue altSigValue = AltSignatureValue.fromExtensions(tbsCrList.getExtensions());
+
+ ContentVerifier verifier;
+
+ try
+ {
+ verifier = verifierProvider.get(AlgorithmIdentifier.getInstance(altSigAlg.toASN1Primitive()));
+
+ OutputStream sOut = verifier.getOutputStream();
+
+ ASN1Sequence tbsSeq = ASN1Sequence.getInstance(tbsCrList.toASN1Primitive());
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ int start = 1; // want to skip signature field
+ if (tbsSeq.getObjectAt(0) instanceof ASN1Integer)
+ {
+ v.add(tbsSeq.getObjectAt(0));
+ start++;
+ }
+
+ for (int i = start; i != tbsSeq.size() - 1; i++)
+ {
+ v.add(tbsSeq.getObjectAt(i));
+ }
+
+ v.add(CertUtils.trimExtensions(0, tbsCrList.getExtensions()));
+
+ new DERSequence(v).encodeTo(sOut, ASN1Encoding.DER);
+
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new CertException("unable to process signature: " + e.getMessage(), e);
+ }
+
+ return verifier.verify(altSigValue.getSignature().getOctets());
+ }
+
+
public boolean equals(
Object o)
{
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
index d78b6a5..bc328fd 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
@@ -10,10 +10,15 @@
import java.util.List;
import java.util.Set;
+import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.AltSignatureAlgorithm;
+import org.bouncycastle.asn1.x509.AltSignatureValue;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
@@ -243,9 +248,9 @@
}
/**
- * Return the bytes making up the signature associated with this attribute certificate.
+ * Return the bytes making up the signature associated with this certificate.
*
- * @return the attribute certificate signature bytes.
+ * @return the certificate signature bytes.
*/
public byte[] getSignature()
{
@@ -298,6 +303,53 @@
return verifier.verify(this.getSignature());
}
+ /**
+ * Validate the signature on the certificate in this holder.
+ *
+ * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature.
+ * @return true if the signature is valid, false otherwise.
+ * @throws CertException if the signature cannot be processed or is inappropriate.
+ */
+ public boolean isAlternativeSignatureValid(ContentVerifierProvider verifierProvider)
+ throws CertException
+ {
+ TBSCertificate tbsCert = x509Certificate.getTBSCertificate();
+ AltSignatureAlgorithm altSigAlg = AltSignatureAlgorithm.fromExtensions(tbsCert.getExtensions());
+ AltSignatureValue altSigValue = AltSignatureValue.fromExtensions(tbsCert.getExtensions());
+
+ ContentVerifier verifier;
+
+ try
+ {
+ verifier = verifierProvider.get(AlgorithmIdentifier.getInstance(altSigAlg.toASN1Primitive()));
+
+ OutputStream sOut = verifier.getOutputStream();
+
+ ASN1Sequence tbsSeq = ASN1Sequence.getInstance(tbsCert.toASN1Primitive());
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != tbsSeq.size() - 1; i++)
+ {
+ if (i != 2) // signature field - must be ver 3 so version always present
+ {
+ v.add(tbsSeq.getObjectAt(i));
+ }
+ }
+
+ v.add(CertUtils.trimExtensions(3, tbsCert.getExtensions()));
+
+ new DERSequence(v).encodeTo(sOut, ASN1Encoding.DER);
+
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new CertException("unable to process signature: " + e.getMessage(), e);
+ }
+
+ return verifier.verify(altSigValue.getSignature().getOctets());
+ }
+
public boolean equals(
Object o)
{
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java
index 3562cbf..403f561 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java
@@ -14,10 +14,12 @@
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERBitString;
+import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.Certificate;
+import org.bouncycastle.asn1.x509.DeltaCertificateDescriptor;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
@@ -26,6 +28,7 @@
import org.bouncycastle.asn1.x509.Time;
import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.util.Exceptions;
/**
@@ -112,7 +115,16 @@
for (Enumeration en = exts.oids(); en.hasMoreElements();)
{
- extGenerator.addExtension(exts.getExtension((ASN1ObjectIdentifier)en.nextElement()));
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)en.nextElement();
+ // we remove the altSignatureAlgorithm, altSignatureValue, and subjectAltPublicKeyInfo
+ // extensions as they probably need to be regenerated.
+ if (Extension.subjectAltPublicKeyInfo.equals(oid)
+ || Extension.altSignatureAlgorithm.equals(oid)
+ || Extension.altSignatureValue.equals(oid))
+ {
+ continue;
+ }
+ extGenerator.addExtension(exts.getExtension(oid));
}
}
@@ -140,6 +152,11 @@
private Extension doGetExtension(ASN1ObjectIdentifier oid)
{
+ if (extGenerator.isEmpty())
+ {
+ return null;
+ }
+
Extensions exts = extGenerator.generate();
return exts.getExtension(oid);
@@ -363,6 +380,21 @@
if (!extGenerator.isEmpty())
{
+ if (extGenerator.hasExtension(Extension.deltaCertificateDescriptor))
+ {
+ Extension deltaExt = extGenerator.getExtension(Extension.deltaCertificateDescriptor);
+ DeltaCertificateDescriptor deltaDesc = DeltaCertificateDescriptor.getInstance(deltaExt.getParsedValue());
+
+ try
+ {
+ extGenerator.replaceExtension(Extension.deltaCertificateDescriptor, deltaExt.isCritical(),
+ deltaDesc.trimTo(tbsGen.generateTBSCertificate(), extGenerator.generate()));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to replace deltaCertificateDescriptor: " + e.getMessage()) ;
+ }
+ }
tbsGen.setExtensions(extGenerator.generate());
}
@@ -373,7 +405,75 @@
}
catch (IOException e)
{
- throw new IllegalArgumentException("cannot produce certificate signature");
+ throw Exceptions.illegalArgumentException("cannot produce certificate signature", e);
+ }
+ }
+
+ /**
+ * Generate an X.509 certificate, based on the current issuer and subject
+ * using the passed in signer and containing altSignatureAlgorithm and altSignatureValue extensions
+ * based on the passed altSigner.
+ *
+ * @param signer the content signer to be used to generate the signature validating the certificate.
+ * @param altSigner the content signer used to create the altSignatureAlgorithm and altSignatureValue extension.
+ * @return a holder containing the resulting signed certificate.
+ */
+ public X509CertificateHolder build(
+ ContentSigner signer,
+ boolean isCritical,
+ ContentSigner altSigner)
+ {
+ try
+ {
+ extGenerator.addExtension(Extension.altSignatureAlgorithm, isCritical, altSigner.getAlgorithmIdentifier());
+ }
+ catch (IOException e)
+ {
+ throw Exceptions.illegalStateException("cannot add altSignatureAlgorithm extension", e);
+ }
+
+ if (extGenerator.hasExtension(Extension.deltaCertificateDescriptor))
+ {
+ tbsGen.setSignature(signer.getAlgorithmIdentifier());
+
+ Extension deltaExt = extGenerator.getExtension(Extension.deltaCertificateDescriptor);
+ DeltaCertificateDescriptor deltaDesc = DeltaCertificateDescriptor.getInstance(deltaExt.getParsedValue());
+
+ try
+ {
+ // the altSignatureValue is not present yet, but it must be in the deltaCertificate and
+ // it must be different (by definition!). We add a dummy one to trigger inclusion.
+ ExtensionsGenerator tmpExtGen = new ExtensionsGenerator();
+ tmpExtGen.addExtension(extGenerator.generate());
+ tmpExtGen.addExtension(Extension.altSignatureValue, false, DERNull.INSTANCE);
+
+ extGenerator.replaceExtension(Extension.deltaCertificateDescriptor, deltaExt.isCritical(),
+ deltaDesc.trimTo(tbsGen.generateTBSCertificate(), tmpExtGen.generate()));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to replace deltaCertificateDescriptor: " + e.getMessage());
+ }
+ }
+
+ tbsGen.setSignature(null);
+
+ tbsGen.setExtensions(extGenerator.generate());
+
+ try
+ {
+ extGenerator.addExtension(Extension.altSignatureValue, isCritical, new DERBitString(generateSig(altSigner, tbsGen.generatePreTBSCertificate())));
+
+ tbsGen.setSignature(signer.getAlgorithmIdentifier());
+
+ tbsGen.setExtensions(extGenerator.generate());
+
+ TBSCertificate tbsCert = tbsGen.generateTBSCertificate();
+ return new X509CertificateHolder(generateStructure(tbsCert, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCert)));
+ }
+ catch (IOException e)
+ {
+ throw Exceptions.illegalArgumentException("cannot produce certificate signature", e);
}
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java
index 5695907..76b8df6 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java
@@ -35,7 +35,7 @@
private Extensions responseExtensions = null;
private RespID responderID;
- private class ResponseObject
+ private static class ResponseObject
{
CertificateID certId;
CertStatus certStatus;
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java
index 3f3c954..389952c 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java
@@ -26,7 +26,7 @@
private GeneralName requestorName = null;
private Extensions requestExtensions = null;
- private class RequestObject
+ private static class RequestObject
{
CertificateID certId;
Extensions extensions;
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RevokedStatus.java b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RevokedStatus.java
index d349f07..7124f38 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RevokedStatus.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RevokedStatus.java
@@ -19,7 +19,12 @@
{
this.info = info;
}
-
+
+ public RevokedStatus(Date revocationDate)
+ {
+ this.info = new RevokedInfo(new ASN1GeneralizedTime(revocationDate));
+ }
+
public RevokedStatus(
Date revocationDate,
int reason)
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSPatchKit.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSPatchKit.java
new file mode 100644
index 0000000..1237988
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSPatchKit.java
@@ -0,0 +1,71 @@
+package org.bouncycastle.cms;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.cms.SignerInfo;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * Toolkit methods for dealing with common errors in CMS
+ * classes.
+ */
+public class CMSPatchKit
+{
+ /**
+ * Create a SignerInformation based on original which uses definite-length
+ * rather than DER encoding for verifying the signature on the signed attributes.
+ *
+ * @param original the source SignerInformation
+ */
+ public static SignerInformation createNonDERSignerInfo(
+ SignerInformation original)
+ {
+ return new DLSignerInformation(original);
+ }
+
+ /**
+ * Create a SignerInformation based on original has it's signatureAlgorithm replaced
+ * with the passed in AlgorithmIdentifier.
+ *
+ * @param original the source SignerInformation
+ */
+ public static SignerInformation createWithSignatureAlgorithm(
+ SignerInformation original,
+ AlgorithmIdentifier signatureAlgorithm)
+ {
+ return new ModEncAlgSignerInformation(original, signatureAlgorithm);
+ }
+
+ private static class DLSignerInformation
+ extends SignerInformation
+ {
+ protected DLSignerInformation(SignerInformation baseInfo)
+ {
+ super(baseInfo);
+ }
+
+ public byte[] getEncodedSignedAttributes()
+ throws IOException
+ {
+ return signedAttributeSet.getEncoded(ASN1Encoding.DL);
+ }
+ }
+
+ private static class ModEncAlgSignerInformation
+ extends SignerInformation
+ {
+ protected ModEncAlgSignerInformation(
+ SignerInformation baseInfo,
+ AlgorithmIdentifier signatureAlgorithm)
+ {
+ super(baseInfo, editEncAlg(baseInfo.info, signatureAlgorithm));
+ }
+
+ private static SignerInfo editEncAlg(SignerInfo info, AlgorithmIdentifier signatureAlgorithm)
+ {
+ return new SignerInfo(info.getSID(), info.getDigestAlgorithm(), info.getAuthenticatedAttributes(),
+ signatureAlgorithm, info.getEncryptedDigest(), info.getUnauthenticatedAttributes());
+ }
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
index 3110fa6..ef1e3d6 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
@@ -21,7 +21,6 @@
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.BERSequence;
-import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.DLSet;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.cms.SignedData;
@@ -30,15 +29,17 @@
import org.bouncycastle.cert.X509AttributeCertificateHolder;
import org.bouncycastle.cert.X509CRLHolder;
import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.util.Encodable;
import org.bouncycastle.util.Store;
/**
* general class for handling a pkcs7-signature message.
- *
+ * <p>
* A simple example of usage - note, in the example below the validity of
- * the certificate isn't verified, just the fact that one of the certs
+ * the certificate isn't verified, just the fact that one of the certs
* matches the given signer...
*
* <pre>
@@ -46,7 +47,7 @@
* SignerInformationStore signers = s.getSignerInfos();
* Collection c = signers.getSigners();
* Iterator it = c.iterator();
- *
+ *
* while (it.hasNext())
* {
* SignerInformation signer = (SignerInformation)it.next();
@@ -54,11 +55,11 @@
*
* Iterator certIt = certCollection.iterator();
* X509CertificateHolder cert = (X509CertificateHolder)certIt.next();
- *
+ *
* if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)))
* {
* verified++;
- * }
+ * }
* }
* </pre>
*/
@@ -66,16 +67,18 @@
implements Encodable
{
private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE;
-
- SignedData signedData;
- ContentInfo contentInfo;
- CMSTypedData signedContent;
- SignerInformationStore signerInfoStore;
+ private static final DefaultDigestAlgorithmIdentifierFinder DIGEST_ALG_ID_FINDER =
+ new DefaultDigestAlgorithmIdentifierFinder();
- private Map hashes;
+ SignedData signedData;
+ ContentInfo contentInfo;
+ CMSTypedData signedContent;
+ SignerInformationStore signerInfoStore;
+
+ private Map hashes;
private CMSSignedData(
- CMSSignedData c)
+ CMSSignedData c)
{
this.signedData = c.signedData;
this.contentInfo = c.contentInfo;
@@ -84,15 +87,15 @@
}
public CMSSignedData(
- byte[] sigBlock)
+ byte[] sigBlock)
throws CMSException
{
this(CMSUtils.readContentInfo(sigBlock));
}
public CMSSignedData(
- CMSProcessable signedContent,
- byte[] sigBlock)
+ CMSProcessable signedContent,
+ byte[] sigBlock)
throws CMSException
{
this(signedContent, CMSUtils.readContentInfo(sigBlock));
@@ -101,12 +104,12 @@
/**
* Content with detached signature, digests precomputed
*
- * @param hashes a map of precomputed digests for content indexed by name of hash.
+ * @param hashes a map of precomputed digests for content indexed by name of hash.
* @param sigBlock the signature object.
*/
public CMSSignedData(
- Map hashes,
- byte[] sigBlock)
+ Map hashes,
+ byte[] sigBlock)
throws CMSException
{
this(hashes, CMSUtils.readContentInfo(sigBlock));
@@ -116,11 +119,11 @@
* base constructor - content with detached signature.
*
* @param signedContent the content that was signed.
- * @param sigData the signature object.
+ * @param sigData the signature object.
*/
public CMSSignedData(
- CMSProcessable signedContent,
- InputStream sigData)
+ CMSProcessable signedContent,
+ InputStream sigData)
throws CMSException
{
this(signedContent, CMSUtils.readContentInfo(new ASN1InputStream(sigData)));
@@ -137,8 +140,8 @@
}
public CMSSignedData(
- final CMSProcessable signedContent,
- ContentInfo sigData)
+ final CMSProcessable signedContent,
+ ContentInfo sigData)
throws CMSException
{
if (signedContent instanceof CMSTypedData)
@@ -172,8 +175,8 @@
}
public CMSSignedData(
- Map hashes,
- ContentInfo sigData)
+ Map hashes,
+ ContentInfo sigData)
throws CMSException
{
this.hashes = hashes;
@@ -244,8 +247,8 @@
{
if (signerInfoStore == null)
{
- ASN1Set s = signedData.getSignerInfos();
- List signerInfos = new ArrayList();
+ ASN1Set s = signedData.getSignerInfos();
+ List signerInfos = new ArrayList();
for (int i = 0; i != s.size(); i++)
{
@@ -328,7 +331,6 @@
* this SignedData structure.
*
* @param otherRevocationInfoFormat OID of the format type been looked for.
- *
* @return a Store of ASN1Encodable objects representing any objects of otherRevocationInfoFormat found.
*
public Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat)
@@ -345,9 +347,9 @@
*/
public Set<AlgorithmIdentifier> getDigestAlgorithmIDs()
{
- Set<AlgorithmIdentifier> digests = new HashSet<AlgorithmIdentifier>(signedData.getDigestAlgorithms().size());
+ Set<AlgorithmIdentifier> digests = new HashSet<AlgorithmIdentifier>();
- for (Enumeration en = signedData.getDigestAlgorithms().getObjects(); en.hasMoreElements();)
+ for (Enumeration en = signedData.getDigestAlgorithms().getObjects(); en.hasMoreElements(); )
{
digests.add(AlgorithmIdentifier.getInstance(en.nextElement()));
}
@@ -358,14 +360,14 @@
/**
* Return the a string representation of the OID associated with the
* encapsulated content info structure carried in the signed data.
- *
+ *
* @return the OID for the content type.
*/
public String getSignedContentTypeOID()
{
return signedData.getEncapContentInfo().getContentType().getId();
}
-
+
public CMSTypedData getSignedContent()
{
return signedContent;
@@ -394,7 +396,18 @@
* return the ASN.1 encoded representation of this object using the specified encoding.
*
* @param encoding the ASN.1 encoding format to use ("BER", "DL", or "DER").
- */
+ *
+ public byte[] getEncoded(String encoding)
+ throws IOException
+ {
+ return contentInfo.getEncoded(encoding);
+ }
+
+ /**
+ * return the ASN.1 encoded representation of this object using the specified encoding.
+ *
+ * @param encoding the ASN.1 encoding format to use ("BER", "DL", or "DER").
+ *
public byte[] getEncoded(String encoding)
throws IOException
{
@@ -405,9 +418,9 @@
* Verify all the SignerInformation objects and their associated counter signatures attached
* to this CMS SignedData object.
*
- * @param verifierProvider a provider of SignerInformationVerifier objects.
+ * @param verifierProvider a provider of SignerInformationVerifier objects.
* @return true if all verify, false otherwise.
- * @throws CMSException if an exception occurs during the verification process.
+ * @throws CMSException if an exception occurs during the verification process.
*
public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider)
throws CMSException
@@ -419,17 +432,17 @@
* Verify all the SignerInformation objects and optionally their associated counter signatures attached
* to this CMS SignedData object.
*
- * @param verifierProvider a provider of SignerInformationVerifier objects.
+ * @param verifierProvider a provider of SignerInformationVerifier objects.
* @param ignoreCounterSignatures if true don't check counter signatures. If false check counter signatures as well.
* @return true if all verify, false otherwise.
- * @throws CMSException if an exception occurs during the verification process.
+ * @throws CMSException if an exception occurs during the verification process.
*
public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider, boolean ignoreCounterSignatures)
throws CMSException
{
Collection signers = this.getSignerInfos().getSigners();
- for (Iterator it = signers.iterator(); it.hasNext();)
+ for (Iterator it = signers.iterator(); it.hasNext(); )
{
SignerInformation signer = (SignerInformation)it.next();
@@ -446,7 +459,7 @@
{
Collection counterSigners = signer.getCounterSignatures().getSigners();
- for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();)
+ for (Iterator cIt = counterSigners.iterator(); cIt.hasNext(); )
{
if (!verifyCounterSignature((SignerInformation)cIt.next(), verifierProvider))
{
@@ -475,7 +488,7 @@
}
Collection counterSigners = counterSigner.getCounterSignatures().getSigners();
- for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();)
+ for (Iterator cIt = counterSigners.iterator(); cIt.hasNext(); )
{
if (!verifyCounterSignature((SignerInformation)cIt.next(), verifierProvider))
{
@@ -489,24 +502,119 @@
// END Android-removed: Unknown reason
/**
+ * Return a new CMSSignedData which guarantees to have the passed in digestAlgorithm
+ * in it. Uses the current DigestAlgorithmIdentifierFinder for creating the digest sets.
+ *
+ * @param signedData the signed data object to be used as a base.
+ * @param digestAlgorithm the digest algorithm to be added to the signed data.
+ * @return a new signed data object.
+ */
+ public static CMSSignedData addDigestAlgorithm(CMSSignedData signedData, AlgorithmIdentifier digestAlgorithm)
+ {
+ return addDigestAlgorithm(signedData, digestAlgorithm, DIGEST_ALG_ID_FINDER);
+ }
+
+ /**
+ * Return a new CMSSignedData which guarantees to have the passed in digestAlgorithm
+ * in it. Uses the passed in DigestAlgorithmIdentifierFinder for creating the digest sets.
+ *
+ * @param signedData the signed data object to be used as a base.
+ * @param digestAlgorithm the digest algorithm to be added to the signed data.
+ * @param digestAlgIdFinder the digest algorithmID map to generate the digest set with.
+ * @return a new signed data object.
+ */
+ public static CMSSignedData addDigestAlgorithm(CMSSignedData signedData, AlgorithmIdentifier digestAlgorithm,
+ DigestAlgorithmIdentifierFinder digestAlgIdFinder)
+ {
+ Set<AlgorithmIdentifier> digestAlgorithms = signedData.getDigestAlgorithmIDs();
+ AlgorithmIdentifier digestAlg = HELPER.fixDigestAlgID(digestAlgorithm, digestAlgIdFinder);
+
+ //
+ // if the algorithm is already present there is no need to add it.
+ //
+ if (digestAlgorithms.contains(digestAlg))
+ {
+ return signedData;
+ }
+
+ //
+ // copy
+ //
+ CMSSignedData cms = new CMSSignedData(signedData);
+
+ //
+ // build up the new set
+ //
+ Set<AlgorithmIdentifier> digestAlgs = new HashSet<AlgorithmIdentifier>();
+
+ Iterator it = digestAlgorithms.iterator();
+ while (it.hasNext())
+ {
+ digestAlgs.add(HELPER.fixDigestAlgID((AlgorithmIdentifier)it.next(), digestAlgIdFinder));
+ }
+ digestAlgs.add(digestAlg);
+
+ ASN1Set digestSet = CMSUtils.convertToDlSet(digestAlgs);
+ ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive();
+
+ //
+ // signers are the last item in the sequence.
+ //
+ ASN1EncodableVector vec = new ASN1EncodableVector(sD.size());
+ vec.add(sD.getObjectAt(0)); // version
+ vec.add(digestSet);
+
+ for (int i = 2; i != sD.size(); i++)
+ {
+ vec.add(sD.getObjectAt(i));
+ }
+
+ cms.signedData = SignedData.getInstance(new BERSequence(vec));
+
+ //
+ // replace the contentInfo with the new one
+ //
+ cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData);
+
+ return cms;
+ }
+
+ /**
* Replace the SignerInformation store associated with this
- * CMSSignedData object with the new one passed in. You would
- * probably only want to do this if you wanted to change the unsigned
+ * CMSSignedData object with the new one passed in using the current
+ * DigestAlgorithmIdentifierFinder for creating the digest sets. You would
+ * probably only want to do this if you wanted to change the unsigned
* attributes associated with a signer, or perhaps delete one.
- *
- * @param signedData the signed data object to be used as a base.
+ *
+ * @param signedData the signed data object to be used as a base.
* @param signerInformationStore the new signer information store to use.
* @return a new signed data object.
*/
- public static CMSSignedData replaceSigners(
- CMSSignedData signedData,
- SignerInformationStore signerInformationStore)
+ public static CMSSignedData replaceSigners(CMSSignedData signedData, SignerInformationStore signerInformationStore)
+ {
+ return replaceSigners(signedData, signerInformationStore, DIGEST_ALG_ID_FINDER);
+ }
+
+ /**
+ * Replace the SignerInformation store associated with this
+ * CMSSignedData object with the new one passed in using the passed in
+ * DigestAlgorithmIdentifierFinder for creating the digest sets. You would
+ * probably only want to do this if you wanted to change the unsigned
+ * attributes associated with a signer, or perhaps delete one.
+ *
+ * @param signedData the signed data object to be used as a base.
+ * @param signerInformationStore the new signer information store to use.
+ * @param digestAlgIdFinder the digest algorithmID map to generate the digest set with.
+ * @return a new signed data object.
+ */
+ public static CMSSignedData replaceSigners(CMSSignedData signedData, SignerInformationStore signerInformationStore,
+ DigestAlgorithmIdentifierFinder digestAlgIdFinder)
{
//
// copy
//
- CMSSignedData cms = new CMSSignedData(signedData);
-
+ CMSSignedData cms = new CMSSignedData(signedData);
+
//
// replace the store
//
@@ -515,43 +623,44 @@
//
// replace the signers in the SignedData object
//
- ASN1EncodableVector digestAlgs = new ASN1EncodableVector();
- ASN1EncodableVector vec = new ASN1EncodableVector();
-
- Iterator it = signerInformationStore.getSigners().iterator();
+ Set<AlgorithmIdentifier> digestAlgs = new HashSet<AlgorithmIdentifier>();
+
+ Collection<SignerInformation> signers = signerInformationStore.getSigners();
+ ASN1EncodableVector vec = new ASN1EncodableVector(signers.size());
+
+ Iterator it = signers.iterator();
while (it.hasNext())
{
SignerInformation signer = (SignerInformation)it.next();
- digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID()));
+ CMSUtils.addDigestAlgs(digestAlgs, signer, digestAlgIdFinder);
vec.add(signer.toASN1Structure());
}
- ASN1Set digests = new DERSet(digestAlgs);
- ASN1Set signers = new DLSet(vec);
- ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive();
+ ASN1Set digestSet = CMSUtils.convertToDlSet(digestAlgs);
+ ASN1Set signerSet = new DLSet(vec);
+ ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive();
- vec = new ASN1EncodableVector();
-
//
// signers are the last item in the sequence.
//
+ vec = new ASN1EncodableVector(sD.size());
vec.add(sD.getObjectAt(0)); // version
- vec.add(digests);
+ vec.add(digestSet);
for (int i = 2; i != sD.size() - 1; i++)
{
vec.add(sD.getObjectAt(i));
}
-
- vec.add(signers);
-
+
+ vec.add(signerSet);
+
cms.signedData = SignedData.getInstance(new BERSequence(vec));
-
+
//
// replace the contentInfo with the new one
//
cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData);
-
+
return cms;
}
@@ -559,24 +668,24 @@
* Replace the certificate and CRL information associated with this
* CMSSignedData object with the new one passed in.
*
- * @param signedData the signed data object to be used as a base.
+ * @param signedData the signed data object to be used as a base.
* @param certificates the new certificates to be used.
- * @param attrCerts the new attribute certificates to be used.
- * @param revocations the new CRLs to be used - a collection of X509CRLHolder objects, OtherRevocationInfoFormat, or both.
+ * @param attrCerts the new attribute certificates to be used.
+ * @param revocations the new CRLs to be used - a collection of X509CRLHolder objects, OtherRevocationInfoFormat, or both.
* @return a new signed data object.
- * @exception CMSException if there is an error processing the CertStore
+ * @throws CMSException if there is an error processing the CertStore
*/
public static CMSSignedData replaceCertificatesAndCRLs(
- CMSSignedData signedData,
- Store certificates,
- Store attrCerts,
- Store revocations)
+ CMSSignedData signedData,
+ Store certificates,
+ Store attrCerts,
+ Store revocations)
throws CMSException
{
//
// copy
//
- CMSSignedData cms = new CMSSignedData(signedData);
+ CMSSignedData cms = new CMSSignedData(signedData);
//
// replace the certs and revocations in the SignedData object
@@ -594,7 +703,7 @@
}
if (attrCerts != null)
{
- certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts));
+ certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts));
}
ASN1Set set = CMSUtils.createBerSetFromList(certs);
@@ -619,10 +728,10 @@
// replace the CMS structure.
//
cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(),
- signedData.signedData.getEncapContentInfo(),
- certSet,
- crlSet,
- signedData.signedData.getSignerInfos());
+ signedData.signedData.getEncapContentInfo(),
+ certSet,
+ crlSet,
+ signedData.signedData.getSignerInfos());
//
// replace the contentInfo with the new one
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java
index 5417ce4..ab63c1d 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java
@@ -5,18 +5,23 @@
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Set;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.BEROctetString;
+import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.cms.SignedData;
import org.bouncycastle.asn1.cms.SignerInfo;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
/**
* general class for generating a pkcs7-signature message.
@@ -48,6 +53,7 @@
extends CMSSignedGenerator
{
private List signerInfs = new ArrayList();
+ private boolean isDefiniteLength = false;
/**
* base constructor
@@ -57,6 +63,24 @@
}
/**
+ * base constructor with a custom DigestAlgorithmIdentifierFinder
+ */
+ public CMSSignedDataGenerator(DigestAlgorithmIdentifierFinder digestAlgIdFinder)
+ {
+ super(digestAlgIdFinder);
+ }
+
+ /**
+ * Specify use of definite length rather than indefinite length encoding.
+ *
+ * @param isDefiniteLength true use definite length, false use indefinite (default false).
+ */
+ public void setDefiniteLengthEncoding(boolean isDefiniteLength)
+ {
+ this.isDefiniteLength = isDefiniteLength;
+ }
+
+ /**
* Generate a CMS Signed Data object carrying a detached CMS signature.
*
* @param content the content to be signed.
@@ -116,7 +140,7 @@
// // TODO signedAttrs must be present for all signers
// }
- ASN1EncodableVector digestAlgs = new ASN1EncodableVector();
+ Set<AlgorithmIdentifier> digestAlgs = new LinkedHashSet<AlgorithmIdentifier>();
ASN1EncodableVector signerInfos = new ASN1EncodableVector();
digests.clear(); // clear the current preserved digest state
@@ -127,8 +151,7 @@
for (Iterator it = _signers.iterator(); it.hasNext();)
{
SignerInformation signer = (SignerInformation)it.next();
- digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID()));
-
+ CMSUtils.addDigestAlgs(digestAlgs, signer, digestAlgIdFinder);
// TODO Verify the content type and calculated digest match the precalculated SignerInfo
signerInfos.add(signer.toASN1Structure());
}
@@ -167,7 +190,14 @@
if (encapsulate)
{
- octs = new BEROctetString(bOut.toByteArray());
+ if (isDefiniteLength)
+ {
+ octs = new DEROctetString(bOut.toByteArray());
+ }
+ else
+ {
+ octs = new BEROctetString(bOut.toByteArray());
+ }
}
}
@@ -191,20 +221,34 @@
if (certs.size() != 0)
{
- certificates = CMSUtils.createBerSetFromList(certs);
+ if (isDefiniteLength)
+ {
+ certificates = CMSUtils.createDlSetFromList(certs);
+ }
+ else
+ {
+ certificates = CMSUtils.createBerSetFromList(certs);
+ }
}
ASN1Set certrevlist = null;
if (crls.size() != 0)
{
- certrevlist = CMSUtils.createBerSetFromList(crls);
+ if (isDefiniteLength)
+ {
+ certrevlist = CMSUtils.createDlSetFromList(crls);
+ }
+ else
+ {
+ certrevlist = CMSUtils.createBerSetFromList(crls);
+ }
}
ContentInfo encInfo = new ContentInfo(contentTypeOID, octs);
SignedData sd = new SignedData(
- new DERSet(digestAlgs),
+ CMSUtils.convertToDlSet(digestAlgs),
encInfo,
certificates,
certrevlist,
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java
index 995de4f..79d776e 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java
@@ -11,8 +11,8 @@
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERTaggedObject;
-import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
// import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
@@ -26,6 +26,8 @@
import org.bouncycastle.cert.X509AttributeCertificateHolder;
import org.bouncycastle.cert.X509CRLHolder;
import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Store;
@@ -34,7 +36,6 @@
/**
* Default type for the signed data.
*/
- public static final String DATA = CMSObjectIdentifiers.data.getId();
public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId();
public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId();
@@ -43,6 +44,7 @@
public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId();
public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId();
// BEGIN Android-removed: Unsupported algorithms
+ // public static final String DATA = CMSObjectIdentifiers.data.getId();
// public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId();
// public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId();
// public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId();
@@ -92,11 +94,19 @@
protected List signerGens = new ArrayList();
protected Map digests = new HashMap();
+ protected DigestAlgorithmIdentifierFinder digestAlgIdFinder;
+
/**
* base constructor
*/
protected CMSSignedGenerator()
{
+ this(new DefaultDigestAlgorithmIdentifierFinder());
+ }
+
+ protected CMSSignedGenerator(DigestAlgorithmIdentifierFinder digestAlgIdFinder)
+ {
+ this.digestAlgIdFinder = digestAlgIdFinder;
}
protected Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
@@ -195,7 +205,9 @@
ASN1ObjectIdentifier otherRevocationInfoFormat,
ASN1Encodable otherRevocationInfo)
{
- crls.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, otherRevocationInfo)));
+ OtherRevocationInfoFormat infoFormat = new OtherRevocationInfoFormat(otherRevocationInfoFormat, otherRevocationInfo);
+ CMSUtils.validateInfoFormat(infoFormat);
+ crls.add(new DERTaggedObject(false, 1, infoFormat));
}
/**
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java
index e71d796..0d43ecd 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java
@@ -12,11 +12,12 @@
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.BERTags;
import org.bouncycastle.asn1.DERNull;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
-import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
+// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -31,6 +32,7 @@
import org.bouncycastle.cert.X509AttributeCertificateHolder;
import org.bouncycastle.cert.X509CRLHolder;
import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import org.bouncycastle.util.CollectionStore;
import org.bouncycastle.util.Store;
@@ -99,9 +101,6 @@
addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_256, "ECDSA");
addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_384, "ECDSA");
addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_512, "ECDSA");
- */
- // END Android-removed: Unsupported algorithms
- addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "DSA");
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "ECDSA");
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "ECDSA");
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "ECDSA");
@@ -111,6 +110,9 @@
addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "RSA");
addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "RSAandMGF1");
addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "RSAandMGF1");
+ */
+ // END Android-removed: Unsupported algorithms
+ addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "DSA");
addEntries(X9ObjectIdentifiers.id_dsa, "DSA");
addEntries(PKCSObjectIdentifiers.rsaEncryption, "RSA");
@@ -152,14 +154,17 @@
return encryptionAlgOID;
}
- AlgorithmIdentifier fixAlgID(AlgorithmIdentifier algId)
+ AlgorithmIdentifier fixDigestAlgID(AlgorithmIdentifier algId, DigestAlgorithmIdentifierFinder dgstAlgFinder)
{
- if (algId.getParameters() == null)
+ ASN1Encodable params = algId.getParameters();
+ if (params == null || DERNull.INSTANCE.equals(params))
{
- return new AlgorithmIdentifier(algId.getAlgorithm(), DERNull.INSTANCE);
+ return dgstAlgFinder.find(algId.getAlgorithm());
}
-
- return algId;
+ else
+ {
+ return algId;
+ }
}
void setSigningEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName)
@@ -201,7 +206,18 @@
if (obj instanceof ASN1TaggedObject)
{
- certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(((ASN1TaggedObject)obj).getObject())));
+ ASN1TaggedObject tObj = (ASN1TaggedObject)obj;
+
+ // CertificateChoices ::= CHOICE {
+ // certificate Certificate,
+ // extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete
+ // v1AttrCert [1] IMPLICIT AttributeCertificateV1, -- Obsolete
+ // v2AttrCert [2] IMPLICIT AttributeCertificateV2,
+ // other [3] IMPLICIT OtherCertificateFormat }
+ if (tObj.getTagNo() == 1 || tObj.getTagNo() == 2)
+ {
+ certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(tObj.getBaseUniversal(false, BERTags.SEQUENCE))));
+ }
}
}
@@ -249,7 +265,7 @@
{
ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(obj);
- if (tObj.getTagNo() == 1)
+ if (tObj.hasContextTag(1))
{
OtherRevocationInfoFormat other = OtherRevocationInfoFormat.getInstance(tObj, false);
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
index 2d38b53..46006d6 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
@@ -21,6 +21,7 @@
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.DLSet;
import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
import org.bouncycastle.asn1.cms.ContentInfo;
// Android-removed: Unsupported algorithms
@@ -37,6 +38,7 @@
import org.bouncycastle.cert.X509AttributeCertificateHolder;
import org.bouncycastle.cert.X509CRLHolder;
import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.Strings;
@@ -59,7 +61,6 @@
/*
des.add(OIWObjectIdentifiers.desCBC.getId());
des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId());
- des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId());
des.add(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId());
mqvAlgs.add(X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme);
@@ -155,6 +156,23 @@
return readContentInfo(new ASN1InputStream(input));
}
+ static ASN1Set convertToDlSet(Set<AlgorithmIdentifier> digestAlgs)
+ {
+ return new DLSet((AlgorithmIdentifier[])digestAlgs.toArray(new AlgorithmIdentifier[digestAlgs.size()]));
+ }
+
+ static void addDigestAlgs(Set<AlgorithmIdentifier> digestAlgs, SignerInformation signer, DigestAlgorithmIdentifierFinder dgstAlgFinder)
+ {
+ digestAlgs.add(CMSSignedHelper.INSTANCE.fixDigestAlgID(signer.getDigestAlgorithmID(), dgstAlgFinder));
+ SignerInformationStore counterSignaturesStore = signer.getCounterSignatures();
+ Iterator<SignerInformation> counterSignatureIt = counterSignaturesStore.iterator();
+ while (counterSignatureIt.hasNext())
+ {
+ SignerInformation counterSigner = (SignerInformation)counterSignatureIt.next();
+ digestAlgs.add(CMSSignedHelper.INSTANCE.fixDigestAlgID(counterSigner.getDigestAlgorithmID(), dgstAlgFinder));
+ }
+ }
+
static List getCertificatesFromStore(Store certStore)
throws CMSException
{
@@ -243,7 +261,7 @@
// BEGIN Android-removed: OtherRevocationInfoFormat isn't supported
/*
- private static void validateInfoFormat(OtherRevocationInfoFormat infoFormat)
+ static void validateInfoFormat(OtherRevocationInfoFormat infoFormat)
{
if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(infoFormat.getInfoFormat()))
{
@@ -287,6 +305,18 @@
return new BERSet(v);
}
+ static ASN1Set createDlSetFromList(List derObjects)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (Iterator it = derObjects.iterator(); it.hasNext(); )
+ {
+ v.add((ASN1Encodable)it.next());
+ }
+
+ return new DLSet(v);
+ }
+
static ASN1Set createDerSetFromList(List derObjects)
{
ASN1EncodableVector v = new ASN1EncodableVector();
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
index f2e1377..2ef8476 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
@@ -5,11 +5,14 @@
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
-import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
+// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -24,6 +27,7 @@
{
private final Map encryptionAlgs = new HashMap();
private final Map digestAlgs = new HashMap();
+ private final Map simpleAlgs = new HashMap();
private void addEntries(ASN1ObjectIdentifier alias, String digest, String encryption)
{
@@ -70,12 +74,22 @@
addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256", "RSA");
addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384", "RSA");
addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512", "RSA");
+ addEntries(PKCSObjectIdentifiers.sha512_224WithRSAEncryption, "SHA512(224)", "RSA");
+ addEntries(PKCSObjectIdentifiers.sha512_256WithRSAEncryption, "SHA512(256)", "RSA");
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224, "SHA3-224", "RSA");
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256, "SHA3-256", "RSA");
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384, "SHA3-384", "RSA");
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512, "SHA3-512", "RSA");
// BEGIN Android-removed: Unsupported algorithms
/*
+ addEntries(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128, "SHAKE128", "RSAPSS");
+ addEntries(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256, "SHAKE256", "RSAPSS");
addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, "RIPEMD128", "RSA");
addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, "RIPEMD160", "RSA");
addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, "RIPEMD256", "RSA");
+ addEntries(CMSObjectIdentifiers.id_ecdsa_with_shake128, "SHAKE128", "ECDSA");
+ addEntries(CMSObjectIdentifiers.id_ecdsa_with_shake256, "SHAKE256", "ECDSA");
*/
// END Android-removed: Unsupported algorithms
@@ -85,6 +99,8 @@
addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384", "ECDSA");
addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512", "ECDSA");
addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1", "DSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1", "ECDSA");
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224", "ECDSA");
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256", "ECDSA");
@@ -94,14 +110,31 @@
addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA");
addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1");
addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1");
- // BEGIN Android-removed: Unsupported algorithms
- /*
addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1", "PLAIN-ECDSA");
addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224", "PLAIN-ECDSA");
addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256", "PLAIN-ECDSA");
addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384", "PLAIN-ECDSA");
addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512", "PLAIN-ECDSA");
addEntries(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA3_224, "SHA3-224", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA3_256, "SHA3-256", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA3_384, "SHA3-384", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA3_512, "SHA3-512", "PLAIN-ECDSA");
+
+// addEntries(GMObjectIdentifiers.sm2sign_with_rmd160, "RIPEMD160", "SM2");
+// addEntries(GMObjectIdentifiers.sm2sign_with_sha1, "SHA1", "SM2");
+// addEntries(GMObjectIdentifiers.sm2sign_with_sha224, "SHA224", "SM2");
+ addEntries(GMObjectIdentifiers.sm2sign_with_sha256, "SHA256", "SM2");
+// addEntries(GMObjectIdentifiers.sm2sign_with_sha384, "SHA384", "SM2");
+// addEntries(GMObjectIdentifiers.sm2sign_with_sha512, "SHA512", "SM2");
+ addEntries(GMObjectIdentifiers.sm2sign_with_sm3, "SM3", "SM2");
+
+ addEntries(BCObjectIdentifiers.sphincs256_with_SHA512, "SHA512", "SPHINCS256");
+ addEntries(BCObjectIdentifiers.sphincs256_with_SHA3_512, "SHA3-512", "SPHINCS256");
+
+ addEntries(BCObjectIdentifiers.picnic_with_shake256, "SHAKE256", "Picnic");
+ addEntries(BCObjectIdentifiers.picnic_with_sha512, "SHA512", "Picnic");
+ addEntries(BCObjectIdentifiers.picnic_with_sha3_512, "SHA3-512", "Picnic");
addEntries(GMObjectIdentifiers.sm2sign_with_rmd160, "RIPEMD160", "SM2");
addEntries(GMObjectIdentifiers.sm2sign_with_sha1, "SHA1", "SM2");
@@ -130,6 +163,7 @@
encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3410");
encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "ECGOST3410-2012-256");
encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "ECGOST3410-2012-512");
+ encryptionAlgs.put(X9ObjectIdentifiers.id_ecPublicKey, "ECDSA");
digestAlgs.put(PKCSObjectIdentifiers.md2, "MD2");
digestAlgs.put(PKCSObjectIdentifiers.md4, "MD4");
@@ -143,6 +177,10 @@
digestAlgs.put(NISTObjectIdentifiers.id_sha512, "SHA512");
// BEGIN Android-removed: Unsupported algorithms
/*
+ digestAlgs.put(NISTObjectIdentifiers.id_sha512_224, "SHA512(224)");
+ digestAlgs.put(NISTObjectIdentifiers.id_sha512_256, "SHA512(256)");
+ digestAlgs.put(NISTObjectIdentifiers.id_shake128, "SHAKE128");
+ digestAlgs.put(NISTObjectIdentifiers.id_shake256, "SHAKE256");
digestAlgs.put(NISTObjectIdentifiers.id_sha3_224, "SHA3-224");
digestAlgs.put(NISTObjectIdentifiers.id_sha3_256, "SHA3-256");
digestAlgs.put(NISTObjectIdentifiers.id_sha3_384, "SHA3-384");
@@ -155,6 +193,34 @@
digestAlgs.put(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256, "GOST3411-2012-256");
digestAlgs.put(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, "GOST3411-2012-512");
digestAlgs.put(GMObjectIdentifiers.sm3, "SM3");
+
+ simpleAlgs.put(EdECObjectIdentifiers.id_Ed25519, "Ed25519");
+ simpleAlgs.put(EdECObjectIdentifiers.id_Ed448, "Ed448");
+ simpleAlgs.put(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, "LMS");
+
+ simpleAlgs.put(MiscObjectIdentifiers.id_alg_composite, "COMPOSITE");
+ simpleAlgs.put(BCObjectIdentifiers.falcon_512, "Falcon-512");
+ simpleAlgs.put(BCObjectIdentifiers.falcon_1024, "Falcon-1024");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium2, "Dilithium2");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium3, "Dilithium3");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium5, "Dilithium5");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_128s, "SPHINCS+-SHA2-128s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_128f, "SPHINCS+-SHA2-128f");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_192s, "SPHINCS+-SHA2-192s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_192f, "SPHINCS+-SHA2-192f");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_256s, "SPHINCS+-SHA2-256s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_256f, "SPHINCS+-SHA2-256f");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_128s, "SPHINCS+-SHAKE-128s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_128f, "SPHINCS+-SHAKE-128f");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_192s, "SPHINCS+-SHAKE-192s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_192f, "SPHINCS+-SHAKE-192f");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_256s, "SPHINCS+-SHAKE-256s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_256f, "SPHINCS+-SHAKE-256f");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium2, "Dilithium2");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium3, "Dilithium3");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium5, "Dilithium5");
+
+ simpleAlgs.put(BCObjectIdentifiers.picnic_signature, "Picnic");
*/
// END Android-removed: Unsupported algorithms
}
@@ -230,16 +296,29 @@
{
return "Ed448";
}
+
+ // if (encryptionAlgOID.on(BCObjectIdentifiers.sphincsPlus))
+ // {
+ // return "SPHINCSPlus";
+ // }
*/
// END Android-removed: unsupported algorithms
- String digestName = getDigestAlgName(encryptionAlg.getAlgorithm());
+ ASN1ObjectIdentifier encryptionAlgOID = encryptionAlg.getAlgorithm();
- if (!digestName.equals(encryptionAlg.getAlgorithm().getId()))
+ String simpleAlgName = (String)simpleAlgs.get(encryptionAlgOID);
+ if (simpleAlgName != null)
{
- return digestName + "with" + getEncryptionAlgName(encryptionAlg.getAlgorithm());
+ return simpleAlgName;
}
- return getDigestAlgName(digestAlg.getAlgorithm()) + "with" + getEncryptionAlgName(encryptionAlg.getAlgorithm());
+ String digestName = getDigestAlgName(encryptionAlgOID);
+
+ if (!digestName.equals(encryptionAlgOID.getId()))
+ {
+ return digestName + "with" + getEncryptionAlgName(encryptionAlgOID);
+ }
+
+ return getDigestAlgName(digestAlg.getAlgorithm()) + "with" + getEncryptionAlgName(encryptionAlgOID);
}
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
index 4e3c967..58dce8f 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
@@ -16,8 +16,8 @@
public class DefaultCMSSignatureEncryptionAlgorithmFinder
implements CMSSignatureEncryptionAlgorithmFinder
{
- private static final Set RSA_PKCS1d5 = new HashSet();
- private static final Map GOST_ENC = new HashMap();
+ protected static final Set RSA_PKCS1d5 = new HashSet();
+ protected static final Map GOST_ENC = new HashMap();
static
{
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/KEMRecipient.java b/bcpkix/src/main/java/org/bouncycastle/cms/KEMRecipient.java
new file mode 100644
index 0000000..0134be4
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/KEMRecipient.java
@@ -0,0 +1,10 @@
+package org.bouncycastle.cms;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface KEMRecipient
+ extends Recipient
+{
+ RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentKey)
+ throws CMSException;
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
index b26dddb..3acb69c 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
@@ -19,11 +19,7 @@
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
-import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import org.bouncycastle.operator.DigestCalculator;
-import org.bouncycastle.operator.DigestCalculatorProvider;
-import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.io.TeeOutputStream;
@@ -34,7 +30,7 @@
private final CMSAttributeTableGenerator unsAttrGen;
private final ContentSigner signer;
private final DigestCalculator digester;
- private final DigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+ private final AlgorithmIdentifier digestAlgorithm;
private final CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder;
private byte[] calculatedDigest = null;
@@ -43,44 +39,32 @@
SignerInfoGenerator(
SignerIdentifier signerIdentifier,
ContentSigner signer,
- DigestCalculatorProvider digesterProvider,
+ AlgorithmIdentifier digesterAlgorithm,
CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder)
- throws OperatorCreationException
{
- this(signerIdentifier, signer, digesterProvider, sigEncAlgFinder, false);
+ this.signerIdentifier = signerIdentifier;
+ this.signer = signer;
+ this.digestAlgorithm = digesterAlgorithm;
+ this.digester = null;
+ this.sAttrGen = null;
+ this.unsAttrGen = null;
+ this.sigEncAlgFinder = sigEncAlgFinder;
}
SignerInfoGenerator(
SignerIdentifier signerIdentifier,
ContentSigner signer,
- DigestCalculatorProvider digesterProvider,
+ DigestCalculator digester,
CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder,
- boolean isDirectSignature)
- throws OperatorCreationException
+ CMSAttributeTableGenerator sAttrGen,
+ CMSAttributeTableGenerator unsAttrGen)
{
this.signerIdentifier = signerIdentifier;
this.signer = signer;
-
- if (digesterProvider != null)
- {
- this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier()));
- }
- else
- {
- this.digester = null;
- }
-
- if (isDirectSignature)
- {
- this.sAttrGen = null;
- this.unsAttrGen = null;
- }
- else
- {
- this.sAttrGen = new DefaultSignedAttributeTableGenerator();
- this.unsAttrGen = null;
- }
-
+ this.digestAlgorithm = digester.getAlgorithmIdentifier();
+ this.digester = digester;
+ this.sAttrGen = sAttrGen;
+ this.unsAttrGen = unsAttrGen;
this.sigEncAlgFinder = sigEncAlgFinder;
}
@@ -91,38 +75,13 @@
{
this.signerIdentifier = original.signerIdentifier;
this.signer = original.signer;
+ this.digestAlgorithm = original.digestAlgorithm;
this.digester = original.digester;
this.sigEncAlgFinder = original.sigEncAlgFinder;
this.sAttrGen = sAttrGen;
this.unsAttrGen = unsAttrGen;
}
- SignerInfoGenerator(
- SignerIdentifier signerIdentifier,
- ContentSigner signer,
- DigestCalculatorProvider digesterProvider,
- CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder,
- CMSAttributeTableGenerator sAttrGen,
- CMSAttributeTableGenerator unsAttrGen)
- throws OperatorCreationException
- {
- this.signerIdentifier = signerIdentifier;
- this.signer = signer;
-
- if (digesterProvider != null)
- {
- this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier()));
- }
- else
- {
- this.digester = null;
- }
-
- this.sAttrGen = sAttrGen;
- this.unsAttrGen = unsAttrGen;
- this.sigEncAlgFinder = sigEncAlgFinder;
- }
-
public SignerIdentifier getSID()
{
return signerIdentifier;
@@ -145,12 +104,7 @@
public AlgorithmIdentifier getDigestAlgorithm()
{
- if (digester != null)
- {
- return digester.getAlgorithmIdentifier();
- }
-
- return digAlgFinder.find(signer.getAlgorithmIdentifier());
+ return digestAlgorithm;
}
public OutputStream getCalculatingOutputStream()
@@ -207,14 +161,13 @@
}
else
{
+ digestAlg = digestAlgorithm;
if (digester != null)
{
- digestAlg = digester.getAlgorithmIdentifier();
calculatedDigest = digester.getDigest();
}
else
{
- digestAlg = digAlgFinder.find(signer.getAlgorithmIdentifier());
calculatedDigest = null;
}
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
index ccb6e2c..b10a6e3 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
@@ -3,8 +3,12 @@
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
import org.bouncycastle.asn1.cms.SignerIdentifier;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
+import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.operator.DigestCalculatorProvider;
import org.bouncycastle.operator.OperatorCreationException;
@@ -13,11 +17,14 @@
*/
public class SignerInfoGeneratorBuilder
{
+ private final DigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+
private DigestCalculatorProvider digestProvider;
private boolean directSignature;
private CMSAttributeTableGenerator signedGen;
private CMSAttributeTableGenerator unsignedGen;
private CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder;
+ private AlgorithmIdentifier contentDigest;
/**
* Base constructor.
@@ -55,6 +62,18 @@
}
/**
+ * Set the algorithm identifier for the contentDigest to be used for processing the data.
+ *
+ * @return the builder object
+ */
+ public SignerInfoGeneratorBuilder setContentDigest(AlgorithmIdentifier contentDigest)
+ {
+ this.contentDigest = contentDigest;
+
+ return this;
+ }
+
+ /**
* Provide a custom signed attribute generator.
*
* @param signedGen a generator of signed attributes.
@@ -120,9 +139,19 @@
private SignerInfoGenerator createGenerator(ContentSigner contentSigner, SignerIdentifier sigId)
throws OperatorCreationException
{
+ DigestCalculator digester;
+ if (contentDigest != null)
+ {
+ digester = digestProvider.get(contentDigest);
+ }
+ else
+ {
+ digester = digestProvider.get(digAlgFinder.find(contentSigner.getAlgorithmIdentifier()));
+ }
+
if (directSignature)
{
- return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, true);
+ return new SignerInfoGenerator(sigId, contentSigner, digester.getAlgorithmIdentifier(), sigEncAlgFinder);
}
if (signedGen != null || unsignedGen != null)
@@ -132,9 +161,9 @@
signedGen = new DefaultSignedAttributeTableGenerator();
}
- return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, signedGen, unsignedGen);
+ return new SignerInfoGenerator(sigId, contentSigner, digester, sigEncAlgFinder, signedGen, unsignedGen);
}
- return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder);
+ return new SignerInfoGenerator(sigId, contentSigner, digester, sigEncAlgFinder, new DefaultSignedAttributeTableGenerator(), null);
}
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
index 96440a5..06a444d 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
@@ -24,6 +24,8 @@
import org.bouncycastle.asn1.cms.SignerIdentifier;
import org.bouncycastle.asn1.cms.SignerInfo;
import org.bouncycastle.asn1.cms.Time;
+import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.DigestInfo;
import org.bouncycastle.cert.X509CertificateHolder;
@@ -39,34 +41,34 @@
*/
public class SignerInformation
{
- private final SignerId sid;
- private final CMSProcessable content;
- private final byte[] signature;
- private final ASN1ObjectIdentifier contentType;
- private final boolean isCounterSignature;
+ private final SignerId sid;
+ private final CMSProcessable content;
+ private final byte[] signature;
+ private final ASN1ObjectIdentifier contentType;
+ private final boolean isCounterSignature;
// Derived
- private AttributeTable signedAttributeValues;
- private AttributeTable unsignedAttributeValues;
- private byte[] resultDigest;
+ private AttributeTable signedAttributeValues;
+ private AttributeTable unsignedAttributeValues;
+ private byte[] resultDigest;
- protected final SignerInfo info;
- protected final AlgorithmIdentifier digestAlgorithm;
- protected final AlgorithmIdentifier encryptionAlgorithm;
- protected final ASN1Set signedAttributeSet;
- protected final ASN1Set unsignedAttributeSet;
+ protected final SignerInfo info;
+ protected final AlgorithmIdentifier digestAlgorithm;
+ protected final AlgorithmIdentifier encryptionAlgorithm;
+ protected final ASN1Set signedAttributeSet;
+ protected final ASN1Set unsignedAttributeSet;
SignerInformation(
- SignerInfo info,
+ SignerInfo info,
ASN1ObjectIdentifier contentType,
- CMSProcessable content,
- byte[] resultDigest)
+ CMSProcessable content,
+ byte[] resultDigest)
{
this.info = info;
this.contentType = contentType;
this.isCounterSignature = contentType == null;
- SignerIdentifier s = info.getSID();
+ SignerIdentifier s = info.getSID();
if (s.isTagged())
{
@@ -76,7 +78,7 @@
}
else
{
- IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.getInstance(s.getId());
+ IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.getInstance(s.getId());
sid = new SignerId(iAnds.getName(), iAnds.getSerialNumber().getValue());
}
@@ -109,7 +111,7 @@
* that by also tweaking the SignerInfo so that these issues can be dealt with.
*
* @param baseInfo the SignerInformation to base this one on.
- * @param info the SignerInfo to associate with the existing baseInfo data.
+ * @param info the SignerInfo to associate with the existing baseInfo data.
*/
protected SignerInformation(SignerInformation baseInfo, SignerInfo info)
{
@@ -124,8 +126,8 @@
this.signature = info.getEncryptedDigest().getOctets();
this.content = baseInfo.content;
this.resultDigest = baseInfo.resultDigest;
- this.signedAttributeValues = baseInfo.signedAttributeValues;
- this.unsignedAttributeValues = baseInfo.unsignedAttributeValues;
+ this.signedAttributeValues = getSignedAttributes();
+ this.unsignedAttributeValues = getUnsignedAttributes();
}
public boolean isCounterSignature()
@@ -139,7 +141,7 @@
}
private byte[] encodeObj(
- ASN1Encodable obj)
+ ASN1Encodable obj)
throws IOException
{
if (obj != null)
@@ -200,10 +202,10 @@
{
throw new IllegalStateException("method can only be called after verify.");
}
-
+
return Arrays.clone(resultDigest);
}
-
+
/**
* return the object identifier for the signature.
*/
@@ -226,7 +228,7 @@
{
throw new RuntimeException("exception getting encryption parameters " + e);
}
- }
+ }
/**
* return a table of the signed attributes - indexed by
@@ -276,7 +278,7 @@
The countersignature attribute MUST be an unsigned attribute; it MUST
NOT be a signed attribute, an authenticated attribute, an
unauthenticated attribute, or an unprotected attribute.
- */
+ */
AttributeTable unsignedAttributeTable = getUnsignedAttributes();
if (unsignedAttributeTable == null)
{
@@ -307,7 +309,7 @@
// TODO Throw an appropriate exception?
}
- for (Enumeration en = values.getObjects(); en.hasMoreElements();)
+ for (Enumeration en = values.getObjects(); en.hasMoreElements(); )
{
/*
Countersignature values have the same meaning as SignerInfo values
@@ -331,9 +333,10 @@
return new SignerInformationStore(counterSignatures);
}
-
+
/**
* return the DER encoding of the signed attributes.
+ *
* @throws IOException if an encoding error occurs.
*/
public byte[] getEncodedSignedAttributes()
@@ -351,12 +354,14 @@
SignerInformationVerifier verifier)
throws CMSException
{
- String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID());
+ String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID());
+ AlgorithmIdentifier realDigestAlgorithm = signedAttributeSet != null ?
+ info.getDigestAlgorithm() : translateBrokenRSAPkcs7(encryptionAlgorithm, info.getDigestAlgorithm());
ContentVerifier contentVerifier;
try
{
- contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, info.getDigestAlgorithm());
+ contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, realDigestAlgorithm);
}
catch (OperatorCreationException e)
{
@@ -369,10 +374,10 @@
if (resultDigest == null)
{
- DigestCalculator calc = verifier.getDigestCalculator(this.getDigestAlgorithmID());
+ DigestCalculator calc = verifier.getDigestCalculator(realDigestAlgorithm);
if (content != null)
{
- OutputStream digOut = calc.getOutputStream();
+ OutputStream digOut = calc.getOutputStream();
if (signedAttributeSet == null)
{
@@ -436,128 +441,18 @@
}
// RFC 3852 11.1 Check the content-type attribute is correct
- {
- ASN1Primitive validContentType = getSingleValuedSignedAttribute(
- CMSAttributes.contentType, "content-type");
- if (validContentType == null)
- {
- if (!isCounterSignature && signedAttributeSet != null)
- {
- throw new CMSException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
- }
- }
- else
- {
- if (isCounterSignature)
- {
- throw new CMSException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
- }
-
- if (!(validContentType instanceof ASN1ObjectIdentifier))
- {
- throw new CMSException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
- }
-
- ASN1ObjectIdentifier signedContentType = (ASN1ObjectIdentifier)validContentType;
-
- if (!signedContentType.equals(contentType))
- {
- throw new CMSException("content-type attribute value does not match eContentType");
- }
- }
- }
+ verifyContentTypeAttributeValue();
AttributeTable signedAttrTable = this.getSignedAttributes();
// RFC 6211 Validate Algorithm Identifier protection attribute if present
- {
- AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
- if (unsignedAttrTable != null && unsignedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect).size() > 0)
- {
- throw new CMSException("A cmsAlgorithmProtect attribute MUST be a signed attribute");
- }
- if (signedAttrTable != null)
- {
- ASN1EncodableVector protectionAttributes = signedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect);
- if (protectionAttributes.size() > 1)
- {
- throw new CMSException("Only one instance of a cmsAlgorithmProtect attribute can be present");
- }
-
- if (protectionAttributes.size() > 0)
- {
- Attribute attr = Attribute.getInstance(protectionAttributes.get(0));
- if (attr.getAttrValues().size() != 1)
- {
- throw new CMSException("A cmsAlgorithmProtect attribute MUST contain exactly one value");
- }
-
- CMSAlgorithmProtection algorithmProtection = CMSAlgorithmProtection.getInstance(attr.getAttributeValues()[0]);
-
- if (!CMSUtils.isEquivalent(algorithmProtection.getDigestAlgorithm(), info.getDigestAlgorithm()))
- {
- throw new CMSException("CMS Algorithm Identifier Protection check failed for digestAlgorithm");
- }
-
- if (!CMSUtils.isEquivalent(algorithmProtection.getSignatureAlgorithm(), info.getDigestEncryptionAlgorithm()))
- {
- throw new CMSException("CMS Algorithm Identifier Protection check failed for signatureAlgorithm");
- }
- }
- }
- }
+ verifyAlgorithmIdentifierProtectionAttribute(signedAttrTable);
// RFC 3852 11.2 Check the message-digest attribute is correct
- {
- ASN1Primitive validMessageDigest = getSingleValuedSignedAttribute(
- CMSAttributes.messageDigest, "message-digest");
- if (validMessageDigest == null)
- {
- if (signedAttributeSet != null)
- {
- throw new CMSException("the message-digest signed attribute type MUST be present when there are any signed attributes present");
- }
- }
- else
- {
- if (!(validMessageDigest instanceof ASN1OctetString))
- {
- throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
- }
-
- ASN1OctetString signedMessageDigest = (ASN1OctetString)validMessageDigest;
-
- if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets()))
- {
- throw new CMSSignerDigestMismatchException("message-digest attribute value does not match calculated value");
- }
- }
- }
+ verifyMessageDigestAttribute();
// RFC 3852 11.4 Validate countersignature attribute(s)
- {
- if (signedAttrTable != null
- && signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0)
- {
- throw new CMSException("A countersignature attribute MUST NOT be a signed attribute");
- }
-
- AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
- if (unsignedAttrTable != null)
- {
- ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature);
- for (int i = 0; i < csAttrs.size(); ++i)
- {
- Attribute csAttr = Attribute.getInstance(csAttrs.get(i));
- if (csAttr.getAttrValues().size() < 1)
- {
- throw new CMSException("A countersignature attribute MUST contain at least one AttributeValue");
- }
-
- // Note: We don't recursively validate the countersignature value
- }
- }
- }
+ verifyCounterSignatureAttribute(signedAttrTable);
try
{
@@ -569,7 +464,7 @@
if (encName.equals("RSA"))
{
- DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest);
+ DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(realDigestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest);
return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature());
}
@@ -587,6 +482,154 @@
}
/**
+ * RFC 3852 11.1 Check the content-type attribute is correct
+ *
+ * @throws CMSException when content-type was invalid.
+ */
+ private void verifyContentTypeAttributeValue()
+ throws CMSException
+ {
+ ASN1Primitive validContentType = getSingleValuedSignedAttribute(
+ CMSAttributes.contentType, "content-type");
+ if (validContentType == null)
+ {
+ if (!isCounterSignature && signedAttributeSet != null)
+ {
+ throw new CMSException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
+ }
+ }
+ else
+ {
+ if (isCounterSignature)
+ {
+ throw new CMSException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
+ }
+
+ if (!(validContentType instanceof ASN1ObjectIdentifier))
+ {
+ throw new CMSException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
+ }
+
+ ASN1ObjectIdentifier signedContentType = (ASN1ObjectIdentifier)validContentType;
+
+ if (!signedContentType.equals(contentType))
+ {
+ throw new CMSException("content-type attribute value does not match eContentType");
+ }
+ }
+ }
+
+ /**
+ * RFC 3852 11.2 Check the message-digest attribute is correct
+ *
+ * @throws CMSException when message-digest attribute was rejected
+ */
+ private void verifyMessageDigestAttribute()
+ throws CMSException
+ {
+ ASN1Primitive validMessageDigest = getSingleValuedSignedAttribute(
+ CMSAttributes.messageDigest, "message-digest");
+ if (validMessageDigest == null)
+ {
+ if (signedAttributeSet != null)
+ {
+ throw new CMSException("the message-digest signed attribute type MUST be present when there are any signed attributes present");
+ }
+ }
+ else
+ {
+ if (!(validMessageDigest instanceof ASN1OctetString))
+ {
+ throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
+ }
+
+ ASN1OctetString signedMessageDigest = (ASN1OctetString)validMessageDigest;
+
+ if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets()))
+ {
+ throw new CMSSignerDigestMismatchException("message-digest attribute value does not match calculated value");
+ }
+ }
+ }
+
+ /**
+ * RFC 6211 Validate Algorithm Identifier protection attribute if present
+ *
+ * @param signedAttrTable signed attributes
+ * @throws CMSException when cmsAlgorihmProtect attribute was rejected
+ */
+ private void verifyAlgorithmIdentifierProtectionAttribute(AttributeTable signedAttrTable)
+ throws CMSException
+ {
+ AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
+ if (unsignedAttrTable != null && unsignedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect).size() > 0)
+ {
+ throw new CMSException("A cmsAlgorithmProtect attribute MUST be a signed attribute");
+ }
+ if (signedAttrTable != null)
+ {
+ ASN1EncodableVector protectionAttributes = signedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect);
+ if (protectionAttributes.size() > 1)
+ {
+ throw new CMSException("Only one instance of a cmsAlgorithmProtect attribute can be present");
+ }
+
+ if (protectionAttributes.size() > 0)
+ {
+ Attribute attr = Attribute.getInstance(protectionAttributes.get(0));
+ if (attr.getAttrValues().size() != 1)
+ {
+ throw new CMSException("A cmsAlgorithmProtect attribute MUST contain exactly one value");
+ }
+
+ CMSAlgorithmProtection algorithmProtection = CMSAlgorithmProtection.getInstance(attr.getAttributeValues()[0]);
+
+ if (!CMSUtils.isEquivalent(algorithmProtection.getDigestAlgorithm(), info.getDigestAlgorithm()))
+ {
+ throw new CMSException("CMS Algorithm Identifier Protection check failed for digestAlgorithm");
+ }
+
+ if (!CMSUtils.isEquivalent(algorithmProtection.getSignatureAlgorithm(), info.getDigestEncryptionAlgorithm()))
+ {
+ throw new CMSException("CMS Algorithm Identifier Protection check failed for signatureAlgorithm");
+ }
+ }
+ }
+ }
+
+ /**
+ * RFC 3852 11.4 Validate countersignature attribute(s)
+ *
+ * @param signedAttrTable signed attributes
+ * @throws CMSException when countersignature attribute was rejected
+ */
+ private void verifyCounterSignatureAttribute(AttributeTable signedAttrTable)
+ throws CMSException
+ {
+ if (signedAttrTable != null
+ && signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0)
+ {
+ throw new CMSException("A countersignature attribute MUST NOT be a signed attribute");
+ }
+
+ AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
+ if (unsignedAttrTable != null)
+ {
+ ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature);
+ for (int i = 0; i < csAttrs.size(); ++i)
+ {
+ Attribute csAttr = Attribute.getInstance(csAttrs.get(i));
+ if (csAttr.getAttrValues().size() < 1)
+ {
+ throw new CMSException("A countersignature attribute MUST contain at least one AttributeValue");
+ }
+
+ // Note: We don't recursively validate the countersignature value
+ }
+ }
+ }
+
+ /**
* Verify that the given verifier can successfully verify the signature on
* this SignerInformation object.
*
@@ -647,27 +690,28 @@
ASN1EncodableVector v = signedAttrTable.getAll(attrOID);
switch (v.size())
{
- case 0:
- return null;
- case 1:
+ case 0:
+ return null;
+ case 1:
+ {
+ Attribute t = (Attribute)v.get(0);
+ ASN1Set attrValues = t.getAttrValues();
+ if (attrValues.size() != 1)
{
- Attribute t = (Attribute)v.get(0);
- ASN1Set attrValues = t.getAttrValues();
- if (attrValues.size() != 1)
- {
- throw new CMSException("A " + printableName
- + " attribute MUST have a single attribute value");
- }
-
- return attrValues.getObjectAt(0).toASN1Primitive();
+ throw new CMSException("A " + printableName
+ + " attribute MUST have a single attribute value");
}
- default:
- throw new CMSException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the "
- + printableName + " attribute");
+
+ return attrValues.getObjectAt(0).toASN1Primitive();
+ }
+ default:
+ throw new CMSException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the "
+ + printableName + " attribute");
}
}
- private Time getSigningTime() throws CMSException
+ private Time getSigningTime()
+ throws CMSException
{
ASN1Primitive validSigningTime = getSingleValuedSignedAttribute(
CMSAttributes.signingTime, "signing-time");
@@ -691,27 +735,27 @@
* Return a signer information object with the passed in unsigned
* attributes replacing the ones that are current associated with
* the object passed in.
- *
- * @param signerInformation the signerInfo to be used as the basis.
+ *
+ * @param signerInformation the signerInfo to be used as the basis.
* @param unsignedAttributes the unsigned attributes to add.
* @return a copy of the original SignerInformationObject with the changed attributes.
*/
public static SignerInformation replaceUnsignedAttributes(
- SignerInformation signerInformation,
- AttributeTable unsignedAttributes)
+ SignerInformation signerInformation,
+ AttributeTable unsignedAttributes)
{
- SignerInfo sInfo = signerInformation.info;
- ASN1Set unsignedAttr = null;
-
+ SignerInfo sInfo = signerInformation.info;
+ ASN1Set unsignedAttr = null;
+
if (unsignedAttributes != null)
{
unsignedAttr = new DERSet(unsignedAttributes.toASN1EncodableVector());
}
-
+
return new SignerInformation(
- new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(),
- sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), unsignedAttr),
- signerInformation.contentType, signerInformation.content, null);
+ new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(),
+ sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), unsignedAttr),
+ signerInformation.contentType, signerInformation.content, null);
}
/**
@@ -719,17 +763,17 @@
* signatures attached as an unsigned attribute.
*
* @param signerInformation the signerInfo to be used as the basis.
- * @param counterSigners signer info objects carrying counter signature.
+ * @param counterSigners signer info objects carrying counter signature.
* @return a copy of the original SignerInformationObject with the changed attributes.
*/
public static SignerInformation addCounterSigners(
- SignerInformation signerInformation,
- SignerInformationStore counterSigners)
+ SignerInformation signerInformation,
+ SignerInformationStore counterSigners)
{
// TODO Perform checks from RFC 3852 11.4
- SignerInfo sInfo = signerInformation.info;
- AttributeTable unsignedAttr = signerInformation.getUnsignedAttributes();
+ SignerInfo sInfo = signerInformation.info;
+ AttributeTable unsignedAttr = signerInformation.getUnsignedAttributes();
ASN1EncodableVector v;
if (unsignedAttr != null)
@@ -743,7 +787,7 @@
ASN1EncodableVector sigs = new ASN1EncodableVector();
- for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext();)
+ for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext(); )
{
sigs.add(((SignerInformation)it.next()).toASN1Structure());
}
@@ -751,8 +795,23 @@
v.add(new Attribute(CMSAttributes.counterSignature, new DERSet(sigs)));
return new SignerInformation(
- new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(),
- sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), new DERSet(v)),
- signerInformation.contentType, signerInformation.content, null);
+ new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(),
+ sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), new DERSet(v)),
+ signerInformation.contentType, signerInformation.content, null);
+ }
+
+ private static AlgorithmIdentifier translateBrokenRSAPkcs7(AlgorithmIdentifier encryptionAlgorithm, AlgorithmIdentifier digestAlgorithm)
+ {
+ if (PKCSObjectIdentifiers.rsaEncryption.equals(encryptionAlgorithm.getAlgorithm()))
+ {
+ // Yes, some people really did this.
+ if (OIWObjectIdentifiers.sha1WithRSA.equals(digestAlgorithm.getAlgorithm())
+ || PKCSObjectIdentifiers.sha1WithRSAEncryption.equals(digestAlgorithm.getAlgorithm()))
+ {
+ return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
+ }
+ }
+
+ return digestAlgorithm;
}
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/bc/package.html b/bcpkix/src/main/java/org/bouncycastle/cms/bc/package.html
deleted file mode 100644
index 7182ae3..0000000
--- a/bcpkix/src/main/java/org/bouncycastle/cms/bc/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
-<body bgcolor="#ffffff">
-CMS operator implementations for doing message encryption, signing, digesting, and MACing operations using the BC lightweight API.
-</body>
-</html>
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
index 17a2f09..d39a7a9 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
@@ -3,6 +3,7 @@
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.bouncycastle.cms.CMSAttributeTableGenerator;
@@ -52,6 +53,13 @@
return this;
}
+ public JcaSignerInfoGeneratorBuilder setContentDigest(AlgorithmIdentifier contentDigest)
+ {
+ builder.setContentDigest(contentDigest);
+
+ return this;
+ }
+
public JcaSignerInfoGeneratorBuilder setSignedAttributeGenerator(CMSAttributeTableGenerator signedGen)
{
builder.setSignedAttributeGenerator(signedGen);
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java
index a805839..0fd0c07 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java
@@ -81,7 +81,7 @@
return new SignerInformationVerifier(sigAlgNameGen, sigAlgIDFinder, helper.createContentVerifierProvider(pubKey), digestProvider);
}
- private class Helper
+ private static class Helper
{
ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey)
throws OperatorCreationException
@@ -108,7 +108,7 @@
}
}
- private class NamedHelper
+ private static class NamedHelper
extends Helper
{
private final String providerName;
@@ -143,7 +143,7 @@
}
}
- private class ProviderHelper
+ private static class ProviderHelper
extends Helper
{
private final Provider provider;
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java
index 441f27d..0a589ec 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java
@@ -51,7 +51,7 @@
return new SignerInformationVerifier(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), helper.createContentVerifierProvider(pubKey), helper.createDigestCalculatorProvider());
}
- private class Helper
+ private static class Helper
{
ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey)
throws OperatorCreationException
@@ -78,7 +78,7 @@
}
}
- private class NamedHelper
+ private static class NamedHelper
extends Helper
{
private final String providerName;
@@ -113,7 +113,7 @@
}
}
- private class ProviderHelper
+ private static class ProviderHelper
extends Helper
{
private final Provider provider;
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JceAADStream.java b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JceAADStream.java
new file mode 100644
index 0000000..23e5785
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JceAADStream.java
@@ -0,0 +1,31 @@
+package org.bouncycastle.cms.jcajce;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.crypto.Cipher;
+
+class JceAADStream
+ extends OutputStream
+{
+ private static final byte[] SINGLE_BYTE = new byte[1];
+ private Cipher cipher;
+
+ JceAADStream(Cipher cipher)
+ {
+ this.cipher = cipher;
+ }
+
+ public void write(byte[] buf, int off, int len)
+ throws IOException
+ {
+ cipher.updateAAD(buf, off, len);
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ SINGLE_BYTE[0] = (byte)b;
+ cipher.updateAAD(SINGLE_BYTE, 0, 1);
+ }
+ }
diff --git a/bcpkix/src/main/java/org/bouncycastle/openssl/CertificateTrustBlock.java b/bcpkix/src/main/java/org/bouncycastle/openssl/CertificateTrustBlock.java
index 9a76084..7c6b65c 100644
--- a/bcpkix/src/main/java/org/bouncycastle/openssl/CertificateTrustBlock.java
+++ b/bcpkix/src/main/java/org/bouncycastle/openssl/CertificateTrustBlock.java
@@ -11,6 +11,7 @@
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.ASN1UTF8String;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.DERUTF8String;
@@ -54,9 +55,9 @@
{
this.prohibitions = ASN1Sequence.getInstance((ASN1TaggedObject)obj, false);
}
- else if (obj instanceof DERUTF8String)
+ else if (obj instanceof ASN1UTF8String)
{
- this.alias = DERUTF8String.getInstance(obj).getString();
+ this.alias = ASN1UTF8String.getInstance(obj).getString();
}
}
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/AADProcessor.java b/bcpkix/src/main/java/org/bouncycastle/operator/AADProcessor.java
new file mode 100644
index 0000000..a663421
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/AADProcessor.java
@@ -0,0 +1,24 @@
+package org.bouncycastle.operator;
+
+import java.io.OutputStream;
+
+/**
+ * Base interface for extra methods required for handling associated data in AEAD ciphers.
+ */
+public interface AADProcessor
+{
+ /**
+ * Return a stream to write associated data to in order to have it incorporated into the
+ * AEAD cipher's MAC.
+ *
+ * @return a stream for collecting associated data.
+ */
+ OutputStream getAADStream();
+
+ /**
+ * Return the final value of AEAD cipher's MAC.
+ *
+ * @return MAC value for the AEAD cipher.
+ */
+ byte[] getMAC();
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/AlgorithmNameFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/AlgorithmNameFinder.java
new file mode 100644
index 0000000..bacb359
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/AlgorithmNameFinder.java
@@ -0,0 +1,35 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * General finder for converting OIDs and AlgorithmIdentifiers into strings.
+ */
+public interface AlgorithmNameFinder
+{
+ /**
+ * Return true if the passed in objectIdentifier has a "human friendly" name associated with it.
+ *
+ * @param objectIdentifier the OID of interest.
+ * @return true if a name lookup exists for the OID, false otherwise.
+ */
+ boolean hasAlgorithmName(ASN1ObjectIdentifier objectIdentifier);
+
+ /**
+ * Return a string representation of the passed in objectIdentifier.
+ *
+ * @param objectIdentifier the OID of interest.
+ * @return a "human friendly" representation of the OID, the OID as a string if none available.
+ */
+ String getAlgorithmName(ASN1ObjectIdentifier objectIdentifier);
+
+ /**
+ * Return a string representation of the passed in AlgorithmIdentifier, based on the OID in the AlgorithmField, with the parameters
+ * included where appropriate.
+ *
+ * @param algorithmIdentifier the AlgorithmIdentifier of interest.
+ * @return a "human friendly" representation of the algorithmIdentifier, the identifiers OID as a string if none available.
+ */
+ String getAlgorithmName(AlgorithmIdentifier algorithmIdentifier);
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
index 119d1b1..a5e4fbb 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
@@ -1,7 +1,9 @@
package org.bouncycastle.operator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -9,6 +11,7 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
@@ -27,6 +30,9 @@
{
private static Map digestOids = new HashMap();
private static Map digestNameToOids = new HashMap();
+ private static Map digestOidToAlgIds = new HashMap();
+
+ private static Set shake256oids = new HashSet(); // signatures that use SHAKE-256
static
{
@@ -37,14 +43,18 @@
// digestOids.put(OIWObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
// digestOids.put(OIWObjectIdentifiers.md4WithRSA, PKCSObjectIdentifiers.md4);
// digestOids.put(OIWObjectIdentifiers.dsaWithSHA1, OIWObjectIdentifiers.idSHA1);
+ // digestOids.put(OIWObjectIdentifiers.md5WithRSA, PKCSObjectIdentifiers.md5);
// END Android-removed: Unsupported algorithms
digestOids.put(OIWObjectIdentifiers.sha1WithRSA, OIWObjectIdentifiers.idSHA1);
+ digestOids.put(PKCSObjectIdentifiers.rsaEncryption, NISTObjectIdentifiers.id_sha256);
digestOids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, NISTObjectIdentifiers.id_sha224);
digestOids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, NISTObjectIdentifiers.id_sha256);
digestOids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, NISTObjectIdentifiers.id_sha384);
digestOids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, NISTObjectIdentifiers.id_sha512);
// BEGIN Android-removed: Unsupported algorithms
+ // digestOids.put(PKCSObjectIdentifiers.sha512_224WithRSAEncryption, NISTObjectIdentifiers.id_sha512_224);
+ // digestOids.put(PKCSObjectIdentifiers.sha512_256WithRSAEncryption, NISTObjectIdentifiers.id_sha512_256);
// digestOids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, PKCSObjectIdentifiers.md2);
// digestOids.put(PKCSObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
// END Android-removed: Unsupported algorithms
@@ -65,6 +75,10 @@
digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, NISTObjectIdentifiers.id_sha256);
digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, NISTObjectIdentifiers.id_sha384);
digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, NISTObjectIdentifiers.id_sha512);
+ digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_224, NISTObjectIdentifiers.id_sha3_224);
+ digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_256, NISTObjectIdentifiers.id_sha3_256);
+ digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_384, NISTObjectIdentifiers.id_sha3_384);
+ digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_512, NISTObjectIdentifiers.id_sha3_512);
digestOids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, TeleTrusTObjectIdentifiers.ripemd160);
digestOids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, OIWObjectIdentifiers.idSHA1);
@@ -114,6 +128,54 @@
digestOids.put(GMObjectIdentifiers.sm2sign_with_sha384, NISTObjectIdentifiers.id_sha384);
digestOids.put(GMObjectIdentifiers.sm2sign_with_sha512, NISTObjectIdentifiers.id_sha512);
digestOids.put(GMObjectIdentifiers.sm2sign_with_sm3, GMObjectIdentifiers.sm3);
+
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(BCObjectIdentifiers.falcon, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.falcon_512, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.falcon_1024, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(BCObjectIdentifiers.picnic_signature, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.picnic_with_sha512, NISTObjectIdentifiers.id_sha512);
+ digestOids.put(BCObjectIdentifiers.picnic_with_sha3_512, NISTObjectIdentifiers.id_sha3_512);
+ digestOids.put(BCObjectIdentifiers.picnic_with_shake256, NISTObjectIdentifiers.id_shake256);
+
+// digestOids.put(GMObjectIdentifiers.sm2sign_with_rmd160, TeleTrusTObjectIdentifiers.ripemd160);
+// digestOids.put(GMObjectIdentifiers.sm2sign_with_sha1, OIWObjectIdentifiers.idSHA1);
+// digestOids.put(GMObjectIdentifiers.sm2sign_with_sha224, NISTObjectIdentifiers.id_sha224);
+ digestOids.put(GMObjectIdentifiers.sm2sign_with_sha256, NISTObjectIdentifiers.id_sha256);
+// digestOids.put(GMObjectIdentifiers.sm2sign_with_sha384, NISTObjectIdentifiers.id_sha384);
+// digestOids.put(GMObjectIdentifiers.sm2sign_with_sha512, NISTObjectIdentifiers.id_sha512);
+ digestOids.put(GMObjectIdentifiers.sm2sign_with_sm3, GMObjectIdentifiers.sm3);
+
+ digestOids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128, NISTObjectIdentifiers.id_shake128);
+ digestOids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(CMSObjectIdentifiers.id_ecdsa_with_shake128, NISTObjectIdentifiers.id_shake128);
+ digestOids.put(CMSObjectIdentifiers.id_ecdsa_with_shake256, NISTObjectIdentifiers.id_shake256);
*/
// END Android-removed: Unsupported algorithms
@@ -140,6 +202,8 @@
digestNameToOids.put("SHA3-384", NISTObjectIdentifiers.id_sha3_384);
digestNameToOids.put("SHA3-512", NISTObjectIdentifiers.id_sha3_512);
+ digestNameToOids.put("SHAKE128", NISTObjectIdentifiers.id_shake128);
+ digestNameToOids.put("SHAKE256", NISTObjectIdentifiers.id_shake256);
digestNameToOids.put("SHAKE-128", NISTObjectIdentifiers.id_shake128);
digestNameToOids.put("SHAKE-256", NISTObjectIdentifiers.id_shake256);
@@ -160,20 +224,106 @@
digestNameToOids.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256);
digestNameToOids.put("SM3", GMObjectIdentifiers.sm3);
+
+ // IETF RFC 3370
+ addDigestAlgId(OIWObjectIdentifiers.idSHA1, true);
+ // IETF RFC 5754
+ addDigestAlgId(NISTObjectIdentifiers.id_sha224, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha256, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha384, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha512, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha512_224, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha512_256, false);
+
+ // NIST CSOR
+ addDigestAlgId(NISTObjectIdentifiers.id_sha3_224, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha3_256, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha3_384, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha3_512, false);
+
+ // RFC 8702
+ addDigestAlgId(NISTObjectIdentifiers.id_shake128, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_shake256, false);
+
+ // RFC 4357
+ addDigestAlgId(CryptoProObjectIdentifiers.gostR3411, true);
+
+ // draft-deremin-rfc4491
+ addDigestAlgId(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256, false);
+ addDigestAlgId(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, false);
+
+ // IETF RFC 1319
+ addDigestAlgId(PKCSObjectIdentifiers.md2, true);
+ // IETF RFC 1320
+ addDigestAlgId(PKCSObjectIdentifiers.md4, true);
+ // IETF RFC 1321
+ addDigestAlgId(PKCSObjectIdentifiers.md5, true);
+
+ // found no standard which specified the handle of AlgorithmIdentifier.parameters,
+ // so let it as before.
+ addDigestAlgId(TeleTrusTObjectIdentifiers.ripemd128, true);
+ addDigestAlgId(TeleTrusTObjectIdentifiers.ripemd160, true);
+ addDigestAlgId(TeleTrusTObjectIdentifiers.ripemd256, true);
+
+ shake256oids.add(EdECObjectIdentifiers.id_Ed448);
+
+ shake256oids.add(BCObjectIdentifiers.dilithium2);
+ shake256oids.add(BCObjectIdentifiers.dilithium3);
+ shake256oids.add(BCObjectIdentifiers.dilithium5);
+ shake256oids.add(BCObjectIdentifiers.dilithium2_aes);
+ shake256oids.add(BCObjectIdentifiers.dilithium3_aes);
+ shake256oids.add(BCObjectIdentifiers.dilithium5_aes);
+
+ shake256oids.add(BCObjectIdentifiers.falcon_512);
+ shake256oids.add(BCObjectIdentifiers.falcon_1024);
*/
// END Android-removed: Unsupported algorithms
}
+ private static void addDigestAlgId(ASN1ObjectIdentifier oid, boolean withNullParams)
+ {
+ AlgorithmIdentifier algId;
+ if (withNullParams)
+ {
+ algId = new AlgorithmIdentifier(oid, DERNull.INSTANCE);
+ }
+ else
+ {
+ algId = new AlgorithmIdentifier(oid);
+ }
+ digestOidToAlgIds.put(oid, algId);
+ }
+
public AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId)
{
- AlgorithmIdentifier digAlgId;
+ ASN1ObjectIdentifier sigAlgOid = sigAlgId.getAlgorithm();
- if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ if (shake256oids.contains(sigAlgOid))
{
- digAlgId = RSASSAPSSparams.getInstance(sigAlgId.getParameters()).getHashAlgorithm();
+ // TODO: it seems it's very hard to find people accepting SHAKE256-len at the moment...
+ // Android-removed: unsupported
+ // if (!sigAlgOid.equals(EdECObjectIdentifiers.id_Ed448))
+ // {
+ // return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256);
+ // }
+
+ return new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256_len, new ASN1Integer(512));
+ }
+
+ ASN1ObjectIdentifier digAlgOid;
+ if (sigAlgOid.equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ digAlgOid = RSASSAPSSparams.getInstance(sigAlgId.getParameters()).getHashAlgorithm().getAlgorithm();
+ }
+ else if (sigAlgOid.equals(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig))
+ {
+ digAlgOid = NISTObjectIdentifiers.id_sha256;
}
// BEGIN Android-removed: Unsupported algorithms
- /*
+ /* // else if (sigAlgOid.equals(EdECObjectIdentifiers.id_Ed25519))
+ {
+ digAlgOid = NISTObjectIdentifiers.id_sha512;
+ }
else if (sigAlgId.getAlgorithm().equals(EdECObjectIdentifiers.id_Ed25519))
{
digAlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512);
@@ -186,14 +336,47 @@
// END Android-removed: Unsupported algorithms
else
{
- digAlgId = new AlgorithmIdentifier((ASN1ObjectIdentifier)digestOids.get(sigAlgId.getAlgorithm()), DERNull.INSTANCE);
+ digAlgOid = (ASN1ObjectIdentifier)digestOids.get(sigAlgOid);
}
- return digAlgId;
+ return find(digAlgOid);
+ }
+
+ public AlgorithmIdentifier find(ASN1ObjectIdentifier digAlgOid)
+ {
+ if (digAlgOid == null)
+ {
+ throw new NullPointerException("digest OID is null");
+ }
+
+ AlgorithmIdentifier digAlgId = (AlgorithmIdentifier)digestOidToAlgIds.get(digAlgOid);
+ if (digAlgId == null)
+ {
+ return new AlgorithmIdentifier(digAlgOid);
+ }
+ else
+ {
+ return digAlgId;
+ }
}
public AlgorithmIdentifier find(String digAlgName)
{
- return new AlgorithmIdentifier((ASN1ObjectIdentifier)digestNameToOids.get(digAlgName), DERNull.INSTANCE);
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)digestNameToOids.get(digAlgName);
+ if (oid != null)
+ {
+ return find(oid);
+ }
+
+ try
+ {
+ return find(new ASN1ObjectIdentifier(digAlgName));
+ }
+ catch (RuntimeException e)
+ {
+ // ignore - tried it but it didn't work...
+ }
+
+ return null;
}
-}
\ No newline at end of file
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultMacAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultMacAlgorithmIdentifierFinder.java
new file mode 100644
index 0000000..75acfed
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultMacAlgorithmIdentifierFinder.java
@@ -0,0 +1,38 @@
+package org.bouncycastle.operator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.bouncycastle.asn1.DERNull;
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.util.Strings;
+
+public class DefaultMacAlgorithmIdentifierFinder
+ implements MacAlgorithmIdentifierFinder
+{
+ private static Map macNameToAlgIds = new HashMap();
+
+ static
+ {
+ macNameToAlgIds.put("HMACSHA1", new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1));
+ macNameToAlgIds.put("HMACSHA224", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA224, DERNull.INSTANCE));
+ macNameToAlgIds.put("HMACSHA256", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA256, DERNull.INSTANCE));
+ macNameToAlgIds.put("HMACSHA384", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA384, DERNull.INSTANCE));
+ macNameToAlgIds.put("HMACSHA512", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA512, DERNull.INSTANCE));
+ macNameToAlgIds.put("HMACSHA512-224", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA512_224, DERNull.INSTANCE));
+ macNameToAlgIds.put("HMACSHA512-256", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA512_256, DERNull.INSTANCE));
+
+ macNameToAlgIds.put("HMACSHA3-224", new AlgorithmIdentifier(NISTObjectIdentifiers.id_hmacWithSHA3_224));
+ macNameToAlgIds.put("HMACSHA3-256", new AlgorithmIdentifier(NISTObjectIdentifiers.id_hmacWithSHA3_256));
+ macNameToAlgIds.put("HMACSHA3-384", new AlgorithmIdentifier(NISTObjectIdentifiers.id_hmacWithSHA3_384));
+ macNameToAlgIds.put("HMACSHA3-512", new AlgorithmIdentifier(NISTObjectIdentifiers.id_hmacWithSHA3_512));
+ }
+
+ public AlgorithmIdentifier find(String macAlgName)
+ {
+ return (AlgorithmIdentifier)macNameToAlgIds.get(Strings.toUpperCase(macAlgName));
+ }
+}
\ 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 9c567b4..8f362af 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
@@ -12,11 +12,13 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
// import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -50,6 +52,7 @@
static
{
// BEGIN Android-removed: Unsupported algorithms
+ // algorithms.put("COMPOSITE", MiscObjectIdentifiers.id_alg_composite);
// algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption);
// algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption);
// END Android-removed: Unsupported algorithms
@@ -65,6 +68,10 @@
algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption);
algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption);
algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption);
+ algorithms.put("SHA512(224)WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512_224WithRSAEncryption);
+ algorithms.put("SHA512(224)WITHRSA", PKCSObjectIdentifiers.sha512_224WithRSAEncryption);
+ algorithms.put("SHA512(256)WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512_256WithRSAEncryption);
+ algorithms.put("SHA512(256)WITHRSA", PKCSObjectIdentifiers.sha512_256WithRSAEncryption);
algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
@@ -132,12 +139,7 @@
algorithms.put("GOST3411-2012-512WITHECGOST3410-2012-512", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512);
algorithms.put("GOST3411-2012-256WITHGOST3410-2012-256", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256);
algorithms.put("GOST3411-2012-512WITHGOST3410-2012-512", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512);
- algorithms.put("SHA1WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA1);
- algorithms.put("SHA224WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA224);
- algorithms.put("SHA256WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA256);
- algorithms.put("SHA384WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA384);
- algorithms.put("SHA512WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA512);
- algorithms.put("RIPEMD160WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_RIPEMD160);
+
algorithms.put("SHA1WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1);
algorithms.put("SHA224WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_224);
algorithms.put("SHA256WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_256);
@@ -155,12 +157,33 @@
algorithms.put("SHA256WITHSM2", GMObjectIdentifiers.sm2sign_with_sha256);
algorithms.put("SHA384WITHSM2", GMObjectIdentifiers.sm2sign_with_sha384);
algorithms.put("SHA512WITHSM2", GMObjectIdentifiers.sm2sign_with_sha512);
+ algorithms.put("SHA1WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA1);
+ algorithms.put("RIPEMD160WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_RIPEMD160);
+ algorithms.put("SHA224WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA224);
+ algorithms.put("SHA256WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA256);
+ algorithms.put("SHA384WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA384);
+ algorithms.put("SHA512WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA512);
+ algorithms.put("SHA3-224WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA3_224);
+ algorithms.put("SHA3-256WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA3_256);
+ algorithms.put("SHA3-384WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA3_384);
+ algorithms.put("SHA3-512WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA3_512);
+
+ // RFC 8702
+ algorithms.put("SHAKE128WITHRSAPSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128);
+ algorithms.put("SHAKE256WITHRSAPSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256);
+ algorithms.put("SHAKE128WITHRSASSA-PSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128);
+ algorithms.put("SHAKE256WITHRSASSA-PSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256);
+ algorithms.put("SHAKE128WITHECDSA", CMSObjectIdentifiers.id_ecdsa_with_shake128);
+ algorithms.put("SHAKE256WITHECDSA", CMSObjectIdentifiers.id_ecdsa_with_shake256);
+
algorithms.put("SM3WITHSM2", GMObjectIdentifiers.sm2sign_with_sm3);
algorithms.put("SHA256WITHXMSS", BCObjectIdentifiers.xmss_SHA256ph);
algorithms.put("SHA512WITHXMSS", BCObjectIdentifiers.xmss_SHA512ph);
algorithms.put("SHAKE128WITHXMSS", BCObjectIdentifiers.xmss_SHAKE128ph);
algorithms.put("SHAKE256WITHXMSS", BCObjectIdentifiers.xmss_SHAKE256ph);
+ algorithms.put("SHAKE128(512)WITHXMSS", BCObjectIdentifiers.xmss_SHAKE128_512ph);
+ algorithms.put("SHAKE256(1024)WITHXMSS", BCObjectIdentifiers.xmss_SHAKE256_1024ph);
algorithms.put("SHA256WITHXMSSMT", BCObjectIdentifiers.xmss_mt_SHA256ph);
algorithms.put("SHA512WITHXMSSMT", BCObjectIdentifiers.xmss_mt_SHA512ph);
@@ -176,6 +199,8 @@
algorithms.put("SHA512WITHXMSSMT-SHA512", BCObjectIdentifiers.xmss_mt_SHA512ph);
algorithms.put("SHAKE128WITHXMSSMT-SHAKE128", BCObjectIdentifiers.xmss_mt_SHAKE128ph);
algorithms.put("SHAKE256WITHXMSSMT-SHAKE256", BCObjectIdentifiers.xmss_mt_SHAKE256ph);
+ algorithms.put("SHAKE128(512)WITHXMSSMT-SHAKE128", BCObjectIdentifiers.xmss_mt_SHAKE128_512ph);
+ algorithms.put("SHAKE256(1024)WITHXMSSMT-SHAKE256", BCObjectIdentifiers.xmss_mt_SHAKE256_1024ph);
algorithms.put("LMS", PKCSObjectIdentifiers.id_alg_hss_lms_hashsig);
@@ -193,6 +218,47 @@
algorithms.put("QTESLA-P-I", BCObjectIdentifiers.qTESLA_p_I);
algorithms.put("QTESLA-P-III", BCObjectIdentifiers.qTESLA_p_III);
+ algorithms.put("SPHINCS+", BCObjectIdentifiers.sphincsPlus);
+ algorithms.put("SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus);
+ algorithms.put("SPHINCS+-SHA2-128S", BCObjectIdentifiers.sphincsPlus_sha2_128s);
+ algorithms.put("SPHINCS+-SHA2-128F", BCObjectIdentifiers.sphincsPlus_sha2_128f);
+ algorithms.put("SPHINCS+-SHA2-192S", BCObjectIdentifiers.sphincsPlus_sha2_192s);
+ algorithms.put("SPHINCS+-SHA2-192F", BCObjectIdentifiers.sphincsPlus_sha2_192f);
+ algorithms.put("SPHINCS+-SHA2-256S", BCObjectIdentifiers.sphincsPlus_sha2_256s);
+ algorithms.put("SPHINCS+-SHA2-256F", BCObjectIdentifiers.sphincsPlus_sha2_256f);
+ algorithms.put("SPHINCS+-SHAKE-128S", BCObjectIdentifiers.sphincsPlus_shake_128s);
+ algorithms.put("SPHINCS+-SHAKE-128F", BCObjectIdentifiers.sphincsPlus_shake_128f);
+ algorithms.put("SPHINCS+-SHAKE-192S", BCObjectIdentifiers.sphincsPlus_shake_192s);
+ algorithms.put("SPHINCS+-SHAKE-192F", BCObjectIdentifiers.sphincsPlus_shake_192f);
+ algorithms.put("SPHINCS+-SHAKE-256S", BCObjectIdentifiers.sphincsPlus_shake_256s);
+ algorithms.put("SPHINCS+-SHAKE-256F", BCObjectIdentifiers.sphincsPlus_shake_256f);
+ algorithms.put("SPHINCS+-HARAKA-128S-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_128s_r3);
+ algorithms.put("SPHINCS+-HARAKA-128F-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_128f_r3);
+ algorithms.put("SPHINCS+-HARAKA-192S-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_192s_r3);
+ algorithms.put("SPHINCS+-HARAKA-192F-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_192f_r3);
+ algorithms.put("SPHINCS+-HARAKA-256S-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_256s_r3);
+ algorithms.put("SPHINCS+-HARAKA-256F-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_256f_r3);
+ algorithms.put("SPHINCS+-HARAKA-128S-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple);
+ algorithms.put("SPHINCS+-HARAKA-128F-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple);
+ algorithms.put("SPHINCS+-HARAKA-192S-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple);
+ algorithms.put("SPHINCS+-HARAKA-192F-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple);
+ algorithms.put("SPHINCS+-HARAKA-256S-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple);
+ algorithms.put("SPHINCS+-HARAKA-256F-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple);
+ algorithms.put("SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus);
+ algorithms.put("DILITHIUM2", BCObjectIdentifiers.dilithium2);
+ algorithms.put("DILITHIUM3", BCObjectIdentifiers.dilithium3);
+ algorithms.put("DILITHIUM5", BCObjectIdentifiers.dilithium5);
+ algorithms.put("DILITHIUM2-AES", BCObjectIdentifiers.dilithium2_aes);
+ algorithms.put("DILITHIUM3-AES", BCObjectIdentifiers.dilithium3_aes);
+ algorithms.put("DILITHIUM5-AES", BCObjectIdentifiers.dilithium5_aes);
+
+ algorithms.put("FALCON-512", BCObjectIdentifiers.falcon_512);
+ algorithms.put("FALCON-1024", BCObjectIdentifiers.falcon_1024);
+
+ algorithms.put("PICNIC", BCObjectIdentifiers.picnic_signature);
+ algorithms.put("SHA512WITHPICNIC", BCObjectIdentifiers.picnic_with_sha512);
+ algorithms.put("SHA3-512WITHPICNIC", BCObjectIdentifiers.picnic_with_sha3_512);
+ algorithms.put("SHAKE256WITHPICNIC", BCObjectIdentifiers.picnic_with_shake256);
*/
// END Android-removed: Unsupported algorithms
@@ -224,6 +290,15 @@
noParams.add(NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
noParams.add(NISTObjectIdentifiers.id_ecdsa_with_sha3_512);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA224);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA256);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA384);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA512);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA3_224);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA3_256);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA3_384);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA3_512);
+
//
// RFC 4491
//
@@ -239,6 +314,67 @@
noParams.add(BCObjectIdentifiers.sphincs256_with_SHA3_512);
//
+ // SPHINCS-PLUS
+ //
+ noParams.add(BCObjectIdentifiers.sphincsPlus);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_128s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_128f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_192s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_192f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_256s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_256f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128f);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_128s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_128f);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_192s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_192f);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_192s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_192f);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_256s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_256f);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_256s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_256f);
+
+ //
+ // Dilithium
+ //
+ noParams.add(BCObjectIdentifiers.dilithium);
+ noParams.add(BCObjectIdentifiers.dilithium2);
+ noParams.add(BCObjectIdentifiers.dilithium3);
+ noParams.add(BCObjectIdentifiers.dilithium5);
+ noParams.add(BCObjectIdentifiers.dilithium2_aes);
+ noParams.add(BCObjectIdentifiers.dilithium3_aes);
+ noParams.add(BCObjectIdentifiers.dilithium5_aes);
+
+ //
+ // Falcon
+ //
+ noParams.add(BCObjectIdentifiers.falcon);
+ noParams.add(BCObjectIdentifiers.falcon_512);
+ noParams.add(BCObjectIdentifiers.falcon_1024);
+
+ //
+ // Picnic
+ //
+ noParams.add(BCObjectIdentifiers.picnic_signature);
+ noParams.add(BCObjectIdentifiers.picnic_with_sha512);
+ noParams.add(BCObjectIdentifiers.picnic_with_sha3_512);
+ noParams.add(BCObjectIdentifiers.picnic_with_shake256);
+
+ //
// XMSS
//
noParams.add(BCObjectIdentifiers.xmss_SHA256ph);
@@ -249,6 +385,8 @@
noParams.add(BCObjectIdentifiers.xmss_mt_SHA512ph);
noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE128ph);
noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE256ph);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE128ph);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE256ph);
noParams.add(BCObjectIdentifiers.xmss_SHA256);
noParams.add(BCObjectIdentifiers.xmss_SHA512);
@@ -282,6 +420,16 @@
noParams.add(EdECObjectIdentifiers.id_Ed25519);
noParams.add(EdECObjectIdentifiers.id_Ed448);
*/
+
+ // EdDSA
+ // noParams.add(EdECObjectIdentifiers.id_Ed25519);
+ // noParams.add(EdECObjectIdentifiers.id_Ed448);
+
+ // RFC 8702
+ // noParams.add(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128);
+ // noParams.add(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256);
+ // noParams.add(CMSObjectIdentifiers.id_ecdsa_with_shake128);
+ // noParams.add(CMSObjectIdentifiers.id_ecdsa_with_shake256);
// END Android-removed: Unsupported algorithms
//
@@ -294,6 +442,8 @@
pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512WithRSAEncryption);
// BEGIN Android-removed: Unsupported algorithms
/*
+ pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512_224WithRSAEncryption);
+ pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512_256WithRSAEncryption);
pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
@@ -357,6 +507,8 @@
// digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, TeleTrusTObjectIdentifiers.ripemd256);
// digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, CryptoProObjectIdentifiers.gostR3411);
// digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, CryptoProObjectIdentifiers.gostR3411);
+ // digestOids.put(PKCSObjectIdentifiers.sha512_224WithRSAEncryption, NISTObjectIdentifiers.id_sha512_224);
+ // digestOids.put(PKCSObjectIdentifiers.sha512_256WithRSAEncryption, NISTObjectIdentifiers.id_sha512_256);
// END Android-removed: Unsupported algorithms
digestOids.put(NISTObjectIdentifiers.dsa_with_sha224, NISTObjectIdentifiers.id_sha224);
digestOids.put(NISTObjectIdentifiers.dsa_with_sha256, NISTObjectIdentifiers.id_sha256);
@@ -400,37 +552,54 @@
digestOids.put(GMObjectIdentifiers.sm2sign_with_sha384, NISTObjectIdentifiers.id_sha384);
digestOids.put(GMObjectIdentifiers.sm2sign_with_sha512, NISTObjectIdentifiers.id_sha512);
digestOids.put(GMObjectIdentifiers.sm2sign_with_sm3, GMObjectIdentifiers.sm3);
+
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128, NISTObjectIdentifiers.id_shake128);
+ digestOids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(CMSObjectIdentifiers.id_ecdsa_with_shake128, NISTObjectIdentifiers.id_shake128);
+ digestOids.put(CMSObjectIdentifiers.id_ecdsa_with_shake256, NISTObjectIdentifiers.id_shake256);
*/
// END Android-removed: Unsupported algorithms
}
- private static AlgorithmIdentifier generate(String signatureAlgorithm)
- {
- AlgorithmIdentifier sigAlgId;
-
- String algorithmName = Strings.toUpperCase(signatureAlgorithm);
- ASN1ObjectIdentifier sigOID = (ASN1ObjectIdentifier)algorithms.get(algorithmName);
- if (sigOID == null)
- {
- throw new IllegalArgumentException("Unknown signature type requested: " + algorithmName);
- }
-
- if (noParams.contains(sigOID))
- {
- sigAlgId = new AlgorithmIdentifier(sigOID);
- }
- else if (params.containsKey(algorithmName))
- {
- sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable)params.get(algorithmName));
- }
- else
- {
- sigAlgId = new AlgorithmIdentifier(sigOID, DERNull.INSTANCE);
- }
-
- return sigAlgId;
- }
-
private static RSASSAPSSparams createPSSParams(AlgorithmIdentifier hashAlgId, int saltSize)
{
return new RSASSAPSSparams(
@@ -442,6 +611,26 @@
public AlgorithmIdentifier find(String sigAlgName)
{
- return generate(sigAlgName);
+ String algorithmName = Strings.toUpperCase(sigAlgName);
+ ASN1ObjectIdentifier sigOID = (ASN1ObjectIdentifier)algorithms.get(algorithmName);
+ if (sigOID == null)
+ {
+ throw new IllegalArgumentException("Unknown signature type requested: " + sigAlgName);
+ }
+
+ AlgorithmIdentifier sigAlgId;
+ if (noParams.contains(sigOID))
+ {
+ sigAlgId = new AlgorithmIdentifier(sigOID);
+ }
+ else if (params.containsKey(algorithmName))
+ {
+ sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable)params.get(algorithmName));
+ }
+ else
+ {
+ sigAlgId = new AlgorithmIdentifier(sigOID, DERNull.INSTANCE);
+ }
+ return sigAlgId;
}
-}
\ No newline at end of file
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureNameFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureNameFinder.java
new file mode 100644
index 0000000..3bfc50d
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureNameFinder.java
@@ -0,0 +1,170 @@
+package org.bouncycastle.operator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+// BEGIN Android-removed: unsupported algorithms
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.DERNull;
+// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
+// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
+// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers;
+import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+// END Android-removed: unsupported algorithms
+
+/**
+ * Class for return signature names from OIDs or AlgorithmIdentifiers
+ */
+public class DefaultSignatureNameFinder
+ implements AlgorithmNameFinder
+{
+ private static final Map oids = new HashMap();
+ private static final Map digests = new HashMap();
+
+ static
+ {
+ //
+ // reverse mappings
+ //
+ // BEGIN Android-removed: unsupported algorithms
+ oids.put(PKCSObjectIdentifiers.id_RSASSA_PSS, "RSASSA-PSS");
+ // oids.put(EdECObjectIdentifiers.id_Ed25519, "ED25519");
+ // oids.put(EdECObjectIdentifiers.id_Ed448, "ED448");
+ oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA");
+ // oids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128, "SHAKE128WITHRSAPSS");
+ // oids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256, "SHAKE256WITHRSAPSS");
+ // oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410");
+ // oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410");
+ // oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "GOST3411-2012-256WITHECGOST3410-2012-256");
+ // oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "GOST3411-2012-512WITHECGOST3410-2012-512");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_224, "SHA3-224WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_256, "SHA3-256WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_384, "SHA3-384WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_512, "SHA3-512WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160WITHPLAIN-ECDSA");
+ // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1WITHCVC-ECDSA");
+ // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224WITHCVC-ECDSA");
+ // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256WITHCVC-ECDSA");
+ // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384WITHCVC-ECDSA");
+ // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512WITHCVC-ECDSA");
+ oids.put(IsaraObjectIdentifiers.id_alg_xmss, "XMSS");
+ oids.put(IsaraObjectIdentifiers.id_alg_xmssmt, "XMSSMT");
+ oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, "RIPEMD128WITHRSA");
+ oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, "RIPEMD160WITHRSA");
+ oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, "RIPEMD256WITHRSA");
+ oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA");
+ oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA");
+ oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA");
+ // oids.put(CMSObjectIdentifiers.id_ecdsa_with_shake128, "SHAKE128WITHECDSA");
+ // oids.put(CMSObjectIdentifiers.id_ecdsa_with_shake256, "SHAKE256WITHECDSA");
+ oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
+ oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA");
+ oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA");
+ oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA");
+ // END Android-removed: unsupported algorithms
+
+ digests.put(OIWObjectIdentifiers.idSHA1, "SHA1");
+ digests.put(NISTObjectIdentifiers.id_sha224, "SHA224");
+ digests.put(NISTObjectIdentifiers.id_sha256, "SHA256");
+ digests.put(NISTObjectIdentifiers.id_sha384, "SHA384");
+ digests.put(NISTObjectIdentifiers.id_sha512, "SHA512");
+ digests.put(NISTObjectIdentifiers.id_sha3_224, "SHA3-224");
+ digests.put(NISTObjectIdentifiers.id_sha3_256, "SHA3-256");
+ digests.put(NISTObjectIdentifiers.id_sha3_384, "SHA3-384");
+ digests.put(NISTObjectIdentifiers.id_sha3_512, "SHA3-512");
+ digests.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD128");
+ digests.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160");
+ digests.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256");
+ }
+
+ public boolean hasAlgorithmName(ASN1ObjectIdentifier objectIdentifier)
+ {
+ return oids.containsKey(objectIdentifier);
+ }
+
+ public String getAlgorithmName(ASN1ObjectIdentifier objectIdentifier)
+ {
+ String name = (String)oids.get(objectIdentifier);
+ if (name != null)
+ {
+ return name;
+ }
+ return objectIdentifier.getId();
+ }
+
+ /**
+ * Return the signature name for the passed in algorithm identifier. For signatures
+ * that require parameters, like RSASSA-PSS, this is the best one to use.
+ *
+ * @param algorithmIdentifier the AlgorithmIdentifier of interest.
+ * @return a string representation of the name.
+ */
+ public String getAlgorithmName(AlgorithmIdentifier algorithmIdentifier)
+ {
+ ASN1Encodable params = algorithmIdentifier.getParameters();
+ if (params != null && !DERNull.INSTANCE.equals(params))
+ {
+ if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
+ AlgorithmIdentifier mgfAlg = rsaParams.getMaskGenAlgorithm();
+ if (mgfAlg.getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1))
+ {
+ AlgorithmIdentifier digAlg = rsaParams.getHashAlgorithm();
+ ASN1ObjectIdentifier mgfHashOid = AlgorithmIdentifier.getInstance(mgfAlg.getParameters()).getAlgorithm();
+ if (mgfHashOid.equals(digAlg.getAlgorithm()))
+ {
+ return getDigestName(digAlg.getAlgorithm()) + "WITHRSAANDMGF1";
+ }
+ else
+ {
+ return getDigestName(digAlg.getAlgorithm()) + "WITHRSAANDMGF1USING" + getDigestName(mgfHashOid);
+ }
+ }
+ return getDigestName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAAND" + mgfAlg.getAlgorithm().getId();
+ }
+ }
+
+ if (oids.containsKey(algorithmIdentifier.getAlgorithm()))
+ {
+ return (String)oids.get(algorithmIdentifier.getAlgorithm());
+ }
+
+ return algorithmIdentifier.getAlgorithm().getId();
+ }
+
+ private static String getDigestName(ASN1ObjectIdentifier oid)
+ {
+ String name = (String)digests.get(oid);
+ if (name != null)
+ {
+ return name;
+ }
+ return oid.getId();
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java
index b2d57c6..de2d680 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java
@@ -1,5 +1,6 @@
package org.bouncycastle.operator;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
public interface DigestAlgorithmIdentifierFinder
@@ -15,6 +16,15 @@
/**
* Find the algorithm identifier that matches with
+ * the passed in digest OID.
+ *
+ * @param digestOid the OID of the digest algorithm of interest.
+ * @return an algorithm identifier for the digest signature.
+ */
+ AlgorithmIdentifier find(ASN1ObjectIdentifier digestOid);
+
+ /**
+ * Find the algorithm identifier that matches with
* the passed in digest name.
*
* @param digAlgName the name of the digest algorithm of interest.
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/InputAEADDecryptor.java b/bcpkix/src/main/java/org/bouncycastle/operator/InputAEADDecryptor.java
new file mode 100644
index 0000000..88adef4
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/InputAEADDecryptor.java
@@ -0,0 +1,9 @@
+package org.bouncycastle.operator;
+
+/**
+ * Base interface for an input consuming AEAD Decryptor supporting associated text.
+ */
+public interface InputAEADDecryptor
+ extends InputDecryptor, AADProcessor
+{
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/MacAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/MacAlgorithmIdentifierFinder.java
new file mode 100644
index 0000000..7a09504
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/MacAlgorithmIdentifierFinder.java
@@ -0,0 +1,15 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface MacAlgorithmIdentifierFinder
+{
+ /**
+ * Find the algorithm identifier that matches with
+ * the passed in digest name.
+ *
+ * @param macAlgName the name of the digest algorithm of interest.
+ * @return an algorithm identifier for the MAC.
+ */
+ AlgorithmIdentifier find(String macAlgName);
+}
\ No newline at end of file
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/MacCaptureStream.java b/bcpkix/src/main/java/org/bouncycastle/operator/MacCaptureStream.java
new file mode 100644
index 0000000..ae44153
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/MacCaptureStream.java
@@ -0,0 +1,67 @@
+package org.bouncycastle.operator;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.bouncycastle.util.Arrays;
+
+/**
+ * A generic class for capturing the mac data at the end of a encrypted data stream.
+ * <p>
+ * Note: this class will not close the underlying stream.
+ * </p>
+ */
+public class MacCaptureStream
+ extends OutputStream
+{
+ private final OutputStream cOut;
+ private final byte[] mac;
+
+ int macIndex = 0;
+
+ public MacCaptureStream(OutputStream cOut, int macLength)
+ {
+ this.cOut = cOut;
+ this.mac = new byte[macLength];
+ }
+
+ public void write(byte[] buf, int off, int len)
+ throws IOException
+ {
+ if (len >= mac.length)
+ {
+ cOut.write(mac, 0, macIndex);
+ macIndex = mac.length;
+ System.arraycopy(buf, off + len - mac.length, mac, 0, mac.length);
+ cOut.write(buf, off, len - mac.length);
+ }
+ else
+ {
+ for (int i = 0; i != len; i++)
+ {
+ write(buf[off + i]);
+ }
+ }
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ if (macIndex == mac.length)
+ {
+ byte b1 = mac[0];
+ System.arraycopy(mac, 1, mac, 0, mac.length - 1);
+ mac[mac.length - 1] = (byte)b;
+ cOut.write(b1);
+ }
+ else
+ {
+ mac[macIndex++] = (byte)b;
+ }
+ }
+
+ public byte[] getMac()
+ {
+ return Arrays.clone(mac);
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/PBEMacCalculatorProvider.java b/bcpkix/src/main/java/org/bouncycastle/operator/PBEMacCalculatorProvider.java
new file mode 100644
index 0000000..b6b9f61
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/PBEMacCalculatorProvider.java
@@ -0,0 +1,9 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface PBEMacCalculatorProvider
+{
+ MacCalculator get(AlgorithmIdentifier algorithm, char[] password)
+ throws OperatorCreationException;
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
index a5f0a7b..d0e8aa55 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
@@ -6,6 +6,9 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.ASN1Integer;
+// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -14,6 +17,25 @@
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.crypto.ExtendedDigest;
import org.bouncycastle.crypto.digests.*;
+// import org.bouncycastle.crypto.Xof;
+// import org.bouncycastle.crypto.digests.Blake3Digest;
+// import org.bouncycastle.crypto.digests.GOST3411Digest;
+// import org.bouncycastle.crypto.digests.GOST3411_2012_256Digest;
+// import org.bouncycastle.crypto.digests.GOST3411_2012_512Digest;
+// import org.bouncycastle.crypto.digests.MD2Digest;
+// import org.bouncycastle.crypto.digests.MD4Digest;
+// import org.bouncycastle.crypto.digests.MD5Digest;
+// import org.bouncycastle.crypto.digests.RIPEMD128Digest;
+// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
+// import org.bouncycastle.crypto.digests.RIPEMD256Digest;
+// import org.bouncycastle.crypto.digests.SHA1Digest;
+// import org.bouncycastle.crypto.digests.SHA224Digest;
+// import org.bouncycastle.crypto.digests.SHA256Digest;
+// import org.bouncycastle.crypto.digests.SHA384Digest;
+// import org.bouncycastle.crypto.digests.SHA3Digest;
+// import org.bouncycastle.crypto.digests.SHA512Digest;
+// import org.bouncycastle.crypto.digests.SHAKEDigest;
+// import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.operator.OperatorCreationException;
public class BcDefaultDigestProvider
@@ -90,6 +112,34 @@
return new SHA3Digest(512);
}
});
+ table.put(NISTObjectIdentifiers.id_shake128, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHAKEDigest(128);
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_shake256, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHAKEDigest(256);
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_shake128_len, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new AdjustedXof(new SHAKEDigest(128), ASN1Integer.getInstance(digestAlgorithmIdentifier.getParameters()).intValueExact());
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_shake256_len, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new AdjustedXof(new SHAKEDigest(256), ASN1Integer.getInstance(digestAlgorithmIdentifier.getParameters()).intValueExact());
+ }
+ });
table.put(PKCSObjectIdentifiers.md5, new BcDigestProvider()
{
public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
@@ -153,6 +203,20 @@
return new RIPEMD256Digest();
}
});
+ table.put(GMObjectIdentifiers.sm3, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SM3Digest();
+ }
+ });
+ table.put(MiscObjectIdentifiers.blake3_256, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new Blake3Digest(256);
+ }
+ });
*/
// END Android-removed: Unsupported algorithms
@@ -178,4 +242,69 @@
return extProv.get(digestAlgorithmIdentifier);
}
+
+ /**
+ * -len OIDs for SHAKE include an integer representing the bitlength in of the output.
+ */
+ // BEGIN Android-removed: unused
+ /*
+ private static class AdjustedXof
+ implements Xof
+ {
+ private final Xof xof;
+ private final int length;
+
+ AdjustedXof(Xof xof, int length)
+ {
+ this.xof = xof;
+ this.length = length;
+ }
+
+ public String getAlgorithmName()
+ {
+ return xof.getAlgorithmName() + "-" + length;
+ }
+
+ public int getDigestSize()
+ {
+ return (length + 7) / 8;
+ }
+
+ public void update(byte in)
+ {
+ xof.update(in);
+ }
+
+ public void update(byte[] in, int inOff, int len)
+ {
+ xof.update(in, inOff, len);
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ {
+ return doFinal(out, outOff, getDigestSize());
+ }
+
+ public void reset()
+ {
+ xof.reset();
+ }
+
+ public int getByteLength()
+ {
+ return xof.getByteLength();
+ }
+
+ public int doFinal(byte[] out, int outOff, int outLen)
+ {
+ return xof.doFinal(out, outOff, outLen);
+ }
+
+ public int doOutput(byte[] out, int outOff, int outLen)
+ {
+ return xof.doOutput(out, outOff, outLen);
+ }
+ }
+ */
+ // END Android-removed: unused
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
index b01b370..61901a9 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
@@ -40,7 +40,7 @@
};
}
- private class DigestOutputStream
+ private static class DigestOutputStream
extends OutputStream
{
private Digest dig;
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
index f219b11..d3e2b92 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
@@ -11,16 +11,20 @@
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PSSParameterSpec;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERBitString;
+import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.jcajce.CompositePrivateKey;
@@ -36,21 +40,31 @@
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.RuntimeOperatorException;
import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder;
+import org.bouncycastle.util.Strings;
import org.bouncycastle.util.io.TeeOutputStream;
public class JcaContentSignerBuilder
{
+ private static final Set isAlgIdFromPrivate = new HashSet();
+
+ static
+ {
+ isAlgIdFromPrivate.add("DILITHIUM");
+ isAlgIdFromPrivate.add("SPHINCS+");
+ isAlgIdFromPrivate.add("SPHINCSPlus");
+ }
+
+ private final String signatureAlgorithm;
+
private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
private SecureRandom random;
- private String signatureAlgorithm;
+
private AlgorithmIdentifier sigAlgId;
private AlgorithmParameterSpec sigAlgSpec;
public JcaContentSignerBuilder(String signatureAlgorithm)
{
this.signatureAlgorithm = signatureAlgorithm;
- this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm);
- this.sigAlgSpec = null;
}
public JcaContentSignerBuilder(String signatureAlgorithm, AlgorithmParameterSpec sigParamSpec)
@@ -111,8 +125,21 @@
try
{
- final Signature sig = helper.createSignature(sigAlgId);
+ if (sigAlgSpec == null)
+ {
+ if (isAlgIdFromPrivate.contains(Strings.toUpperCase(signatureAlgorithm)))
+ {
+ sigAlgId = PrivateKeyInfo.getInstance(privateKey.getEncoded()).getPrivateKeyAlgorithm();
+ this.sigAlgSpec = null;
+ }
+ else
+ {
+ this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm);
+ this.sigAlgSpec = null;
+ }
+ }
final AlgorithmIdentifier signatureAlgId = sigAlgId;
+ final Signature sig = helper.createSignature(sigAlgId);
if (random != null)
{
@@ -234,8 +261,16 @@
private static RSASSAPSSparams createPSSParams(PSSParameterSpec pssSpec)
{
DigestAlgorithmIdentifierFinder digFinder = new DefaultDigestAlgorithmIdentifierFinder();
- AlgorithmIdentifier digId = digFinder.find(pssSpec.getDigestAlgorithm());
- AlgorithmIdentifier mgfDig = digFinder.find(((MGF1ParameterSpec)pssSpec.getMGFParameters()).getDigestAlgorithm());
+ AlgorithmIdentifier digId = digFinder.find(pssSpec.getDigestAlgorithm());
+ if (digId.getParameters() == null)
+ {
+ digId = new AlgorithmIdentifier(digId.getAlgorithm(), DERNull.INSTANCE);
+ }
+ AlgorithmIdentifier mgfDig = digFinder.find(((MGF1ParameterSpec)pssSpec.getMGFParameters()).getDigestAlgorithm());
+ if (mgfDig.getParameters() == null)
+ {
+ mgfDig = new AlgorithmIdentifier(mgfDig.getAlgorithm(), DERNull.INSTANCE);
+ }
return new RSASSAPSSparams(
digId,
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
index 8f2102b..c44a24a 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
@@ -11,8 +11,8 @@
import java.security.cert.X509Certificate;
import java.util.List;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Sequence;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
@@ -278,7 +278,7 @@
return rawSig;
}
- private class SigVerifier
+ private static class SigVerifier
implements ContentVerifier
{
private final AlgorithmIdentifier algorithm;
@@ -321,7 +321,7 @@
}
}
- private class RawSigVerifier
+ private static class RawSigVerifier
extends SigVerifier
implements RawContentVerifier
{
@@ -382,7 +382,7 @@
}
}
- private class CompositeVerifier
+ private static class CompositeVerifier
implements ContentVerifier
{
private Signature[] sigs;
@@ -433,7 +433,7 @@
{
if (sigs[i] != null)
{
- if (!sigs[i].verify(DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes()))
+ if (!sigs[i].verify(ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes()))
{
failed = true;
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java
index e356796..6494bf3 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java
@@ -8,6 +8,7 @@
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
import org.bouncycastle.operator.DigestCalculator;
@@ -22,6 +23,14 @@
{
}
+
+ public JcaDigestCalculatorProviderBuilder setHelper(JcaJceHelper helper)
+ {
+ this.helper = new OperatorHelper(helper);
+
+ return this;
+ }
+
public JcaDigestCalculatorProviderBuilder setProvider(Provider provider)
{
this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
@@ -63,7 +72,7 @@
{
return algorithm;
}
-
+
public OutputStream getOutputStream()
{
return stream;
@@ -78,7 +87,7 @@
};
}
- private class DigestOutputStream
+ private static class DigestOutputStream
extends OutputStream
{
private MessageDigest dig;
@@ -97,13 +106,13 @@
public void write(byte[] bytes)
throws IOException
{
- dig.update(bytes);
+ dig.update(bytes);
}
public void write(int b)
throws IOException
{
- dig.update((byte)b);
+ dig.update((byte)b);
}
byte[] getDigest()
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 eb8b2d5..c3d2c85 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
@@ -44,12 +44,12 @@
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.jcajce.util.AlgorithmParametersUtils;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jcajce.util.MessageDigestUtils;
+import org.bouncycastle.operator.DefaultSignatureNameFinder;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.util.Integers;
@@ -61,54 +61,10 @@
private static final Map symmetricKeyAlgNames = new HashMap();
private static final Map symmetricWrapperKeySizes = new HashMap();
+ private static DefaultSignatureNameFinder sigFinder = new DefaultSignatureNameFinder();
+
static
{
- //
- // reverse mappings
- //
- oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA");
- oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA");
- oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA");
- oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA");
- oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA");
- // BEGIN Android-removed: Unsupported algorithms
- /*
- oids.put(EdECObjectIdentifiers.id_Ed25519, "Ed25519");
- oids.put(EdECObjectIdentifiers.id_Ed448, "Ed448");
- oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410");
- oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410");
- oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "GOST3411-2012-256WITHECGOST3410-2012-256");
- oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "GOST3411-2012-512WITHECGOST3410-2012-512");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160WITHPLAIN-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512WITHCVC-ECDSA");
- oids.put(IsaraObjectIdentifiers.id_alg_xmss, "XMSS");
- oids.put(IsaraObjectIdentifiers.id_alg_xmssmt, "XMSSMT");
- */
- // END Android-removed: Unsupported algorithms
-
- oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA");
- // BEGIN Android-removed: Unsupported algorithms
- // oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA");
- // END Android-removed: Unsupported algorithms
- oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA");
- oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA");
- oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA");
- oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA");
- oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA");
- oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA");
- oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
- oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA");
- oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA");
- oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA");
oids.put(OIWObjectIdentifiers.idSHA1, "SHA1");
oids.put(NISTObjectIdentifiers.id_sha224, "SHA224");
@@ -124,6 +80,8 @@
// END Android-removed: Unsupported algorithms
asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding");
+ asymmetricWrapperAlgNames.put(OIWObjectIdentifiers.elGamalAlgorithm, "Elgamal/ECB/PKCS1Padding");
+ asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_RSAES_OAEP, "RSA/ECB/OAEPPadding");
// Android-removed: Unsupported algorithms
// asymmetricWrapperAlgNames.put(CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410");
@@ -321,24 +279,43 @@
AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
throws OperatorCreationException
{
- AlgorithmParameters parameters;
+ AlgorithmParameters parameters = null;
if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
{
return null;
}
- try
+ if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSAES_OAEP))
{
- parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
+ try
+ {
+ parameters = helper.createAlgorithmParameters("OAEP");
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // try below
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
+ }
}
- catch (NoSuchAlgorithmException e)
+
+ if (parameters == null)
{
- return null; // There's a good chance there aren't any!
- }
- catch (NoSuchProviderException e)
- {
- throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
+ try
+ {
+ parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ return null; // There's a good chance there aren't any!
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
+ }
}
try
@@ -364,6 +341,10 @@
{
dig = helper.createMessageDigest("SHAKE256-" + ASN1Integer.getInstance(digAlgId.getParameters()).getValue());
}
+ else if (digAlgId.getAlgorithm().equals(NISTObjectIdentifiers.id_shake128_len))
+ {
+ dig = helper.createMessageDigest("SHAKE128-" + ASN1Integer.getInstance(digAlgId.getParameters()).getValue());
+ }
else
{
dig = helper.createMessageDigest(MessageDigestUtils.getDigestName(digAlgId.getAlgorithm()));
@@ -411,12 +392,6 @@
sig = helper.createSignature(signatureAlgorithm);
}
- else if (oids.get(sigAlgId.getAlgorithm()) != null)
- {
- String signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm());
-
- sig = helper.createSignature(signatureAlgorithm);
- }
else
{
throw e;
@@ -447,7 +422,7 @@
return sig;
}
- public Signature createRawSignature(AlgorithmIdentifier algorithm)
+ Signature createRawSignature(AlgorithmIdentifier algorithm)
{
Signature sig;
@@ -483,27 +458,11 @@
private static String getSignatureName(
AlgorithmIdentifier sigAlgId)
{
- ASN1Encodable params = sigAlgId.getParameters();
-
- if (params != null && !DERNull.INSTANCE.equals(params))
- {
- if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
- {
- RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
- return getDigestName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1";
- }
- }
-
- if (oids.containsKey(sigAlgId.getAlgorithm()))
- {
- return (String)oids.get(sigAlgId.getAlgorithm());
- }
-
- return sigAlgId.getAlgorithm().getId();
+ return sigFinder.getAlgorithmName(sigAlgId);
}
// we need to remove the - to create a correct signature name
- private static String getDigestName(ASN1ObjectIdentifier oid)
+ static String getDigestName(ASN1ObjectIdentifier oid)
{
String name = MessageDigestUtils.getDigestName(oid);
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/DeltaCertAttributeUtils.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/DeltaCertAttributeUtils.java
new file mode 100644
index 0000000..627780b
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/DeltaCertAttributeUtils.java
@@ -0,0 +1,65 @@
+package org.bouncycastle.pkcs;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERSet;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.pkcs.Attribute;
+import org.bouncycastle.asn1.pkcs.CertificationRequest;
+import org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.operator.ContentVerifierProvider;
+
+public class DeltaCertAttributeUtils
+{
+ public static Extension makeDeltaCertificateExtension(DeltaCertificateRequestAttributeValue deltaReqAttr)
+ throws IOException
+ {
+ return null;
+ }
+
+ public static boolean isDeltaRequestSignatureValid(PKCS10CertificationRequest baseRequest, ContentVerifierProvider contentVerifierProvider)
+ throws PKCSException
+ {
+ Attribute[] attributes = baseRequest.getAttributes(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.2"));
+
+ DeltaCertificateRequestAttributeValue deltaReq = new DeltaCertificateRequestAttributeValue(attributes[0]);
+
+ attributes = baseRequest.getAttributes(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.3"));
+
+ CertificationRequest deltaPkcs10 = baseRequest.toASN1Structure();
+ CertificationRequestInfo deltaInfo = deltaPkcs10.getCertificationRequestInfo();
+
+ ASN1EncodableVector deltaPkcs10InfoV = new ASN1EncodableVector();
+ deltaPkcs10InfoV.add(deltaInfo.getVersion());
+ deltaPkcs10InfoV.add(deltaInfo.getSubject());
+ deltaPkcs10InfoV.add(deltaInfo.getSubjectPublicKeyInfo());
+
+ ASN1EncodableVector attrSetV = new ASN1EncodableVector();
+ for (Enumeration en = deltaInfo.getAttributes().getObjects(); en.hasMoreElements();)
+ {
+ Attribute attr = Attribute.getInstance(en.nextElement());
+
+ if (!attr.getAttrType().equals(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.3")))
+ {
+ attrSetV.add(attr);
+ }
+ }
+
+ deltaPkcs10InfoV.add(new DERTaggedObject(false, 0, new DERSet(attrSetV)));
+
+ ASN1EncodableVector deltaPkcs10V = new ASN1EncodableVector();
+
+ deltaPkcs10V.add(new DERSequence(deltaPkcs10InfoV));
+ deltaPkcs10V.add(deltaReq.getSignatureAlgorithm());
+ deltaPkcs10V.add(attributes[0].getAttributeValues()[0]);
+
+ PKCS10CertificationRequest deltaPkcs10Req = new PKCS10CertificationRequest(CertificationRequest.getInstance(new DERSequence(deltaPkcs10V)));
+
+ return deltaPkcs10Req.isSignatureValid(contentVerifierProvider);
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValue.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValue.java
new file mode 100644
index 0000000..58aec1d
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValue.java
@@ -0,0 +1,102 @@
+package org.bouncycastle.pkcs;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.pkcs.Attribute;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.Extensions;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+
+/**
+ * The delta certificate request attribute defined in: https://datatracker.ietf.org/doc/draft-bonnell-lamps-chameleon-certs/
+ */
+public class DeltaCertificateRequestAttributeValue
+ implements ASN1Encodable
+{
+ private final X500Name subject;
+ private final SubjectPublicKeyInfo subjectPKInfo;
+ private final Extensions extensions;
+ private final AlgorithmIdentifier signatureAlgorithm;
+ private final ASN1Sequence attrSeq;
+
+ public DeltaCertificateRequestAttributeValue(Attribute attribute)
+ {
+ this(ASN1Sequence.getInstance(attribute.getAttributeValues()[0]));
+ }
+
+ DeltaCertificateRequestAttributeValue(ASN1Sequence attrSeq)
+ {
+ this.attrSeq = attrSeq;
+ // TODO: validate attribute size
+
+ int idx = 0;
+ if (attrSeq.getObjectAt(0) instanceof ASN1TaggedObject)
+ {
+ subject = X500Name.getInstance(ASN1TaggedObject.getInstance(attrSeq.getObjectAt(0)), true);
+ idx++;
+ }
+ else
+ {
+ subject = null;
+ }
+
+ subjectPKInfo = SubjectPublicKeyInfo.getInstance(attrSeq.getObjectAt(idx));
+ idx++;
+
+ Extensions ext = null;
+ AlgorithmIdentifier sigAlg = null;
+
+ if (idx != attrSeq.size())
+ {
+ while (idx < attrSeq.size())
+ {
+ ASN1TaggedObject tagObj = ASN1TaggedObject.getInstance(attrSeq.getObjectAt(idx));
+ if (tagObj.getTagNo() == 1)
+ {
+ ext = Extensions.getInstance(tagObj, false);
+ }
+ else if (tagObj.getTagNo() == 2)
+ {
+ sigAlg = AlgorithmIdentifier.getInstance(tagObj, false);
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown tag");
+ }
+ idx++;
+ }
+ }
+
+ this.extensions = ext;
+ this.signatureAlgorithm = sigAlg;
+ }
+
+ public X500Name getSubject()
+ {
+ return subject;
+ }
+
+ public SubjectPublicKeyInfo getSubjectPKInfo()
+ {
+ return subjectPKInfo;
+ }
+
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return signatureAlgorithm;
+ }
+
+ @Override
+ public ASN1Primitive toASN1Primitive()
+ {
+ return attrSeq;
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValueBuilder.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValueBuilder.java
new file mode 100644
index 0000000..1c844f2
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValueBuilder.java
@@ -0,0 +1,57 @@
+package org.bouncycastle.pkcs;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERSet;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.pkcs.Attribute;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+
+public class DeltaCertificateRequestAttributeValueBuilder
+{
+ private final SubjectPublicKeyInfo subjectPublicKey;
+
+ private AlgorithmIdentifier signatureAlgorithm;
+ private X500Name subject;
+
+ public DeltaCertificateRequestAttributeValueBuilder(SubjectPublicKeyInfo subjectPublicKey)
+ {
+ this.subjectPublicKey = subjectPublicKey;
+ }
+
+ public DeltaCertificateRequestAttributeValueBuilder setSignatureAlgorithm(AlgorithmIdentifier signatureAlgorithm)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+
+ return this;
+ }
+
+ public DeltaCertificateRequestAttributeValueBuilder setSubject(X500Name subject)
+ {
+ this.subject = subject;
+
+ return this;
+ }
+
+ public DeltaCertificateRequestAttributeValue build()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (subject != null)
+ {
+ v.add(new DERTaggedObject(false, 0, subject));
+ }
+ v.add(subjectPublicKey);
+ if (signatureAlgorithm != null)
+ {
+ v.add(new DERTaggedObject(false, 2, signatureAlgorithm));
+ }
+
+
+ return new DeltaCertificateRequestAttributeValue(new Attribute(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.2"),
+ new DERSet(new DERSequence(v))));
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequest.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequest.java
new file mode 100644
index 0000000..67ebd62
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequest.java
@@ -0,0 +1,435 @@
+package org.bouncycastle.pkcs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.bouncycastle.asn1.ASN1BitString;
+import org.bouncycastle.asn1.ASN1Boolean;
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1Set;
+import org.bouncycastle.asn1.DERSet;
+import org.bouncycastle.asn1.pkcs.Attribute;
+import org.bouncycastle.asn1.pkcs.CertificationRequest;
+import org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.Extensions;
+import org.bouncycastle.asn1.x509.ExtensionsGenerator;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.operator.ContentVerifier;
+import org.bouncycastle.operator.ContentVerifierProvider;
+import org.bouncycastle.util.Exceptions;
+
+/**
+ * Holding class for a PKCS#10 certification request.
+ */
+public class PKCS10CertificationRequest
+{
+ private static Attribute[] EMPTY_ARRAY = new Attribute[0];
+
+ private final CertificationRequest certificationRequest;
+ private final boolean isAltRequest;
+ private final AlgorithmIdentifier altSignature;
+ private final SubjectPublicKeyInfo altPublicKey;
+ private final ASN1BitString altSignatureValue;
+
+ private static CertificationRequest parseBytes(byte[] encoding)
+ throws IOException
+ {
+ try
+ {
+ CertificationRequest rv = CertificationRequest.getInstance(ASN1Primitive.fromByteArray(encoding));
+
+ if (rv == null)
+ {
+ throw new PKCSIOException("empty data passed to constructor");
+ }
+
+ return rv;
+ }
+ catch (ClassCastException e)
+ {
+ throw new PKCSIOException("malformed data: " + e.getMessage(), e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new PKCSIOException("malformed data: " + e.getMessage(), e);
+ }
+ }
+
+ private static ASN1Encodable getSingleValue(Attribute at)
+ {
+ ASN1Encodable[] attrValues = at.getAttributeValues();
+ if (attrValues.length!= 1)
+ {
+ throw new IllegalArgumentException("single value attribute value not size of 1");
+ }
+
+ return attrValues[0];
+ }
+
+ /**
+ * Create a PKCS10CertificationRequestHolder from an underlying ASN.1 structure.
+ *
+ * @param certificationRequest the underlying ASN.1 structure representing a request.
+ */
+ public PKCS10CertificationRequest(CertificationRequest certificationRequest)
+ {
+ if (certificationRequest == null)
+ {
+ throw new NullPointerException("certificationRequest cannot be null");
+ }
+ this.certificationRequest = certificationRequest;
+
+ ASN1Set attributes = certificationRequest.getCertificationRequestInfo().getAttributes();
+
+ AlgorithmIdentifier altSig = null;
+ SubjectPublicKeyInfo altPub = null;
+ ASN1BitString altSigValue = null;
+
+ if (attributes != null)
+ {
+ for (Enumeration en = attributes.getObjects(); en.hasMoreElements();)
+ {
+ Attribute at = Attribute.getInstance(en.nextElement());
+
+ if (Extension.altSignatureAlgorithm.equals(at.getAttrType()))
+ {
+ altSig = AlgorithmIdentifier.getInstance(getSingleValue(at));
+ }
+ if (Extension.subjectAltPublicKeyInfo.equals(at.getAttrType()))
+ {
+ altPub = SubjectPublicKeyInfo.getInstance(getSingleValue(at));
+ }
+ if (Extension.altSignatureValue.equals(at.getAttrType()))
+ {
+ altSigValue = ASN1BitString.getInstance(getSingleValue(at));
+ }
+ }
+ }
+
+ this.isAltRequest = (altSig != null) | (altPub != null) | (altSigValue != null);
+ if (isAltRequest)
+ {
+ if (!((altSig != null) & (altPub != null) & (altSigValue != null)))
+ {
+ throw new IllegalArgumentException("invalid alternate public key details found");
+ }
+ }
+
+ this.altSignature = altSig;
+ this.altPublicKey = altPub;
+ this.altSignatureValue = altSigValue;
+ }
+
+ /**
+ * Create a PKCS10CertificationRequestHolder from the passed in bytes.
+ *
+ * @param encoded BER/DER encoding of the CertificationRequest structure.
+ * @throws IOException in the event of corrupted data, or an incorrect structure.
+ */
+ public PKCS10CertificationRequest(byte[] encoded)
+ throws IOException
+ {
+ this(parseBytes(encoded));
+ }
+
+ /**
+ * Return the underlying ASN.1 structure for this request.
+ *
+ * @return a CertificateRequest object.
+ */
+ public CertificationRequest toASN1Structure()
+ {
+ return certificationRequest;
+ }
+
+ /**
+ * Return the subject on this request.
+ *
+ * @return the X500Name representing the request's subject.
+ */
+ public X500Name getSubject()
+ {
+ return X500Name.getInstance(certificationRequest.getCertificationRequestInfo().getSubject());
+ }
+
+ /**
+ * Return the details of the signature algorithm used to create this request.
+ *
+ * @return the AlgorithmIdentifier describing the signature algorithm used to create this request.
+ */
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return certificationRequest.getSignatureAlgorithm();
+ }
+
+ /**
+ * Return the bytes making up the signature associated with this request.
+ *
+ * @return the request signature bytes.
+ */
+ public byte[] getSignature()
+ {
+ return certificationRequest.getSignature().getOctets();
+ }
+
+ /**
+ * Return the SubjectPublicKeyInfo describing the public key this request is carrying.
+ *
+ * @return the public key ASN.1 structure contained in the request.
+ */
+ public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
+ {
+ return certificationRequest.getCertificationRequestInfo().getSubjectPublicKeyInfo();
+ }
+
+ /**
+ * Return the attributes, if any associated with this request.
+ *
+ * @return an array of Attribute, zero length if none present.
+ */
+ public Attribute[] getAttributes()
+ {
+ ASN1Set attrSet = certificationRequest.getCertificationRequestInfo().getAttributes();
+
+ if (attrSet == null)
+ {
+ return EMPTY_ARRAY;
+ }
+
+ Attribute[] attrs = new Attribute[attrSet.size()];
+
+ for (int i = 0; i != attrSet.size(); i++)
+ {
+ attrs[i] = Attribute.getInstance(attrSet.getObjectAt(i));
+ }
+
+ return attrs;
+ }
+
+ /**
+ * Return an array of attributes matching the passed in type OID.
+ *
+ * @param type the type of the attribute being looked for.
+ * @return an array of Attribute of the requested type, zero length if none present.
+ */
+ public Attribute[] getAttributes(ASN1ObjectIdentifier type)
+ {
+ ASN1Set attrSet = certificationRequest.getCertificationRequestInfo().getAttributes();
+
+ if (attrSet == null)
+ {
+ return EMPTY_ARRAY;
+ }
+
+ List list = new ArrayList();
+
+ for (int i = 0; i != attrSet.size(); i++)
+ {
+ Attribute attr = Attribute.getInstance(attrSet.getObjectAt(i));
+ if (attr.getAttrType().equals(type))
+ {
+ list.add(attr);
+ }
+ }
+
+ if (list.size() == 0)
+ {
+ return EMPTY_ARRAY;
+ }
+
+ return (Attribute[])list.toArray(new Attribute[list.size()]);
+ }
+
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return certificationRequest.getEncoded();
+ }
+
+ /**
+ * Validate the signature on the PKCS10 certification request in this holder.
+ *
+ * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature.
+ * @return true if the signature is valid, false otherwise.
+ * @throws PKCSException if the signature cannot be processed or is inappropriate.
+ */
+ public boolean isSignatureValid(ContentVerifierProvider verifierProvider)
+ throws PKCSException
+ {
+ CertificationRequestInfo requestInfo = certificationRequest.getCertificationRequestInfo();
+
+ ContentVerifier verifier;
+
+ try
+ {
+ verifier = verifierProvider.get(certificationRequest.getSignatureAlgorithm());
+
+ OutputStream sOut = verifier.getOutputStream();
+
+ sOut.write(requestInfo.getEncoded(ASN1Encoding.DER));
+
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new PKCSException("unable to process signature: " + e.getMessage(), e);
+ }
+
+ return verifier.verify(this.getSignature());
+ }
+
+ /**
+ * Return true if the certification request has an alternate public key present.
+ *
+ * @return true if this is a dual key request, false otherwise.
+ */
+ public boolean hasAltPublicKey()
+ {
+ return isAltRequest;
+ }
+
+ /**
+ * Validate the alternate signature on the PKCS10 certification request in this holder.
+ *
+ * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature.
+ * @return true if the alternate signature is valid, false otherwise.
+ * @throws PKCSException if the signature cannot be processed or is inappropriate.
+ */
+ public boolean isAltSignatureValid(ContentVerifierProvider verifierProvider)
+ throws PKCSException
+ {
+ if (!isAltRequest)
+ {
+ throw new IllegalStateException("no alternate public key present");
+ }
+
+ CertificationRequestInfo requestInfo = certificationRequest.getCertificationRequestInfo();
+ ASN1Set attributes = requestInfo.getAttributes();
+ ASN1EncodableVector atV = new ASN1EncodableVector();
+
+ for (Enumeration en = attributes.getObjects(); en.hasMoreElements();)
+ {
+ Attribute at = Attribute.getInstance(en.nextElement());
+
+ if (Extension.altSignatureValue.equals(at.getAttrType()))
+ {
+ continue;
+ }
+
+ atV.add(at);
+ }
+
+ requestInfo = new CertificationRequestInfo(requestInfo.getSubject(), requestInfo.getSubjectPublicKeyInfo(), new DERSet(atV));
+ ContentVerifier verifier;
+
+ try
+ {
+ verifier = verifierProvider.get(this.altSignature);
+
+ OutputStream sOut = verifier.getOutputStream();
+
+ sOut.write(requestInfo.getEncoded(ASN1Encoding.DER));
+
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new PKCSException("unable to process signature: " + e.getMessage(), e);
+ }
+
+ return verifier.verify(this.altSignatureValue.getOctets());
+ }
+
+ /**
+ * Return any extensions requested in the PKCS#10 request. If none are present, the method
+ * will return null.
+ *
+ * @return the requested extensions, null if none are requested.
+ * @throws IllegalStateException if the extension request is and is somehow invalid.
+ */
+ public Extensions getRequestedExtensions()
+ {
+ Attribute[] attributes = getAttributes();
+ for (int i = 0; i != attributes.length; i++)
+ {
+ Attribute encodable = attributes[i];
+ if (PKCSObjectIdentifiers.pkcs_9_at_extensionRequest.equals(encodable.getAttrType()))
+ {
+ ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
+
+ ASN1Set attrValues = encodable.getAttrValues();
+ if (attrValues == null || attrValues.size() == 0)
+ {
+ throw new IllegalStateException("pkcs_9_at_extensionRequest present but has no value");
+ }
+
+ ASN1Sequence extensionSequence = ASN1Sequence.getInstance(attrValues.getObjectAt(0));
+
+ try
+ {
+ for (Enumeration en = extensionSequence.getObjects(); en.hasMoreElements(); )
+ {
+ ASN1Sequence itemSeq = ASN1Sequence.getInstance(en.nextElement());
+
+ boolean critical = itemSeq.size() == 3 && ASN1Boolean.getInstance(itemSeq.getObjectAt(1)).isTrue();
+ if (itemSeq.size() == 2)
+ {
+ extensionsGenerator.addExtension(ASN1ObjectIdentifier.getInstance(itemSeq.getObjectAt(0)), false, ASN1OctetString.getInstance(itemSeq.getObjectAt(1)).getOctets());
+ }
+ else if (itemSeq.size() == 3)
+ {
+ extensionsGenerator.addExtension(ASN1ObjectIdentifier.getInstance(itemSeq.getObjectAt(0)), critical, ASN1OctetString.getInstance(itemSeq.getObjectAt(2)).getOctets());
+ }
+ else
+ {
+ throw new IllegalStateException("incorrect sequence size of Extension get " + itemSeq.size() + " expected 2 or three");
+ }
+ }
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw Exceptions.illegalStateException("asn1 processing issue: " + e.getMessage(), e);
+ }
+
+ return extensionsGenerator.generate();
+ }
+ }
+ return null;
+ }
+
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof PKCS10CertificationRequest))
+ {
+ return false;
+ }
+
+ PKCS10CertificationRequest other = (PKCS10CertificationRequest)o;
+
+ return this.toASN1Structure().equals(other.toASN1Structure());
+ }
+
+ public int hashCode()
+ {
+ return this.toASN1Structure().hashCode();
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/PKCSException.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/PKCSException.java
new file mode 100644
index 0000000..8ee6f6f
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/PKCSException.java
@@ -0,0 +1,27 @@
+package org.bouncycastle.pkcs;
+
+/**
+ * General checked Exception thrown in the cert package and its sub-packages.
+ */
+public class PKCSException
+ extends Exception
+{
+ private Throwable cause;
+
+ public PKCSException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public PKCSException(String msg)
+ {
+ super(msg);
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/PKCSIOException.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/PKCSIOException.java
new file mode 100644
index 0000000..2776006
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/PKCSIOException.java
@@ -0,0 +1,30 @@
+package org.bouncycastle.pkcs;
+
+import java.io.IOException;
+
+/**
+ * General IOException thrown in the cert package and its sub-packages.
+ */
+public class PKCSIOException
+ extends IOException
+{
+ private Throwable cause;
+
+ public PKCSIOException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public PKCSIOException(String msg)
+ {
+ super(msg);
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
+
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/AnnotatedException.java b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/AnnotatedException.java
deleted file mode 100644
index c7211dc..0000000
--- a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/AnnotatedException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.bouncycastle.pkix.jcajce;
-
-class AnnotatedException
- extends Exception
-{
- private Throwable _underlyingException;
-
- public AnnotatedException(String string, Throwable e)
- {
- super(string);
-
- _underlyingException = e;
- }
-
- public AnnotatedException(String string)
- {
- this(string, null);
- }
-
- public Throwable getCause()
- {
- return _underlyingException;
- }
-}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/CRLNotFoundException.java b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/CRLNotFoundException.java
deleted file mode 100644
index 06f58bf..0000000
--- a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/CRLNotFoundException.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.bouncycastle.pkix.jcajce;
-
-import java.security.cert.CertPathValidatorException;
-
-class CRLNotFoundException
- extends CertPathValidatorException
-{
- CRLNotFoundException(String message)
- {
- super(message);
- }
-
- public CRLNotFoundException(String message, Throwable cause)
- {
- super(message, cause);
- }
-}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/CertStatus.java b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/CertStatus.java
deleted file mode 100644
index 8c334d4..0000000
--- a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/CertStatus.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.bouncycastle.pkix.jcajce;
-
-import java.util.Date;
-
-class CertStatus
-{
- public static final int UNREVOKED = 11;
-
- public static final int UNDETERMINED = 12;
-
- int certStatus = UNREVOKED;
-
- Date revocationDate = null;
-
- /**
- * @return Returns the revocationDate.
- */
- public Date getRevocationDate()
- {
- return revocationDate;
- }
-
- /**
- * @param revocationDate The revocationDate to set.
- */
- public void setRevocationDate(Date revocationDate)
- {
- this.revocationDate = revocationDate;
- }
-
- /**
- * @return Returns the certStatus.
- */
- public int getCertStatus()
- {
- return certStatus;
- }
-
- /**
- * @param certStatus The certStatus to set.
- */
- public void setCertStatus(int certStatus)
- {
- this.certStatus = certStatus;
- }
-}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java
deleted file mode 100644
index bf3b7de..0000000
--- a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package org.bouncycastle.pkix.jcajce;
-
-import java.security.cert.CertStore;
-import java.security.cert.CertStoreException;
-import java.security.cert.X509CRL;
-import java.security.cert.X509Certificate;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.bouncycastle.jcajce.PKIXCRLStoreSelector;
-import org.bouncycastle.util.Store;
-import org.bouncycastle.util.StoreException;
-
-abstract class PKIXCRLUtil
-{
- static Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores)
- throws AnnotatedException
- {
- HashSet initialSet = new HashSet();
-
- // get complete CRL(s)
- try
- {
- findCRLs(initialSet, crlselect, pkixCrlStores);
- findCRLs(initialSet, crlselect, certStores);
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Exception obtaining complete CRLs.", e);
- }
-
- Set finalSet = new HashSet();
-
- // based on RFC 5280 6.3.3
- for (Iterator it = initialSet.iterator(); it.hasNext();)
- {
- X509CRL crl = (X509CRL)it.next();
-
- if (crl.getNextUpdate().after(validityDate))
- {
- X509Certificate cert = crlselect.getCertificateChecking();
-
- if (null == cert || crl.getThisUpdate().before(cert.getNotAfter()))
- {
- finalSet.add(crl);
- }
- }
- }
-
- return finalSet;
- }
-
- /**
- * Add to a HashSet any and all CRLs found in the X509Store's that are matching the crlSelect
- * criteria.
- *
- * @param crls
- * the {@link HashSet} to add the CRLs to.
- * @param crlSelect
- * a {@link PKIXCRLStoreSelector} object that will be used to select the CRLs
- * @param crlStores
- * a List containing only {@link Store} objects. These are used to search for CRLs
- */
- private static void findCRLs(HashSet crls, PKIXCRLStoreSelector crlSelect, List crlStores) throws AnnotatedException
- {
- AnnotatedException lastException = null;
- boolean foundValidStore = false;
-
- Iterator iter = crlStores.iterator();
- while (iter.hasNext())
- {
- Object obj = iter.next();
- if (obj instanceof Store)
- {
- Store store = (Store)obj;
- try
- {
- crls.addAll(store.getMatches(crlSelect));
- foundValidStore = true;
- }
- catch (StoreException e)
- {
- lastException = new AnnotatedException("Exception searching in X.509 CRL store.", e);
- }
- }
- else
- {
- CertStore store = (CertStore)obj;
- try
- {
- crls.addAll(PKIXCRLStoreSelector.getCRLs(crlSelect, store));
- foundValidStore = true;
- }
- catch (CertStoreException e)
- {
- lastException = new AnnotatedException("Exception searching in X.509 CRL store.", e);
- }
- }
- }
- if (!foundValidStore && lastException != null)
- {
- throw lastException;
- }
- }
-}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXJcaJceHelper.java b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXJcaJceHelper.java
deleted file mode 100644
index b3cd88e..0000000
--- a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXJcaJceHelper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.bouncycastle.pkix.jcajce;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.cert.CertPathBuilder;
-
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-
-interface PKIXJcaJceHelper
- extends JcaJceHelper
-{
- CertPathBuilder createCertPathBuilder(String type)
- throws NoSuchAlgorithmException, NoSuchProviderException;
-}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java
deleted file mode 100644
index 83b8ddc..0000000
--- a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java
+++ /dev/null
@@ -1,1002 +0,0 @@
-package org.bouncycastle.pkix.jcajce;
-
-import java.io.IOException;
-import java.security.PublicKey;
-import java.security.cert.CertPathBuilder;
-import java.security.cert.CertPathBuilderException;
-import java.security.cert.CertPathValidatorException;
-import java.security.cert.X509CRL;
-import java.security.cert.X509CRLSelector;
-import java.security.cert.X509CertSelector;
-import java.security.cert.X509Certificate;
-import java.security.cert.X509Extension;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1EncodableVector;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.ASN1Sequence;
-import org.bouncycastle.asn1.DERSequence;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.BasicConstraints;
-import org.bouncycastle.asn1.x509.CRLDistPoint;
-import org.bouncycastle.asn1.x509.CRLReason;
-import org.bouncycastle.asn1.x509.DistributionPoint;
-import org.bouncycastle.asn1.x509.DistributionPointName;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.GeneralName;
-import org.bouncycastle.asn1.x509.GeneralNames;
-import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
-import org.bouncycastle.jcajce.PKIXCRLStoreSelector;
-import org.bouncycastle.jcajce.PKIXCertStoreSelector;
-import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
-import org.bouncycastle.jcajce.PKIXExtendedParameters;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.util.Arrays;
-
-class RFC3280CertPathUtilities
-{
- /**
- * If the complete CRL includes an issuing distribution point (IDP) CRL
- * extension check the following:
- * <p>
- * (i) If the distribution point name is present in the IDP CRL extension
- * and the distribution field is present in the DP, then verify that one of
- * the names in the IDP matches one of the names in the DP. If the
- * distribution point name is present in the IDP CRL extension and the
- * distribution field is omitted from the DP, then verify that one of the
- * names in the IDP matches one of the names in the cRLIssuer field of the
- * DP.
- * </p>
- * <p>
- * (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL
- * extension, verify that the certificate does not include the basic
- * constraints extension with the cA boolean asserted.
- * </p>
- * <p>
- * (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL
- * extension, verify that the certificate includes the basic constraints
- * extension with the cA boolean asserted.
- * </p>
- * <p>
- * (iv) Verify that the onlyContainsAttributeCerts boolean is not asserted.
- * </p>
- *
- * @param dp The distribution point.
- * @param cert The certificate.
- * @param crl The CRL.
- * @throws AnnotatedException if one of the conditions is not met or an error occurs.
- */
- protected static void processCRLB2(
- DistributionPoint dp,
- Object cert,
- X509CRL crl)
- throws AnnotatedException
- {
- IssuingDistributionPoint idp = null;
- try
- {
- idp = IssuingDistributionPoint.getInstance(RevocationUtilities.getExtensionValue(crl,
- Extension.issuingDistributionPoint));
- }
- catch (Exception e)
- {
- throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e);
- }
- // (b) (2) (i)
- // distribution point name is present
- if (idp != null)
- {
- if (idp.getDistributionPoint() != null)
- {
- // make list of names
- DistributionPointName dpName = IssuingDistributionPoint.getInstance(idp).getDistributionPoint();
- List names = new ArrayList();
-
- if (dpName.getType() == DistributionPointName.FULL_NAME)
- {
- GeneralName[] genNames = GeneralNames.getInstance(dpName.getName()).getNames();
- for (int j = 0; j < genNames.length; j++)
- {
- names.add(genNames[j]);
- }
- }
- if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
- {
- ASN1EncodableVector vec = new ASN1EncodableVector();
- try
- {
- Enumeration e = ASN1Sequence.getInstance(crl.getIssuerX500Principal().getEncoded()).getObjects();
- while (e.hasMoreElements())
- {
- vec.add((ASN1Encodable)e.nextElement());
- }
- }
- catch (Exception e)
- {
- throw new AnnotatedException("Could not read CRL issuer.", e);
- }
- vec.add(dpName.getName());
- names.add(new GeneralName(X500Name.getInstance(new DERSequence(vec))));
- }
- boolean matches = false;
- // verify that one of the names in the IDP matches one
- // of the names in the DP.
- if (dp.getDistributionPoint() != null)
- {
- dpName = dp.getDistributionPoint();
- GeneralName[] genNames = null;
- if (dpName.getType() == DistributionPointName.FULL_NAME)
- {
- genNames = GeneralNames.getInstance(dpName.getName()).getNames();
- }
- if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
- {
- if (dp.getCRLIssuer() != null)
- {
- genNames = dp.getCRLIssuer().getNames();
- }
- else
- {
- genNames = new GeneralName[1];
- try
- {
- genNames[0] = new GeneralName(X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded()));
- }
- catch (Exception e)
- {
- throw new AnnotatedException("Could not read certificate issuer.", e);
- }
- }
- for (int j = 0; j < genNames.length; j++)
- {
- Enumeration e = ASN1Sequence.getInstance(genNames[j].getName().toASN1Primitive()).getObjects();
- ASN1EncodableVector vec = new ASN1EncodableVector();
- while (e.hasMoreElements())
- {
- vec.add((ASN1Encodable)e.nextElement());
- }
- vec.add(dpName.getName());
- genNames[j] = new GeneralName(X500Name.getInstance(new DERSequence(vec)));
- }
- }
- if (genNames != null)
- {
- for (int j = 0; j < genNames.length; j++)
- {
- if (names.contains(genNames[j]))
- {
- matches = true;
- break;
- }
- }
- }
- if (!matches)
- {
- throw new AnnotatedException(
- "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point.");
- }
- }
- // verify that one of the names in
- // the IDP matches one of the names in the cRLIssuer field of
- // the DP
- else
- {
- if (dp.getCRLIssuer() == null)
- {
- throw new AnnotatedException("Either the cRLIssuer or the distributionPoint field must "
- + "be contained in DistributionPoint.");
- }
- GeneralName[] genNames = dp.getCRLIssuer().getNames();
- for (int j = 0; j < genNames.length; j++)
- {
- if (names.contains(genNames[j]))
- {
- matches = true;
- break;
- }
- }
- if (!matches)
- {
- throw new AnnotatedException(
- "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point.");
- }
- }
- }
- BasicConstraints bc = null;
- try
- {
- bc = BasicConstraints.getInstance(RevocationUtilities.getExtensionValue((X509Extension)cert,
- Extension.basicConstraints));
- }
- catch (Exception e)
- {
- throw new AnnotatedException("Basic constraints extension could not be decoded.", e);
- }
-
- if (cert instanceof X509Certificate)
- {
- // (b) (2) (ii)
- if (idp.onlyContainsUserCerts() && (bc != null && bc.isCA()))
- {
- throw new AnnotatedException("CA Cert CRL only contains user certificates.");
- }
-
- // (b) (2) (iii)
- if (idp.onlyContainsCACerts() && (bc == null || !bc.isCA()))
- {
- throw new AnnotatedException("End CRL only contains CA certificates.");
- }
- }
-
- // (b) (2) (iv)
- if (idp.onlyContainsAttributeCerts())
- {
- throw new AnnotatedException("onlyContainsAttributeCerts boolean is asserted.");
- }
- }
- }
-
- /**
- * If the DP includes cRLIssuer, then verify that the issuer field in the
- * complete CRL matches cRLIssuer in the DP and that the complete CRL
- * contains an issuing distribution point extension with the indirectCRL
- * boolean asserted. Otherwise, verify that the CRL issuer matches the
- * certificate issuer.
- *
- * @param dp The distribution point.
- * @param cert The certificate ot attribute certificate.
- * @param crl The CRL for <code>cert</code>.
- * @throws AnnotatedException if one of the above conditions does not apply or an error
- * occurs.
- */
- protected static void processCRLB1(
- DistributionPoint dp,
- Object cert,
- X509CRL crl)
- throws AnnotatedException
- {
- ASN1Primitive idp = RevocationUtilities.getExtensionValue(crl, Extension.issuingDistributionPoint);
- boolean isIndirect = false;
- if (idp != null)
- {
- if (IssuingDistributionPoint.getInstance(idp).isIndirectCRL())
- {
- isIndirect = true;
- }
- }
- byte[] issuerBytes;
-
- issuerBytes = crl.getIssuerX500Principal().getEncoded();
-
-
- boolean matchIssuer = false;
- if (dp.getCRLIssuer() != null)
- {
- GeneralName genNames[] = dp.getCRLIssuer().getNames();
- for (int j = 0; j < genNames.length; j++)
- {
- if (genNames[j].getTagNo() == GeneralName.directoryName)
- {
- try
- {
- if (Arrays.areEqual(genNames[j].getName().toASN1Primitive().getEncoded(), issuerBytes))
- {
- matchIssuer = true;
- }
- }
- catch (IOException e)
- {
- throw new AnnotatedException(
- "CRL issuer information from distribution point cannot be decoded.", e);
- }
- }
- }
- if (matchIssuer && !isIndirect)
- {
- throw new AnnotatedException("Distribution point contains cRLIssuer field but CRL is not indirect.");
- }
- if (!matchIssuer)
- {
- throw new AnnotatedException("CRL issuer of CRL does not match CRL issuer of distribution point.");
- }
- }
- else
- {
- if (crl.getIssuerX500Principal().equals(((X509Certificate)cert).getIssuerX500Principal()))
- {
- matchIssuer = true;
- }
- }
- if (!matchIssuer)
- {
- throw new AnnotatedException("Cannot find matching CRL issuer for certificate.");
- }
- }
-
- protected static ReasonsMask processCRLD(
- X509CRL crl,
- DistributionPoint dp)
- throws AnnotatedException
- {
- IssuingDistributionPoint idp = null;
- try
- {
- idp = IssuingDistributionPoint.getInstance(RevocationUtilities.getExtensionValue(crl,
- Extension.issuingDistributionPoint));
- }
- catch (Exception e)
- {
- throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e);
- }
- // (d) (1)
- if (idp != null && idp.getOnlySomeReasons() != null && dp.getReasons() != null)
- {
- return new ReasonsMask(dp.getReasons()).intersect(new ReasonsMask(idp.getOnlySomeReasons()));
- }
- // (d) (4)
- if ((idp == null || idp.getOnlySomeReasons() == null) && dp.getReasons() == null)
- {
- return ReasonsMask.allReasons;
- }
- // (d) (2) and (d)(3)
- return (dp.getReasons() == null
- ? ReasonsMask.allReasons
- : new ReasonsMask(dp.getReasons())).intersect(idp == null
- ? ReasonsMask.allReasons
- : new ReasonsMask(idp.getOnlySomeReasons()));
-
- }
-
-
- public static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId();
-
- public static final String FRESHEST_CRL = Extension.freshestCRL.getId();
-
- public static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId();
-
- public static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId();
-
- public static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId();
-
- /*
- * key usage bits
- */
- protected static final int KEY_CERT_SIGN = 5;
-
- protected static final int CRL_SIGN = 6;
-
- /**
- * Obtain and validate the certification path for the complete CRL issuer.
- * If a key usage extension is present in the CRL issuer's certificate,
- * verify that the cRLSign bit is set.
- *
- * @param crl CRL which contains revocation information for the certificate
- * <code>cert</code>.
- * @param cert The attribute certificate or certificate to check if it is
- * revoked.
- * @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
- * @param defaultCRLSignKey The public key of the issuer certificate
- * <code>defaultCRLSignCert</code>.
- * @param paramsPKIX PKIX parameters.
- * @param certPathCerts The certificates on the certification path.
- * @return A <code>Set</code> with all keys of possible CRL issuer
- * certificates.
- * @throws AnnotatedException if the CRL is not valid or the status cannot be checked or
- * some error occurs.
- */
- protected static Set processCRLF(
- X509CRL crl,
- Object cert,
- X509Certificate defaultCRLSignCert,
- PublicKey defaultCRLSignKey,
- PKIXExtendedParameters paramsPKIX,
- List certPathCerts,
- JcaJceHelper helper)
- throws AnnotatedException
- {
- // (f)
-
- // get issuer from CRL
- X509CertSelector certSelector = new X509CertSelector();
- try
- {
- byte[] issuerPrincipal = crl.getIssuerX500Principal().getEncoded();
- certSelector.setSubject(issuerPrincipal);
- }
- catch (IOException e)
- {
- throw new AnnotatedException(
- "subject criteria for certificate selector to find issuer certificate for CRL could not be set", e);
- }
-
- PKIXCertStoreSelector selector = new PKIXCertStoreSelector.Builder(certSelector).build();
-
- // get CRL signing certs
- LinkedHashSet coll = new LinkedHashSet();
- try
- {
- RevocationUtilities.findCertificates(coll, selector, paramsPKIX.getCertificateStores());
- RevocationUtilities.findCertificates(coll, selector, paramsPKIX.getCertStores());
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Issuer certificate for CRL cannot be searched.", e);
- }
-
- coll.add(defaultCRLSignCert);
-
- List validCerts = new ArrayList();
- List validKeys = new ArrayList();
-
- Iterator cert_it = coll.iterator();
- while (cert_it.hasNext())
- {
- X509Certificate signingCert = (X509Certificate)cert_it.next();
-
- /*
- * CA of the certificate, for which this CRL is checked, has also
- * signed CRL, so skip the path validation, because is already done
- */
- if (signingCert.equals(defaultCRLSignCert))
- {
- validCerts.add(signingCert);
- validKeys.add(defaultCRLSignKey);
- continue;
- }
- try
- {
- CertPathBuilder builder = helper.createCertPathBuilder("PKIX");
- X509CertSelector tmpCertSelector = new X509CertSelector();
- tmpCertSelector.setCertificate(signingCert);
-
- PKIXExtendedParameters.Builder paramsBuilder = new PKIXExtendedParameters.Builder(paramsPKIX)
- .setTargetConstraints(new PKIXCertStoreSelector.Builder(tmpCertSelector).build());
-
- /*
- * if signingCert is placed not higher on the cert path a
- * dependency loop results. CRL for cert is checked, but
- * signingCert is needed for checking the CRL which is dependent
- * on checking cert because it is higher in the cert path and so
- * signing signingCert transitively. so, revocation is disabled,
- * forgery attacks of the CRL are detected in this outer loop
- * for all other it must be enabled to prevent forgery attacks
- */
- if (certPathCerts.contains(signingCert))
- {
- paramsBuilder.setRevocationEnabled(false);
- }
- else
- {
- paramsBuilder.setRevocationEnabled(true);
- }
-
- PKIXExtendedBuilderParameters extParams = new PKIXExtendedBuilderParameters.Builder(paramsBuilder.build()).build();
-
- List certs = builder.build(extParams).getCertPath().getCertificates();
- validCerts.add(signingCert);
- validKeys.add(RevocationUtilities.getNextWorkingKey(certs, 0, helper));
- }
- catch (CertPathBuilderException e)
- {
- throw new AnnotatedException("CertPath for CRL signer failed to validate.", e);
- }
- catch (CertPathValidatorException e)
- {
- throw new AnnotatedException("Public key of issuer certificate of CRL could not be retrieved.", e);
- }
- catch (Exception e)
- {
- throw new AnnotatedException(e.getMessage());
- }
- }
-
- Set checkKeys = new HashSet();
-
- AnnotatedException lastException = null;
- for (int i = 0; i < validCerts.size(); i++)
- {
- X509Certificate signCert = (X509Certificate)validCerts.get(i);
- boolean[] keyUsage = signCert.getKeyUsage();
-
- if (keyUsage != null && (keyUsage.length <= CRL_SIGN || !keyUsage[CRL_SIGN]))
- {
- lastException = new AnnotatedException(
- "Issuer certificate key usage extension does not permit CRL signing.");
- }
- else
- {
- checkKeys.add(validKeys.get(i));
- }
- }
-
- if (checkKeys.isEmpty() && lastException == null)
- {
- throw new AnnotatedException("Cannot find a valid issuer certificate.");
- }
- if (checkKeys.isEmpty() && lastException != null)
- {
- throw lastException;
- }
-
- return checkKeys;
- }
-
- protected static PublicKey processCRLG(
- X509CRL crl,
- Set keys)
- throws AnnotatedException
- {
- Exception lastException = null;
- for (Iterator it = keys.iterator(); it.hasNext();)
- {
- PublicKey key = (PublicKey)it.next();
- try
- {
- crl.verify(key);
- return key;
- }
- catch (Exception e)
- {
- lastException = e;
- }
- }
- throw new AnnotatedException("Cannot verify CRL.", lastException);
- }
-
- protected static X509CRL processCRLH(
- Set deltacrls,
- PublicKey key)
- throws AnnotatedException
- {
- Exception lastException = null;
-
- for (Iterator it = deltacrls.iterator(); it.hasNext();)
- {
- X509CRL crl = (X509CRL)it.next();
- try
- {
- crl.verify(key);
- return crl;
- }
- catch (Exception e)
- {
- lastException = e;
- }
- }
-
- if (lastException != null)
- {
- throw new AnnotatedException("Cannot verify delta CRL.", lastException);
- }
- return null;
- }
-
- protected static Set processCRLA1i(
- PKIXExtendedParameters paramsPKIX,
- Date currentDate,
- X509Certificate cert,
- X509CRL crl)
- throws AnnotatedException
- {
- Set set = new HashSet();
- if (paramsPKIX.isUseDeltasEnabled())
- {
- CRLDistPoint freshestCRL = null;
- try
- {
- freshestCRL = CRLDistPoint
- .getInstance(RevocationUtilities.getExtensionValue(cert, Extension.freshestCRL));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Freshest CRL extension could not be decoded from certificate.", e);
- }
- if (freshestCRL == null)
- {
- try
- {
- freshestCRL = CRLDistPoint.getInstance(RevocationUtilities.getExtensionValue(crl,
- Extension.freshestCRL));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Freshest CRL extension could not be decoded from CRL.", e);
- }
- }
- if (freshestCRL != null)
- {
- List crlStores = new ArrayList();
-
- crlStores.addAll(paramsPKIX.getCRLStores());
-
- try
- {
- crlStores.addAll(RevocationUtilities.getAdditionalStoresFromCRLDistributionPoint(freshestCRL, paramsPKIX.getNamedCRLStoreMap()));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException(
- "No new delta CRL locations could be added from Freshest CRL extension.", e);
- }
-
- // get delta CRL(s)
- try
- {
- set.addAll(RevocationUtilities.getDeltaCRLs(currentDate, crl, paramsPKIX.getCertStores(), crlStores));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Exception obtaining delta CRLs.", e);
- }
- }
- }
- return set;
- }
-
- protected static Set[] processCRLA1ii(
- PKIXExtendedParameters paramsPKIX,
- Date currentDate,
- Date validityDate,
- X509Certificate cert,
- X509CRL crl)
- throws AnnotatedException
- {
- X509CRLSelector crlselect = new X509CRLSelector();
- crlselect.setCertificateChecking(cert);
-
- try
- {
- crlselect.addIssuerName(crl.getIssuerX500Principal().getEncoded());
- }
- catch (IOException e)
- {
- throw new AnnotatedException("Cannot extract issuer from CRL." + e, e);
- }
-
- PKIXCRLStoreSelector extSelect = new PKIXCRLStoreSelector.Builder(crlselect).setCompleteCRLEnabled(true).build();
-
- Set completeSet = PKIXCRLUtil.findCRLs(extSelect, validityDate, paramsPKIX.getCertStores(),
- paramsPKIX.getCRLStores());
- Set deltaSet = new HashSet();
-
- if (paramsPKIX.isUseDeltasEnabled())
- {
- // get delta CRL(s)
- try
- {
- deltaSet.addAll(RevocationUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores()));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Exception obtaining delta CRLs.", e);
- }
- }
- return new Set[]{ completeSet, deltaSet };
- }
-
- /**
- * If use-deltas is set, verify the issuer and scope of the delta CRL.
- *
- * @param deltaCRL The delta CRL.
- * @param completeCRL The complete CRL.
- * @param pkixParams The PKIX paramaters.
- * @throws AnnotatedException if an exception occurs.
- */
- protected static void processCRLC(
- X509CRL deltaCRL,
- X509CRL completeCRL,
- PKIXExtendedParameters pkixParams)
- throws AnnotatedException
- {
- if (deltaCRL == null)
- {
- return;
- }
- IssuingDistributionPoint completeidp = null;
- try
- {
- completeidp = IssuingDistributionPoint.getInstance(RevocationUtilities.getExtensionValue(
- completeCRL, Extension.issuingDistributionPoint));
- }
- catch (Exception e)
- {
- throw new AnnotatedException("issuing distribution point extension could not be decoded.", e);
- }
-
- if (pkixParams.isUseDeltasEnabled())
- {
- // (c) (1)
- if (!deltaCRL.getIssuerX500Principal().equals(completeCRL.getIssuerX500Principal()))
- {
- throw new AnnotatedException("complete CRL issuer does not match delta CRL issuer");
- }
-
- // (c) (2)
- IssuingDistributionPoint deltaidp = null;
- try
- {
- deltaidp = IssuingDistributionPoint.getInstance(RevocationUtilities.getExtensionValue(
- deltaCRL, Extension.issuingDistributionPoint));
- }
- catch (Exception e)
- {
- throw new AnnotatedException(
- "Issuing distribution point extension from delta CRL could not be decoded.", e);
- }
-
- boolean match = false;
- if (completeidp == null)
- {
- if (deltaidp == null)
- {
- match = true;
- }
- }
- else
- {
- if (completeidp.equals(deltaidp))
- {
- match = true;
- }
- }
- if (!match)
- {
- throw new AnnotatedException(
- "Issuing distribution point extension from delta CRL and complete CRL does not match.");
- }
-
- // (c) (3)
- ASN1Primitive completeKeyIdentifier = null;
- try
- {
- completeKeyIdentifier = RevocationUtilities.getExtensionValue(
- completeCRL, Extension.authorityKeyIdentifier);
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException(
- "Authority key identifier extension could not be extracted from complete CRL.", e);
- }
-
- ASN1Primitive deltaKeyIdentifier = null;
- try
- {
- deltaKeyIdentifier = RevocationUtilities.getExtensionValue(
- deltaCRL, Extension.authorityKeyIdentifier);
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException(
- "Authority key identifier extension could not be extracted from delta CRL.", e);
- }
-
- if (completeKeyIdentifier == null)
- {
- throw new AnnotatedException("CRL authority key identifier is null.");
- }
-
- if (deltaKeyIdentifier == null)
- {
- throw new AnnotatedException("Delta CRL authority key identifier is null.");
- }
-
- if (!completeKeyIdentifier.equals(deltaKeyIdentifier))
- {
- throw new AnnotatedException(
- "Delta CRL authority key identifier does not match complete CRL authority key identifier.");
- }
- }
- }
-
- protected static void processCRLI(
- Date validDate,
- X509CRL deltacrl,
- Object cert,
- CertStatus certStatus,
- PKIXExtendedParameters pkixParams)
- throws AnnotatedException
- {
- if (pkixParams.isUseDeltasEnabled() && deltacrl != null)
- {
- RevocationUtilities.getCertStatus(validDate, deltacrl, cert, certStatus);
- }
- }
-
- protected static void processCRLJ(
- Date validDate,
- X509CRL completecrl,
- Object cert,
- CertStatus certStatus)
- throws AnnotatedException
- {
- if (certStatus.getCertStatus() == CertStatus.UNREVOKED)
- {
- RevocationUtilities.getCertStatus(validDate, completecrl, cert, certStatus);
- }
- }
-
- /**
- * Checks a distribution point for revocation information for the
- * certificate <code>cert</code>.
- *
- * @param dp The distribution point to consider.
- * @param paramsPKIX PKIX parameters.
- * @param cert Certificate to check if it is revoked.
- * @param validDate The date when the certificate revocation status should be
- * checked.
- * @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
- * @param defaultCRLSignKey The public key of the issuer certificate
- * <code>defaultCRLSignCert</code>.
- * @param certStatus The current certificate revocation status.
- * @param reasonMask The reasons mask which is already checked.
- * @param certPathCerts The certificates of the certification path.
- * @throws AnnotatedException if the certificate is revoked or the status cannot be checked
- * or some error occurs.
- */
- static void checkCRL(
- DistributionPoint dp,
- PKIXExtendedParameters paramsPKIX,
- Date currentDate,
- Date validityDate,
- X509Certificate cert,
- X509Certificate defaultCRLSignCert,
- PublicKey defaultCRLSignKey,
- CertStatus certStatus,
- ReasonsMask reasonMask,
- List certPathCerts,
- JcaJceHelper helper)
- throws AnnotatedException, CRLNotFoundException
- {
- if (validityDate.getTime() > currentDate.getTime())
- {
- throw new AnnotatedException("Validation time is in future.");
- }
-
- // (a)
- /*
- * We always get timely valid CRLs, so there is no step (a) (1).
- * "locally cached" CRLs are assumed to be in getStore(), additional
- * CRLs must be enabled in the ExtendedPKIXParameters and are in
- * getAdditionalStore()
- */
-
- Set crls = RevocationUtilities.getCompleteCRLs(dp, cert, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
- boolean validCrlFound = false;
- AnnotatedException lastException = null;
- Iterator crl_iter = crls.iterator();
-
- while (crl_iter.hasNext() && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonMask.isAllReasons())
- {
- try
- {
- X509CRL crl = (X509CRL)crl_iter.next();
-
- // (d)
- ReasonsMask interimReasonsMask = RFC3280CertPathUtilities.processCRLD(crl, dp);
-
- // (e)
- /*
- * The reasons mask is updated at the end, so only valid CRLs
- * can update it. If this CRL does not contain new reasons it
- * must be ignored.
- */
- if (!interimReasonsMask.hasNewReasons(reasonMask))
- {
- continue;
- }
-
- // (f)
- Set keys = RFC3280CertPathUtilities.processCRLF(crl, cert, defaultCRLSignCert, defaultCRLSignKey,
- paramsPKIX, certPathCerts, helper);
- // (g)
- PublicKey key = RFC3280CertPathUtilities.processCRLG(crl, keys);
-
- X509CRL deltaCRL = null;
-
- if (paramsPKIX.isUseDeltasEnabled())
- {
- // get delta CRLs
- Set deltaCRLs = RevocationUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
- // we only want one valid delta CRL
- // (h)
- deltaCRL = RFC3280CertPathUtilities.processCRLH(deltaCRLs, key);
- }
-
- /*
- * CRL must be be valid at the current time, not the validation
- * time. If a certificate is revoked with reason keyCompromise,
- * cACompromise, it can be used for forgery, also for the past.
- * This reason may not be contained in older CRLs.
- */
-
- /*
- * in the chain model signatures stay valid also after the
- * certificate has been expired, so they do not have to be in
- * the CRL validity time
- */
-
- if (paramsPKIX.getValidityModel() != PKIXExtendedParameters.CHAIN_VALIDITY_MODEL)
- {
- /*
- * if a certificate has expired, but was revoked, it is not
- * more in the CRL, so it would be regarded as valid if the
- * first check is not done
- */
- if (cert.getNotAfter().getTime() < crl.getThisUpdate().getTime())
- {
- throw new AnnotatedException("No valid CRL for current time found.");
- }
- }
-
- RFC3280CertPathUtilities.processCRLB1(dp, cert, crl);
-
- // (b) (2)
- RFC3280CertPathUtilities.processCRLB2(dp, cert, crl);
-
- // (c)
- RFC3280CertPathUtilities.processCRLC(deltaCRL, crl, paramsPKIX);
-
- // (i)
- RFC3280CertPathUtilities.processCRLI(validityDate, deltaCRL, cert, certStatus, paramsPKIX);
-
- // (j)
- RFC3280CertPathUtilities.processCRLJ(validityDate, crl, cert, certStatus);
-
- // (k)
- if (certStatus.getCertStatus() == CRLReason.removeFromCRL)
- {
- certStatus.setCertStatus(CertStatus.UNREVOKED);
- }
-
- // update reasons mask
- reasonMask.addReasons(interimReasonsMask);
-
- Set criticalExtensions = crl.getCriticalExtensionOIDs();
- if (criticalExtensions != null)
- {
- criticalExtensions = new HashSet(criticalExtensions);
- criticalExtensions.remove(Extension.issuingDistributionPoint.getId());
- criticalExtensions.remove(Extension.deltaCRLIndicator.getId());
-
- if (!criticalExtensions.isEmpty())
- {
- throw new AnnotatedException("CRL contains unsupported critical extensions.");
- }
- }
-
- if (deltaCRL != null)
- {
- criticalExtensions = deltaCRL.getCriticalExtensionOIDs();
- if (criticalExtensions != null)
- {
- criticalExtensions = new HashSet(criticalExtensions);
- criticalExtensions.remove(Extension.issuingDistributionPoint.getId());
- criticalExtensions.remove(Extension.deltaCRLIndicator.getId());
- if (!criticalExtensions.isEmpty())
- {
- throw new AnnotatedException("Delta CRL contains unsupported critical extension.");
- }
- }
- }
-
- validCrlFound = true;
- }
- catch (AnnotatedException e)
- {
- lastException = e;
- }
- }
- if (!validCrlFound)
- {
- throw lastException;
- }
- }
-}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/ReasonsMask.java b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/ReasonsMask.java
deleted file mode 100644
index d5b1fb0..0000000
--- a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/ReasonsMask.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.bouncycastle.pkix.jcajce;
-
-import org.bouncycastle.asn1.x509.ReasonFlags;
-
-/**
- * This class helps to handle CRL revocation reasons mask. Each CRL handles a
- * certain set of revocation reasons.
- */
-class ReasonsMask
-{
- private int _reasons;
-
- /**
- * Constructs are reason mask with the reasons.
- *
- * @param reasons The reasons.
- */
- ReasonsMask(ReasonFlags reasons)
- {
- _reasons = reasons.intValue();
- }
-
- private ReasonsMask(int reasons)
- {
- _reasons = reasons;
- }
-
- /**
- * A reason mask with no reason.
- *
- */
- ReasonsMask()
- {
- this(0);
- }
-
- /**
- * A mask with all revocation reasons.
- */
- static final ReasonsMask allReasons = new ReasonsMask(ReasonFlags.aACompromise
- | ReasonFlags.affiliationChanged | ReasonFlags.cACompromise
- | ReasonFlags.certificateHold | ReasonFlags.cessationOfOperation
- | ReasonFlags.keyCompromise | ReasonFlags.privilegeWithdrawn
- | ReasonFlags.unused | ReasonFlags.superseded);
-
- /**
- * Adds all reasons from the reasons mask to this mask.
- *
- * @param mask The reasons mask to add.
- */
- void addReasons(ReasonsMask mask)
- {
- _reasons = _reasons | mask.getReasons();
- }
-
- /**
- * Returns <code>true</code> if this reasons mask contains all possible
- * reasons.
- *
- * @return <code>true</code> if this reasons mask contains all possible
- * reasons.
- */
- boolean isAllReasons()
- {
- return _reasons == allReasons._reasons ? true : false;
- }
-
- /**
- * Intersects this mask with the given reasons mask.
- *
- * @param mask The mask to intersect with.
- * @return The intersection of this and teh given mask.
- */
- ReasonsMask intersect(ReasonsMask mask)
- {
- ReasonsMask _mask = new ReasonsMask();
- _mask.addReasons(new ReasonsMask(_reasons & mask.getReasons()));
- return _mask;
- }
-
- /**
- * Returns <code>true</code> if the passed reasons mask has new reasons.
- *
- * @param mask The reasons mask which should be tested for new reasons.
- * @return <code>true</code> if the passed reasons mask has new reasons.
- */
- boolean hasNewReasons(ReasonsMask mask)
- {
- return ((_reasons | mask.getReasons() ^ _reasons) != 0);
- }
-
- /**
- * Returns the reasons in this mask.
- *
- * @return Returns the reasons.
- */
- int getReasons()
- {
- return _reasons;
- }
-}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RevocationUtilities.java b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RevocationUtilities.java
deleted file mode 100644
index 1354861..0000000
--- a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RevocationUtilities.java
+++ /dev/null
@@ -1,644 +0,0 @@
-package org.bouncycastle.pkix.jcajce;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.KeyFactory;
-import java.security.PublicKey;
-import java.security.cert.CRLException;
-import java.security.cert.CertPathValidatorException;
-import java.security.cert.CertStore;
-import java.security.cert.CertStoreException;
-import java.security.cert.Certificate;
-import java.security.cert.X509CRL;
-import java.security.cert.X509CRLEntry;
-import java.security.cert.X509CRLSelector;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPublicKey;
-import java.security.spec.DSAPublicKeySpec;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.security.auth.x500.X500Principal;
-
-import org.bouncycastle.asn1.ASN1Enumerated;
-import org.bouncycastle.asn1.ASN1Integer;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1OctetString;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x500.style.RFC4519Style;
-import org.bouncycastle.asn1.x509.CRLDistPoint;
-import org.bouncycastle.asn1.x509.CRLReason;
-import org.bouncycastle.asn1.x509.DistributionPoint;
-import org.bouncycastle.asn1.x509.DistributionPointName;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.GeneralName;
-import org.bouncycastle.asn1.x509.GeneralNames;
-import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
-import org.bouncycastle.jcajce.PKIXCRLStore;
-import org.bouncycastle.jcajce.PKIXCRLStoreSelector;
-import org.bouncycastle.jcajce.PKIXCertStoreSelector;
-import org.bouncycastle.jcajce.PKIXExtendedParameters;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.util.Selector;
-import org.bouncycastle.util.Store;
-import org.bouncycastle.util.StoreException;
-
-class RevocationUtilities
-{
- protected static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId();
-
- protected static Date getValidityDate(PKIXExtendedParameters paramsPKIX, Date currentDate)
- {
- Date validityDate = paramsPKIX.getValidityDate();
-
- return null == validityDate ? currentDate : validityDate;
- }
-
- /**
- * Extract the value of the given extension, if it exists.
- *
- * @param ext
- * The extension object.
- * @param oid
- * The object identifier to obtain.
- * @throws AnnotatedException
- * if the extension cannot be read.
- */
- protected static ASN1Primitive getExtensionValue(java.security.cert.X509Extension ext, ASN1ObjectIdentifier oid)
- throws AnnotatedException
- {
- byte[] bytes = ext.getExtensionValue(oid.getId());
-
- return null == bytes ? null : getObject(oid, bytes);
- }
-
- private static ASN1Primitive getObject(ASN1ObjectIdentifier oid, byte[] ext) throws AnnotatedException
- {
- try
- {
- return ASN1Primitive.fromByteArray(ASN1OctetString.getInstance(ext).getOctets());
- }
- catch (Exception e)
- {
- throw new AnnotatedException("exception processing extension " + oid, e);
- }
- }
-
- /**
- * Add to a LinkedHashSet all certificates or attribute certificates found in the X509Store's
- * that are matching the certSelect criteria.
- *
- * @param certs
- * a {@link LinkedHashSet} to which the certificates will be added.
- * @param certSelect
- * a {@link Selector} object that will be used to select the certificates
- * @param certStores
- * a List containing only {@link Store} objects. These are used to search for
- * certificates.
- * @return a Collection of all found {@link X509Certificate} May be empty but never
- * <code>null</code>.
- */
- protected static void findCertificates(LinkedHashSet certs, PKIXCertStoreSelector certSelect, List certStores)
- throws AnnotatedException
- {
- Iterator iter = certStores.iterator();
- while (iter.hasNext())
- {
- Object obj = iter.next();
-
- if (obj instanceof Store)
- {
- Store certStore = (Store)obj;
- try
- {
- certs.addAll(certStore.getMatches(certSelect));
- }
- catch (StoreException e)
- {
- throw new AnnotatedException("Problem while picking certificates from X.509 store.", e);
- }
- }
- else
- {
- CertStore certStore = (CertStore)obj;
- try
- {
- certs.addAll(PKIXCertStoreSelector.getCertificates(certSelect, certStore));
- }
- catch (CertStoreException e)
- {
- throw new AnnotatedException("Problem while picking certificates from certificate store.", e);
- }
- }
- }
- }
-
- static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint(CRLDistPoint crldp,
- Map<GeneralName, PKIXCRLStore> namedCRLStoreMap) throws AnnotatedException
- {
- if (crldp == null)
- {
- return Collections.emptyList();
- }
-
- DistributionPoint dps[];
- try
- {
- dps = crldp.getDistributionPoints();
- }
- catch (Exception e)
- {
- throw new AnnotatedException("Distribution points could not be read.", e);
- }
-
- List<PKIXCRLStore> stores = new ArrayList<PKIXCRLStore>();
-
- for (int i = 0; i < dps.length; i++)
- {
- DistributionPointName dpn = dps[i].getDistributionPoint();
- // look for URIs in fullName
- if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME)
- {
- GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
-
- for (int j = 0; j < genNames.length; j++)
- {
- PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]);
- if (store != null)
- {
- stores.add(store);
- }
- }
- }
- }
-
- return stores;
- }
-
- /**
- * Add the CRL issuers from the cRLIssuer field of the distribution point or
- * from the certificate if not given to the issuer criterion of the
- * <code>selector</code>.
- * <p>
- * The <code>issuerPrincipals</code> are a collection with a single
- * <code>X500Name</code> for <code>X509Certificate</code>s.
- * </p>
- * @param dp The distribution point.
- * @param issuerPrincipals The issuers of the certificate or attribute
- * certificate which contains the distribution point.
- * @param selector The CRL selector.
- * @throws AnnotatedException if an exception occurs while processing.
- * @throws ClassCastException if <code>issuerPrincipals</code> does not
- * contain only <code>X500Name</code>s.
- */
- protected static void getCRLIssuersFromDistributionPoint(DistributionPoint dp, Collection issuerPrincipals,
- X509CRLSelector selector) throws AnnotatedException
- {
- List issuers = new ArrayList();
- // indirect CRL
- if (dp.getCRLIssuer() != null)
- {
- GeneralName genNames[] = dp.getCRLIssuer().getNames();
- // look for a DN
- for (int j = 0; j < genNames.length; j++)
- {
- if (genNames[j].getTagNo() == GeneralName.directoryName)
- {
- try
- {
- issuers.add(X500Name.getInstance(genNames[j].getName()));
- }
- catch (IllegalArgumentException e)
- {
- throw new AnnotatedException(
- "CRL issuer information from distribution point cannot be decoded.", e);
- }
- }
- }
- }
- else
- {
- /*
- * certificate issuer is CRL issuer, distributionPoint field MUST be
- * present.
- */
- if (dp.getDistributionPoint() == null)
- {
- throw new AnnotatedException(
- "CRL issuer is omitted from distribution point but no distributionPoint field present.");
- }
- // add and check issuer principals
- for (Iterator it = issuerPrincipals.iterator(); it.hasNext(); )
- {
- issuers.add(it.next());
- }
- }
- // TODO: is not found although this should correctly add the rel name. selector of Sun is buggy here or PKI test case is invalid
- // distributionPoint
-// if (dp.getDistributionPoint() != null)
-// {
-// // look for nameRelativeToCRLIssuer
-// if (dp.getDistributionPoint().getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
-// {
-// // append fragment to issuer, only one
-// // issuer can be there, if this is given
-// if (issuers.size() != 1)
-// {
-// throw new AnnotatedException(
-// "nameRelativeToCRLIssuer field is given but more than one CRL issuer is given.");
-// }
-// ASN1Encodable relName = dp.getDistributionPoint().getName();
-// Iterator it = issuers.iterator();
-// List issuersTemp = new ArrayList(issuers.size());
-// while (it.hasNext())
-// {
-// Enumeration e = null;
-// try
-// {
-// e = ASN1Sequence.getInstance(
-// new ASN1InputStream(((X500Principal) it.next())
-// .getEncoded()).readObject()).getObjects();
-// }
-// catch (IOException ex)
-// {
-// throw new AnnotatedException(
-// "Cannot decode CRL issuer information.", ex);
-// }
-// ASN1EncodableVector v = new ASN1EncodableVector();
-// while (e.hasMoreElements())
-// {
-// v.add((ASN1Encodable) e.nextElement());
-// }
-// v.add(relName);
-// issuersTemp.add(new X500Principal(new DERSequence(v)
-// .getDEREncoded()));
-// }
-// issuers.clear();
-// issuers.addAll(issuersTemp);
-// }
-// }
- Iterator it = issuers.iterator();
- while (it.hasNext())
- {
- try
- {
- selector.addIssuerName(((X500Name)it.next()).getEncoded());
- }
- catch (IOException ex)
- {
- throw new AnnotatedException(
- "Cannot decode CRL issuer information.", ex);
- }
- }
- }
-
- protected static void getCertStatus(Date validDate, X509CRL crl, Object cert, CertStatus certStatus)
- throws AnnotatedException
- {
- boolean isIndirect;
- try
- {
- isIndirect = isIndirectCRL(crl);
- }
- catch (CRLException exception)
- {
- throw new AnnotatedException("Failed check for indirect CRL.", exception);
- }
-
- X509Certificate x509Cert = (X509Certificate)cert;
- X500Name x509CertIssuer = getIssuer(x509Cert);
-
- if (!isIndirect)
- {
- X500Name crlIssuer = getIssuer(crl);
- if (!x509CertIssuer.equals(crlIssuer))
- {
- return;
- }
- }
-
- X509CRLEntry crl_entry = crl.getRevokedCertificate(x509Cert.getSerialNumber());
- if (null == crl_entry)
- {
- return;
- }
-
- if (isIndirect)
- {
- X500Principal certificateIssuer = crl_entry.getCertificateIssuer();
-
- X500Name expectedCertIssuer;
- if (null == certificateIssuer)
- {
- expectedCertIssuer = getIssuer(crl);
- }
- else
- {
- expectedCertIssuer = getX500Name(certificateIssuer);
- }
-
- if (!x509CertIssuer.equals(expectedCertIssuer))
- {
- return;
- }
- }
-
- int reasonCodeValue = CRLReason.unspecified;
-
- if (crl_entry.hasExtensions())
- {
- try
- {
- ASN1Primitive extValue = RevocationUtilities.getExtensionValue(crl_entry, Extension.reasonCode);
- ASN1Enumerated reasonCode = ASN1Enumerated.getInstance(extValue);
- if (null != reasonCode)
- {
- reasonCodeValue = reasonCode.intValueExact();
- }
- }
- catch (Exception e)
- {
- throw new AnnotatedException("Reason code CRL entry extension could not be decoded.", e);
- }
- }
-
- Date revocationDate = crl_entry.getRevocationDate();
-
- if (validDate.before(revocationDate))
- {
- switch (reasonCodeValue)
- {
- case CRLReason.unspecified:
- case CRLReason.keyCompromise:
- case CRLReason.cACompromise:
- case CRLReason.aACompromise:
- break;
- default:
- return;
- }
- }
-
- // (i) or (j)
- certStatus.setCertStatus(reasonCodeValue);
- certStatus.setRevocationDate(revocationDate);
- }
-
- /**
- * Fetches delta CRLs according to RFC 3280 section 5.2.4.
- *
- * @param validityDate
- * The date for which the delta CRLs must be valid.
- * @param completeCRL
- * The complete CRL the delta CRL is for.
- * @return A <code>Set</code> of <code>X509CRL</code>s with delta CRLs.
- * @throws AnnotatedException
- * if an exception occurs while picking the delta CRLs.
- */
- protected static Set getDeltaCRLs(Date validityDate, X509CRL completeCRL, List<CertStore> certStores,
- List<PKIXCRLStore> pkixCrlStores) throws AnnotatedException
- {
- X509CRLSelector baseDeltaSelect = new X509CRLSelector();
- // 5.2.4 (a)
- try
- {
- baseDeltaSelect.addIssuerName(completeCRL.getIssuerX500Principal().getEncoded());
- }
- catch (IOException e)
- {
- throw new AnnotatedException("cannot extract issuer from CRL.", e);
- }
-
- BigInteger completeCRLNumber = null;
- try
- {
- ASN1Primitive derObject = RevocationUtilities.getExtensionValue(completeCRL, Extension.cRLNumber);
- if (derObject != null)
- {
- completeCRLNumber = ASN1Integer.getInstance(derObject).getPositiveValue();
- }
- }
- catch (Exception e)
- {
- throw new AnnotatedException(
- "cannot extract CRL number extension from CRL", e);
- }
-
- // 5.2.4 (b)
- byte[] idp;
- try
- {
- idp = completeCRL.getExtensionValue(ISSUING_DISTRIBUTION_POINT);
- }
- catch (Exception e)
- {
- throw new AnnotatedException("issuing distribution point extension value could not be read", e);
- }
-
- // 5.2.4 (d)
-
- baseDeltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber
- .add(BigInteger.valueOf(1)));
-
- PKIXCRLStoreSelector.Builder selBuilder = new PKIXCRLStoreSelector.Builder(baseDeltaSelect);
-
- selBuilder.setIssuingDistributionPoint(idp);
- selBuilder.setIssuingDistributionPointEnabled(true);
-
- // 5.2.4 (c)
- selBuilder.setMaxBaseCRLNumber(completeCRLNumber);
-
- PKIXCRLStoreSelector deltaSelect = selBuilder.build();
-
- // find delta CRLs
- Set temp = PKIXCRLUtil.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores);
-
- Set result = new HashSet();
-
- for (Iterator it = temp.iterator(); it.hasNext(); )
- {
- X509CRL crl = (X509CRL)it.next();
-
- if (isDeltaCRL(crl))
- {
- result.add(crl);
- }
- }
-
- return result;
- }
-
- private static boolean isDeltaCRL(X509CRL crl)
- {
- Set critical = crl.getCriticalExtensionOIDs();
-
- return null == critical ? false : critical.contains(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR);
- }
-
- /**
- * Fetches complete CRLs according to RFC 3280.
- *
- * @param dp
- * The distribution point for which the complete CRL
- * @param cert
- * The <code>X509Certificate</code> for which the CRL should be searched.
- * @return A <code>Set</code> of <code>X509CRL</code>s with complete CRLs.
- * @throws AnnotatedException
- * if an exception occurs while picking the CRLs or no CRLs are found.
- */
- protected static Set getCompleteCRLs(DistributionPoint dp, Object cert, Date validityDate, List certStores, List crlStores)
- throws AnnotatedException, CRLNotFoundException
- {
- X509CRLSelector baseCrlSelect = new X509CRLSelector();
-
- try
- {
- Set issuers = new HashSet();
- issuers.add(getIssuer((X509Certificate)cert));
-
- RevocationUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, baseCrlSelect);
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException(
- "Could not get issuer information from distribution point.", e);
- }
-
- if (cert instanceof X509Certificate)
- {
- baseCrlSelect.setCertificateChecking((X509Certificate)cert);
- }
-
- PKIXCRLStoreSelector crlSelect = new PKIXCRLStoreSelector.Builder(baseCrlSelect).setCompleteCRLEnabled(true).build();
-
- Set crls = PKIXCRLUtil.findCRLs(crlSelect, validityDate, certStores, crlStores);
-
- checkCRLsNotEmpty(crls, cert);
-
- return crls;
- }
-
- /**
- * Return the next working key inheriting DSA parameters if necessary.
- * <p>
- * This methods inherits DSA parameters from the indexed certificate or
- * previous certificates in the certificate chain to the returned
- * <code>PublicKey</code>. The list is searched upwards, meaning the end
- * certificate is at position 0 and previous certificates are following.
- * </p>
- * <p>
- * If the indexed certificate does not contain a DSA key this method simply
- * returns the public key. If the DSA key already contains DSA parameters
- * the key is also only returned.
- * </p>
- *
- * @param certs The certification path.
- * @param index The index of the certificate which contains the public key
- * which should be extended with DSA parameters.
- * @return The public key of the certificate in list position
- * <code>index</code> extended with DSA parameters if applicable.
- * @throws AnnotatedException if DSA parameters cannot be inherited.
- */
- protected static PublicKey getNextWorkingKey(List certs, int index, JcaJceHelper helper)
- throws CertPathValidatorException
- {
- Certificate cert = (Certificate)certs.get(index);
- PublicKey pubKey = cert.getPublicKey();
- if (!(pubKey instanceof DSAPublicKey))
- {
- return pubKey;
- }
- DSAPublicKey dsaPubKey = (DSAPublicKey)pubKey;
- if (dsaPubKey.getParams() != null)
- {
- return dsaPubKey;
- }
- for (int i = index + 1; i < certs.size(); i++)
- {
- X509Certificate parentCert = (X509Certificate)certs.get(i);
- pubKey = parentCert.getPublicKey();
- if (!(pubKey instanceof DSAPublicKey))
- {
- throw new CertPathValidatorException(
- "DSA parameters cannot be inherited from previous certificate.");
- }
- DSAPublicKey prevDSAPubKey = (DSAPublicKey)pubKey;
- if (prevDSAPubKey.getParams() == null)
- {
- continue;
- }
- DSAParams dsaParams = prevDSAPubKey.getParams();
- DSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec(
- dsaPubKey.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG());
- try
- {
- KeyFactory keyFactory = helper.createKeyFactory("DSA");
- return keyFactory.generatePublic(dsaPubKeySpec);
- }
- catch (Exception exception)
- {
- throw new RuntimeException(exception.getMessage());
- }
- }
- throw new CertPathValidatorException("DSA parameters cannot be inherited from previous certificate.");
- }
-
- static void checkCRLsNotEmpty(Set crls, Object cert)
- throws CRLNotFoundException
- {
- if (crls.isEmpty())
- {
-// if (cert instanceof X509AttributeCertificate)
-// {
-// X509AttributeCertificate aCert = (X509AttributeCertificate)cert;
-//
-// throw new NoCRLFoundException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\"");
-// }
-// else
- {
- X500Name certIssuer = getIssuer((X509Certificate)cert);
-
- throw new CRLNotFoundException(
- "No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(certIssuer) + "\"");
- }
- }
- }
-
- public static boolean isIndirectCRL(X509CRL crl) throws CRLException
- {
- try
- {
- byte[] idp = crl.getExtensionValue(Extension.issuingDistributionPoint.getId());
- return idp != null
- && IssuingDistributionPoint.getInstance(ASN1OctetString.getInstance(idp).getOctets()).isIndirectCRL();
- }
- catch (Exception e)
- {
- throw new CRLException("exception reading IssuingDistributionPoint", e);
- }
- }
-
- private static X500Name getIssuer(X509Certificate cert)
- {
- return getX500Name(cert.getIssuerX500Principal());
- }
-
- private static X500Name getIssuer(X509CRL crl)
- {
- return getX500Name(crl.getIssuerX500Principal());
- }
-
- private static X500Name getX500Name(X500Principal principal)
- {
- return X500Name.getInstance(principal.getEncoded());
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Absent.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Absent.java
new file mode 100644
index 0000000..0f74c77
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Absent.java
@@ -0,0 +1,45 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * An ASN1 class that encodes to nothing, used in the OER library to deal with the Optional type.
+ */
+public class ASN1Absent
+ extends ASN1Primitive
+{
+
+ public static final ASN1Absent INSTANCE = new ASN1Absent();
+
+ private ASN1Absent()
+ {
+
+ }
+
+ public int hashCode()
+ {
+ return 0;
+ }
+
+ boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength(boolean withTag)
+ throws IOException
+ {
+ return 0;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag)
+ throws IOException
+ {
+
+ }
+
+ boolean asn1Equals(ASN1Primitive o)
+ {
+ return o == this;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
deleted file mode 100644
index ac5db1c..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
+++ /dev/null
@@ -1,246 +0,0 @@
-package org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.encoders.Hex;
-
-/**
- * Base class for an ASN.1 ApplicationSpecific object
- */
-public abstract class ASN1ApplicationSpecific
- extends ASN1Primitive
-{
- protected final boolean isConstructed;
- protected final int tag;
- protected final byte[] octets;
-
- ASN1ApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- this.isConstructed = isConstructed;
- this.tag = tag;
- this.octets = Arrays.clone(octets);
- }
-
- /**
- * Return an ASN1ApplicationSpecific from the passed in object, which may be a byte array, or null.
- *
- * @param obj the object to be converted.
- * @return obj's representation as an ASN1ApplicationSpecific object.
- */
- public static ASN1ApplicationSpecific getInstance(Object obj)
- {
- if (obj == null || obj instanceof ASN1ApplicationSpecific)
- {
- return (ASN1ApplicationSpecific)obj;
- }
- else if (obj instanceof byte[])
- {
- try
- {
- return ASN1ApplicationSpecific.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("Failed to construct object from byte[]: " + e.getMessage());
- }
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
- }
-
- protected static int getLengthOfHeader(byte[] data)
- {
- int length = data[1] & 0xff; // TODO: assumes 1 byte tag
-
- if (length == 0x80)
- {
- return 2; // indefinite-length encoding
- }
-
- if (length > 127)
- {
- int size = length & 0x7f;
-
- // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
- if (size > 4)
- {
- throw new IllegalStateException("DER length more than 4 bytes: " + size);
- }
-
- return size + 2;
- }
-
- return 2;
- }
-
- /**
- * Return true if the object is marked as constructed, false otherwise.
- *
- * @return true if constructed, otherwise false.
- */
- public boolean isConstructed()
- {
- return isConstructed;
- }
-
- /**
- * Return the contents of this object as a byte[]
- *
- * @return the encoded contents of the object.
- */
- public byte[] getContents()
- {
- return Arrays.clone(octets);
- }
-
- /**
- * Return the tag number associated with this object,
- *
- * @return the application tag number.
- */
- public int getApplicationTag()
- {
- return tag;
- }
-
- /**
- * Return the enclosed object assuming explicit tagging.
- *
- * @return the resulting object
- * @throws IOException if reconstruction fails.
- */
- public ASN1Primitive getObject()
- throws IOException
- {
- return ASN1Primitive.fromByteArray(getContents());
- }
-
- /**
- * Return the enclosed object assuming implicit tagging.
- *
- * @param derTagNo the type tag that should be applied to the object's contents.
- * @return the resulting object
- * @throws IOException if reconstruction fails.
- */
- public ASN1Primitive getObject(int derTagNo)
- throws IOException
- {
- if (derTagNo >= 0x1f)
- {
- throw new IOException("unsupported tag number");
- }
-
- byte[] orig = this.getEncoded();
- byte[] tmp = replaceTagNumber(derTagNo, orig);
-
- if ((orig[0] & BERTags.CONSTRUCTED) != 0)
- {
- tmp[0] |= BERTags.CONSTRUCTED;
- }
-
- return ASN1Primitive.fromByteArray(tmp);
- }
-
- int encodedLength()
- throws IOException
- {
- return StreamUtil.calculateTagLength(tag) + StreamUtil.calculateBodyLength(octets.length) + octets.length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncoded(withTag, flags, tag, octets);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof ASN1ApplicationSpecific))
- {
- return false;
- }
-
- ASN1ApplicationSpecific other = (ASN1ApplicationSpecific)o;
-
- return isConstructed == other.isConstructed
- && tag == other.tag
- && Arrays.areEqual(octets, other.octets);
- }
-
- public int hashCode()
- {
- return (isConstructed ? 1 : 0) ^ tag ^ Arrays.hashCode(octets);
- }
-
- private byte[] replaceTagNumber(int newTag, byte[] input)
- throws IOException
- {
- int tagNo = input[0] & 0x1f;
- int index = 1;
- //
- // with tagged object tag number is bottom 5 bits, or stored at the start of the content
- //
- if (tagNo == 0x1f)
- {
- int b = input[index++] & 0xff;
-
- // X.690-0207 8.1.2.4.2
- // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
- if ((b & 0x7f) == 0) // Note: -1 will pass
- {
- throw new IOException("corrupted stream - invalid high tag number found");
- }
-
- while ((b & 0x80) != 0)
- {
- b = input[index++] & 0xff;
- }
- }
-
- byte[] tmp = new byte[input.length - index + 1];
-
- System.arraycopy(input, index, tmp, 1, tmp.length - 1);
-
- tmp[0] = (byte)newTag;
-
- return tmp;
- }
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
- sb.append("[");
- if (isConstructed())
- {
- sb.append("CONSTRUCTED ");
- }
- sb.append("APPLICATION ");
- sb.append(Integer.toString(getApplicationTag()));
- sb.append("]");
- // @todo content encoding somehow?
- if (this.octets != null)
- {
- sb.append(" #");
- sb.append(Hex.toHexString(this.octets));
- }
- else
- {
- sb.append(" #null");
- }
- sb.append(" ");
- return sb.toString();
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BMPString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BMPString.java
new file mode 100644
index 0000000..6b1fb1c
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BMPString.java
@@ -0,0 +1,213 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+
+/**
+ * ASN.1 BMPString object encodes BMP (<i>Basic Multilingual Plane</i>) subset
+ * (aka UCS-2) of UNICODE (ISO 10646) characters in codepoints 0 to 65535.
+ * <p>
+ * At ISO-10646:2011 the term "BMP" has been withdrawn, and replaced by
+ * term "UCS-2".
+ * </p>
+ */
+public abstract class ASN1BMPString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1BMPString.class, BERTags.BMP_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a BMP String from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1BMPString instance, or null.
+ */
+ public static ASN1BMPString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1BMPString)
+ {
+ return (ASN1BMPString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1BMPString)
+ {
+ return (ASN1BMPString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1BMPString)TYPE.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());
+ }
+
+ /**
+ * Return a BMP String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1BMPString instance.
+ */
+ public static ASN1BMPString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1BMPString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final char[] string;
+
+ ASN1BMPString(String string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ this.string = string.toCharArray();
+ }
+
+ ASN1BMPString(byte[] string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ int byteLen = string.length;
+ if (0 != (byteLen & 1))
+ {
+ throw new IllegalArgumentException("malformed BMPString encoding encountered");
+ }
+
+ int charLen = byteLen / 2;
+ char[] cs = new char[charLen];
+
+ for (int i = 0; i != charLen; i++)
+ {
+ cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
+ }
+
+ this.string = cs;
+ }
+
+ ASN1BMPString(char[] string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ this.string = string;
+ }
+
+ public final String getString()
+ {
+ return new String(string);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1BMPString))
+ {
+ return false;
+ }
+
+ ASN1BMPString that = (ASN1BMPString)other;
+
+ return Arrays.areEqual(this.string, that.string);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, string.length * 2);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ int count = string.length;
+
+ out.writeIdentifier(withTag, BERTags.BMP_STRING);
+ out.writeDL(count * 2);
+
+ byte[] buf = new byte[8];
+
+ int i = 0, limit = count & -4;
+ while (i < limit)
+ {
+ char c0 = string[i], c1 = string[i + 1], c2 = string[i + 2], c3 = string[i + 3];
+ i += 4;
+
+ buf[0] = (byte)(c0 >> 8);
+ buf[1] = (byte)c0;
+ buf[2] = (byte)(c1 >> 8);
+ buf[3] = (byte)c1;
+ buf[4] = (byte)(c2 >> 8);
+ buf[5] = (byte)c2;
+ buf[6] = (byte)(c3 >> 8);
+ buf[7] = (byte)c3;
+
+ out.write(buf, 0, 8);
+ }
+ if (i < count)
+ {
+ int bufPos = 0;
+ do
+ {
+ char c0 = string[i];
+ i += 1;
+
+ buf[bufPos++] = (byte)(c0 >> 8);
+ buf[bufPos++] = (byte)c0;
+ }
+ while (i < count);
+
+ out.write(buf, 0, bufPos);
+ }
+ }
+
+ static ASN1BMPString createPrimitive(byte[] contents)
+ {
+ return new DERBMPString(contents);
+ }
+
+ static ASN1BMPString createPrimitive(char[] string)
+ {
+ // TODO ASN1InputStream has a validator/converter that should be unified in this class somehow
+ return new DERBMPString(string);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java
index 95abee1..aff5209 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java
@@ -1,23 +1,67 @@
package org.bouncycastle.asn1;
-import java.io.EOFException;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.io.Streams;
/**
* Base class for BIT STRING objects
*/
public abstract class ASN1BitString
extends ASN1Primitive
- implements ASN1String
+ implements ASN1String, ASN1BitStringParser
{
- private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1BitString.class, BERTags.BIT_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
- protected final byte[] data;
- protected final int padBits;
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence.toASN1BitString();
+ }
+ };
+
+ public static ASN1BitString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1BitString)
+ {
+ return (ASN1BitString)obj;
+ }
+// else if (obj instanceof ASN1BitStringParser)
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1BitString)
+ {
+ return (ASN1BitString)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1BitString)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct BIT STRING from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ public static ASN1BitString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1BitString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/**
* @param bitString an int containing the BIT STRING
@@ -99,15 +143,16 @@
return result;
}
- protected ASN1BitString(byte data, int padBits)
+ final byte[] contents;
+
+ ASN1BitString(byte data, int padBits)
{
if (padBits > 7 || padBits < 0)
{
throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
}
- this.data = new byte[]{ data };
- this.padBits = padBits;
+ this.contents = new byte[]{ (byte)padBits, data };
}
/**
@@ -116,9 +161,7 @@
* @param data the octets making up the bit string.
* @param padBits the number of extra bits at the end of the string.
*/
- public ASN1BitString(
- byte[] data,
- int padBits)
+ ASN1BitString(byte[] data, int padBits)
{
if (data == null)
{
@@ -133,8 +176,58 @@
throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
}
- this.data = Arrays.clone(data);
- this.padBits = padBits;
+ this.contents = Arrays.prepend(data, (byte)padBits);
+ }
+
+ ASN1BitString(byte[] contents, boolean check)
+ {
+ if (check)
+ {
+ if (null == contents)
+ {
+ throw new NullPointerException("'contents' cannot be null");
+ }
+ if (contents.length < 1)
+ {
+ throw new IllegalArgumentException("'contents' cannot be empty");
+ }
+
+ int padBits = contents[0] & 0xFF;
+ if (padBits > 0)
+ {
+ if (contents.length < 2)
+ {
+ throw new IllegalArgumentException("zero length data with non-zero pad bits");
+ }
+ if (padBits > 7)
+ {
+ throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
+ }
+ }
+ }
+
+ this.contents = contents;
+ }
+
+ public InputStream getBitStream() throws IOException
+ {
+ return new ByteArrayInputStream(contents, 1, contents.length - 1);
+ }
+
+ public InputStream getOctetStream() throws IOException
+ {
+ int padBits = contents[0] & 0xFF;
+ if (0 != padBits)
+ {
+ throw new IOException("expected octet-aligned bitstring, but found padBits: " + padBits);
+ }
+
+ return getBitStream();
+ }
+
+ public ASN1BitStringParser parser()
+ {
+ return this;
}
/**
@@ -144,8 +237,6 @@
*/
public String getString()
{
- StringBuffer buf = new StringBuffer("#");
-
byte[] string;
try
{
@@ -156,10 +247,14 @@
throw new ASN1ParsingException("Internal error encoding BitString: " + e.getMessage(), e);
}
+ StringBuffer buf = new StringBuffer(1 + string.length * 2);
+ buf.append('#');
+
for (int i = 0; i != string.length; i++)
{
- buf.append(table[(string[i] >>> 4) & 0xf]);
- buf.append(table[string[i] & 0xf]);
+ byte b = string[i];
+ buf.append(table[(b >>> 4) & 0xf]);
+ buf.append(table[b & 0xf]);
}
return buf.toString();
@@ -171,15 +266,16 @@
public int intValue()
{
int value = 0;
- int end = Math.min(4, data.length - 1);
- for (int i = 0; i < end; ++i)
+ int end = Math.min(5, contents.length - 1);
+ for (int i = 1; i < end; ++i)
{
- value |= (data[i] & 0xFF) << (8 * i);
+ value |= (contents[i] & 0xFF) << (8 * (i - 1));
}
- if (0 <= end && end < 4)
+ if (1 <= end && end < 5)
{
- byte der = (byte)(data[end] & (0xFF << padBits));
- value |= (der & 0xFF) << (8 * end);
+ int padBits = contents[0] & 0xFF;
+ byte der = (byte)(contents[end] & (0xFF << padBits));
+ value |= (der & 0xFF) << (8 * (end - 1));
}
return value;
}
@@ -193,30 +289,31 @@
*/
public byte[] getOctets()
{
- if (padBits != 0)
+ if (contents[0] != 0)
{
throw new IllegalStateException("attempt to get non-octet aligned data from BIT STRING");
}
- return Arrays.clone(data);
+ return Arrays.copyOfRange(contents, 1, contents.length);
}
public byte[] getBytes()
{
- if (0 == data.length)
+ if (contents.length == 1)
{
- return data;
+ return ASN1OctetString.EMPTY_OCTETS;
}
- byte[] rv = Arrays.clone(data);
+ int padBits = contents[0] & 0xFF;
+ byte[] rv = Arrays.copyOfRange(contents, 1, contents.length);
// DER requires pad bits be zero
- rv[data.length - 1] &= (0xFF << padBits);
+ rv[rv.length - 1] &= (byte)(0xFF << padBits);
return rv;
}
public int getPadBits()
{
- return padBits;
+ return contents[0] & 0xFF;
}
public String toString()
@@ -226,85 +323,56 @@
public int hashCode()
{
- int end = data.length;
- if (--end < 0)
+ if (contents.length < 2)
{
return 1;
}
- byte der = (byte)(data[end] & (0xFF << padBits));
+ int padBits = contents[0] & 0xFF;
+ int last = contents.length - 1;
- int hc = Arrays.hashCode(data, 0, end);
+ byte lastOctetDER = (byte)(contents[last] & (0xFF << padBits));
+
+ int hc = Arrays.hashCode(contents, 0, last);
hc *= 257;
- hc ^= der;
- return hc ^ padBits;
+ hc ^= lastOctetDER;
+ return hc;
}
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive other)
{
- if (!(o instanceof ASN1BitString))
+ if (!(other instanceof ASN1BitString))
{
return false;
}
- ASN1BitString other = (ASN1BitString)o;
- if (padBits != other.padBits)
+ ASN1BitString that = (ASN1BitString)other;
+ byte[] thisContents = this.contents, thatContents = that.contents;
+
+ int length = thisContents.length;
+ if (thatContents.length != length)
{
return false;
}
- byte[] a = data, b = other.data;
- int end = a.length;
- if (end != b.length)
- {
- return false;
- }
- if (--end < 0)
+ if (length == 1)
{
return true;
}
- for (int i = 0; i < end; ++i)
+
+ int last = length - 1;
+ for (int i = 0; i < last; ++i)
{
- if (a[i] != b[i])
+ if (thisContents[i] != thatContents[i])
{
return false;
}
}
- byte derA = (byte)(a[end] & (0xFF << padBits));
- byte derB = (byte)(b[end] & (0xFF << padBits));
+ int padBits = thisContents[0] & 0xFF;
+ byte thisLastOctetDER = (byte)(thisContents[last] & (0xFF << padBits));
+ byte thatLastOctetDER = (byte)(thatContents[last] & (0xFF << padBits));
- return derA == derB;
- }
-
- static ASN1BitString fromInputStream(int length, InputStream stream)
- throws IOException
- {
- if (length < 1)
- {
- throw new IllegalArgumentException("truncated BIT STRING detected");
- }
-
- int padBits = stream.read();
- byte[] data = new byte[length - 1];
-
- if (data.length != 0)
- {
- if (Streams.readFully(stream, data) != data.length)
- {
- throw new EOFException("EOF encountered in middle of BIT STRING");
- }
-
- if (padBits > 0 && padBits < 8)
- {
- if (data[data.length - 1] != (byte)(data[data.length - 1] & (0xFF << padBits)))
- {
- return new DLBitString(data, padBits);
- }
- }
- }
-
- return new DERBitString(data, padBits);
+ return thisLastOctetDER == thatLastOctetDER;
}
public ASN1Primitive getLoadedObject()
@@ -314,13 +382,37 @@
ASN1Primitive toDERObject()
{
- return new DERBitString(data, padBits);
+ return new DERBitString(contents, false);
}
ASN1Primitive toDLObject()
{
- return new DLBitString(data, padBits);
+ return new DLBitString(contents, false);
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
+ static ASN1BitString createPrimitive(byte[] contents)
+ {
+ int length = contents.length;
+ if (length < 1)
+ {
+ throw new IllegalArgumentException("truncated BIT STRING detected");
+ }
+
+ int padBits = contents[0] & 0xFF;
+ if (padBits > 0)
+ {
+ if (padBits > 7 || length < 2)
+ {
+ throw new IllegalArgumentException("invalid pad bits detected");
+ }
+
+ byte finalOctet = contents[length - 1];
+ if (finalOctet != (byte)(finalOctet & (0xFF << padBits)))
+ {
+ return new DLBitString(contents, false);
+ }
+ }
+
+ return new DERBitString(contents, false);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitStringParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitStringParser.java
new file mode 100644
index 0000000..29c73d2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitStringParser.java
@@ -0,0 +1,40 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A basic parser for a BIT STRING object
+ */
+public interface ASN1BitStringParser
+ extends ASN1Encodable, InMemoryRepresentable
+{
+ /**
+ * Return an InputStream representing the contents of the BIT STRING. The final
+ * byte, if any, may include pad bits. See {@link #getPadBits()}.
+ *
+ * @return an InputStream with its source as the BIT STRING content.
+ */
+ public InputStream getBitStream() throws IOException;
+
+ /**
+ * Return an InputStream representing the contents of the BIT STRING, where the
+ * content is expected to be octet-aligned (this will be automatically checked
+ * during parsing).
+ *
+ * @return an InputStream with its source as the BIT STRING content.
+ */
+ public InputStream getOctetStream() throws IOException;
+
+ /**
+ * Return the number of pad bits, if any, in the final byte, if any, read from
+ * {@link #getBitStream()}. This number is in the range zero to seven. That
+ * number of the least significant bits of the final byte, if any, are not part
+ * of the contents and should be ignored. NOTE: Must be called AFTER the stream
+ * has been fully processed. (Does not need to be called if
+ * {@link #getOctetStream()} was used instead of {@link #getBitStream()}).
+ *
+ * @return the number of pad bits. In the range zero to seven.
+ */
+ public int getPadBits();
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java
index 93b40ec..752aaa6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java
@@ -16,6 +16,14 @@
public class ASN1Boolean
extends ASN1Primitive
{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Boolean.class, BERTags.BOOLEAN)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
private static final byte FALSE_VALUE = 0x00;
private static final byte TRUE_VALUE = (byte)0xFF;
@@ -44,7 +52,7 @@
byte[] enc = (byte[])obj;
try
{
- return (ASN1Boolean)fromByteArray(enc);
+ return (ASN1Boolean)TYPE.fromByteArray(enc);
}
catch (IOException e)
{
@@ -89,25 +97,16 @@
/**
* Return a Boolean from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1Boolean instance.
*/
- public static ASN1Boolean getInstance(ASN1TaggedObject obj, boolean explicit)
+ public static ASN1Boolean getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1Boolean)
- {
- return getInstance(o);
- }
- else
- {
- return ASN1Boolean.fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1Boolean)TYPE.getContextInstance(taggedObject, explicit);
}
private ASN1Boolean(byte value)
@@ -120,19 +119,19 @@
return value != FALSE_VALUE;
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 3;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, 1);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.BOOLEAN, value);
+ out.writeEncodingDL(withTag, BERTags.BOOLEAN, value);
}
boolean asn1Equals(ASN1Primitive other)
@@ -162,14 +161,14 @@
return isTrue() ? "TRUE" : "FALSE";
}
- static ASN1Boolean fromOctetString(byte[] value)
+ static ASN1Boolean createPrimitive(byte[] contents)
{
- if (value.length != 1)
+ if (contents.length != 1)
{
throw new IllegalArgumentException("BOOLEAN value should have 1 byte in it");
}
- byte b = value[0];
+ byte b = contents[0];
switch (b)
{
case FALSE_VALUE: return FALSE;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java
index 9baff44..0b011c6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java
@@ -48,6 +48,16 @@
this.elementCount = minCapacity;
}
+ public void addAll(ASN1Encodable[] others)
+ {
+ if (null == others)
+ {
+ throw new NullPointerException("'others' cannot be null");
+ }
+
+ doAddAll(others, "'others' elements cannot be null");
+ }
+
public void addAll(ASN1EncodableVector other)
{
if (null == other)
@@ -55,7 +65,12 @@
throw new NullPointerException("'other' cannot be null");
}
- int otherElementCount = other.size();
+ doAddAll(other.elements, "'other' elements cannot be null");
+ }
+
+ private void doAddAll(ASN1Encodable[] others, String nullMsg)
+ {
+ int otherElementCount = others.length;
if (otherElementCount < 1)
{
return;
@@ -71,10 +86,10 @@
int i = 0;
do
{
- ASN1Encodable otherElement = other.get(i);
+ ASN1Encodable otherElement = others[i];
if (null == otherElement)
{
- throw new NullPointerException("'other' elements cannot be null");
+ throw new NullPointerException(nullMsg);
}
this.elements[elementCount + i] = otherElement;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
index eff24a9..c2aa7dc 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
@@ -11,8 +11,13 @@
public class ASN1Enumerated
extends ASN1Primitive
{
- private final byte[] bytes;
- private final int start;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Enumerated.class, BERTags.ENUMERATED)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets(), false);
+ }
+ };
/**
* return an enumerated from the passed in object
@@ -33,7 +38,7 @@
{
try
{
- return (ASN1Enumerated)fromByteArray((byte[])obj);
+ return (ASN1Enumerated)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -47,29 +52,21 @@
/**
* return an Enumerated from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1Enumerated instance, or null.
*/
- public static ASN1Enumerated getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1Enumerated getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1Enumerated)
- {
- return getInstance(o);
- }
- else
- {
- return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1Enumerated)TYPE.getContextInstance(taggedObject, explicit);
}
+ private final byte[] contents;
+ private final int start;
+
/**
* Constructor from int.
*
@@ -82,7 +79,7 @@
throw new IllegalArgumentException("enumerated must be non-negative");
}
- this.bytes = BigInteger.valueOf(value).toByteArray();
+ this.contents = BigInteger.valueOf(value).toByteArray();
this.start = 0;
}
@@ -98,67 +95,78 @@
throw new IllegalArgumentException("enumerated must be non-negative");
}
- this.bytes = value.toByteArray();
+ this.contents = value.toByteArray();
this.start = 0;
}
/**
* Constructor from encoded BigInteger.
*
- * @param bytes the value of this enumerated as an encoded BigInteger (signed).
+ * @param contents the value of this enumerated as an encoded BigInteger (signed).
*/
- public ASN1Enumerated(byte[] bytes)
+ public ASN1Enumerated(byte[] contents)
{
- if (ASN1Integer.isMalformed(bytes))
+ this(contents, true);
+ }
+
+ ASN1Enumerated(byte[] contents, boolean clone)
+ {
+ if (ASN1Integer.isMalformed(contents))
{
throw new IllegalArgumentException("malformed enumerated");
}
- if (0 != (bytes[0] & 0x80))
+ if (0 != (contents[0] & 0x80))
{
throw new IllegalArgumentException("enumerated must be non-negative");
}
- this.bytes = Arrays.clone(bytes);
- this.start = ASN1Integer.signBytesToSkip(bytes);
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ this.start = ASN1Integer.signBytesToSkip(contents);
}
public BigInteger getValue()
{
- return new BigInteger(bytes);
+ return new BigInteger(contents);
+ }
+
+ public boolean hasValue(int x)
+ {
+ return (contents.length - start) <= 4
+ && ASN1Integer.intValue(contents, start, ASN1Integer.SIGN_EXT_SIGNED) == x;
}
public boolean hasValue(BigInteger x)
{
return null != x
// Fast check to avoid allocation
- && ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED) == x.intValue()
+ && ASN1Integer.intValue(contents, start, ASN1Integer.SIGN_EXT_SIGNED) == x.intValue()
&& getValue().equals(x);
}
public int intValueExact()
{
- int count = bytes.length - start;
+ int count = contents.length - start;
if (count > 4)
{
throw new ArithmeticException("ASN.1 Enumerated out of int range");
}
- return ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED);
+ return ASN1Integer.intValue(contents, start, ASN1Integer.SIGN_EXT_SIGNED);
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.ENUMERATED, bytes);
+ out.writeEncodingDL(withTag, BERTags.ENUMERATED, contents);
}
boolean asn1Equals(
@@ -171,39 +179,39 @@
ASN1Enumerated other = (ASN1Enumerated)o;
- return Arrays.areEqual(this.bytes, other.bytes);
+ return Arrays.areEqual(this.contents, other.contents);
}
public int hashCode()
{
- return Arrays.hashCode(bytes);
+ return Arrays.hashCode(contents);
}
- private static ASN1Enumerated[] cache = new ASN1Enumerated[12];
+ private static final ASN1Enumerated[] cache = new ASN1Enumerated[12];
- static ASN1Enumerated fromOctetString(byte[] enc)
+ static ASN1Enumerated createPrimitive(byte[] contents, boolean clone)
{
- if (enc.length > 1)
+ if (contents.length > 1)
{
- return new ASN1Enumerated(enc);
+ return new ASN1Enumerated(contents, clone);
}
- if (enc.length == 0)
+ if (contents.length == 0)
{
throw new IllegalArgumentException("ENUMERATED has zero length");
}
- int value = enc[0] & 0xff;
+ int value = contents[0] & 0xff;
if (value >= cache.length)
{
- return new ASN1Enumerated(enc);
+ return new ASN1Enumerated(contents, clone);
}
ASN1Enumerated possibleMatch = cache[value];
if (possibleMatch == null)
{
- possibleMatch = cache[value] = new ASN1Enumerated(enc);
+ possibleMatch = cache[value] = new ASN1Enumerated(contents, clone);
}
return possibleMatch;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1External.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1External.java
index 082605d..c246164 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1External.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1External.java
@@ -2,107 +2,132 @@
import java.io.IOException;
+import org.bouncycastle.util.Objects;
+
/**
* Class representing the DER-type External
*/
public abstract class ASN1External
extends ASN1Primitive
{
- protected ASN1ObjectIdentifier directReference;
- protected ASN1Integer indirectReference;
- protected ASN1Primitive dataValueDescriptor;
- protected int encoding;
- protected ASN1Primitive externalContent;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1External.class, BERTags.EXTERNAL)
+ {
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ // TODO Ideally ASN1External would have no subclasses and just hold the sequence
+ return sequence.toASN1External();
+ }
+ };
- /**
- * Construct an EXTERNAL object, the input encoding vector must have exactly two elements on it.
- * <p>
- * Acceptable input formats are:
- * <ul>
- * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
- * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
- * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
- * </ul>
- *
- * @throws IllegalArgumentException if input size is wrong, or
- */
- public ASN1External(ASN1EncodableVector vector)
+ public static ASN1External getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1External)
+ {
+ return (ASN1External)obj;
+ }
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1External)
+ {
+ return (ASN1External)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1External)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct external from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ public static ASN1External getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1External)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ ASN1ObjectIdentifier directReference;
+ ASN1Integer indirectReference;
+ // TODO Actually use ASN1ObjectDescriptor for this
+ ASN1Primitive dataValueDescriptor;
+ int encoding;
+ ASN1Primitive externalContent;
+
+ ASN1External(ASN1Sequence sequence)
{
int offset = 0;
- ASN1Primitive enc = getObjFromVector(vector, offset);
- if (enc instanceof ASN1ObjectIdentifier)
+ ASN1Primitive asn1 = getObjFromSequence(sequence, offset);
+ if (asn1 instanceof ASN1ObjectIdentifier)
{
- directReference = (ASN1ObjectIdentifier)enc;
- offset++;
- enc = getObjFromVector(vector, offset);
+ directReference = (ASN1ObjectIdentifier)asn1;
+ asn1 = getObjFromSequence(sequence, ++offset);
}
- if (enc instanceof ASN1Integer)
+ if (asn1 instanceof ASN1Integer)
{
- indirectReference = (ASN1Integer) enc;
- offset++;
- enc = getObjFromVector(vector, offset);
+ indirectReference = (ASN1Integer)asn1;
+ asn1 = getObjFromSequence(sequence, ++offset);
}
- if (!(enc instanceof ASN1TaggedObject))
+ if (!(asn1 instanceof ASN1TaggedObject))
{
- dataValueDescriptor = (ASN1Primitive) enc;
- offset++;
- enc = getObjFromVector(vector, offset);
+ dataValueDescriptor = asn1;
+ asn1 = getObjFromSequence(sequence, ++offset);
}
- if (vector.size() != offset + 1)
+ if (sequence.size() != offset + 1)
{
- throw new IllegalArgumentException("input vector too large");
+ throw new IllegalArgumentException("input sequence too large");
}
- if (!(enc instanceof ASN1TaggedObject))
+ if (!(asn1 instanceof ASN1TaggedObject))
{
- throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
+ throw new IllegalArgumentException(
+ "No tagged object found in sequence. Structure doesn't seem to be of type External");
}
- ASN1TaggedObject obj = (ASN1TaggedObject)enc;
- setEncoding(obj.getTagNo());
- externalContent = obj.getObject();
+
+ ASN1TaggedObject obj = (ASN1TaggedObject)asn1;
+ this.encoding = checkEncoding(obj.getTagNo());
+ this.externalContent = getExternalContent(obj);
}
- private ASN1Primitive getObjFromVector(ASN1EncodableVector v, int index)
+ ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor,
+ DERTaggedObject externalData)
{
- if (v.size() <= index)
- {
- throw new IllegalArgumentException("too few objects in input vector");
- }
-
- return v.get(index).toASN1Primitive();
+ this.directReference = directReference;
+ this.indirectReference = indirectReference;
+ this.dataValueDescriptor = dataValueDescriptor;
+ this.encoding = checkEncoding(externalData.getTagNo());
+ this.externalContent = getExternalContent(externalData);
}
- /**
- * Creates a new instance of External
- * See X.690 for more informations about the meaning of these parameters
- * @param directReference The direct reference or <code>null</code> if not set.
- * @param indirectReference The indirect reference or <code>null</code> if not set.
- * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
- * @param externalData The external data in its encoded form.
- */
- public ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor,
+ int encoding, ASN1Primitive externalData)
{
- this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ this.directReference = directReference;
+ this.indirectReference = indirectReference;
+ this.dataValueDescriptor = dataValueDescriptor;
+ this.encoding = checkEncoding(encoding);
+ this.externalContent = checkExternalContent(encoding, externalData);
}
- /**
- * Creates a new instance of External.
- * See X.690 for more informations about the meaning of these parameters
- * @param directReference The direct reference or <code>null</code> if not set.
- * @param indirectReference The indirect reference or <code>null</code> if not set.
- * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
- * @param encoding The encoding to be used for the external data
- * @param externalData The external data
- */
- public ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ abstract ASN1Sequence buildSequence();
+
+ int encodedLength(boolean withTag) throws IOException
{
- setDirectReference(directReference);
- setIndirectReference(indirectReference);
- setDataValueDescriptor(dataValueDescriptor);
- setEncoding(encoding);
- setExternalContent(externalData.toASN1Primitive());
+ return buildSequence().encodedLength(withTag);
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.EXTERNAL);
+ buildSequence().encode(out, false);
}
ASN1Primitive toDERObject()
@@ -115,75 +140,38 @@
return new DLExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
}
- /* (non-Javadoc)
- * @see java.lang.Object#hashCode()
- */
public int hashCode()
{
- int ret = 0;
- if (directReference != null)
- {
- ret = directReference.hashCode();
- }
- if (indirectReference != null)
- {
- ret ^= indirectReference.hashCode();
- }
- if (dataValueDescriptor != null)
- {
- ret ^= dataValueDescriptor.hashCode();
- }
- ret ^= externalContent.hashCode();
- return ret;
+ return Objects.hashCode(this.directReference)
+ ^ Objects.hashCode(this.indirectReference)
+ ^ Objects.hashCode(this.dataValueDescriptor)
+ ^ this.encoding
+ ^ this.externalContent.hashCode();
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return true;
}
- int encodedLength()
- throws IOException
+ boolean asn1Equals(ASN1Primitive primitive)
{
- return this.getEncoded().length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#asn1Equals(org.bouncycastle.asn1.ASN1Primitive)
- */
- boolean asn1Equals(ASN1Primitive o)
- {
- if (!(o instanceof ASN1External))
- {
- return false;
- }
- if (this == o)
+ if (this == primitive)
{
return true;
}
- ASN1External other = (ASN1External)o;
- if (directReference != null)
+ if (!(primitive instanceof ASN1External))
{
- if (other.directReference == null || !other.directReference.equals(directReference))
- {
- return false;
- }
+ return false;
}
- if (indirectReference != null)
- {
- if (other.indirectReference == null || !other.indirectReference.equals(indirectReference))
- {
- return false;
- }
- }
- if (dataValueDescriptor != null)
- {
- if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor))
- {
- return false;
- }
- }
- return externalContent.equals(other.externalContent);
+
+ ASN1External that = (ASN1External)primitive;
+
+ return Objects.areEqual(this.directReference, that.directReference)
+ && Objects.areEqual(this.indirectReference, that.indirectReference)
+ && Objects.areEqual(this.dataValueDescriptor, that.dataValueDescriptor)
+ && this.encoding == that.encoding
+ && this.externalContent.equals(that.externalContent);
}
/**
@@ -217,7 +205,7 @@
{
return encoding;
}
-
+
/**
* Returns the content of this element
* @return The content
@@ -226,7 +214,7 @@
{
return externalContent;
}
-
+
/**
* Returns the indirect reference of this element
* @return The reference
@@ -235,27 +223,9 @@
{
return indirectReference;
}
-
- /**
- * Sets the data value descriptor
- * @param dataValueDescriptor The descriptor
- */
- private void setDataValueDescriptor(ASN1Primitive dataValueDescriptor)
- {
- this.dataValueDescriptor = dataValueDescriptor;
- }
/**
- * Sets the direct reference of the external element
- * @param directReferemce The reference
- */
- private void setDirectReference(ASN1ObjectIdentifier directReferemce)
- {
- this.directReference = directReferemce;
- }
-
- /**
- * Sets the encoding of the content. Valid values are
+ * Checks the encoding of the content. Valid values are
* <ul>
* <li><code>0</code> single-ASN1-type</li>
* <li><code>1</code> OCTET STRING</li>
@@ -263,30 +233,57 @@
* </ul>
* @param encoding The encoding
*/
- private void setEncoding(int encoding)
+ private static int checkEncoding(int encoding)
{
if (encoding < 0 || encoding > 2)
{
throw new IllegalArgumentException("invalid encoding value: " + encoding);
}
- this.encoding = encoding;
+
+ return encoding;
}
-
- /**
- * Sets the content of this element
- * @param externalContent The content
- */
- private void setExternalContent(ASN1Primitive externalContent)
+
+ private static ASN1Primitive checkExternalContent(int tagNo, ASN1Primitive externalContent)
{
- this.externalContent = externalContent;
+ switch (tagNo)
+ {
+ case 1:
+ return ASN1OctetString.TYPE.checkedCast(externalContent);
+ case 2:
+ return ASN1BitString.TYPE.checkedCast(externalContent);
+ default:
+ return externalContent;
+ }
}
-
- /**
- * Sets the indirect reference of this element
- * @param indirectReference The reference
- */
- private void setIndirectReference(ASN1Integer indirectReference)
+
+ private static ASN1Primitive getExternalContent(ASN1TaggedObject encoding)
{
- this.indirectReference = indirectReference;
+ int tagClass = encoding.getTagClass(), tagNo = encoding.getTagNo();
+ if (BERTags.CONTEXT_SPECIFIC != tagClass)
+ {
+ throw new IllegalArgumentException("invalid tag: " + ASN1Util.getTagText(tagClass, tagNo));
+ }
+
+ switch (tagNo)
+ {
+ case 0:
+ return encoding.getExplicitBaseObject().toASN1Primitive();
+ case 1:
+ return ASN1OctetString.getInstance(encoding, false);
+ case 2:
+ return ASN1BitString.getInstance(encoding, false);
+ default:
+ throw new IllegalArgumentException("invalid tag: " + ASN1Util.getTagText(tagClass, tagNo));
+ }
+ }
+
+ private static ASN1Primitive getObjFromSequence(ASN1Sequence sequence, int index)
+ {
+ if (sequence.size() <= index)
+ {
+ throw new IllegalArgumentException("too few objects in input sequence");
+ }
+
+ return sequence.getObjectAt(index).toASN1Primitive();
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ExternalParser.java
similarity index 76%
rename from bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java
rename to bcprov/src/main/java/org/bouncycastle/asn1/ASN1ExternalParser.java
index 422bccf..e335e54 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ExternalParser.java
@@ -3,9 +3,9 @@
import java.io.IOException;
/**
- * Interface to parse ASN.1 ApplicationSpecific objects.
+ * Parser DER EXTERNAL tagged objects.
*/
-public interface ASN1ApplicationSpecificParser
+public interface ASN1ExternalParser
extends ASN1Encodable, InMemoryRepresentable
{
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralString.java
new file mode 100644
index 0000000..c527f4d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralString.java
@@ -0,0 +1,151 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 GENERAL-STRING data type.
+ * <p>
+ * This is an 8-bit encoded ISO 646 (ASCII) character set
+ * with optional escapes to other character sets.
+ * </p>
+ */
+public abstract class ASN1GeneralString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1GeneralString.class, BERTags.GENERAL_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a GeneralString from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1GeneralString instance, or null.
+ */
+ public static ASN1GeneralString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1GeneralString)
+ {
+ return (ASN1GeneralString) obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1GeneralString)
+ {
+ return (ASN1GeneralString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1GeneralString)TYPE.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());
+ }
+
+ /**
+ * Return a GeneralString from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1GeneralString instance.
+ */
+ public static ASN1GeneralString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1GeneralString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1GeneralString(String string)
+ {
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1GeneralString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ /**
+ * Return a Java String representation of our contained String.
+ *
+ * @return a Java String representing our contents.
+ */
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ /**
+ * Return a byte array representation of our contained String.
+ *
+ * @return a byte array representing our contents.
+ */
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.GENERAL_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1GeneralString))
+ {
+ return false;
+ }
+
+ ASN1GeneralString that = (ASN1GeneralString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1GeneralString createPrimitive(byte[] contents)
+ {
+ return new DERGeneralString(contents, false);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java
index 3d076cc..620e1ad 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java
@@ -46,7 +46,13 @@
public class ASN1GeneralizedTime
extends ASN1Primitive
{
- protected byte[] time;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1GeneralizedTime.class, BERTags.GENERALIZED_TIME)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
/**
* return a generalized time from the passed in object
@@ -62,12 +68,19 @@
{
return (ASN1GeneralizedTime)obj;
}
-
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1GeneralizedTime)
+ {
+ return (ASN1GeneralizedTime)primitive;
+ }
+ }
if (obj instanceof byte[])
{
try
{
- return (ASN1GeneralizedTime)fromByteArray((byte[])obj);
+ return (ASN1GeneralizedTime)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -81,29 +94,19 @@
/**
* return a Generalized Time object from a tagged object.
*
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
* @return an ASN1GeneralizedTime instance.
- * @throws IllegalArgumentException if the tagged object cannot
- * be converted.
+ * @throws IllegalArgumentException if the tagged object cannot be converted.
*/
- public static ASN1GeneralizedTime getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1GeneralizedTime getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1GeneralizedTime)
- {
- return getInstance(o);
- }
- else
- {
- return new ASN1GeneralizedTime(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1GeneralizedTime)TYPE.getContextInstance(taggedObject, explicit);
}
+ final byte[] contents;
+
/**
* The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z
* for local time, or Z+-HHMM on the end, for difference between local
@@ -116,7 +119,7 @@
public ASN1GeneralizedTime(
String time)
{
- this.time = Strings.toByteArray(time);
+ this.contents = Strings.toByteArray(time);
try
{
this.getDate();
@@ -141,7 +144,7 @@
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
/**
@@ -163,7 +166,7 @@
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
ASN1GeneralizedTime(
@@ -173,7 +176,7 @@
{
throw new IllegalArgumentException("GeneralizedTime string too short");
}
- this.time = bytes;
+ this.contents = bytes;
if (!(isDigit(0) && isDigit(1) && isDigit(2) && isDigit(3)))
{
@@ -188,7 +191,7 @@
*/
public String getTimeString()
{
- return Strings.fromByteArray(time);
+ return Strings.fromByteArray(contents);
}
/**
@@ -206,7 +209,7 @@
*/
public String getTime()
{
- String stime = Strings.fromByteArray(time);
+ String stime = Strings.fromByteArray(contents);
//
// standardise the format.
@@ -358,34 +361,26 @@
throws ParseException
{
SimpleDateFormat dateF;
- String stime = Strings.fromByteArray(time);
+ String stime = Strings.fromByteArray(contents);
String d = stime;
if (stime.endsWith("Z"))
{
if (hasFractionalSeconds())
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'", LocaleUtil.EN_Locale);
}
else if (hasSeconds())
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", LocaleUtil.EN_Locale);
}
else if (hasMinutes())
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmm'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHHmm'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHHmm'Z'", LocaleUtil.EN_Locale);
}
else
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHH'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHH'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHH'Z'", LocaleUtil.EN_Locale);
}
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
@@ -430,14 +425,14 @@
d = pruneFractionalSeconds(d);
}
- return DateUtil.epochAdjust(dateF.parse(d));
+ return dateF.parse(d);
}
protected boolean hasFractionalSeconds()
{
- for (int i = 0; i != time.length; i++)
+ for (int i = 0; i != contents.length; i++)
{
- if (time[i] == '.')
+ if (contents[i] == '.')
{
if (i == 14)
{
@@ -460,49 +455,46 @@
private boolean isDigit(int pos)
{
- return time.length > pos && time[pos] >= '0' && time[pos] <= '9';
+ return contents.length > pos && contents[pos] >= '0' && contents[pos] <= '9';
}
- boolean isConstructed()
+ final boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- int length = time.length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, time);
+ out.writeEncodingDL(withTag, BERTags.GENERALIZED_TIME, contents);
}
ASN1Primitive toDERObject()
{
- return new DERGeneralizedTime(time);
+ return new DERGeneralizedTime(contents);
}
- ASN1Primitive toDLObject()
- {
- return new DERGeneralizedTime(time);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive o)
{
if (!(o instanceof ASN1GeneralizedTime))
{
return false;
}
- return Arrays.areEqual(time, ((ASN1GeneralizedTime)o).time);
+ return Arrays.areEqual(contents, ((ASN1GeneralizedTime)o).contents);
}
public int hashCode()
{
- return Arrays.hashCode(time);
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1GeneralizedTime createPrimitive(byte[] contents)
+ {
+ return new ASN1GeneralizedTime(contents);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GraphicString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GraphicString.java
new file mode 100644
index 0000000..b21142b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GraphicString.java
@@ -0,0 +1,128 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+public abstract class ASN1GraphicString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1GraphicString.class, BERTags.GRAPHIC_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a GraphicString from the passed in object.
+ *
+ * @param obj an ASN1GraphicString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1GraphicString instance, or null.
+ */
+ public static ASN1GraphicString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1GraphicString)
+ {
+ return (ASN1GraphicString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1GraphicString)
+ {
+ return (ASN1GraphicString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1GraphicString)TYPE.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());
+ }
+
+ /**
+ * Return a GraphicString from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly tagged,
+ * false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1GraphicString instance, or null.
+ */
+ public static ASN1GraphicString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1GraphicString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1GraphicString(byte[] contents, boolean clone)
+ {
+ if (null == contents)
+ {
+ throw new NullPointerException("'contents' cannot be null");
+ }
+
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.GRAPHIC_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1GraphicString))
+ {
+ return false;
+ }
+
+ ASN1GraphicString that = (ASN1GraphicString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ static ASN1GraphicString createPrimitive(byte[] contents)
+ {
+ return new DERGraphicString(contents, false);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1IA5String.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1IA5String.java
new file mode 100644
index 0000000..ecf848f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1IA5String.java
@@ -0,0 +1,170 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 IA5String object - this is a ISO 646 (ASCII) string encoding code points 0 to 127.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ */
+public abstract class ASN1IA5String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1IA5String.class, BERTags.IA5_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return an IA5 string from the passed in object
+ *
+ * @param obj an ASN1IA5String or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a ASN1IA5String instance, or null.
+ */
+ public static ASN1IA5String getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1IA5String)
+ {
+ return (ASN1IA5String)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1IA5String)
+ {
+ return (ASN1IA5String)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1IA5String)TYPE.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());
+ }
+
+ /**
+ * Return an IA5 String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1IA5String instance, or null.
+ */
+ public static ASN1IA5String getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1IA5String)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1IA5String(String string, boolean validate)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+ if (validate && !isIA5String(string))
+ {
+ throw new IllegalArgumentException("'string' contains illegal characters");
+ }
+
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1IA5String(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.IA5_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1IA5String))
+ {
+ return false;
+ }
+
+ ASN1IA5String that = (ASN1IA5String)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ /**
+ * return true if the passed in String can be represented without
+ * loss as an IA5String, false otherwise.
+ *
+ * @param str the string to check.
+ * @return true if character set in IA5String set, false otherwise.
+ */
+ public static boolean isIA5String(String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ static ASN1IA5String createPrimitive(byte[] contents)
+ {
+ return new DERIA5String(contents, false);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java
index ca8257b..ff7e3e0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java
@@ -20,11 +20,9 @@
{
private final int limit;
private final boolean lazyEvaluate;
-
private final byte[][] tmpBuffers;
- public ASN1InputStream(
- InputStream is)
+ public ASN1InputStream(InputStream is)
{
this(is, StreamUtil.findLimit(is));
}
@@ -35,8 +33,7 @@
*
* @param input array containing ASN.1 encoded data.
*/
- public ASN1InputStream(
- byte[] input)
+ public ASN1InputStream(byte[] input)
{
this(new ByteArrayInputStream(input), input.length);
}
@@ -48,22 +45,18 @@
* @param input array containing ASN.1 encoded data.
* @param lazyEvaluate true if parsing inside constructed objects can be delayed.
*/
- public ASN1InputStream(
- byte[] input,
- boolean lazyEvaluate)
+ public ASN1InputStream(byte[] input, boolean lazyEvaluate)
{
this(new ByteArrayInputStream(input), input.length, lazyEvaluate);
}
-
+
/**
* Create an ASN1InputStream where no DER object will be longer than limit.
*
* @param input stream containing ASN.1 encoded data.
* @param limit maximum size of a DER encoded object.
*/
- public ASN1InputStream(
- InputStream input,
- int limit)
+ public ASN1InputStream(InputStream input, int limit)
{
this(input, limit, false);
}
@@ -75,9 +68,7 @@
* @param input stream containing ASN.1 encoded data.
* @param lazyEvaluate true if parsing inside constructed objects can be delayed.
*/
- public ASN1InputStream(
- InputStream input,
- boolean lazyEvaluate)
+ public ASN1InputStream(InputStream input, boolean lazyEvaluate)
{
this(input, StreamUtil.findLimit(input), lazyEvaluate);
}
@@ -90,15 +81,17 @@
* @param limit maximum size of a DER encoded object.
* @param lazyEvaluate true if parsing inside constructed objects can be delayed.
*/
- public ASN1InputStream(
- InputStream input,
- int limit,
- boolean lazyEvaluate)
+ public ASN1InputStream(InputStream input, int limit, boolean lazyEvaluate)
+ {
+ this(input, limit, lazyEvaluate, new byte[11][]);
+ }
+
+ private ASN1InputStream(InputStream input, int limit, boolean lazyEvaluate, byte[][] tmpBuffers)
{
super(input);
this.limit = limit;
this.lazyEvaluate = lazyEvaluate;
- this.tmpBuffers = new byte[11][];
+ this.tmpBuffers = tmpBuffers;
}
int getLimit()
@@ -116,7 +109,7 @@
byte[] bytes)
throws IOException
{
- if (Streams.readFully(this, bytes) != bytes.length)
+ if (Streams.readFully(this, bytes, 0, bytes.length) != bytes.length)
{
throw new EOFException("EOF encountered in middle of object");
}
@@ -137,82 +130,57 @@
int length)
throws IOException
{
- boolean isConstructed = (tag & CONSTRUCTED) != 0;
+ // TODO[asn1] Special-case zero length first?
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length, limit);
- if ((tag & APPLICATION) != 0)
+ if (0 == (tag & FLAGS))
{
- return new DLApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
+ return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
}
- if ((tag & TAGGED) != 0)
+ int tagClass = tag & PRIVATE;
+ if (0 != tagClass)
{
- return new ASN1StreamParser(defIn).readTaggedObject(isConstructed, tagNo);
+ boolean isConstructed = (tag & CONSTRUCTED) != 0;
+ return readTaggedObjectDL(tagClass, tagNo, isConstructed, defIn);
}
- if (isConstructed)
+ switch (tagNo)
{
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagNo)
+ case BIT_STRING:
+ {
+ return buildConstructedBitString(readVector(defIn));
+ }
+ case OCTET_STRING:
+ {
+ //
+ // yes, people actually do this...
+ //
+ return buildConstructedOctetString(readVector(defIn));
+ }
+ case SEQUENCE:
+ {
+ if (defIn.getRemaining() < 1)
{
- case OCTET_STRING:
- //
- // yes, people actually do this...
- //
- ASN1EncodableVector v = readVector(defIn);
- ASN1OctetString[] strings = new ASN1OctetString[v.size()];
-
- for (int i = 0; i != strings.length; i++)
- {
- ASN1Encodable asn1Obj = v.get(i);
- if (asn1Obj instanceof ASN1OctetString)
- {
- strings[i] = (ASN1OctetString)asn1Obj;
- }
- else
- {
- throw new ASN1Exception("unknown object encountered in constructed OCTET STRING: " + asn1Obj.getClass());
- }
- }
-
- return new BEROctetString(strings);
- case SEQUENCE:
- if (lazyEvaluate)
- {
- return new LazyEncodedSequence(defIn.toByteArray());
- }
- else
- {
- return DLFactory.createSequence(readVector(defIn));
- }
- case SET:
- return DLFactory.createSet(readVector(defIn));
- case EXTERNAL:
- return new DLExternal(readVector(defIn));
- default:
- throw new IOException("unknown tag " + tagNo + " encountered");
+ return DLFactory.EMPTY_SEQUENCE;
+ }
+ else if (lazyEvaluate)
+ {
+ return new LazyEncodedSequence(defIn.toByteArray());
+ }
+ else
+ {
+ return DLFactory.createSequence(readVector(defIn));
}
}
-
- return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
- }
-
- ASN1EncodableVector readVector(DefiniteLengthInputStream dIn) throws IOException
- {
- if (dIn.getRemaining() < 1)
- {
- return new ASN1EncodableVector(0);
+ case SET:
+ return DLFactory.createSet(readVector(defIn));
+ case EXTERNAL:
+ return DLFactory.createSequence(readVector(defIn)).toASN1External();
+ default:
+ throw new IOException("unknown tag " + tagNo + " encountered");
}
-
- ASN1InputStream subStream = new ASN1InputStream(dIn);
- ASN1EncodableVector v = new ASN1EncodableVector();
- ASN1Primitive p;
- while ((p = subStream.readObject()) != null)
- {
- v.add(p);
- }
- return v;
}
public ASN1Primitive readObject()
@@ -229,55 +197,12 @@
return null;
}
- //
- // calculate tag number
- //
int tagNo = readTagNumber(this, tag);
-
- boolean isConstructed = (tag & CONSTRUCTED) != 0;
-
- //
- // calculate length
- //
int length = readLength();
- if (length < 0) // indefinite-length method
+ if (length >= 0)
{
- if (!isConstructed)
- {
- throw new IOException("indefinite-length primitive encoding encountered");
- }
-
- IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit);
- ASN1StreamParser sp = new ASN1StreamParser(indIn, limit);
-
- if ((tag & APPLICATION) != 0)
- {
- return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject();
- }
-
- if ((tag & TAGGED) != 0)
- {
- return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject();
- }
-
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagNo)
- {
- case OCTET_STRING:
- return new BEROctetStringParser(sp).getLoadedObject();
- case SEQUENCE:
- return new BERSequenceParser(sp).getLoadedObject();
- case SET:
- return new BERSetParser(sp).getLoadedObject();
- case EXTERNAL:
- return new DERExternalParser(sp).getLoadedObject();
- default:
- throw new IOException("unknown BER object encountered");
- }
- }
- else
- {
+ // definite-length
try
{
return buildObject(tag, tagNo, length);
@@ -287,6 +212,124 @@
throw new ASN1Exception("corrupted stream detected", e);
}
}
+
+ // indefinite-length
+
+ if (0 == (tag & CONSTRUCTED))
+ {
+ throw new IOException("indefinite-length primitive encoding encountered");
+ }
+
+ IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit);
+ ASN1StreamParser sp = new ASN1StreamParser(indIn, limit, tmpBuffers);
+
+ int tagClass = tag & PRIVATE;
+ if (0 != tagClass)
+ {
+ return sp.loadTaggedIL(tagClass, tagNo);
+ }
+
+ switch (tagNo)
+ {
+ case BIT_STRING:
+ return BERBitStringParser.parse(sp);
+ case OCTET_STRING:
+ return BEROctetStringParser.parse(sp);
+ case EXTERNAL:
+ // TODO[asn1] BERExternalParser
+ return DERExternalParser.parse(sp);
+ case SEQUENCE:
+ return BERSequenceParser.parse(sp);
+ case SET:
+ return BERSetParser.parse(sp);
+ default:
+ throw new IOException("unknown BER object encountered");
+ }
+ }
+
+ ASN1BitString buildConstructedBitString(ASN1EncodableVector contentsElements) throws IOException
+ {
+ ASN1BitString[] strings = new ASN1BitString[contentsElements.size()];
+
+ for (int i = 0; i != strings.length; i++)
+ {
+ ASN1Encodable asn1Obj = contentsElements.get(i);
+ if (asn1Obj instanceof ASN1BitString)
+ {
+ strings[i] = (ASN1BitString)asn1Obj;
+ }
+ else
+ {
+ throw new ASN1Exception(
+ "unknown object encountered in constructed BIT STRING: " + asn1Obj.getClass());
+ }
+ }
+
+ // TODO Probably ought to be DLBitString
+ return new BERBitString(strings);
+ }
+
+ ASN1OctetString buildConstructedOctetString(ASN1EncodableVector contentsElements) throws IOException
+ {
+ ASN1OctetString[] strings = new ASN1OctetString[contentsElements.size()];
+
+ for (int i = 0; i != strings.length; i++)
+ {
+ ASN1Encodable asn1Obj = contentsElements.get(i);
+ if (asn1Obj instanceof ASN1OctetString)
+ {
+ strings[i] = (ASN1OctetString)asn1Obj;
+ }
+ else
+ {
+ throw new ASN1Exception(
+ "unknown object encountered in constructed OCTET STRING: " + asn1Obj.getClass());
+ }
+ }
+
+ // TODO Probably ought to be DEROctetString (no DLOctetString available)
+ return new BEROctetString(strings);
+ }
+
+ ASN1Primitive readTaggedObjectDL(int tagClass, int tagNo, boolean constructed, DefiniteLengthInputStream defIn)
+ throws IOException
+ {
+ if (!constructed)
+ {
+ byte[] contentsOctets = defIn.toByteArray();
+ return ASN1TaggedObject.createPrimitive(tagClass, tagNo, contentsOctets);
+ }
+
+ ASN1EncodableVector contentsElements = readVector(defIn);
+ return ASN1TaggedObject.createConstructedDL(tagClass, tagNo, contentsElements);
+ }
+
+ ASN1EncodableVector readVector() throws IOException
+ {
+ ASN1Primitive p = readObject();
+ if (null == p)
+ {
+ return new ASN1EncodableVector(0);
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ do
+ {
+ v.add(p);
+ }
+ while ((p = readObject()) != null);
+ return v;
+ }
+
+ ASN1EncodableVector readVector(DefiniteLengthInputStream defIn) throws IOException
+ {
+ int remaining = defIn.getRemaining();
+ if (remaining < 1)
+ {
+ return new ASN1EncodableVector(0);
+ }
+
+ return new ASN1InputStream(defIn, remaining, lazyEvaluate, tmpBuffers).readVector();
}
static int readTagNumber(InputStream s, int tag)
@@ -299,32 +342,44 @@
//
if (tagNo == 0x1f)
{
- tagNo = 0;
-
int b = s.read();
+ if (b < 31)
+ {
+ if (b < 0)
+ {
+ throw new EOFException("EOF found inside tag value.");
+ }
+ throw new IOException("corrupted stream - high tag number < 31 found");
+ }
+
+ tagNo = b & 0x7f;
// X.690-0207 8.1.2.4.2
// "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
- if ((b & 0x7f) == 0) // Note: -1 will pass
+ if (0 == tagNo)
{
throw new IOException("corrupted stream - invalid high tag number found");
}
- while ((b >= 0) && ((b & 0x80) != 0))
+ while ((b & 0x80) != 0)
{
- tagNo |= (b & 0x7f);
- tagNo <<= 7;
- b = s.read();
- }
+ if ((tagNo >>> 24) != 0)
+ {
+ throw new IOException("Tag number more than 31 bits");
+ }
- if (b < 0)
- {
- throw new EOFException("EOF found inside tag value.");
+ tagNo <<= 7;
+
+ b = s.read();
+ if (b < 0)
+ {
+ throw new EOFException("EOF found inside tag value.");
+ }
+
+ tagNo |= (b & 0x7f);
}
-
- tagNo |= (b & 0x7f);
}
-
+
return tagNo;
}
@@ -332,48 +387,48 @@
throws IOException
{
int length = s.read();
+ if (0 == (length >>> 7))
+ {
+ // definite-length short form
+ return length;
+ }
+ if (0x80 == length)
+ {
+ // indefinite-length
+ return -1;
+ }
if (length < 0)
{
throw new EOFException("EOF found when length expected");
}
-
- if (length == 0x80)
+ if (0xFF == length)
{
- return -1; // indefinite-length encoding
+ throw new IOException("invalid long form definite-length 0xFF");
}
- if (length > 127)
+ int octetsCount = length & 0x7F, octetsPos = 0;
+
+ length = 0;
+ do
{
- int size = length & 0x7f;
-
- // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
- if (size > 4)
+ int octet = s.read();
+ if (octet < 0)
{
- throw new IOException("DER length more than 4 bytes: " + size);
+ throw new EOFException("EOF found reading length");
}
- length = 0;
- for (int i = 0; i < size; i++)
+ if ((length >>> 23) != 0)
{
- int next = s.read();
-
- if (next < 0)
- {
- throw new EOFException("EOF found reading length");
- }
-
- length = (length << 8) + next;
+ throw new IOException("long form definite-length more than 31 bits");
}
- if (length < 0)
- {
- throw new IOException("corrupted stream - negative length found");
- }
+ length = (length << 8) + octet;
+ }
+ while (++octetsPos < octetsCount);
- if (length >= limit && !isParsing) // after all we must have read at least 1 byte
- {
- throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
- }
+ if (length >= limit && !isParsing) // after all we must have read at least 1 byte
+ {
+ throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
}
return length;
@@ -457,50 +512,79 @@
byte[][] tmpBuffers)
throws IOException
{
- switch (tagNo)
+ /*
+ * TODO[asn1] Lookup the universal type object and get it to parse the stream directly (possibly with
+ * access to a single temporary buffer replacing tmpBuffers).
+ */
+ try
{
+ switch (tagNo)
+ {
case BIT_STRING:
- return ASN1BitString.fromInputStream(defIn.getRemaining(), defIn);
+ return ASN1BitString.createPrimitive(defIn.toByteArray());
case BMP_STRING:
- return new DERBMPString(getBMPCharBuffer(defIn));
+ return ASN1BMPString.createPrimitive(getBMPCharBuffer(defIn));
case BOOLEAN:
- return ASN1Boolean.fromOctetString(getBuffer(defIn, tmpBuffers));
+ return ASN1Boolean.createPrimitive(getBuffer(defIn, tmpBuffers));
case ENUMERATED:
- return ASN1Enumerated.fromOctetString(getBuffer(defIn, tmpBuffers));
- case GENERALIZED_TIME:
- return new ASN1GeneralizedTime(defIn.toByteArray());
+ // TODO Ideally only clone if we used a buffer
+ return ASN1Enumerated.createPrimitive(getBuffer(defIn, tmpBuffers), true);
case GENERAL_STRING:
- return new DERGeneralString(defIn.toByteArray());
- case IA5_STRING:
- return new DERIA5String(defIn.toByteArray());
- case INTEGER:
- return new ASN1Integer(defIn.toByteArray(), false);
- case NULL:
- return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?)
- case NUMERIC_STRING:
- return new DERNumericString(defIn.toByteArray());
- case OBJECT_IDENTIFIER:
- return ASN1ObjectIdentifier.fromOctetString(getBuffer(defIn, tmpBuffers));
- case OCTET_STRING:
- return new DEROctetString(defIn.toByteArray());
- case PRINTABLE_STRING:
- return new DERPrintableString(defIn.toByteArray());
- case T61_STRING:
- return new DERT61String(defIn.toByteArray());
- case UNIVERSAL_STRING:
- return new DERUniversalString(defIn.toByteArray());
- case UTC_TIME:
- return new ASN1UTCTime(defIn.toByteArray());
- case UTF8_STRING:
- return new DERUTF8String(defIn.toByteArray());
- case VISIBLE_STRING:
- return new DERVisibleString(defIn.toByteArray());
+ return ASN1GeneralString.createPrimitive(defIn.toByteArray());
+ case GENERALIZED_TIME:
+ return ASN1GeneralizedTime.createPrimitive(defIn.toByteArray());
case GRAPHIC_STRING:
- return new DERGraphicString(defIn.toByteArray());
+ return ASN1GraphicString.createPrimitive(defIn.toByteArray());
+ case IA5_STRING:
+ return ASN1IA5String.createPrimitive(defIn.toByteArray());
+ case INTEGER:
+ return ASN1Integer.createPrimitive(defIn.toByteArray());
+ case NULL:
+ return ASN1Null.createPrimitive(defIn.toByteArray());
+ case NUMERIC_STRING:
+ return ASN1NumericString.createPrimitive(defIn.toByteArray());
+ case OBJECT_DESCRIPTOR:
+ return ASN1ObjectDescriptor.createPrimitive(defIn.toByteArray());
+ case OBJECT_IDENTIFIER:
+ // TODO Ideally only clone if we used a buffer
+ return ASN1ObjectIdentifier.createPrimitive(getBuffer(defIn, tmpBuffers), true);
+ case OCTET_STRING:
+ return ASN1OctetString.createPrimitive(defIn.toByteArray());
+ case PRINTABLE_STRING:
+ return ASN1PrintableString.createPrimitive(defIn.toByteArray());
+ case RELATIVE_OID:
+ return ASN1RelativeOID.createPrimitive(defIn.toByteArray(), false);
+ case T61_STRING:
+ return ASN1T61String.createPrimitive(defIn.toByteArray());
+ case UNIVERSAL_STRING:
+ return ASN1UniversalString.createPrimitive(defIn.toByteArray());
+ case UTC_TIME:
+ return ASN1UTCTime.createPrimitive(defIn.toByteArray());
+ case UTF8_STRING:
+ return ASN1UTF8String.createPrimitive(defIn.toByteArray());
case VIDEOTEX_STRING:
- return new DERVideotexString(defIn.toByteArray());
+ return ASN1VideotexString.createPrimitive(defIn.toByteArray());
+ case VISIBLE_STRING:
+ return ASN1VisibleString.createPrimitive(defIn.toByteArray());
+ case TIME:
+ case DATE:
+ case TIME_OF_DAY:
+ case DATE_TIME:
+ case DURATION:
+ case OBJECT_IDENTIFIER_IRI:
+ case RELATIVE_OID_IRI:
+ throw new IOException("unsupported tag " + tagNo + " encountered");
default:
throw new IOException("unknown tag " + tagNo + " encountered");
+ }
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception(e.getMessage(), e);
+ }
+ catch (IllegalStateException e)
+ {
+ throw new ASN1Exception(e.getMessage(), e);
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
index baad01c..cfc4049 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
@@ -12,6 +12,14 @@
public class ASN1Integer
extends ASN1Primitive
{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Integer.class, BERTags.INTEGER)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
static final int SIGN_EXT_SIGNED = 0xFFFFFFFF;
static final int SIGN_EXT_UNSIGNED = 0xFF;
@@ -37,7 +45,7 @@
{
try
{
- return (ASN1Integer)fromByteArray((byte[])obj);
+ return (ASN1Integer)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -51,27 +59,16 @@
/**
* Return an Integer from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @return an ASN1Integer instance.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
*/
- public static ASN1Integer getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1Integer getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1Integer)
- {
- return getInstance(o);
- }
- else
- {
- return new ASN1Integer(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1Integer)TYPE.getContextInstance(taggedObject, explicit);
}
/**
@@ -150,6 +147,18 @@
return new BigInteger(bytes);
}
+ public boolean hasValue(int x)
+ {
+ return (bytes.length - start) <= 4
+ && intValue(bytes, start, SIGN_EXT_SIGNED) == x;
+ }
+
+ public boolean hasValue(long x)
+ {
+ return (bytes.length - start) <= 8
+ && longValue(bytes, start, SIGN_EXT_SIGNED) == x;
+ }
+
public boolean hasValue(BigInteger x)
{
return null != x
@@ -191,19 +200,19 @@
return longValue(bytes, start, SIGN_EXT_SIGNED);
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, bytes.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.INTEGER, bytes);
+ out.writeEncodingDL(withTag, BERTags.INTEGER, bytes);
}
public int hashCode()
@@ -228,6 +237,11 @@
return getValue().toString();
}
+ static ASN1Integer createPrimitive(byte[] contents)
+ {
+ return new ASN1Integer(contents, false);
+ }
+
static int intValue(byte[] bytes, int start, int signExt)
{
int length = bytes.length;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java
index c181527..bad2347 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java
@@ -1,6 +1,3 @@
-/***************************************************************/
-/****** DO NOT EDIT THIS CLASS bc-java SOURCE FILE ******/
-/***************************************************************/
package org.bouncycastle.asn1;
import java.io.IOException;
@@ -11,10 +8,13 @@
public abstract class ASN1Null
extends ASN1Primitive
{
- ASN1Null()
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Null.class, BERTags.NULL)
{
-
- }
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
/**
* Return an instance of ASN.1 NULL from the passed in object.
@@ -42,21 +42,26 @@
{
try
{
- return ASN1Null.getInstance(ASN1Primitive.fromByteArray((byte[])o));
+ return (ASN1Null)TYPE.fromByteArray((byte[])o);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct NULL from byte[]: " + e.getMessage());
}
- catch (ClassCastException e)
- {
- throw new IllegalArgumentException("unknown object in getInstance(): " + o.getClass().getName());
- }
}
return null;
}
+ public static ASN1Null getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1Null)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ ASN1Null()
+ {
+ }
+
public int hashCode()
{
return -1;
@@ -73,10 +78,17 @@
return true;
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
return "NULL";
}
+
+ static ASN1Null createPrimitive(byte[] contents)
+ {
+ if (0 != contents.length)
+ {
+ throw new IllegalStateException("malformed NULL encoding encountered");
+ }
+ return DERNull.INSTANCE;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1NumericString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1NumericString.java
new file mode 100644
index 0000000..3609aca
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1NumericString.java
@@ -0,0 +1,213 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+/**
+ * NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
+ * ASN.1 NUMERIC-STRING object.
+ * <p>
+ * This is an ASCII string of characters {0,1,2,3,4,5,6,7,8,9} + space.
+ * <p>
+ * See X.680 section 37.2.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ */
+public abstract class ASN1NumericString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1NumericString.class, BERTags.NUMERIC_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a Numeric string from the passed in object
+ *
+ * @param obj an ASN1NumericString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1NumericString instance, or null
+ */
+ public static ASN1NumericString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1NumericString)
+ {
+ return (ASN1NumericString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1NumericString)
+ {
+ return (ASN1NumericString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1NumericString)TYPE.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());
+ }
+
+ /**
+ * Return an Numeric String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1NumericString instance, or null.
+ */
+ public static ASN1NumericString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1NumericString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ /**
+ * Constructor with optional validation.
+ *
+ * @param string the base string to wrap.
+ * @param validate whether or not to check the string.
+ * @throws IllegalArgumentException if validate is true and the string
+ * contains characters that should not be in a NumericString.
+ */
+ ASN1NumericString(String string, boolean validate)
+ {
+ if (validate && !isNumericString(string))
+ {
+ throw new IllegalArgumentException("string contains illegal characters");
+ }
+
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1NumericString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.NUMERIC_STRING, contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1NumericString))
+ {
+ return false;
+ }
+
+ ASN1NumericString that = (ASN1NumericString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ /**
+ * Return true if the string can be represented as a NumericString ('0'..'9', ' ')
+ *
+ * @param str string to validate.
+ * @return true if numeric, false otherwise.
+ */
+ public static boolean isNumericString(String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+
+ if (('0' <= ch && ch <= '9') || ch == ' ')
+ {
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ static boolean isNumericString(byte[] contents)
+ {
+ for (int i = 0; i < contents.length; ++i)
+ {
+ switch (contents[i])
+ {
+ case 0x20:
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ case 0x38:
+ case 0x39:
+ break;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ static ASN1NumericString createPrimitive(byte[] contents)
+ {
+ // TODO Validation - sort out exception types
+// if (!isNumericString(contents))
+
+ return new DERNumericString(contents, false);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java
index 0af2cdd..d099008 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java
@@ -14,12 +14,12 @@
{
public void encodeTo(OutputStream output) throws IOException
{
- ASN1OutputStream.create(output).writeObject(this);
+ toASN1Primitive().encodeTo(output);
}
public void encodeTo(OutputStream output, String encoding) throws IOException
{
- ASN1OutputStream.create(output, encoding).writeObject(this);
+ toASN1Primitive().encodeTo(output, encoding);
}
/**
@@ -31,7 +31,7 @@
public byte[] getEncoded() throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- encodeTo(bOut);
+ toASN1Primitive().encodeTo(bOut);
return bOut.toByteArray();
}
@@ -45,7 +45,7 @@
public byte[] getEncoded(String encoding) throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- encodeTo(bOut, encoding);
+ toASN1Primitive().encodeTo(bOut, encoding);
return bOut.toByteArray();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectDescriptor.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectDescriptor.java
new file mode 100644
index 0000000..5323d5c
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectDescriptor.java
@@ -0,0 +1,141 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+public final class ASN1ObjectDescriptor
+ extends ASN1Primitive
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1ObjectDescriptor.class, BERTags.OBJECT_DESCRIPTOR)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return new ASN1ObjectDescriptor(
+ (ASN1GraphicString)ASN1GraphicString.TYPE.fromImplicitPrimitive(octetString));
+ }
+
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return new ASN1ObjectDescriptor(
+ (ASN1GraphicString)ASN1GraphicString.TYPE.fromImplicitConstructed(sequence));
+ }
+ };
+
+ /**
+ * Return an ObjectDescriptor from the passed in object.
+ *
+ * @param obj an ASN1ObjectDescriptor or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1ObjectDescriptor instance, or null.
+ */
+ public static ASN1ObjectDescriptor getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1ObjectDescriptor)
+ {
+ return (ASN1ObjectDescriptor)obj;
+ }
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1ObjectDescriptor)
+ {
+ return (ASN1ObjectDescriptor)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1ObjectDescriptor)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct object descriptor from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an ObjectDescriptor from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly tagged,
+ * false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1ObjectDescriptor instance, or null.
+ */
+ public static ASN1ObjectDescriptor getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1ObjectDescriptor)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ private final ASN1GraphicString baseGraphicString;
+
+ public ASN1ObjectDescriptor(ASN1GraphicString baseGraphicString)
+ {
+ if (null == baseGraphicString)
+ {
+ throw new NullPointerException("'baseGraphicString' cannot be null");
+ }
+
+ this.baseGraphicString = baseGraphicString;
+ }
+
+ public ASN1GraphicString getBaseGraphicString()
+ {
+ return baseGraphicString;
+ }
+
+ boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength(boolean withTag)
+ {
+ return baseGraphicString.encodedLength(withTag);
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeIdentifier(withTag, BERTags.OBJECT_DESCRIPTOR);
+ baseGraphicString.encode(out, false);
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ ASN1GraphicString der = (ASN1GraphicString)baseGraphicString.toDERObject();
+
+ return der == baseGraphicString ? this : new ASN1ObjectDescriptor(der);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ ASN1GraphicString dl = (ASN1GraphicString)baseGraphicString.toDLObject();
+
+ return dl == baseGraphicString ? this : new ASN1ObjectDescriptor(dl);
+ }
+
+ boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1ObjectDescriptor))
+ {
+ return false;
+ }
+
+ ASN1ObjectDescriptor that = (ASN1ObjectDescriptor)other;
+
+ return this.baseGraphicString.asn1Equals(that.baseGraphicString);
+ }
+
+ public int hashCode()
+ {
+ return ~baseGraphicString.hashCode();
+ }
+
+ static ASN1ObjectDescriptor createPrimitive(byte[] contents)
+ {
+ return new ASN1ObjectDescriptor(ASN1GraphicString.createPrimitive(contents));
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
index 8373dca..b4bb0d2 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
@@ -14,9 +14,18 @@
public class ASN1ObjectIdentifier
extends ASN1Primitive
{
- private final String identifier;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1ObjectIdentifier.class, BERTags.OBJECT_IDENTIFIER)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets(), false);
+ }
+ };
- private byte[] body;
+ public static ASN1ObjectIdentifier fromContents(byte[] contents)
+ {
+ return createPrimitive(contents, true);
+ }
/**
* Return an OID from the passed in object
@@ -25,30 +34,25 @@
* @return an ASN1ObjectIdentifier instance, or null.
* @throws IllegalArgumentException if the object cannot be converted.
*/
- public static ASN1ObjectIdentifier getInstance(
- Object obj)
+ public static ASN1ObjectIdentifier getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1ObjectIdentifier)
{
return (ASN1ObjectIdentifier)obj;
}
-
- if (obj instanceof ASN1Encodable)
+ else if (obj instanceof ASN1Encodable)
{
ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
if (primitive instanceof ASN1ObjectIdentifier)
{
return (ASN1ObjectIdentifier)primitive;
}
}
-
- if (obj instanceof byte[])
+ else if (obj instanceof byte[])
{
- byte[] enc = (byte[])obj;
try
{
- return (ASN1ObjectIdentifier)fromByteArray(enc);
+ return (ASN1ObjectIdentifier)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
@@ -62,47 +66,60 @@
/**
* Return an OBJECT IDENTIFIER from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @return an ASN1ObjectIdentifier instance, or null.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
*/
- public static ASN1ObjectIdentifier getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1ObjectIdentifier getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
+ /*
+ * TODO[asn1] This block here is for backward compatibility, but should eventually be removed.
+ *
+ * - see https://github.com/bcgit/bc-java/issues/1015
+ */
+ if (!explicit && !taggedObject.isParsed() && BERTags.CONTEXT_SPECIFIC == taggedObject.getTagClass())
+ {
+ ASN1Primitive base = taggedObject.getBaseObject().toASN1Primitive();
+ if (!(base instanceof ASN1ObjectIdentifier))
+ {
+ return fromContents(ASN1OctetString.getInstance(base).getOctets());
+ }
+ }
- if (explicit || o instanceof ASN1ObjectIdentifier)
- {
- return getInstance(o);
- }
- else
- {
- return ASN1ObjectIdentifier.fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1ObjectIdentifier)TYPE.getContextInstance(taggedObject, explicit);
}
- private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f;
+ private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7F;
- ASN1ObjectIdentifier(
- byte[] bytes)
+ private static final ConcurrentMap<OidHandle, ASN1ObjectIdentifier> pool =
+ new ConcurrentHashMap<OidHandle, ASN1ObjectIdentifier>();
+
+ private final String identifier;
+ private byte[] contents;
+
+ ASN1ObjectIdentifier(byte[] contents, boolean clone)
{
- StringBuffer objId = new StringBuffer();
+ if (contents.length == 0)
+ {
+ throw new IllegalArgumentException("empty OBJECT IDENTIFIER with no sub-identifiers");
+ }
+
+ StringBuilder objId = new StringBuilder();
long value = 0;
BigInteger bigValue = null;
boolean first = true;
- for (int i = 0; i != bytes.length; i++)
+ for (int i = 0; i != contents.length; i++)
{
- int b = bytes[i] & 0xff;
+ int b = contents[i] & 0xff;
if (value <= LONG_LIMIT)
{
- value += (b & 0x7f);
- if ((b & 0x80) == 0) // end of number reached
+ value += b & 0x7F;
+ if ((b & 0x80) == 0)
{
if (first)
{
@@ -138,7 +155,7 @@
{
bigValue = BigInteger.valueOf(value);
}
- bigValue = bigValue.or(BigInteger.valueOf(b & 0x7f));
+ bigValue = bigValue.or(BigInteger.valueOf(b & 0x7F));
if ((b & 0x80) == 0)
{
if (first)
@@ -162,7 +179,7 @@
// Android-changed: Intern the identifier so there aren't hundreds of duplicates in practice.
this.identifier = objId.toString().intern();
- this.body = Arrays.clone(bytes);
+ this.contents = clone ? Arrays.clone(contents) : contents;
}
/**
@@ -194,7 +211,7 @@
*/
ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branchID)
{
- if (!isValidBranchID(branchID, 0))
+ if (!ASN1RelativeOID.isValidIdentifier(branchID, 0))
{
throw new IllegalArgumentException("string " + branchID + " not a valid OID branch");
}
@@ -235,44 +252,6 @@
return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId);
}
- private void writeField(
- ByteArrayOutputStream out,
- long fieldValue)
- {
- byte[] result = new byte[9];
- int pos = 8;
- result[pos] = (byte)((int)fieldValue & 0x7f);
- while (fieldValue >= (1L << 7))
- {
- fieldValue >>= 7;
- result[--pos] = (byte)((int)fieldValue & 0x7f | 0x80);
- }
- out.write(result, pos, 9 - pos);
- }
-
- private void writeField(
- ByteArrayOutputStream out,
- BigInteger fieldValue)
- {
- int byteCount = (fieldValue.bitLength() + 6) / 7;
- if (byteCount == 0)
- {
- out.write(0);
- }
- else
- {
- BigInteger tmpValue = fieldValue;
- byte[] tmp = new byte[byteCount];
- for (int i = byteCount - 1; i >= 0; i--)
- {
- tmp[i] = (byte)((tmpValue.intValue() & 0x7f) | 0x80);
- tmpValue = tmpValue.shiftRight(7);
- }
- tmp[byteCount - 1] &= 0x7f;
- out.write(tmp, 0, tmp.length);
- }
- }
-
private void doOutput(ByteArrayOutputStream aOut)
{
OIDTokenizer tok = new OIDTokenizer(identifier);
@@ -281,11 +260,11 @@
String secondToken = tok.nextToken();
if (secondToken.length() <= 18)
{
- writeField(aOut, first + Long.parseLong(secondToken));
+ ASN1RelativeOID.writeField(aOut, first + Long.parseLong(secondToken));
}
else
{
- writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
+ ASN1RelativeOID.writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
}
while (tok.hasMoreTokens())
@@ -293,45 +272,42 @@
String token = tok.nextToken();
if (token.length() <= 18)
{
- writeField(aOut, Long.parseLong(token));
+ ASN1RelativeOID.writeField(aOut, Long.parseLong(token));
}
else
{
- writeField(aOut, new BigInteger(token));
+ ASN1RelativeOID.writeField(aOut, new BigInteger(token));
}
}
}
- private synchronized byte[] getBody()
+ private synchronized byte[] getContents()
{
- if (body == null)
+ if (contents == null)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
doOutput(bOut);
- body = bOut.toByteArray();
+ contents = bOut.toByteArray();
}
- return body;
+ return contents;
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
- throws IOException
+ int encodedLength(boolean withTag)
{
- int length = getBody().length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContents().length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.OBJECT_IDENTIFIER, getBody());
+ out.writeEncodingDL(withTag, BERTags.OBJECT_IDENTIFIER, getContents());
}
public int hashCode()
@@ -360,45 +336,6 @@
return getId();
}
- private static boolean isValidBranchID(
- String branchID, int start)
- {
- int digitCount = 0;
-
- int pos = branchID.length();
- while (--pos >= start)
- {
- char ch = branchID.charAt(pos);
-
- if (ch == '.')
- {
- if (0 == digitCount
- || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
- {
- return false;
- }
-
- digitCount = 0;
- }
- else if ('0' <= ch && ch <= '9')
- {
- ++digitCount;
- }
- else
- {
- return false;
- }
- }
-
- if (0 == digitCount
- || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
- {
- return false;
- }
-
- return true;
- }
-
private static boolean isValidIdentifier(
String identifier)
{
@@ -413,7 +350,7 @@
return false;
}
- return isValidBranchID(identifier, 2);
+ return ASN1RelativeOID.isValidIdentifier(identifier, 2);
}
/**
@@ -428,30 +365,35 @@
*/
public ASN1ObjectIdentifier intern()
{
- final OidHandle hdl = new OidHandle(getBody());
+ final OidHandle hdl = new OidHandle(getContents());
ASN1ObjectIdentifier oid = pool.get(hdl);
if (oid == null)
{
- oid = pool.putIfAbsent(hdl, this);
- if (oid == null)
+ synchronized (pool)
{
- oid = this;
+ if (!pool.containsKey(hdl))
+ {
+ pool.put(hdl, this);
+ return this;
+ }
+ else
+ {
+ return pool.get(hdl);
+ }
}
}
return oid;
}
- private static final ConcurrentMap<OidHandle, ASN1ObjectIdentifier> pool = new ConcurrentHashMap<OidHandle, ASN1ObjectIdentifier>();
-
private static class OidHandle
{
private final int key;
- private final byte[] enc;
+ private final byte[] contents;
- OidHandle(byte[] enc)
+ OidHandle(byte[] contents)
{
- this.key = Arrays.hashCode(enc);
- this.enc = enc;
+ this.key = Arrays.hashCode(contents);
+ this.contents = contents;
}
public int hashCode()
@@ -463,20 +405,20 @@
{
if (o instanceof OidHandle)
{
- return Arrays.areEqual(enc, ((OidHandle)o).enc);
+ return Arrays.areEqual(contents, ((OidHandle)o).contents);
}
return false;
}
}
- static ASN1ObjectIdentifier fromOctetString(byte[] enc)
+ static ASN1ObjectIdentifier createPrimitive(byte[] contents, boolean clone)
{
- final OidHandle hdl = new OidHandle(enc);
+ final OidHandle hdl = new OidHandle(contents);
ASN1ObjectIdentifier oid = pool.get(hdl);
if (oid == null)
{
- return new ASN1ObjectIdentifier(enc);
+ return new ASN1ObjectIdentifier(contents, clone);
}
return oid;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
index 59c6f34..896f56f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
@@ -100,7 +100,18 @@
extends ASN1Primitive
implements ASN1OctetStringParser
{
- byte[] string;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1OctetString.class, BERTags.OCTET_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return octetString;
+ }
+
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence.toASN1OctetString();
+ }
+ };
/**
* return an Octet String from a tagged object.
@@ -111,70 +122,9 @@
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
- public static ASN1OctetString getInstance(
- ASN1TaggedObject taggedObject,
- boolean explicit)
+ public static ASN1OctetString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- if (explicit)
- {
- if (!taggedObject.isExplicit())
- {
- throw new IllegalArgumentException("object implicit - explicit expected.");
- }
-
- return getInstance(taggedObject.getObject());
- }
-
- ASN1Primitive o = taggedObject.getObject();
-
- /*
- * constructed object which appears to be explicitly tagged and it's really implicit means
- * we have to add the surrounding octet string.
- */
- if (taggedObject.isExplicit())
- {
- ASN1OctetString singleSegment = getInstance(o);
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BEROctetString(new ASN1OctetString[]{ singleSegment });
- }
-
- // TODO Should really be similar to the BERTaggedObject case above:
-// return new DLOctetString(new ASN1OctetString[]{ singleSegment });
- return (ASN1OctetString)new BEROctetString(new ASN1OctetString[]{ singleSegment }).toDLObject();
- }
-
- if (o instanceof ASN1OctetString)
- {
- ASN1OctetString s = (ASN1OctetString)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return s;
- }
-
- return (ASN1OctetString)s.toDLObject();
- }
-
- /*
- * in this case the parser returns a sequence, convert it into an octet string.
- */
- if (o instanceof ASN1Sequence)
- {
- ASN1Sequence s = (ASN1Sequence)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return BEROctetString.fromSequence(s);
- }
-
- // TODO Should really be similar to the BERTaggedObject case above:
-// return DLOctetString.fromSequence(s);
- return (ASN1OctetString)BEROctetString.fromSequence(s).toDLObject();
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ return (ASN1OctetString)TYPE.getContextInstance(taggedObject, explicit);
}
/**
@@ -183,37 +133,40 @@
* @param obj the object we want converted.
* @exception IllegalArgumentException if the object cannot be converted.
*/
- public static ASN1OctetString getInstance(
- Object obj)
+ public static ASN1OctetString getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1OctetString)
{
return (ASN1OctetString)obj;
}
+// else if (obj instanceof ASN1OctetStringParser)
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1OctetString)
+ {
+ return (ASN1OctetString)primitive;
+ }
+ }
else if (obj instanceof byte[])
{
try
{
- return getInstance(fromByteArray((byte[])obj));
+ return (ASN1OctetString)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct OCTET STRING from byte[]: " + e.getMessage());
}
}
- else if (obj instanceof ASN1Encodable)
- {
- ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
- if (primitive instanceof ASN1OctetString)
- {
- return (ASN1OctetString)primitive;
- }
- }
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
+ static final byte[] EMPTY_OCTETS = new byte[0];
+
+ byte[] string;
+
/**
* Base constructor.
*
@@ -259,6 +212,11 @@
return string;
}
+ public int getOctetsLength()
+ {
+ return getOctets().length;
+ }
+
public int hashCode()
{
return Arrays.hashCode(this.getOctets());
@@ -292,10 +250,13 @@
return new DEROctetString(string);
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
return "#" + Strings.fromByteArray(Hex.encode(string));
}
+
+ static ASN1OctetString createPrimitive(byte[] contents)
+ {
+ return new DEROctetString(contents);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OutputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OutputStream.java
index e6ae93f..73bab8a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OutputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OutputStream.java
@@ -32,250 +32,33 @@
private OutputStream os;
- /**
- * @deprecated Use {@link ASN1OutputStream#create(OutputStream)} instead.
- */
- public ASN1OutputStream(OutputStream os)
+ ASN1OutputStream(OutputStream os)
{
this.os = os;
}
- final void writeLength(
- int length)
- throws IOException
+ public void close() throws IOException
{
- if (length > 127)
- {
- int size = 1;
- int val = length;
-
- while ((val >>>= 8) != 0)
- {
- size++;
- }
-
- write((byte)(size | 0x80));
-
- for (int i = (size - 1) * 8; i >= 0; i -= 8)
- {
- write((byte)(length >> i));
- }
- }
- else
- {
- write((byte)length);
- }
+ os.close();
}
- final void write(int b)
- throws IOException
+ public void flush() throws IOException
{
- os.write(b);
+ os.flush();
}
- final void write(byte[] bytes, int off, int len)
- throws IOException
+ public final void writeObject(ASN1Encodable encodable) throws IOException
{
- os.write(bytes, off, len);
- }
-
- final void writeElements(ASN1Encodable[] elements)
- throws IOException
- {
- int count = elements.length;
- for (int i = 0; i < count; ++i)
- {
- ASN1Primitive primitive = elements[i].toASN1Primitive();
-
- writePrimitive(primitive, true);
- }
- }
-
- final void writeElements(Enumeration elements)
- throws IOException
- {
- while (elements.hasMoreElements())
- {
- ASN1Primitive primitive = ((ASN1Encodable)elements.nextElement()).toASN1Primitive();
-
- writePrimitive(primitive, true);
- }
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte contents)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(1);
- write(contents);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte[] contents)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(contents.length);
- write(contents, 0, contents.length);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte[] contents,
- int contentsOff,
- int contentsLen)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(contentsLen);
- write(contents, contentsOff, contentsLen);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte headByte,
- byte[] tailBytes)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(1 + tailBytes.length);
- write(headByte);
- write(tailBytes, 0, tailBytes.length);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte headByte,
- byte[] body,
- int bodyOff,
- int bodyLen,
- byte tailByte)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(2 + bodyLen);
- write(headByte);
- write(body, bodyOff, bodyLen);
- write(tailByte);
- }
-
- final void writeEncoded(boolean withTag, int flags, int tagNo, byte[] contents)
- throws IOException
- {
- writeTag(withTag, flags, tagNo);
- writeLength(contents.length);
- write(contents, 0, contents.length);
- }
-
- final void writeEncodedIndef(boolean withTag, int flags, int tagNo, byte[] contents)
- throws IOException
- {
- writeTag(withTag, flags, tagNo);
- write(0x80);
- write(contents, 0, contents.length);
- write(0x00);
- write(0x00);
- }
-
- final void writeEncodedIndef(boolean withTag, int tag, ASN1Encodable[] elements)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- write(0x80);
- writeElements(elements);
- write(0x00);
- write(0x00);
- }
-
- final void writeEncodedIndef(boolean withTag, int tag, Enumeration elements)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- write(0x80);
- writeElements(elements);
- write(0x00);
- write(0x00);
- }
-
- final void writeTag(boolean withTag, int flags, int tagNo)
- throws IOException
- {
- if (!withTag)
- {
- return;
- }
-
- if (tagNo < 31)
- {
- write(flags | tagNo);
- }
- else
- {
- write(flags | 0x1f);
- if (tagNo < 128)
- {
- write(tagNo);
- }
- else
- {
- byte[] stack = new byte[5];
- int pos = stack.length;
-
- stack[--pos] = (byte)(tagNo & 0x7F);
-
- do
- {
- tagNo >>= 7;
- stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
- }
- while (tagNo > 127);
-
- write(stack, pos, stack.length - pos);
- }
- }
- }
-
- public void writeObject(ASN1Encodable obj) throws IOException
- {
- if (null == obj)
+ if (null == encodable)
{
throw new IOException("null object detected");
}
- writePrimitive(obj.toASN1Primitive(), true);
+ writePrimitive(encodable.toASN1Primitive(), true);
flushInternal();
}
- public void writeObject(ASN1Primitive primitive) throws IOException
+ public final void writeObject(ASN1Primitive primitive) throws IOException
{
if (null == primitive)
{
@@ -286,25 +69,7 @@
flushInternal();
}
- void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
- {
- primitive.encode(this, withTag);
- }
-
- public void close()
- throws IOException
- {
- os.close();
- }
-
- public void flush()
- throws IOException
- {
- os.flush();
- }
-
- void flushInternal()
- throws IOException
+ void flushInternal() throws IOException
{
// Placeholder to support future internal buffering
}
@@ -314,8 +79,192 @@
return new DEROutputStream(os);
}
- ASN1OutputStream getDLSubStream()
+ DLOutputStream getDLSubStream()
{
return new DLOutputStream(os);
}
+
+ final void writeDL(int length) throws IOException
+ {
+ if (length < 128)
+ {
+ write(length);
+ }
+ else
+ {
+ byte[] stack = new byte[5];
+ int pos = stack.length;
+
+ do
+ {
+ stack[--pos] = (byte)length;
+ length >>>= 8;
+ }
+ while (length != 0);
+
+ int count = stack.length - pos;
+ stack[--pos] = (byte)(0x80 | count);
+
+ write(stack, pos, count + 1);
+ }
+ }
+
+ final void write(int b) throws IOException
+ {
+ os.write(b);
+ }
+
+ final void write(byte[] bytes, int off, int len) throws IOException
+ {
+ os.write(bytes, off, len);
+ }
+
+ void writeElements(ASN1Encodable[] elements)
+ throws IOException
+ {
+ for (int i = 0, count = elements.length; i < count; ++i)
+ {
+ elements[i].toASN1Primitive().encode(this, true);
+ }
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte contents) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(1);
+ write(contents);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte[] contents) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(contents.length);
+ write(contents, 0, contents.length);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte[] contents, int contentsOff, int contentsLen)
+ throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(contentsLen);
+ write(contents, contentsOff, contentsLen);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte contentsPrefix, byte[] contents, int contentsOff,
+ int contentsLen) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(1 + contentsLen);
+ write(contentsPrefix);
+ write(contents, contentsOff, contentsLen);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte[] contents, int contentsOff, int contentsLen,
+ byte contentsSuffix) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(contentsLen + 1);
+ write(contents, contentsOff, contentsLen);
+ write(contentsSuffix);
+ }
+
+ final void writeEncodingDL(boolean withID, int flags, int tag, byte[] contents) throws IOException
+ {
+ writeIdentifier(withID, flags, tag);
+ writeDL(contents.length);
+ write(contents, 0, contents.length);
+ }
+
+ final void writeEncodingIL(boolean withID, int identifier, ASN1Encodable[] elements) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ write(0x80);
+ writeElements(elements);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeIdentifier(boolean withID, int identifier) throws IOException
+ {
+ if (withID)
+ {
+ write(identifier);
+ }
+ }
+
+ final void writeIdentifier(boolean withID, int flags, int tag) throws IOException
+ {
+ if (!withID)
+ {
+ // Don't write the identifier
+ }
+ else if (tag < 31)
+ {
+ write(flags | tag);
+ }
+ else
+ {
+ byte[] stack = new byte[6];
+ int pos = stack.length;
+
+ stack[--pos] = (byte)(tag & 0x7F);
+ while (tag > 127)
+ {
+ tag >>>= 7;
+ stack[--pos] = (byte)(tag & 0x7F | 0x80);
+ }
+
+ stack[--pos] = (byte)(flags | 0x1F);
+
+ write(stack, pos, stack.length - pos);
+ }
+ }
+
+ void writePrimitive(ASN1Primitive primitive, boolean withID) throws IOException
+ {
+ primitive.encode(this, withID);
+ }
+
+ void writePrimitives(ASN1Primitive[] primitives) throws IOException
+ {
+ for (int i = 0, count = primitives.length; i < count; ++i)
+ {
+ primitives[i].encode(this, true);
+ }
+ }
+
+ static int getLengthOfDL(int dl)
+ {
+ if (dl < 128)
+ {
+ return 1;
+ }
+
+ int length = 2;
+ while ((dl >>>= 8) != 0)
+ {
+ ++length;
+ }
+ return length;
+ }
+
+ static int getLengthOfEncodingDL(boolean withID, int contentsLength)
+ {
+ return (withID ? 1 : 0) + getLengthOfDL(contentsLength) + contentsLength;
+ }
+
+ static int getLengthOfIdentifier(int tag)
+ {
+ if (tag < 31)
+ {
+ return 1;
+ }
+
+ int length = 2;
+ while ((tag >>>= 7) != 0)
+ {
+ ++length;
+ }
+ return length;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java
index b562b06..6e5d3d6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java
@@ -15,12 +15,16 @@
public void encodeTo(OutputStream output) throws IOException
{
- ASN1OutputStream.create(output).writeObject(this);
+ ASN1OutputStream asn1Out = ASN1OutputStream.create(output);
+ asn1Out.writePrimitive(this, true);
+ asn1Out.flushInternal();
}
public void encodeTo(OutputStream output, String encoding) throws IOException
{
- ASN1OutputStream.create(output, encoding).writeObject(this);
+ ASN1OutputStream asn1Out = ASN1OutputStream.create(output, encoding);
+ asn1Out.writePrimitive(this, true);
+ asn1Out.flushInternal();
}
/**
@@ -103,14 +107,9 @@
* Return true if this objected is a CONSTRUCTED one, false otherwise.
* @return true if CONSTRUCTED bit set on object's tag, false otherwise.
*/
- abstract boolean isConstructed();
+ abstract boolean encodeConstructed();
- /**
- * Return the length of the encoding this object will produce.
- * @return the length of the object's encoding.
- * @throws IOException if the encoding length cannot be calculated.
- */
- abstract int encodedLength() throws IOException;
+ abstract int encodedLength(boolean withTag) throws IOException;
abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1PrintableString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1PrintableString.java
new file mode 100644
index 0000000..a859b7d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1PrintableString.java
@@ -0,0 +1,229 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 PrintableString object.
+ * <p>
+ * X.680 section 37.4 defines PrintableString character codes as ASCII subset of following characters:
+ * </p>
+ * <ul>
+ * <li>Latin capital letters: 'A' .. 'Z'</li>
+ * <li>Latin small letters: 'a' .. 'z'</li>
+ * <li>Digits: '0'..'9'</li>
+ * <li>Space</li>
+ * <li>Apostrophe: '\''</li>
+ * <li>Left parenthesis: '('</li>
+ * <li>Right parenthesis: ')'</li>
+ * <li>Plus sign: '+'</li>
+ * <li>Comma: ','</li>
+ * <li>Hyphen-minus: '-'</li>
+ * <li>Full stop: '.'</li>
+ * <li>Solidus: '/'</li>
+ * <li>Colon: ':'</li>
+ * <li>Equals sign: '='</li>
+ * <li>Question mark: '?'</li>
+ * </ul>
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ */
+public abstract class ASN1PrintableString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1PrintableString.class, BERTags.PRINTABLE_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a printable string from the passed in object.
+ *
+ * @param obj an ASN1PrintableString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1PrintableString instance, or null.
+ */
+ public static ASN1PrintableString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1PrintableString)
+ {
+ return (ASN1PrintableString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1PrintableString)
+ {
+ return (ASN1PrintableString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1PrintableString)TYPE.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());
+ }
+
+ /**
+ * Return a Printable String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1PrintableString instance, or null.
+ */
+ public static ASN1PrintableString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1PrintableString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ /**
+ * Constructor with optional validation.
+ *
+ * @param string the base string to wrap.
+ * @param validate whether or not to check the string.
+ * @throws IllegalArgumentException if validate is true and the string
+ * contains characters that should not be in a PrintableString.
+ */
+ ASN1PrintableString(String string, boolean validate)
+ {
+ if (validate && !isPrintableString(string))
+ {
+ throw new IllegalArgumentException("string contains illegal characters");
+ }
+
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1PrintableString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.PRINTABLE_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1PrintableString))
+ {
+ return false;
+ }
+
+ ASN1PrintableString that = (ASN1PrintableString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ /**
+ * return true if the passed in String can be represented without
+ * loss as a PrintableString, false otherwise.
+ *
+ * @return true if in printable set, false otherwise.
+ */
+ public static boolean isPrintableString(
+ String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+
+ if ('a' <= ch && ch <= 'z')
+ {
+ continue;
+ }
+
+ if ('A' <= ch && ch <= 'Z')
+ {
+ continue;
+ }
+
+ if ('0' <= ch && ch <= '9')
+ {
+ continue;
+ }
+
+ switch (ch)
+ {
+ case ' ':
+ case '\'':
+ case '(':
+ case ')':
+ case '+':
+ case '-':
+ case '.':
+ case ':':
+ case '=':
+ case '?':
+ case '/':
+ case ',':
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ static ASN1PrintableString createPrimitive(byte[] contents)
+ {
+ return new DERPrintableString(contents, false);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1RelativeOID.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1RelativeOID.java
new file mode 100644
index 0000000..b107cb2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1RelativeOID.java
@@ -0,0 +1,313 @@
+package org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import org.bouncycastle.util.Arrays;
+
+public class ASN1RelativeOID
+ extends ASN1Primitive
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1RelativeOID.class, BERTags.RELATIVE_OID)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets(), false);
+ }
+ };
+
+ public static ASN1RelativeOID fromContents(byte[] contents)
+ {
+ return createPrimitive(contents, true);
+ }
+
+ public static ASN1RelativeOID getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1RelativeOID)
+ {
+ return (ASN1RelativeOID)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1RelativeOID)
+ {
+ return (ASN1RelativeOID)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ byte[] enc = (byte[])obj;
+ try
+ {
+ return (ASN1RelativeOID)TYPE.fromByteArray(enc);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct relative OID from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ public static ASN1RelativeOID getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1RelativeOID)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7F;
+
+ private final String identifier;
+ private byte[] contents;
+
+ public ASN1RelativeOID(String identifier)
+ {
+ if (identifier == null)
+ {
+ throw new NullPointerException("'identifier' cannot be null");
+ }
+ if (!isValidIdentifier(identifier, 0))
+ {
+ throw new IllegalArgumentException("string " + identifier + " not a relative OID");
+ }
+
+ this.identifier = identifier;
+ }
+
+ ASN1RelativeOID(ASN1RelativeOID oid, String branchID)
+ {
+ if (!isValidIdentifier(branchID, 0))
+ {
+ throw new IllegalArgumentException("string " + branchID + " not a valid OID branch");
+ }
+
+ this.identifier = oid.getId() + "." + branchID;
+ }
+
+ private ASN1RelativeOID(byte[] contents, boolean clone)
+ {
+ StringBuffer objId = new StringBuffer();
+ long value = 0;
+ BigInteger bigValue = null;
+ boolean first = true;
+
+ for (int i = 0; i != contents.length; i++)
+ {
+ int b = contents[i] & 0xff;
+
+ if (value <= LONG_LIMIT)
+ {
+ value += b & 0x7F;
+ if ((b & 0x80) == 0)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ objId.append('.');
+ }
+
+ objId.append(value);
+ value = 0;
+ }
+ else
+ {
+ value <<= 7;
+ }
+ }
+ else
+ {
+ if (bigValue == null)
+ {
+ bigValue = BigInteger.valueOf(value);
+ }
+ bigValue = bigValue.or(BigInteger.valueOf(b & 0x7F));
+ if ((b & 0x80) == 0)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ objId.append('.');
+ }
+
+ objId.append(bigValue);
+ bigValue = null;
+ value = 0;
+ }
+ else
+ {
+ bigValue = bigValue.shiftLeft(7);
+ }
+ }
+ }
+
+ this.identifier = objId.toString();
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public ASN1RelativeOID branch(String branchID)
+ {
+ return new ASN1RelativeOID(this, branchID);
+ }
+
+ public String getId()
+ {
+ return identifier;
+ }
+
+ public int hashCode()
+ {
+ return identifier.hashCode();
+ }
+
+ public String toString()
+ {
+ return getId();
+ }
+
+ boolean asn1Equals(ASN1Primitive other)
+ {
+ if (this == other)
+ {
+ return true;
+ }
+ if (!(other instanceof ASN1RelativeOID))
+ {
+ return false;
+ }
+
+ ASN1RelativeOID that = (ASN1RelativeOID)other;
+
+ return this.identifier.equals(that.identifier);
+ }
+
+ int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContents().length);
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.RELATIVE_OID, getContents());
+ }
+
+ boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ private void doOutput(ByteArrayOutputStream aOut)
+ {
+ OIDTokenizer tok = new OIDTokenizer(identifier);
+ while (tok.hasMoreTokens())
+ {
+ String token = tok.nextToken();
+ if (token.length() <= 18)
+ {
+ writeField(aOut, Long.parseLong(token));
+ }
+ else
+ {
+ writeField(aOut, new BigInteger(token));
+ }
+ }
+ }
+
+ private synchronized byte[] getContents()
+ {
+ if (contents == null)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ doOutput(bOut);
+
+ contents = bOut.toByteArray();
+ }
+
+ return contents;
+ }
+
+ static ASN1RelativeOID createPrimitive(byte[] contents, boolean clone)
+ {
+ return new ASN1RelativeOID(contents, clone);
+ }
+
+ static boolean isValidIdentifier(String identifier, int from)
+ {
+ int digitCount = 0;
+
+ int pos = identifier.length();
+ while (--pos >= from)
+ {
+ char ch = identifier.charAt(pos);
+
+ if (ch == '.')
+ {
+ if (0 == digitCount
+ || (digitCount > 1 && identifier.charAt(pos + 1) == '0'))
+ {
+ return false;
+ }
+
+ digitCount = 0;
+ }
+ else if ('0' <= ch && ch <= '9')
+ {
+ ++digitCount;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (0 == digitCount
+ || (digitCount > 1 && identifier.charAt(pos + 1) == '0'))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ static void writeField(ByteArrayOutputStream out, long fieldValue)
+ {
+ byte[] result = new byte[9];
+ int pos = 8;
+ result[pos] = (byte)((int)fieldValue & 0x7F);
+ while (fieldValue >= (1L << 7))
+ {
+ fieldValue >>= 7;
+ result[--pos] = (byte)((int)fieldValue | 0x80);
+ }
+ out.write(result, pos, 9 - pos);
+ }
+
+ static void writeField(ByteArrayOutputStream out, BigInteger fieldValue)
+ {
+ int byteCount = (fieldValue.bitLength() + 6) / 7;
+ if (byteCount == 0)
+ {
+ out.write(0);
+ }
+ else
+ {
+ BigInteger tmpValue = fieldValue;
+ byte[] tmp = new byte[byteCount];
+ for (int i = byteCount - 1; i >= 0; i--)
+ {
+ tmp[i] = (byte)(tmpValue.intValue() | 0x80);
+ tmpValue = tmpValue.shiftRight(7);
+ }
+ tmp[byteCount - 1] &= 0x7F;
+ out.write(tmp, 0, tmp.length);
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java
index b64127a..99d680f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java
@@ -60,8 +60,13 @@
extends ASN1Primitive
implements org.bouncycastle.util.Iterable<ASN1Encodable>
{
- // NOTE: Only non-final to support LazyEncodedSequence
- ASN1Encodable[] elements;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Sequence.class, BERTags.SEQUENCE)
+ {
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence;
+ }
+ };
/**
* Return an ASN1Sequence from the given object.
@@ -70,37 +75,32 @@
* @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Sequence instance, or null.
*/
- public static ASN1Sequence getInstance(
- Object obj)
+ public static ASN1Sequence getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1Sequence)
{
return (ASN1Sequence)obj;
}
- else if (obj instanceof ASN1SequenceParser)
+// else if (obj instanceof ASN1SequenceParser)
+ else if (obj instanceof ASN1Encodable)
{
- return ASN1Sequence.getInstance(((ASN1SequenceParser)obj).toASN1Primitive());
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1Sequence)
+ {
+ return (ASN1Sequence)primitive;
+ }
}
else if (obj instanceof byte[])
{
try
{
- return ASN1Sequence.getInstance(fromByteArray((byte[])obj));
+ return (ASN1Sequence)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage());
}
}
- else if (obj instanceof ASN1Encodable)
- {
- ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
- if (primitive instanceof ASN1Sequence)
- {
- return (ASN1Sequence)primitive;
- }
- }
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
}
@@ -122,51 +122,14 @@
* be converted.
* @return an ASN1Sequence instance.
*/
- public static ASN1Sequence getInstance(
- ASN1TaggedObject taggedObject,
- boolean explicit)
+ public static ASN1Sequence getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- if (explicit)
- {
- if (!taggedObject.isExplicit())
- {
- throw new IllegalArgumentException("object implicit - explicit expected.");
- }
-
- return getInstance(taggedObject.getObject());
- }
-
- ASN1Primitive o = taggedObject.getObject();
-
- /*
- * constructed object which appears to be explicitly tagged when it should be implicit means
- * we have to add the surrounding sequence.
- */
- if (taggedObject.isExplicit())
- {
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BERSequence(o);
- }
-
- return new DLSequence(o);
- }
-
- if (o instanceof ASN1Sequence)
- {
- ASN1Sequence s = (ASN1Sequence)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return s;
- }
-
- return (ASN1Sequence)s.toDLObject();
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ return (ASN1Sequence)TYPE.getContextInstance(taggedObject, explicit);
}
+ // NOTE: Only non-final to support LazyEncodedSequence
+ ASN1Encodable[] elements;
+
/**
* Create an empty SEQUENCE
*/
@@ -340,6 +303,7 @@
ASN1Sequence that = (ASN1Sequence)other;
+ // NOTE: Call size() here (on both) to 'force' a LazyEncodedSequence
int count = this.size();
if (that.size() != count)
{
@@ -378,13 +342,19 @@
return new DLSequence(elements, false);
}
- boolean isConstructed()
+ abstract ASN1BitString toASN1BitString();
+
+ abstract ASN1External toASN1External();
+
+ abstract ASN1OctetString toASN1OctetString();
+
+ abstract ASN1Set toASN1Set();
+
+ boolean encodeConstructed()
{
return true;
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
// NOTE: Call size() here to 'force' a LazyEncodedSequence
@@ -413,4 +383,28 @@
{
return new Arrays.Iterator<ASN1Encodable>(elements);
}
+
+ ASN1BitString[] getConstructedBitStrings()
+ {
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ int count = size();
+ ASN1BitString[] bitStrings = new ASN1BitString[count];
+ for (int i = 0; i < count; ++i)
+ {
+ bitStrings[i] = ASN1BitString.getInstance(elements[i]);
+ }
+ return bitStrings;
+ }
+
+ ASN1OctetString[] getConstructedOctetStrings()
+ {
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ int count = size();
+ ASN1OctetString[] octetStrings = new ASN1OctetString[count];
+ for (int i = 0; i < count; ++i)
+ {
+ octetStrings[i] = ASN1OctetString.getInstance(elements[i]);
+ }
+ return octetStrings;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java
index fd676d7..8cd3ad5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java
@@ -98,8 +98,13 @@
extends ASN1Primitive
implements org.bouncycastle.util.Iterable<ASN1Encodable>
{
- protected final ASN1Encodable[] elements;
- protected final boolean isSorted;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Set.class, BERTags.SET)
+ {
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence.toASN1Set();
+ }
+ };
/**
* return an ASN1Set from the given object.
@@ -108,37 +113,32 @@
* @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Set instance, or null.
*/
- public static ASN1Set getInstance(
- Object obj)
+ public static ASN1Set getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1Set)
{
return (ASN1Set)obj;
}
- else if (obj instanceof ASN1SetParser)
+// else if (obj instanceof ASN1SetParser)
+ else if (obj instanceof ASN1Encodable)
{
- return ASN1Set.getInstance(((ASN1SetParser)obj).toASN1Primitive());
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1Set)
+ {
+ return (ASN1Set)primitive;
+ }
}
else if (obj instanceof byte[])
{
try
{
- return ASN1Set.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ return (ASN1Set)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct set from byte[]: " + e.getMessage());
}
}
- else if (obj instanceof ASN1Encodable)
- {
- ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
- if (primitive instanceof ASN1Set)
- {
- return (ASN1Set)primitive;
- }
- }
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
}
@@ -160,73 +160,19 @@
* be converted.
* @return an ASN1Set instance.
*/
- public static ASN1Set getInstance(
- ASN1TaggedObject taggedObject,
- boolean explicit)
+ public static ASN1Set getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- if (explicit)
- {
- if (!taggedObject.isExplicit())
- {
- throw new IllegalArgumentException("object implicit - explicit expected.");
- }
-
- return getInstance(taggedObject.getObject());
- }
-
- ASN1Primitive o = taggedObject.getObject();
-
- /*
- * constructed object which appears to be explicitly tagged and it's really implicit means
- * we have to add the surrounding set.
- */
- if (taggedObject.isExplicit())
- {
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BERSet(o);
- }
-
- return new DLSet(o);
- }
-
- if (o instanceof ASN1Set)
- {
- ASN1Set s = (ASN1Set)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return s;
- }
-
- return (ASN1Set)s.toDLObject();
- }
-
- /*
- * in this case the parser returns a sequence, convert it into a set.
- */
- if (o instanceof ASN1Sequence)
- {
- ASN1Sequence s = (ASN1Sequence)o;
-
- // NOTE: Will force() a LazyEncodedSequence
- ASN1Encodable[] elements = s.toArrayInternal();
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BERSet(false, elements);
- }
-
- return new DLSet(false, elements);
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ return (ASN1Set)TYPE.getContextInstance(taggedObject, explicit);
}
+ protected final ASN1Encodable[] elements;
+
+ protected ASN1Encodable[] sortedElements;
+
protected ASN1Set()
{
this.elements = ASN1EncodableVector.EMPTY_ELEMENTS;
- this.isSorted = true;
+ this.sortedElements = elements;
}
/**
@@ -241,7 +187,7 @@
}
this.elements = new ASN1Encodable[]{ element };
- this.isSorted = true;
+ this.sortedElements = elements;
}
/**
@@ -268,7 +214,7 @@
}
this.elements = tmp;
- this.isSorted = doSort || tmp.length < 2;
+ this.sortedElements = (doSort || tmp.length < 2) ? elements : null;
}
/**
@@ -290,13 +236,19 @@
}
this.elements = tmp;
- this.isSorted = doSort || tmp.length < 2;
+ this.sortedElements = (doSort || tmp.length < 2) ? elements : null;
}
ASN1Set(boolean isSorted, ASN1Encodable[] elements)
{
this.elements = elements;
- this.isSorted = isSorted || elements.length < 2;
+ this.sortedElements = (isSorted || elements.length < 2) ? elements : null;
+ }
+
+ ASN1Set(ASN1Encodable[] elements, ASN1Encodable[] sortedElements)
+ {
+ this.elements = elements;
+ this.sortedElements = sortedElements;
}
public Enumeration getObjects()
@@ -408,18 +360,13 @@
*/
ASN1Primitive toDERObject()
{
- ASN1Encodable[] tmp;
- if (isSorted)
+ if (sortedElements == null)
{
- tmp = elements;
- }
- else
- {
- tmp = (ASN1Encodable[])elements.clone();
- sort(tmp);
+ sortedElements = (ASN1Encodable[])elements.clone();
+ sort(sortedElements);
}
- return new DERSet(true, tmp);
+ return new DERSet(true, sortedElements);
}
/**
@@ -428,7 +375,7 @@
*/
ASN1Primitive toDLObject()
{
- return new DLSet(isSorted, elements);
+ return new DLSet(elements, sortedElements);
}
boolean asn1Equals(ASN1Primitive other)
@@ -463,13 +410,11 @@
return true;
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return true;
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
int count = size();
@@ -529,8 +474,8 @@
* primitive form accordingly. Failing to ignore the CONSTRUCTED bit could therefore lead to
* ordering inversions.
*/
- int a0 = a[0] & ~BERTags.CONSTRUCTED;
- int b0 = b[0] & ~BERTags.CONSTRUCTED;
+ int a0 = a[0] & (~BERTags.CONSTRUCTED & 0xff);
+ int b0 = b[0] & (~BERTags.CONSTRUCTED & 0xff);
if (a0 != b0)
{
return a0 < b0;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java
index 95bc611..bfcebc8 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java
@@ -10,214 +10,257 @@
public class ASN1StreamParser
{
private final InputStream _in;
- private final int _limit;
+ private final int _limit;
private final byte[][] tmpBuffers;
- public ASN1StreamParser(
- InputStream in)
+ public ASN1StreamParser(InputStream in)
{
this(in, StreamUtil.findLimit(in));
}
- public ASN1StreamParser(
- InputStream in,
- int limit)
- {
- this._in = in;
- this._limit = limit;
-
- this.tmpBuffers = new byte[11][];
- }
-
- public ASN1StreamParser(
- byte[] encoding)
+ public ASN1StreamParser(byte[] encoding)
{
this(new ByteArrayInputStream(encoding), encoding.length);
}
- ASN1Encodable readIndef(int tagValue) throws IOException
+ public ASN1StreamParser(InputStream in, int limit)
{
- // Note: INDEF => CONSTRUCTED
-
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagValue)
- {
- case BERTags.EXTERNAL:
- return new DERExternalParser(this);
- case BERTags.OCTET_STRING:
- return new BEROctetStringParser(this);
- case BERTags.SEQUENCE:
- return new BERSequenceParser(this);
- case BERTags.SET:
- return new BERSetParser(this);
- default:
- throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(tagValue));
- }
+ this(in, limit, new byte[11][]);
}
- ASN1Encodable readImplicit(boolean constructed, int tag) throws IOException
+ ASN1StreamParser(InputStream in, int limit, byte[][] tmpBuffers)
{
- if (_in instanceof IndefiniteLengthInputStream)
- {
- if (!constructed)
- {
- throw new IOException("indefinite-length primitive encoding encountered");
- }
-
- return readIndef(tag);
- }
-
- if (constructed)
- {
- switch (tag)
- {
- case BERTags.SET:
- return new DLSetParser(this);
- case BERTags.SEQUENCE:
- return new DLSequenceParser(this);
- case BERTags.OCTET_STRING:
- return new BEROctetStringParser(this);
- }
- }
- else
- {
- switch (tag)
- {
- case BERTags.SET:
- throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
- case BERTags.SEQUENCE:
- throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
- case BERTags.OCTET_STRING:
- return new DEROctetStringParser((DefiniteLengthInputStream)_in);
- }
- }
-
- throw new ASN1Exception("implicit tagging not implemented");
+ this._in = in;
+ this._limit = limit;
+ this.tmpBuffers = tmpBuffers;
}
- ASN1Primitive readTaggedObject(boolean constructed, int tag) throws IOException
+ public ASN1Encodable readObject() throws IOException
{
- if (!constructed)
- {
- // Note: !CONSTRUCTED => IMPLICIT
- DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
- return new DLTaggedObject(false, tag, new DEROctetString(defIn.toByteArray()));
- }
-
- ASN1EncodableVector v = readVector();
-
- if (_in instanceof IndefiniteLengthInputStream)
- {
- return v.size() == 1
- ? new BERTaggedObject(true, tag, v.get(0))
- : new BERTaggedObject(false, tag, BERFactory.createSequence(v));
- }
-
- return v.size() == 1
- ? new DLTaggedObject(true, tag, v.get(0))
- : new DLTaggedObject(false, tag, DLFactory.createSequence(v));
- }
-
- public ASN1Encodable readObject()
- throws IOException
- {
- int tag = _in.read();
- if (tag == -1)
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
{
return null;
}
+ return implParseObject(tagHdr);
+ }
+
+ ASN1Encodable implParseObject(int tagHdr) throws IOException
+ {
//
- // turn of looking for "00" while we resolve the tag
+ // turn off looking for "00" while we resolve the tag
//
set00Check(false);
//
// calculate tag number
//
- int tagNo = ASN1InputStream.readTagNumber(_in, tag);
-
- boolean isConstructed = (tag & BERTags.CONSTRUCTED) != 0;
+ int tagNo = ASN1InputStream.readTagNumber(_in, tagHdr);
//
// calculate length
//
int length = ASN1InputStream.readLength(_in, _limit,
- tagNo == BERTags.OCTET_STRING || tagNo == BERTags.SEQUENCE || tagNo == BERTags.SET || tagNo == BERTags.EXTERNAL);
+ tagNo == BERTags.BIT_STRING || tagNo == BERTags.OCTET_STRING || tagNo == BERTags.SEQUENCE
+ || tagNo == BERTags.SET || tagNo == BERTags.EXTERNAL);
if (length < 0) // indefinite-length method
{
- if (!isConstructed)
+ if (0 == (tagHdr & BERTags.CONSTRUCTED))
{
throw new IOException("indefinite-length primitive encoding encountered");
}
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit);
- ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit);
+ ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit, tmpBuffers);
- if ((tag & BERTags.APPLICATION) != 0)
+ int tagClass = tagHdr & BERTags.PRIVATE;
+ if (0 != tagClass)
{
- return new BERApplicationSpecificParser(tagNo, sp);
+ return new BERTaggedObjectParser(tagClass, tagNo, sp);
}
- if ((tag & BERTags.TAGGED) != 0)
- {
- return new BERTaggedObjectParser(true, tagNo, sp);
- }
-
- return sp.readIndef(tagNo);
+ return sp.parseImplicitConstructedIL(tagNo);
}
else
{
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length, _limit);
- if ((tag & BERTags.APPLICATION) != 0)
+ if (0 == (tagHdr & BERTags.FLAGS))
{
- return new DLApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
+ return parseImplicitPrimitive(tagNo, defIn);
}
- if ((tag & BERTags.TAGGED) != 0)
+ ASN1StreamParser sp = new ASN1StreamParser(defIn, defIn.getLimit(), tmpBuffers);
+
+ int tagClass = tagHdr & BERTags.PRIVATE;
+ if (0 != tagClass)
{
- return new BERTaggedObjectParser(isConstructed, tagNo, new ASN1StreamParser(defIn));
+ boolean isConstructed = (tagHdr & BERTags.CONSTRUCTED) != 0;
+
+ return new DLTaggedObjectParser(tagClass, tagNo, isConstructed, sp);
}
- if (isConstructed)
- {
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagNo)
- {
- case BERTags.OCTET_STRING:
- //
- // yes, people actually do this...
- //
- return new BEROctetStringParser(new ASN1StreamParser(defIn));
- case BERTags.SEQUENCE:
- return new DLSequenceParser(new ASN1StreamParser(defIn));
- case BERTags.SET:
- return new DLSetParser(new ASN1StreamParser(defIn));
- case BERTags.EXTERNAL:
- return new DERExternalParser(new ASN1StreamParser(defIn));
- default:
- throw new IOException("unknown tag " + tagNo + " encountered");
- }
- }
+ return sp.parseImplicitConstructedDL(tagNo);
+ }
+ }
- // Some primitive encodings can be handled by parsers too...
- switch (tagNo)
- {
- case BERTags.OCTET_STRING:
- return new DEROctetStringParser(defIn);
- }
+ ASN1Primitive loadTaggedDL(int tagClass, int tagNo, boolean constructed) throws IOException
+ {
+ if (!constructed)
+ {
+ byte[] contentsOctets = ((DefiniteLengthInputStream) _in).toByteArray();
+ return ASN1TaggedObject.createPrimitive(tagClass, tagNo, contentsOctets);
+ }
- try
+ ASN1EncodableVector contentsElements = readVector();
+ return ASN1TaggedObject.createConstructedDL(tagClass, tagNo, contentsElements);
+ }
+
+ ASN1Primitive loadTaggedIL(int tagClass, int tagNo) throws IOException
+ {
+ ASN1EncodableVector contentsElements = readVector();
+ return ASN1TaggedObject.createConstructedIL(tagClass, tagNo, contentsElements);
+ }
+
+ ASN1Encodable parseImplicitConstructedDL(int univTagNo) throws IOException
+ {
+ switch (univTagNo)
+ {
+ case BERTags.BIT_STRING:
+ // TODO[asn1] DLConstructedBitStringParser
+ return new BERBitStringParser(this);
+ case BERTags.EXTERNAL:
+ return new DERExternalParser(this);
+ case BERTags.OCTET_STRING:
+ // TODO[asn1] DLConstructedOctetStringParser
+ return new BEROctetStringParser(this);
+ case BERTags.SET:
+ return new DLSetParser(this);
+ case BERTags.SEQUENCE:
+ return new DLSequenceParser(this);
+ default:
+ // -DM toHexString
+ throw new ASN1Exception("unknown DL object encountered: 0x" + Integer.toHexString(univTagNo));
+ }
+ }
+
+ ASN1Encodable parseImplicitConstructedIL(int univTagNo) throws IOException
+ {
+ switch (univTagNo)
+ {
+ case BERTags.BIT_STRING:
+ return new BERBitStringParser(this);
+ case BERTags.OCTET_STRING:
+ return new BEROctetStringParser(this);
+ case BERTags.EXTERNAL:
+ // TODO[asn1] BERExternalParser
+ return new DERExternalParser(this);
+ case BERTags.SEQUENCE:
+ return new BERSequenceParser(this);
+ case BERTags.SET:
+ return new BERSetParser(this);
+ default:
+ throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(univTagNo));
+ }
+ }
+
+ ASN1Encodable parseImplicitPrimitive(int univTagNo) throws IOException
+ {
+ return parseImplicitPrimitive(univTagNo, (DefiniteLengthInputStream)_in);
+ }
+
+ ASN1Encodable parseImplicitPrimitive(int univTagNo, DefiniteLengthInputStream defIn) throws IOException
+ {
+ // Some primitive encodings can be handled by parsers too...
+ switch (univTagNo)
+ {
+ case BERTags.BIT_STRING:
+ return new DLBitStringParser(defIn);
+ case BERTags.EXTERNAL:
+ throw new ASN1Exception("externals must use constructed encoding (see X.690 8.18)");
+ case BERTags.OCTET_STRING:
+ return new DEROctetStringParser(defIn);
+ case BERTags.SET:
+ throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
+ case BERTags.SEQUENCE:
+ throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
+ }
+
+ try
+ {
+ return ASN1InputStream.createPrimitiveDERObject(univTagNo, defIn, tmpBuffers);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception("corrupted stream detected", e);
+ }
+ }
+
+ ASN1Encodable parseObject(int univTagNo) throws IOException
+ {
+ if (univTagNo < 0 || univTagNo > 30)
+ {
+ throw new IllegalArgumentException("invalid universal tag number: " + univTagNo);
+ }
+
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
+ {
+ return null;
+ }
+
+ if ((tagHdr & ~BERTags.CONSTRUCTED) != univTagNo)
+ {
+ throw new IOException("unexpected identifier encountered: " + tagHdr);
+ }
+
+ return implParseObject(tagHdr);
+ }
+
+ ASN1TaggedObjectParser parseTaggedObject() throws IOException
+ {
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
+ {
+ return null;
+ }
+
+ int tagClass = tagHdr & BERTags.PRIVATE;
+ if (0 == tagClass)
+ {
+ throw new ASN1Exception("no tagged object found");
+ }
+
+ return (ASN1TaggedObjectParser)implParseObject(tagHdr);
+ }
+
+ // TODO[asn1] Prefer 'loadVector'
+ ASN1EncodableVector readVector() throws IOException
+ {
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
+ {
+ return new ASN1EncodableVector(0);
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ do
+ {
+ ASN1Encodable obj = implParseObject(tagHdr);
+
+ if (obj instanceof InMemoryRepresentable)
{
- return ASN1InputStream.createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
+ v.add(((InMemoryRepresentable) obj).getLoadedObject());
}
- catch (IllegalArgumentException e)
+ else
{
- throw new ASN1Exception("corrupted stream detected", e);
+ v.add(obj.toASN1Primitive());
}
}
+ while ((tagHdr = _in.read()) >= 0);
+ return v;
}
private void set00Check(boolean enabled)
@@ -227,28 +270,4 @@
((IndefiniteLengthInputStream)_in).setEofOn00(enabled);
}
}
-
- ASN1EncodableVector readVector() throws IOException
- {
- ASN1Encodable obj = readObject();
- if (null == obj)
- {
- return new ASN1EncodableVector(0);
- }
-
- ASN1EncodableVector v = new ASN1EncodableVector();
- do
- {
- if (obj instanceof InMemoryRepresentable)
- {
- v.add(((InMemoryRepresentable)obj).getLoadedObject());
- }
- else
- {
- v.add(obj.toASN1Primitive());
- }
- }
- while ((obj = readObject()) != null);
- return v;
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1T61String.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1T61String.java
new file mode 100644
index 0000000..2592005
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1T61String.java
@@ -0,0 +1,145 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 T61String (also the teletex string), try not to use this if you don't need to. The standard support the encoding for
+ * this has been withdrawn.
+ */
+public abstract class ASN1T61String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1T61String.class, BERTags.T61_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a T61 string from the passed in object.
+ *
+ * @param obj an ASN1T61String or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1T61String instance, or null
+ */
+ public static ASN1T61String getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1T61String)
+ {
+ return (ASN1T61String)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1T61String)
+ {
+ return (ASN1T61String)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1T61String)TYPE.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());
+ }
+
+ /**
+ * Return an T61 String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1T61String instance, or null
+ */
+ public static ASN1T61String getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1T61String)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1T61String(String string)
+ {
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1T61String(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ /**
+ * Decode the encoded string and return it, 8 bit encoding assumed.
+ * @return the decoded String
+ */
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.T61_STRING, contents);
+ }
+
+ /**
+ * Return the encoded string as a byte array.
+ * @return the actual bytes making up the encoded body of the T61 string.
+ */
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1T61String))
+ {
+ return false;
+ }
+
+ ASN1T61String that = (ASN1T61String)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1T61String createPrimitive(byte[] contents)
+ {
+ return new DERT61String(contents, false);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Tag.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Tag.java
new file mode 100644
index 0000000..280e8c6
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Tag.java
@@ -0,0 +1,28 @@
+package org.bouncycastle.asn1;
+
+final class ASN1Tag
+{
+ static ASN1Tag create(int tagClass, int tagNumber)
+ {
+ return new ASN1Tag(tagClass, tagNumber);
+ }
+
+ private final int tagClass;
+ private final int tagNumber;
+
+ private ASN1Tag(int tagClass, int tagNumber)
+ {
+ this.tagClass = tagClass;
+ this.tagNumber = tagNumber;
+ }
+
+ int getTagClass()
+ {
+ return tagClass;
+ }
+
+ int getTagNumber()
+ {
+ return tagNumber;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
index 00aac91..78c59b9 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
@@ -2,6 +2,8 @@
import java.io.IOException;
+import org.bouncycastle.util.Arrays;
+
/**
* ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by
* a [n] where n is some number - these are assumed to follow the construction
@@ -11,34 +13,32 @@
extends ASN1Primitive
implements ASN1TaggedObjectParser
{
- final int tagNo;
- final boolean explicit;
- final ASN1Encodable obj;
+ private static final int DECLARED_EXPLICIT = 1;
+ private static final int DECLARED_IMPLICIT = 2;
+ // TODO It will probably be better to track parsing constructed vs primitive instead
+ private static final int PARSED_EXPLICIT = 3;
+ private static final int PARSED_IMPLICIT = 4;
- static public ASN1TaggedObject getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- if (explicit)
- {
- return getInstance(obj.getObject());
- }
-
- throw new IllegalArgumentException("implicitly tagged tagged object");
- }
-
- static public ASN1TaggedObject getInstance(
- Object obj)
+ public static ASN1TaggedObject getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1TaggedObject)
{
return (ASN1TaggedObject)obj;
}
+// else if (obj instanceof ASN1TaggedObjectParser)
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1TaggedObject)
+ {
+ return (ASN1TaggedObject)primitive;
+ }
+ }
else if (obj instanceof byte[])
{
try
{
- return ASN1TaggedObject.getInstance(fromByteArray((byte[])obj));
+ return checkedCast(fromByteArray((byte[])obj));
}
catch (IOException e)
{
@@ -49,6 +49,58 @@
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
}
+ public static ASN1TaggedObject getInstance(Object obj, int tagClass)
+ {
+ if (obj == null)
+ {
+ throw new NullPointerException("'obj' cannot be null");
+ }
+
+ ASN1TaggedObject taggedObject = getInstance(obj);
+ if (tagClass != taggedObject.getTagClass())
+ {
+ throw new IllegalArgumentException("unexpected tag in getInstance: " + ASN1Util.getTagText(taggedObject));
+ }
+
+ return taggedObject;
+ }
+
+ public static ASN1TaggedObject getInstance(Object obj, int tagClass, int tagNo)
+ {
+ if (obj == null)
+ {
+ throw new NullPointerException("'obj' cannot be null");
+ }
+
+ ASN1TaggedObject taggedObject = getInstance(obj);
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ throw new IllegalArgumentException("unexpected tag in getInstance: " + ASN1Util.getTagText(taggedObject));
+ }
+
+ return taggedObject;
+ }
+
+ public static ASN1TaggedObject getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
+ {
+ if (BERTags.CONTEXT_SPECIFIC != taggedObject.getTagClass())
+ {
+ throw new IllegalStateException("this method only valid for CONTEXT_SPECIFIC tags");
+ }
+
+ if (declaredExplicit)
+ {
+ return taggedObject.getExplicitBaseTagged();
+ }
+
+ throw new IllegalArgumentException("this method not valid for implicitly tagged tagged objects");
+ }
+
+ final int explicitness;
+ final int tagClass;
+ final int tagNo;
+ final ASN1Encodable obj;
+
/**
* Create a tagged object with the style given by the value of explicit.
* <p>
@@ -59,22 +111,34 @@
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public ASN1TaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
+ protected ASN1TaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
+ {
+ this(explicit, BERTags.CONTEXT_SPECIFIC, tagNo, obj);
+ }
+
+ protected ASN1TaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ this(explicit ? DECLARED_EXPLICIT : DECLARED_IMPLICIT, tagClass, tagNo, obj);
+ }
+
+ ASN1TaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
{
if (null == obj)
{
throw new NullPointerException("'obj' cannot be null");
}
+ if (tagClass == BERTags.UNIVERSAL || (tagClass & BERTags.PRIVATE) != tagClass)
+ {
+ throw new IllegalArgumentException("invalid tag class: " + tagClass);
+ }
+ this.explicitness = (obj instanceof ASN1Choice) ? DECLARED_EXPLICIT : explicitness;
+ this.tagClass = tagClass;
this.tagNo = tagNo;
- this.explicit = explicit || (obj instanceof ASN1Choice);
this.obj = obj;
}
- boolean asn1Equals(ASN1Primitive other)
+ final boolean asn1Equals(ASN1Primitive other)
{
if (!(other instanceof ASN1TaggedObject))
{
@@ -83,20 +147,58 @@
ASN1TaggedObject that = (ASN1TaggedObject)other;
- if (this.tagNo != that.tagNo || this.explicit != that.explicit)
+ if (this.tagNo != that.tagNo ||
+ this.tagClass != that.tagClass)
{
return false;
}
+ if (this.explicitness != that.explicitness)
+ {
+ /*
+ * TODO This seems incorrect for some cases of implicit tags e.g. if one is a
+ * declared-implicit SET and the other a parsed object.
+ */
+ if (this.isExplicit() != that.isExplicit())
+ {
+ return false;
+ }
+ }
+
ASN1Primitive p1 = this.obj.toASN1Primitive();
ASN1Primitive p2 = that.obj.toASN1Primitive();
- return p1 == p2 || p1.asn1Equals(p2);
+ if (p1 == p2)
+ {
+ return true;
+ }
+
+ if (!this.isExplicit())
+ {
+ try
+ {
+ byte[] d1 = this.getEncoded();
+ byte[] d2 = that.getEncoded();
+
+ return Arrays.areEqual(d1, d2);
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
+ }
+
+ return p1.asn1Equals(p2);
}
public int hashCode()
{
- return tagNo ^ (explicit ? 0x0F : 0xF0) ^ obj.toASN1Primitive().hashCode();
+ return (tagClass * 7919) ^ tagNo ^ (isExplicit() ? 0x0F : 0xF0) ^ obj.toASN1Primitive().hashCode();
+ }
+
+ public int getTagClass()
+ {
+ return tagClass;
}
/**
@@ -109,18 +211,24 @@
return tagNo;
}
- /**
- * return whether or not the object may be explicitly tagged.
- * <p>
- * Note: if the object has been read from an input stream, the only
- * time you can be sure if isExplicit is returning the true state of
- * affairs is if it returns false. An implicitly tagged object may appear
- * to be explicitly tagged, so you need to understand the context under
- * which the reading was done as well, see getObject below.
- */
- public boolean isExplicit()
+ public boolean hasContextTag()
{
- return explicit;
+ return this.tagClass == BERTags.CONTEXT_SPECIFIC;
+ }
+
+ public boolean hasContextTag(int tagNo)
+ {
+ return this.tagClass == BERTags.CONTEXT_SPECIFIC && this.tagNo == tagNo;
+ }
+
+ public boolean hasTag(int tagClass, int tagNo)
+ {
+ return this.tagClass == tagClass && this.tagNo == tagNo;
+ }
+
+ public boolean hasTagClass(int tagClass)
+ {
+ return this.tagClass == tagClass;
}
/**
@@ -136,52 +244,246 @@
}
/**
- * Return the object held in this tagged object as a parser assuming it has
- * the type of the passed in tag. If the object doesn't have a parser
- * associated with it, the base object is returned.
+ * return whether or not the object may be explicitly tagged.
+ * <p>
+ * Note: if the object has been read from an input stream, the only
+ * time you can be sure if isExplicit is returning the true state of
+ * affairs is if it returns false. An implicitly tagged object may appear
+ * to be explicitly tagged, so you need to understand the context under
+ * which the reading was done as well, see getObject below.
*/
- public ASN1Encodable getObjectParser(
- int tag,
- boolean isExplicit)
- throws IOException
+ public boolean isExplicit()
{
- switch (tag)
+ // TODO New methods like 'isKnownExplicit' etc. to distinguish uncertain cases?
+ switch (explicitness)
{
- case BERTags.SET:
- return ASN1Set.getInstance(this, isExplicit).parser();
- case BERTags.SEQUENCE:
- return ASN1Sequence.getInstance(this, isExplicit).parser();
+ case DECLARED_EXPLICIT:
+ case PARSED_EXPLICIT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ boolean isParsed()
+ {
+ switch (explicitness)
+ {
+ case PARSED_EXPLICIT:
+ case PARSED_IMPLICIT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Needed for open types, until we have better type-guided parsing support. Use sparingly for other
+ * purposes, and prefer {@link #getExplicitBaseTagged()}, {@link #getImplicitBaseTagged(int, int)} or
+ * {@link #getBaseUniversal(boolean, int)} where possible. Before using, check for matching tag
+ * {@link #getTagClass() class} and {@link #getTagNo() number}.
+ */
+ public ASN1Object getBaseObject()
+ {
+ return obj instanceof ASN1Object ? (ASN1Object)obj : obj.toASN1Primitive();
+ }
+
+ /**
+ * Needed for open types, until we have better type-guided parsing support. Use
+ * sparingly for other purposes, and prefer {@link #getExplicitBaseTagged()} or
+ * {@link #getBaseUniversal(boolean, int)} where possible. Before using, check
+ * for matching tag {@link #getTagClass() class} and {@link #getTagNo() number}.
+ */
+ public ASN1Object getExplicitBaseObject()
+ {
+ if (!isExplicit())
+ {
+ throw new IllegalStateException("object implicit - explicit expected.");
+ }
+
+ return obj instanceof ASN1Object ? (ASN1Object)obj : obj.toASN1Primitive();
+ }
+
+ public ASN1TaggedObject getExplicitBaseTagged()
+ {
+ if (!isExplicit())
+ {
+ throw new IllegalStateException("object implicit - explicit expected.");
+ }
+
+ return checkedCast(obj.toASN1Primitive());
+ }
+
+ public ASN1TaggedObject getImplicitBaseTagged(int baseTagClass, int baseTagNo)
+ {
+ if (baseTagClass == BERTags.UNIVERSAL || (baseTagClass & BERTags.PRIVATE) != baseTagClass)
+ {
+ throw new IllegalArgumentException("invalid base tag class: " + baseTagClass);
+ }
+
+ switch (explicitness)
+ {
+ case DECLARED_EXPLICIT:
+ throw new IllegalStateException("object explicit - implicit expected.");
+
+ case DECLARED_IMPLICIT:
+ {
+ ASN1TaggedObject declared = checkedCast(obj.toASN1Primitive());
+ return ASN1Util.checkTag(declared, baseTagClass, baseTagNo);
+ }
+
+ // Parsed; return a virtual tag (i.e. that couldn't have been present in the encoding)
+ default:
+ return replaceTag(baseTagClass, baseTagNo);
+ }
+ }
+
+ /**
+ * Note: tagged objects are generally context dependent. Before trying to
+ * extract a tagged object this way, make sure you have checked that both the
+ * {@link #getTagClass() tag class} and {@link #getTagNo() tag number} match
+ * what you are looking for.
+ *
+ * @param declaredExplicit Whether the tagged type for this object was declared
+ * EXPLICIT.
+ * @param tagNo The universal {@link BERTags tag number} of the
+ * expected base object.
+ */
+ public ASN1Primitive getBaseUniversal(boolean declaredExplicit, int tagNo)
+ {
+ ASN1UniversalType universalType = ASN1UniversalTypes.get(tagNo);
+ if (null == universalType)
+ {
+ throw new IllegalArgumentException("unsupported UNIVERSAL tag number: " + tagNo);
+ }
+
+ return getBaseUniversal(declaredExplicit, universalType);
+ }
+
+ ASN1Primitive getBaseUniversal(boolean declaredExplicit, ASN1UniversalType universalType)
+ {
+ if (declaredExplicit)
+ {
+ if (!isExplicit())
+ {
+ throw new IllegalStateException("object explicit - implicit expected.");
+ }
+
+ return universalType.checkedCast(obj.toASN1Primitive());
+ }
+
+ if (DECLARED_EXPLICIT == explicitness)
+ {
+ throw new IllegalStateException("object explicit - implicit expected.");
+ }
+
+ ASN1Primitive primitive = obj.toASN1Primitive();
+ switch (explicitness)
+ {
+ case PARSED_EXPLICIT:
+ return universalType.fromImplicitConstructed(rebuildConstructed(primitive));
+ case PARSED_IMPLICIT:
+ {
+ if (primitive instanceof ASN1Sequence)
+ {
+ return universalType.fromImplicitConstructed((ASN1Sequence)primitive);
+ }
+ return universalType.fromImplicitPrimitive((DEROctetString)primitive);
+ }
+ default:
+ return universalType.checkedCast(primitive);
+ }
+ }
+
+ public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ ASN1Primitive primitive = getBaseUniversal(declaredExplicit, baseTagNo);
+
+ switch (baseTagNo)
+ {
+ case BERTags.BIT_STRING:
+ return ((ASN1BitString)primitive).parser();
case BERTags.OCTET_STRING:
- return ASN1OctetString.getInstance(this, isExplicit).parser();
+ return ((ASN1OctetString)primitive).parser();
+ case BERTags.SEQUENCE:
+ return ((ASN1Sequence)primitive).parser();
+ case BERTags.SET:
+ return ((ASN1Set)primitive).parser();
}
- if (isExplicit)
- {
- return getObject();
- }
-
- throw new ASN1Exception("implicit tagging not implemented for tag: " + tag);
+ return primitive;
}
- public ASN1Primitive getLoadedObject()
+ public ASN1Encodable parseExplicitBaseObject() throws IOException
{
- return this.toASN1Primitive();
+ return getExplicitBaseObject();
}
+ public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException
+ {
+ return getExplicitBaseTagged();
+ }
+
+ public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException
+ {
+ return getImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public final ASN1Primitive getLoadedObject()
+ {
+ return this;
+ }
+
+ abstract ASN1Sequence rebuildConstructed(ASN1Primitive primitive);
+
+ abstract ASN1TaggedObject replaceTag(int tagClass, int tagNo);
+
ASN1Primitive toDERObject()
{
- return new DERTaggedObject(explicit, tagNo, obj);
+ return new DERTaggedObject(explicitness, tagClass, tagNo, obj);
}
ASN1Primitive toDLObject()
{
- return new DLTaggedObject(explicit, tagNo, obj);
+ return new DLTaggedObject(explicitness, tagClass, tagNo, obj);
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
- return "[" + tagNo + "]" + obj;
+ return ASN1Util.getTagText(tagClass, tagNo) + obj;
+ }
+
+ static ASN1Primitive createConstructedDL(int tagClass, int tagNo, ASN1EncodableVector contentsElements)
+ {
+ boolean maybeExplicit = (contentsElements.size() == 1);
+
+ return maybeExplicit
+ ? new DLTaggedObject(PARSED_EXPLICIT, tagClass, tagNo, contentsElements.get(0))
+ : new DLTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, DLFactory.createSequence(contentsElements));
+ }
+
+ static ASN1Primitive createConstructedIL(int tagClass, int tagNo, ASN1EncodableVector contentsElements)
+ {
+ boolean maybeExplicit = (contentsElements.size() == 1);
+
+ return maybeExplicit
+ ? new BERTaggedObject(PARSED_EXPLICIT, tagClass, tagNo, contentsElements.get(0))
+ : new BERTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, BERFactory.createSequence(contentsElements));
+ }
+
+ static ASN1Primitive createPrimitive(int tagClass, int tagNo, byte[] contentsOctets)
+ {
+ // Note: !CONSTRUCTED => IMPLICIT
+ return new DLTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, new DEROctetString(contentsOctets));
+ }
+
+ private static ASN1TaggedObject checkedCast(ASN1Primitive primitive)
+ {
+ if (primitive instanceof ASN1TaggedObject)
+ {
+ return (ASN1TaggedObject)primitive;
+ }
+
+ throw new IllegalStateException("unexpected object: " + primitive.getClass().getName());
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObjectParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObjectParser.java
index 660d9a2..f92bc1c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObjectParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObjectParser.java
@@ -9,19 +9,38 @@
extends ASN1Encodable, InMemoryRepresentable
{
/**
- * Return the tag number associated with the underlying tagged object.
- * @return the object's tag number.
+ * Return the tag class associated with this object.
+ *
+ * @return the tag class.
+ */
+ int getTagClass();
+
+ /**
+ * Return the tag number associated with this object.
+ *
+ * @return the tag number.
*/
int getTagNo();
+ boolean hasContextTag();
+
+ boolean hasContextTag(int tagNo);
+
+ boolean hasTag(int tagClass, int tagNo);
+
+ boolean hasTagClass(int tagClass);
+
+ ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException;
+
/**
- * Return a parser for the actual object tagged.
- *
- * @param tag the primitive tag value for the object tagged originally.
- * @param isExplicit true if the tagging was done explicitly.
- * @return a parser for the tagged object.
- * @throws IOException if a parser cannot be constructed.
+ * Needed for open types, until we have better type-guided parsing support. Use sparingly for other
+ * purposes, and prefer {@link #parseExplicitBaseTagged()} or {@link #parseBaseUniversal(boolean, int)}
+ * where possible. Before using, check for matching tag {@link #getTagClass() class} and
+ * {@link #getTagNo() number}.
*/
- ASN1Encodable getObjectParser(int tag, boolean isExplicit)
- throws IOException;
+ ASN1Encodable parseExplicitBaseObject() throws IOException;
+
+ ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException;
+
+ ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Type.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Type.java
new file mode 100644
index 0000000..5ab85d7
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Type.java
@@ -0,0 +1,26 @@
+package org.bouncycastle.asn1;
+
+abstract class ASN1Type
+{
+ final Class javaClass;
+
+ ASN1Type(Class javaClass)
+ {
+ this.javaClass = javaClass;
+ }
+
+ final Class getJavaClass()
+ {
+ return javaClass;
+ }
+
+ public final boolean equals(Object that)
+ {
+ return this == that;
+ }
+
+ public final int hashCode()
+ {
+ return super.hashCode();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTCTime.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTCTime.java
index d9a2629..34ba2fe 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTCTime.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTCTime.java
@@ -36,7 +36,13 @@
public class ASN1UTCTime
extends ASN1Primitive
{
- private byte[] time;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1UTCTime.class, BERTags.UTC_TIME)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
/**
* Return an UTC Time from the passed in object.
@@ -52,12 +58,19 @@
{
return (ASN1UTCTime)obj;
}
-
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1UTCTime)
+ {
+ return (ASN1UTCTime)primitive;
+ }
+ }
if (obj instanceof byte[])
{
try
{
- return (ASN1UTCTime)fromByteArray((byte[])obj);
+ return (ASN1UTCTime)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -71,29 +84,19 @@
/**
* Return an UTC Time from a tagged object.
*
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
* @return an ASN1UTCTime instance, or null.
*/
- public static ASN1UTCTime getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1UTCTime getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Object o = obj.getObject();
-
- if (explicit || o instanceof ASN1UTCTime)
- {
- return getInstance(o);
- }
- else
- {
- return new ASN1UTCTime(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1UTCTime)TYPE.getContextInstance(taggedObject, explicit);
}
+ final byte[] contents;
+
/**
* The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
* never encoded. When you're creating one of these objects from scratch, that's
@@ -107,7 +110,7 @@
public ASN1UTCTime(
String time)
{
- this.time = Strings.toByteArray(time);
+ this.contents = Strings.toByteArray(time);
try
{
this.getDate();
@@ -131,7 +134,7 @@
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
/**
@@ -153,17 +156,16 @@
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
- ASN1UTCTime(
- byte[] time)
+ ASN1UTCTime(byte[] contents)
{
- if (time.length < 2)
+ if (contents.length < 2)
{
throw new IllegalArgumentException("UTCTime string too short");
}
- this.time = time;
+ this.contents = contents;
if (!(isDigit(0) && isDigit(1)))
{
throw new IllegalArgumentException("illegal characters in UTCTime string");
@@ -184,7 +186,7 @@
// SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz");
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz", Locale.US);
- return DateUtil.epochAdjust(dateF.parse(getTime()));
+ return dateF.parse(getTime());
}
/**
@@ -202,8 +204,8 @@
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz", Locale.US);
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
-
- return DateUtil.epochAdjust(dateF.parse(getAdjustedTime()));
+
+ return dateF.parse(getAdjustedTime());
}
/**
@@ -224,7 +226,7 @@
*/
public String getTime()
{
- String stime = Strings.fromByteArray(time);
+ String stime = Strings.fromByteArray(contents);
//
// standardise the format.
@@ -285,24 +287,22 @@
private boolean isDigit(int pos)
{
- return time.length > pos && time[pos] >= '0' && time[pos] <= '9';
+ return contents.length > pos && contents[pos] >= '0' && contents[pos] <= '9';
}
- boolean isConstructed()
+ final boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- int length = time.length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.UTC_TIME, time);
+ out.writeEncodingDL(withTag, BERTags.UTC_TIME, contents);
}
boolean asn1Equals(
@@ -313,16 +313,21 @@
return false;
}
- return Arrays.areEqual(time, ((ASN1UTCTime)o).time);
+ return Arrays.areEqual(contents, ((ASN1UTCTime)o).contents);
}
public int hashCode()
{
- return Arrays.hashCode(time);
+ return Arrays.hashCode(contents);
}
public String toString()
{
- return Strings.fromByteArray(time);
+ return Strings.fromByteArray(contents);
+ }
+
+ static ASN1UTCTime createPrimitive(byte[] contents)
+ {
+ return new ASN1UTCTime(contents);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTF8String.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTF8String.java
new file mode 100644
index 0000000..8f8d00c
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTF8String.java
@@ -0,0 +1,129 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+public abstract class ASN1UTF8String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1UTF8String.class, BERTags.UTF8_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a UTF8 string from the passed in object.
+ *
+ * @param obj an ASN1UTF8String or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1UTF8String instance, or null
+ */
+ public static ASN1UTF8String getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1UTF8String)
+ {
+ return (ASN1UTF8String)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1UTF8String)
+ {
+ return (ASN1UTF8String)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1UTF8String)TYPE.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());
+ }
+
+ /**
+ * Return an UTF8 String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return a DERUTF8String instance, or null
+ */
+ public static ASN1UTF8String getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1UTF8String)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1UTF8String(String string)
+ {
+ this(Strings.toUTF8ByteArray(string), false);
+ }
+
+ ASN1UTF8String(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromUTF8ByteArray(contents);
+ }
+
+ // TODO Not sure this is useful unless all ASN.1 types have a meaningful one
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1UTF8String))
+ {
+ return false;
+ }
+
+ ASN1UTF8String that = (ASN1UTF8String)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.UTF8_STRING, contents);
+ }
+
+ static ASN1UTF8String createPrimitive(byte[] contents)
+ {
+ return new DERUTF8String(contents, false);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UniversalString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UniversalString.java
new file mode 100644
index 0000000..fe8addf
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UniversalString.java
@@ -0,0 +1,178 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+
+/**
+ * ASN.1 UniversalString object - encodes UNICODE (ISO 10646) characters using 32-bit format. In Java we
+ * have no way of representing this directly so we rely on byte arrays to carry these.
+ */
+public abstract class ASN1UniversalString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1UniversalString.class, BERTags.UNIVERSAL_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ /**
+ * Return a Universal String from the passed in object.
+ *
+ * @param obj an ASN1UniversalString or an object that can be converted into
+ * one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1UniversalString instance, or null
+ */
+ public static ASN1UniversalString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1UniversalString)
+ {
+ return (ASN1UniversalString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1UniversalString)
+ {
+ return (ASN1UniversalString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1UniversalString)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return a Universal String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return a ASN1UniversalString instance, or null
+ */
+ public static ASN1UniversalString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1UniversalString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1UniversalString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ int dl = contents.length;
+ StringBuffer buf = new StringBuffer(3 + 2 * (ASN1OutputStream.getLengthOfDL(dl) + dl));
+ buf.append("#1C");
+ encodeHexDL(buf, dl);
+
+ for (int i = 0; i < dl; ++i)
+ {
+ encodeHexByte(buf, contents[i]);
+ }
+
+ return buf.toString();
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.UNIVERSAL_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1UniversalString))
+ {
+ return false;
+ }
+
+ ASN1UniversalString that = (ASN1UniversalString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1UniversalString createPrimitive(byte[] contents)
+ {
+ return new DERUniversalString(contents, false);
+ }
+
+ private static void encodeHexByte(StringBuffer buf, int i)
+ {
+ buf.append(table[(i >>> 4) & 0xF]);
+ buf.append(table[i & 0xF]);
+ }
+
+ private static void encodeHexDL(StringBuffer buf, int dl)
+ {
+ if (dl < 128)
+ {
+ encodeHexByte(buf, dl);
+ return;
+ }
+
+ byte[] stack = new byte[5];
+ int pos = 5;
+
+ do
+ {
+ stack[--pos] = (byte)dl;
+ dl >>>= 8;
+ }
+ while (dl != 0);
+
+ int count = stack.length - pos;
+ stack[--pos] = (byte)(0x80 | count);
+
+ do
+ {
+ encodeHexByte(buf, stack[pos++]);
+ }
+ while (pos < stack.length);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UniversalType.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UniversalType.java
new file mode 100644
index 0000000..f0bde9d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UniversalType.java
@@ -0,0 +1,56 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+abstract class ASN1UniversalType
+ extends ASN1Type
+{
+ final ASN1Tag tag;
+
+ ASN1UniversalType(Class javaClass, int tagNumber)
+ {
+ super(javaClass);
+
+ this.tag = ASN1Tag.create(BERTags.UNIVERSAL, tagNumber);
+ }
+
+ final ASN1Primitive checkedCast(ASN1Primitive primitive)
+ {
+ if (javaClass.isInstance(primitive))
+ {
+ return primitive;
+ }
+
+ throw new IllegalStateException("unexpected object: " + primitive.getClass().getName());
+ }
+
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ throw new IllegalStateException("unexpected implicit primitive encoding");
+ }
+
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ throw new IllegalStateException("unexpected implicit constructed encoding");
+ }
+
+ final ASN1Primitive fromByteArray(byte[] bytes) throws IOException
+ {
+ return checkedCast(ASN1Primitive.fromByteArray(bytes));
+ }
+
+ final ASN1Primitive getContextInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
+ {
+ if (BERTags.CONTEXT_SPECIFIC != taggedObject.getTagClass())
+ {
+ throw new IllegalStateException("this method only valid for CONTEXT_SPECIFIC tags");
+ }
+
+ return checkedCast(taggedObject.getBaseUniversal(declaredExplicit, this));
+ }
+
+ final ASN1Tag getTag()
+ {
+ return tag;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UniversalTypes.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UniversalTypes.java
new file mode 100644
index 0000000..da217fa
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UniversalTypes.java
@@ -0,0 +1,71 @@
+package org.bouncycastle.asn1;
+
+final class ASN1UniversalTypes
+{
+ private ASN1UniversalTypes()
+ {
+ }
+
+ static ASN1UniversalType get(int tagNumber)
+ {
+ switch (tagNumber)
+ {
+ case BERTags.BOOLEAN:
+ return ASN1Boolean.TYPE;
+ case BERTags.INTEGER:
+ return ASN1Integer.TYPE;
+ case BERTags.BIT_STRING:
+ return ASN1BitString.TYPE;
+ case BERTags.OCTET_STRING:
+ return ASN1OctetString.TYPE;
+ case BERTags.NULL:
+ return ASN1Null.TYPE;
+ case BERTags.OBJECT_IDENTIFIER:
+ return ASN1ObjectIdentifier.TYPE;
+ case BERTags.OBJECT_DESCRIPTOR: // [UNIVERSAL 7] IMPLICIT GraphicString
+ return ASN1ObjectDescriptor.TYPE;
+ case BERTags.EXTERNAL:
+ return ASN1External.TYPE;
+ case BERTags.ENUMERATED:
+ return ASN1Enumerated.TYPE;
+ case BERTags.UTF8_STRING: // [UNIVERSAL 12] IMPLICIT OCTET STRING (encode as if)
+ return ASN1UTF8String.TYPE;
+ case BERTags.RELATIVE_OID:
+ return ASN1RelativeOID.TYPE;
+ case BERTags.SEQUENCE:
+ return ASN1Sequence.TYPE;
+ case BERTags.SET:
+ return ASN1Set.TYPE;
+ case BERTags.NUMERIC_STRING: // [UNIVERSAL 18] IMPLICIT OCTET STRING (encode as if)
+ return ASN1NumericString.TYPE;
+ case BERTags.PRINTABLE_STRING: // [UNIVERSAL 19] IMPLICIT OCTET STRING (encode as if)
+ return ASN1PrintableString.TYPE;
+ case BERTags.T61_STRING: // [UNIVERSAL 20] IMPLICIT OCTET STRING (encode as if)
+ return ASN1T61String.TYPE;
+ case BERTags.VIDEOTEX_STRING: // [UNIVERSAL 21] IMPLICIT OCTET STRING (encode as if)
+ return ASN1VideotexString.TYPE;
+ case BERTags.IA5_STRING: // [UNIVERSAL 22] IMPLICIT OCTET STRING (encode as if)
+ return ASN1IA5String.TYPE;
+ case BERTags.UTC_TIME: // [UNIVERSAL 23] IMPLICIT VisibleString (restricted values)
+ return ASN1UTCTime.TYPE;
+ case BERTags.GENERALIZED_TIME: // [UNIVERSAL 24] IMPLICIT VisibleString (restricted values)
+ return ASN1GeneralizedTime.TYPE;
+ case BERTags.GRAPHIC_STRING: // [UNIVERSAL 25] IMPLICIT OCTET STRING (encode as if)
+ return ASN1GraphicString.TYPE;
+ case BERTags.VISIBLE_STRING: // [UNIVERSAL 26] IMPLICIT OCTET STRING (encode as if)
+ return ASN1VisibleString.TYPE;
+ case BERTags.GENERAL_STRING: // [UNIVERSAL 27] IMPLICIT OCTET STRING (encode as if)
+ return ASN1GeneralString.TYPE;
+ case BERTags.UNIVERSAL_STRING: // [UNIVERSAL 28] IMPLICIT OCTET STRING (encode as if)
+ return ASN1UniversalString.TYPE;
+ case BERTags.BMP_STRING: // [UNIVERSAL 30] IMPLICIT OCTET STRING (encode as if)
+ return ASN1BMPString.TYPE;
+
+ case BERTags.REAL:
+ case BERTags.EMBEDDED_PDV:
+ case BERTags.UNRESTRICTED_STRING:
+ default:
+ return null;
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Util.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Util.java
new file mode 100644
index 0000000..eced42d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Util.java
@@ -0,0 +1,327 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+public abstract class ASN1Util
+{
+ static ASN1TaggedObject checkTag(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ String expected = getTagText(tagClass, tagNo);
+ String found = getTagText(taggedObject);
+ throw new IllegalStateException("Expected " + expected + " tag but found " + found);
+ }
+ return taggedObject;
+ }
+
+ static ASN1TaggedObjectParser checkTag(ASN1TaggedObjectParser taggedObjectParser, int tagClass, int tagNo)
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ String expected = getTagText(tagClass, tagNo);
+ String found = getTagText(taggedObjectParser);
+ throw new IllegalStateException("Expected " + expected + " tag but found " + found);
+ }
+ return taggedObjectParser;
+ }
+
+
+ /*
+ * Tag text methods
+ */
+
+ static String getTagText(ASN1Tag tag)
+ {
+ return getTagText(tag.getTagClass(), tag.getTagNumber());
+ }
+
+ public static String getTagText(ASN1TaggedObject taggedObject)
+ {
+ return getTagText(taggedObject.getTagClass(), taggedObject.getTagNo());
+ }
+
+ public static String getTagText(ASN1TaggedObjectParser taggedObjectParser)
+ {
+ return getTagText(taggedObjectParser.getTagClass(), taggedObjectParser.getTagNo());
+ }
+
+ public static String getTagText(int tagClass, int tagNo)
+ {
+ switch (tagClass)
+ {
+ case BERTags.APPLICATION:
+ return "[APPLICATION " + tagNo + "]";
+ case BERTags.CONTEXT_SPECIFIC:
+ return "[CONTEXT " + tagNo + "]";
+ case BERTags.PRIVATE:
+ return "[PRIVATE " + tagNo + "]";
+ default:
+ return "[UNIVERSAL " + tagNo + "]";
+ }
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getExplicitBaseObject
+ */
+
+ public static ASN1Object getExplicitBaseObject(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getExplicitBaseObject();
+ }
+
+ public static ASN1Object getExplicitContextBaseObject(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return getExplicitBaseObject(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1Object tryGetExplicitBaseObject(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getExplicitBaseObject();
+ }
+
+ public static ASN1Object tryGetExplicitContextBaseObject(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return tryGetExplicitBaseObject(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getExplicitBaseTagged
+ */
+
+ public static ASN1TaggedObject getExplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObject getExplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return getExplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1TaggedObject tryGetExplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObject tryGetExplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return tryGetExplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getImplicitBaseTagged
+ */
+
+ public static ASN1TaggedObject getImplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObject getImplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ return getImplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObject tryGetImplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObject tryGetImplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ return tryGetImplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getBaseUniversal
+ */
+
+ public static ASN1Primitive getBaseUniversal(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Primitive getContextBaseUniversal(ASN1TaggedObject taggedObject, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ return getBaseUniversal(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Primitive tryGetBaseUniversal(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Primitive tryGetContextBaseUniversal(ASN1TaggedObject taggedObject, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ return tryGetBaseUniversal(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseExplicitBaseTagged
+ */
+
+ public static ASN1TaggedObjectParser parseExplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObjectParser parseExplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo) throws IOException
+ {
+ return parseExplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1TaggedObjectParser tryParseExplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObjectParser tryParseExplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo) throws IOException
+ {
+ return tryParseExplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseImplicitBaseTagged
+ */
+
+ public static ASN1TaggedObjectParser parseImplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObjectParser parseImplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ return parseImplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObjectParser tryParseImplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObjectParser tryParseImplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ return tryParseImplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseBaseUniversal
+ */
+
+ public static ASN1Encodable parseBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo, boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Encodable parseContextBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagNo,
+ boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ return parseBaseUniversal(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Encodable tryParseBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo, boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Encodable tryParseContextBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagNo,
+ boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ return tryParseBaseUniversal(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseExplicitBaseObject
+ */
+
+ public static ASN1Encodable parseExplicitBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseExplicitBaseObject();
+ }
+
+ public static ASN1Encodable parseExplicitContextBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagNo)
+ throws IOException
+ {
+ return parseExplicitBaseObject(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1Encodable tryParseExplicitBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseExplicitBaseObject();
+ }
+
+ public static ASN1Encodable tryParseExplicitContextBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagNo)
+ throws IOException
+ {
+ return tryParseExplicitBaseObject(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1VideotexString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1VideotexString.java
new file mode 100644
index 0000000..ae9c422
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1VideotexString.java
@@ -0,0 +1,127 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+public abstract class ASN1VideotexString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1VideotexString.class, BERTags.VIDEOTEX_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * return a Videotex String from the passed in object
+ *
+ * @param obj an ASN1VideotexString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1VideotexString instance, or null.
+ */
+ public static ASN1VideotexString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1VideotexString)
+ {
+ return (ASN1VideotexString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1VideotexString)
+ {
+ return (ASN1VideotexString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1VideotexString)TYPE.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());
+ }
+
+ /**
+ * return a Videotex String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1VideotexString instance, or null.
+ */
+ public static ASN1VideotexString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1VideotexString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ /**
+ * basic constructor - with bytes.
+ * @param string the byte encoding of the characters making up the string.
+ */
+ ASN1VideotexString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.VIDEOTEX_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1VideotexString))
+ {
+ return false;
+ }
+
+ ASN1VideotexString that = (ASN1VideotexString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ static ASN1VideotexString createPrimitive(byte[] contents)
+ {
+ return new DERVideotexString(contents, false);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1VisibleString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1VisibleString.java
new file mode 100644
index 0000000..6424cfc
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1VisibleString.java
@@ -0,0 +1,141 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 VisibleString object encoding ISO 646 (ASCII) character code points 32 to 126.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ */
+public abstract class ASN1VisibleString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1VisibleString.class, BERTags.VISIBLE_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a Visible String from the passed in object.
+ *
+ * @param obj an ASN1VisibleString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1VisibleString instance, or null
+ */
+ public static ASN1VisibleString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1VisibleString)
+ {
+ return (ASN1VisibleString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1VisibleString)
+ {
+ return (ASN1VisibleString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1VisibleString)TYPE.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());
+ }
+
+ /**
+ * Return a Visible String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1VisibleString instance, or null
+ */
+ public static ASN1VisibleString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1VisibleString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1VisibleString(String string)
+ {
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1VisibleString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.VISIBLE_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1VisibleString))
+ {
+ return false;
+ }
+
+ ASN1VisibleString that = (ASN1VisibleString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1VisibleString createPrimitive(byte[] contents)
+ {
+ return new DERVisibleString(contents, false);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java
deleted file mode 100644
index a0e3600..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * An indefinite-length encoding version of an ASN.1 ApplicationSpecific object.
- */
-public class BERApplicationSpecific
- extends ASN1ApplicationSpecific
-{
- BERApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- super(isConstructed, tag, octets);
- }
-
- /**
- * Create an application specific object with a tagging of explicit/constructed.
- *
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public BERApplicationSpecific(
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- this(true, tag, object);
- }
-
- /**
- * Create an application specific object with the tagging style given by the value of constructed.
- *
- * @param constructed true if the object is constructed.
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public BERApplicationSpecific(
- boolean constructed,
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
- }
-
- private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
- throws IOException
- {
- byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.BER);
-
- if (explicit)
- {
- return data;
- }
- else
- {
- int lenBytes = getLengthOfHeader(data);
- byte[] tmp = new byte[data.length - lenBytes];
- System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
- return tmp;
- }
- }
-
- /**
- * Create an application specific object which is marked as constructed
- *
- * @param tagNo the tag number for this object.
- * @param vec the objects making up the application specific object.
- */
- public BERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
- {
- super(true, tagNo, getEncodedVector(vec));
- }
-
- private static byte[] getEncodedVector(ASN1EncodableVector vec)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != vec.size(); i++)
- {
- try
- {
- bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.BER));
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("malformed object: " + e, e);
- }
- }
- return bOut.toByteArray();
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncodedIndef(withTag, flags, tag, octets);
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java
deleted file mode 100644
index c915415..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-/**
- * A parser for indefinite-length ASN.1 ApplicationSpecific objects.
- */
-public class BERApplicationSpecificParser
- implements ASN1ApplicationSpecificParser
-{
- private final int tag;
- private final ASN1StreamParser parser;
-
- BERApplicationSpecificParser(int tag, ASN1StreamParser parser)
- {
- this.tag = tag;
- this.parser = parser;
- }
-
- /**
- * Return the object contained in this application specific object,
- * @return the contained object.
- * @throws IOException if the underlying stream cannot be read, or does not contain an ASN.1 encoding.
- */
- public ASN1Encodable readObject()
- throws IOException
- {
- return parser.readObject();
- }
-
- /**
- * Return an in-memory, encodable, representation of the application specific object.
- *
- * @return a BERApplicationSpecific.
- * @throws IOException if there is an issue loading the data.
- */
- public ASN1Primitive getLoadedObject()
- throws IOException
- {
- return new BERApplicationSpecific(tag, parser.readVector());
- }
-
- /**
- * Return a BERApplicationSpecific representing this parser and its contents.
- *
- * @return a BERApplicationSpecific
- */
- public ASN1Primitive toASN1Primitive()
- {
- try
- {
- return getLoadedObject();
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException(e.getMessage(), e);
- }
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERBitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERBitString.java
new file mode 100644
index 0000000..45ebaa4
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERBitString.java
@@ -0,0 +1,188 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+public class BERBitString
+ extends ASN1BitString
+{
+ private static final int DEFAULT_SEGMENT_LIMIT = 1000;
+
+ private final int segmentLimit;
+ private final ASN1BitString[] elements;
+
+ /**
+ * Convert a vector of bit strings into a single bit string
+ */
+ static byte[] flattenBitStrings(ASN1BitString[] bitStrings)
+ {
+ int count = bitStrings.length;
+ switch (count)
+ {
+ case 0:
+ // No bits
+ return new byte[]{ 0 };
+ case 1:
+ return bitStrings[0].contents;
+ default:
+ {
+ int last = count - 1, totalLength = 0;
+ for (int i = 0; i < last; ++i)
+ {
+ byte[] elementContents = bitStrings[i].contents;
+ if (elementContents[0] != 0)
+ {
+ throw new IllegalArgumentException("only the last nested bitstring can have padding");
+ }
+
+ totalLength += elementContents.length - 1;
+ }
+
+ // Last one can have padding
+ byte[] lastElementContents = bitStrings[last].contents;
+ byte padBits = lastElementContents[0];
+ totalLength += lastElementContents.length;
+
+ byte[] contents = new byte[totalLength];
+ contents[0] = padBits;
+
+ int pos = 1;
+ for (int i = 0; i < count; ++i)
+ {
+ byte[] elementContents = bitStrings[i].contents;
+ int length = elementContents.length - 1;
+ System.arraycopy(elementContents, 1, contents, pos, length);
+ pos += length;
+ }
+
+// assert pos == totalLength;
+ return contents;
+ }
+ }
+ }
+
+ public BERBitString(byte[] data)
+ {
+ this(data, 0);
+ }
+
+ public BERBitString(byte data, int padBits)
+ {
+ super(data, padBits);
+ this.elements = null;
+ this.segmentLimit = DEFAULT_SEGMENT_LIMIT;
+ }
+
+ public BERBitString(byte[] data, int padBits)
+ {
+ this(data, padBits, DEFAULT_SEGMENT_LIMIT);
+ }
+
+ public BERBitString(byte[] data, int padBits, int segmentLimit)
+ {
+ super(data, padBits);
+ this.elements = null;
+ this.segmentLimit = segmentLimit;
+ }
+
+ public BERBitString(ASN1Encodable obj) throws IOException
+ {
+ this(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
+ }
+
+ public BERBitString(ASN1BitString[] elements)
+ {
+ this(elements, DEFAULT_SEGMENT_LIMIT);
+ }
+
+ public BERBitString(ASN1BitString[] elements, int segmentLimit)
+ {
+ super(flattenBitStrings(elements), false);
+ this.elements = elements;
+ this.segmentLimit = segmentLimit;
+ }
+
+ BERBitString(byte[] contents, boolean check)
+ {
+ super(contents, check);
+ this.elements = null;
+ this.segmentLimit = DEFAULT_SEGMENT_LIMIT;
+ }
+
+ boolean encodeConstructed()
+ {
+ return null != elements || contents.length > segmentLimit;
+ }
+
+ int encodedLength(boolean withTag)
+ throws IOException
+ {
+ if (!encodeConstructed())
+ {
+ return DLBitString.encodedLength(withTag, contents.length);
+ }
+
+ int totalLength = withTag ? 4 : 3;
+
+ if (null != elements)
+ {
+ for (int i = 0; i < elements.length; ++i)
+ {
+ totalLength += elements[i].encodedLength(true);
+ }
+ }
+ else if (contents.length < 2)
+ {
+ // No bits
+ }
+ else
+ {
+ int extraSegments = (contents.length - 2) / (segmentLimit - 1);
+ totalLength += extraSegments * DLBitString.encodedLength(true, segmentLimit);
+
+ int lastSegmentLength = contents.length - (extraSegments * (segmentLimit - 1));
+ totalLength += DLBitString.encodedLength(true, lastSegmentLength);
+ }
+
+ return totalLength;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ if (!encodeConstructed())
+ {
+ DLBitString.encode(out, withTag, contents, 0, contents.length);
+ return;
+ }
+
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.BIT_STRING);
+ out.write(0x80);
+
+ if (null != elements)
+ {
+ out.writePrimitives(elements);
+ }
+ else if (contents.length < 2)
+ {
+ // No bits
+ }
+ else
+ {
+ byte pad = contents[0];
+ int length = contents.length;
+ int remaining = length - 1;
+ int segmentLength = segmentLimit - 1;
+
+ while (remaining > segmentLength)
+ {
+ DLBitString.encode(out, true, (byte)0, contents, length - remaining, segmentLength);
+ remaining -= segmentLength;
+ }
+
+ DLBitString.encode(out, true, pad, contents, length - remaining, remaining);
+ }
+
+ out.write(0x00);
+ out.write(0x00);
+ }
+}
+
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERBitStringParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERBitStringParser.java
new file mode 100644
index 0000000..9b2cfaf
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERBitStringParser.java
@@ -0,0 +1,66 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.bouncycastle.util.io.Streams;
+
+/**
+ * A parser for indefinite-length BIT STRINGs.
+ *
+ * @deprecated Check for 'ASN1BitStringParser' instead
+ */
+public class BERBitStringParser
+ implements ASN1BitStringParser
+{
+ private ASN1StreamParser _parser;
+
+ private ConstructedBitStream _bitStream;
+
+ BERBitStringParser(
+ ASN1StreamParser parser)
+ {
+ _parser = parser;
+ }
+
+ public InputStream getOctetStream() throws IOException
+ {
+ return _bitStream = new ConstructedBitStream(_parser, true);
+ }
+
+ public InputStream getBitStream() throws IOException
+ {
+ return _bitStream = new ConstructedBitStream(_parser, false);
+ }
+
+ public int getPadBits()
+ {
+ return _bitStream.getPadBits();
+ }
+
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return parse(_parser);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
+ }
+ }
+
+ static BERBitString parse(ASN1StreamParser sp) throws IOException
+ {
+ ConstructedBitStream bitStream = new ConstructedBitStream(sp, false);
+ byte[] data = Streams.readAll(bitStream);
+ int padBits = bitStream.getPadBits();
+ return new BERBitString(data, padBits);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERConstructedOctetString.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERConstructedOctetString.java
deleted file mode 100644
index cad6e42..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERConstructedOctetString.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Vector;
-
-/**
- * @deprecated use BEROctetString
- */
-public class BERConstructedOctetString
- extends BEROctetString
-{
- private static final int MAX_LENGTH = 1000;
-
- /**
- * convert a vector of octet strings into a single byte string
- */
- static private byte[] toBytes(
- Vector octs)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != octs.size(); i++)
- {
- try
- {
- DEROctetString o = (DEROctetString)octs.elementAt(i);
-
- bOut.write(o.getOctets());
- }
- catch (ClassCastException e)
- {
- throw new IllegalArgumentException(octs.elementAt(i).getClass().getName() + " found in input should only contain DEROctetString");
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("exception converting octets " + e.toString());
- }
- }
-
- return bOut.toByteArray();
- }
-
- private Vector octs;
-
- /**
- * @param string the octets making up the octet string.
- */
- public BERConstructedOctetString(
- byte[] string)
- {
- super(string);
- }
-
- public BERConstructedOctetString(
- Vector octs)
- {
- super(toBytes(octs));
-
- this.octs = octs;
- }
-
- public BERConstructedOctetString(
- ASN1Primitive obj)
- {
- super(toByteArray(obj));
- }
-
- private static byte[] toByteArray(ASN1Primitive obj)
- {
- try
- {
- return obj.getEncoded();
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("Unable to encode object");
- }
- }
-
- public BERConstructedOctetString(
- ASN1Encodable obj)
- {
- this(obj.toASN1Primitive());
- }
-
- public byte[] getOctets()
- {
- return string;
- }
-
- /**
- * return the DER octets that make up this string.
- */
- public Enumeration getObjects()
- {
- if (octs == null)
- {
- return generateOcts().elements();
- }
-
- return octs.elements();
- }
-
- private Vector generateOcts()
- {
- Vector vec = new Vector();
- for (int i = 0; i < string.length; i += MAX_LENGTH)
- {
- int end;
-
- if (i + MAX_LENGTH > string.length)
- {
- end = string.length;
- }
- else
- {
- end = i + MAX_LENGTH;
- }
-
- byte[] nStr = new byte[end - i];
-
- System.arraycopy(string, i, nStr, 0, nStr.length);
-
- vec.addElement(new DEROctetString(nStr));
- }
-
- return vec;
- }
-
- public static BEROctetString fromSequence(ASN1Sequence seq)
- {
- Vector v = new Vector();
- Enumeration e = seq.getObjects();
-
- while (e.hasMoreElements())
- {
- v.addElement(e.nextElement());
- }
-
- return new BERConstructedOctetString(v);
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java
index b492157..ad2b37f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java
@@ -6,7 +6,7 @@
/**
* Base class for generators for indefinite-length structures.
*/
-public class BERGenerator
+public abstract class BERGenerator
extends ASN1Generator
{
private boolean _tagged = false;
@@ -43,7 +43,7 @@
{
if (_tagged)
{
- int tagNum = _tagNo | BERTags.TAGGED;
+ int tagNum = _tagNo | BERTags.CONTEXT_SPECIFIC;
if (_isExplicit)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetString.java b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetString.java
index 3544c56..dbc8e4b 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetString.java
@@ -1,9 +1,6 @@
package org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
/**
* ASN.1 OctetStrings, with indefinite length rules, and <i>constructed form</i> support.
@@ -22,172 +19,148 @@
public class BEROctetString
extends ASN1OctetString
{
- private static final int DEFAULT_CHUNK_SIZE = 1000;
+ private static final int DEFAULT_SEGMENT_LIMIT = 1000;
- private final int chunkSize;
- private final ASN1OctetString[] octs;
+ private final int segmentLimit;
+ private final ASN1OctetString[] elements;
/**
* Convert a vector of octet strings into a single byte string
*/
- static private byte[] toBytes(
- ASN1OctetString[] octs)
+ static byte[] flattenOctetStrings(ASN1OctetString[] octetStrings)
{
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != octs.length; i++)
+ int count = octetStrings.length;
+ switch (count)
{
- try
+ case 0:
+ return EMPTY_OCTETS;
+ case 1:
+ return octetStrings[0].string;
+ default:
+ {
+ int totalOctets = 0;
+ for (int i = 0; i < count; ++i)
{
- bOut.write(octs[i].getOctets());
+ totalOctets += octetStrings[i].string.length;
}
- catch (IOException e)
+
+ byte[] string = new byte[totalOctets];
+ for (int i = 0, pos = 0; i < count; ++i)
{
- throw new IllegalArgumentException("exception converting octets " + e.toString());
+ byte[] octets = octetStrings[i].string;
+ System.arraycopy(octets, 0, string, pos, octets.length);
+ pos += octets.length;
}
+
+// assert pos == totalOctets;
+ return string;
}
-
- return bOut.toByteArray();
+ }
}
/**
* Create an OCTET-STRING object from a byte[]
* @param string the octets making up the octet string.
*/
- public BEROctetString(
- byte[] string)
+ public BEROctetString(byte[] string)
{
- this(string, DEFAULT_CHUNK_SIZE);
+ this(string, DEFAULT_SEGMENT_LIMIT);
}
/**
* Multiple {@link ASN1OctetString} data blocks are input,
* the result is <i>constructed form</i>.
*
- * @param octs an array of OCTET STRING to construct the BER OCTET STRING from.
+ * @param elements an array of OCTET STRING to construct the BER OCTET STRING from.
*/
- public BEROctetString(
- ASN1OctetString[] octs)
+ public BEROctetString(ASN1OctetString[] elements)
{
- this(octs, DEFAULT_CHUNK_SIZE);
+ this(elements, DEFAULT_SEGMENT_LIMIT);
}
/**
* Create an OCTET-STRING object from a byte[]
* @param string the octets making up the octet string.
- * @param chunkSize the number of octets stored in each DER encoded component OCTET STRING.
+ * @param segmentLimit the number of octets stored in each DER encoded component OCTET STRING.
*/
- public BEROctetString(
- byte[] string,
- int chunkSize)
+ public BEROctetString(byte[] string, int segmentLimit)
{
- this(string, null, chunkSize);
+ this(string, null, segmentLimit);
}
/**
* Multiple {@link ASN1OctetString} data blocks are input,
* the result is <i>constructed form</i>.
*
- * @param octs an array of OCTET STRING to construct the BER OCTET STRING from.
- * @param chunkSize the number of octets stored in each DER encoded component OCTET STRING.
+ * @param elements an array of OCTET STRING to construct the BER OCTET STRING from.
+ * @param segmentLimit the number of octets stored in each DER encoded component OCTET STRING.
*/
- public BEROctetString(
- ASN1OctetString[] octs,
- int chunkSize)
+ public BEROctetString(ASN1OctetString[] elements, int segmentLimit)
{
- this(toBytes(octs), octs, chunkSize);
+ this(flattenOctetStrings(elements), elements, segmentLimit);
}
- private BEROctetString(byte[] string, ASN1OctetString[] octs, int chunkSize)
+ private BEROctetString(byte[] string, ASN1OctetString[] elements, int segmentLimit)
{
super(string);
- this.octs = octs;
- this.chunkSize = chunkSize;
+ this.elements = elements;
+ this.segmentLimit = segmentLimit;
}
- /**
- * Return the OCTET STRINGs that make up this string.
- *
- * @return an Enumeration of the component OCTET STRINGs.
- */
- public Enumeration getObjects()
- {
- if (octs == null)
- {
- return new Enumeration()
- {
- int pos = 0;
-
- public boolean hasMoreElements()
- {
- return pos < string.length;
- }
-
- public Object nextElement()
- {
- if (pos < string.length)
- {
- int length = Math.min(string.length - pos, chunkSize);
- byte[] chunk = new byte[length];
- System.arraycopy(string, pos, chunk, 0, length);
- pos += length;
- return new DEROctetString(chunk);
- }
- throw new NoSuchElementException();
- }
- };
- }
-
- return new Enumeration()
- {
- int counter = 0;
-
- public boolean hasMoreElements()
- {
- return counter < octs.length;
- }
-
- public Object nextElement()
- {
- if (counter < octs.length)
- {
- return octs[counter++];
- }
- throw new NoSuchElementException();
- }
- };
- }
-
- boolean isConstructed()
+ boolean encodeConstructed()
{
return true;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
throws IOException
{
- int length = 0;
- for (Enumeration e = getObjects(); e.hasMoreElements();)
+ int totalLength = withTag ? 4 : 3;
+
+ if (null != elements)
{
- length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
+ for (int i = 0; i < elements.length; ++i)
+ {
+ totalLength += elements[i].encodedLength(true);
+ }
+ }
+ else
+ {
+ int fullSegments = string.length / segmentLimit;
+ totalLength += fullSegments * DEROctetString.encodedLength(true, segmentLimit);
+
+ int lastSegmentLength = string.length - (fullSegments * segmentLimit);
+ if (lastSegmentLength > 0)
+ {
+ totalLength += DEROctetString.encodedLength(true, lastSegmentLength);
+ }
}
- return 2 + length + 2;
+ return totalLength;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncodedIndef(withTag, BERTags.CONSTRUCTED | BERTags.OCTET_STRING, getObjects());
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
+ out.write(0x80);
- static BEROctetString fromSequence(ASN1Sequence seq)
- {
- int count = seq.size();
- ASN1OctetString[] v = new ASN1OctetString[count];
- for (int i = 0; i < count; ++i)
+ if (null != elements)
{
- v[i] = ASN1OctetString.getInstance(seq.getObjectAt(i));
+ out.writePrimitives(elements);
}
- return new BEROctetString(v);
+ else
+ {
+ int pos = 0;
+ while (pos < string.length)
+ {
+ int segmentLength = Math.min(string.length - pos, segmentLimit);
+ DEROctetString.encode(out, true, string, pos, segmentLength);
+ pos += segmentLength;
+ }
+ }
+
+ out.write(0x00);
+ out.write(0x00);
}
}
+
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java
index 68bf801..8be481f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java
@@ -96,23 +96,32 @@
public void write(byte[] b, int off, int len) throws IOException
{
- while (len > 0)
+ int bufLen = _buf.length;
+ int available = bufLen - _off;
+ if (len < available)
{
- int numToCopy = Math.min(len, _buf.length - _off);
- System.arraycopy(b, off, _buf, _off, numToCopy);
-
- _off += numToCopy;
- if (_off < _buf.length)
- {
- break;
- }
-
- DEROctetString.encode(_derOut, true, _buf, 0, _buf.length);
- _off = 0;
-
- off += numToCopy;
- len -= numToCopy;
+ System.arraycopy(b, off, _buf, _off, len);
+ _off += len;
+ return;
}
+
+ int count = 0;
+ if (_off > 0)
+ {
+ System.arraycopy(b, off, _buf, _off, available);
+ count += available;
+ DEROctetString.encode(_derOut, true, _buf, 0, bufLen);
+ }
+
+ int remaining;
+ while ((remaining = (len - count)) >= bufLen)
+ {
+ DEROctetString.encode(_derOut, true, b, off + count, bufLen);
+ count += bufLen;
+ }
+
+ System.arraycopy(b, off + count, _buf, 0, remaining);
+ this._off = remaining;
}
public void close()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java
index 77a3049..bce7f01 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java
@@ -7,6 +7,8 @@
/**
* A parser for indefinite-length OCTET STRINGs.
+ *
+ * @deprecated Check for 'ASN1OctetStringParser' instead
*/
public class BEROctetStringParser
implements ASN1OctetStringParser
@@ -38,7 +40,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new BEROctetString(Streams.readAll(getOctetStream()));
+ return parse(_parser);
}
/**
@@ -57,4 +59,9 @@
throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
}
}
+
+ static BEROctetString parse(ASN1StreamParser sp) throws IOException
+ {
+ return new BEROctetString(Streams.readAll(new ConstructedOctetStream(sp)));
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java
index 269c6d4..b50f493 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java
@@ -44,22 +44,42 @@
super(elements);
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int count = elements.length;
- int totalLength = 0;
+ int totalLength = withTag ? 4 : 3;
- for (int i = 0; i < count; ++i)
+ for (int i = 0, count = elements.length; i < count; ++i)
{
ASN1Primitive p = elements[i].toASN1Primitive();
- totalLength += p.encodedLength();
+ totalLength += p.encodedLength(true);
}
- return 2 + totalLength + 2;
+ return totalLength;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncodedIndef(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, elements);
+ out.writeEncodingIL(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE, elements);
+ }
+
+ ASN1BitString toASN1BitString()
+ {
+ return new BERBitString(getConstructedBitStrings());
+ }
+
+ ASN1External toASN1External()
+ {
+ // TODO There is currently no BERExternal class
+ return ((ASN1Sequence)toDLObject()).toASN1External();
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ return new BEROctetString(getConstructedOctetStrings());
+ }
+
+ ASN1Set toASN1Set()
+ {
+ return new BERSet(false, toArrayInternal());
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java
index 543a182..c53b001 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java
@@ -4,6 +4,8 @@
/**
* Parser for indefinite-length SEQUENCEs.
+ *
+ * @deprecated Check for 'ASN1SequenceParser' instead
*/
public class BERSequenceParser
implements ASN1SequenceParser
@@ -36,7 +38,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new BERSequence(_parser.readVector());
+ return parse(_parser);
}
/**
@@ -55,4 +57,9 @@
throw new IllegalStateException(e.getMessage());
}
}
+
+ static BERSequence parse(ASN1StreamParser sp) throws IOException
+ {
+ return new BERSequence(sp.readVector());
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java
index 905b4e7..f900258 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java
@@ -59,22 +59,21 @@
super(isSorted, elements);
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int count = elements.length;
- int totalLength = 0;
+ int totalLength = withTag ? 4 : 3;
- for (int i = 0; i < count; ++i)
+ for (int i = 0, count = elements.length; i < count; ++i)
{
ASN1Primitive p = elements[i].toASN1Primitive();
- totalLength += p.encodedLength();
+ totalLength += p.encodedLength(true);
}
- return 2 + totalLength + 2;
+ return totalLength;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncodedIndef(withTag, BERTags.SET | BERTags.CONSTRUCTED, elements);
+ out.writeEncodingIL(withTag, BERTags.CONSTRUCTED | BERTags.SET, elements);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERSetParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERSetParser.java
index c6e1809..cc369df 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERSetParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERSetParser.java
@@ -4,6 +4,8 @@
/**
* Parser for indefinite-length SETs.
+ *
+ * @deprecated Check for 'ASN1SetParser' instead
*/
public class BERSetParser
implements ASN1SetParser
@@ -36,7 +38,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new BERSet(_parser.readVector());
+ return parse(_parser);
}
/**
@@ -55,4 +57,9 @@
throw new ASN1ParsingException(e.getMessage(), e);
}
}
-}
\ No newline at end of file
+
+ static BERSet parse(ASN1StreamParser sp) throws IOException
+ {
+ return new BERSet(sp.readVector());
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java
index 51036f6..1ef1ccb 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java
@@ -1,7 +1,6 @@
package org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* BER TaggedObject - in ASN.1 notation this is any object preceded by
@@ -15,124 +14,96 @@
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public BERTaggedObject(
- int tagNo,
- ASN1Encodable obj)
+ public BERTaggedObject(int tagNo, ASN1Encodable obj)
{
super(true, tagNo, obj);
}
+ public BERTaggedObject(int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ super(true, tagClass, tagNo, obj);
+ }
+
/**
* @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public BERTaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
+ public BERTaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
{
super(explicit, tagNo, obj);
}
- /**
- * create an implicitly tagged object that contains a zero
- * length sequence.
- */
- public BERTaggedObject(
- int tagNo)
+ public BERTaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
{
- super(false, tagNo, new BERSequence());
+ super(explicit, tagClass, tagNo, obj);
}
- boolean isConstructed()
+ BERTaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
{
- return explicit || obj.toASN1Primitive().isConstructed();
+ super(explicitness, tagClass, tagNo, obj);
}
- int encodedLength()
- throws IOException
+ boolean encodeConstructed()
+ {
+ return isExplicit() || obj.toASN1Primitive().encodeConstructed();
+ }
+
+ int encodedLength(boolean withTag) throws IOException
{
ASN1Primitive primitive = obj.toASN1Primitive();
- int length = primitive.encodedLength();
+ boolean explicit = isExplicit();
+
+ int length = primitive.encodedLength(explicit);
if (explicit)
{
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ length += 3;
}
- else
- {
- // header length already in calculation
- length = length - 1;
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ length += withTag ? ASN1OutputStream.getLengthOfIdentifier(tagNo) : 0;
+
+ return length;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeTag(withTag, BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
- out.write(0x80);
+// assert out.getClass().isAssignableFrom(ASN1OutputStream.class);
- if (!explicit)
+ ASN1Primitive primitive = obj.toASN1Primitive();
+ boolean explicit = isExplicit();
+
+ if (withTag)
{
- Enumeration e;
- if (obj instanceof ASN1OctetString)
+ int flags = tagClass;
+ if (explicit || primitive.encodeConstructed())
{
- if (obj instanceof BEROctetString)
- {
- e = ((BEROctetString)obj).getObjects();
- }
- else
- {
- ASN1OctetString octs = (ASN1OctetString)obj;
- BEROctetString berO = new BEROctetString(octs.getOctets());
- e = berO.getObjects();
- }
- }
- else if (obj instanceof ASN1Sequence)
- {
- e = ((ASN1Sequence)obj).getObjects();
- }
- else if (obj instanceof ASN1Set)
- {
- e = ((ASN1Set)obj).getObjects();
- }
- else
- {
- throw new ASN1Exception("not implemented: " + obj.getClass().getName());
+ flags |= BERTags.CONSTRUCTED;
}
- out.writeElements(e);
+ out.writeIdentifier(true, flags, tagNo);
+ }
+
+ if (explicit)
+ {
+ out.write(0x80);
+ primitive.encode(out, true);
+ out.write(0x00);
+ out.write(0x00);
}
else
{
- out.writePrimitive(obj.toASN1Primitive(), true);
+ primitive.encode(out, false);
}
+ }
- out.write(0x00);
- out.write(0x00);
+ ASN1Sequence rebuildConstructed(ASN1Primitive primitive)
+ {
+ return new BERSequence(primitive);
+ }
-// ASN1Primitive primitive = obj.toASN1Primitive();
-//
-// int flags = BERTags.TAGGED;
-// if (explicit || primitive.isConstructed())
-// {
-// flags |= BERTags.CONSTRUCTED;
-// }
-//
-// out.writeTag(withTag, flags, tagNo);
-//
-// if (explicit)
-// {
-// out.write(0x80);
-// out.writePrimitive(obj.toASN1Primitive(), true);
-// out.write(0x00);
-// out.write(0x00);
-// }
-// else
-// {
-// out.writePrimitive(obj.toASN1Primitive(), false);
-// }
+ ASN1TaggedObject replaceTag(int tagClass, int tagNo)
+ {
+ return new BERTaggedObject(explicitness, tagClass, tagNo, obj);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java
index 02f3f26..838e884 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java
@@ -5,66 +5,48 @@
/**
* Parser for indefinite-length tagged objects.
*/
-public class BERTaggedObjectParser
+class BERTaggedObjectParser
implements ASN1TaggedObjectParser
{
- private boolean _constructed;
- private int _tagNumber;
- private ASN1StreamParser _parser;
+ final int _tagClass;
+ final int _tagNo;
+ final ASN1StreamParser _parser;
- BERTaggedObjectParser(
- boolean constructed,
- int tagNumber,
- ASN1StreamParser parser)
+ BERTaggedObjectParser(int tagClass, int tagNo, ASN1StreamParser parser)
{
- _constructed = constructed;
- _tagNumber = tagNumber;
+ _tagClass = tagClass;
+ _tagNo = tagNo;
_parser = parser;
}
- /**
- * Return true if this tagged object is marked as constructed.
- *
- * @return true if constructed, false otherwise.
- */
- public boolean isConstructed()
+ public int getTagClass()
{
- return _constructed;
+ return _tagClass;
}
- /**
- * Return the tag number associated with this object.
- *
- * @return the tag number.
- */
public int getTagNo()
{
- return _tagNumber;
+ return _tagNo;
}
- /**
- * Return an object parser for the contents of this tagged object.
- *
- * @param tag the actual tag number of the object (needed if implicit).
- * @param isExplicit true if the contained object was explicitly tagged, false if implicit.
- * @return an ASN.1 encodable object parser.
- * @throws IOException if there is an issue building the object parser from the stream.
- */
- public ASN1Encodable getObjectParser(
- int tag,
- boolean isExplicit)
- throws IOException
+ public boolean hasContextTag()
{
- if (isExplicit)
- {
- if (!_constructed)
- {
- throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
- }
- return _parser.readObject();
- }
+ return this._tagClass == BERTags.CONTEXT_SPECIFIC;
+ }
- return _parser.readImplicit(_constructed, tag);
+ public boolean hasContextTag(int tagNo)
+ {
+ return this._tagClass == BERTags.CONTEXT_SPECIFIC && this._tagNo == tagNo;
+ }
+
+ public boolean hasTag(int tagClass, int tagNo)
+ {
+ return this._tagClass == tagClass && this._tagNo == tagNo;
+ }
+
+ public boolean hasTagClass(int tagClass)
+ {
+ return this._tagClass == tagClass;
}
/**
@@ -76,7 +58,32 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return _parser.readTaggedObject(_constructed, _tagNumber);
+ return _parser.loadTaggedIL(_tagClass, _tagNo);
+ }
+
+ public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ if (declaredExplicit)
+ {
+ return _parser.parseObject(baseTagNo);
+ }
+
+ return _parser.parseImplicitConstructedIL(baseTagNo);
+ }
+
+ public ASN1Encodable parseExplicitBaseObject() throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException
+ {
+ return _parser.parseTaggedObject();
+ }
+
+ public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException
+ {
+ return new BERTaggedObjectParser(baseTagClass, baseTagNo, _parser);
}
/**
@@ -88,7 +95,7 @@
{
try
{
- return this.getLoadedObject();
+ return getLoadedObject();
}
catch (IOException e)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERTags.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERTags.java
index 39b517e..2c6c28c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERTags.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERTags.java
@@ -2,20 +2,26 @@
public interface BERTags
{
+ // 0x00: Reserved for use by the encoding rules
public static final int BOOLEAN = 0x01;
public static final int INTEGER = 0x02;
public static final int BIT_STRING = 0x03;
public static final int OCTET_STRING = 0x04;
public static final int NULL = 0x05;
public static final int OBJECT_IDENTIFIER = 0x06;
+ public static final int OBJECT_DESCRIPTOR = 0x07;
public static final int EXTERNAL = 0x08;
+ public static final int REAL = 0x09;
public static final int ENUMERATED = 0x0a; // decimal 10
+ public static final int EMBEDDED_PDV = 0x0b; // decimal 11
+ public static final int UTF8_STRING = 0x0c; // decimal 12
+ public static final int RELATIVE_OID = 0x0d; // decimal 13
+ public static final int TIME = 0x0e;
+ // 0x0f: Reserved for future editions of this Recommendation | International Standard
public static final int SEQUENCE = 0x10; // decimal 16
public static final int SEQUENCE_OF = 0x10; // for completeness - used to model a SEQUENCE of the same type.
public static final int SET = 0x11; // decimal 17
public static final int SET_OF = 0x11; // for completeness - used to model a SET of the same type.
-
-
public static final int NUMERIC_STRING = 0x12; // decimal 18
public static final int PRINTABLE_STRING = 0x13; // decimal 19
public static final int T61_STRING = 0x14; // decimal 20
@@ -27,10 +33,23 @@
public static final int VISIBLE_STRING = 0x1a; // decimal 26
public static final int GENERAL_STRING = 0x1b; // decimal 27
public static final int UNIVERSAL_STRING = 0x1c; // decimal 28
+ public static final int UNRESTRICTED_STRING = 0x1d; // decimal 29
public static final int BMP_STRING = 0x1e; // decimal 30
- public static final int UTF8_STRING = 0x0c; // decimal 12
-
+ public static final int DATE = 0x1f;
+ public static final int TIME_OF_DAY = 0x20;
+ public static final int DATE_TIME = 0x21;
+ public static final int DURATION = 0x22;
+ public static final int OBJECT_IDENTIFIER_IRI = 0x23;
+ public static final int RELATIVE_OID_IRI = 0x24;
+ // 0x25..: Reserved for addenda to this Recommendation | International Standard
+
public static final int CONSTRUCTED = 0x20; // decimal 32
+
+ public static final int UNIVERSAL = 0x00; // decimal 32
public static final int APPLICATION = 0x40; // decimal 64
- public static final int TAGGED = 0x80; // decimal 128
+ public static final int TAGGED = 0x80; // decimal 128 - maybe should deprecate this.
+ public static final int CONTEXT_SPECIFIC = 0x80; // decimal 128
+ public static final int PRIVATE = 0xC0; // decimal 192
+
+ public static final int FLAGS = 0xE0;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ConstructedBitStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/ConstructedBitStream.java
new file mode 100644
index 0000000..cd020ea
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ConstructedBitStream.java
@@ -0,0 +1,145 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class ConstructedBitStream
+ extends InputStream
+{
+ private final ASN1StreamParser _parser;
+ private final boolean _octetAligned;
+
+ private boolean _first = true;
+ private int _padBits = 0;
+
+ private ASN1BitStringParser _currentParser;
+ private InputStream _currentStream;
+
+ ConstructedBitStream(ASN1StreamParser parser, boolean octetAligned)
+ {
+ _parser = parser;
+ _octetAligned = octetAligned;
+ }
+
+ int getPadBits()
+ {
+ return _padBits;
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException
+ {
+ if (_currentStream == null)
+ {
+ if (!_first)
+ {
+ return -1;
+ }
+
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ return -1;
+ }
+
+ _first = false;
+ _currentStream = _currentParser.getBitStream();
+
+ }
+
+ int totalRead = 0;
+
+ for (;;)
+ {
+ int numRead = _currentStream.read(b, off + totalRead, len - totalRead);
+
+ if (numRead >= 0)
+ {
+ totalRead += numRead;
+
+ if (totalRead == len)
+ {
+ return totalRead;
+ }
+ }
+ else
+ {
+ _padBits = _currentParser.getPadBits();
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ _currentStream = null;
+ return totalRead < 1 ? -1 : totalRead;
+ }
+
+ _currentStream = _currentParser.getBitStream();
+ }
+ }
+ }
+
+ public int read()
+ throws IOException
+ {
+ if (_currentStream == null)
+ {
+ if (!_first)
+ {
+ return -1;
+ }
+
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ return -1;
+ }
+
+ _first = false;
+ _currentStream = _currentParser.getBitStream();
+ }
+
+ for (;;)
+ {
+ int b = _currentStream.read();
+
+ if (b >= 0)
+ {
+ return b;
+ }
+
+ _padBits = _currentParser.getPadBits();
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ _currentStream = null;
+ return -1;
+ }
+
+ _currentStream = _currentParser.getBitStream();
+ }
+ }
+
+ private ASN1BitStringParser getNextParser() throws IOException
+ {
+ ASN1Encodable asn1Obj = _parser.readObject();
+ if (asn1Obj == null)
+ {
+ if (_octetAligned && _padBits != 0)
+ {
+ throw new IOException("expected octet-aligned bitstring, but found padBits: " + _padBits);
+ }
+
+ return null;
+ }
+
+ if (asn1Obj instanceof ASN1BitStringParser)
+ {
+ if (_padBits != 0)
+ {
+ throw new IOException("only the last nested bitstring can have padding");
+ }
+
+ return (ASN1BitStringParser)asn1Obj;
+ }
+
+ throw new IOException("unknown object encountered: " + asn1Obj.getClass());
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java
deleted file mode 100644
index eb54b20..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * A DER encoding version of an application specific object.
- */
-public class DERApplicationSpecific
- extends ASN1ApplicationSpecific
-{
- DERApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- super(isConstructed, tag, octets);
- }
-
- /**
- * Create an application specific object from the passed in data. This will assume
- * the data does not represent a constructed object.
- *
- * @param tag the tag number for this object.
- * @param octets the encoding of the object's body.
- */
- public DERApplicationSpecific(
- int tag,
- byte[] octets)
- {
- this(false, tag, octets);
- }
-
- /**
- * Create an application specific object with a tagging of explicit/constructed.
- *
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DERApplicationSpecific(
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- this(true, tag, object);
- }
-
- /**
- * Create an application specific object with the tagging style given by the value of constructed.
- *
- * @param constructed true if the object is constructed.
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DERApplicationSpecific(
- boolean constructed,
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
- }
-
- private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
- throws IOException
- {
- byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.DER);
-
- if (explicit)
- {
- return data;
- }
- else
- {
- int lenBytes = getLengthOfHeader(data);
- byte[] tmp = new byte[data.length - lenBytes];
- System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
- return tmp;
- }
- }
-
- /**
- * Create an application specific object which is marked as constructed
- *
- * @param tagNo the tag number for this object.
- * @param vec the objects making up the application specific object.
- */
- public DERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
- {
- super(true, tagNo, getEncodedVector(vec));
- }
-
- private static byte[] getEncodedVector(ASN1EncodableVector vec)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != vec.size(); i++)
- {
- try
- {
- bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DER));
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("malformed object: " + e, e);
- }
- }
- return bOut.toByteArray();
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncoded(withTag, flags, tag, octets);
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java
index 8daf842..31f54ac 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java
@@ -1,9 +1,5 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-
/**
* DER BMPString object encodes BMP (<i>Basic Multilingual Plane</i>) subset
* (aka UCS-2) of UNICODE (ISO 10646) characters in codepoints 0 to 65535.
@@ -13,203 +9,28 @@
* </p>
*/
public class DERBMPString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1BMPString
{
- private final char[] string;
-
- /**
- * Return a BMP String from the given object.
- *
- * @param obj the object we want converted.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERBMPString instance, or null.
- */
- public static DERBMPString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERBMPString)
- {
- return (DERBMPString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERBMPString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a BMP String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERBMPString instance.
- */
- public static DERBMPString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERBMPString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERBMPString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - byte encoded string.
- * @param string the encoded BMP STRING to wrap.
- */
- DERBMPString(
- byte[] string)
- {
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
-
- int byteLen = string.length;
- if (0 != (byteLen & 1))
- {
- throw new IllegalArgumentException("malformed BMPString encoding encountered");
- }
-
- int charLen = byteLen / 2;
- char[] cs = new char[charLen];
-
- for (int i = 0; i != charLen; i++)
- {
- cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
- }
-
- this.string = cs;
- }
-
- DERBMPString(char[] string)
- {
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
-
- this.string = string;
- }
-
/**
* Basic constructor
* @param string a String to wrap as a BMP STRING.
*/
- public DERBMPString(
- String string)
+ public DERBMPString(String string)
{
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
-
- this.string = string.toCharArray();
+ super(string);
}
- public String getString()
+ /**
+ * Basic constructor - byte encoded string.
+ * @param contents the encoded BMP STRING to wrap.
+ */
+ DERBMPString(byte[] contents)
{
- return new String(string);
+ super(contents);
}
- public String toString()
+ DERBMPString(char[] string)
{
- return getString();
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- protected boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERBMPString))
- {
- return false;
- }
-
- DERBMPString s = (DERBMPString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length * 2) + (string.length * 2);
- }
-
- void encode(
- ASN1OutputStream out, boolean withTag)
- throws IOException
- {
- int count = string.length;
- if (withTag)
- {
- out.write(BERTags.BMP_STRING);
- }
- out.writeLength(count * 2);
-
- byte[] buf = new byte[8];
-
- int i = 0, limit = count & -4;
- while (i < limit)
- {
- char c0 = string[i], c1 = string[i + 1], c2 = string[i + 2], c3 = string[i + 3];
- i += 4;
-
- buf[0] = (byte)(c0 >> 8);
- buf[1] = (byte)c0;
- buf[2] = (byte)(c1 >> 8);
- buf[3] = (byte)c1;
- buf[4] = (byte)(c2 >> 8);
- buf[5] = (byte)c2;
- buf[6] = (byte)(c3 >> 8);
- buf[7] = (byte)c3;
-
- out.write(buf, 0, 8);
- }
- if (i < count)
- {
- int bufPos = 0;
- do
- {
- char c0 = string[i];
- i += 1;
-
- buf[bufPos++] = (byte)(c0 >> 8);
- buf[bufPos++] = (byte)c0;
- }
- while (i < count);
-
- out.write(buf, 0, bufPos);
- }
+ super(string);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
index 0807aaf..26953ec 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
@@ -8,123 +8,69 @@
public class DERBitString
extends ASN1BitString
{
- /**
- * return a Bit String from the passed in object
- *
- * @param obj a DERBitString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERBitString instance, or null.
- */
- public static DERBitString getInstance(
- Object obj)
+ public static DERBitString convert(ASN1BitString bitString)
{
- if (obj == null || obj instanceof DERBitString)
- {
- return (DERBitString)obj;
- }
- if (obj instanceof DLBitString)
- {
- return new DERBitString(((DLBitString)obj).data, ((DLBitString)obj).padBits);
- }
- if (obj instanceof byte[])
- {
- try
- {
- return (DERBitString)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());
+ return (DERBitString)bitString.toDERObject();
}
- /**
- * return a Bit String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERBitString instance, or null.
- */
- public static DERBitString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERBitString)
- {
- return getInstance(o);
- }
- else
- {
- return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- protected DERBitString(byte data, int padBits)
- {
- super(data, padBits);
- }
-
- /**
- * @param data the octets making up the bit string.
- * @param padBits the number of extra bits at the end of the string.
- */
- public DERBitString(
- byte[] data,
- int padBits)
- {
- super(data, padBits);
- }
-
- public DERBitString(
- byte[] data)
+ public DERBitString(byte[] data)
{
this(data, 0);
}
- public DERBitString(
- int value)
+ public DERBitString(byte data, int padBits)
{
+ super(data, padBits);
+ }
+
+ public DERBitString(byte[] data, int padBits)
+ {
+ super(data, padBits);
+ }
+
+ public DERBitString(int value)
+ {
+ // TODO[asn1] Unify in single allocation of 'contents'
super(getBytes(value), getPadBits(value));
}
- public DERBitString(
- ASN1Encodable obj)
- throws IOException
+ public DERBitString(ASN1Encodable obj) throws IOException
{
+ // TODO[asn1] Unify in single allocation of 'contents'
super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
}
- boolean isConstructed()
+ DERBitString(byte[] contents, boolean check)
+ {
+ super(contents, check);
+ }
+
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- int len = data.length;
- if (0 == len
- || 0 == padBits
- || (data[len - 1] == (byte)(data[len - 1] & (0xFF << padBits))))
+ int padBits = contents[0] & 0xFF;
+ int length = contents.length;
+ int last = length - 1;
+
+ byte lastOctet = contents[last];
+ byte lastOctetDER = (byte)(contents[last] & (0xFF << padBits));
+
+ if (lastOctet == lastOctetDER)
{
- out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, contents);
}
else
{
- byte der = (byte)(data[len - 1] & (0xFF << padBits));
- out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data, 0, len - 1, der);
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, contents, 0, last, lastOctetDER);
}
}
@@ -138,21 +84,8 @@
return this;
}
- static DERBitString fromOctetString(byte[] bytes)
+ static DERBitString fromOctetString(ASN1OctetString octetString)
{
- if (bytes.length < 1)
- {
- throw new IllegalArgumentException("truncated BIT STRING detected");
- }
-
- int padBits = bytes[0];
- byte[] data = new byte[bytes.length - 1];
-
- if (data.length != 0)
- {
- System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
- }
-
- return new DERBitString(data, padBits);
+ return new DERBitString(octetString.getOctets(), true);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DEREncodableVector.java b/bcprov/src/main/java/org/bouncycastle/asn1/DEREncodableVector.java
deleted file mode 100644
index ff1059a..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DEREncodableVector.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.bouncycastle.asn1;
-
-/**
- * a general class for building up a vector of DER encodable objects -
- * this will eventually be superseded by ASN1EncodableVector so you should
- * use that class in preference.
- */
-public class DEREncodableVector
- extends ASN1EncodableVector
-{
- /**
- * @deprecated use ASN1EncodableVector instead.
- */
- public DEREncodableVector()
- {
-
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DEREnumerated.java b/bcprov/src/main/java/org/bouncycastle/asn1/DEREnumerated.java
deleted file mode 100644
index daa8777..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DEREnumerated.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.bouncycastle.asn1;
-
-import java.math.BigInteger;
-
-/**
- * @deprecated Use ASN1Enumerated instead of this.
- */
-public class DEREnumerated
- extends ASN1Enumerated
-{
- /**
- * @param bytes the value of this enumerated as an encoded BigInteger (signed).
- * @deprecated use ASN1Enumerated
- */
- DEREnumerated(byte[] bytes)
- {
- super(bytes);
- }
-
- /**
- * @param value the value of this enumerated.
- * @deprecated use ASN1Enumerated
- */
- public DEREnumerated(BigInteger value)
- {
- super(value);
- }
-
- /**
- * @param value the value of this enumerated.
- * @deprecated use ASN1Enumerated
- */
- public DEREnumerated(int value)
- {
- super(value);
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java
index 02b0e76..fced6d2 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java
@@ -1,8 +1,5 @@
package org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
/**
* Class representing the DER-type External
*/
@@ -19,11 +16,30 @@
* <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
* </ul>
*
- * @throws IllegalArgumentException if input size is wrong, or
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ *
+ * @deprecated Use {@link DERExternal#DERExternal(DERSequence)} instead.
*/
public DERExternal(ASN1EncodableVector vector)
{
- super(vector);
+ this(DERFactory.createSequence(vector));
+ }
+
+ /**
+ * Construct a DER EXTERNAL object, the input sequence must have exactly two elements on it.
+ * <p>
+ * Acceptable input formats are:
+ * <ul>
+ * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
+ * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
+ * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
+ * </ul>
+ *
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ */
+ public DERExternal(DERSequence sequence)
+ {
+ super(sequence);
}
/**
@@ -34,9 +50,10 @@
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param externalData The external data in its encoded form.
*/
- public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
{
- this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ super(directReference, indirectReference, dataValueDescriptor, externalData);
}
/**
@@ -48,11 +65,33 @@
* @param encoding The encoding to be used for the external data
* @param externalData The external data
*/
- public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
{
super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
}
+ ASN1Sequence buildSequence()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+ if (directReference != null)
+ {
+ v.add(directReference);
+ }
+ if (indirectReference != null)
+ {
+ v.add(indirectReference);
+ }
+ if (dataValueDescriptor != null)
+ {
+ v.add(dataValueDescriptor.toDERObject());
+ }
+
+ v.add(new DERTaggedObject(0 == encoding, encoding, externalContent));
+
+ return new DERSequence(v);
+ }
+
ASN1Primitive toDERObject()
{
return this;
@@ -62,34 +101,4 @@
{
return this;
}
-
- int encodedLength()
- throws IOException
- {
- return this.getEncoded().length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- if (directReference != null)
- {
- baos.write(directReference.getEncoded(ASN1Encoding.DER));
- }
- if (indirectReference != null)
- {
- baos.write(indirectReference.getEncoded(ASN1Encoding.DER));
- }
- if (dataValueDescriptor != null)
- {
- baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DER));
- }
- DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
- baos.write(obj.getEncoded(ASN1Encoding.DER));
-
- out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERExternalParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERExternalParser.java
index afdf510..310acad 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERExternalParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERExternalParser.java
@@ -6,7 +6,7 @@
* Parser DER EXTERNAL tagged objects.
*/
public class DERExternalParser
- implements ASN1Encodable, InMemoryRepresentable
+ implements ASN1ExternalParser
{
private ASN1StreamParser _parser;
@@ -35,14 +35,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- try
- {
- return new DLExternal(_parser.readVector());
- }
- catch (IllegalArgumentException e)
- {
- throw new ASN1Exception(e.getMessage(), e);
- }
+ return parse(_parser);
}
/**
@@ -65,4 +58,16 @@
throw new ASN1ParsingException("unable to get DER object", ioe);
}
}
+
+ static DLExternal parse(ASN1StreamParser sp) throws IOException
+ {
+ try
+ {
+ return new DLExternal(new DLSequence(sp.readVector()));
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception(e.getMessage(), e);
+ }
+ }
}
\ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERFactory.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERFactory.java
index d7c7d86..00447be 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERFactory.java
@@ -2,10 +2,10 @@
class DERFactory
{
- static final ASN1Sequence EMPTY_SEQUENCE = new DERSequence();
- static final ASN1Set EMPTY_SET = new DERSet();
+ static final DERSequence EMPTY_SEQUENCE = new DERSequence();
+ static final DERSet EMPTY_SET = new DERSet();
- static ASN1Sequence createSequence(ASN1EncodableVector v)
+ static DERSequence createSequence(ASN1EncodableVector v)
{
if (v.size() < 1)
{
@@ -15,7 +15,7 @@
return new DERSequence(v);
}
- static ASN1Set createSet(ASN1EncodableVector v)
+ static DERSet createSet(ASN1EncodableVector v)
{
if (v.size() < 1)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java
index bac214f..c60979e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java
@@ -1,10 +1,5 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Strings;
-
/**
* ASN.1 GENERAL-STRING data type.
* <p>
@@ -13,136 +8,20 @@
* </p>
*/
public class DERGeneralString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1GeneralString
{
- private final byte[] string;
-
- /**
- * Return a GeneralString from the given object.
- *
- * @param obj the object we want converted.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERBMPString instance, or null.
- */
- public static DERGeneralString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERGeneralString)
- {
- return (DERGeneralString) obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERGeneralString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: "
- + obj.getClass().getName());
- }
-
- /**
- * Return a GeneralString from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERGeneralString instance.
- */
- public static DERGeneralString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERGeneralString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERGeneralString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- DERGeneralString(byte[] string)
- {
- this.string = string;
- }
-
/**
* Construct a GeneralString from the passed in String.
*
* @param string the string to be contained in this object.
*/
- public DERGeneralString(String string)
+ public DERGeneralString(String string)
{
- this.string = Strings.toByteArray(string);
+ super(string);
}
- /**
- * Return a Java String representation of our contained String.
- *
- * @return a Java String representing our contents.
- */
- public String getString()
+ DERGeneralString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- /**
- * Return a byte array representation of our contained String.
- *
- * @return a byte array representing our contents.
- */
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.GENERAL_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(ASN1Primitive o)
- {
- if (!(o instanceof DERGeneralString))
- {
- return false;
- }
- DERGeneralString s = (DERGeneralString)o;
-
- return Arrays.areEqual(string, s.string);
+ super(contents, clone);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java
index 33b9abf..493a73e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java
@@ -42,39 +42,39 @@
private byte[] getDERTime()
{
- if (time[time.length - 1] == 'Z')
+ if (contents[contents.length - 1] == 'Z')
{
if (!hasMinutes())
{
- byte[] derTime = new byte[time.length + 4];
+ byte[] derTime = new byte[contents.length + 4];
- System.arraycopy(time, 0, derTime, 0, time.length - 1);
- System.arraycopy(Strings.toByteArray("0000Z"), 0, derTime, time.length - 1, 5);
+ System.arraycopy(contents, 0, derTime, 0, contents.length - 1);
+ System.arraycopy(Strings.toByteArray("0000Z"), 0, derTime, contents.length - 1, 5);
return derTime;
}
else if (!hasSeconds())
{
- byte[] derTime = new byte[time.length + 2];
+ byte[] derTime = new byte[contents.length + 2];
- System.arraycopy(time, 0, derTime, 0, time.length - 1);
- System.arraycopy(Strings.toByteArray("00Z"), 0, derTime, time.length - 1, 3);
+ System.arraycopy(contents, 0, derTime, 0, contents.length - 1);
+ System.arraycopy(Strings.toByteArray("00Z"), 0, derTime, contents.length - 1, 3);
return derTime;
}
else if (hasFractionalSeconds())
{
- int ind = time.length - 2;
- while (ind > 0 && time[ind] == '0')
+ int ind = contents.length - 2;
+ while (ind > 0 && contents[ind] == '0')
{
ind--;
}
- if (time[ind] == '.')
+ if (contents[ind] == '.')
{
byte[] derTime = new byte[ind + 1];
- System.arraycopy(time, 0, derTime, 0, ind);
+ System.arraycopy(contents, 0, derTime, 0, ind);
derTime[ind] = (byte)'Z';
return derTime;
@@ -83,7 +83,7 @@
{
byte[] derTime = new byte[ind + 2];
- System.arraycopy(time, 0, derTime, 0, ind + 1);
+ System.arraycopy(contents, 0, derTime, 0, ind + 1);
derTime[ind + 1] = (byte)'Z';
return derTime;
@@ -91,25 +91,23 @@
}
else
{
- return time;
+ return contents;
}
}
else
{
- return time; // TODO: is there a better way?
+ return contents; // TODO: is there a better way?
}
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- int length = getDERTime().length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getDERTime().length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, getDERTime());
+ out.writeEncodingDL(withTag, BERTags.GENERALIZED_TIME, getDERTime());
}
ASN1Primitive toDERObject()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java
index 2beb435..7b6f55f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java
@@ -1,122 +1,15 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Strings;
-
public class DERGraphicString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1GraphicString
{
- private final byte[] string;
-
- /**
- * return a Graphic String from the passed in object
- *
- * @param obj a DERGraphicString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERGraphicString instance, or null.
- */
- public static DERGraphicString getInstance(
- Object obj)
+ public DERGraphicString(byte[] octets)
{
- if (obj == null || obj instanceof DERGraphicString)
- {
- return (DERGraphicString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERGraphicString)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());
+ this(octets, true);
}
- /**
- * return a Graphic String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERGraphicString instance, or null.
- */
- public static DERGraphicString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ DERGraphicString(byte[] contents, boolean clone)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERGraphicString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERGraphicString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * basic constructor - with bytes.
- * @param string the byte encoding of the characters making up the string.
- */
- public DERGraphicString(
- byte[] string)
- {
- this.string = Arrays.clone(string);
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.GRAPHIC_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERGraphicString))
- {
- return false;
- }
-
- DERGraphicString s = (DERGraphicString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- public String getString()
- {
- return Strings.fromByteArray(string);
+ super(contents, clone);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java
index d238741..b2644aa 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java
@@ -1,10 +1,5 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Strings;
-
/**
* DER IA5String object - this is a ISO 646 (ASCII) string encoding code points 0 to 127.
* <p>
@@ -12,83 +7,13 @@
* </p>
*/
public class DERIA5String
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1IA5String
{
- private final byte[] string;
-
- /**
- * Return an IA5 string from the passed in object
- *
- * @param obj a DERIA5String or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERIA5String instance, or null.
- */
- public static DERIA5String getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERIA5String)
- {
- return (DERIA5String)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERIA5String)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return an IA5 String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERIA5String instance, or null.
- */
- public static DERIA5String getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERIA5String)
- {
- return getInstance(o);
- }
- else
- {
- return new DERIA5String(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - with bytes.
- * @param string the byte encoding of the characters making up the string.
- */
- DERIA5String(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor - without validation.
* @param string the base string to use..
*/
- public DERIA5String(
- String string)
+ public DERIA5String(String string)
{
this(string, false);
}
@@ -101,90 +26,13 @@
* @throws IllegalArgumentException if validate is true and the string
* contains characters that should not be in an IA5String.
*/
- public DERIA5String(
- String string,
- boolean validate)
+ public DERIA5String(String string, boolean validate)
{
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
- if (validate && !isIA5String(string))
- {
- throw new IllegalArgumentException("'string' contains illegal characters");
- }
-
- this.string = Strings.toByteArray(string);
+ super(string, validate);
}
- public String getString()
+ DERIA5String(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.IA5_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERIA5String))
- {
- return false;
- }
-
- DERIA5String s = (DERIA5String)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- /**
- * return true if the passed in String can be represented without
- * loss as an IA5String, false otherwise.
- *
- * @param str the string to check.
- * @return true if character set in IA5String set, false otherwise.
- */
- public static boolean isIA5String(
- String str)
- {
- for (int i = str.length() - 1; i >= 0; i--)
- {
- char ch = str.charAt(i);
-
- if (ch > 0x007f)
- {
- return false;
- }
- }
-
- return true;
+ super(contents, clone);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERInteger.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERInteger.java
deleted file mode 100644
index d2e850f..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERInteger.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.bouncycastle.asn1;
-
-import java.math.BigInteger;
-
-/**
- * @deprecated Use ASN1Integer instead of this,
- */
-public class DERInteger
- extends ASN1Integer
-{
- /**
- * Constructor from a byte array containing a signed representation of the number.
- *
- * @param bytes a byte array containing the signed number.A copy is made of the byte array.
- */
- public DERInteger(byte[] bytes)
- {
- super(bytes, true);
- }
-
- public DERInteger(BigInteger value)
- {
- super(value);
- }
-
- public DERInteger(long value)
- {
- super(value);
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java
index 38960a4..73e0ef0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java
@@ -18,18 +18,18 @@
{
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 2;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, 0);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.NULL, zeroBytes);
+ out.writeEncodingDL(withTag, BERTags.NULL, zeroBytes);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java
index 9a4a968..0ce5074 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java
@@ -1,10 +1,5 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Strings;
-
/**
* DER NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
* ASN.1 NUMERIC-STRING object.
@@ -16,81 +11,12 @@
* Explicit character set escape sequences are not allowed.
*/
public class DERNumericString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1NumericString
{
- private final byte[] string;
-
- /**
- * Return a Numeric string from the passed in object
- *
- * @param obj a DERNumericString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERNumericString instance, or null
- */
- public static DERNumericString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERNumericString)
- {
- return (DERNumericString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERNumericString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return an Numeric String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERNumericString instance, or null.
- */
- public static DERNumericString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERNumericString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERNumericString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - with bytes.
- */
- DERNumericString(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor - without validation..
*/
- public DERNumericString(
- String string)
+ public DERNumericString(String string)
{
this(string, false);
}
@@ -103,92 +29,13 @@
* @throws IllegalArgumentException if validate is true and the string
* contains characters that should not be in a NumericString.
*/
- public DERNumericString(
- String string,
- boolean validate)
+ public DERNumericString(String string, boolean validate)
{
- if (validate && !isNumericString(string))
- {
- throw new IllegalArgumentException("string contains illegal characters");
- }
-
- this.string = Strings.toByteArray(string);
+ super(string, validate);
}
- public String getString()
+ DERNumericString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.NUMERIC_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERNumericString))
- {
- return false;
- }
-
- DERNumericString s = (DERNumericString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- /**
- * Return true if the string can be represented as a NumericString ('0'..'9', ' ')
- *
- * @param str string to validate.
- * @return true if numeric, fale otherwise.
- */
- public static boolean isNumericString(
- String str)
- {
- for (int i = str.length() - 1; i >= 0; i--)
- {
- char ch = str.charAt(i);
-
- if (ch > 0x007f)
- {
- return false;
- }
-
- if (('0' <= ch && ch <= '9') || ch == ' ')
- {
- continue;
- }
-
- return false;
- }
-
- return true;
+ super(contents, clone);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERObjectIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERObjectIdentifier.java
deleted file mode 100644
index acb2ada..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERObjectIdentifier.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.bouncycastle.asn1;
-
-/**
- *
- * @deprecated Use ASN1ObjectIdentifier instead of this,
- */
-public class DERObjectIdentifier
- extends ASN1ObjectIdentifier
-{
- public DERObjectIdentifier(String identifier)
- {
- super(identifier);
- }
-
- DERObjectIdentifier(byte[] bytes)
- {
- super(bytes);
- }
-
- DERObjectIdentifier(ASN1ObjectIdentifier oid, String branch)
- {
- super(oid, branch);
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java
index 2b535e8..6d11821 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java
@@ -31,19 +31,19 @@
super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER));
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, string.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.OCTET_STRING, string);
+ out.writeEncodingDL(withTag, BERTags.OCTET_STRING, string);
}
ASN1Primitive toDERObject()
@@ -56,8 +56,13 @@
return this;
}
- static void encode(ASN1OutputStream derOut, boolean withTag, byte[] buf, int off, int len) throws IOException
+ static void encode(ASN1OutputStream out, boolean withTag, byte[] buf, int off, int len) throws IOException
{
- derOut.writeEncoded(withTag, BERTags.OCTET_STRING, buf, off, len);
+ out.writeEncodingDL(withTag, BERTags.OCTET_STRING, buf, off, len);
+ }
+
+ static int encodedLength(boolean withTag, int contentsLength)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contentsLength);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java
index 1c9c159..33e1bca 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java
@@ -5,6 +5,8 @@
/**
* Parser for DER encoded OCTET STRINGS
+ *
+ * @deprecated Check for 'ASN1OctetStringParser' instead
*/
public class DEROctetStringParser
implements ASN1OctetStringParser
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DEROutputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/DEROutputStream.java
index caa9766..5995b5d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DEROutputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DEROutputStream.java
@@ -16,18 +16,32 @@
super(os);
}
- void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
- {
- primitive.toDERObject().encode(this, withTag);
- }
-
DEROutputStream getDERSubStream()
{
return this;
}
- ASN1OutputStream getDLSubStream()
+ void writeElements(ASN1Encodable[] elements)
+ throws IOException
{
- return this;
+ for (int i = 0, count = elements.length; i < count; ++i)
+ {
+ elements[i].toASN1Primitive().toDERObject().encode(this, true);
+ }
+ }
+
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
+ {
+ primitive.toDERObject().encode(this, withTag);
+ }
+
+ void writePrimitives(ASN1Primitive[] primitives)
+ throws IOException
+ {
+ int count = primitives.length;
+ for (int i = 0; i < count; ++i)
+ {
+ primitives[i].toDERObject().encode(this, true);
+ }
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java
index f7721c2..a403b87 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java
@@ -1,10 +1,5 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Strings;
-
/**
* DER PrintableString object.
* <p>
@@ -32,76 +27,8 @@
* </p>
*/
public class DERPrintableString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1PrintableString
{
- private final byte[] string;
-
- /**
- * Return a printable string from the passed in object.
- *
- * @param obj a DERPrintableString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERPrintableString instance, or null.
- */
- public static DERPrintableString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERPrintableString)
- {
- return (DERPrintableString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERPrintableString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a Printable String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERPrintableString instance, or null.
- */
- public static DERPrintableString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERPrintableString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERPrintableString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - byte encoded string.
- */
- DERPrintableString(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor - this does not validate the string
*/
@@ -123,115 +50,11 @@
String string,
boolean validate)
{
- if (validate && !isPrintableString(string))
- {
- throw new IllegalArgumentException("string contains illegal characters");
- }
-
- this.string = Strings.toByteArray(string);
+ super(string, validate);
}
- public String getString()
+ DERPrintableString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.PRINTABLE_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERPrintableString))
- {
- return false;
- }
-
- DERPrintableString s = (DERPrintableString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- /**
- * return true if the passed in String can be represented without
- * loss as a PrintableString, false otherwise.
- *
- * @return true if in printable set, false otherwise.
- */
- public static boolean isPrintableString(
- String str)
- {
- for (int i = str.length() - 1; i >= 0; i--)
- {
- char ch = str.charAt(i);
-
- if (ch > 0x007f)
- {
- return false;
- }
-
- if ('a' <= ch && ch <= 'z')
- {
- continue;
- }
-
- if ('A' <= ch && ch <= 'Z')
- {
- continue;
- }
-
- if ('0' <= ch && ch <= '9')
- {
- continue;
- }
-
- switch (ch)
- {
- case ' ':
- case '\'':
- case '(':
- case ')':
- case '+':
- case '-':
- case '.':
- case ':':
- case '=':
- case '?':
- case '/':
- case ',':
- continue;
- }
-
- return false;
- }
-
- return true;
+ super(contents, clone);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java
index e547471..9bffbb2 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java
@@ -16,7 +16,7 @@
return (DERSequence)seq.toDERObject();
}
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* Create an empty sequence
@@ -57,9 +57,9 @@
super(elements, clone);
}
- private int getBodyLength() throws IOException
+ private int getContentsLength() throws IOException
{
- if (bodyLength < 0)
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -67,20 +67,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/*
@@ -93,17 +91,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE);
DEROutputStream derOut = out.getDERSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -120,11 +115,11 @@
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
derObjects[i] = derObject;
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
@@ -133,6 +128,27 @@
}
}
+ ASN1BitString toASN1BitString()
+ {
+ return new DERBitString(BERBitString.flattenBitStrings(getConstructedBitStrings()), false);
+ }
+
+ ASN1External toASN1External()
+ {
+ return new DERExternal(this);
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ return new DEROctetString(BEROctetString.flattenOctetStrings(getConstructedOctetStrings()));
+ }
+
+ ASN1Set toASN1Set()
+ {
+ // NOTE: DLSet is intentional, we don't want sorting
+ return new DLSet(false, toArrayInternal());
+ }
+
ASN1Primitive toDERObject()
{
return this;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java
deleted file mode 100644
index aed121a..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-/**
- * @deprecated Use DLSequenceParser instead
- */
-public class DERSequenceParser
- implements ASN1SequenceParser
-{
- private ASN1StreamParser _parser;
-
- DERSequenceParser(ASN1StreamParser parser)
- {
- this._parser = parser;
- }
-
- /**
- * Return the next object in the SEQUENCE.
- *
- * @return next object in SEQUENCE.
- * @throws IOException if there is an issue loading the object.
- */
- public ASN1Encodable readObject()
- throws IOException
- {
- return _parser.readObject();
- }
-
- /**
- * Return an in memory, encodable, representation of the SEQUENCE.
- *
- * @return a DERSequence.
- * @throws IOException if there is an issue loading the data.
- */
- public ASN1Primitive getLoadedObject()
- throws IOException
- {
- return new DLSequence(_parser.readVector());
- }
-
- /**
- * Return a DERSequence representing this parser and its contents.
- *
- * @return a DERSequence.
- */
- public ASN1Primitive toASN1Primitive()
- {
- try
- {
- return getLoadedObject();
- }
- catch (IOException e)
- {
- throw new IllegalStateException(e.getMessage());
- }
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
index bc55bcb..f86689b 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
@@ -20,7 +20,7 @@
return (DERSet)set.toDERObject();
}
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* create an empty set
@@ -61,9 +61,9 @@
super(checkSorted(isSorted), elements);
}
- private int getBodyLength() throws IOException
+ private int getContentsLength() throws IOException
{
- if (bodyLength < 0)
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -71,20 +71,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/*
@@ -97,17 +95,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SET);
DEROutputStream derOut = out.getDERSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -124,11 +119,11 @@
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
derObjects[i] = derObject;
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
@@ -139,7 +134,7 @@
ASN1Primitive toDERObject()
{
- return isSorted ? this : super.toDERObject();
+ return (sortedElements != null) ? this : super.toDERObject();
}
ASN1Primitive toDLObject()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java
deleted file mode 100644
index 492f4a4..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-/**
- * @deprecated Use DLSetParser instead
- */
-public class DERSetParser
- implements ASN1SetParser
-{
- private ASN1StreamParser _parser;
-
- DERSetParser(ASN1StreamParser parser)
- {
- this._parser = parser;
- }
-
- /**
- * Return the next object in the SET.
- *
- * @return next object in SET.
- * @throws IOException if there is an issue loading the object.
- */
- public ASN1Encodable readObject()
- throws IOException
- {
- return _parser.readObject();
- }
-
- /**
- * Return an in memory, encodable, representation of the SET.
- *
- * @return a DERSet.
- * @throws IOException if there is an issue loading the data.
- */
- public ASN1Primitive getLoadedObject()
- throws IOException
- {
- return new DLSet(_parser.readVector());
- }
-
- /**
- * Return a DERSet representing this parser and its contents.
- *
- * @return a DERSet
- */
- public ASN1Primitive toASN1Primitive()
- {
- try
- {
- return getLoadedObject();
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException(e.getMessage(), e);
- }
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java
index 018f636..ade137a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java
@@ -1,74 +1,20 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Strings;
-
/**
* DER T61String (also the teletex string), try not to use this if you don't need to. The standard support the encoding for
* this has been withdrawn.
*/
public class DERT61String
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1T61String
{
- private byte[] string;
-
/**
- * Return a T61 string from the passed in object.
+ * Basic constructor - with string 8 bit assumed.
*
- * @param obj a DERT61String or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERT61String instance, or null
+ * @param string the string to be wrapped.
*/
- public static DERT61String getInstance(
- Object obj)
+ public DERT61String(String string)
{
- if (obj == null || obj instanceof DERT61String)
- {
- return (DERT61String)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERT61String)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return an T61 String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERT61String instance, or null
- */
- public static DERT61String getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERT61String)
- {
- return getInstance(o);
- }
- else
- {
- return new DERT61String(ASN1OctetString.getInstance(o).getOctets());
- }
+ super(string);
}
/**
@@ -76,74 +22,13 @@
*
* @param string the byte encoding of the string to be wrapped.
*/
- public DERT61String(
- byte[] string)
+ public DERT61String(byte[] string)
{
- this.string = Arrays.clone(string);
+ this(string, true);
}
- /**
- * Basic constructor - with string 8 bit assumed.
- *
- * @param string the string to be wrapped.
- */
- public DERT61String(
- String string)
+ DERT61String(byte[] contents, boolean clone)
{
- this.string = Strings.toByteArray(string);
- }
-
- /**
- * Decode the encoded string and return it, 8 bit encoding assumed.
- * @return the decoded String
- */
- public String getString()
- {
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.T61_STRING, string);
- }
-
- /**
- * Return the encoded string as a byte array.
- * @return the actual bytes making up the encoded body of the T61 string.
- */
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERT61String))
- {
- return false;
- }
-
- return Arrays.areEqual(string, ((DERT61String)o).string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
+ super(contents, clone);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java
index dfdfcd2..97ffb66 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java
@@ -10,68 +10,94 @@
public class DERTaggedObject
extends ASN1TaggedObject
{
- /**
- * @param explicit true if an explicitly tagged object.
- * @param tagNo the tag number for this object.
- * @param obj the tagged object.
- */
- public DERTaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
- {
- super(explicit, tagNo, obj);
- }
-
public DERTaggedObject(int tagNo, ASN1Encodable encodable)
{
super(true, tagNo, encodable);
}
- boolean isConstructed()
+ public DERTaggedObject(int tagClass, int tagNo, ASN1Encodable obj)
{
- return explicit || obj.toASN1Primitive().toDERObject().isConstructed();
+ super(true, tagClass, tagNo, obj);
}
- int encodedLength()
- throws IOException
+ /**
+ * @param explicit true if an explicitly tagged object.
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public DERTaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
+ {
+ super(explicit, tagNo, obj);
+ }
+
+ public DERTaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ super(explicit, tagClass, tagNo, obj);
+ }
+
+ DERTaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ super(explicitness, tagClass, tagNo, obj);
+ }
+
+ boolean encodeConstructed()
+ {
+ return isExplicit() || obj.toASN1Primitive().toDERObject().encodeConstructed();
+ }
+
+ int encodedLength(boolean withTag) throws IOException
{
ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
- int length = primitive.encodedLength();
+ boolean explicit = isExplicit();
+
+ int length = primitive.encodedLength(explicit);
if (explicit)
{
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ length += ASN1OutputStream.getLengthOfDL(length);
}
- else
- {
- // header length already in calculation
- length = length - 1;
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ length += withTag ? ASN1OutputStream.getLengthOfIdentifier(tagNo) : 0;
+
+ return length;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
+// assert out.getClass().isAssignableFrom(DEROutputStream.class);
+
ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
+ boolean explicit = isExplicit();
- int flags = BERTags.TAGGED;
- if (explicit || primitive.isConstructed())
+ if (withTag)
{
- flags |= BERTags.CONSTRUCTED;
- }
+ int flags = tagClass;
+ if (explicit || primitive.encodeConstructed())
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
- out.writeTag(withTag, flags, tagNo);
+ out.writeIdentifier(true, flags, tagNo);
+ }
if (explicit)
{
- out.writeLength(primitive.encodedLength());
+ out.writeDL(primitive.encodedLength(true));
}
primitive.encode(out.getDERSubStream(), explicit);
}
+ ASN1Sequence rebuildConstructed(ASN1Primitive primitive)
+ {
+ return new DERSequence(primitive);
+ }
+
+ ASN1TaggedObject replaceTag(int tagClass, int tagNo)
+ {
+ return new DERTaggedObject(explicitness, tagClass, tagNo, obj);
+ }
+
ASN1Primitive toDERObject()
{
return this;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERTags.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERTags.java
deleted file mode 100644
index 83fd7fd..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERTags.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.bouncycastle.asn1;
-
-/**
- * @deprecated use BERTags
- */
-public interface DERTags
- extends BERTags
-{
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java
index ceb1409..1b08584 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java
@@ -1,86 +1,11 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Strings;
-
/**
* DER UTF8String object.
*/
public class DERUTF8String
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1UTF8String
{
- private final byte[] string;
-
- /**
- * Return an UTF8 string from the passed in object.
- *
- * @param obj a DERUTF8String or an object that can be converted into one.
- * @exception IllegalArgumentException
- * if the object cannot be converted.
- * @return a DERUTF8String instance, or null
- */
- public static DERUTF8String getInstance(Object obj)
- {
- if (obj == null || obj instanceof DERUTF8String)
- {
- return (DERUTF8String)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERUTF8String)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: "
- + obj.getClass().getName());
- }
-
- /**
- * Return an UTF8 String from a tagged object.
- *
- * @param obj
- * the tagged object holding the object we want
- * @param explicit
- * true if the object is meant to be explicitly tagged false
- * otherwise.
- * @exception IllegalArgumentException
- * if the tagged object cannot be converted.
- * @return a DERUTF8String instance, or null
- */
- public static DERUTF8String getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERUTF8String)
- {
- return getInstance(o);
- }
- else
- {
- return new DERUTF8String(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /*
- * Basic constructor - byte encoded string.
- */
- DERUTF8String(byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor
*
@@ -88,49 +13,11 @@
*/
public DERUTF8String(String string)
{
- this.string = Strings.toUTF8ByteArray(string);
+ super(string);
}
- public String getString()
+ DERUTF8String(byte[] contents, boolean clone)
{
- return Strings.fromUTF8ByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(ASN1Primitive o)
- {
- if (!(o instanceof DERUTF8String))
- {
- return false;
- }
-
- DERUTF8String s = (DERUTF8String)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- throws IOException
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.UTF8_STRING, string);
+ super(contents, clone);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java
index 474584b..0c50ef9 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java
@@ -1,148 +1,24 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-
/**
* DER UniversalString object - encodes UNICODE (ISO 10646) characters using 32-bit format. In Java we
* have no way of representing this directly so we rely on byte arrays to carry these.
*/
public class DERUniversalString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1UniversalString
{
- private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- private final byte[] string;
-
- /**
- * Return a Universal String from the passed in object.
- *
- * @param obj a DERUniversalString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERUniversalString instance, or null
- */
- public static DERUniversalString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERUniversalString)
- {
- return (DERUniversalString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERUniversalString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a Universal String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERUniversalString instance, or null
- */
- public static DERUniversalString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERUniversalString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERUniversalString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
/**
* Basic constructor - byte encoded string.
*
* @param string the byte encoding of the string to be carried in the UniversalString object,
*/
- public DERUniversalString(
- byte[] string)
+ public DERUniversalString(byte[] string)
{
- this.string = Arrays.clone(string);
+ this(string, true);
}
- public String getString()
+ DERUniversalString(byte[] contents, boolean clone)
{
- StringBuffer buf = new StringBuffer("#");
-
- byte[] string;
- try
- {
- string = getEncoded();
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("internal error encoding UniversalString");
- }
-
- for (int i = 0; i != string.length; i++)
- {
- buf.append(table[(string[i] >>> 4) & 0xf]);
- buf.append(table[string[i] & 0xf]);
- }
-
- return buf.toString();
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.UNIVERSAL_STRING, string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERUniversalString))
- {
- return false;
- }
-
- return Arrays.areEqual(string, ((DERUniversalString)o).string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
+ super(contents, clone);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java
index 35458a8..141bab9 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java
@@ -1,122 +1,15 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Strings;
-
public class DERVideotexString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1VideotexString
{
- private final byte[] string;
-
- /**
- * return a Videotex String from the passed in object
- *
- * @param obj a DERVideotexString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERVideotexString instance, or null.
- */
- public static DERVideotexString getInstance(
- Object obj)
+ public DERVideotexString(byte[] octets)
{
- if (obj == null || obj instanceof DERVideotexString)
- {
- return (DERVideotexString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERVideotexString)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());
+ this(octets, true);
}
- /**
- * return a Videotex String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERVideotexString instance, or null.
- */
- public static DERVideotexString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ DERVideotexString(byte[] contents, boolean clone)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERVideotexString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERVideotexString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * basic constructor - with bytes.
- * @param string the byte encoding of the characters making up the string.
- */
- public DERVideotexString(
- byte[] string)
- {
- this.string = Arrays.clone(string);
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.VIDEOTEX_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERVideotexString))
- {
- return false;
- }
-
- DERVideotexString s = (DERVideotexString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- public String getString()
- {
- return Strings.fromByteArray(string);
+ super(contents, clone);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java
index ddb692a..47dc787 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java
@@ -1,10 +1,5 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
-
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Strings;
-
/**
* DER VisibleString object encoding ISO 646 (ASCII) character code points 32 to 126.
* <p>
@@ -12,130 +7,20 @@
* </p>
*/
public class DERVisibleString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1VisibleString
{
- private final byte[] string;
-
- /**
- * Return a Visible String from the passed in object.
- *
- * @param obj a DERVisibleString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERVisibleString instance, or null
- */
- public static DERVisibleString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERVisibleString)
- {
- return (DERVisibleString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERVisibleString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a Visible String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERVisibleString instance, or null
- */
- public static DERVisibleString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERVisibleString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERVisibleString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /*
- * Basic constructor - byte encoded string.
- */
- DERVisibleString(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor
*
* @param string the string to be carried in the VisibleString object,
*/
- public DERVisibleString(
- String string)
+ public DERVisibleString(String string)
{
- this.string = Strings.toByteArray(string);
+ super(string);
}
- public String getString()
+ DERVisibleString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.VISIBLE_STRING, this.string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERVisibleString))
- {
- return false;
- }
-
- return Arrays.areEqual(string, ((DERVisibleString)o).string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
+ super(contents, clone);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLApplicationSpecific.java
deleted file mode 100644
index 88059a7..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLApplicationSpecific.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * A DER encoding version of an application specific object.
- */
-public class DLApplicationSpecific
- extends ASN1ApplicationSpecific
-{
- DLApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- super(isConstructed, tag, octets);
- }
-
- /**
- * Create an application specific object from the passed in data. This will assume
- * the data does not represent a constructed object.
- *
- * @param tag the tag number for this object.
- * @param octets the encoding of the object's body.
- */
- public DLApplicationSpecific(
- int tag,
- byte[] octets)
- {
- this(false, tag, octets);
- }
-
- /**
- * Create an application specific object with a tagging of explicit/constructed.
- *
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DLApplicationSpecific(
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- this(true, tag, object);
- }
-
- /**
- * Create an application specific object with the tagging style given by the value of constructed.
- *
- * @param constructed true if the object is constructed.
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DLApplicationSpecific(
- boolean constructed,
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
- }
-
- private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
- throws IOException
- {
- byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.DL);
-
- if (explicit)
- {
- return data;
- }
- else
- {
- int lenBytes = getLengthOfHeader(data);
- byte[] tmp = new byte[data.length - lenBytes];
- System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
- return tmp;
- }
- }
-
- /**
- * Create an application specific object which is marked as constructed
- *
- * @param tagNo the tag number for this object.
- * @param vec the objects making up the application specific object.
- */
- public DLApplicationSpecific(int tagNo, ASN1EncodableVector vec)
- {
- super(true, tagNo, getEncodedVector(vec));
- }
-
- private static byte[] getEncodedVector(ASN1EncodableVector vec)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != vec.size(); i++)
- {
- try
- {
- bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DL));
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("malformed object: " + e, e);
- }
- }
- return bOut.toByteArray();
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncoded(withTag, flags, tag, octets);
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java
index 176dc8e..ecb0797 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java
@@ -8,113 +8,51 @@
public class DLBitString
extends ASN1BitString
{
- /**
- * return a Bit String that can be definite-length encoded from the passed in object.
- *
- * @param obj a DL or DER BitString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return an ASN1BitString instance, or null.
- */
- public static ASN1BitString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DLBitString)
- {
- return (DLBitString)obj;
- }
- if (obj instanceof DERBitString)
- {
- return (DERBitString)obj;
- }
- if (obj instanceof byte[])
- {
- try
- {
- return (ASN1BitString)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());
- }
-
- /**
- * return a Bit String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return an ASN1BitString instance, or null.
- */
- public static ASN1BitString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DLBitString)
- {
- return getInstance(o);
- }
- else
- {
- return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- protected DLBitString(byte data, int padBits)
- {
- super(data, padBits);
- }
-
- /**
- * @param data the octets making up the bit string.
- * @param padBits the number of extra bits at the end of the string.
- */
- public DLBitString(
- byte[] data,
- int padBits)
- {
- super(data, padBits);
- }
-
- public DLBitString(
- byte[] data)
+ public DLBitString(byte[] data)
{
this(data, 0);
}
- public DLBitString(
- int value)
+ public DLBitString(byte data, int padBits)
{
+ super(data, padBits);
+ }
+
+ public DLBitString(byte[] data, int padBits)
+ {
+ super(data, padBits);
+ }
+
+ public DLBitString(int value)
+ {
+ // TODO[asn1] Unify in single allocation of 'contents'
super(getBytes(value), getPadBits(value));
}
- public DLBitString(
- ASN1Encodable obj)
- throws IOException
+ public DLBitString(ASN1Encodable obj) throws IOException
{
+ // TODO[asn1] Unify in single allocation of 'contents'
super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
}
- boolean isConstructed()
+ DLBitString(byte[] contents, boolean check)
+ {
+ super(contents, check);
+ }
+
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, contents);
}
ASN1Primitive toDLObject()
@@ -122,21 +60,19 @@
return this;
}
- static DLBitString fromOctetString(byte[] bytes)
+ static int encodedLength(boolean withTag, int contentsLength)
{
- if (bytes.length < 1)
- {
- throw new IllegalArgumentException("truncated BIT STRING detected");
- }
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contentsLength);
+ }
- int padBits = bytes[0];
- byte[] data = new byte[bytes.length - 1];
+ static void encode(ASN1OutputStream out, boolean withTag, byte[] buf, int off, int len) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, buf, off, len);
+ }
- if (data.length != 0)
- {
- System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
- }
-
- return new DLBitString(data, padBits);
+ static void encode(ASN1OutputStream out, boolean withTag, byte pad, byte[] buf, int off, int len)
+ throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, pad, buf, off, len);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLBitStringParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLBitStringParser.java
new file mode 100644
index 0000000..ce92398
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLBitStringParser.java
@@ -0,0 +1,83 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Parser for a DL encoded BIT STRING.
+ *
+ * @deprecated Check for 'ASN1BitStringParser' instead
+ */
+public class DLBitStringParser
+ implements ASN1BitStringParser
+{
+ private final DefiniteLengthInputStream stream;
+ private int padBits = 0;
+
+ DLBitStringParser(
+ DefiniteLengthInputStream stream)
+ {
+ this.stream = stream;
+ }
+
+ public InputStream getBitStream() throws IOException
+ {
+ return getBitStream(false);
+ }
+
+ public InputStream getOctetStream() throws IOException
+ {
+ return getBitStream(true);
+ }
+
+ public int getPadBits()
+ {
+ return padBits;
+ }
+
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return ASN1BitString.createPrimitive(stream.toByteArray());
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
+ }
+ }
+
+ private InputStream getBitStream(boolean octetAligned) throws IOException
+ {
+ int length = stream.getRemaining();
+ if (length < 1)
+ {
+ throw new IllegalStateException("content octets cannot be empty");
+ }
+
+ padBits = stream.read();
+ if (padBits > 0)
+ {
+ if (length < 2)
+ {
+ throw new IllegalStateException("zero length data with non-zero pad bits");
+ }
+ if (padBits > 7)
+ {
+ throw new IllegalStateException("pad bits cannot be greater than 7 or less than 0");
+ }
+ if (octetAligned)
+ {
+ throw new IOException("expected octet-aligned bitstring, but found padBits: " + padBits);
+ }
+ }
+
+ return stream;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLExternal.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLExternal.java
index 833c60e..8424fc5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLExternal.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLExternal.java
@@ -1,8 +1,5 @@
package org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
/**
* Class representing the Definite-Length-type External
*/
@@ -19,11 +16,30 @@
* <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
* </ul>
*
- * @throws IllegalArgumentException if input size is wrong, or
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ *
+ * @deprecated Use {@link DLExternal#DLExternal(DLSequence)} instead.
*/
public DLExternal(ASN1EncodableVector vector)
{
- super(vector);
+ this(DLFactory.createSequence(vector));
+ }
+
+ /**
+ * Construct a Definite-Length EXTERNAL object, the input sequence must have exactly two elements on it.
+ * <p>
+ * Acceptable input formats are:
+ * <ul>
+ * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
+ * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
+ * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
+ * </ul>
+ *
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ */
+ public DLExternal(DLSequence sequence)
+ {
+ super(sequence);
}
/**
@@ -34,9 +50,10 @@
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param externalData The external data in its encoded form.
*/
- public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
{
- this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ super(directReference, indirectReference, dataValueDescriptor, externalData);
}
/**
@@ -48,43 +65,35 @@
* @param encoding The encoding to be used for the external data
* @param externalData The external data
*/
- public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
{
super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
}
+ ASN1Sequence buildSequence()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+ if (directReference != null)
+ {
+ v.add(directReference);
+ }
+ if (indirectReference != null)
+ {
+ v.add(indirectReference);
+ }
+ if (dataValueDescriptor != null)
+ {
+ v.add(dataValueDescriptor.toDLObject());
+ }
+
+ v.add(new DLTaggedObject(0 == encoding, encoding, externalContent));
+
+ return new DLSequence(v);
+ }
+
ASN1Primitive toDLObject()
{
return this;
}
-
- int encodedLength()
- throws IOException
- {
- return this.getEncoded().length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- if (directReference != null)
- {
- baos.write(directReference.getEncoded(ASN1Encoding.DL));
- }
- if (indirectReference != null)
- {
- baos.write(indirectReference.getEncoded(ASN1Encoding.DL));
- }
- if (dataValueDescriptor != null)
- {
- baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DL));
- }
- ASN1TaggedObject obj = new DLTaggedObject(true, encoding, externalContent);
- baos.write(obj.getEncoded(ASN1Encoding.DL));
-
- out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLFactory.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLFactory.java
index 0ce21ca..9ae4742 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLFactory.java
@@ -2,10 +2,10 @@
class DLFactory
{
- static final ASN1Sequence EMPTY_SEQUENCE = new DLSequence();
- static final ASN1Set EMPTY_SET = new DLSet();
+ static final DLSequence EMPTY_SEQUENCE = new DLSequence();
+ static final DLSet EMPTY_SET = new DLSet();
- static ASN1Sequence createSequence(ASN1EncodableVector v)
+ static DLSequence createSequence(ASN1EncodableVector v)
{
if (v.size() < 1)
{
@@ -15,7 +15,7 @@
return new DLSequence(v);
}
- static ASN1Set createSet(ASN1EncodableVector v)
+ static DLSet createSet(ASN1EncodableVector v)
{
if (v.size() < 1)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLOutputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLOutputStream.java
index 9c2a88c..edefdbf 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLOutputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLOutputStream.java
@@ -14,13 +14,32 @@
super(os);
}
+ DLOutputStream getDLSubStream()
+ {
+ return this;
+ }
+
+ void writeElements(ASN1Encodable[] elements)
+ throws IOException
+ {
+ for (int i = 0, count = elements.length; i < count; ++i)
+ {
+ elements[i].toASN1Primitive().toDLObject().encode(this, true);
+ }
+ }
+
void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
{
primitive.toDLObject().encode(this, withTag);
}
- ASN1OutputStream getDLSubStream()
+ void writePrimitives(ASN1Primitive[] primitives)
+ throws IOException
{
- return this;
+ int count = primitives.length;
+ for (int i = 0; i < count; ++i)
+ {
+ primitives[i].toDLObject().encode(this, true);
+ }
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java
index b040ded..5cc4bb4 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java
@@ -8,7 +8,7 @@
public class DLSequence
extends ASN1Sequence
{
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* Create an empty sequence
@@ -49,9 +49,9 @@
super(elements, clone);
}
- private int getBodyLength() throws IOException
+ private int getContentsLength() throws IOException
{
- if (bodyLength < 0)
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -59,20 +59,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/**
@@ -85,17 +83,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE);
ASN1OutputStream dlOut = out.getDLSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -111,11 +106,11 @@
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
dlObjects[i] = dlObject;
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
@@ -124,8 +119,29 @@
}
}
+ ASN1BitString toASN1BitString()
+ {
+ return new DLBitString(BERBitString.flattenBitStrings(getConstructedBitStrings()), false);
+ }
+
+ ASN1External toASN1External()
+ {
+ return new DLExternal(this);
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ // NOTE: There is no DLOctetString
+ return new DEROctetString(BEROctetString.flattenOctetStrings(getConstructedOctetStrings()));
+ }
+
+ ASN1Set toASN1Set()
+ {
+ return new DLSet(false, toArrayInternal());
+ }
+
ASN1Primitive toDLObject()
{
return this;
}
-}
\ No newline at end of file
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java
index 290a46e..7e54814 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java
@@ -5,7 +5,7 @@
/**
* Parser class for DL SEQUENCEs.
*
- * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ * @deprecated Check for 'ASN1SequenceParser' instead
*/
public class DLSequenceParser
implements ASN1SequenceParser
@@ -38,7 +38,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new DLSequence(_parser.readVector());
+ return DLFactory.createSequence(_parser.readVector());
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLSet.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLSet.java
index 576197a..695b1e3 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLSet.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLSet.java
@@ -53,7 +53,7 @@
public class DLSet
extends ASN1Set
{
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* create an empty set
@@ -91,9 +91,14 @@
super(isSorted, elements);
}
- private int getBodyLength() throws IOException
+ DLSet(ASN1Encodable[] elements, ASN1Encodable[] sortedElements)
{
- if (bodyLength < 0)
+ super(elements, sortedElements);
+ }
+
+ private int getContentsLength() throws IOException
+ {
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -101,20 +106,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/**
@@ -127,17 +130,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SET);
ASN1OutputStream dlOut = out.getDLSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -153,11 +153,11 @@
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
dlObjects[i] = dlObject;
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLSetParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLSetParser.java
index 9f4421d..8a55a6d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLSetParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLSetParser.java
@@ -5,7 +5,7 @@
/**
* Parser class for DL SETs.
*
- * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ * @deprecated Check for 'ASN1SetParser' instead
*/
public class DLSetParser
implements ASN1SetParser
@@ -38,7 +38,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new DLSet(_parser.readVector());
+ return DLFactory.createSet(_parser.readVector());
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java
index 50a3a26..c4e1859 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java
@@ -10,60 +10,92 @@
public class DLTaggedObject
extends ASN1TaggedObject
{
+ public DLTaggedObject(int tagNo, ASN1Encodable encodable)
+ {
+ super(true, tagNo, encodable);
+ }
+
+ public DLTaggedObject(int tagClass, int tagNo, ASN1Encodable encodable)
+ {
+ super(true, tagClass, tagNo, encodable);
+ }
+
/**
* @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public DLTaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
+ public DLTaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
{
super(explicit, tagNo, obj);
}
- boolean isConstructed()
+ public DLTaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
{
- return explicit || obj.toASN1Primitive().toDLObject().isConstructed();
+ super(explicit, tagClass, tagNo, obj);
}
- int encodedLength()
- throws IOException
+ DLTaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
{
- int length = obj.toASN1Primitive().toDLObject().encodedLength();
+ super(explicitness, tagClass, tagNo, obj);
+ }
+
+ boolean encodeConstructed()
+ {
+ return isExplicit() || obj.toASN1Primitive().toDLObject().encodeConstructed();
+ }
+
+ int encodedLength(boolean withTag) throws IOException
+ {
+ ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
+ boolean explicit = isExplicit();
+
+ int length = primitive.encodedLength(explicit);
if (explicit)
{
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ length += ASN1OutputStream.getLengthOfDL(length);
}
- else
- {
- // header length already in calculation
- length = length - 1;
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ length += withTag ? ASN1OutputStream.getLengthOfIdentifier(tagNo) : 0;
+
+ return length;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
+// assert out.getClass().isAssignableFrom(DLOutputStream.class);
+
ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
+ boolean explicit = isExplicit();
- int flags = BERTags.TAGGED;
- if (explicit || primitive.isConstructed())
+ if (withTag)
{
- flags |= BERTags.CONSTRUCTED;
- }
+ int flags = tagClass;
+ if (explicit || primitive.encodeConstructed())
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
- out.writeTag(withTag, flags, tagNo);
+ out.writeIdentifier(true, flags, tagNo);
+ }
if (explicit)
{
- out.writeLength(primitive.encodedLength());
+ out.writeDL(primitive.encodedLength(true));
}
- out.getDLSubStream().writePrimitive(primitive, explicit);
+ primitive.encode(out.getDLSubStream(), explicit);
+ }
+
+ ASN1Sequence rebuildConstructed(ASN1Primitive primitive)
+ {
+ return new DLSequence(primitive);
+ }
+
+ ASN1TaggedObject replaceTag(int tagClass, int tagNo)
+ {
+ return new DLTaggedObject(explicitness, tagClass, tagNo, obj);
}
ASN1Primitive toDLObject()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObjectParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObjectParser.java
new file mode 100644
index 0000000..3addbaa
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObjectParser.java
@@ -0,0 +1,73 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser for definite-length tagged objects.
+ */
+class DLTaggedObjectParser
+ extends BERTaggedObjectParser
+{
+ private final boolean _constructed;
+
+ DLTaggedObjectParser(int tagClass, int tagNo, boolean constructed, ASN1StreamParser parser)
+ {
+ super(tagClass, tagNo, parser);
+
+ _constructed = constructed;
+ }
+
+ /**
+ * Return an in-memory, encodable, representation of the tagged object.
+ *
+ * @return an ASN1TaggedObject.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return _parser.loadTaggedDL(_tagClass, _tagNo, _constructed);
+ }
+
+ public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ if (declaredExplicit)
+ {
+ if (!_constructed)
+ {
+ throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
+ }
+
+ return _parser.parseObject(baseTagNo);
+ }
+
+ return _constructed
+ ? _parser.parseImplicitConstructedDL(baseTagNo)
+ : _parser.parseImplicitPrimitive(baseTagNo);
+ }
+
+ public ASN1Encodable parseExplicitBaseObject() throws IOException
+ {
+ if (!_constructed)
+ {
+ throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
+ }
+
+ return _parser.readObject();
+ }
+
+ public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException
+ {
+ if (!_constructed)
+ {
+ throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
+ }
+
+ return _parser.parseTaggedObject();
+ }
+
+ public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException
+ {
+ return new DLTaggedObjectParser(baseTagClass, baseTagNo, _constructed, _parser);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java
index 359bcc2..3589c8b 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java
@@ -25,18 +25,18 @@
{
super(in, limit);
- if (length < 0)
+ if (length <= 0)
{
- throw new IllegalArgumentException("negative lengths not allowed");
+ if (length < 0)
+ {
+ throw new IllegalArgumentException("negative lengths not allowed");
+ }
+
+ setParentEofDetect(true);
}
this._originalLength = length;
this._remaining = length;
-
- if (length == 0)
- {
- setParentEofDetect(true);
- }
}
int getRemaining()
@@ -111,7 +111,7 @@
throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
}
- if ((_remaining -= Streams.readFully(_in, buf)) != 0)
+ if ((_remaining -= Streams.readFully(_in, buf, 0, buf.length)) != 0)
{
throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
}
@@ -134,7 +134,7 @@
}
byte[] bytes = new byte[_remaining];
- if ((_remaining -= Streams.readFully(_in, bytes)) != 0)
+ if ((_remaining -= Streams.readFully(_in, bytes, 0, bytes.length)) != 0)
{
throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/LazyConstructionEnumeration.java b/bcprov/src/main/java/org/bouncycastle/asn1/LazyConstructionEnumeration.java
index c671e5b..4216e9e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/LazyConstructionEnumeration.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/LazyConstructionEnumeration.java
@@ -40,7 +40,7 @@
}
catch (IOException e)
{
- throw new ASN1ParsingException("malformed DER construction: " + e, e);
+ throw new ASN1ParsingException("malformed ASN.1: " + e, e);
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/LazyEncodedSequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/LazyEncodedSequence.java
index 23c72f8..93e9ff0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/LazyEncodedSequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/LazyEncodedSequence.java
@@ -17,18 +17,24 @@
// NOTE: Initially, the actual 'elements' will be empty
super();
+ if (null == encoded)
+ {
+ throw new NullPointerException("'encoded' cannot be null");
+ }
+
this.encoded = encoded;
}
- public synchronized ASN1Encodable getObjectAt(int index)
+ public ASN1Encodable getObjectAt(int index)
{
force();
return super.getObjectAt(index);
}
- public synchronized Enumeration getObjects()
+ public Enumeration getObjects()
{
+ byte[] encoded = getContents();
if (null != encoded)
{
return new LazyConstructionEnumeration(encoded);
@@ -37,28 +43,28 @@
return super.getObjects();
}
- public synchronized int hashCode()
+ public int hashCode()
{
force();
return super.hashCode();
}
- public synchronized Iterator<ASN1Encodable> iterator()
+ public Iterator<ASN1Encodable> iterator()
{
force();
return super.iterator();
}
- public synchronized int size()
+ public int size()
{
force();
return super.size();
}
- public synchronized ASN1Encodable[] toArray()
+ public ASN1Encodable[] toArray()
{
force();
@@ -72,27 +78,48 @@
return super.toArrayInternal();
}
- synchronized int encodedLength()
+ int encodedLength(boolean withTag)
throws IOException
{
+ byte[] encoded = getContents();
if (null != encoded)
{
- return 1 + StreamUtil.calculateBodyLength(encoded.length) + encoded.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, encoded.length);
}
- return super.toDLObject().encodedLength();
+ return super.toDLObject().encodedLength(withTag);
}
- synchronized void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
+ byte[] encoded = getContents();
if (null != encoded)
{
- out.writeEncoded(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded);
+ out.writeEncodingDL(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE, encoded);
+ return;
}
- else
- {
- super.toDLObject().encode(out, withTag);
- }
+
+ super.toDLObject().encode(out, withTag);
+ }
+
+ ASN1BitString toASN1BitString()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1BitString();
+ }
+
+ ASN1External toASN1External()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1External();
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1OctetString();
+ }
+
+ ASN1Set toASN1Set()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1Set();
}
synchronized ASN1Primitive toDERObject()
@@ -109,20 +136,28 @@
return super.toDLObject();
}
- private void force()
+ private synchronized void force()
{
if (null != encoded)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
-
- Enumeration en = new LazyConstructionEnumeration(encoded);
- while (en.hasMoreElements())
+ ASN1InputStream aIn = new ASN1InputStream(encoded, true);
+ try
{
- v.add((ASN1Primitive)en.nextElement());
- }
+ ASN1EncodableVector v = aIn.readVector();
+ aIn.close();
- this.elements = v.takeElements();
- this.encoded = null;
+ this.elements = v.takeElements();
+ this.encoded = null;
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("malformed ASN.1: " + e, e);
+ }
}
}
+
+ private synchronized byte[] getContents()
+ {
+ return encoded;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DateUtil.java b/bcprov/src/main/java/org/bouncycastle/asn1/LocaleUtil.java
similarity index 79%
rename from bcprov/src/main/java/org/bouncycastle/asn1/DateUtil.java
rename to bcprov/src/main/java/org/bouncycastle/asn1/LocaleUtil.java
index 83d8bb2..1a7821e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DateUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/LocaleUtil.java
@@ -7,13 +7,17 @@
import java.util.Locale;
import java.util.Map;
-class DateUtil
-{
- private static Long ZERO = longValueOf(0);
+import org.bouncycastle.util.Longs;
+/**
+ * ASN.1 uses an EN locale for its internal formatting. This class finds the nearest equivalent in the
+ * current JVM to ensure date formats are always respected.
+ */
+public class LocaleUtil
+{
private static final Map localeCache = new HashMap();
- static Locale EN_Locale = forEN();
+ public static Locale EN_Locale = forEN();
private static Locale forEN()
{
@@ -52,19 +56,12 @@
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
long v = dateF.parse("19700101000000GMT+00:00").getTime();
- if (v == 0)
- {
- adj = ZERO;
- }
- else
- {
- adj = longValueOf(v);
- }
+ adj = longValueOf(v);
localeCache.put(locale, adj);
}
- if (adj != ZERO)
+ if (adj.longValue() != 0L)
{
return new Date(date.getTime() - adj.longValue());
}
@@ -75,6 +72,6 @@
private static Long longValueOf(long v)
{
- return Long.valueOf(v);
+ return Longs.valueOf(v);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
index 31b14f2..2189edc 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
@@ -3,74 +3,102 @@
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
/**
- * Object Identifiers belonging to iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle (1.3.6.1.4.1.22554)
+ * Object Identifiers belonging to iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle (1.3.6.1.4.1.22554)
*/
public interface BCObjectIdentifiers
{
/**
- * iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle
- *<p>
- * 1.3.6.1.4.1.22554
+ * iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle
+ * <p>
+ * 1.3.6.1.4.1.22554
*/
- public static final ASN1ObjectIdentifier bc = new ASN1ObjectIdentifier("1.3.6.1.4.1.22554");
+ ASN1ObjectIdentifier bc = new ASN1ObjectIdentifier("1.3.6.1.4.1.22554");
/**
* pbe(1) algorithms
* <p>
* 1.3.6.1.4.1.22554.1
*/
- public static final ASN1ObjectIdentifier bc_pbe = bc.branch("1");
+ ASN1ObjectIdentifier bc_pbe = bc.branch("1");
/**
* SHA-1(1)
* <p>
* 1.3.6.1.4.1.22554.1.1
*/
- public static final ASN1ObjectIdentifier bc_pbe_sha1 = bc_pbe.branch("1");
+ ASN1ObjectIdentifier bc_pbe_sha1 = bc_pbe.branch("1");
- /** SHA-2.SHA-256; 1.3.6.1.4.1.22554.1.2.1 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256 = bc_pbe.branch("2.1");
- /** SHA-2.SHA-384; 1.3.6.1.4.1.22554.1.2.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha384 = bc_pbe.branch("2.2");
- /** SHA-2.SHA-512; 1.3.6.1.4.1.22554.1.2.3 */
- public static final ASN1ObjectIdentifier bc_pbe_sha512 = bc_pbe.branch("2.3");
- /** SHA-2.SHA-224; 1.3.6.1.4.1.22554.1.2.4 */
- public static final ASN1ObjectIdentifier bc_pbe_sha224 = bc_pbe.branch("2.4");
+ /**
+ * SHA-2.SHA-256; 1.3.6.1.4.1.22554.1.2.1
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256 = bc_pbe.branch("2.1");
+ /**
+ * SHA-2.SHA-384; 1.3.6.1.4.1.22554.1.2.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha384 = bc_pbe.branch("2.2");
+ /**
+ * SHA-2.SHA-512; 1.3.6.1.4.1.22554.1.2.3
+ */
+ ASN1ObjectIdentifier bc_pbe_sha512 = bc_pbe.branch("2.3");
+ /**
+ * SHA-2.SHA-224; 1.3.6.1.4.1.22554.1.2.4
+ */
+ ASN1ObjectIdentifier bc_pbe_sha224 = bc_pbe.branch("2.4");
/**
* PKCS-5(1)|PKCS-12(2)
*/
- /** SHA-1.PKCS5; 1.3.6.1.4.1.22554.1.1.1 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs5 = bc_pbe_sha1.branch("1");
- /** SHA-1.PKCS12; 1.3.6.1.4.1.22554.1.1.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12 = bc_pbe_sha1.branch("2");
+ /**
+ * SHA-1.PKCS5; 1.3.6.1.4.1.22554.1.1.1
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs5 = bc_pbe_sha1.branch("1");
+ /**
+ * SHA-1.PKCS12; 1.3.6.1.4.1.22554.1.1.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12 = bc_pbe_sha1.branch("2");
- /** SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.1 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs5 = bc_pbe_sha256.branch("1");
- /** SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12 = bc_pbe_sha256.branch("2");
+ /**
+ * SHA-256.PKCS5; 1.3.6.1.4.1.22554.1.2.1.1
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs5 = bc_pbe_sha256.branch("1");
+ /**
+ * SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12 = bc_pbe_sha256.branch("2");
/**
* AES(1) . (CBC-128(2)|CBC-192(22)|CBC-256(42))
*/
- /** 1.3.6.1.4.1.22554.1.1.2.1.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = bc_pbe_sha1_pkcs12.branch("1.2");
- /** 1.3.6.1.4.1.22554.1.1.2.1.22 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = bc_pbe_sha1_pkcs12.branch("1.22");
- /** 1.3.6.1.4.1.22554.1.1.2.1.42 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = bc_pbe_sha1_pkcs12.branch("1.42");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.1.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = bc_pbe_sha1_pkcs12.branch("1.2");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.1.22
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = bc_pbe_sha1_pkcs12.branch("1.22");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.1.42
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = bc_pbe_sha1_pkcs12.branch("1.42");
- /** 1.3.6.1.4.1.22554.1.1.2.2.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = bc_pbe_sha256_pkcs12.branch("1.2");
- /** 1.3.6.1.4.1.22554.1.1.2.2.22 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = bc_pbe_sha256_pkcs12.branch("1.22");
- /** 1.3.6.1.4.1.22554.1.1.2.2.42 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = bc_pbe_sha256_pkcs12.branch("1.42");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.2.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = bc_pbe_sha256_pkcs12.branch("1.2");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.2.22
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = bc_pbe_sha256_pkcs12.branch("1.22");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.2.42
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = bc_pbe_sha256_pkcs12.branch("1.42");
/**
* signature(2) algorithms
*/
- public static final ASN1ObjectIdentifier bc_sig = bc.branch("2");
+ ASN1ObjectIdentifier bc_sig = bc.branch("2");
// BEGIN Android-removed: Unsupported algorithms
/*
@@ -81,101 +109,329 @@
public static final ASN1ObjectIdentifier sphincs256_with_BLAKE512 = sphincs256.branch("1");
public static final ASN1ObjectIdentifier sphincs256_with_SHA512 = sphincs256.branch("2");
public static final ASN1ObjectIdentifier sphincs256_with_SHA3_512 = sphincs256.branch("3");
+ ASN1ObjectIdentifier sphincs256 = bc_sig.branch("1");
+ ASN1ObjectIdentifier sphincs256_with_BLAKE512 = sphincs256.branch("1");
+ ASN1ObjectIdentifier sphincs256_with_SHA512 = sphincs256.branch("2");
+ ASN1ObjectIdentifier sphincs256_with_SHA3_512 = sphincs256.branch("3");
+ */
/**
* XMSS
*/
- public static final ASN1ObjectIdentifier xmss = bc_sig.branch("2");
- public static final ASN1ObjectIdentifier xmss_SHA256ph = xmss.branch("1");
- public static final ASN1ObjectIdentifier xmss_SHA512ph = xmss.branch("2");
- public static final ASN1ObjectIdentifier xmss_SHAKE128ph = xmss.branch("3");
- public static final ASN1ObjectIdentifier xmss_SHAKE256ph = xmss.branch("4");
- public static final ASN1ObjectIdentifier xmss_SHA256 = xmss.branch("5");
- public static final ASN1ObjectIdentifier xmss_SHA512 = xmss.branch("6");
- public static final ASN1ObjectIdentifier xmss_SHAKE128 = xmss.branch("7");
- public static final ASN1ObjectIdentifier xmss_SHAKE256 = xmss.branch("8");
+ ASN1ObjectIdentifier xmss = bc_sig.branch("2");
+ ASN1ObjectIdentifier xmss_SHA256ph = xmss.branch("1");
+ ASN1ObjectIdentifier xmss_SHA512ph = xmss.branch("2");
+ ASN1ObjectIdentifier xmss_SHAKE128_512ph = xmss.branch("3");
+ ASN1ObjectIdentifier xmss_SHAKE256_1024ph = xmss.branch("4");
+ ASN1ObjectIdentifier xmss_SHA256 = xmss.branch("5");
+ ASN1ObjectIdentifier xmss_SHA512 = xmss.branch("6");
+ ASN1ObjectIdentifier xmss_SHAKE128 = xmss.branch("7");
+ ASN1ObjectIdentifier xmss_SHAKE256 = xmss.branch("8");
+ ASN1ObjectIdentifier xmss_SHAKE128ph = xmss.branch("9");
+ ASN1ObjectIdentifier xmss_SHAKE256ph = xmss.branch("10");
/**
* XMSS^MT
*/
- public static final ASN1ObjectIdentifier xmss_mt = bc_sig.branch("3");
- public static final ASN1ObjectIdentifier xmss_mt_SHA256ph = xmss_mt.branch("1");
- public static final ASN1ObjectIdentifier xmss_mt_SHA512ph = xmss_mt.branch("2");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE128ph = xmss_mt.branch("3");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE256ph = xmss_mt.branch("4");
- public static final ASN1ObjectIdentifier xmss_mt_SHA256 = xmss_mt.branch("5");
- public static final ASN1ObjectIdentifier xmss_mt_SHA512 = xmss_mt.branch("6");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE128 = xmss_mt.branch("7");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE256 = xmss_mt.branch("8");
-
- // old OIDs.
- /**
- * @deprecated use xmss_SHA256ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHA256 = xmss_SHA256ph;
- /**
- * @deprecated use xmss_SHA512ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHA512 = xmss_SHA512ph;
- /**
- * @deprecated use xmss_SHAKE128ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHAKE128 = xmss_SHAKE128ph;
- /**
- * @deprecated use xmss_SHAKE256ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHAKE256 = xmss_SHAKE256ph;
-
- /**
- * @deprecated use xmss_mt_SHA256ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHA256 = xmss_mt_SHA256ph;
- /**
- * @deprecated use xmss_mt_SHA512ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHA512 = xmss_mt_SHA512ph;
- /**
- * @deprecated use xmss_mt_SHAKE128ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE128 = xmss_mt_SHAKE128;
- /**
- * @deprecated use xmss_mt_SHAKE256ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE256 = xmss_mt_SHAKE256;
+ ASN1ObjectIdentifier xmss_mt = bc_sig.branch("3");
+ ASN1ObjectIdentifier xmss_mt_SHA256ph = xmss_mt.branch("1");
+ ASN1ObjectIdentifier xmss_mt_SHA512ph = xmss_mt.branch("2");
+ ASN1ObjectIdentifier xmss_mt_SHAKE128_512ph = xmss_mt.branch("3");
+ ASN1ObjectIdentifier xmss_mt_SHAKE256_1024ph = xmss_mt.branch("4");
+ ASN1ObjectIdentifier xmss_mt_SHA256 = xmss_mt.branch("5");
+ ASN1ObjectIdentifier xmss_mt_SHA512 = xmss_mt.branch("6");
+ ASN1ObjectIdentifier xmss_mt_SHAKE128 = xmss_mt.branch("7");
+ ASN1ObjectIdentifier xmss_mt_SHAKE256 = xmss_mt.branch("8");
+ ASN1ObjectIdentifier xmss_mt_SHAKE128ph = xmss_mt.branch("9");
+ ASN1ObjectIdentifier xmss_mt_SHAKE256ph = xmss_mt.branch("10");
/**
* qTESLA
*/
- public static final ASN1ObjectIdentifier qTESLA = bc_sig.branch("4");
+ ASN1ObjectIdentifier qTESLA = bc_sig.branch("4");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_I = qTESLA.branch("1");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_size = qTESLA.branch("2");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_speed = qTESLA.branch("3");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_I = qTESLA.branch("4");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_III = qTESLA.branch("5");
+ ASN1ObjectIdentifier qTESLA_Rnd1_I = qTESLA.branch("1");
+ ASN1ObjectIdentifier qTESLA_Rnd1_III_size = qTESLA.branch("2");
+ ASN1ObjectIdentifier qTESLA_Rnd1_III_speed = qTESLA.branch("3");
+ ASN1ObjectIdentifier qTESLA_Rnd1_p_I = qTESLA.branch("4");
+ ASN1ObjectIdentifier qTESLA_Rnd1_p_III = qTESLA.branch("5");
- public static final ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("11");
- public static final ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("12");
+ ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("11");
+ ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("12");
+
+ /**
+ * SPHINCS+
+ */
+ ASN1ObjectIdentifier sphincsPlus = bc_sig.branch("5");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128s_r3 = sphincsPlus.branch("1");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128f_r3 = sphincsPlus.branch("2");
+ ASN1ObjectIdentifier sphincsPlus_shake_128s_r3 = sphincsPlus.branch("3");
+ ASN1ObjectIdentifier sphincsPlus_shake_128f_r3 = sphincsPlus.branch("4");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128s_r3 = sphincsPlus.branch("5");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128f_r3 = sphincsPlus.branch("6");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_192s_r3 = sphincsPlus.branch("7");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192f_r3 = sphincsPlus.branch("8");
+ ASN1ObjectIdentifier sphincsPlus_shake_192s_r3 = sphincsPlus.branch("9");
+ ASN1ObjectIdentifier sphincsPlus_shake_192f_r3 = sphincsPlus.branch("10");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192s_r3 = sphincsPlus.branch("11");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192f_r3 = sphincsPlus.branch("12");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_256s_r3 = sphincsPlus.branch("13");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256f_r3 = sphincsPlus.branch("14");
+ ASN1ObjectIdentifier sphincsPlus_shake_256s_r3 = sphincsPlus.branch("15");
+ ASN1ObjectIdentifier sphincsPlus_shake_256f_r3 = sphincsPlus.branch("16");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256s_r3 = sphincsPlus.branch("17");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256f_r3 = sphincsPlus.branch("18");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_128s_r3_simple = sphincsPlus.branch("19");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128f_r3_simple = sphincsPlus.branch("20");
+ ASN1ObjectIdentifier sphincsPlus_shake_128s_r3_simple = sphincsPlus.branch("21");
+ ASN1ObjectIdentifier sphincsPlus_shake_128f_r3_simple = sphincsPlus.branch("22");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128s_r3_simple = sphincsPlus.branch("23");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128f_r3_simple = sphincsPlus.branch("24");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_192s_r3_simple = sphincsPlus.branch("25");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192f_r3_simple = sphincsPlus.branch("26");
+ ASN1ObjectIdentifier sphincsPlus_shake_192s_r3_simple = sphincsPlus.branch("27");
+ ASN1ObjectIdentifier sphincsPlus_shake_192f_r3_simple = sphincsPlus.branch("28");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192s_r3_simple = sphincsPlus.branch("29");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192f_r3_simple = sphincsPlus.branch("30");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_256s_r3_simple = sphincsPlus.branch("31");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256f_r3_simple = sphincsPlus.branch("32");
+ ASN1ObjectIdentifier sphincsPlus_shake_256s_r3_simple = sphincsPlus.branch("33");
+ ASN1ObjectIdentifier sphincsPlus_shake_256f_r3_simple = sphincsPlus.branch("34");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256s_r3_simple = sphincsPlus.branch("35");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256f_r3_simple = sphincsPlus.branch("36");
+
+
+ ASN1ObjectIdentifier sphincsPlus_interop = new ASN1ObjectIdentifier("1.3.9999.6");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_128f = new ASN1ObjectIdentifier("1.3.9999.6.4.13");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128s = new ASN1ObjectIdentifier("1.3.9999.6.4.16");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192f = new ASN1ObjectIdentifier("1.3.9999.6.5.10");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192s = new ASN1ObjectIdentifier("1.3.9999.6.5.12");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256f = new ASN1ObjectIdentifier("1.3.9999.6.6.10");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256s = new ASN1ObjectIdentifier("1.3.9999.6.6.12");
+
+ ASN1ObjectIdentifier sphincsPlus_shake_128f = new ASN1ObjectIdentifier("1.3.9999.6.7.13");
+ ASN1ObjectIdentifier sphincsPlus_shake_128s = new ASN1ObjectIdentifier("1.3.9999.6.7.16");
+ ASN1ObjectIdentifier sphincsPlus_shake_192f = new ASN1ObjectIdentifier("1.3.9999.6.8.10");
+ ASN1ObjectIdentifier sphincsPlus_shake_192s = new ASN1ObjectIdentifier("1.3.9999.6.8.12");
+ ASN1ObjectIdentifier sphincsPlus_shake_256f = new ASN1ObjectIdentifier("1.3.9999.6.9.10");
+ ASN1ObjectIdentifier sphincsPlus_shake_256s = new ASN1ObjectIdentifier("1.3.9999.6.9.12");
+
+ /**
+ * Picnic
+ */
+ ASN1ObjectIdentifier picnic = bc_sig.branch("6");
+
+ ASN1ObjectIdentifier picnic_key = picnic.branch("1");
+
+ ASN1ObjectIdentifier picnicl1fs = picnic_key.branch("1");
+ ASN1ObjectIdentifier picnicl1ur = picnic_key.branch("2");
+ ASN1ObjectIdentifier picnicl3fs = picnic_key.branch("3");
+ ASN1ObjectIdentifier picnicl3ur = picnic_key.branch("4");
+ ASN1ObjectIdentifier picnicl5fs = picnic_key.branch("5");
+ ASN1ObjectIdentifier picnicl5ur = picnic_key.branch("6");
+ ASN1ObjectIdentifier picnic3l1 = picnic_key.branch("7");
+ ASN1ObjectIdentifier picnic3l3 = picnic_key.branch("8");
+ ASN1ObjectIdentifier picnic3l5 = picnic_key.branch("9");
+ ASN1ObjectIdentifier picnicl1full = picnic_key.branch("10");
+ ASN1ObjectIdentifier picnicl3full = picnic_key.branch("11");
+ ASN1ObjectIdentifier picnicl5full = picnic_key.branch("12");
+
+ ASN1ObjectIdentifier picnic_signature = picnic.branch("2");
+ ASN1ObjectIdentifier picnic_with_sha512 = picnic_signature.branch("1");
+ ASN1ObjectIdentifier picnic_with_shake256 = picnic_signature.branch("2");
+ ASN1ObjectIdentifier picnic_with_sha3_512 = picnic_signature.branch("3");
+
+
+ /*
+ * Falcon
+ */
+ ASN1ObjectIdentifier falcon = bc_sig.branch("7");
+
+ ASN1ObjectIdentifier falcon_512 = new ASN1ObjectIdentifier("1.3.9999.3.6"); // falcon.branch("1");
+ ASN1ObjectIdentifier falcon_1024 = new ASN1ObjectIdentifier("1.3.9999.3.9"); // falcon.branch("2");
+
+ /*
+ * Dilithium
+ */
+ ASN1ObjectIdentifier dilithium = bc_sig.branch("8");
+
+ // OpenSSL OIDs
+ ASN1ObjectIdentifier dilithium2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.4.4"); // dilithium.branch("1");
+ ASN1ObjectIdentifier dilithium3 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.6.5"); // dilithium.branch("2");
+ ASN1ObjectIdentifier dilithium5 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.8.7"); // dilithium.branch("3");
+ ASN1ObjectIdentifier dilithium2_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.4.4"); // dilithium.branch("4");
+ ASN1ObjectIdentifier dilithium3_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.6.5"); // dilithium.branch("5");
+ ASN1ObjectIdentifier dilithium5_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.8.7"); // dilithium.branch("6");
+
+ /*
+ * Rainbow
+ */
+ ASN1ObjectIdentifier rainbow = bc_sig.branch("9");
+
+ ASN1ObjectIdentifier rainbow_III_classic = rainbow.branch("1");
+ ASN1ObjectIdentifier rainbow_III_circumzenithal = rainbow.branch("2");
+ ASN1ObjectIdentifier rainbow_III_compressed = rainbow.branch("3");
+ ASN1ObjectIdentifier rainbow_V_classic = rainbow.branch("4");
+ ASN1ObjectIdentifier rainbow_V_circumzenithal = rainbow.branch("5");
+ ASN1ObjectIdentifier rainbow_V_compressed = rainbow.branch("6");
/**
* key_exchange(3) algorithms
- *
- public static final ASN1ObjectIdentifier bc_exch = bc.branch("3");
+ */
+ ASN1ObjectIdentifier bc_exch = bc.branch("3");
/**
* NewHope
- *
- public static final ASN1ObjectIdentifier newHope = bc_exch.branch("1");
- */
- // END Android-removed: Unsupported algorithms
+ */
+ ASN1ObjectIdentifier newHope = bc_exch.branch("1");
/**
- * X.509 extension(4) values
+ * X.509 extension/certificate types
* <p>
* 1.3.6.1.4.1.22554.4
*/
- public static final ASN1ObjectIdentifier bc_ext = bc.branch("4");
+ ASN1ObjectIdentifier bc_ext = bc.branch("4");
- public static final ASN1ObjectIdentifier linkedCertificate = bc_ext.branch("1");
+ ASN1ObjectIdentifier linkedCertificate = bc_ext.branch("1");
+ ASN1ObjectIdentifier external_value = bc_ext.branch("2");
+
+ /**
+ * KEM(5) algorithms
+ */
+ ASN1ObjectIdentifier bc_kem = bc.branch("5");
+
+ /**
+ * Classic McEliece
+ */
+ ASN1ObjectIdentifier pqc_kem_mceliece = bc_kem.branch("1");
+
+ ASN1ObjectIdentifier mceliece348864_r3 = pqc_kem_mceliece.branch("1");
+ ASN1ObjectIdentifier mceliece348864f_r3 = pqc_kem_mceliece.branch("2");
+ ASN1ObjectIdentifier mceliece460896_r3 = pqc_kem_mceliece.branch("3");
+ ASN1ObjectIdentifier mceliece460896f_r3 = pqc_kem_mceliece.branch("4");
+ ASN1ObjectIdentifier mceliece6688128_r3 = pqc_kem_mceliece.branch("5");
+ ASN1ObjectIdentifier mceliece6688128f_r3 = pqc_kem_mceliece.branch("6");
+ ASN1ObjectIdentifier mceliece6960119_r3 = pqc_kem_mceliece.branch("7");
+ ASN1ObjectIdentifier mceliece6960119f_r3 = pqc_kem_mceliece.branch("8");
+ ASN1ObjectIdentifier mceliece8192128_r3 = pqc_kem_mceliece.branch("9");
+ ASN1ObjectIdentifier mceliece8192128f_r3 = pqc_kem_mceliece.branch("10");
+
+
+ /**
+ * Frodo
+ */
+ ASN1ObjectIdentifier pqc_kem_frodo = bc_kem.branch("2");
+
+ ASN1ObjectIdentifier frodokem640aes = pqc_kem_frodo.branch("1");
+ ASN1ObjectIdentifier frodokem640shake = pqc_kem_frodo.branch("2");
+ ASN1ObjectIdentifier frodokem976aes = pqc_kem_frodo.branch("3");
+ ASN1ObjectIdentifier frodokem976shake = pqc_kem_frodo.branch("4");
+ ASN1ObjectIdentifier frodokem1344aes = pqc_kem_frodo.branch("5");
+ ASN1ObjectIdentifier frodokem1344shake = pqc_kem_frodo.branch("6");
+
+ /**
+ * SABER
+ */
+ ASN1ObjectIdentifier pqc_kem_saber = bc_kem.branch("3");
+
+ ASN1ObjectIdentifier lightsaberkem128r3 = pqc_kem_saber.branch("1");
+ ASN1ObjectIdentifier saberkem128r3 = pqc_kem_saber.branch("2");
+ ASN1ObjectIdentifier firesaberkem128r3 = pqc_kem_saber.branch("3");
+ ASN1ObjectIdentifier lightsaberkem192r3 = pqc_kem_saber.branch("4");
+ ASN1ObjectIdentifier saberkem192r3 = pqc_kem_saber.branch("5");
+ ASN1ObjectIdentifier firesaberkem192r3 = pqc_kem_saber.branch("6");
+ ASN1ObjectIdentifier lightsaberkem256r3 = pqc_kem_saber.branch("7");
+ ASN1ObjectIdentifier saberkem256r3 = pqc_kem_saber.branch("8");
+ ASN1ObjectIdentifier firesaberkem256r3 = pqc_kem_saber.branch("9");
+ ASN1ObjectIdentifier ulightsaberkemr3 = pqc_kem_saber.branch("10");
+ ASN1ObjectIdentifier usaberkemr3 = pqc_kem_saber.branch("11");
+ ASN1ObjectIdentifier ufiresaberkemr3 = pqc_kem_saber.branch("12");
+ ASN1ObjectIdentifier lightsaberkem90sr3 = pqc_kem_saber.branch("13");
+ ASN1ObjectIdentifier saberkem90sr3 = pqc_kem_saber.branch("14");
+ ASN1ObjectIdentifier firesaberkem90sr3 = pqc_kem_saber.branch("15");
+ ASN1ObjectIdentifier ulightsaberkem90sr3 = pqc_kem_saber.branch("16");
+ ASN1ObjectIdentifier usaberkem90sr3 = pqc_kem_saber.branch("17");
+ ASN1ObjectIdentifier ufiresaberkem90sr3 = pqc_kem_saber.branch("18");
+
+ /**
+ * SIKE
+ */
+ ASN1ObjectIdentifier pqc_kem_sike = bc_kem.branch("4");
+
+ ASN1ObjectIdentifier sikep434 = pqc_kem_sike.branch("1");
+ ASN1ObjectIdentifier sikep503 = pqc_kem_sike.branch("2");
+ ASN1ObjectIdentifier sikep610 = pqc_kem_sike.branch("3");
+ ASN1ObjectIdentifier sikep751 = pqc_kem_sike.branch("4");
+ ASN1ObjectIdentifier sikep434_compressed = pqc_kem_sike.branch("5");
+ ASN1ObjectIdentifier sikep503_compressed = pqc_kem_sike.branch("6");
+ ASN1ObjectIdentifier sikep610_compressed = pqc_kem_sike.branch("7");
+ ASN1ObjectIdentifier sikep751_compressed = pqc_kem_sike.branch("8");
+
+ /**
+ * NTRU
+ */
+ ASN1ObjectIdentifier pqc_kem_ntru = bc_kem.branch("5");
+
+ ASN1ObjectIdentifier ntruhps2048509 = pqc_kem_ntru.branch("1");
+ ASN1ObjectIdentifier ntruhps2048677 = pqc_kem_ntru.branch("2");
+ ASN1ObjectIdentifier ntruhps4096821 = pqc_kem_ntru.branch("3");
+ ASN1ObjectIdentifier ntruhrss701 = pqc_kem_ntru.branch("4");
+
+ /**
+ * Kyber
+ */
+ ASN1ObjectIdentifier pqc_kem_kyber = bc_kem.branch("6");
+
+ ASN1ObjectIdentifier kyber512 = pqc_kem_kyber.branch("1");
+ ASN1ObjectIdentifier kyber768 = pqc_kem_kyber.branch("2");
+ ASN1ObjectIdentifier kyber1024 = pqc_kem_kyber.branch("3");
+ ASN1ObjectIdentifier kyber512_aes = pqc_kem_kyber.branch("4");
+ ASN1ObjectIdentifier kyber768_aes = pqc_kem_kyber.branch("5");
+ ASN1ObjectIdentifier kyber1024_aes = pqc_kem_kyber.branch("6");
+
+ /**
+ * NTRUPrime
+ */
+ ASN1ObjectIdentifier pqc_kem_ntruprime = bc_kem.branch("7");
+
+ ASN1ObjectIdentifier pqc_kem_ntrulprime = pqc_kem_ntruprime.branch("1");
+ ASN1ObjectIdentifier ntrulpr653 = pqc_kem_ntrulprime.branch("1");
+ ASN1ObjectIdentifier ntrulpr761 = pqc_kem_ntrulprime.branch("2");
+ ASN1ObjectIdentifier ntrulpr857 = pqc_kem_ntrulprime.branch("3");
+ ASN1ObjectIdentifier ntrulpr953 = pqc_kem_ntrulprime.branch("4");
+ ASN1ObjectIdentifier ntrulpr1013 = pqc_kem_ntrulprime.branch("5");
+ ASN1ObjectIdentifier ntrulpr1277 = pqc_kem_ntrulprime.branch("6");
+
+ ASN1ObjectIdentifier pqc_kem_sntruprime = pqc_kem_ntruprime.branch("2");
+ ASN1ObjectIdentifier sntrup653 = pqc_kem_sntruprime.branch("1");
+ ASN1ObjectIdentifier sntrup761 = pqc_kem_sntruprime.branch("2");
+ ASN1ObjectIdentifier sntrup857 = pqc_kem_sntruprime.branch("3");
+ ASN1ObjectIdentifier sntrup953 = pqc_kem_sntruprime.branch("4");
+ ASN1ObjectIdentifier sntrup1013 = pqc_kem_sntruprime.branch("5");
+ ASN1ObjectIdentifier sntrup1277 = pqc_kem_sntruprime.branch("6");
+
+ /**
+ * BIKE
+ **/
+ ASN1ObjectIdentifier pqc_kem_bike = bc_kem.branch("8");
+
+ ASN1ObjectIdentifier bike128 = pqc_kem_bike.branch("1");
+ ASN1ObjectIdentifier bike192 = pqc_kem_bike.branch("2");
+ ASN1ObjectIdentifier bike256 = pqc_kem_bike.branch("3");
+
+ /**
+ * HQC
+ **/
+ ASN1ObjectIdentifier pqc_kem_hqc = bc_kem.branch("9");
+
+ ASN1ObjectIdentifier hqc128 = pqc_kem_hqc.branch("1");
+ ASN1ObjectIdentifier hqc192 = pqc_kem_hqc.branch("2");
+ ASN1ObjectIdentifier hqc256 = pqc_kem_hqc.branch("3");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/bc/ExternalValue.java b/bcprov/src/main/java/org/bouncycastle/asn1/bc/ExternalValue.java
new file mode 100644
index 0000000..9c31888
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/bc/ExternalValue.java
@@ -0,0 +1,117 @@
+package org.bouncycastle.asn1.bc;
+
+import org.bouncycastle.asn1.ASN1BitString;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERBitString;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.util.Arrays;
+
+/**
+ * Based on External Keys And Signatures For Use In Internet PKI
+ * draft-ounsworth-pq-external-pubkeys-00
+ * <pre>
+ * ExternalValue ::= SEQUENCE {
+ * location GeneralNames, # MUST refer to a DER encoded SubjectPublicKeyInfo/Signature (may be Base64)
+ * hashAlg AlgorithmIdentifier,
+ * hashVal OCTET STRING }
+ * </pre>
+ */
+public class ExternalValue
+ extends ASN1Object
+{
+ private final GeneralNames location;
+ private final AlgorithmIdentifier hashAlg;
+ private final byte[] hashValue;
+
+ public ExternalValue(GeneralName location, AlgorithmIdentifier hashAlg, byte[] hashVal)
+ {
+ this.location = new GeneralNames(location);
+ this.hashAlg = hashAlg;
+ this.hashValue = Arrays.clone(hashVal);
+ }
+
+ private ExternalValue(ASN1Sequence seq)
+ {
+ if (seq.size() == 3)
+ {
+ location = GeneralNames.getInstance(seq.getObjectAt(0));
+ hashAlg = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ if (seq.getObjectAt(2) instanceof ASN1BitString) // legacy implementation on 2021 draft
+ {
+ hashValue = ASN1BitString.getInstance(seq.getObjectAt(2)).getOctets();
+ }
+ else
+ {
+ hashValue = ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets();
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown sequence");
+ }
+ }
+
+ public static ExternalValue getInstance(Object o)
+ {
+ if (o instanceof ExternalValue)
+ {
+ return (ExternalValue)o;
+ }
+ else if (o != null)
+ {
+ return new ExternalValue(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public GeneralName getLocation()
+ {
+ return location.getNames()[0];
+ }
+
+ public GeneralName[] getLocations()
+ {
+ return location.getNames();
+ }
+
+ public AlgorithmIdentifier getHashAlg()
+ {
+ return hashAlg;
+ }
+
+ public byte[] getHashValue()
+ {
+ return Arrays.clone(hashValue);
+ }
+
+ /**
+ * Get the hash value as a BIT STRING.
+ *
+ * @return the hash value as a BIT STRING
+ * @deprecated use getHash(), the internal encoding is now an OCTET STRING
+ */
+ public ASN1BitString getHashVal()
+ {
+ return new DERBitString(hashValue);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(location);
+ v.add(hashAlg);
+ v.add(new DEROctetString(hashValue));
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/bc/LinkedCertificate.java b/bcprov/src/main/java/org/bouncycastle/asn1/bc/LinkedCertificate.java
new file mode 100644
index 0000000..d812087
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/bc/LinkedCertificate.java
@@ -0,0 +1,126 @@
+package org.bouncycastle.asn1.bc;
+
+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.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.DigestInfo;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
+
+/**
+ * Extension to tie an alternate certificate to the containing certificate.
+ * <pre>
+ * LinkedCertificate := SEQUENCE {
+ * digest DigestInfo, -- digest of PQC certificate
+ * certLocation GeneralName, -- location of PQC certificate
+ * certIssuer [0] Name OPTIONAL, -- issuer of PQC cert (if different from current certificate)
+ * cACerts [1] GeneralNames OPTIONAL, -- CA certificates for PQC cert (one of more locations)
+ * }
+ * </pre>
+ */
+public class LinkedCertificate
+ extends ASN1Object
+{
+ private final DigestInfo digest;
+ private final GeneralName certLocation;
+
+ private X500Name certIssuer;
+ private GeneralNames cACerts;
+
+ public LinkedCertificate(DigestInfo digest, GeneralName certLocation)
+ {
+ this(digest, certLocation, null, null);
+ }
+
+ public LinkedCertificate(DigestInfo digest, GeneralName certLocation, X500Name certIssuer, GeneralNames cACerts)
+ {
+ this.digest = digest;
+ this.certLocation = certLocation;
+ this.certIssuer = certIssuer;
+ this.cACerts = cACerts;
+ }
+
+ private LinkedCertificate(ASN1Sequence seq)
+ {
+ this.digest = DigestInfo.getInstance(seq.getObjectAt(0));
+ this.certLocation = GeneralName.getInstance(seq.getObjectAt(1));
+
+ if (seq.size() > 2)
+ {
+ for (int i = 2; i != seq.size(); i++)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(i));
+
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ certIssuer = X500Name.getInstance(tagged, false);
+ break;
+ case 1:
+ cACerts = GeneralNames.getInstance(tagged, false);
+ break;
+ default:
+ throw new IllegalArgumentException("unknown tag in tagged field");
+ }
+ }
+ }
+ }
+
+ public static LinkedCertificate getInstance(Object o)
+ {
+ if (o instanceof LinkedCertificate)
+ {
+ return (LinkedCertificate)o;
+ }
+ else if (o != null)
+ {
+ return new LinkedCertificate(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public DigestInfo getDigest()
+ {
+ return digest;
+ }
+
+ public GeneralName getCertLocation()
+ {
+ return certLocation;
+ }
+
+ public X500Name getCertIssuer()
+ {
+ return certIssuer;
+ }
+
+ public GeneralNames getCACerts()
+ {
+ return cACerts;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(digest);
+ v.add(certLocation);
+
+ if (certIssuer != null)
+ {
+ v.add(new DERTaggedObject(false, 0, certIssuer));
+ }
+ if (cACerts != null)
+ {
+ v.add(new DERTaggedObject(false, 1, cACerts));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java
index be197d2..ffd3569 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java
@@ -128,3 +128,4 @@
return new BERSequence(v);
}
}
+
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
deleted file mode 100644
index 35e65f5..0000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package org.bouncycastle.asn1.eac;
-
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-
-/**
- * German Federal Office for Information Security
- * (Bundesamt für Sicherheit in der Informationstechnik)
- * <a href="https://www.bsi.bund.de/">https://www.bsi.bund.de/</a>
- * <p>
- * <a href="https://www.bsi.bund.de/EN/Publications/TechnicalGuidelines/TR03110/BSITR03110.html">BSI TR-03110</a>
- * Technical Guideline Advanced Security Mechanisms for Machine Readable Travel Documents
- * <p>
- * <a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03110/TR-03110_v2.1_P3pdf.pdf">
- * Technical Guideline TR-03110-3</a>
- * Advanced Security Mechanisms for Machine Readable Travel Documents;
- * Part 3: Common Specifications.
- */
-public interface EACObjectIdentifiers
-{
- /**
- * <pre>
- * bsi-de OBJECT IDENTIFIER ::= {
- * itu-t(0) identified-organization(4) etsi(0)
- * reserved(127) etsi-identified-organization(0) 7
- * }
- * </pre>
- * OID: 0.4.0.127.0.7
- */
- static final ASN1ObjectIdentifier bsi_de = new ASN1ObjectIdentifier("0.4.0.127.0.7");
-
- /**
- * <pre>
- * id-PK OBJECT IDENTIFIER ::= {
- * bsi-de protocols(2) smartcard(2) 1
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.2.2.1
- */
- static final ASN1ObjectIdentifier id_PK = bsi_de.branch("2.2.1");
-
- /** OID: 0.4.0.127.0.7.2.2.1.1 */
- static final ASN1ObjectIdentifier id_PK_DH = id_PK.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.1.2 */
- static final ASN1ObjectIdentifier id_PK_ECDH = id_PK.branch("2");
-
- /**
- * <pre>
- * id-CA OBJECT IDENTIFIER ::= {
- * bsi-de protocols(2) smartcard(2) 3
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.2.2.3
- */
- static final ASN1ObjectIdentifier id_CA = bsi_de.branch("2.2.3");
- /** OID: 0.4.0.127.0.7.2.2.3.1 */
- static final ASN1ObjectIdentifier id_CA_DH = id_CA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.3.1.1 */
- static final ASN1ObjectIdentifier id_CA_DH_3DES_CBC_CBC = id_CA_DH.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.3.2 */
- static final ASN1ObjectIdentifier id_CA_ECDH = id_CA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.3.2.1 */
- static final ASN1ObjectIdentifier id_CA_ECDH_3DES_CBC_CBC = id_CA_ECDH.branch("1");
-
- /**
- * <pre>
- * id-TA OBJECT IDENTIFIER ::= {
- * bsi-de protocols(2) smartcard(2) 2
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.2.2.2
- */
- static final ASN1ObjectIdentifier id_TA = bsi_de.branch("2.2.2");
-
- /** OID: 0.4.0.127.0.7.2.2.2.1 */
- static final ASN1ObjectIdentifier id_TA_RSA = id_TA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.2.1.1 */
- static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_1 = id_TA_RSA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.2.1.2 */
- static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_256 = id_TA_RSA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.2.1.3 */
- static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_1 = id_TA_RSA.branch("3");
- /** OID: 0.4.0.127.0.7.2.2.2.1.4 */
- static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_256 = id_TA_RSA.branch("4");
- /** OID: 0.4.0.127.0.7.2.2.2.1.5 */
- static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_512 = id_TA_RSA.branch("5");
- /** OID: 0.4.0.127.0.7.2.2.2.1.6 */
- static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_512 = id_TA_RSA.branch("6");
- /** OID: 0.4.0.127.0.7.2.2.2.2 */
- static final ASN1ObjectIdentifier id_TA_ECDSA = id_TA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.2.2.1 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_1 = id_TA_ECDSA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.2.2.2 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_224 = id_TA_ECDSA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.2.2.3 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_256 = id_TA_ECDSA.branch("3");
- /** OID: 0.4.0.127.0.7.2.2.2.2.4 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_384 = id_TA_ECDSA.branch("4");
- /** OID: 0.4.0.127.0.7.2.2.2.2.5 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_512 = id_TA_ECDSA.branch("5");
-
- /**
- * <pre>
- * id-EAC-ePassport OBJECT IDENTIFIER ::= {
- * bsi-de applications(3) mrtd(1) roles(2) 1
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.3.1.2.1
- */
- static final ASN1ObjectIdentifier id_EAC_ePassport = bsi_de.branch("3.1.2.1");
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java
index ade6782..d0df5a9 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java
@@ -4,6 +4,8 @@
public interface GMObjectIdentifiers
{
+ //1.2.156.10197: Chinese Cryptography Standardization Technology Committee (CCSTC)
+ //1.2.156.11235: China Broadband Wireless IP Standard Group
ASN1ObjectIdentifier sm_scheme = new ASN1ObjectIdentifier("1.2.156.10197.1");
ASN1ObjectIdentifier sm6_ecb = sm_scheme.branch("101.1");
@@ -46,7 +48,20 @@
ASN1ObjectIdentifier sm2exchange = sm_scheme.branch("301.2");
ASN1ObjectIdentifier sm2encrypt = sm_scheme.branch("301.3");
- ASN1ObjectIdentifier wapip192v1 = sm_scheme.branch("301.101");
+ /**
+ * <Information security technology — Cryptographic application identifier criterion specification>
+ * <url>http://c.gb688.cn/bzgk/gb/showGb?type=online&hcno=252CF0F72A7BE339A56DEA7D774E8994</url>,
+ * Page 21 only cover from 301.1 to 301.3
+ * */
+ ASN1ObjectIdentifier wapip192v1 = sm_scheme.branch("301.101");
+ /**
+ * <WAPI certificate management—Part 5: Example of certificate format (draft)>
+ * <url>http://www.chinabwips.org.cn/zqyjgs1.htm</url> and
+ * <url>http://www.chinabwips.org.cn/doc/101.pdf</url>,
+ * Page 9 and page 10 states the OID of ECDSA-192 algorithm based on SHA-256 is 1.2.156.11235.1.1.1
+ * */
+ ASN1ObjectIdentifier wapi192v1 = new ASN1ObjectIdentifier("1.2.156.11235.1.1.1");
+ ASN1ObjectIdentifier wapi192v1_parameters = new ASN1ObjectIdentifier("1.2.156.11235.1.1.2.1");
ASN1ObjectIdentifier sm2encrypt_recommendedParameters = sm2encrypt.branch("1");
ASN1ObjectIdentifier sm2encrypt_specifiedParameters = sm2encrypt.branch("2");
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java
new file mode 100644
index 0000000..cf46920
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java
@@ -0,0 +1,22 @@
+package org.bouncycastle.asn1.isara;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+public interface IsaraObjectIdentifiers
+{
+ /*
+ id-alg-xmss OBJECT IDENTIFIER ::= { itu-t(0)
+ identified-organization(4) etsi(0) reserved(127)
+ etsi-identified-organization(0) isara(15) algorithms(1)
+ asymmetric(1) xmss(13) 0 }
+ */
+ static ASN1ObjectIdentifier id_alg_xmss = new ASN1ObjectIdentifier("0.4.0.127.0.15.1.1.13.0");
+
+ /*
+ id-alg-xmssmt OBJECT IDENTIFIER ::= { itu-t(0)
+ identified-organization(4) etsi(0) reserved(127)
+ etsi-identified-organization(0) isara(15) algorithms(1)
+ asymmetric(1) xmssmt(14) 0 }
+ */
+ static ASN1ObjectIdentifier id_alg_xmssmt = new ASN1ObjectIdentifier("0.4.0.127.0.15.1.1.14.0");
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
index 89b91d0..195978f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
@@ -124,7 +124,7 @@
ASN1ObjectIdentifier cryptlib_algorithm_blowfish_OFB = cryptlib_algorithm.branch("1.4");
//
- // Blake2b
+ // Blake2b/Blake2s
//
ASN1ObjectIdentifier blake2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.1722.12.2");
@@ -138,6 +138,10 @@
ASN1ObjectIdentifier id_blake2s224 = blake2.branch("2.7");
ASN1ObjectIdentifier id_blake2s256 = blake2.branch("2.8");
+ ASN1ObjectIdentifier blake3 = blake2.branch("3");
+
+ ASN1ObjectIdentifier blake3_256 = blake3.branch("8");
+
//
// Scrypt
ASN1ObjectIdentifier id_scrypt = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.4.11");
@@ -148,4 +152,15 @@
// iso(1) identified-organization(3) dod(6) internet(1) private(4)
// enterprise(1) OpenCA(18227) Algorithms(2) id-alg-composite(1) }
ASN1ObjectIdentifier id_alg_composite = new ASN1ObjectIdentifier("1.3.6.1.4.1.18227.2.1");
+
+ // -- To be replaced by IANA
+ //
+ //id-composite-key OBJECT IDENTIFIER ::= {
+ //
+ // joint-iso-itu-t(2) country(16) us(840) organization(1) entrust(114027)
+ //
+ // Algorithm(80) Composite(4) CompositeKey(1)
+ ASN1ObjectIdentifier id_composite_key = new ASN1ObjectIdentifier("2.16.840.1.114027.80.4.1");
+
+ ASN1ObjectIdentifier id_oracle_pkcs12_trusted_key_usage = new ASN1ObjectIdentifier("2.16.840.1.113894.746875.1.1");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java b/bcprov/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java
index 846a205..761b4c4 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java
@@ -1,5 +1,6 @@
package org.bouncycastle.asn1.misc;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.DERBitString;
/**
@@ -42,13 +43,18 @@
}
public NetscapeCertType(
- DERBitString usage)
+ ASN1BitString usage)
{
super(usage.getBytes(), usage.getPadBits());
}
+ public boolean hasUsages(int usages)
+ {
+ return (intValue() & usages) == usages;
+ }
+
public String toString()
{
- return "NetscapeCertType: 0x" + Integer.toHexString(data[0] & 0xff);
+ return "NetscapeCertType: 0x" + Integer.toHexString(intValue());
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java b/bcprov/src/main/java/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java
index c0347da..1687913 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java
@@ -1,12 +1,13 @@
package org.bouncycastle.asn1.misc;
+import org.bouncycastle.asn1.ASN1IA5String;
import org.bouncycastle.asn1.DERIA5String;
public class NetscapeRevocationURL
extends DERIA5String
{
public NetscapeRevocationURL(
- DERIA5String str)
+ ASN1IA5String str)
{
super(str.getString());
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/misc/VerisignCzagExtension.java b/bcprov/src/main/java/org/bouncycastle/asn1/misc/VerisignCzagExtension.java
index f09880a..db13c31 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/misc/VerisignCzagExtension.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/misc/VerisignCzagExtension.java
@@ -1,12 +1,13 @@
package org.bouncycastle.asn1.misc;
+import org.bouncycastle.asn1.ASN1IA5String;
import org.bouncycastle.asn1.DERIA5String;
public class VerisignCzagExtension
extends DERIA5String
{
public VerisignCzagExtension(
- DERIA5String str)
+ ASN1IA5String str)
{
super(str.getString());
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java b/bcprov/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java
new file mode 100644
index 0000000..129034b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java
@@ -0,0 +1,114 @@
+package org.bouncycastle.asn1.nist;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * KMACwithSHAKE128-params ::= SEQUENCE {
+ * kMACOutputLength INTEGER DEFAULT 256, -- Output length in bits
+ * customizationString OCTET STRING DEFAULT ''H
+ * }
+ * </pre>
+ */
+public class KMACwithSHAKE128_params
+ extends ASN1Object
+{
+ private static final byte[] EMPTY_STRING = new byte[0];
+ private static final int DEF_LENGTH = 256;
+
+ private final int outputLength;
+ private final byte[] customizationString;
+
+ public KMACwithSHAKE128_params(int outputLength)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = EMPTY_STRING;
+ }
+
+ public KMACwithSHAKE128_params(int outputLength, byte[] customizationString)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = Arrays.clone(customizationString);
+ }
+
+ public static KMACwithSHAKE128_params getInstance(Object o)
+ {
+ if (o instanceof KMACwithSHAKE128_params)
+ {
+ return (KMACwithSHAKE128_params)o;
+ }
+ else if (o != null)
+ {
+ return new KMACwithSHAKE128_params(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ private KMACwithSHAKE128_params(ASN1Sequence seq)
+ {
+ if (seq.size() > 2)
+ {
+ throw new IllegalArgumentException("sequence size greater than 2");
+ }
+
+ if (seq.size() == 2)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+ }
+ else if (seq.size() == 1)
+ {
+ if (seq.getObjectAt(0) instanceof ASN1Integer)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = EMPTY_STRING;
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
+ }
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = EMPTY_STRING;
+ }
+ }
+
+ public int getOutputLength()
+ {
+ return outputLength;
+ }
+
+ public byte[] getCustomizationString()
+ {
+ return Arrays.clone(customizationString);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (outputLength != DEF_LENGTH)
+ {
+ v.add(new ASN1Integer(outputLength));
+ }
+
+ if (customizationString.length != 0)
+ {
+ v.add(new DEROctetString(getCustomizationString()));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java b/bcprov/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java
new file mode 100644
index 0000000..390c903
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java
@@ -0,0 +1,114 @@
+package org.bouncycastle.asn1.nist;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * KMACwithSHAKE256-params ::= SEQUENCE {
+ * kMACOutputLength INTEGER DEFAULT 512, -- Output length in bits
+ * customizationString OCTET STRING DEFAULT ''H
+ * }
+ * </pre>
+ */
+public class KMACwithSHAKE256_params
+ extends ASN1Object
+{
+ private static final byte[] EMPTY_STRING = new byte[0];
+ private static final int DEF_LENGTH = 512;
+
+ private final int outputLength;
+ private final byte[] customizationString;
+
+ public KMACwithSHAKE256_params(int outputLength)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = EMPTY_STRING;
+ }
+
+ public KMACwithSHAKE256_params(int outputLength, byte[] customizationString)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = Arrays.clone(customizationString);
+ }
+
+ public static KMACwithSHAKE256_params getInstance(Object o)
+ {
+ if (o instanceof KMACwithSHAKE256_params)
+ {
+ return (KMACwithSHAKE256_params)o;
+ }
+ else if (o != null)
+ {
+ return new KMACwithSHAKE256_params(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ private KMACwithSHAKE256_params(ASN1Sequence seq)
+ {
+ if (seq.size() > 2)
+ {
+ throw new IllegalArgumentException("sequence size greater than 2");
+ }
+
+ if (seq.size() == 2)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+ }
+ else if (seq.size() == 1)
+ {
+ if (seq.getObjectAt(0) instanceof ASN1Integer)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = EMPTY_STRING;
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
+ }
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = EMPTY_STRING;
+ }
+ }
+
+ public int getOutputLength()
+ {
+ return outputLength;
+ }
+
+ public byte[] getCustomizationString()
+ {
+ return Arrays.clone(customizationString);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (outputLength != DEF_LENGTH)
+ {
+ v.add(new ASN1Integer(outputLength));
+ }
+
+ if (customizationString.length != 0)
+ {
+ v.add(new DEROctetString(getCustomizationString()));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTNamedCurves.java b/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTNamedCurves.java
index ba7e518..e2b624a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTNamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTNamedCurves.java
@@ -7,6 +7,7 @@
import org.bouncycastle.asn1.sec.SECNamedCurves;
import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.asn1.x9.X9ECParametersHolder;
import org.bouncycastle.util.Strings;
/**
@@ -42,17 +43,16 @@
defineCurve("P-192", SECObjectIdentifiers.secp192r1);
}
- public static X9ECParameters getByName(
- String name)
+ public static X9ECParameters getByName(String name)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name));
+ ASN1ObjectIdentifier oid = getOID(name);
+ return null != oid ? SECNamedCurves.getByOID(oid) : null;
+ }
- if (oid != null)
- {
- return getByOID(oid);
- }
-
- return null;
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ ASN1ObjectIdentifier oid = getOID(name);
+ return null != oid ? SECNamedCurves.getByOIDLazy(oid) : null;
}
/**
@@ -61,10 +61,14 @@
*
* @param oid an object identifier representing a named curve, if present.
*/
- public static X9ECParameters getByOID(
- ASN1ObjectIdentifier oid)
+ public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- return SECNamedCurves.getByOID(oid);
+ return names.containsKey(oid) ? SECNamedCurves.getByOID(oid) : null;
+ }
+
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return names.containsKey(oid) ? SECNamedCurves.getByOIDLazy(oid) : null;
}
/**
@@ -73,8 +77,7 @@
*
* @return the object identifier associated with name, if present.
*/
- public static ASN1ObjectIdentifier getOID(
- String name)
+ public static ASN1ObjectIdentifier getOID(String name)
{
return (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name));
}
@@ -82,8 +85,7 @@
/**
* return the named curve name represented by the given object identifier.
*/
- public static String getName(
- ASN1ObjectIdentifier oid)
+ public static String getName(ASN1ObjectIdentifier oid)
{
return (String)names.get(oid);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
index 8de357a..572f6f4 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
@@ -58,69 +58,137 @@
/** 2.16.840.1.101.3.4.2.19 */
static final ASN1ObjectIdentifier id_KmacWithSHAKE128 = hashAlgs.branch("19");
/** 2.16.840.1.101.3.4.2.20 */
- static final ASN1ObjectIdentifier id_KmacWithSHAKE256 = hashAlgs.branch("20");
+ static final ASN1ObjectIdentifier id_KmacWithSHAKE256 = hashAlgs.branch("20");
- /** 2.16.840.1.101.3.4.1 */
- static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1");
-
- /** 2.16.840.1.101.3.4.1.1 */
- static final ASN1ObjectIdentifier id_aes128_ECB = aes.branch("1");
- /** 2.16.840.1.101.3.4.1.2 */
- static final ASN1ObjectIdentifier id_aes128_CBC = aes.branch("2");
- /** 2.16.840.1.101.3.4.1.3 */
- static final ASN1ObjectIdentifier id_aes128_OFB = aes.branch("3");
- /** 2.16.840.1.101.3.4.1.4 */
- static final ASN1ObjectIdentifier id_aes128_CFB = aes.branch("4");
- /** 2.16.840.1.101.3.4.1.5 */
- static final ASN1ObjectIdentifier id_aes128_wrap = aes.branch("5");
- /** 2.16.840.1.101.3.4.1.6 */
- static final ASN1ObjectIdentifier id_aes128_GCM = aes.branch("6");
- /** 2.16.840.1.101.3.4.1.7 */
- static final ASN1ObjectIdentifier id_aes128_CCM = aes.branch("7");
- /** 2.16.840.1.101.3.4.1.28 */
- static final ASN1ObjectIdentifier id_aes128_wrap_pad = aes.branch("8");
+ /**
+ * 2.16.840.1.101.3.4.1
+ */
+ static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1");
- /** 2.16.840.1.101.3.4.1.21 */
- static final ASN1ObjectIdentifier id_aes192_ECB = aes.branch("21");
- /** 2.16.840.1.101.3.4.1.22 */
- static final ASN1ObjectIdentifier id_aes192_CBC = aes.branch("22");
- /** 2.16.840.1.101.3.4.1.23 */
- static final ASN1ObjectIdentifier id_aes192_OFB = aes.branch("23");
- /** 2.16.840.1.101.3.4.1.24 */
- static final ASN1ObjectIdentifier id_aes192_CFB = aes.branch("24");
- /** 2.16.840.1.101.3.4.1.25 */
- static final ASN1ObjectIdentifier id_aes192_wrap = aes.branch("25");
- /** 2.16.840.1.101.3.4.1.26 */
- static final ASN1ObjectIdentifier id_aes192_GCM = aes.branch("26");
- /** 2.16.840.1.101.3.4.1.27 */
- static final ASN1ObjectIdentifier id_aes192_CCM = aes.branch("27");
- /** 2.16.840.1.101.3.4.1.28 */
- static final ASN1ObjectIdentifier id_aes192_wrap_pad = aes.branch("28");
+ /**
+ * 2.16.840.1.101.3.4.1.1
+ */
+ static final ASN1ObjectIdentifier id_aes128_ECB = aes.branch("1");
+ /**
+ * 2.16.840.1.101.3.4.1.2
+ */
+ static final ASN1ObjectIdentifier id_aes128_CBC = aes.branch("2");
+ /**
+ * 2.16.840.1.101.3.4.1.3
+ */
+ static final ASN1ObjectIdentifier id_aes128_OFB = aes.branch("3");
+ /**
+ * 2.16.840.1.101.3.4.1.4
+ */
+ static final ASN1ObjectIdentifier id_aes128_CFB = aes.branch("4");
+ /**
+ * 2.16.840.1.101.3.4.1.5
+ */
+ static final ASN1ObjectIdentifier id_aes128_wrap = aes.branch("5");
+ /**
+ * 2.16.840.1.101.3.4.1.6
+ */
+ static final ASN1ObjectIdentifier id_aes128_GCM = aes.branch("6");
+ /**
+ * 2.16.840.1.101.3.4.1.7
+ */
+ static final ASN1ObjectIdentifier id_aes128_CCM = aes.branch("7");
+ /**
+ * 2.16.840.1.101.3.4.1.8
+ */
+ static final ASN1ObjectIdentifier id_aes128_wrap_pad = aes.branch("8");
+ /**
+ * 2.16.840.1.101.3.4.1.9
+ */
+ static final ASN1ObjectIdentifier id_aes128_GMAC = aes.branch("9");
- /** 2.16.840.1.101.3.4.1.41 */
- static final ASN1ObjectIdentifier id_aes256_ECB = aes.branch("41");
- /** 2.16.840.1.101.3.4.1.42 */
- static final ASN1ObjectIdentifier id_aes256_CBC = aes.branch("42");
- /** 2.16.840.1.101.3.4.1.43 */
- static final ASN1ObjectIdentifier id_aes256_OFB = aes.branch("43");
- /** 2.16.840.1.101.3.4.1.44 */
- static final ASN1ObjectIdentifier id_aes256_CFB = aes.branch("44");
- /** 2.16.840.1.101.3.4.1.45 */
- static final ASN1ObjectIdentifier id_aes256_wrap = aes.branch("45");
- /** 2.16.840.1.101.3.4.1.46 */
- static final ASN1ObjectIdentifier id_aes256_GCM = aes.branch("46");
- /** 2.16.840.1.101.3.4.1.47 */
- static final ASN1ObjectIdentifier id_aes256_CCM = aes.branch("47");
- /** 2.16.840.1.101.3.4.1.48 */
- static final ASN1ObjectIdentifier id_aes256_wrap_pad = aes.branch("48");
+
+ /**
+ * 2.16.840.1.101.3.4.1.21
+ */
+ static final ASN1ObjectIdentifier id_aes192_ECB = aes.branch("21");
+ /**
+ * 2.16.840.1.101.3.4.1.22
+ */
+ static final ASN1ObjectIdentifier id_aes192_CBC = aes.branch("22");
+ /**
+ * 2.16.840.1.101.3.4.1.23
+ */
+ static final ASN1ObjectIdentifier id_aes192_OFB = aes.branch("23");
+ /**
+ * 2.16.840.1.101.3.4.1.24
+ */
+ static final ASN1ObjectIdentifier id_aes192_CFB = aes.branch("24");
+ /**
+ * 2.16.840.1.101.3.4.1.25
+ */
+ static final ASN1ObjectIdentifier id_aes192_wrap = aes.branch("25");
+ /**
+ * 2.16.840.1.101.3.4.1.26
+ */
+ static final ASN1ObjectIdentifier id_aes192_GCM = aes.branch("26");
+ /**
+ * 2.16.840.1.101.3.4.1.27
+ */
+ static final ASN1ObjectIdentifier id_aes192_CCM = aes.branch("27");
+ /**
+ * 2.16.840.1.101.3.4.1.28
+ */
+ static final ASN1ObjectIdentifier id_aes192_wrap_pad = aes.branch("28");
+
+ /**
+ * 2.16.840.1.101.3.4.1.29
+ */
+ static final ASN1ObjectIdentifier id_aes192_GMAC = aes.branch("29");
+
+
+ /**
+ * 2.16.840.1.101.3.4.1.41
+ */
+ static final ASN1ObjectIdentifier id_aes256_ECB = aes.branch("41");
+ /**
+ * 2.16.840.1.101.3.4.1.42
+ */
+ static final ASN1ObjectIdentifier id_aes256_CBC = aes.branch("42");
+ /**
+ * 2.16.840.1.101.3.4.1.43
+ */
+ static final ASN1ObjectIdentifier id_aes256_OFB = aes.branch("43");
+ /**
+ * 2.16.840.1.101.3.4.1.44
+ */
+ static final ASN1ObjectIdentifier id_aes256_CFB = aes.branch("44");
+ /**
+ * 2.16.840.1.101.3.4.1.45
+ */
+ static final ASN1ObjectIdentifier id_aes256_wrap = aes.branch("45");
+ /**
+ * 2.16.840.1.101.3.4.1.46
+ */
+ static final ASN1ObjectIdentifier id_aes256_GCM = aes.branch("46");
+ /**
+ * 2.16.840.1.101.3.4.1.47
+ */
+ static final ASN1ObjectIdentifier id_aes256_CCM = aes.branch("47");
+ /**
+ * 2.16.840.1.101.3.4.1.48
+ */
+ static final ASN1ObjectIdentifier id_aes256_wrap_pad = aes.branch("48");
+ /**
+ * 2.16.840.1.101.3.4.1.49
+ */
+ static final ASN1ObjectIdentifier id_aes256_GMAC = aes.branch("49");
+
//
// signatures
//
- /** 2.16.840.1.101.3.4.3 */
- static final ASN1ObjectIdentifier sigAlgs = nistAlgorithm.branch("3");
+ /**
+ * 2.16.840.1.101.3.4.3
+ */
+ static final ASN1ObjectIdentifier sigAlgs = nistAlgorithm.branch("3");
- static final ASN1ObjectIdentifier id_dsa_with_sha2 = sigAlgs;
+ static final ASN1ObjectIdentifier id_dsa_with_sha2 = sigAlgs;
/** 2.16.840.1.101.3.4.3.1 */
static final ASN1ObjectIdentifier dsa_with_sha224 = sigAlgs.branch("1");
@@ -150,12 +218,12 @@
static final ASN1ObjectIdentifier id_ecdsa_with_sha3_512 = sigAlgs.branch("12");
// RSA PKCS #1 v1.5 Signature with SHA-3 family.
- /** 2.16.840.1.101.3.4.3.9 */
+ /** 2.16.840.1.101.3.4.3.13 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_224 = sigAlgs.branch("13");
- /** 2.16.840.1.101.3.4.3.10 */
+ /** 2.16.840.1.101.3.4.3.14 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_256 = sigAlgs.branch("14");
- /** 2.16.840.1.101.3.4.3.11 */
+ /** 2.16.840.1.101.3.4.3.15 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_384 = sigAlgs.branch("15");
- /** 2.16.840.1.101.3.4.3.12 */
+ /** 2.16.840.1.101.3.4.3.16 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_512 = sigAlgs.branch("16");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java
index e471149..ed1eec6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java
@@ -2,9 +2,11 @@
import org.bouncycastle.asn1.ASN1Choice;
import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Null;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.ASN1Util;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERTaggedObject;
@@ -42,22 +44,25 @@
private CertStatus(
ASN1TaggedObject choice)
{
- this.tagNo = choice.getTagNo();
+ int tagNo = choice.getTagNo();
- switch (choice.getTagNo())
+ switch (tagNo)
{
case 0:
- value = DERNull.INSTANCE;
+ value = ASN1Null.getInstance(choice, false);
break;
case 1:
value = RevokedInfo.getInstance(choice, false);
break;
case 2:
- value = DERNull.INSTANCE;
+ // UnknownInfo ::= NULL
+ value = ASN1Null.getInstance(choice, false);
break;
default:
- throw new IllegalArgumentException("Unknown tag encountered: " + choice.getTagNo());
+ throw new IllegalArgumentException("Unknown tag encountered: " + ASN1Util.getTagText(choice));
}
+
+ this.tagNo = tagNo;
}
public static CertStatus getInstance(
@@ -79,7 +84,7 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ return getInstance(obj.getExplicitBaseTagged()); // must be explicitly tagged
}
public int getTagNo()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CrlID.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CrlID.java
index b9f5d7c..49afce6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CrlID.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CrlID.java
@@ -4,6 +4,7 @@
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
+import org.bouncycastle.asn1.ASN1IA5String;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
@@ -16,7 +17,7 @@
public class CrlID
extends ASN1Object
{
- private DERIA5String crlUrl;
+ private ASN1IA5String crlUrl;
private ASN1Integer crlNum;
private ASN1GeneralizedTime crlTime;
@@ -32,7 +33,7 @@
switch (o.getTagNo())
{
case 0:
- crlUrl = DERIA5String.getInstance(o, true);
+ crlUrl = ASN1IA5String.getInstance(o, true);
break;
case 1:
crlNum = ASN1Integer.getInstance(o, true);
@@ -62,8 +63,18 @@
return null;
}
+ /**
+ * @deprecated Use {@link #getCrlUrlIA5()} instead.
+ */
public DERIA5String getCrlUrl()
{
+ return null == crlUrl || crlUrl instanceof DERIA5String
+ ? (DERIA5String)crlUrl
+ : new DERIA5String(crlUrl.getString(), false);
+ }
+
+ public ASN1IA5String getCrlUrlIA5()
+ {
return crlUrl;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponderID.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponderID.java
index 9719047..c851d79 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponderID.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponderID.java
@@ -60,7 +60,12 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
+ return getInstance(obj.getExplicitBaseObject());
}
public byte[] getKeyHash()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseBytes.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseBytes.java
index ec6d926..eaeaa60 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseBytes.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseBytes.java
@@ -31,10 +31,7 @@
this.response = response;
}
- /**
- * @deprecated use getInstance()
- */
- public ResponseBytes(
+ private ResponseBytes(
ASN1Sequence seq)
{
responseType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/RevokedInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/RevokedInfo.java
index 2976d4b..9a6e666 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/RevokedInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/RevokedInfo.java
@@ -17,6 +17,11 @@
private ASN1GeneralizedTime revocationTime;
private CRLReason revocationReason;
+ public RevokedInfo(ASN1GeneralizedTime revocationTime)
+ {
+ this(revocationTime, null);
+ }
+
public RevokedInfo(
ASN1GeneralizedTime revocationTime,
CRLReason revocationReason)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
index 47e1a54..1bb92f5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
@@ -22,8 +22,8 @@
private CRLBag(
ASN1Sequence seq)
{
- this.crlId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
- this.crlValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject();
+ this.crlId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ this.crlValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
}
public static CRLBag getInstance(Object o)
@@ -67,7 +67,7 @@
*
* x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}
* -- DER-encoded X.509 CRL stored in OCTET STRING
- *
+ *
* CRLTypes BAG-TYPE ::= {
* x509CRL,
* ... -- For future extensions
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java
index f43f472..87f03de 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java
@@ -20,7 +20,7 @@
ASN1Sequence seq)
{
this.certId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
- this.certValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject();
+ this.certValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
}
public static CertBag getInstance(Object o)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java
index 13587f8..2dbc10c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java
@@ -1,5 +1,6 @@
package org.bouncycastle.asn1.pkcs;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
@@ -23,7 +24,7 @@
{
protected CertificationRequestInfo reqInfo = null;
protected AlgorithmIdentifier sigAlgId = null;
- protected DERBitString sigBits = null;
+ protected ASN1BitString sigBits = null;
public static CertificationRequest getInstance(Object o)
{
@@ -47,7 +48,7 @@
public CertificationRequest(
CertificationRequestInfo requestInfo,
AlgorithmIdentifier algorithm,
- DERBitString signature)
+ ASN1BitString signature)
{
this.reqInfo = requestInfo;
this.sigAlgId = algorithm;
@@ -75,7 +76,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sigBits;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
index 11fdf6c..b092bb8 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
@@ -97,10 +97,7 @@
this(X500Name.getInstance(subject.toASN1Primitive()), pkInfo, attributes);
}
- /**
- * @deprecated use getInstance().
- */
- public CertificationRequestInfo(
+ private CertificationRequestInfo(
ASN1Sequence seq)
{
version = (ASN1Integer)seq.getObjectAt(0);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java
index a7b2bc7..d28e942 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java
@@ -46,7 +46,7 @@
if (e.hasMoreElements())
{
- content = ((ASN1TaggedObject)e.nextElement()).getObject();
+ content = ((ASN1TaggedObject)e.nextElement()).getExplicitBaseObject();
}
isBer = seq instanceof BERSequence;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java
index e4d449b..8faafe5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java
@@ -55,9 +55,8 @@
private EncryptedData(
ASN1Sequence seq)
{
- int version = ((ASN1Integer)seq.getObjectAt(0)).intValueExact();
-
- if (version != 0)
+ ASN1Integer version = (ASN1Integer)seq.getObjectAt(0);
+ if (!version.hasValue(0))
{
throw new IllegalArgumentException("sequence not version 0");
}
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 82645ae..cc16037 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
@@ -10,6 +10,7 @@
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.util.Arrays;
public class EncryptedPrivateKeyInfo
extends ASN1Object
@@ -31,7 +32,7 @@
byte[] encoding)
{
this.algId = algId;
- this.data = new DEROctetString(encoding);
+ this.data = new DEROctetString(Arrays.clone(encoding));
}
public static EncryptedPrivateKeyInfo getInstance(
@@ -56,7 +57,7 @@
public byte[] getEncryptedData()
{
- return data.getOctets();
+ return Arrays.clone(data.getOctets());
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
index 58fa82b..a59d16c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
@@ -183,7 +183,7 @@
*/
public byte[] getSalt()
{
- return octStr.getOctets();
+ return Arrays.clone(octStr.getOctets());
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBMAC1Params.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBMAC1Params.java
new file mode 100644
index 0000000..fdbaefd
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBMAC1Params.java
@@ -0,0 +1,88 @@
+package org.bouncycastle.asn1.pkcs;
+
+import java.util.Enumeration;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+
+/**
+ * From https://datatracker.ietf.org/doc/html/rfc8018
+ *
+ * <pre>
+ * PBMAC1-params ::= SEQUENCE {
+ * keyDerivationFunc AlgorithmIdentifier {{PBMAC1-KDFs}},
+ * messageAuthScheme AlgorithmIdentifier {{PBMAC1-MACs}} }
+ * </pre>
+ */
+public class PBMAC1Params
+ extends ASN1Object
+ implements PKCSObjectIdentifiers
+{
+ private AlgorithmIdentifier func;
+ private AlgorithmIdentifier scheme;
+
+ public static PBMAC1Params getInstance(
+ Object obj)
+ {
+ if (obj instanceof PBMAC1Params)
+ {
+ return (PBMAC1Params)obj;
+ }
+ if (obj != null)
+ {
+ return new PBMAC1Params(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public PBMAC1Params(AlgorithmIdentifier keyDevFunc, AlgorithmIdentifier encScheme)
+ {
+ this.func = keyDevFunc;
+ this.scheme = encScheme;
+ }
+
+ private PBMAC1Params(
+ ASN1Sequence obj)
+ {
+ Enumeration e = obj.getObjects();
+ ASN1Sequence funcSeq = ASN1Sequence.getInstance(((ASN1Encodable)e.nextElement()).toASN1Primitive());
+
+ if (funcSeq.getObjectAt(0).equals(id_PBKDF2))
+ {
+ func = new AlgorithmIdentifier(id_PBKDF2, PBKDF2Params.getInstance(funcSeq.getObjectAt(1)));
+ }
+ else
+ {
+ func = AlgorithmIdentifier.getInstance(funcSeq);
+ }
+
+ scheme = AlgorithmIdentifier.getInstance(e.nextElement());
+ }
+
+ public AlgorithmIdentifier getKeyDerivationFunc()
+ {
+ return func;
+ }
+
+ public AlgorithmIdentifier getMessageAuthScheme()
+ {
+ return scheme;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(func);
+ v.add(scheme);
+
+ return new DERSequence(v);
+ }
+}
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 7cf720f..057d825 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
@@ -76,10 +76,12 @@
ASN1ObjectIdentifier pbeWithSHA1AndDES_CBC = pkcs_5.branch("10");
/** PKCS#5: 1.2.840.113549.1.5.11 */
ASN1ObjectIdentifier pbeWithSHA1AndRC2_CBC = pkcs_5.branch("11");
- /** PKCS#5: 1.2.840.113549.1.5.13 */
- ASN1ObjectIdentifier id_PBES2 = pkcs_5.branch("13");
/** PKCS#5: 1.2.840.113549.1.5.12 */
ASN1ObjectIdentifier id_PBKDF2 = pkcs_5.branch("12");
+ /** PKCS#5: 1.2.840.113549.1.5.13 */
+ ASN1ObjectIdentifier id_PBES2 = pkcs_5.branch("13");
+ /** PKCS#5: 1.2.840.113549.1.5.14 */
+ ASN1ObjectIdentifier id_PBMAC1 = pkcs_5.branch("14");
//
// encryptionAlgorithm OBJECT IDENTIFIER ::= {
@@ -135,6 +137,10 @@
ASN1ObjectIdentifier id_hmacWithSHA384 = digestAlgorithm.branch("10").intern();
/** 1.2.840.113549.2.11 */
ASN1ObjectIdentifier id_hmacWithSHA512 = digestAlgorithm.branch("11").intern();
+ /** 1.2.840.113549.2.12 */
+ ASN1ObjectIdentifier id_hmacWithSHA512_224 = digestAlgorithm.branch("12").intern();
+ /** 1.2.840.113549.2.13 */
+ ASN1ObjectIdentifier id_hmacWithSHA512_256 = digestAlgorithm.branch("13").intern();
//
// pkcs-7 OBJECT IDENTIFIER ::= {
@@ -189,6 +195,8 @@
ASN1ObjectIdentifier pkcs_9_at_smimeCapabilities = pkcs_9.branch("15").intern();
/** PKCS#9: 1.2.840.113549.1.9.16 */
ASN1ObjectIdentifier id_smime = pkcs_9.branch("16").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.46 */
+ ASN1ObjectIdentifier pkcs_9_at_binarySigningTime = pkcs_9.branch("16.2.46").intern();
/** PKCS#9: 1.2.840.113549.1.9.20 */
ASN1ObjectIdentifier pkcs_9_at_friendlyName = pkcs_9.branch("20").intern();
@@ -247,8 +255,20 @@
/** S/MIME: Algorithm Identifiers ; 1.2.840.113549.1.9.16.3 */
ASN1ObjectIdentifier id_alg = id_smime.branch("3");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.5 */
+ ASN1ObjectIdentifier id_alg_ESDH = id_alg.branch("5");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.6 */
+ ASN1ObjectIdentifier id_alg_CMS3DESwrap = id_alg.branch("6");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.7 */
+ ASN1ObjectIdentifier id_alg_CMSRC2wrap = id_alg.branch("7");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.8 */
+ ASN1ObjectIdentifier id_alg_zlibCompress = id_alg.branch("8");
/** PKCS#9: 1.2.840.113549.1.9.16.3.9 */
- ASN1ObjectIdentifier id_alg_PWRI_KEK = id_alg.branch("9");
+ ASN1ObjectIdentifier id_alg_PWRI_KEK = id_alg.branch("9");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.10 */
+ ASN1ObjectIdentifier id_alg_SSDH = id_alg.branch("10");
+
/**
* <pre>
* -- RSA-KEM Key Transport Algorithm RFC 5990
@@ -466,14 +486,5 @@
* @deprecated use pbeWithSHAAnd40BitRC2_CBC
*/
ASN1ObjectIdentifier pbewithSHAAnd40BitRC2_CBC = pkcs_12PbeIds.branch("6");
-
- /** PKCS#9: 1.2.840.113549.1.9.16.3.6 */
- ASN1ObjectIdentifier id_alg_CMS3DESwrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.6");
- /** PKCS#9: 1.2.840.113549.1.9.16.3.7 */
- ASN1ObjectIdentifier id_alg_CMSRC2wrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.7");
- /** PKCS#9: 1.2.840.113549.1.9.16.3.5 */
- ASN1ObjectIdentifier id_alg_ESDH = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.5");
- /** PKCS#9: 1.2.840.113549.1.9.16.3.10 */
- ASN1ObjectIdentifier id_alg_SSDH = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.10");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java
index 5954313..8d51197 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java
@@ -21,7 +21,7 @@
ASN1Sequence seq)
{
ASN1Integer version = ASN1Integer.getInstance(seq.getObjectAt(0));
- if (version.intValueExact() != 3)
+ if (!version.hasValue(3))
{
throw new IllegalArgumentException("wrong version for PFX PDU");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
index 9ac8c5e..2a78c1f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
@@ -164,7 +164,7 @@
throw new IllegalArgumentException("'publicKey' requires version v2(1) or later");
}
- this.publicKey = DERBitString.getInstance(tagged, false);
+ this.publicKey = ASN1BitString.getInstance(tagged, false);
break;
}
default:
@@ -195,6 +195,11 @@
return new DEROctetString(privateKey.getOctets());
}
+ public int getPrivateKeyLength()
+ {
+ return privateKey.getOctetsLength();
+ }
+
public ASN1Encodable parsePrivateKey()
throws IOException
{
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 9e5c364..45b93fc 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
@@ -58,11 +58,7 @@
this.pSourceAlgorithm = pSourceAlgorithm;
}
- /**
- * @deprecated use getInstance()
- * @param seq
- */
- public RSAESOAEPparams(
+ private RSAESOAEPparams(
ASN1Sequence seq)
{
hashAlgorithm = DEFAULT_HASH_ALGORITHM;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java
index 1d39416..d6b508e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java
@@ -57,7 +57,7 @@
ASN1Sequence seq)
{
this.bagId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
- this.bagValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject();
+ this.bagValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getExplicitBaseObject();
if (seq.size() == 3)
{
this.bagAttributes = (ASN1Set)seq.getObjectAt(2);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java
index d6e9d47..d37769f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java
@@ -3,6 +3,7 @@
import java.math.BigInteger;
import java.util.Enumeration;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
@@ -11,7 +12,7 @@
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERBitString;
+import org.bouncycastle.asn1.BERTags;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
@@ -91,7 +92,7 @@
*/
public ECPrivateKey(
BigInteger key,
- DERBitString publicKey,
+ ASN1BitString publicKey,
ASN1Encodable parameters)
{
this(key.bitLength(), key, publicKey, parameters);
@@ -108,7 +109,7 @@
public ECPrivateKey(
int orderBitLength,
BigInteger key,
- DERBitString publicKey,
+ ASN1BitString publicKey,
ASN1Encodable parameters)
{
byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key);
@@ -137,18 +138,27 @@
return new BigInteger(1, octs.getOctets());
}
-
- public DERBitString getPublicKey()
+
+ public ASN1BitString getPublicKey()
{
- return (DERBitString)getObjectInTag(1);
+ return (ASN1BitString)getObjectInTag(1, BERTags.BIT_STRING);
}
+ /**
+ * @deprecated Use {@link #getParametersObject()} instead and getInstance
+ * methods or similar to get the object at the desired type.
+ */
public ASN1Primitive getParameters()
{
- return getObjectInTag(0);
+ return getParametersObject().toASN1Primitive();
}
- private ASN1Primitive getObjectInTag(int tagNo)
+ public ASN1Object getParametersObject()
+ {
+ return getObjectInTag(0, -1);
+ }
+
+ private ASN1Object getObjectInTag(int tagNo, int baseTagNo)
{
Enumeration e = seq.getObjects();
@@ -159,9 +169,11 @@
if (obj instanceof ASN1TaggedObject)
{
ASN1TaggedObject tag = (ASN1TaggedObject)obj;
- if (tag.getTagNo() == tagNo)
+ if (tag.hasContextTag(tagNo))
{
- return tag.getObject().toASN1Primitive();
+ return baseTagNo < 0
+ ? tag.getExplicitBaseObject().toASN1Primitive()
+ : tag.getBaseUniversal(true, baseTagNo);
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java b/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
index d163987..5c33b1e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
@@ -3,6 +3,7 @@
import java.math.BigInteger;
import java.util.Enumeration;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
@@ -11,7 +12,6 @@
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
@@ -54,7 +54,7 @@
public ECPrivateKeyStructure(
BigInteger key,
- DERBitString publicKey,
+ ASN1BitString publicKey,
ASN1Encodable parameters)
{
byte[] bytes = BigIntegers.asUnsignedByteArray(key);
@@ -84,9 +84,9 @@
return new BigInteger(1, octs.getOctets());
}
- public DERBitString getPublicKey()
+ public ASN1BitString getPublicKey()
{
- return (DERBitString)getObjectInTag(1);
+ return (ASN1BitString)getObjectInTag(1);
}
public ASN1Primitive getParameters()
@@ -107,7 +107,7 @@
ASN1TaggedObject tag = (ASN1TaggedObject)obj;
if (tag.getTagNo() == tagNo)
{
- return (ASN1Primitive)((ASN1Encodable)tag.getObject()).toASN1Primitive();
+ return (ASN1Primitive)((ASN1Encodable)tag.getExplicitBaseObject()).toASN1Primitive();
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java b/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java
index 03c09c4..92dfd32 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java
@@ -46,22 +46,27 @@
*/
static X9ECParametersHolder secp112r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = (2^128 - 3) / 76439
BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
BigInteger a = fromHex("DB7C2ABF62E35E668076BEAD2088");
BigInteger b = fromHex("659EF8BA043916EEDE8911702B22");
- byte[] S = Hex.decodeStrict("00F50B028E4D696E676875615175290472783FB1");
BigInteger n = fromHex("DB7C2ABF62E35E7628DFAC6561C5");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("00F50B028E4D696E676875615175290472783FB1");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -70,22 +75,27 @@
*/
static X9ECParametersHolder secp112r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = (2^128 - 3) / 76439
BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
BigInteger a = fromHex("6127C24C05F38A0AAAF65C0EF02C");
BigInteger b = fromHex("51DEF1815DB5ED74FCC34C85D709");
- byte[] S = Hex.decodeStrict("002757A1114D696E6768756151755316C05E0BD4");
BigInteger n = fromHex("36DF0AAFD8B8D7597CA10520D04B");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("002757A1114D696E6768756151755316C05E0BD4");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -94,22 +104,27 @@
*/
static X9ECParametersHolder secp128r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^128 - 2^97 - 1
BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("E87579C11079F43DD824993C2CEE5ED3");
- byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
BigInteger n = fromHex("FFFFFFFE0000000075A30D1B9038A115");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -118,22 +133,27 @@
*/
static X9ECParametersHolder secp128r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^128 - 2^97 - 1
BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("D6031998D1B3BBFEBF59CC9BBFF9AEE1");
BigInteger b = fromHex("5EEEFCA380D02919DC2C6558BB6D8A5D");
- byte[] S = Hex.decodeStrict("004D696E67687561517512D8F03431FCE63B88F4");
BigInteger n = fromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("004D696E67687561517512D8F03431FCE63B88F4");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -142,13 +162,12 @@
*/
static X9ECParametersHolder secp160k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(7);
- byte[] S = null;
BigInteger n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3");
BigInteger h = BigInteger.valueOf(1);
@@ -166,12 +185,18 @@
new BigInteger("96341f1138933bc2f503fd44", 16),
176));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -180,22 +205,27 @@
*/
static X9ECParametersHolder secp160r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^160 - 2^31 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC");
BigInteger b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45");
- byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
BigInteger n = fromHex("0100000000000000000001F4C8F927AED3CA752257");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -204,22 +234,27 @@
*/
static X9ECParametersHolder secp160r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70");
BigInteger b = fromHex("B4E134D3FB59EB8BAB57274904664D5AF50388BA");
- byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
BigInteger n = fromHex("0100000000000000000000351EE786A818F3A1A16B");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -228,13 +263,12 @@
*/
static X9ECParametersHolder secp192k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(3);
- byte[] S = null;
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D");
BigInteger h = BigInteger.valueOf(1);
@@ -252,12 +286,18 @@
new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
208));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -266,22 +306,27 @@
*/
static X9ECParametersHolder secp192r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^192 - 2^64 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1");
- byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -290,13 +335,12 @@
*/
static X9ECParametersHolder secp224k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(5);
- byte[] S = null;
BigInteger n = fromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
BigInteger h = BigInteger.valueOf(1);
@@ -314,12 +358,18 @@
new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
240));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -328,22 +378,27 @@
*/
static X9ECParametersHolder secp224r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^224 - 2^96 + 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE");
BigInteger b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4");
- byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -352,13 +407,12 @@
*/
static X9ECParametersHolder secp256k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(7);
- byte[] S = null;
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
BigInteger h = BigInteger.valueOf(1);
@@ -376,12 +430,18 @@
new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
272));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -390,22 +450,27 @@
*/
static X9ECParametersHolder secp256r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1
BigInteger p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B");
- byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -414,23 +479,28 @@
*/
static X9ECParametersHolder secp384r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^384 - 2^128 - 2^96 + 2^32 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC");
BigInteger b = fromHex("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF");
- byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -439,23 +509,28 @@
*/
static X9ECParametersHolder secp521r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^521 - 1
BigInteger p = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00");
- byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
+ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -464,23 +539,28 @@
*/
static X9ECParametersHolder sect113r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 113;
int k = 9;
BigInteger a = fromHex("003088250CA6E7C7FE649CE85820F7");
BigInteger b = fromHex("00E8BEE4D3E2260744188BE0E9C723");
- byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
BigInteger n = fromHex("0100000000000000D9CCEC8A39E56F");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -489,23 +569,28 @@
*/
static X9ECParametersHolder sect113r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 113;
int k = 9;
BigInteger a = fromHex("00689918DBEC7E5A0DD6DFC0AA55C7");
BigInteger b = fromHex("0095E9A9EC9B297BD4BF36E059184F");
- byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
BigInteger n = fromHex("010000000000000108789B2496AF93");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -514,7 +599,7 @@
*/
static X9ECParametersHolder sect131r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 131;
int k1 = 2;
@@ -523,16 +608,21 @@
BigInteger a = fromHex("07A11B09A76B562144418FF3FF8C2570B8");
BigInteger b = fromHex("0217C05610884B63B9C6C7291678F9D341");
- byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
BigInteger n = fromHex("0400000000000000023123953A9464B54D");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -541,7 +631,7 @@
*/
static X9ECParametersHolder sect131r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 131;
int k1 = 2;
@@ -550,16 +640,21 @@
BigInteger a = fromHex("03E5A88919D7CAFCBF415F07C2176573B2");
BigInteger b = fromHex("04B8266A46C55657AC734CE38F018F2192");
- byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
BigInteger n = fromHex("0400000000000000016954A233049BA98F");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -568,7 +663,7 @@
*/
static X9ECParametersHolder sect163k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 163;
int k1 = 3;
@@ -577,16 +672,21 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("04000000000000000000020108A2E0CC0D99F8A5EF");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -595,7 +695,7 @@
*/
static X9ECParametersHolder sect163r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 163;
int k1 = 3;
@@ -604,16 +704,21 @@
BigInteger a = fromHex("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2");
BigInteger b = fromHex("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9");
- byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -622,7 +727,7 @@
*/
static X9ECParametersHolder sect163r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 163;
int k1 = 3;
@@ -631,16 +736,21 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("020A601907B8C953CA1481EB10512F78744A3205FD");
- byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
BigInteger n = fromHex("040000000000000000000292FE77E70C12A4234C33");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -649,23 +759,28 @@
*/
static X9ECParametersHolder sect193r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 193;
int k = 15;
BigInteger a = fromHex("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01");
BigInteger b = fromHex("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814");
- byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
BigInteger n = fromHex("01000000000000000000000000C7F34A778F443ACC920EBA49");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -674,23 +789,28 @@
*/
static X9ECParametersHolder sect193r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 193;
int k = 15;
BigInteger a = fromHex("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B");
BigInteger b = fromHex("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE");
- byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
BigInteger n = fromHex("010000000000000000000000015AAB561B005413CCD4EE99D5");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -699,23 +819,28 @@
*/
static X9ECParametersHolder sect233k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 233;
int k = 74;
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -724,23 +849,28 @@
*/
static X9ECParametersHolder sect233r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 233;
int k = 74;
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD");
- byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
BigInteger n = fromHex("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -749,23 +879,28 @@
*/
static X9ECParametersHolder sect239k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 239;
int k = 158;
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -774,7 +909,7 @@
*/
static X9ECParametersHolder sect283k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 283;
int k1 = 5;
@@ -783,17 +918,22 @@
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
+ "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -802,7 +942,7 @@
*/
static X9ECParametersHolder sect283r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 283;
int k1 = 5;
@@ -811,17 +951,22 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5");
- byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
+ "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -830,24 +975,29 @@
*/
static X9ECParametersHolder sect409k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 409;
int k = 87;
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
+ "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -856,24 +1006,29 @@
*/
static X9ECParametersHolder sect409r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 409;
int k = 87;
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F");
- byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
BigInteger n = fromHex("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
+ "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -882,7 +1037,7 @@
*/
static X9ECParametersHolder sect571k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 571;
int k1 = 2;
@@ -891,17 +1046,22 @@
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
+ "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -910,7 +1070,7 @@
*/
static X9ECParametersHolder sect571r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 571;
int k1 = 2;
@@ -919,17 +1079,22 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A");
- byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
+ "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -983,26 +1148,35 @@
defineCurve("sect571r1", SECObjectIdentifiers.sect571r1, sect571r1);
}
- public static X9ECParameters getByName(
- String name)
+ public static X9ECParameters getByName(String name)
{
ASN1ObjectIdentifier oid = getOID(name);
return oid == null ? null : getByOID(oid);
}
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOIDLazy(oid);
+ }
+
/**
* return the X9ECParameters object for the named curve represented by
* the passed in object identifier. Null if the curve isn't present.
*
* @param oid an object identifier representing a named curve, if present.
*/
- public static X9ECParameters getByOID(
- ASN1ObjectIdentifier oid)
+ public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid);
+ X9ECParametersHolder holder = getByOIDLazy(oid);
return holder == null ? null : holder.getParameters();
}
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return (X9ECParametersHolder)curves.get(oid);
+ }
+
/**
* return the object identifier signified by the passed in name. Null
* if there is no object identifier associated with name.
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 a8e07fe..4ff5e2d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
@@ -1,42 +1,41 @@
package org.bouncycastle.asn1.util;
-import java.io.IOException;
-import java.util.Enumeration;
-
-import org.bouncycastle.asn1.ASN1ApplicationSpecific;
+import org.bouncycastle.asn1.ASN1BMPString;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Boolean;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Enumerated;
import org.bouncycastle.asn1.ASN1External;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
+import org.bouncycastle.asn1.ASN1GraphicString;
+import org.bouncycastle.asn1.ASN1IA5String;
import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Null;
+import org.bouncycastle.asn1.ASN1NumericString;
+import org.bouncycastle.asn1.ASN1ObjectDescriptor;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1PrintableString;
+import org.bouncycastle.asn1.ASN1RelativeOID;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
+import org.bouncycastle.asn1.ASN1T61String;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.ASN1UTCTime;
-import org.bouncycastle.asn1.BERApplicationSpecific;
+import org.bouncycastle.asn1.ASN1UTF8String;
+import org.bouncycastle.asn1.ASN1Util;
+import org.bouncycastle.asn1.ASN1VideotexString;
+import org.bouncycastle.asn1.ASN1VisibleString;
import org.bouncycastle.asn1.BEROctetString;
import org.bouncycastle.asn1.BERSequence;
import org.bouncycastle.asn1.BERSet;
import org.bouncycastle.asn1.BERTaggedObject;
-import org.bouncycastle.asn1.BERTags;
-import org.bouncycastle.asn1.DERApplicationSpecific;
-import org.bouncycastle.asn1.DERBMPString;
import org.bouncycastle.asn1.DERBitString;
-import org.bouncycastle.asn1.DERGraphicString;
-import org.bouncycastle.asn1.DERIA5String;
-import org.bouncycastle.asn1.DERNull;
-import org.bouncycastle.asn1.DERPrintableString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERSet;
-import org.bouncycastle.asn1.DERT61String;
-import org.bouncycastle.asn1.DERUTF8String;
-import org.bouncycastle.asn1.DERVideotexString;
-import org.bouncycastle.asn1.DERVisibleString;
-import org.bouncycastle.asn1.DLApplicationSpecific;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.DLBitString;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
@@ -60,11 +59,14 @@
StringBuffer buf)
{
String nl = Strings.lineSeparator();
- if (obj instanceof ASN1Sequence)
+ if (obj instanceof ASN1Null)
{
- Enumeration e = ((ASN1Sequence)obj).getObjects();
- String tab = indent + TAB;
-
+ buf.append(indent);
+ buf.append("NULL");
+ buf.append(nl);
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
buf.append(indent);
if (obj instanceof BERSequence)
{
@@ -78,64 +80,19 @@
{
buf.append("Sequence");
}
-
buf.append(nl);
- while (e.hasMoreElements())
+ ASN1Sequence sequence = (ASN1Sequence)obj;
+ String elementsIndent = indent + TAB;
+
+ for (int i = 0, count = sequence.size(); i < count; ++i)
{
- Object o = e.nextElement();
-
- if (o == null || o.equals(DERNull.INSTANCE))
- {
- 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);
- }
+ _dumpAsString(elementsIndent, verbose, sequence.getObjectAt(i).toASN1Primitive(), buf);
}
}
- else if (obj instanceof ASN1TaggedObject)
- {
- String tab = indent + TAB;
-
- buf.append(indent);
- if (obj instanceof BERTaggedObject)
- {
- buf.append("BER Tagged [");
- }
- else
- {
- buf.append("Tagged [");
- }
-
- ASN1TaggedObject o = (ASN1TaggedObject)obj;
-
- buf.append(Integer.toString(o.getTagNo()));
- buf.append(']');
-
- if (!o.isExplicit())
- {
- buf.append(" IMPLICIT ");
- }
-
- buf.append(nl);
-
- _dumpAsString(tab, verbose, o.getObject(), buf);
- }
else if (obj instanceof ASN1Set)
{
- Enumeration e = ((ASN1Set)obj).getObjects();
- String tab = indent + TAB;
-
buf.append(indent);
-
if (obj instanceof BERSet)
{
buf.append("BER Set");
@@ -150,26 +107,45 @@
}
buf.append(nl);
- while (e.hasMoreElements())
- {
- Object o = e.nextElement();
+ ASN1Set set = (ASN1Set)obj;
+ String elementsIndent = indent + TAB;
- 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);
- }
+ for (int i = 0, count = set.size(); i < count; ++i)
+ {
+ _dumpAsString(elementsIndent, verbose, set.getObjectAt(i).toASN1Primitive(), buf);
}
}
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ buf.append(indent);
+ if (obj instanceof BERTaggedObject)
+ {
+ buf.append("BER Tagged ");
+ }
+ else if (obj instanceof DERTaggedObject)
+ {
+ buf.append("DER Tagged ");
+ }
+ else
+ {
+ buf.append("Tagged ");
+ }
+
+ ASN1TaggedObject o = (ASN1TaggedObject)obj;
+
+ buf.append(ASN1Util.getTagText(o));
+
+ if (!o.isExplicit())
+ {
+ buf.append(" IMPLICIT ");
+ }
+
+ buf.append(nl);
+
+ String baseIndent = indent + TAB;
+
+ _dumpAsString(baseIndent, verbose, o.getBaseObject().toASN1Primitive(), buf);
+ }
else if (obj instanceof ASN1OctetString)
{
ASN1OctetString oct = (ASN1OctetString)obj;
@@ -195,6 +171,10 @@
{
buf.append(indent + "ObjectIdentifier(" + ((ASN1ObjectIdentifier)obj).getId() + ")" + nl);
}
+ else if (obj instanceof ASN1RelativeOID)
+ {
+ buf.append(indent + "RelativeOID(" + ((ASN1RelativeOID)obj).getId() + ")" + nl);
+ }
else if (obj instanceof ASN1Boolean)
{
buf.append(indent + "Boolean(" + ((ASN1Boolean)obj).isTrue() + ")" + nl);
@@ -203,50 +183,70 @@
{
buf.append(indent + "Integer(" + ((ASN1Integer)obj).getValue() + ")" + nl);
}
- else if (obj instanceof DERBitString)
+ else if (obj instanceof ASN1BitString)
{
- DERBitString bt = (DERBitString)obj;
- buf.append(indent + "DER Bit String" + "[" + bt.getBytes().length + ", " + bt.getPadBits() + "] ");
+ ASN1BitString bitString = (ASN1BitString)obj;
+
+ byte[] bytes = bitString.getBytes();
+ int padBits = bitString.getPadBits();
+
+ if (bitString instanceof DERBitString)
+ {
+ buf.append(indent + "DER Bit String" + "[" + bytes.length + ", " + padBits + "] ");
+ }
+ else if (bitString instanceof DLBitString)
+ {
+ buf.append(indent + "DL Bit String" + "[" + bytes.length + ", " + padBits + "] ");
+ }
+ else
+ {
+ buf.append(indent + "BER Bit String" + "[" + bytes.length + ", " + padBits + "] ");
+ }
+
if (verbose)
{
- buf.append(dumpBinaryDataAsString(indent, bt.getBytes()));
+ buf.append(dumpBinaryDataAsString(indent, bytes));
}
else
{
buf.append(nl);
}
}
- else if (obj instanceof DERIA5String)
+ else if (obj instanceof ASN1IA5String)
{
- buf.append(indent + "IA5String(" + ((DERIA5String)obj).getString() + ") " + nl);
+ buf.append(indent + "IA5String(" + ((ASN1IA5String)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERUTF8String)
+ else if (obj instanceof ASN1UTF8String)
{
- buf.append(indent + "UTF8String(" + ((DERUTF8String)obj).getString() + ") " + nl);
+ buf.append(indent + "UTF8String(" + ((ASN1UTF8String)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERPrintableString)
+ else if (obj instanceof ASN1NumericString)
{
- buf.append(indent + "PrintableString(" + ((DERPrintableString)obj).getString() + ") " + nl);
+ buf.append(indent + "NumericString(" + ((ASN1NumericString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERVisibleString)
+ else if (obj instanceof ASN1PrintableString)
{
- buf.append(indent + "VisibleString(" + ((DERVisibleString)obj).getString() + ") " + nl);
+ buf.append(indent + "PrintableString(" + ((ASN1PrintableString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERBMPString)
+ else if (obj instanceof ASN1VisibleString)
{
- buf.append(indent + "BMPString(" + ((DERBMPString)obj).getString() + ") " + nl);
+ buf.append(indent + "VisibleString(" + ((ASN1VisibleString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERT61String)
+ else if (obj instanceof ASN1BMPString)
{
- buf.append(indent + "T61String(" + ((DERT61String)obj).getString() + ") " + nl);
+ buf.append(indent + "BMPString(" + ((ASN1BMPString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERGraphicString)
+ else if (obj instanceof ASN1T61String)
{
- buf.append(indent + "GraphicString(" + ((DERGraphicString)obj).getString() + ") " + nl);
+ buf.append(indent + "T61String(" + ((ASN1T61String)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERVideotexString)
+ else if (obj instanceof ASN1GraphicString)
{
- buf.append(indent + "VideotexString(" + ((DERVideotexString)obj).getString() + ") " + nl);
+ buf.append(indent + "GraphicString(" + ((ASN1GraphicString)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof ASN1VideotexString)
+ {
+ buf.append(indent + "VideotexString(" + ((ASN1VideotexString)obj).getString() + ") " + nl);
}
else if (obj instanceof ASN1UTCTime)
{
@@ -256,23 +256,16 @@
{
buf.append(indent + "GeneralizedTime(" + ((ASN1GeneralizedTime)obj).getTime() + ") " + nl);
}
- else if (obj instanceof BERApplicationSpecific)
- {
- buf.append(outputApplicationSpecific("BER", indent, verbose, obj, nl));
- }
- else if (obj instanceof DERApplicationSpecific)
- {
- buf.append(outputApplicationSpecific("DER", indent, verbose, obj, nl));
- }
- else if (obj instanceof DLApplicationSpecific)
- {
- buf.append(outputApplicationSpecific("", indent, verbose, obj, nl));
- }
else if (obj instanceof ASN1Enumerated)
{
ASN1Enumerated en = (ASN1Enumerated) obj;
buf.append(indent + "DER Enumerated(" + en.getValue() + ")" + nl);
}
+ else if (obj instanceof ASN1ObjectDescriptor)
+ {
+ ASN1ObjectDescriptor od = (ASN1ObjectDescriptor)obj;
+ buf.append(indent + "ObjectDescriptor(" + od.getBaseGraphicString().getString() + ") " + nl);
+ }
else if (obj instanceof ASN1External)
{
ASN1External ext = (ASN1External) obj;
@@ -298,32 +291,6 @@
buf.append(indent + obj.toString() + nl);
}
}
-
- private static String outputApplicationSpecific(String type, String indent, boolean verbose, ASN1Primitive obj, String nl)
- {
- ASN1ApplicationSpecific app = ASN1ApplicationSpecific.getInstance(obj);
- StringBuffer buf = new StringBuffer();
-
- if (app.isConstructed())
- {
- try
- {
- ASN1Sequence s = ASN1Sequence.getInstance(app.getObject(BERTags.SEQUENCE));
- buf.append(indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "]" + nl);
- for (Enumeration e = s.getObjects(); e.hasMoreElements();)
- {
- _dumpAsString(indent + TAB, verbose, (ASN1Primitive)e.nextElement(), buf);
- }
- }
- catch (IOException e)
- {
- buf.append(e);
- }
- return buf.toString();
- }
-
- return indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "] (" + Strings.fromByteArray(Hex.encode(app.getContents())) + ")" + nl;
- }
/**
* dump out a DER object as a formatted string, in non-verbose mode.
@@ -348,21 +315,22 @@
Object obj,
boolean verbose)
{
- StringBuffer buf = new StringBuffer();
-
+ ASN1Primitive primitive;
if (obj instanceof ASN1Primitive)
{
- _dumpAsString("", verbose, (ASN1Primitive)obj, buf);
+ primitive = (ASN1Primitive)obj;
}
else if (obj instanceof ASN1Encodable)
{
- _dumpAsString("", verbose, ((ASN1Encodable)obj).toASN1Primitive(), buf);
+ primitive = ((ASN1Encodable)obj).toASN1Primitive();
}
else
{
return "unknown object type " + obj.toString();
}
+ StringBuffer buf = new StringBuffer();
+ _dumpAsString("", verbose, primitive, buf);
return buf.toString();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java
index 39312de..3d09921 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java
@@ -1,16 +1,17 @@
package org.bouncycastle.asn1.x500;
+import org.bouncycastle.asn1.ASN1BMPString;
import org.bouncycastle.asn1.ASN1Choice;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1PrintableString;
import org.bouncycastle.asn1.ASN1String;
+import org.bouncycastle.asn1.ASN1T61String;
import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERBMPString;
-import org.bouncycastle.asn1.DERPrintableString;
-import org.bouncycastle.asn1.DERT61String;
+import org.bouncycastle.asn1.ASN1UTF8String;
+import org.bouncycastle.asn1.ASN1UniversalString;
import org.bouncycastle.asn1.DERUTF8String;
-import org.bouncycastle.asn1.DERUniversalString;
/**
* The DirectoryString CHOICE object.
@@ -28,29 +29,29 @@
return (DirectoryString)o;
}
- if (o instanceof DERT61String)
+ if (o instanceof ASN1T61String)
{
- return new DirectoryString((DERT61String)o);
+ return new DirectoryString((ASN1T61String)o);
}
- if (o instanceof DERPrintableString)
+ if (o instanceof ASN1PrintableString)
{
- return new DirectoryString((DERPrintableString)o);
+ return new DirectoryString((ASN1PrintableString)o);
}
- if (o instanceof DERUniversalString)
+ if (o instanceof ASN1UniversalString)
{
- return new DirectoryString((DERUniversalString)o);
+ return new DirectoryString((ASN1UniversalString)o);
}
- if (o instanceof DERUTF8String)
+ if (o instanceof ASN1UTF8String)
{
- return new DirectoryString((DERUTF8String)o);
+ return new DirectoryString((ASN1UTF8String)o);
}
- if (o instanceof DERBMPString)
+ if (o instanceof ASN1BMPString)
{
- return new DirectoryString((DERBMPString)o);
+ return new DirectoryString((ASN1BMPString)o);
}
throw new IllegalArgumentException("illegal object in getInstance: " + o.getClass().getName());
@@ -63,35 +64,35 @@
throw new IllegalArgumentException("choice item must be explicitly tagged");
}
- return getInstance(o.getObject());
+ return getInstance(o.getExplicitBaseObject());
}
private DirectoryString(
- DERT61String string)
+ ASN1T61String string)
{
this.string = string;
}
private DirectoryString(
- DERPrintableString string)
+ ASN1PrintableString string)
{
this.string = string;
}
private DirectoryString(
- DERUniversalString string)
+ ASN1UniversalString string)
{
this.string = string;
}
private DirectoryString(
- DERUTF8String string)
+ ASN1UTF8String string)
{
this.string = string;
}
private DirectoryString(
- DERBMPString string)
+ ASN1BMPString string)
{
this.string = string;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java
index 1475b4a..a5f092d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java
@@ -1,12 +1,11 @@
package org.bouncycastle.asn1.x500;
import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Set;
-import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSet;
/**
@@ -19,6 +18,7 @@
private RDN(ASN1Set values)
{
+ // TODO Require minimum size of 1?
this.values = values;
}
@@ -36,6 +36,11 @@
return null;
}
+ public static RDN getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
+ {
+ return new RDN(ASN1Set.getInstance(taggedObject, declaredExplicit));
+ }
+
/**
* Create a single valued RDN.
*
@@ -44,12 +49,7 @@
*/
public RDN(ASN1ObjectIdentifier oid, ASN1Encodable value)
{
- ASN1EncodableVector v = new ASN1EncodableVector(2);
-
- v.add(oid);
- v.add(value);
-
- this.values = new DERSet(new DERSequence(v));
+ this(new AttributeTypeAndValue(oid, value));
}
public RDN(AttributeTypeAndValue attrTAndV)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java
index 50efe50..bf6fdd7 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java
@@ -1,7 +1,5 @@
package org.bouncycastle.asn1.x500;
-import java.util.Enumeration;
-
import org.bouncycastle.asn1.ASN1Choice;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Object;
@@ -111,18 +109,18 @@
X500NameStyle style,
ASN1Sequence seq)
{
+ int count = seq.size();
+
this.style = style;
- this.rdns = new RDN[seq.size()];
+ this.rdns = new RDN[count];
boolean inPlace = true;
-
- int index = 0;
- for (Enumeration e = seq.getObjects(); e.hasMoreElements();)
+ for (int index = 0; index < count; ++index)
{
- Object element = e.nextElement();
+ ASN1Encodable element = seq.getObjectAt(index);
RDN rdn = RDN.getInstance(element);
inPlace &= (rdn == element);
- rdns[index++] = rdn;
+ rdns[index] = rdn;
}
if (inPlace)
@@ -229,6 +227,11 @@
return res;
}
+ public int size()
+ {
+ return rdns.length;
+ }
+
public ASN1Primitive toASN1Primitive()
{
return rdnSeq;
@@ -265,14 +268,14 @@
ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive();
- if (this.toASN1Primitive().equals(derO))
+ if (toASN1Primitive().equals(derO))
{
return true;
}
try
{
- return style.areEqual(this, new X500Name(ASN1Sequence.getInstance(((ASN1Encodable)obj).toASN1Primitive())));
+ return style.areEqual(this, getInstance(obj));
}
catch (Exception e)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
index 8d801b3..6f20e23 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
@@ -131,19 +131,22 @@
public boolean areEqual(X500Name name1, X500Name name2)
{
- RDN[] rdns1 = name1.getRDNs();
- RDN[] rdns2 = name2.getRDNs();
-
- if (rdns1.length != rdns2.length)
+ if (name1.size() != name2.size())
{
return false;
}
+ RDN[] rdns1 = name1.getRDNs();
+ RDN[] rdns2 = name2.getRDNs();
+
boolean reverse = false;
- if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null)
+ AttributeTypeAndValue first1 = rdns1[0].getFirst();
+ AttributeTypeAndValue first2 = rdns2[0].getFirst();
+
+ if (first1 != null && first2 != null)
{
- reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType()); // guess forward
+ reverse = !first1.getType().equals(first2.getType()); // guess forward
}
for (int i = 0; i != rdns1.length; i++)
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 eb627c0..dd5f15f 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
@@ -15,14 +15,14 @@
public boolean areEqual(X500Name name1, X500Name name2)
{
- RDN[] rdns1 = name1.getRDNs();
- RDN[] rdns2 = name2.getRDNs();
-
- if (rdns1.length != rdns2.length)
+ if (name1.size() != name2.size())
{
return false;
}
+ RDN[] rdns1 = name1.getRDNs();
+ RDN[] rdns2 = name2.getRDNs();
+
for (int i = 0; i != rdns1.length; i++)
{
if (!rdnAreEqual(rdns1[i], rdns2[i]))
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 a7be3eb..dfece78 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
@@ -289,9 +289,9 @@
defaultLookUp = copyHashTable(DefaultLookUp);
}
- protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid,
- String value) {
- if (oid.equals(EmailAddress) || oid.equals(DC))
+ protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, String value)
+ {
+ if (oid.equals(EmailAddress) || oid.equals(DC))
{
return new DERIA5String(value);
}
@@ -299,18 +299,18 @@
{
return new ASN1GeneralizedTime(value);
}
- else if (oid.equals(C) || oid.equals(SN) || oid.equals(DN_QUALIFIER)
+ else if (oid.equals(C) || oid.equals(SERIALNUMBER) || oid.equals(DN_QUALIFIER)
|| oid.equals(TELEPHONE_NUMBER))
{
return new DERPrintableString(value);
}
-
- return super.encodeStringValue(oid, value);
+
+ return super.encodeStringValue(oid, value);
}
public String oidToDisplayName(ASN1ObjectIdentifier oid)
{
- return (String)DefaultSymbols.get(oid);
+ return (String)defaultSymbols.get(oid);
}
public String[] oidToAttrNames(ASN1ObjectIdentifier oid)
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 5ddd322..03d5b73 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
@@ -10,7 +10,7 @@
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1String;
-import org.bouncycastle.asn1.DERUniversalString;
+import org.bouncycastle.asn1.ASN1UniversalString;
import org.bouncycastle.asn1.x500.AttributeTypeAndValue;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500NameBuilder;
@@ -22,12 +22,15 @@
{
private static String unescape(String elt)
{
- if (elt.length() == 0 || (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0))
+ if (elt.length() == 0)
+ {
+ return elt;
+ }
+ if (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0)
{
return elt.trim();
}
- char[] elts = elt.toCharArray();
boolean escaped = false;
boolean quoted = false;
StringBuffer buf = new StringBuffer(elt.length());
@@ -35,9 +38,9 @@
// if it's an escaped hash string and not an actual encoding in string form
// we need to leave it escaped.
- if (elts[0] == '\\')
+ if (elt.charAt(0) == '\\')
{
- if (elts[1] == '#')
+ if (elt.charAt(1) == '#')
{
start = 2;
buf.append("\\#");
@@ -48,9 +51,9 @@
int lastEscaped = 0;
char hex1 = 0;
- for (int i = start; i != elts.length; i++)
+ for (int i = start; i != elt.length(); i++)
{
- char c = elts[i];
+ char c = elt.charAt(i);
if (c != ' ')
{
@@ -66,8 +69,8 @@
else
{
buf.append(c);
+ escaped = false;
}
- escaped = false;
}
else if (c == '\\' && !(escaped || quoted))
{
@@ -128,81 +131,93 @@
public static RDN[] rDNsFromString(String name, X500NameStyle x500Style)
{
- X500NameTokenizer nTok = new X500NameTokenizer(name);
+ X500NameTokenizer tokenizer = new X500NameTokenizer(name);
X500NameBuilder builder = new X500NameBuilder(x500Style);
- while (nTok.hasMoreTokens())
+ addRDNs(x500Style, builder, tokenizer);
+
+ // TODO There's an unnecessary clone of the RDNs array happening here
+ return builder.build().getRDNs();
+ }
+
+ private static void addRDNs(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer)
+ {
+ String token;
+ while ((token = tokenizer.nextToken()) != null)
{
- String token = nTok.nextToken();
-
- if (token.indexOf('+') > 0)
+ if (token.indexOf('+') >= 0)
{
- X500NameTokenizer pTok = new X500NameTokenizer(token, '+');
- X500NameTokenizer vTok = new X500NameTokenizer(pTok.nextToken(), '=');
-
- String attr = vTok.nextToken();
-
- if (!vTok.hasMoreTokens())
- {
- throw new IllegalArgumentException("badly formatted directory string");
- }
-
- String value = vTok.nextToken();
- ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim());
-
- if (pTok.hasMoreTokens())
- {
- Vector oids = new Vector();
- Vector values = new Vector();
-
- oids.addElement(oid);
- values.addElement(unescape(value));
-
- while (pTok.hasMoreTokens())
- {
- vTok = new X500NameTokenizer(pTok.nextToken(), '=');
-
- attr = vTok.nextToken();
-
- if (!vTok.hasMoreTokens())
- {
- throw new IllegalArgumentException("badly formatted directory string");
- }
-
- value = vTok.nextToken();
- oid = x500Style.attrNameToOID(attr.trim());
-
-
- oids.addElement(oid);
- values.addElement(unescape(value));
- }
-
- builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values));
- }
- else
- {
- builder.addRDN(oid, unescape(value));
- }
+ addMultiValuedRDN(style, builder, new X500NameTokenizer(token, '+'));
}
else
{
- X500NameTokenizer vTok = new X500NameTokenizer(token, '=');
-
- String attr = vTok.nextToken();
-
- if (!vTok.hasMoreTokens())
- {
- throw new IllegalArgumentException("badly formatted directory string");
- }
-
- String value = vTok.nextToken();
- ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim());
-
- builder.addRDN(oid, unescape(value));
+ addRDN(style, builder, token);
}
}
+ }
- return builder.build().getRDNs();
+ private static void addMultiValuedRDN(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer)
+ {
+ String token = tokenizer.nextToken();
+ if (token == null)
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
+
+ if (!tokenizer.hasMoreTokens())
+ {
+ addRDN(style, builder, token);
+ return;
+ }
+
+ Vector oids = new Vector();
+ Vector values = new Vector();
+
+ do
+ {
+ collectAttributeTypeAndValue(style, oids, values, token);
+ token = tokenizer.nextToken();
+ }
+ while (token != null);
+
+ builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values));
+ }
+
+ private static void addRDN(X500NameStyle style, X500NameBuilder builder, String token)
+ {
+ X500NameTokenizer tokenizer = new X500NameTokenizer(token, '=');
+
+ String typeToken = nextToken(tokenizer, true);
+ String valueToken = nextToken(tokenizer, false);
+
+ ASN1ObjectIdentifier oid = style.attrNameToOID(typeToken.trim());
+ String value = unescape(valueToken);
+
+ builder.addRDN(oid, value);
+ }
+
+ private static void collectAttributeTypeAndValue(X500NameStyle style, Vector oids, Vector values, String token)
+ {
+ X500NameTokenizer tokenizer = new X500NameTokenizer(token, '=');
+
+ String typeToken = nextToken(tokenizer, true);
+ String valueToken = nextToken(tokenizer, false);
+
+ ASN1ObjectIdentifier oid = style.attrNameToOID(typeToken.trim());
+ String value = unescape(valueToken);
+
+ oids.addElement(oid);
+ values.addElement(value);
+ }
+
+ private static String nextToken(X500NameTokenizer tokenizer, boolean expectMoreTokens)
+ {
+ String token = tokenizer.nextToken();
+ if (token == null || tokenizer.hasMoreTokens() != expectMoreTokens)
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
+ return token;
}
private static String[] toValueArray(Vector values)
@@ -354,7 +369,7 @@
{
StringBuffer vBuf = new StringBuffer();
- if (value instanceof ASN1String && !(value instanceof DERUniversalString))
+ if (value instanceof ASN1String && !(value instanceof ASN1UniversalString))
{
String v = ((ASN1String)value).getString();
if (v.length() > 0 && v.charAt(0) == '#')
@@ -369,6 +384,7 @@
try
{
vBuf.append('#');
+ // -DM Hex.toHexString
vBuf.append(Hex.toHexString(value.toASN1Primitive().getEncoded(ASN1Encoding.DER)));
}
catch (IOException e)
@@ -423,7 +439,7 @@
int endBuf = vBuf.length() - 1;
- while (endBuf >= 0 && vBuf.charAt(endBuf) == ' ')
+ while (endBuf >= start && vBuf.charAt(endBuf) == ' ')
{
vBuf.insert(endBuf, '\\');
endBuf--;
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 2a40fb0..f07112f 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
@@ -11,7 +11,7 @@
import org.bouncycastle.asn1.x500.X500NameStyle;
public class RFC4519Style
- extends AbstractX500NameStyle
+ extends AbstractX500NameStyle
{
public static final ASN1ObjectIdentifier businessCategory = new ASN1ObjectIdentifier("2.5.4.15").intern();
public static final ASN1ObjectIdentifier c = new ASN1ObjectIdentifier("2.5.4.6").intern();
@@ -175,9 +175,9 @@
defaultLookUp = copyHashTable(DefaultLookUp);
}
- protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid,
- String value) {
- if (oid.equals(dc))
+ protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, String value)
+ {
+ if (oid.equals(dc))
{
return new DERIA5String(value);
}
@@ -187,12 +187,12 @@
return new DERPrintableString(value);
}
- return super.encodeStringValue(oid, value);
+ return super.encodeStringValue(oid, value);
}
public String oidToDisplayName(ASN1ObjectIdentifier oid)
{
- return (String)DefaultSymbols.get(oid);
+ return (String)defaultSymbols.get(oid);
}
public String[] oidToAttrNames(ASN1ObjectIdentifier oid)
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 b7e52f2..30dbf7a 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
@@ -8,83 +8,78 @@
*/
public class X500NameTokenizer
{
- private String value;
- private int index;
- private char separator;
- private StringBuffer buf = new StringBuffer();
+ private final String value;
+ private final char separator;
- public X500NameTokenizer(
- String oid)
+ private int index;
+
+ public X500NameTokenizer(String oid)
{
this(oid, ',');
}
-
- public X500NameTokenizer(
- String oid,
- char separator)
+
+ public X500NameTokenizer(String oid, char separator)
{
+ if (oid == null)
+ {
+ throw new NullPointerException();
+ }
+ if (separator == '"' || separator == '\\')
+ {
+ throw new IllegalArgumentException("reserved separator character");
+ }
+
this.value = oid;
- this.index = -1;
this.separator = separator;
+ this.index = oid.length() < 1 ? 0 : -1;
}
public boolean hasMoreTokens()
{
- return (index != value.length());
+ return index < value.length();
}
public String nextToken()
{
- if (index == value.length())
+ if (index >= value.length())
{
return null;
}
- int end = index + 1;
boolean quoted = false;
boolean escaped = false;
- buf.setLength(0);
-
- while (end != value.length())
+ int beginIndex = index + 1;
+ while (++index < value.length())
{
- char c = value.charAt(end);
+ char c = value.charAt(index);
- if (c == '"')
+ if (escaped)
{
- if (!escaped)
- {
- quoted = !quoted;
- }
- buf.append(c);
escaped = false;
}
- else
+ else if (c == '"')
{
- if (escaped || quoted)
- {
- buf.append(c);
- escaped = false;
- }
- else if (c == '\\')
- {
- buf.append(c);
- escaped = true;
- }
- else if (c == separator)
- {
- break;
- }
- else
- {
- buf.append(c);
- }
+ quoted = !quoted;
}
- end++;
+ else if (quoted)
+ {
+ }
+ else if (c == '\\')
+ {
+ escaped = true;
+ }
+ else if (c == separator)
+ {
+ return value.substring(beginIndex, index);
+ }
}
- index = end;
+ if (escaped || quoted)
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
- return buf.toString();
+ return value.substring(beginIndex, index);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AltSignatureAlgorithm.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AltSignatureAlgorithm.java
new file mode 100644
index 0000000..08f05a0
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AltSignatureAlgorithm.java
@@ -0,0 +1,94 @@
+package org.bouncycastle.asn1.x509;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+
+/**
+ * X.509 Section 9.8.3.
+ * <br/>
+ * This extension may be used as a public-key certificate extension, a CRL extension or an AVL extension. It shall contain
+ * the algorithm identifier for the alternative digital signature algorithm used by the signer when creating an alternative
+ * digital signature and by the relying party when validating the alternative digital signature.
+ * <pre>
+ * altSignatureAlgorithm EXTENSION ::= {
+ * SYNTAX AltSignatureAlgorithm
+ * IDENTIFIED BY id-ce-altSignatureAlgorithm }
+ *
+ * AltSignatureAlgorithm ::= AlgorithmIdentifier{{SupportedAlgorithms}}
+ * </pre>
+ * When the altSignatureAlgorithm extension is included in a particular value that is an instance of a data type that
+ * supports extensions, the altSignatureValue extension shall also be included.
+ * <br/>
+ * NOTE 1 – By having a separate altSignatureAlgorithm extension, instead of having it combined with the
+ * altSignatureValue extension, the alternative digital signature algorithm is protected by the alternative signature.
+ * This extension may be flagged either as critical or as non-critical.
+ * <br/>
+ * NOTE 2 – It is recommended that it be flagged as non-critical. Flagging it as critical would require all relying parties to understand
+ * the extension and the alternative public-key algorithms
+ */
+public class AltSignatureAlgorithm
+ extends ASN1Object
+{
+ private final AlgorithmIdentifier algorithm;
+
+ public static AltSignatureAlgorithm getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(AlgorithmIdentifier.getInstance(obj, explicit));
+ }
+
+ public static AltSignatureAlgorithm getInstance(
+ Object obj)
+ {
+ if (obj instanceof AltSignatureAlgorithm)
+ {
+ return (AltSignatureAlgorithm)obj;
+ }
+ else if (obj != null)
+ {
+ return new AltSignatureAlgorithm(AlgorithmIdentifier.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static AltSignatureAlgorithm fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.altSignatureAlgorithm));
+ }
+
+ public AltSignatureAlgorithm(AlgorithmIdentifier algorithm)
+ {
+ this.algorithm = algorithm;
+ }
+
+ public AltSignatureAlgorithm(ASN1ObjectIdentifier algorithm)
+ {
+ this(algorithm, null);
+ }
+
+ public AltSignatureAlgorithm(ASN1ObjectIdentifier algorithm, ASN1Encodable parameters)
+ {
+ this.algorithm = new AlgorithmIdentifier(algorithm, parameters);
+ }
+
+ /**
+ * Return the algorithm identifier representing the alternate signature algorithm
+ * used to generate the alternate signature algorithm value extension.
+ *
+ * @return alternate signature algorithm identifier.
+ */
+ public AlgorithmIdentifier getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return algorithm.toASN1Primitive();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AltSignatureValue.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AltSignatureValue.java
new file mode 100644
index 0000000..96e7f67
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AltSignatureValue.java
@@ -0,0 +1,94 @@
+package org.bouncycastle.asn1.x509;
+
+import org.bouncycastle.asn1.ASN1BitString;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERBitString;
+
+/**
+ * X.509 Section 9.8.4.
+ * <br/>
+ * This extension may be used as a public-key certificate extension, a CRL extension or an AVL extension.
+ * This alternative signature shall be created by the issuer using its alternative private key, and it shall be verified using the
+ * alternative public key of the issuer.
+ * <pre>
+ * altSignatureValue EXTENSION ::= {
+ * SYNTAX AltSignatureValue
+ * IDENTIFIED BY id-ce-altSignatureValue }
+ *
+ * AltSignatureValue ::= BIT STRING
+ * </pre>
+ * This extension can only be created by a signer holding a multiple cryptographic algorithms public-key certificate. When
+ * creating the alternative digital signature on an issued public-key certificate or CRL, the signer shall use its alternative
+ * private key.
+ * <br/>
+ * The procedures for creating and validating alternative digital signatures are specified in:
+ * <ul>
+ * <li>clause 7.2.2 for public-key certificates;</li>
+ * <li>clause 7.10.3 for CRLs: and</li>
+ * <li>clause 11.4 for AVLs.</li>
+ * </ul>
+ */
+public class AltSignatureValue
+ extends ASN1Object
+{
+ private final ASN1BitString signature;
+
+ public static AltSignatureValue getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1BitString.getInstance(obj, explicit));
+ }
+
+ public static AltSignatureValue getInstance(
+ Object obj)
+ {
+ if (obj instanceof AltSignatureValue)
+ {
+ return (AltSignatureValue)obj;
+ }
+ else if (obj != null)
+ {
+ return new AltSignatureValue(ASN1BitString.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static AltSignatureValue fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.altSignatureValue));
+ }
+
+ private AltSignatureValue(ASN1BitString signature)
+ {
+ this.signature = signature;
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param signature a signature value, based on the enclosing certificate.
+ */
+ public AltSignatureValue(byte[] signature)
+ {
+ this.signature = new DERBitString(signature);
+ }
+
+ /**
+ * Return the alternate signature to verify the certificate.
+ *
+ * @return certificate's alternate signature.
+ */
+ public ASN1BitString getSignature()
+ {
+ return signature;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return signature;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertIssuer.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertIssuer.java
index 21907c6..4c53c2a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertIssuer.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertIssuer.java
@@ -46,7 +46,7 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ return getInstance(obj.getExplicitBaseObject()); // must be explicitly tagged
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java
index 7042e1e..7eb26be 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java
@@ -1,5 +1,6 @@
package org.bouncycastle.asn1.x509;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
@@ -12,7 +13,7 @@
{
AttributeCertificateInfo acinfo;
AlgorithmIdentifier signatureAlgorithm;
- DERBitString signatureValue;
+ ASN1BitString signatureValue;
/**
* @param obj
@@ -35,28 +36,23 @@
public AttributeCertificate(
AttributeCertificateInfo acinfo,
AlgorithmIdentifier signatureAlgorithm,
- DERBitString signatureValue)
+ ASN1BitString signatureValue)
{
this.acinfo = acinfo;
this.signatureAlgorithm = signatureAlgorithm;
this.signatureValue = signatureValue;
}
- /**
- * @deprecated use getInstance() method.
- */
- public AttributeCertificate(
- ASN1Sequence seq)
+ private AttributeCertificate(ASN1Sequence seq)
{
if (seq.size() != 3)
{
- throw new IllegalArgumentException("Bad sequence size: "
- + seq.size());
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
}
this.acinfo = AttributeCertificateInfo.getInstance(seq.getObjectAt(0));
this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- this.signatureValue = DERBitString.getInstance(seq.getObjectAt(2));
+ this.signatureValue = ASN1BitString.getInstance(seq.getObjectAt(2));
}
public AttributeCertificateInfo getAcinfo()
@@ -69,7 +65,7 @@
return signatureAlgorithm;
}
- public DERBitString getSignatureValue()
+ public ASN1BitString getSignatureValue()
{
return signatureValue;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
index 431cb29..a494d62 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
@@ -1,5 +1,6 @@
package org.bouncycastle.asn1.x509;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
@@ -7,7 +8,6 @@
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
public class AttributeCertificateInfo
@@ -17,10 +17,10 @@
private Holder holder;
private AttCertIssuer issuer;
private AlgorithmIdentifier signature;
- private ASN1Integer serialNumber;
+ private ASN1Integer serialNumber;
private AttCertValidityPeriod attrCertValidityPeriod;
private ASN1Sequence attributes;
- private DERBitString issuerUniqueID;
+ private ASN1BitString issuerUniqueID;
private Extensions extensions;
public static AttributeCertificateInfo getInstance(
@@ -76,9 +76,9 @@
{
ASN1Encodable obj = seq.getObjectAt(i);
- if (obj instanceof DERBitString)
+ if (obj instanceof ASN1BitString)
{
- this.issuerUniqueID = DERBitString.getInstance(seq.getObjectAt(i));
+ this.issuerUniqueID = ASN1BitString.getInstance(seq.getObjectAt(i));
}
else if (obj instanceof ASN1Sequence || obj instanceof Extensions)
{
@@ -122,7 +122,7 @@
return attributes;
}
- public DERBitString getIssuerUniqueID()
+ public ASN1BitString getIssuerUniqueID()
{
return issuerUniqueID;
}
@@ -154,7 +154,7 @@
{
ASN1EncodableVector v = new ASN1EncodableVector(9);
- if (version.intValueExact() != 0)
+ if (!version.hasValue(0))
{
v.add(version);
}
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 356a2fe..d82751d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
@@ -17,6 +17,7 @@
// Android-changed: Use Android digests
// import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.encoders.Hex;
/**
@@ -173,7 +174,7 @@
GeneralNames name,
BigInteger serialNumber)
{
- this.keyidentifier = (keyIdentifier != null) ? new DEROctetString(keyIdentifier) : null;
+ this.keyidentifier = (keyIdentifier != null) ? new DEROctetString(Arrays.clone(keyIdentifier)) : null;
this.certissuer = name;
this.certserno = (serialNumber != null) ? new ASN1Integer(serialNumber) : null;
}
@@ -230,6 +231,7 @@
public String toString()
{
+ // -DM Hex.toHexString
String keyID = (keyidentifier != null) ? Hex.toHexString(keyidentifier.getOctets()) : "null";
return "AuthorityKeyIdentifier: KeyID(" + keyID + ")";
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 fa4c53d..4773c7f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java
@@ -122,6 +122,11 @@
return null;
}
+ public ASN1Integer getPathLenConstraintInteger()
+ {
+ return pathLenConstraint;
+ }
+
/**
* Produce an object suitable for an ASN1OutputStream.
* <pre>
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLNumber.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLNumber.java
index 95425ba..baac2b0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLNumber.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLNumber.java
@@ -5,6 +5,7 @@
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.util.BigIntegers;
/**
* The CRLNumber object.
@@ -20,6 +21,10 @@
public CRLNumber(
BigInteger number)
{
+ if (BigIntegers.ZERO.compareTo(number) > 0)
+ {
+ throw new IllegalArgumentException("Invalid CRL number : not in (0..MAX)");
+ }
this.number = number;
}
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 a62122e..9bad7b6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLReason.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLReason.java
@@ -51,7 +51,7 @@
/**
* @deprecated use lower case version
*/
- public static final int CESSATION_OF_OPERATION = 5;
+ public static final int CESSATION_OF_OPERATION = 5;
/**
* @deprecated use lower case version
*/
@@ -74,7 +74,7 @@
public static final int cACompromise = 2;
public static final int affiliationChanged = 3;
public static final int superseded = 4;
- public static final int cessationOfOperation = 5;
+ public static final int cessationOfOperation = 5;
public static final int certificateHold = 6;
// 7 -> unknown
public static final int removeFromCRL = 8;
@@ -82,11 +82,11 @@
public static final int aACompromise = 10;
private static final String[] reasonString =
- {
- "unspecified", "keyCompromise", "cACompromise", "affiliationChanged",
- "superseded", "cessationOfOperation", "certificateHold", "unknown",
- "removeFromCRL", "privilegeWithdrawn", "aACompromise"
- };
+ {
+ "unspecified", "keyCompromise", "cACompromise", "affiliationChanged",
+ "superseded", "cessationOfOperation", "certificateHold", "unknown",
+ "removeFromCRL", "privilegeWithdrawn", "aACompromise"
+ };
private static final Hashtable table = new Hashtable();
@@ -109,6 +109,10 @@
private CRLReason(
int reason)
{
+ if (reason < 0)
+ {
+ throw new IllegalArgumentException("Invalid CRL reason : not in (0..MAX)");
+ }
value = new ASN1Enumerated(reason);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Certificate.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Certificate.java
index 4ca14d4..e64a197 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Certificate.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Certificate.java
@@ -1,11 +1,11 @@
package org.bouncycastle.asn1.x509;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.x500.X500Name;
/**
@@ -24,7 +24,7 @@
ASN1Sequence seq;
TBSCertificate tbsCert;
AlgorithmIdentifier sigAlgId;
- DERBitString sig;
+ ASN1BitString sig;
public static Certificate getInstance(
ASN1TaggedObject obj,
@@ -61,7 +61,7 @@
tbsCert = TBSCertificate.getInstance(seq.getObjectAt(0));
sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- sig = DERBitString.getInstance(seq.getObjectAt(2));
+ sig = ASN1BitString.getInstance(seq.getObjectAt(2));
}
else
{
@@ -119,7 +119,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sig;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CertificateList.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CertificateList.java
index b21e3cd..c4c14d9 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CertificateList.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CertificateList.java
@@ -3,6 +3,7 @@
import java.util.Enumeration;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
@@ -30,7 +31,7 @@
{
TBSCertList tbsCertList;
AlgorithmIdentifier sigAlgId;
- DERBitString sig;
+ ASN1BitString sig;
boolean isHashCodeSet = false;
int hashCodeValue;
@@ -56,18 +57,14 @@
return null;
}
- /**
- * @deprecated use getInstance() method.
- * @param seq
- */
- public CertificateList(
+ private CertificateList(
ASN1Sequence seq)
{
if (seq.size() == 3)
{
tbsCertList = TBSCertList.getInstance(seq.getObjectAt(0));
sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- sig = DERBitString.getInstance(seq.getObjectAt(2));
+ sig = ASN1BitString.getInstance(seq.getObjectAt(2));
}
else
{
@@ -95,7 +92,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sig;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java
new file mode 100644
index 0000000..d562595
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java
@@ -0,0 +1,274 @@
+package org.bouncycastle.asn1.x509;
+
+import java.util.Enumeration;
+
+import org.bouncycastle.asn1.ASN1BitString;
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Integer;
+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;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * <pre>
+ * DeltaCertificateDescriptor ::= SEQUENCE {
+ * serialNumber CertificateSerialNumber,
+ * signature [0] IMPLICIT AlgorithmIdentifier
+ * {SIGNATURE_ALGORITHM, {...}} OPTIONAL,
+ * issuer [1] IMPLICIT Name OPTIONAL,
+ * validity [2] IMPLICIT Validity OPTIONAL,
+ * subject [3] IMPLICIT Name OPTIONAL,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * extensions [4] IMPLICIT Extensions{CertExtensions}
+ * OPTIONAL,
+ * signatureValue BIT STRING
+ * }
+ * </pre>
+ */
+public class DeltaCertificateDescriptor
+ extends ASN1Object
+{
+ private final ASN1Integer serialNumber;
+
+ private AlgorithmIdentifier signature;
+ private X500Name issuer;
+ private ASN1Sequence validity;
+ private X500Name subject;
+ private SubjectPublicKeyInfo subjectPublicKeyInfo;
+ private Extensions extensions;
+
+ private final ASN1BitString signatureValue;
+
+ public static DeltaCertificateDescriptor getInstance(
+ Object obj)
+ {
+ if (obj instanceof DeltaCertificateDescriptor)
+ {
+ return (DeltaCertificateDescriptor)obj;
+ }
+ else if (obj != null)
+ {
+ return new DeltaCertificateDescriptor(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieve a DeltaCertificateDescriptor for a passed in Extensions object, if present.
+ *
+ * @param extensions the extensions object to be examined.
+ * @return the DeltaCertificateDescriptor, null if the extension is not present.
+ */
+ public static DeltaCertificateDescriptor fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.deltaCertificateDescriptor));
+ }
+
+ private DeltaCertificateDescriptor(ASN1Sequence seq)
+ {
+ this.serialNumber = ASN1Integer.getInstance(seq.getObjectAt(0));
+
+ int idx = 1;
+ ASN1Encodable next = seq.getObjectAt(idx);
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ signature = AlgorithmIdentifier.getInstance(tagged, false);
+ break;
+ case 1:
+ issuer = X500Name.getInstance(tagged, true); // issuer
+ break;
+ case 2:
+ validity = ASN1Sequence.getInstance(tagged, false);
+ break;
+ case 3:
+ subject = X500Name.getInstance(tagged, true); // subject
+ break;
+ }
+ next = seq.getObjectAt(idx++);
+ }
+
+ subjectPublicKeyInfo = subjectPublicKeyInfo.getInstance(next);
+
+ next = seq.getObjectAt(idx);
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 4:
+ extensions = Extensions.getInstance(tagged, false);
+ break;
+ }
+ next = seq.getObjectAt(idx++);
+ }
+
+ signatureValue = ASN1BitString.getInstance(next);
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ public AlgorithmIdentifier getSignature()
+ {
+ return signature;
+ }
+
+ public X500Name getIssuer()
+ {
+ return issuer;
+ }
+
+ public ASN1Sequence getValidity()
+ {
+ return validity;
+ }
+
+ public X500Name getSubject()
+ {
+ return subject;
+ }
+
+ public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
+ {
+ return subjectPublicKeyInfo;
+ }
+
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+
+ public ASN1BitString getSignatureValue()
+ {
+ return signatureValue;
+ }
+
+ public DeltaCertificateDescriptor trimTo(TBSCertificate baseTbsCertificate, Extensions tbsExtensions)
+ {
+ AlgorithmIdentifier signature = baseTbsCertificate.signature;
+ X500Name issuer = baseTbsCertificate.issuer;
+ ASN1Sequence validity = new DERSequence(new ASN1Encodable[]
+ {
+ baseTbsCertificate.startDate, baseTbsCertificate.endDate
+ });
+ X500Name subject = baseTbsCertificate.subject;
+ ASN1Sequence s = ASN1Sequence.getInstance(toASN1Primitive());
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ Enumeration en = s.getObjects();
+ v.add((ASN1Encodable)en.nextElement());
+
+ ASN1Encodable next = (ASN1Encodable)en.nextElement();
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ AlgorithmIdentifier sig = AlgorithmIdentifier.getInstance(tagged, false);
+ if (!sig.equals(signature))
+ {
+ v.add(next);
+ }
+ break;
+ case 1:
+ X500Name iss = X500Name.getInstance(tagged, true); // issuer
+ if (!iss.equals(issuer))
+ {
+ v.add(next);
+ }
+ break;
+ case 2:
+ ASN1Sequence val = ASN1Sequence.getInstance(tagged, false);
+ if (!val.equals(validity))
+ {
+ v.add(next);
+ }
+ break;
+ case 3:
+ X500Name sub = X500Name.getInstance(tagged, true); // subject
+ if (!sub.equals(subject))
+ {
+ v.add(next);
+ }
+ break;
+ }
+ next = (ASN1Encodable)en.nextElement();
+ }
+
+ v.add(next);
+
+ next = (ASN1Encodable)en.nextElement();
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 4:
+ Extensions deltaExts = Extensions.getInstance(tagged, false);
+ ExtensionsGenerator deltaExtGen = new ExtensionsGenerator();
+ for (Enumeration extEn = deltaExts.oids(); extEn.hasMoreElements(); )
+ {
+ Extension deltaExt = deltaExts.getExtension((ASN1ObjectIdentifier)extEn.nextElement());
+ Extension primaryExt = tbsExtensions.getExtension(deltaExt.getExtnId());
+
+ if (primaryExt != null)
+ {
+ if (!deltaExt.equals(primaryExt))
+ {
+ deltaExtGen.addExtension(deltaExt);
+ }
+ }
+ }
+
+ DeltaCertificateDescriptor trimmedDeltaCertDesc;
+ if (!deltaExtGen.isEmpty())
+ {
+ v.add(new DERTaggedObject(false, 4, deltaExtGen.generate()));
+ }
+ }
+ next = (ASN1Encodable)en.nextElement();
+ }
+
+ v.add(next);
+
+ return new DeltaCertificateDescriptor(new DERSequence(v));
+ }
+
+ private void addOptional(ASN1EncodableVector v, int tag, boolean explicit, ASN1Object obj)
+ {
+ if (obj != null)
+ {
+ v.add(new DERTaggedObject(explicit, tag, obj));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(7);
+
+ v.add(serialNumber);
+ addOptional(v, 0, false, signature);
+ addOptional(v, 1, true, issuer); // CHOICE
+ addOptional(v, 2, false, validity);
+ addOptional(v, 3, true, subject); // CHOICE
+ v.add(subjectPublicKeyInfo);
+ addOptional(v, 4, false, extensions);
+ v.add(signatureValue);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java
index f001700..368b12a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java
@@ -1,11 +1,11 @@
package org.bouncycastle.asn1.x509;
+import org.bouncycastle.asn1.ASN1BitString;
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.DERBitString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.util.Strings;
@@ -59,10 +59,11 @@
switch (t.getTagNo())
{
case 0:
+ // CHOICE so explicit
distributionPoint = DistributionPointName.getInstance(t, true);
break;
case 1:
- reasons = new ReasonFlags(DERBitString.getInstance(t, false));
+ reasons = new ReasonFlags(ASN1BitString.getInstance(t, false));
break;
case 2:
cRLIssuer = GeneralNames.getInstance(t, false);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java
index 5008028..95cf846 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java
@@ -12,6 +12,7 @@
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.util.Arrays;
/**
* an object for the elements in the X.509 V3 extension block.
@@ -179,6 +180,26 @@
*/
public static final ASN1ObjectIdentifier expiredCertsOnCRL = new ASN1ObjectIdentifier("2.5.29.60").intern();
+ /**
+ * the subject’s alternative public key information
+ */
+ public static final ASN1ObjectIdentifier subjectAltPublicKeyInfo = new ASN1ObjectIdentifier("2.5.29.72").intern();
+
+ /**
+ * the algorithm identifier for the alternative digital signature algorithm.
+ */
+ public static final ASN1ObjectIdentifier altSignatureAlgorithm = new ASN1ObjectIdentifier("2.5.29.73").intern();
+
+ /**
+ * alternative signature shall be created by the issuer using its alternative private key.
+ */
+ public static final ASN1ObjectIdentifier altSignatureValue = new ASN1ObjectIdentifier("2.5.29.74").intern();
+
+ /**
+ * delta certificate extension - prototype value will change!
+ */
+ public static final ASN1ObjectIdentifier deltaCertificateDescriptor = new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.1");
+
private ASN1ObjectIdentifier extnId;
private boolean critical;
private ASN1OctetString value;
@@ -210,7 +231,7 @@
boolean critical,
byte[] value)
{
- this(extnId, critical, new DEROctetString(value));
+ this(extnId, critical, new DEROctetString(Arrays.clone(value)));
}
/**
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 0795a08..d25187a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java
@@ -12,6 +12,7 @@
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.util.Properties;
/**
* <pre>
@@ -70,6 +71,11 @@
private Extensions(
ASN1Sequence seq)
{
+ if (seq.size() == 0)
+ {
+ throw new IllegalArgumentException("empty extension sequence found");
+ }
+
Enumeration e = seq.getObjects();
while (e.hasMoreElements())
@@ -78,7 +84,10 @@
if (extensions.containsKey(ext.getExtnId()))
{
- throw new IllegalArgumentException("repeated extension found: " + ext.getExtnId());
+ if (!Properties.isOverrideSet("org.bouncycastle.x509.ignore_repeated_extensions"))
+ {
+ throw new IllegalArgumentException("repeated extension found: " + ext.getExtnId());
+ }
}
extensions.put(ext.getExtnId(), ext);
@@ -106,6 +115,11 @@
public Extensions(
Extension[] extensions)
{
+ if (extensions == null || extensions.length == 0)
+ {
+ throw new IllegalArgumentException("extension array cannot be null or empty");
+ }
+
for (int i = 0; i != extensions.length; i++)
{
Extension ext = extensions[i];
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
index e4e2ffe..e5726d3 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
@@ -1,13 +1,22 @@
package org.bouncycastle.asn1.x509;
import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Set;
import java.util.Vector;
import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1ParsingException;
+import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.util.Arrays;
/**
* Generator for X.509 extensions
@@ -16,6 +25,18 @@
{
private Hashtable extensions = new Hashtable();
private Vector extOrdering = new Vector();
+ private static final Set dupsAllowed;
+
+
+ static
+ {
+ Set dups = new HashSet();
+ dups.add(Extension.subjectAlternativeName);
+ dups.add(Extension.issuerAlternativeName);
+ dups.add(Extension.subjectDirectoryAttributes);
+ dups.add(Extension.certificateIssuer);
+ dupsAllowed = Collections.unmodifiableSet(dups);
+ }
/**
* Reset the generator
@@ -30,14 +51,14 @@
* Add an extension with the given oid and the passed in value to be included
* in the OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
- * @param critical true if critical, false otherwise.
- * @param value the ASN.1 object to be included in the extension.
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the ASN.1 object to be included in the extension.
*/
public void addExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- ASN1Encodable value)
+ boolean critical,
+ ASN1Encodable value)
throws IOException
{
this.addExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER));
@@ -47,22 +68,52 @@
* Add an extension with the given oid and the passed in byte array to be wrapped in the
* OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
+ * @param oid OID for the extension.
* @param critical true if critical, false otherwise.
- * @param value the byte array to be wrapped.
+ * @param value the byte array to be wrapped.
*/
public void addExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- byte[] value)
+ boolean critical,
+ byte[] value)
{
if (extensions.containsKey(oid))
{
- throw new IllegalArgumentException("extension " + oid + " already added");
- }
+ if (dupsAllowed.contains(oid))
+ {
+ Extension existingExtension = (Extension)extensions.get(oid);
+ ASN1Sequence seq1 = ASN1Sequence.getInstance(DEROctetString.getInstance(existingExtension.getExtnValue()).getOctets());
+ ASN1Sequence seq2 = ASN1Sequence.getInstance(value);
- extOrdering.addElement(oid);
- extensions.put(oid, new Extension(oid, critical, new DEROctetString(value)));
+ ASN1EncodableVector items = new ASN1EncodableVector(seq1.size() + seq2.size());
+ for (Enumeration en = seq1.getObjects(); en.hasMoreElements();)
+ {
+ items.add((ASN1Encodable)en.nextElement());
+ }
+ for (Enumeration en = seq2.getObjects(); en.hasMoreElements();)
+ {
+ items.add((ASN1Encodable)en.nextElement());
+ }
+
+ try
+ {
+ extensions.put(oid, new Extension(oid, critical, new DERSequence(items).getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException(e.getMessage(), e);
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("extension " + oid + " already added");
+ }
+ }
+ else
+ {
+ extOrdering.addElement(oid);
+ extensions.put(oid, new Extension(oid, critical, new DEROctetString(Arrays.clone(value))));
+ }
}
/**
@@ -86,14 +137,14 @@
* Replace an extension with the given oid and the passed in value to be included
* in the OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
- * @param critical true if critical, false otherwise.
- * @param value the ASN.1 object to be included in the extension.
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the ASN.1 object to be included in the extension.
*/
public void replaceExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- ASN1Encodable value)
+ boolean critical,
+ ASN1Encodable value)
throws IOException
{
this.replaceExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER));
@@ -103,14 +154,14 @@
* Replace an extension with the given oid and the passed in byte array to be wrapped in the
* OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
+ * @param oid OID for the extension.
* @param critical true if critical, false otherwise.
- * @param value the byte array to be wrapped.
+ * @param value the byte array to be wrapped.
*/
public void replaceExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- byte[] value)
+ boolean critical,
+ byte[] value)
{
this.replaceExtension(new Extension(oid, critical, value));
}
@@ -156,7 +207,7 @@
*/
public boolean hasExtension(ASN1ObjectIdentifier oid)
{
- return extensions.containsKey(oid);
+ return extensions.containsKey(oid);
}
/**
@@ -167,7 +218,7 @@
*/
public Extension getExtension(ASN1ObjectIdentifier oid)
{
- return (Extension)extensions.get(oid);
+ return (Extension)extensions.get(oid);
}
/**
@@ -183,7 +234,7 @@
/**
* Generate an Extensions object based on the current state of the generator.
*
- * @return an X09Extensions object.
+ * @return an X09Extensions object.
*/
public Extensions generate()
{
@@ -196,4 +247,15 @@
return new Extensions(exts);
}
+
+ public void addExtension(Extensions extensions)
+ {
+ ASN1ObjectIdentifier[] oids = extensions.getExtensionOIDs();
+ for (int i = 0; i != oids.length; i++)
+ {
+ ASN1ObjectIdentifier ident = oids[i];
+ Extension ext = extensions.getExtension(ident);
+ addExtension(ASN1ObjectIdentifier.getInstance(ident), ext.isCritical(), ext.getExtnValue().getOctets());
+ }
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java
index 50b88d8..20c1910 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java
@@ -5,6 +5,7 @@
import org.bouncycastle.asn1.ASN1Choice;
import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1IA5String;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
@@ -194,7 +195,7 @@
case dNSName:
case rfc822Name:
case uniformResourceIdentifier:
- return new GeneralName(tag, DERIA5String.getInstance(tagObj, false));
+ return new GeneralName(tag, ASN1IA5String.getInstance(tagObj, false));
case directoryName:
return new GeneralName(tag, X500Name.getInstance(tagObj, true));
@@ -227,6 +228,11 @@
ASN1TaggedObject tagObj,
boolean explicit)
{
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
return GeneralName.getInstance(ASN1TaggedObject.getInstance(tagObj, true));
}
@@ -251,7 +257,7 @@
case rfc822Name:
case dNSName:
case uniformResourceIdentifier:
- buf.append(DERIA5String.getInstance(obj).getString());
+ buf.append(ASN1IA5String.getInstance(obj).getString());
break;
case directoryName:
buf.append(X500Name.getInstance(obj).toString());
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralSubtree.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralSubtree.java
index db06da4..53e782d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralSubtree.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralSubtree.java
@@ -203,7 +203,7 @@
v.add(base);
- if (minimum != null && !minimum.hasValue(ZERO))
+ if (minimum != null && !minimum.hasValue(0))
{
v.add(new DERTaggedObject(false, 0, minimum));
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Holder.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Holder.java
index 9a457b8..cdd3975 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Holder.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Holder.java
@@ -87,7 +87,7 @@
default:
throw new IllegalArgumentException("unknown tag in Holder");
}
- version = 0;
+ version = V1_CERTIFICATE_HOLDER;
}
/**
@@ -123,7 +123,7 @@
throw new IllegalArgumentException("unknown tag in Holder");
}
}
- version = 1;
+ version = V2_CERTIFICATE_HOLDER;
}
public Holder(IssuerSerial baseCertificateID)
@@ -209,7 +209,7 @@
public ASN1Primitive toASN1Primitive()
{
- if (version == 1)
+ if (version == V2_CERTIFICATE_HOLDER)
{
ASN1EncodableVector v = new ASN1EncodableVector(3);
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 4d8e323..df3af14 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java
@@ -2,22 +2,22 @@
import java.math.BigInteger;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x500.X500Name;
public class IssuerSerial
extends ASN1Object
{
- GeneralNames issuer;
- ASN1Integer serial;
- DERBitString issuerUID;
+ GeneralNames issuer;
+ ASN1Integer serial;
+ ASN1BitString issuerUID;
public static IssuerSerial getInstance(
Object obj)
@@ -55,7 +55,7 @@
if (seq.size() == 3)
{
- issuerUID = DERBitString.getInstance(seq.getObjectAt(2));
+ issuerUID = ASN1BitString.getInstance(seq.getObjectAt(2));
}
}
@@ -91,7 +91,7 @@
return serial;
}
- public DERBitString getIssuerUID()
+ public ASN1BitString getIssuerUID()
{
return issuerUID;
}
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 687fc99..ef78f62 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
@@ -1,5 +1,6 @@
package org.bouncycastle.asn1.x509;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Boolean;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Object;
@@ -152,7 +153,7 @@
switch (o.getTagNo())
{
case 0:
- // CHOICE so explicit
+ // CHOICE so explicit
distributionPoint = DistributionPointName.getInstance(o, true);
break;
case 1:
@@ -162,7 +163,7 @@
onlyContainsCACerts = ASN1Boolean.getInstance(o, false).isTrue();
break;
case 3:
- onlySomeReasons = new ReasonFlags(ReasonFlags.getInstance(o, false));
+ onlySomeReasons = new ReasonFlags(ASN1BitString.getInstance(o, false));
break;
case 4:
indirectCRL = ASN1Boolean.getInstance(o, false).isTrue();
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 18e056d..29d6316 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java
@@ -107,6 +107,30 @@
*/
public static final KeyPurposeId id_kp_capwapWTP = new KeyPurposeId(id_kp.branch("19"));
+
+ /**
+ * id-kp-cmcCA OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) kp(3) 27 }
+ */
+ public static final KeyPurposeId id_kp_cmcCA = new KeyPurposeId(id_kp.branch("27"));
+
+ /**
+ * id-kp-cmcRA OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) kp(3) 28 }
+ */
+ public static final KeyPurposeId id_kp_cmcRA = new KeyPurposeId(id_kp.branch("28"));
+
+ /**
+ * id-kp-cmKGA OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) kp(3) 32 }
+ */
+ public static final KeyPurposeId id_kp_cmKGA = new KeyPurposeId(id_kp.branch("32"));
+
+
+
//
// microsoft key purpose ids
//
@@ -140,15 +164,6 @@
this.id = id;
}
- /**
- * @param id string representation of an OID.
- * @deprecated use getInstance and an OID or one of the constants above.
- */
- public KeyPurposeId(String id)
- {
- this(new ASN1ObjectIdentifier(id));
- }
-
public static KeyPurposeId getInstance(Object o)
{
if (o instanceof KeyPurposeId)
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 8301013..78d2318 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,6 @@
package org.bouncycastle.asn1.x509;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DERBitString;
@@ -34,7 +35,7 @@
public static final int encipherOnly = (1 << 0);
public static final int decipherOnly = (1 << 15);
- private DERBitString bitString;
+ private ASN1BitString bitString;
public static KeyUsage getInstance(Object obj) // needs to be DERBitString for other VMs
{
@@ -44,7 +45,7 @@
}
else if (obj != null)
{
- return new KeyUsage(DERBitString.getInstance(obj));
+ return new KeyUsage(ASN1BitString.getInstance(obj));
}
return null;
@@ -69,7 +70,7 @@
}
private KeyUsage(
- DERBitString bitString)
+ ASN1BitString bitString)
{
this.bitString = bitString;
}
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 d055705..6f83541 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
@@ -1,5 +1,6 @@
package org.bouncycastle.asn1.x509;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Enumerated;
import org.bouncycastle.asn1.ASN1Object;
@@ -54,7 +55,7 @@
AlgorithmIdentifier digestAlgorithm;
- DERBitString objectDigest;
+ ASN1BitString objectDigest;
public static ObjectDigestInfo getInstance(
Object obj)
@@ -129,7 +130,7 @@
digestAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1 + offset));
- objectDigest = DERBitString.getInstance(seq.getObjectAt(2 + offset));
+ objectDigest = ASN1BitString.getInstance(seq.getObjectAt(2 + offset));
}
public ASN1Enumerated getDigestedObjectType()
@@ -147,7 +148,7 @@
return digestAlgorithm;
}
- public DERBitString getObjectDigest()
+ public ASN1BitString getObjectDigest()
{
return objectDigest;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/OtherName.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/OtherName.java
index 93cbafc..989d0d1 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/OtherName.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/OtherName.java
@@ -67,7 +67,7 @@
private OtherName(ASN1Sequence seq)
{
this.typeID = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
- this.value = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject(); // explicitly tagged
+ this.value = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
}
public ASN1ObjectIdentifier getTypeID()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
index 22bf7ce..b918f98 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
@@ -9,9 +9,9 @@
import java.util.Map;
import java.util.Set;
+import org.bouncycastle.asn1.ASN1IA5String;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;
-import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.IETFUtils;
@@ -1822,22 +1822,22 @@
private static String extractHostFromURL(String url)
{
// see RFC 1738
- // remove ':' after protocol, e.g. http:
+ // remove ':' after protocol, e.g. https:
String sub = url.substring(url.indexOf(':') + 1);
- // extract host from Common Internet Scheme Syntax, e.g. http://
+ // extract host from Common Internet Scheme Syntax, e.g. https://
if (sub.indexOf("//") != -1)
{
sub = sub.substring(sub.indexOf("//") + 2);
}
- // first remove port, e.g. http://test.com:21
+ // first remove port, e.g. https://test.com:21
if (sub.lastIndexOf(':') != -1)
{
sub = sub.substring(0, sub.lastIndexOf(':'));
}
- // remove user and password, e.g. http://john:[email protected]
+ // remove user and password, e.g. https://john:[email protected]
sub = sub.substring(sub.indexOf(':') + 1);
sub = sub.substring(sub.indexOf('@') + 1);
- // remove local parts, e.g. http://test.com/bla
+ // remove local parts, e.g. https://test.com/bla
if (sub.indexOf('/') != -1)
{
sub = sub.substring(0, sub.indexOf('/'));
@@ -1847,7 +1847,7 @@
private String extractNameAsString(GeneralName name)
{
- return DERIA5String.getInstance(name.getName()).getString();
+ return ASN1IA5String.getInstance(name.getName()).getString();
}
/**
@@ -2076,6 +2076,7 @@
temp.append(":");
try
{
+ // -DM Hex.toHexString
temp.append(Hex.toHexString(name.getValue().toASN1Primitive().getEncoded()));
}
catch (IOException e)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
index 6c6b89c..9b4a54f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
@@ -114,4 +114,9 @@
return new DERSequence(dev);
}
+
+ public String toString()
+ {
+ return "PolicyQualifierInfo[" + policyQualifierId + ", " + qualifier + "]";
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ReasonFlags.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ReasonFlags.java
index 612e2c5..5a405f0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ReasonFlags.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ReasonFlags.java
@@ -1,5 +1,6 @@
package org.bouncycastle.asn1.x509;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.DERBitString;
/**
@@ -78,7 +79,7 @@
}
public ReasonFlags(
- DERBitString reasons)
+ ASN1BitString reasons)
{
super(reasons.getBytes(), reasons.getPadBits());
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectAltPublicKeyInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectAltPublicKeyInfo.java
new file mode 100644
index 0000000..19e79fd
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectAltPublicKeyInfo.java
@@ -0,0 +1,108 @@
+package org.bouncycastle.asn1.x509;
+
+import org.bouncycastle.asn1.ASN1BitString;
+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.DERSequence;
+
+/**
+ * X.509 Section 9.8.2.
+ * <br/>
+ * This public-key certificate extension, when present, shall contain the subject’s alternative public key information
+ * <pre>
+ * subjectAltPublicKeyInfo EXTENSION ::= {
+ * SYNTAX SubjectAltPublicKeyInfo
+ * IDENTIFIED BY id-ce-subjectAltPublicKeyInfo }
+ *
+ * SubjectAltPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier{{SupportedAlgorithms}},
+ * subjectAltPublicKey BIT STRING }
+ * </pre>
+ * The SubjectAltPublicKeyInfo data type has the following components:
+ * <ul>
+ * <li>the algorithm subcomponent, which shall hold the algorithm that this public key is an instance of</li>
+ * <li>the subjectAltPublicKey subcomponent, which shall hold the alternative public key</li>
+ * </ul>
+ * This extension may be flagged as critical or as non-critical.
+ * <br/>
+ * NOTE – It is recommended that it be flagged as non-critical. Flagging it as critical would require relying parties to understand this
+ * extension and the alternative public-key algorithm.
+ */
+public class SubjectAltPublicKeyInfo
+ extends ASN1Object
+{
+ private AlgorithmIdentifier algorithm;
+ private ASN1BitString subjectAltPublicKey;
+
+ public static SubjectAltPublicKeyInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static SubjectAltPublicKeyInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof SubjectAltPublicKeyInfo)
+ {
+ return (SubjectAltPublicKeyInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new SubjectAltPublicKeyInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static SubjectAltPublicKeyInfo fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.subjectAltPublicKeyInfo));
+ }
+
+ private SubjectAltPublicKeyInfo(ASN1Sequence s)
+ {
+ if (s.size() != 2)
+ {
+ throw new IllegalArgumentException("extension should contain only 2 elements");
+ }
+ algorithm = AlgorithmIdentifier.getInstance(s.getObjectAt(0));
+ subjectAltPublicKey = ASN1BitString.getInstance(s.getObjectAt(1));
+ }
+
+ public SubjectAltPublicKeyInfo(AlgorithmIdentifier algorithm, ASN1BitString subjectAltPublicKey)
+ {
+ this.algorithm = algorithm;
+ this.subjectAltPublicKey = subjectAltPublicKey;
+ }
+
+ public SubjectAltPublicKeyInfo(SubjectPublicKeyInfo subjectPublicKeyInfo)
+ {
+ this.algorithm = subjectPublicKeyInfo.getAlgorithm();
+ this.subjectAltPublicKey = subjectPublicKeyInfo.getPublicKeyData();
+ }
+
+ public AlgorithmIdentifier getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public ASN1BitString getSubjectAltPublicKey()
+ {
+ return subjectAltPublicKey;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(algorithm);
+ v.add(subjectAltPublicKey);
+
+ return new DERSequence(v);
+ }
+}
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 5ad2952..9c2241c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
@@ -3,6 +3,7 @@
import java.io.IOException;
import java.util.Enumeration;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Object;
@@ -22,7 +23,7 @@
extends ASN1Object
{
private AlgorithmIdentifier algId;
- private DERBitString keyData;
+ private ASN1BitString keyData;
public static SubjectPublicKeyInfo getInstance(
ASN1TaggedObject obj,
@@ -48,6 +49,14 @@
public SubjectPublicKeyInfo(
AlgorithmIdentifier algId,
+ ASN1BitString publicKey)
+ {
+ this.keyData = publicKey;
+ this.algId = algId;
+ }
+
+ public SubjectPublicKeyInfo(
+ AlgorithmIdentifier algId,
ASN1Encodable publicKey)
throws IOException
{
@@ -75,10 +84,10 @@
+ seq.size());
}
- Enumeration e = seq.getObjects();
+ Enumeration e = seq.getObjects();
this.algId = AlgorithmIdentifier.getInstance(e.nextElement());
- this.keyData = DERBitString.getInstance(e.nextElement());
+ this.keyData = ASN1BitString.getInstance(e.nextElement());
}
public AlgorithmIdentifier getAlgorithm()
@@ -129,7 +138,7 @@
*
* @return the public key as the raw bit string...
*/
- public DERBitString getPublicKeyData()
+ public ASN1BitString getPublicKeyData()
{
return keyData;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java
index abaa909..deda9dd 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java
@@ -102,7 +102,7 @@
}
}
- private class RevokedCertificatesEnumeration
+ private static class RevokedCertificatesEnumeration
implements Enumeration
{
private final Enumeration en;
@@ -123,7 +123,7 @@
}
}
- private class EmptyEnumeration
+ private static class EmptyEnumeration
implements Enumeration
{
public boolean hasMoreElements()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
index 6ae198a..7676329 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
@@ -1,18 +1,15 @@
package org.bouncycastle.asn1.x509;
-import java.math.BigInteger;
-
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.Properties;
/**
@@ -47,8 +44,8 @@
Time startDate, endDate;
X500Name subject;
SubjectPublicKeyInfo subjectPublicKeyInfo;
- DERBitString issuerUniqueId;
- DERBitString subjectUniqueId;
+ ASN1BitString issuerUniqueId;
+ ASN1BitString subjectUniqueId;
Extensions extensions;
public static TBSCertificate getInstance(
@@ -96,15 +93,15 @@
boolean isV1 = false;
boolean isV2 = false;
- if (version.hasValue(BigInteger.valueOf(0)))
+ if (version.hasValue(0))
{
isV1 = true;
}
- else if (version.hasValue(BigInteger.valueOf(1)))
+ else if (version.hasValue(1))
{
isV2 = true;
}
- else if (!version.hasValue(BigInteger.valueOf(2)))
+ else if (!version.hasValue(2))
{
throw new IllegalArgumentException("version number not recognised");
}
@@ -142,10 +139,10 @@
switch (extra.getTagNo())
{
case 1:
- issuerUniqueId = DERBitString.getInstance(extra, false);
+ issuerUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 2:
- subjectUniqueId = DERBitString.getInstance(extra, false);
+ subjectUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 3:
if (isV2)
@@ -206,12 +203,12 @@
return subjectPublicKeyInfo;
}
- public DERBitString getIssuerUniqueId()
+ public ASN1BitString getIssuerUniqueId()
{
return issuerUniqueId;
}
- public DERBitString getSubjectUniqueId()
+ public ASN1BitString getSubjectUniqueId()
{
return subjectUniqueId;
}
@@ -238,7 +235,7 @@
ASN1EncodableVector v = new ASN1EncodableVector();
// DEFAULT Zero
- if (!version.hasValue(BigIntegers.ZERO))
+ if (!version.hasValue(0))
{
v.add(new DERTaggedObject(true, 0, version));
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
index b635d59..440ca5d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
@@ -1,11 +1,11 @@
package org.bouncycastle.asn1.x509;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
@@ -43,8 +43,8 @@
Time startDate, endDate;
X500Name subject;
SubjectPublicKeyInfo subjectPublicKeyInfo;
- DERBitString issuerUniqueId;
- DERBitString subjectUniqueId;
+ ASN1BitString issuerUniqueId;
+ ASN1BitString subjectUniqueId;
X509Extensions extensions;
public static TBSCertificateStructure getInstance(
@@ -116,10 +116,10 @@
switch (extra.getTagNo())
{
case 1:
- issuerUniqueId = DERBitString.getInstance(extra, false);
+ issuerUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 2:
- subjectUniqueId = DERBitString.getInstance(extra, false);
+ subjectUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 3:
extensions = X509Extensions.getInstance(extra);
@@ -172,12 +172,12 @@
return subjectPublicKeyInfo;
}
- public DERBitString getIssuerUniqueId()
+ public ASN1BitString getIssuerUniqueId()
{
return issuerUniqueId;
}
- public DERBitString getSubjectUniqueId()
+ public ASN1BitString getSubjectUniqueId()
{
return subjectUniqueId;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Time.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Time.java
index a99dddf..0efba33 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Time.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Time.java
@@ -16,6 +16,7 @@
import org.bouncycastle.asn1.ASN1UTCTime;
import org.bouncycastle.asn1.DERGeneralizedTime;
import org.bouncycastle.asn1.DERUTCTime;
+import org.bouncycastle.asn1.LocaleUtil;
public class Time
extends ASN1Object
@@ -27,7 +28,12 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
+ return getInstance(obj.getExplicitBaseObject());
}
public Time(
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V2Form.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V2Form.java
index bd4c59c..6063439 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V2Form.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V2Form.java
@@ -67,10 +67,7 @@
this.objectDigestInfo = objectDigestInfo;
}
- /**
- * @deprecated use getInstance().
- */
- public V2Form(
+ private V2Form(
ASN1Sequence seq)
{
if (seq.size() > 3)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
index c4ebdc1..4434d73 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
@@ -2,6 +2,8 @@
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1UTCTime;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
@@ -155,20 +157,34 @@
}
}
- public TBSCertificate generateTBSCertificate()
+ public ASN1Sequence generatePreTBSCertificate()
{
- if ((serialNumber == null) || (signature == null)
+ if (signature != null)
+ {
+ throw new IllegalStateException("signature field should not be set in PreTBSCertificate");
+ }
+ if ((serialNumber == null)
|| (issuer == null) || (startDate == null) || (endDate == null)
|| (subject == null && !altNamePresentAndCritical) || (subjectPublicKeyInfo == null))
{
throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator");
}
+ return generateTBSStructure();
+ }
+
+ private ASN1Sequence generateTBSStructure()
+ {
ASN1EncodableVector v = new ASN1EncodableVector(10);
v.add(version);
v.add(serialNumber);
- v.add(signature);
+
+ if (signature != null)
+ {
+ v.add(signature);
+ }
+
v.add(issuer);
//
@@ -208,6 +224,18 @@
v.add(new DERTaggedObject(true, 3, extensions));
}
- return TBSCertificate.getInstance(new DERSequence(v));
+ return new DERSequence(v);
+ }
+
+ public TBSCertificate generateTBSCertificate()
+ {
+ if ((serialNumber == null) || (signature == null)
+ || (issuer == null) || (startDate == null) || (endDate == null)
+ || (subject == null && !altNamePresentAndCritical) || (subjectPublicKeyInfo == null))
+ {
+ throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator");
+ }
+
+ return TBSCertificate.getInstance(generateTBSStructure());
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509CertificateStructure.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509CertificateStructure.java
index 6830030..7c25580 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509CertificateStructure.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509CertificateStructure.java
@@ -1,11 +1,11 @@
package org.bouncycastle.asn1.x509;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
@@ -27,7 +27,7 @@
ASN1Sequence seq;
TBSCertificateStructure tbsCert;
AlgorithmIdentifier sigAlgId;
- DERBitString sig;
+ ASN1BitString sig;
public static X509CertificateStructure getInstance(
ASN1TaggedObject obj,
@@ -64,7 +64,7 @@
tbsCert = TBSCertificateStructure.getInstance(seq.getObjectAt(0));
sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- sig = DERBitString.getInstance(seq.getObjectAt(2));
+ sig = ASN1BitString.getInstance(seq.getObjectAt(2));
}
else
{
@@ -117,7 +117,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sig;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
index 0ae0f80..c888754 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
@@ -8,6 +8,7 @@
import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DERPrintableString;
import org.bouncycastle.asn1.DERUTF8String;
+import org.bouncycastle.asn1.x500.style.BCStyle;
/**
* The default converter for X509 DN entries when going from their
@@ -45,16 +46,16 @@
{
value = value.substring(1);
}
- if (oid.equals(X509Name.EmailAddress) || oid.equals(X509Name.DC))
+ if (oid.equals(BCStyle.EmailAddress) || oid.equals(BCStyle.DC))
{
return new DERIA5String(value);
}
- else if (oid.equals(X509Name.DATE_OF_BIRTH)) // accept time string as well as # (for compatibility)
+ else if (oid.equals(BCStyle.DATE_OF_BIRTH)) // accept time string as well as # (for compatibility)
{
return new DERGeneralizedTime(value);
}
- else if (oid.equals(X509Name.C) || oid.equals(X509Name.SN) || oid.equals(X509Name.DN_QUALIFIER)
- || oid.equals(X509Name.TELEPHONE_NUMBER))
+ else if (oid.equals(BCStyle.C) || oid.equals(BCStyle.SERIALNUMBER) || oid.equals(BCStyle.DN_QUALIFIER)
+ || oid.equals(BCStyle.TELEPHONE_NUMBER))
{
return new DERPrintableString(value);
}
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 86e3b24..b43ecd3 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java
@@ -12,10 +12,11 @@
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.BERTags;
import org.bouncycastle.asn1.DERSequence;
/**
- * @deprecated use {@link Extensions}
+ * @deprecated use {@link Extension} and {@link Extensions}
*/
public class X509Extensions
extends ASN1Object
@@ -236,7 +237,9 @@
if (obj instanceof ASN1TaggedObject)
{
- return getInstance(((ASN1TaggedObject)obj).getObject());
+ ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC);
+
+ return getInstance(taggedObject.getBaseObject().toASN1Primitive());
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
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 9f8d9b9..c931797 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Name.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Name.java
@@ -15,9 +15,9 @@
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1String;
import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.ASN1UniversalString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERSet;
-import org.bouncycastle.asn1.DERUniversalString;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.util.Strings;
@@ -425,7 +425,7 @@
ordering.addElement(ASN1ObjectIdentifier.getInstance(s.getObjectAt(0)));
ASN1Encodable value = s.getObjectAt(1);
- if (value instanceof ASN1String && !(value instanceof DERUniversalString))
+ if (value instanceof ASN1String && !(value instanceof ASN1UniversalString))
{
String v = ((ASN1String)value).getString();
if (v.length() > 0 && v.charAt(0) == '#')
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameEntryConverter.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
index b5de2e0..42e50c5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
@@ -4,7 +4,7 @@
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.DERPrintableString;
+import org.bouncycastle.asn1.ASN1PrintableString;
import org.bouncycastle.util.encoders.Hex;
/**
@@ -71,7 +71,7 @@
protected boolean canBePrintable(
String str)
{
- return DERPrintableString.isPrintableString(str);
+ return ASN1PrintableString.isPrintableString(str);
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
index 02857c7..c1eab27 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
@@ -107,4 +107,11 @@
static final ASN1ObjectIdentifier ocspAccessMethod = id_ad_ocsp;
/** OID for crl uri in AuthorityInformationAccess extension */
static final ASN1ObjectIdentifier crlAccessMethod = id_ad_caIssuers;
+
+
+ /**
+ * id-PasswordBasedMac OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) nt(113533) nsn(7) algorithms(66) 13 }
+ */
+ static final ASN1ObjectIdentifier id_PasswordBasedMac = new ASN1ObjectIdentifier("1.2.840.113533.7.66.13");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
index 8def60c..053dc2c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
@@ -1,12 +1,12 @@
package org.bouncycastle.asn1.x9;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
/**
@@ -14,7 +14,7 @@
*/
public class DHValidationParms extends ASN1Object
{
- private DERBitString seed;
+ private ASN1BitString seed;
private ASN1Integer pgenCounter;
public static DHValidationParms getInstance(ASN1TaggedObject obj, boolean explicit)
@@ -36,7 +36,7 @@
return null;
}
- public DHValidationParms(DERBitString seed, ASN1Integer pgenCounter)
+ public DHValidationParms(ASN1BitString seed, ASN1Integer pgenCounter)
{
if (seed == null)
{
@@ -58,11 +58,11 @@
throw new IllegalArgumentException("Bad sequence size: " + seq.size());
}
- this.seed = DERBitString.getInstance(seq.getObjectAt(0));
+ this.seed = ASN1BitString.getInstance(seq.getObjectAt(0));
this.pgenCounter = ASN1Integer.getInstance(seq.getObjectAt(1));
}
- public DERBitString getSeed()
+ public ASN1BitString getSeed()
{
return this.seed;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
index 1d68df7..32a4845 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
@@ -69,6 +69,47 @@
return ecP;
}
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ X9ECParametersHolder holder = X962NamedCurves.getByNameLazy(name);
+
+ if (null == holder)
+ {
+ holder = SECNamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = NISTNamedCurves.getByNameLazy(name);
+ }
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ if (null == holder)
+ {
+ holder = TeleTrusTNamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = ANSSINamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = ECGOST3410NamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = GMNamedCurves.getByNameLazy(name);
+ }
+ */
+ // END Android-removed: Unsupported curves
+
+ return holder;
+ }
+
/**
* return the object identifier signified by the passed in name. Null
* if there is no object identifier associated with name.
@@ -222,6 +263,44 @@
return ecP;
}
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ X9ECParametersHolder holder = X962NamedCurves.getByOIDLazy(oid);
+
+ if (null == holder)
+ {
+ holder = SECNamedCurves.getByOIDLazy(oid);
+ }
+
+ // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ if (null == holder)
+ {
+ holder = TeleTrusTNamedCurves.getByOIDLazy(oid);
+ }
+
+ if (null == holder)
+ {
+ holder = ANSSINamedCurves.getByOIDLazy(oid);
+ }
+
+ if (null == holder)
+ {
+ holder = ECGOST3410NamedCurves.getByOIDLazy(oid);
+ }
+
+ if (null == holder)
+ {
+ holder = GMNamedCurves.getByOIDLazy(oid);
+ }
+ */
+ // END Android-removed: Unsupported curves
+
+ return holder;
+ }
+
/**
* return an enumeration of the names of the available curves.
*
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java
index 466e265..47d16ca 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java
@@ -2,6 +2,7 @@
import java.math.BigInteger;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
@@ -23,7 +24,7 @@
public class ValidationParams
extends ASN1Object
{
- private DERBitString seed;
+ private ASN1BitString seed;
private ASN1Integer pgenCounter;
public static ValidationParams getInstance(ASN1TaggedObject obj, boolean explicit)
@@ -78,7 +79,7 @@
throw new IllegalArgumentException("Bad sequence size: " + seq.size());
}
- this.seed = DERBitString.getInstance(seq.getObjectAt(0));
+ this.seed = ASN1BitString.getInstance(seq.getObjectAt(0));
this.pgenCounter = ASN1Integer.getInstance(seq.getObjectAt(1));
}
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 3d1ddd5..38690fd 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java
@@ -35,141 +35,183 @@
static X9ECParametersHolder prime192v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("ffffffffffffffffffffffff99def836146bc9b1b4d22831");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
fromHex("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("3045AE6FC8422f64ED579528D38120EAE12196D5");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("3045AE6FC8422f64ED579528D38120EAE12196D5"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime192v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
fromHex("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("31a92ee2029fd10d901b113e990710f0d21ac6b6");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("31a92ee2029fd10d901b113e990710f0d21ac6b6"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime192v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("ffffffffffffffffffffffff7a62d031c83f4294f640ec13");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
fromHex("22123dc2395a05caa7423daeccc94760a7d462256bd56916"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("c469684435deb378c4b65ca9591e2a5763059a2e");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"027d29778100c65a1da1783716588dce2b8b4aee8e228f1896");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c469684435deb378c4b65ca9591e2a5763059a2e"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime239v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
fromHex("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("e43bb460f0b80cc0c0b075798e948060f8321b7d");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e43bb460f0b80cc0c0b075798e948060f8321b7d"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime239v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
fromHex("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("e8b4011604095303ca3b8099982be09fcb9ae616");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e8b4011604095303ca3b8099982be09fcb9ae616"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime239v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
fromHex("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("7d7374168ffe3471b60a857686a19475d3bfa2ff");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("7d7374168ffe3471b60a857686a19475d3bfa2ff"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime256v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"),
fromHex("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc"),
fromHex("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("c49d360886e704936a6678e1139d26b7819f7e90");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c49d360886e704936a6678e1139d26b7819f7e90"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -178,337 +220,433 @@
*/
static X9ECParametersHolder c2pnb163v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0400000000000000000001E60FC8821CC74DAEAFC1");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
fromHex("072546B5435234A422E0789675F432C89435DE5242"),
fromHex("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("D2C0FB15760860DEF1EEF4D696E6768756151754");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0307AF69989546103D79329FCC3D74880F33BBE803CB");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("D2C0FB15760860DEF1EEF4D696E6768756151754"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb163v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
fromHex("0108B39E77C4B108BED981ED0E890E117C511CF072"),
fromHex("0667ACEB38AF4E488C407433FFAE4F1C811638DF20"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"030024266E4EB5106D0A964D92C4860E2671DB9B6CC5");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb163v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
fromHex("07A526C63D3E25A256A007699F5447E32AE456B50E"),
fromHex("03F7061798EB99E238FD6F1BF95B48FEEB4854252B"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb176w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("010092537397ECA4F6145799D62B0A19CE06FE26AD");
BigInteger h = BigInteger.valueOf(0xFF6E);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
176,
1, 2, 43,
fromHex("E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B"),
fromHex("5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"038D16C2866798B600F9F08BB4A8E860F3298CE04A5798");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb191v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("40000000000000000000000004A20E90C39067C893BBB9A5");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
191,
9,
fromHex("2866537B676752636A68F56554E12640276B649EF7526267"),
fromHex("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("4E13CA542744D696E67687561517552F279A8C84");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("4E13CA542744D696E67687561517552F279A8C84"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb191v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("20000000000000000000000050508CB89F652824E06B8173");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
191,
9,
fromHex("401028774D7777C7B7666D1366EA432071274F89FF01E718"),
fromHex("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb191v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("155555555555555555555555610C0B196812BFB6288A3EA3");
BigInteger h = BigInteger.valueOf(6);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
191,
9,
fromHex("6C01074756099122221056911C77D77E77A777E7E7E77FCB"),
fromHex("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"03375D4CE24FDE434489DE8746E71786015009E66E38A926DD");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb208w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D");
BigInteger h = BigInteger.valueOf(0xFE48);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
208,
1, 2, 83,
BigInteger.valueOf(0),
fromHex("C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb239v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
239,
36,
fromHex("32010857077C5431123A46B808906756F543423E8D27877578125778AC76"),
fromHex("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb239v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D");
BigInteger h = BigInteger.valueOf(6);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
239,
36,
fromHex("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F"),
fromHex("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb239v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF");
BigInteger h = BigInteger.valueOf(10);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
239,
36,
fromHex("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F"),
fromHex("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb272w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521");
BigInteger h = BigInteger.valueOf(0xFF06);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
272,
1, 3, 56,
fromHex("91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20"),
fromHex("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb304w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D");
BigInteger h = BigInteger.valueOf(0xFE2E);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
304,
1, 2, 11,
fromHex("FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681"),
fromHex("BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb359v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B");
BigInteger h = BigInteger.valueOf(0x4C);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
359,
68,
fromHex("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557"),
fromHex("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb368w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967");
BigInteger h = BigInteger.valueOf(0xFF70);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
368,
1, 2, 85,
fromHex("E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D"),
fromHex("FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb431r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91");
BigInteger h = BigInteger.valueOf(0x2760);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
431,
120,
fromHex("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F"),
fromHex("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -551,17 +689,16 @@
defineCurve("c2tnb431r1", X9ObjectIdentifiers.c2tnb431r1, c2tnb431r1);
}
- public static X9ECParameters getByName(
- String name)
+ public static X9ECParameters getByName(String name)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name));
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOID(oid);
+ }
- if (oid != null)
- {
- return getByOID(oid);
- }
-
- return null;
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOIDLazy(oid);
}
/**
@@ -570,17 +707,15 @@
*
* @param oid an object identifier representing a named curve, if present.
*/
- public static X9ECParameters getByOID(
- ASN1ObjectIdentifier oid)
+ public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid);
+ X9ECParametersHolder holder = getByOIDLazy(oid);
+ return holder == null ? null : holder.getParameters();
+ }
- if (holder != null)
- {
- return holder.getParameters();
- }
-
- return null;
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return (X9ECParametersHolder)curves.get(oid);
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
index eb067e6..b7b29be 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
@@ -48,7 +48,12 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
+ return getInstance(obj.getExplicitBaseObject());
}
public X962Parameters(
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java
index 5a1c0be..31f5d42 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java
@@ -36,7 +36,7 @@
ASN1Sequence seq)
{
if (!(seq.getObjectAt(0) instanceof ASN1Integer)
- || !((ASN1Integer)seq.getObjectAt(0)).hasValue(ONE))
+ || !((ASN1Integer)seq.getObjectAt(0)).hasValue(1))
{
throw new IllegalArgumentException("bad version in X9ECParameters");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParametersHolder.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
index 2dd8ff1..e2b7ea2 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
@@ -1,12 +1,25 @@
package org.bouncycastle.asn1.x9;
+import org.bouncycastle.math.ec.ECCurve;
+
/**
* A holding class that allows for X9ECParameters to be lazily constructed.
*/
public abstract class X9ECParametersHolder
{
+ private ECCurve curve;
private X9ECParameters params;
+ public synchronized ECCurve getCurve()
+ {
+ if (curve == null)
+ {
+ curve = createCurve();
+ }
+
+ return curve;
+ }
+
public synchronized X9ECParameters getParameters()
{
if (params == null)
@@ -17,5 +30,10 @@
return params;
}
+ protected ECCurve createCurve()
+ {
+ return createParameters().getCurve();
+ }
+
protected abstract X9ECParameters createParameters();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9FieldElement.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9FieldElement.java
index 4cba82d..1612a99 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9FieldElement.java
@@ -1,9 +1,6 @@
package org.bouncycastle.asn1.x9;
-import java.math.BigInteger;
-
import org.bouncycastle.asn1.ASN1Object;
-import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.math.ec.ECFieldElement;
@@ -23,22 +20,6 @@
this.f = f;
}
- /**
- * @deprecated Will be removed
- */
- public X9FieldElement(BigInteger p, ASN1OctetString s)
- {
- this(new ECFieldElement.Fp(p, new BigInteger(1, s.getOctets())));
- }
-
- /**
- * @deprecated Will be removed
- */
- public X9FieldElement(int m, int k1, int k2, int k3, ASN1OctetString s)
- {
- this(new ECFieldElement.F2m(m, k1, k2, k3, new BigInteger(1, s.getOctets())));
- }
-
public ECFieldElement getValue()
{
return f;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/AlphabetMapper.java b/bcprov/src/main/java/org/bouncycastle/crypto/AlphabetMapper.java
new file mode 100644
index 0000000..f40d989
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/AlphabetMapper.java
@@ -0,0 +1,32 @@
+package org.bouncycastle.crypto;
+
+/**
+ * Base interface for mapping from an alphabet to a set of indexes
+ * suitable for use with FPE.
+ */
+public interface AlphabetMapper
+{
+ /**
+ * Return the number of characters in the alphabet.
+ *
+ * @return the radix for the alphabet.
+ */
+ int getRadix();
+
+ /**
+ * Return the passed in char[] as a byte array of indexes (indexes
+ * can be more than 1 byte)
+ *
+ * @param input characters to be mapped.
+ * @return an index array.
+ */
+ byte[] convertToIndexes(char[] input);
+
+ /**
+ * Return a char[] for this alphabet based on the indexes passed.
+ *
+ * @param input input array of indexes.
+ * @return an array of char corresponding to the index values.
+ */
+ char[] convertToChars(byte[] input);
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/BlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/BlockCipher.java
index 3cfa25a..370225f 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/BlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/BlockCipher.java
@@ -36,16 +36,16 @@
* Process one block of input from the array in and write it to
* the out array.
*
- * @param in the array containing the input data.
+ * @param input the array containing the input data.
* @param inOff offset into the in array the data starts at.
- * @param out the array the output data will be copied into.
+ * @param output the array the output data will be copied into.
* @param outOff the offset into the out array the output will start at.
- * @exception DataLengthException if there isn't enough data in in, or
+ * @exception DataLengthException if there isn't enough data in input , or
* space in out.
* @exception IllegalStateException if the cipher isn't initialised.
* @return the number of bytes processed and produced.
*/
- public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
+ public int processBlock(byte[] input, int inOff, byte[] output, int outOff)
throws DataLengthException, IllegalStateException;
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
index 8ab2cdc..6a29741 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
@@ -14,8 +14,9 @@
protected byte[] buf;
protected int bufOff;
- protected boolean forEncryption;
- protected BlockCipher cipher;
+ protected boolean forEncryption;
+ protected BlockCipher cipher;
+ protected MultiBlockCipher mbCipher;
protected boolean partialBlockOkay;
protected boolean pgpCFB;
@@ -23,7 +24,7 @@
/**
* constructor for subclasses
*/
- protected BufferedBlockCipher()
+ BufferedBlockCipher()
{
}
@@ -31,13 +32,24 @@
* Create a buffered block cipher without padding.
*
* @param cipher the underlying block cipher this buffering object wraps.
+ * @deprecated use the constructor on DefaultBufferedBlockCipher.
*/
public BufferedBlockCipher(
BlockCipher cipher)
{
this.cipher = cipher;
- buf = new byte[cipher.getBlockSize()];
+ if (cipher instanceof MultiBlockCipher)
+ {
+ this.mbCipher = (MultiBlockCipher)cipher;
+ buf = new byte[mbCipher.getMultiBlockSize()];
+ }
+ else
+ {
+ this.mbCipher = null;
+ buf = new byte[cipher.getBlockSize()];
+ }
+
bufOff = 0;
//
@@ -143,6 +155,11 @@
public int getOutputSize(
int length)
{
+ if (pgpCFB && forEncryption)
+ {
+ return length + bufOff + (cipher.getBlockSize() + 2);
+ }
+
// Note: Can assume partialBlockOkay is true for purposes of this calculation
return length + bufOff;
}
@@ -225,12 +242,29 @@
len -= gapLen;
inOff += gapLen;
- while (len > buf.length)
+ if (mbCipher != null)
{
- resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen);
+ int blockCount = len / mbCipher.getMultiBlockSize();
- len -= blockSize;
- inOff += blockSize;
+ if (blockCount > 0)
+ {
+ resultLen += mbCipher.processBlocks(in, inOff, blockCount, out, outOff + resultLen);
+
+ int processed = blockCount * mbCipher.getMultiBlockSize();
+
+ len -= processed;
+ inOff += processed;
+ }
+ }
+ else
+ {
+ while (len > buf.length)
+ {
+ resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen);
+
+ len -= blockSize;
+ inOff += blockSize;
+ }
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/CipherKeyGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/CipherKeyGenerator.java
index 451f8e8..9b41d71 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/CipherKeyGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/CipherKeyGenerator.java
@@ -2,6 +2,8 @@
import java.security.SecureRandom;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+
/**
* The base class for symmetric, or secret, cipher key generators.
*/
@@ -20,6 +22,8 @@
{
this.random = param.getRandom();
this.strength = (param.getStrength() + 7) / 8;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("SymKeyGen", param.getStrength()));
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServiceConstraintsException.java b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServiceConstraintsException.java
new file mode 100644
index 0000000..015557a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServiceConstraintsException.java
@@ -0,0 +1,10 @@
+package org.bouncycastle.crypto;
+
+public class CryptoServiceConstraintsException
+ extends RuntimeException
+{
+ public CryptoServiceConstraintsException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServiceProperties.java b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServiceProperties.java
new file mode 100644
index 0000000..07a5440
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServiceProperties.java
@@ -0,0 +1,12 @@
+package org.bouncycastle.crypto;
+
+public interface CryptoServiceProperties
+{
+ int bitsOfSecurity();
+
+ String getServiceName();
+
+ CryptoServicePurpose getPurpose();
+
+ Object getParams();
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicePurpose.java b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicePurpose.java
new file mode 100644
index 0000000..2789326
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicePurpose.java
@@ -0,0 +1,15 @@
+package org.bouncycastle.crypto;
+
+public enum CryptoServicePurpose
+{
+ AGREEMENT,
+ ENCRYPTION,
+ DECRYPTION,
+ KEYGEN,
+ SIGNING, // for signatures (and digests)
+ VERIFYING,
+ AUTHENTICATION, // for MACs (and digests)
+ VERIFICATION,
+ PRF,
+ ANY
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesConstraints.java b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesConstraints.java
new file mode 100644
index 0000000..1fc4488
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesConstraints.java
@@ -0,0 +1,6 @@
+package org.bouncycastle.crypto;
+
+public interface CryptoServicesConstraints
+{
+ void check(CryptoServiceProperties service);
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesPermission.java b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesPermission.java
index 8a62a8d..608436a 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesPermission.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesPermission.java
@@ -25,6 +25,11 @@
*/
public static final String DEFAULT_RANDOM = "defaultRandomConfig";
+ /**
+ * Enable the setting of the constraints.
+ */
+ public static final String CONSTRAINTS = "constraints";
+
private final Set<String> actions = new HashSet<String>();
public CryptoServicesPermission(String name)
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java
index 6b28394..90d3c85 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java
@@ -8,12 +8,16 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Logger;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.params.DHParameters;
import org.bouncycastle.crypto.params.DHValidationParameters;
import org.bouncycastle.crypto.params.DSAParameters;
import org.bouncycastle.crypto.params.DSAValidationParameters;
+import org.bouncycastle.util.Properties;
+import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
/**
@@ -21,15 +25,28 @@
*/
public final class CryptoServicesRegistrar
{
+ private static final Logger LOG = Logger.getLogger(CryptoServicesRegistrar.class.getName());
+
private static final Permission CanSetDefaultProperty = new CryptoServicesPermission(CryptoServicesPermission.GLOBAL_CONFIG);
private static final Permission CanSetThreadProperty = new CryptoServicesPermission(CryptoServicesPermission.THREAD_LOCAL_CONFIG);
private static final Permission CanSetDefaultRandom = new CryptoServicesPermission(CryptoServicesPermission.DEFAULT_RANDOM);
+ private static final Permission CanSetConstraints = new CryptoServicesPermission(CryptoServicesPermission.CONSTRAINTS);
private static final ThreadLocal<Map<String, Object[]>> threadProperties = new ThreadLocal<Map<String, Object[]>>();
private static final Map<String, Object[]> globalProperties = Collections.synchronizedMap(new HashMap<String, Object[]>());
+ private static final SecureRandomProvider defaultRandomProviderImpl = new ThreadLocalSecureRandomProvider();
- private static final Object cacheLock = new Object();
- private static SecureRandom defaultSecureRandom;
+ private static final CryptoServicesConstraints noConstraintsImpl = new CryptoServicesConstraints()
+ {
+ public void check(CryptoServiceProperties service)
+ {
+ // anything goes.
+ }
+ };
+
+ private static final AtomicReference<SecureRandomProvider> defaultSecureRandomProvider = new AtomicReference<SecureRandomProvider>();
+ private static final boolean preconfiguredConstraints;
+ private static final AtomicReference<CryptoServicesConstraints> servicesConstraints = new AtomicReference<CryptoServicesConstraints>();
static
{
@@ -43,56 +60,59 @@
DSAParameters def768Params = new DSAParameters(
new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5" +
- "d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a" +
- "22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45" +
- "ee3688c11a8c56ab127a3daf", 16),
+ "d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a" +
+ "22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45" +
+ "ee3688c11a8c56ab127a3daf", 16),
new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16),
new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7" +
- "a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d366844577" +
- "1f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a" +
- "7064f316933a346d3f529252", 16),
+ "a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d366844577" +
+ "1f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a" +
+ "7064f316933a346d3f529252", 16),
new DSAValidationParameters(Hex.decodeStrict("77d0f8c4dad15eb8c4f2f8d6726cefd96d5bb399"), 263));
DSAParameters def1024Params = new DSAParameters(
new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80" +
- "b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b" +
- "801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c6" +
- "1bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675" +
- "f3ae2b61d72aeff22203199dd14801c7", 16),
+ "b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b" +
+ "801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c6" +
+ "1bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675" +
+ "f3ae2b61d72aeff22203199dd14801c7", 16),
new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16),
new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b" +
- "3d0782675159578ebad4594fe67107108180b449167123e84c281613" +
- "b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f" +
- "0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06" +
- "928b665e807b552564014c3bfecf492a", 16),
+ "3d0782675159578ebad4594fe67107108180b449167123e84c281613" +
+ "b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f" +
+ "0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06" +
+ "928b665e807b552564014c3bfecf492a", 16),
new DSAValidationParameters(Hex.decodeStrict("8d5155894229d5e689ee01e6018a237e2cae64cd"), 92));
DSAParameters def2048Params = new DSAParameters(
new BigInteger("95475cf5d93e596c3fcd1d902add02f427f5f3c7210313bb45fb4d5b" +
- "b2e5fe1cbd678cd4bbdd84c9836be1f31c0777725aeb6c2fc38b85f4" +
- "8076fa76bcd8146cc89a6fb2f706dd719898c2083dc8d896f84062e2" +
- "c9c94d137b054a8d8096adb8d51952398eeca852a0af12df83e475aa" +
- "65d4ec0c38a9560d5661186ff98b9fc9eb60eee8b030376b236bc73b" +
- "e3acdbd74fd61c1d2475fa3077b8f080467881ff7e1ca56fee066d79" +
- "506ade51edbb5443a563927dbc4ba520086746175c8885925ebc64c6" +
- "147906773496990cb714ec667304e261faee33b3cbdf008e0c3fa906" +
- "50d97d3909c9275bf4ac86ffcb3d03e6dfc8ada5934242dd6d3bcca2" +
- "a406cb0b", 16),
+ "b2e5fe1cbd678cd4bbdd84c9836be1f31c0777725aeb6c2fc38b85f4" +
+ "8076fa76bcd8146cc89a6fb2f706dd719898c2083dc8d896f84062e2" +
+ "c9c94d137b054a8d8096adb8d51952398eeca852a0af12df83e475aa" +
+ "65d4ec0c38a9560d5661186ff98b9fc9eb60eee8b030376b236bc73b" +
+ "e3acdbd74fd61c1d2475fa3077b8f080467881ff7e1ca56fee066d79" +
+ "506ade51edbb5443a563927dbc4ba520086746175c8885925ebc64c6" +
+ "147906773496990cb714ec667304e261faee33b3cbdf008e0c3fa906" +
+ "50d97d3909c9275bf4ac86ffcb3d03e6dfc8ada5934242dd6d3bcca2" +
+ "a406cb0b", 16),
new BigInteger("f8183668ba5fc5bb06b5981e6d8b795d30b8978d43ca0ec572e37e09939a9773", 16),
new BigInteger("42debb9da5b3d88cc956e08787ec3f3a09bba5f48b889a74aaf53174" +
- "aa0fbe7e3c5b8fcd7a53bef563b0e98560328960a9517f4014d3325f" +
- "c7962bf1e049370d76d1314a76137e792f3f0db859d095e4a5b93202" +
- "4f079ecf2ef09c797452b0770e1350782ed57ddf794979dcef23cb96" +
- "f183061965c4ebc93c9c71c56b925955a75f94cccf1449ac43d586d0" +
- "beee43251b0b2287349d68de0d144403f13e802f4146d882e057af19" +
- "b6f6275c6676c8fa0e3ca2713a3257fd1b27d0639f695e347d8d1cf9" +
- "ac819a26ca9b04cb0eb9b7b035988d15bbac65212a55239cfc7e58fa" +
- "e38d7250ab9991ffbc97134025fe8ce04c4399ad96569be91a546f49" +
- "78693c7a", 16),
+ "aa0fbe7e3c5b8fcd7a53bef563b0e98560328960a9517f4014d3325f" +
+ "c7962bf1e049370d76d1314a76137e792f3f0db859d095e4a5b93202" +
+ "4f079ecf2ef09c797452b0770e1350782ed57ddf794979dcef23cb96" +
+ "f183061965c4ebc93c9c71c56b925955a75f94cccf1449ac43d586d0" +
+ "beee43251b0b2287349d68de0d144403f13e802f4146d882e057af19" +
+ "b6f6275c6676c8fa0e3ca2713a3257fd1b27d0639f695e347d8d1cf9" +
+ "ac819a26ca9b04cb0eb9b7b035988d15bbac65212a55239cfc7e58fa" +
+ "e38d7250ab9991ffbc97134025fe8ce04c4399ad96569be91a546f49" +
+ "78693c7a", 16),
new DSAValidationParameters(Hex.decodeStrict("b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536"), 497));
localSetGlobalProperty(Property.DSA_DEFAULT_PARAMS, def512Params, def768Params, def1024Params, def2048Params);
localSetGlobalProperty(Property.DH_DEFAULT_PARAMS, toDH(def512Params), toDH(def768Params), toDH(def1024Params), toDH(def2048Params));
+
+ servicesConstraints.set(getDefaultConstraints());
+ preconfiguredConstraints = (servicesConstraints.get() != noConstraintsImpl);
}
private CryptoServicesRegistrar()
@@ -107,25 +127,9 @@
*/
public static SecureRandom getSecureRandom()
{
- synchronized (cacheLock)
- {
- if (null != defaultSecureRandom)
- {
- return defaultSecureRandom;
- }
- }
+ defaultSecureRandomProvider.compareAndSet(null, defaultRandomProviderImpl);
- SecureRandom tmp = new SecureRandom();
-
- synchronized (cacheLock)
- {
- if (null == defaultSecureRandom)
- {
- defaultSecureRandom = tmp;
- }
-
- return defaultSecureRandom;
- }
+ return defaultSecureRandomProvider.get().get();
}
/**
@@ -144,13 +148,83 @@
*
* @param secureRandom the SecureRandom to use as the default.
*/
- public static void setSecureRandom(SecureRandom secureRandom)
+ public static void setSecureRandom(final SecureRandom secureRandom)
{
checkPermission(CanSetDefaultRandom);
- synchronized (cacheLock)
+ if (secureRandom == null)
{
- defaultSecureRandom = secureRandom;
+ defaultSecureRandomProvider.set(defaultRandomProviderImpl);
+ }
+ else
+ {
+ defaultSecureRandomProvider.set(new SecureRandomProvider()
+ {
+ public SecureRandom get()
+ {
+ return secureRandom;
+ }
+ });
+ }
+ }
+
+ /**
+ * Set a default secure random provider to be used where none is otherwise provided.
+ *
+ * @param secureRandomProvider a provider SecureRandom to use when a default SecureRandom is requested.
+ */
+ public static void setSecureRandomProvider(SecureRandomProvider secureRandomProvider)
+ {
+ checkPermission(CanSetDefaultRandom);
+
+ defaultSecureRandomProvider.set(secureRandomProvider);
+ }
+
+ /**
+ * Return the current algorithm/services constraints.
+ *
+ * @return the algorithm/services constraints.
+ */
+ public static CryptoServicesConstraints getServicesConstraints()
+ {
+ return servicesConstraints.get();
+ }
+
+ /**
+ * Check a service to make sure it meets the current constraints.
+ *
+ * @param cryptoService the service to be checked.
+ * @throws CryptoServiceConstraintsException if the service violates the current constraints.
+ */
+ public static void checkConstraints(CryptoServiceProperties cryptoService)
+ {
+ servicesConstraints.get().check(cryptoService);
+ }
+
+ /**
+ * Set the current algorithm constraints.
+ */
+ public static void setServicesConstraints(CryptoServicesConstraints constraints)
+ {
+ checkPermission(CanSetConstraints);
+
+ CryptoServicesConstraints newConstraints = (constraints == null) ? noConstraintsImpl : constraints;
+
+ if (preconfiguredConstraints)
+ {
+ if (Properties.isOverrideSet("org.bouncycastle.constraints.allow_override"))
+ {
+ servicesConstraints.set(newConstraints);
+ }
+ else
+ {
+ LOG.warning("attempt to override pre-configured constraints ignored");
+ }
+ }
+ else
+ {
+ // TODO: should this only be allowed once?
+ servicesConstraints.set(newConstraints);
}
}
@@ -159,7 +233,7 @@
* configuration first and then on the global configuration in no local configuration exists.
*
* @param property the property to look up.
- * @param <T> the type to be returned
+ * @param <T> the type to be returned
* @return null if the property is not set, the default value otherwise,
*/
public static <T> T getProperty(Property property)
@@ -195,7 +269,7 @@
* DSA_DEFAULT_PARAMS.
*
* @param property the name of the property to look up.
- * @param <T> the base type of the array to be returned.
+ * @param <T> the base type of the array to be returned.
* @return null if the property is not set, an array of the current values otherwise.
*/
public static <T> T[] getSizedProperty(Property property)
@@ -215,8 +289,8 @@
* DSA_DEFAULT_PARAMS.
*
* @param property the name of the property to look up.
- * @param size the size (in bits) of the defining value in the property type.
- * @param <T> the type of the value to be returned.
+ * @param size the size (in bits) of the defining value in the property type.
+ * @param <T> the type of the value to be returned.
* @return the current value for the size, null if there is no value set,
*/
public static <T> T getSizedProperty(Property property, int size)
@@ -261,9 +335,9 @@
* one value can be passed in for a sized property. If more than one value is provided the
* first value in the argument list becomes the default value.
*
- * @param property the name of the property to set.
+ * @param property the name of the property to set.
* @param propertyValue the values to assign to the property.
- * @param <T> the base type of the property value.
+ * @param <T> the base type of the property value.
*/
public static <T> void setThreadProperty(Property property, T... propertyValue)
{
@@ -282,9 +356,9 @@
* one value can be passed in for a sized property. If more than one value is provided the
* first value in the argument list becomes the default value.
*
- * @param property the name of the property to set.
+ * @param property the name of the property to set.
* @param propertyValue the values to assign to the property.
- * @param <T> the base type of the property value.
+ * @param <T> the base type of the property value.
*/
public static <T> void setGlobalProperty(Property property, T... propertyValue)
{
@@ -323,7 +397,7 @@
* Clear the global value for the passed in property.
*
* @param property the property to be cleared.
- * @param <T> the base type of the property value
+ * @param <T> the base type of the property value
* @return an array of T if a value was previously set, null otherwise.
*/
public static <T> T[] clearGlobalProperty(Property property)
@@ -340,7 +414,7 @@
* Clear the thread local value for the passed in property.
*
* @param property the property to be cleared.
- * @param <T> the base type of the property value
+ * @param <T> the base type of the property value
* @return an array of T if a value was previously set, null otherwise.
*/
public static <T> T[] clearThreadProperty(Property property)
@@ -415,6 +489,13 @@
return m;
}
+ private static CryptoServicesConstraints getDefaultConstraints()
+ {
+ // TODO: return one based on system/security properties if set.
+
+ return noConstraintsImpl;
+ }
+
/**
* Available properties that can be set.
*/
@@ -427,11 +508,11 @@
/**
* The default parameters for a particular size of Diffie-Hellman key.This is a sized property.
*/
- public static final Property DH_DEFAULT_PARAMS= new Property("dhDefaultParams", DHParameters.class);
+ public static final Property DH_DEFAULT_PARAMS = new Property("dhDefaultParams", DHParameters.class);
/**
* The default parameters for a particular size of DSA key. This is a sized property.
*/
- public static final Property DSA_DEFAULT_PARAMS= new Property("dsaDefaultParams", DSAParameters.class);
+ public static final Property DSA_DEFAULT_PARAMS = new Property("dsaDefaultParams", DSAParameters.class);
private final String name;
private final Class type;
@@ -441,4 +522,20 @@
this.type = type;
}
}
+
+ private static class ThreadLocalSecureRandomProvider
+ implements SecureRandomProvider
+ {
+ final ThreadLocal<SecureRandom> defaultRandoms = new ThreadLocal<SecureRandom>();
+
+ public SecureRandom get()
+ {
+ if (defaultRandoms.get() == null)
+ {
+ defaultRandoms.set(new SecureRandom());
+ }
+
+ return defaultRandoms.get();
+ }
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java
new file mode 100644
index 0000000..662a23a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java
@@ -0,0 +1,356 @@
+package org.bouncycastle.crypto;
+
+
+/**
+ * A wrapper class that allows block ciphers to be used to process data in
+ * a piecemeal fashion. The BufferedBlockCipher outputs a block only when the
+ * buffer is full and more data is being added, or on a doFinal.
+ * <p>
+ * Note: in the case where the underlying cipher is either a CFB cipher or an
+ * OFB one the last block may not be a multiple of the block size. Use this class
+ * for construction rather than BufferedBlockCipher as BufferedBlockCipher will eventually
+ * turn into an interface.
+ */
+public class DefaultBufferedBlockCipher
+ extends BufferedBlockCipher
+{
+ protected byte[] buf;
+ protected int bufOff;
+
+ protected boolean forEncryption;
+ protected BlockCipher cipher;
+ protected MultiBlockCipher mbCipher;
+
+ protected boolean partialBlockOkay;
+ protected boolean pgpCFB;
+
+ /**
+ * constructor for subclasses
+ */
+ protected DefaultBufferedBlockCipher()
+ {
+ }
+
+ /**
+ * Create a buffered block cipher without padding.
+ *
+ * @param cipher the underlying block cipher this buffering object wraps.
+ */
+ public DefaultBufferedBlockCipher(
+ BlockCipher cipher)
+ {
+ this.cipher = cipher;
+
+ if (cipher instanceof MultiBlockCipher)
+ {
+ this.mbCipher = (MultiBlockCipher)cipher;
+ buf = new byte[mbCipher.getMultiBlockSize()];
+ }
+ else
+ {
+ this.mbCipher = null;
+ buf = new byte[cipher.getBlockSize()];
+ }
+
+ bufOff = 0;
+
+ //
+ // check if we can handle partial blocks on doFinal.
+ //
+ String name = cipher.getAlgorithmName();
+ int idx = name.indexOf('/') + 1;
+
+ pgpCFB = (idx > 0 && name.startsWith("PGP", idx));
+
+ if (pgpCFB || cipher instanceof StreamCipher)
+ {
+ partialBlockOkay = true;
+ }
+ else
+ {
+ partialBlockOkay = (idx > 0 && (name.startsWith("OpenPGP", idx)));
+ }
+ }
+
+ /**
+ * return the cipher this object wraps.
+ *
+ * @return the cipher this object wraps.
+ */
+ public BlockCipher getUnderlyingCipher()
+ {
+ return cipher;
+ }
+
+ /**
+ * initialise the cipher.
+ *
+ * @param forEncryption if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param params the key and other data required by the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters params)
+ throws IllegalArgumentException
+ {
+ this.forEncryption = forEncryption;
+
+ reset();
+
+ cipher.init(forEncryption, params);
+ }
+
+ /**
+ * return the blocksize for the underlying cipher.
+ *
+ * @return the blocksize for the underlying cipher.
+ */
+ public int getBlockSize()
+ {
+ return cipher.getBlockSize();
+ }
+
+ /**
+ * return the size of the output buffer required for an update
+ * an input of len bytes.
+ *
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to update
+ * with len bytes of input.
+ */
+ public int getUpdateOutputSize(
+ int len)
+ {
+ int total = len + bufOff;
+ int leftOver;
+
+ if (pgpCFB)
+ {
+ if (forEncryption)
+ {
+ leftOver = total % buf.length - (cipher.getBlockSize() + 2);
+ }
+ else
+ {
+ leftOver = total % buf.length;
+ }
+ }
+ else
+ {
+ leftOver = total % buf.length;
+ }
+
+ return total - leftOver;
+ }
+
+ /**
+ * return the size of the output buffer required for an update plus a
+ * doFinal with an input of 'length' bytes.
+ *
+ * @param length the length of the input.
+ * @return the space required to accommodate a call to update and doFinal
+ * with 'length' bytes of input.
+ */
+ public int getOutputSize(
+ int length)
+ {
+ if (pgpCFB && forEncryption)
+ {
+ return length + bufOff + (cipher.getBlockSize() + 2);
+ }
+
+ // Note: Can assume partialBlockOkay is true for purposes of this calculation
+ return length + bufOff;
+ }
+
+ /**
+ * process a single byte, producing an output block if necessary.
+ *
+ * @param in the input byte.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processByte(
+ byte in,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ int resultLen = 0;
+
+ buf[bufOff++] = in;
+
+ if (bufOff == buf.length)
+ {
+ resultLen = cipher.processBlock(buf, 0, out, outOff);
+ bufOff = 0;
+ }
+
+ return resultLen;
+ }
+
+ /**
+ * process an array of bytes, producing output if necessary.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset at which the input data starts.
+ * @param len the number of bytes to be copied out of the input array.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processBytes(
+ byte[] in,
+ int inOff,
+ int len,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Can't have a negative input length!");
+ }
+
+ int blockSize = getBlockSize();
+ int length = getUpdateOutputSize(len);
+
+ if (length > 0)
+ {
+ if ((outOff + length) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ }
+
+ int resultLen = 0;
+ int gapLen = buf.length - bufOff;
+
+ if (len > gapLen)
+ {
+ System.arraycopy(in, inOff, buf, bufOff, gapLen);
+
+ resultLen += cipher.processBlock(buf, 0, out, outOff);
+
+ bufOff = 0;
+ len -= gapLen;
+ inOff += gapLen;
+
+ if (mbCipher != null)
+ {
+ int blockCount = len / mbCipher.getMultiBlockSize();
+
+ if (blockCount > 0)
+ {
+ resultLen += mbCipher.processBlocks(in, inOff, blockCount, out, outOff + resultLen);
+
+ int processed = blockCount * mbCipher.getMultiBlockSize();
+
+ len -= processed;
+ inOff += processed;
+ }
+ }
+ else
+ {
+ while (len > buf.length)
+ {
+ resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen);
+
+ len -= blockSize;
+ inOff += blockSize;
+ }
+ }
+ }
+
+ System.arraycopy(in, inOff, buf, bufOff, len);
+
+ bufOff += len;
+
+ if (bufOff == buf.length)
+ {
+ resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen);
+ bufOff = 0;
+ }
+
+ return resultLen;
+ }
+
+ /**
+ * Process the last block in the buffer.
+ *
+ * @param out the array the block currently being held is copied into.
+ * @param outOff the offset at which the copying starts.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there is insufficient space in out for
+ * the output, or the input is not block size aligned and should be.
+ * @exception IllegalStateException if the underlying cipher is not
+ * initialised.
+ * @exception InvalidCipherTextException if padding is expected and not found.
+ * @exception DataLengthException if the input is not block size
+ * aligned.
+ */
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException, InvalidCipherTextException
+ {
+ try
+ {
+ int resultLen = 0;
+
+ if (outOff + bufOff > out.length)
+ {
+ throw new OutputLengthException("output buffer too short for doFinal()");
+ }
+
+ if (bufOff != 0)
+ {
+ if (!partialBlockOkay)
+ {
+ throw new DataLengthException("data not block size aligned");
+ }
+
+ cipher.processBlock(buf, 0, buf, 0);
+ resultLen = bufOff;
+ bufOff = 0;
+ System.arraycopy(buf, 0, out, outOff, resultLen);
+ }
+
+ return resultLen;
+ }
+ finally
+ {
+ reset();
+ }
+ }
+
+ /**
+ * Reset the buffer and cipher. After resetting the object is in the same
+ * state as it was after the last init (if there was one).
+ */
+ public void reset()
+ {
+ //
+ // clean the buffer.
+ //
+ for (int i = 0; i < buf.length; i++)
+ {
+ buf[i] = 0;
+ }
+
+ bufOff = 0;
+
+ //
+ // reset the underlying cipher.
+ //
+ cipher.reset();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/DefaultMultiBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/DefaultMultiBlockCipher.java
new file mode 100644
index 0000000..3bc565c
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/DefaultMultiBlockCipher.java
@@ -0,0 +1,33 @@
+package org.bouncycastle.crypto;
+
+public abstract class DefaultMultiBlockCipher
+ implements MultiBlockCipher
+{
+ protected DefaultMultiBlockCipher()
+ {
+ }
+
+ public int getMultiBlockSize()
+ {
+ return this.getBlockSize();
+ }
+
+ public int processBlocks(byte[] in, int inOff, int blockCount, byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+
+ // TODO check if the underlying cipher supports the multiblock interface and call it directly?
+
+ int resultLen = 0;
+ int blockSize = this.getMultiBlockSize();
+
+ for (int i = 0; i != blockCount; i++)
+ {
+ resultLen += this.processBlock(in, inOff, out, outOff + resultLen);
+
+ inOff += blockSize;
+ }
+
+ return resultLen;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/EncapsulatedSecretExtractor.java b/bcprov/src/main/java/org/bouncycastle/crypto/EncapsulatedSecretExtractor.java
new file mode 100644
index 0000000..2b0b15f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/EncapsulatedSecretExtractor.java
@@ -0,0 +1,18 @@
+package org.bouncycastle.crypto;
+
+public interface EncapsulatedSecretExtractor
+{
+ /**
+ * Extract the secret based on the recipient private key.
+ *
+ * @param encapsulation the encapsulated secret.
+ */
+ byte[] extractSecret(byte[] encapsulation);
+
+ /**
+ * Return the length in bytes of the encapsulation.
+ *
+ * @return length in bytes of an encapsulation for this parameter set.
+ */
+ int getEncapsulationLength();
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/EncapsulatedSecretGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/EncapsulatedSecretGenerator.java
new file mode 100644
index 0000000..760e3b5
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/EncapsulatedSecretGenerator.java
@@ -0,0 +1,13 @@
+package org.bouncycastle.crypto;
+
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+
+public interface EncapsulatedSecretGenerator
+{
+ /**
+ * Generate secret/encapsulation based on the recipient public key.
+ *
+ * @return An SecretWithEncapsulation derived from the recipient public key.
+ */
+ SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey);
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/MultiBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/MultiBlockCipher.java
new file mode 100644
index 0000000..dad4020
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/MultiBlockCipher.java
@@ -0,0 +1,31 @@
+package org.bouncycastle.crypto;
+
+/**
+ * Base interface for a cipher engine capable of processing multiple blocks at a time.
+ */
+public interface MultiBlockCipher
+ extends BlockCipher
+{
+ /**
+ * Return the multi-block size for this cipher (in bytes).
+ *
+ * @return the multi-block size for this cipher in bytes.
+ */
+ int getMultiBlockSize();
+
+ /**
+ * Process blockCount blocks from input in offset inOff and place the output in
+ * out from offset outOff.
+ *
+ * @param in input data array.
+ * @param inOff start of input data in in.
+ * @param blockCount number of blocks to be processed.
+ * @param out output data array.
+ * @param outOff start position for output data.
+ * @return number of bytes written to out.
+ * @throws DataLengthException
+ * @throws IllegalStateException
+ */
+ int processBlocks(byte[] in, int inOff, int blockCount, byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException;
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/SavableDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/SavableDigest.java
new file mode 100644
index 0000000..fed8cd7
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/SavableDigest.java
@@ -0,0 +1,13 @@
+package org.bouncycastle.crypto;
+
+import org.bouncycastle.crypto.digests.EncodableDigest;
+import org.bouncycastle.util.Memoable;
+
+/**
+ * Extended digest which provides the ability to store state and
+ * provide an encoding.
+ */
+public interface SavableDigest
+ extends ExtendedDigest, EncodableDigest, Memoable
+{
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/SecretWithEncapsulation.java b/bcprov/src/main/java/org/bouncycastle/crypto/SecretWithEncapsulation.java
new file mode 100644
index 0000000..15dabba
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/SecretWithEncapsulation.java
@@ -0,0 +1,24 @@
+package org.bouncycastle.crypto;
+
+import javax.security.auth.Destroyable;
+
+/**
+ * Interface describing secret with encapsulation details.
+ */
+public interface SecretWithEncapsulation
+ extends Destroyable
+{
+ /**
+ * Return the secret associated with the encapsulation.
+ *
+ * @return the secret the encapsulation is for.
+ */
+ byte[] getSecret();
+
+ /**
+ * Return the data that carries the secret in its encapsulated form.
+ *
+ * @return the encapsulation of the secret.
+ */
+ byte[] getEncapsulation();
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/SecureRandomProvider.java b/bcprov/src/main/java/org/bouncycastle/crypto/SecureRandomProvider.java
new file mode 100644
index 0000000..33dea73
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/SecureRandomProvider.java
@@ -0,0 +1,15 @@
+package org.bouncycastle.crypto;
+
+import java.security.SecureRandom;
+
+/**
+ * Source provider for SecureRandom implementations.
+ */
+public interface SecureRandomProvider
+{
+ /**
+ * Return a SecureRandom instance.
+ * @return a SecureRandom
+ */
+ SecureRandom get();
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/StreamBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/StreamBlockCipher.java
index 77d8ac9..b1702fe 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/StreamBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/StreamBlockCipher.java
@@ -5,7 +5,8 @@
* a streaming mode.
*/
public abstract class StreamBlockCipher
- implements BlockCipher, StreamCipher
+ extends DefaultMultiBlockCipher
+ implements StreamCipher
{
private final BlockCipher cipher;
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 3490819..61c6f39 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
@@ -4,6 +4,7 @@
import org.bouncycastle.crypto.BasicAgreement;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.DHParameters;
import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
@@ -47,6 +48,8 @@
this.key = (DHPrivateKeyParameters)kParam;
this.dhParams = key.getParameters();
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("DHB", key));
}
public int getFieldSize()
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 49a79c8..e344638 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
@@ -4,6 +4,7 @@
import org.bouncycastle.crypto.BasicAgreement;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
@@ -34,6 +35,8 @@
CipherParameters key)
{
this.key = (ECPrivateKeyParameters)key;
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("ECDH", this.key));
}
public int getFieldSize()
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/agreement/Utils.java b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/Utils.java
new file mode 100644
index 0000000..80e779a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/Utils.java
@@ -0,0 +1,40 @@
+package org.bouncycastle.crypto.agreement;
+
+import org.bouncycastle.crypto.CryptoServiceProperties;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.constraints.ConstraintUtils;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import org.bouncycastle.crypto.params.DHKeyParameters;
+import org.bouncycastle.crypto.params.ECKeyParameters;
+// Android-removed: unsupported algorithms
+// import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
+// import org.bouncycastle.crypto.params.X448PrivateKeyParameters;
+
+class Utils
+{
+ static CryptoServiceProperties getDefaultProperties(String algorithm, ECKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getCurve()), k, CryptoServicePurpose.AGREEMENT);
+ }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, DHKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getP()), k, CryptoServicePurpose.AGREEMENT);
+ }
+
+ // BEGIN Android-removed: unsupported algorithms
+ /*
+ static CryptoServiceProperties getDefaultProperties(String algorithm, X448PrivateKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, 224, k, CryptoServicePurpose.AGREEMENT);
+ }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, X25519PrivateKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, 128, k, CryptoServicePurpose.AGREEMENT);
+ }
+ */
+ // END Android-removed: unsupported algorithms
+}
+
+
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/constraints/ConstraintUtils.java b/bcprov/src/main/java/org/bouncycastle/crypto/constraints/ConstraintUtils.java
new file mode 100644
index 0000000..a902a80
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/constraints/ConstraintUtils.java
@@ -0,0 +1,47 @@
+package org.bouncycastle.crypto.constraints;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.math.ec.ECCurve;
+
+public class ConstraintUtils
+{
+ /**
+ * Return the bits of security for the passed in RSA modulus or DH/DSA group value.
+ *
+ * @param p a modulus or group value
+ * @return the security strength in bits.
+ */
+ public static int bitsOfSecurityFor(BigInteger p)
+ {
+ return bitsOfSecurityForFF(p.bitLength());
+ }
+
+ /**
+ * Return the bits of security for the passed in Elliptic Curve.
+ *
+ * @param curve the ECCurve of interest.
+ * @return the security strength in bits.
+ */
+ public static int bitsOfSecurityFor(ECCurve curve)
+ {
+ int sBits = (curve.getFieldSize() + 1) / 2;
+
+ return (sBits > 256) ? 256 : sBits;
+ }
+
+ public static int bitsOfSecurityForFF(int strength)
+ {
+ if (strength >= 2048)
+ {
+ return (strength >= 3072) ?
+ ((strength >= 7680) ?
+ ((strength >= 15360) ? 256
+ : 192)
+ : 128)
+ : 112;
+ }
+
+ return (strength >= 1024) ? 80 : 20; // TODO: possibly a bit harsh...
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/constraints/DefaultServiceProperties.java b/bcprov/src/main/java/org/bouncycastle/crypto/constraints/DefaultServiceProperties.java
new file mode 100644
index 0000000..42642e9
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/constraints/DefaultServiceProperties.java
@@ -0,0 +1,55 @@
+package org.bouncycastle.crypto.constraints;
+
+import org.bouncycastle.crypto.CryptoServiceProperties;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+
+public class DefaultServiceProperties
+ implements CryptoServiceProperties
+{
+ private final String algorithm;
+ private final int bitsOfSecurity;
+ private final Object params;
+ private final CryptoServicePurpose purpose;
+
+ public DefaultServiceProperties(String algorithm, int bitsOfSecurity)
+ {
+ this(algorithm, bitsOfSecurity, null, CryptoServicePurpose.ANY);
+ }
+
+ public DefaultServiceProperties(String algorithm, int bitsOfSecurity, Object params)
+ {
+ this(algorithm, bitsOfSecurity, params, CryptoServicePurpose.ANY);
+ }
+
+ public DefaultServiceProperties(String algorithm, int bitsOfSecurity, Object params, CryptoServicePurpose purpose)
+ {
+ this.algorithm = algorithm;
+ this.bitsOfSecurity = bitsOfSecurity;
+ this.params = params;
+ if (params instanceof CryptoServicePurpose)
+ {
+ throw new IllegalArgumentException("params should not be CryptoServicePurpose");
+ }
+ this.purpose = purpose;
+ }
+
+ public int bitsOfSecurity()
+ {
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return algorithm;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return purpose;
+ }
+
+ public Object getParams()
+ {
+ return params;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/AsconDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/AsconDigest.java
new file mode 100644
index 0000000..fd47927
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/AsconDigest.java
@@ -0,0 +1,215 @@
+package org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.ExtendedDigest;
+import org.bouncycastle.crypto.OutputLengthException;
+
+/* ASCON v1.2 Digest, https://ascon.iaik.tugraz.at/ .
+ * <p>
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf
+ * <p>
+ * ASCON v1.2 Digest with reference to C Reference Impl from: https://github.com/ascon/ascon-c .
+ */
+public class AsconDigest
+ implements ExtendedDigest
+{
+ public enum AsconParameters
+ {
+ AsconHash,
+ AsconHashA,
+ }
+
+ AsconParameters asconParameters;
+
+ public AsconDigest(AsconParameters parameters)
+ {
+ this.asconParameters = parameters;
+ switch (parameters)
+ {
+ case AsconHash:
+ ASCON_PB_ROUNDS = 12;
+ algorithmName = "Ascon-Hash";
+ break;
+ case AsconHashA:
+ ASCON_PB_ROUNDS = 8;
+ algorithmName = "Ascon-HashA";
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid parameter settings for Ascon Hash");
+ }
+ reset();
+ }
+
+ private final String algorithmName;
+ private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ private long x0;
+ private long x1;
+ private long x2;
+ private long x3;
+ private long x4;
+ private final int CRYPTO_BYTES = 32;
+ private final int ASCON_PB_ROUNDS;
+
+ private long ROR(long x, int n)
+ {
+ return x >>> n | x << (64 - n);
+ }
+
+ private void ROUND(long C)
+ {
+ long t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
+ long t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
+ long t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
+ long t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
+ long t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
+ x0 = t0 ^ ROR(t0, 19) ^ ROR(t0, 28);
+ x1 = t1 ^ ROR(t1, 39) ^ ROR(t1, 61);
+ x2 = ~(t2 ^ ROR(t2, 1) ^ ROR(t2, 6));
+ x3 = t3 ^ ROR(t3, 10) ^ ROR(t3, 17);
+ x4 = t4 ^ ROR(t4, 7) ^ ROR(t4, 41);
+ }
+
+ private void P(int nr)
+ {
+ if (nr == 12)
+ {
+ ROUND(0xf0L);
+ ROUND(0xe1L);
+ ROUND(0xd2L);
+ ROUND(0xc3L);
+ }
+ if (nr >= 8)
+ {
+ ROUND(0xb4L);
+ ROUND(0xa5L);
+ }
+ ROUND(0x96L);
+ ROUND(0x87L);
+ ROUND(0x78L);
+ ROUND(0x69L);
+ ROUND(0x5aL);
+ ROUND(0x4bL);
+ }
+
+ private long PAD(int i)
+ {
+ return 0x80L << (56 - (i << 3));
+ }
+
+ private long LOADBYTES(final byte[] bytes, int inOff, int n)
+ {
+ long x = 0;
+ for (int i = 0; i < n; ++i)
+ {
+ x |= (bytes[i + inOff] & 0xFFL) << ((7 - i) << 3);
+ }
+ return x;
+ }
+
+ private void STOREBYTES(byte[] bytes, int inOff, long w, int n)
+ {
+ for (int i = 0; i < n; ++i)
+ {
+ bytes[i + inOff] = (byte)(w >>> ((7 - i) << 3));
+ }
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return algorithmName;
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return CRYPTO_BYTES;
+ }
+
+ @Override
+ public int getByteLength()
+ {
+ return 8;
+ }
+
+ @Override
+ public void update(byte in)
+ {
+ buffer.write(in);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+ }
+
+ @Override
+ public int doFinal(byte[] output, int outOff)
+ {
+ if (CRYPTO_BYTES + outOff > output.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ byte[] input = buffer.toByteArray();
+ int len = buffer.size();
+ int inOff = 0;
+ /* absorb full plaintext blocks */
+ int ASCON_HASH_RATE = 8;
+ while (len >= ASCON_HASH_RATE)
+ {
+ x0 ^= LOADBYTES(input, inOff, 8);
+ P(ASCON_PB_ROUNDS);
+ inOff += ASCON_HASH_RATE;
+ len -= ASCON_HASH_RATE;
+ }
+ /* absorb final plaintext block */
+ x0 ^= LOADBYTES(input, inOff, len);
+ x0 ^= PAD(len);
+ int ASCON_PA_ROUNDS = 12;
+ P(ASCON_PA_ROUNDS);
+ /* squeeze full output blocks */
+ len = CRYPTO_BYTES;
+ while (len > ASCON_HASH_RATE)
+ {
+ STOREBYTES(output, outOff, x0, 8);
+ P(ASCON_PB_ROUNDS);
+ outOff += ASCON_HASH_RATE;
+ len -= ASCON_HASH_RATE;
+ }
+ /* squeeze final output block */
+ STOREBYTES(output, outOff, x0, len);
+ reset();
+ return CRYPTO_BYTES;
+ }
+
+ @Override
+ public void reset()
+ {
+ buffer.reset();
+ /* initialize */
+ switch (asconParameters)
+ {
+ case AsconHashA:
+ x0 = 92044056785660070L;
+ x1 = 8326807761760157607L;
+ x2 = 3371194088139667532L;
+ x3 = -2956994353054992515L;
+ x4 = -6828509670848688761L;
+ break;
+ case AsconHash:
+ x0 = -1255492011513352131L;
+ x1 = -8380609354527731710L;
+ x2 = -5437372128236807582L;
+ x3 = 4834782570098516968L;
+ x4 = 3787428097924915520L;
+ break;
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java
index 011e97c..518a54b 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java
@@ -1,3 +1,4 @@
+// BEGIN Android-changed: maintain old behaviour
package org.bouncycastle.crypto.digests;
import org.bouncycastle.crypto.ExtendedDigest;
@@ -158,3 +159,4 @@
protected abstract void processBlock();
}
+// END Android-changed: maintain old behaviour
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/Haraka256Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/Haraka256Digest.java
new file mode 100644
index 0000000..1e04a23
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/Haraka256Digest.java
@@ -0,0 +1,154 @@
+package org.bouncycastle.crypto.digests;
+
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Bytes;
+
+/**
+ * Haraka-256 v2, https://eprint.iacr.org/2016/098.pdf
+ * <p>
+ * Haraka256-256 with reference to Python Reference Impl from: https://github.com/kste/haraka
+ * </p>
+ */
+public class Haraka256Digest
+ extends HarakaBase
+{
+ private void mix256(byte[][] s1, byte[][] s2)
+ {
+ System.arraycopy(s1[0], 0, s2[0], 0, 4);
+ System.arraycopy(s1[1], 0, s2[0], 4, 4);
+ System.arraycopy(s1[0], 4, s2[0], 8, 4);
+ System.arraycopy(s1[1], 4, s2[0], 12, 4);
+
+ System.arraycopy(s1[0], 8, s2[1], 0, 4);
+ System.arraycopy(s1[1], 8, s2[1], 4, 4);
+ System.arraycopy(s1[0], 12, s2[1], 8, 4);
+ System.arraycopy(s1[1], 12, s2[1], 12, 4);
+ }
+
+ private int haraka256256(byte[] msg, byte[] out, int outOff)
+ {
+ byte[][] s1 = new byte[2][16];
+ byte[][] s2 = new byte[2][16];
+
+ System.arraycopy(msg, 0, s1[0], 0, 16);
+ System.arraycopy(msg, 16, s1[1], 0, 16);
+
+ s1[0] = aesEnc(s1[0], RC[0]);
+ s1[1] = aesEnc(s1[1], RC[1]);
+ s1[0] = aesEnc(s1[0], RC[2]);
+ s1[1] = aesEnc(s1[1], RC[3]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[4]);
+ s1[1] = aesEnc(s2[1], RC[5]);
+ s1[0] = aesEnc(s1[0], RC[6]);
+ s1[1] = aesEnc(s1[1], RC[7]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[8]);
+ s1[1] = aesEnc(s2[1], RC[9]);
+ s1[0] = aesEnc(s1[0], RC[10]);
+ s1[1] = aesEnc(s1[1], RC[11]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[12]);
+ s1[1] = aesEnc(s2[1], RC[13]);
+ s1[0] = aesEnc(s1[0], RC[14]);
+ s1[1] = aesEnc(s1[1], RC[15]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[16]);
+ s1[1] = aesEnc(s2[1], RC[17]);
+ s1[0] = aesEnc(s1[0], RC[18]);
+ s1[1] = aesEnc(s1[1], RC[19]);
+ mix256(s1, s2);
+
+ Bytes.xor(16, s2[0], 0, msg, 0, out, outOff);
+ Bytes.xor(16, s2[1], 0, msg, 16, out, outOff + 16);
+
+ return DIGEST_SIZE;
+ }
+
+ private final byte[] buffer;
+ private int off;
+
+ private final CryptoServicePurpose purpose;
+
+
+ public Haraka256Digest()
+ {
+ this(CryptoServicePurpose.ANY);
+ }
+
+ public Haraka256Digest(CryptoServicePurpose purpose)
+ {
+ this.purpose = purpose;
+
+ this.buffer = new byte[32];
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties(this, getDigestSize()*4, purpose));
+ }
+
+ public Haraka256Digest(Haraka256Digest digest)
+ {
+ this.purpose = digest.purpose;
+
+ this.buffer = Arrays.clone(digest.buffer);
+ this.off = digest.off;
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties(this, getDigestSize()*4, purpose));
+ }
+
+ public String getAlgorithmName()
+ {
+ return "Haraka-256";
+ }
+
+ public void update(byte in)
+ {
+ if (off > 32 - 1)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 32 bytes");
+ }
+
+ buffer[off++] = in;
+ }
+
+ public void update(byte[] in, int inOff, int len)
+ {
+ if (off > 32 - len)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 32 bytes");
+ }
+
+ System.arraycopy(in, inOff, buffer, off, len);
+ off += len;
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ {
+ if (off != 32)
+ {
+ throw new IllegalStateException("input must be exactly 32 bytes");
+ }
+
+ if (out.length - outOff < 32)
+ {
+ throw new IllegalArgumentException("output too short to receive digest");
+ }
+
+ int rv = haraka256256(buffer, out, outOff);
+
+ reset();
+
+ return rv;
+ }
+
+ public void reset()
+ {
+ off = 0;
+ Arrays.clear(buffer);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/Haraka512Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/Haraka512Digest.java
new file mode 100644
index 0000000..d9e9ba6
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/Haraka512Digest.java
@@ -0,0 +1,189 @@
+package org.bouncycastle.crypto.digests;
+
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Bytes;
+
+/**
+ * Haraka-512 v2, https://eprint.iacr.org/2016/098.pdf
+ * <p>
+ * Haraka512-256 with reference to Python Reference Impl from: https://github.com/kste/haraka
+ * </p>
+ */
+public class Haraka512Digest
+ extends HarakaBase
+{
+ private final byte[] buffer;
+ private int off;
+
+ private final CryptoServicePurpose purpose;
+
+
+ public Haraka512Digest()
+ {
+ this(CryptoServicePurpose.ANY);
+ }
+ public Haraka512Digest(CryptoServicePurpose purpose)
+ {
+ this.purpose = purpose;
+
+ this.buffer = new byte[64];
+ }
+
+ public Haraka512Digest(Haraka512Digest digest)
+ {
+ this.purpose = digest.purpose;
+
+ this.buffer = Arrays.clone(digest.buffer);
+ this.off = digest.off;
+ }
+
+ private void mix512(byte[][] s1, byte[][] s2)
+ {
+ System.arraycopy(s1[0], 12, s2[0], 0, 4);
+ System.arraycopy(s1[2], 12, s2[0], 4, 4);
+ System.arraycopy(s1[1], 12, s2[0], 8, 4);
+ System.arraycopy(s1[3], 12, s2[0], 12, 4);
+
+ System.arraycopy(s1[2], 0, s2[1], 0, 4);
+ System.arraycopy(s1[0], 0, s2[1], 4, 4);
+ System.arraycopy(s1[3], 0, s2[1], 8, 4);
+ System.arraycopy(s1[1], 0, s2[1], 12, 4);
+
+ System.arraycopy(s1[2], 4, s2[2], 0, 4);
+ System.arraycopy(s1[0], 4, s2[2], 4, 4);
+ System.arraycopy(s1[3], 4, s2[2], 8, 4);
+ System.arraycopy(s1[1], 4, s2[2], 12, 4);
+
+ System.arraycopy(s1[0], 8, s2[3], 0, 4);
+ System.arraycopy(s1[2], 8, s2[3], 4, 4);
+ System.arraycopy(s1[1], 8, s2[3], 8, 4);
+ System.arraycopy(s1[3], 8, s2[3], 12, 4);
+ }
+
+ private int haraka512256(byte[] msg, byte[] out, int outOff)
+ {
+ byte[][] s1 = new byte[4][16];
+ byte[][] s2 = new byte[4][16];
+
+ //-- Unrolled version of above.
+
+ System.arraycopy(msg, 0, s1[0], 0, 16);
+ System.arraycopy(msg, 16, s1[1], 0, 16);
+ System.arraycopy(msg, 32, s1[2], 0, 16);
+ System.arraycopy(msg, 48, s1[3], 0, 16);
+
+ s1[0] = aesEnc(s1[0], RC[0]);
+ s1[1] = aesEnc(s1[1], RC[1]);
+ s1[2] = aesEnc(s1[2], RC[2]);
+ s1[3] = aesEnc(s1[3], RC[3]);
+ s1[0] = aesEnc(s1[0], RC[4]);
+ s1[1] = aesEnc(s1[1], RC[5]);
+ s1[2] = aesEnc(s1[2], RC[6]);
+ s1[3] = aesEnc(s1[3], RC[7]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[8]);
+ s1[1] = aesEnc(s2[1], RC[9]);
+ s1[2] = aesEnc(s2[2], RC[10]);
+ s1[3] = aesEnc(s2[3], RC[11]);
+ s1[0] = aesEnc(s1[0], RC[12]);
+ s1[1] = aesEnc(s1[1], RC[13]);
+ s1[2] = aesEnc(s1[2], RC[14]);
+ s1[3] = aesEnc(s1[3], RC[15]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[16]);
+ s1[1] = aesEnc(s2[1], RC[17]);
+ s1[2] = aesEnc(s2[2], RC[18]);
+ s1[3] = aesEnc(s2[3], RC[19]);
+ s1[0] = aesEnc(s1[0], RC[20]);
+ s1[1] = aesEnc(s1[1], RC[21]);
+ s1[2] = aesEnc(s1[2], RC[22]);
+ s1[3] = aesEnc(s1[3], RC[23]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[24]);
+ s1[1] = aesEnc(s2[1], RC[25]);
+ s1[2] = aesEnc(s2[2], RC[26]);
+ s1[3] = aesEnc(s2[3], RC[27]);
+ s1[0] = aesEnc(s1[0], RC[28]);
+ s1[1] = aesEnc(s1[1], RC[29]);
+ s1[2] = aesEnc(s1[2], RC[30]);
+ s1[3] = aesEnc(s1[3], RC[31]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[32]);
+ s1[1] = aesEnc(s2[1], RC[33]);
+ s1[2] = aesEnc(s2[2], RC[34]);
+ s1[3] = aesEnc(s2[3], RC[35]);
+ s1[0] = aesEnc(s1[0], RC[36]);
+ s1[1] = aesEnc(s1[1], RC[37]);
+ s1[2] = aesEnc(s1[2], RC[38]);
+ s1[3] = aesEnc(s1[3], RC[39]);
+ mix512(s1, s2);
+
+ Bytes.xor(16, s2[0], 0, msg, 0, s1[0], 0);
+ Bytes.xor(16, s2[1], 0, msg, 16, s1[1], 0);
+ Bytes.xor(16, s2[2], 0, msg, 32, s1[2], 0);
+ Bytes.xor(16, s2[3], 0, msg, 48, s1[3], 0);
+
+ System.arraycopy(s1[0], 8, out, outOff, 8);
+ System.arraycopy(s1[1], 8, out, outOff + 8, 8);
+ System.arraycopy(s1[2], 0, out, outOff + 16, 8);
+ System.arraycopy(s1[3], 0, out, outOff + 24, 8);
+
+ return DIGEST_SIZE;
+ }
+
+ public String getAlgorithmName()
+ {
+ return "Haraka-512";
+ }
+
+ public void update(byte in)
+ {
+ if (off > 64 - 1)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 64 bytes");
+ }
+
+ buffer[off++] = in;
+ }
+
+ public void update(byte[] in, int inOff, int len)
+ {
+ if (off > 64 - len)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 64 bytes");
+ }
+
+ System.arraycopy(in, inOff, buffer, off, len);
+ off += len;
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ {
+ if (off != 64)
+ {
+ throw new IllegalStateException("input must be exactly 64 bytes");
+ }
+
+ if (out.length - outOff < 32)
+ {
+ throw new IllegalArgumentException("output too short to receive digest");
+ }
+
+ int rv = haraka512256(buffer, out, outOff);
+
+ reset();
+
+ return rv;
+ }
+
+ public void reset()
+ {
+ off = 0;
+ Arrays.clear(buffer);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/HarakaBase.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/HarakaBase.java
new file mode 100644
index 0000000..db9f3f2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/HarakaBase.java
@@ -0,0 +1,147 @@
+package org.bouncycastle.crypto.digests;
+
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.util.Bytes;
+
+/**
+ * Base class for Haraka v2, https://eprint.iacr.org/2016/098.pdf
+ */
+public abstract class HarakaBase
+ implements Digest
+{
+ protected static final int DIGEST_SIZE = 32;
+
+ // Haraka round constants
+ static final byte[][] RC = new byte[][]
+ {
+ new byte[]{ (byte)0x9D, (byte)0x7B, (byte)0x81, (byte)0x75, (byte)0xF0, (byte)0xFE, (byte)0xC5, (byte)0xB2, (byte)0x0A, (byte)0xC0, (byte)0x20, (byte)0xE6, (byte)0x4C, (byte)0x70, (byte)0x84, (byte)0x06 },
+ new byte[]{ (byte)0x17, (byte)0xF7, (byte)0x08, (byte)0x2F, (byte)0xA4, (byte)0x6B, (byte)0x0F, (byte)0x64, (byte)0x6B, (byte)0xA0, (byte)0xF3, (byte)0x88, (byte)0xE1, (byte)0xB4, (byte)0x66, (byte)0x8B },
+ new byte[]{ (byte)0x14, (byte)0x91, (byte)0x02, (byte)0x9F, (byte)0x60, (byte)0x9D, (byte)0x02, (byte)0xCF, (byte)0x98, (byte)0x84, (byte)0xF2, (byte)0x53, (byte)0x2D, (byte)0xDE, (byte)0x02, (byte)0x34 },
+ new byte[]{ (byte)0x79, (byte)0x4F, (byte)0x5B, (byte)0xFD, (byte)0xAF, (byte)0xBC, (byte)0xF3, (byte)0xBB, (byte)0x08, (byte)0x4F, (byte)0x7B, (byte)0x2E, (byte)0xE6, (byte)0xEA, (byte)0xD6, (byte)0x0E },
+ new byte[]{ (byte)0x44, (byte)0x70, (byte)0x39, (byte)0xBE, (byte)0x1C, (byte)0xCD, (byte)0xEE, (byte)0x79, (byte)0x8B, (byte)0x44, (byte)0x72, (byte)0x48, (byte)0xCB, (byte)0xB0, (byte)0xCF, (byte)0xCB },
+ new byte[]{ (byte)0x7B, (byte)0x05, (byte)0x8A, (byte)0x2B, (byte)0xED, (byte)0x35, (byte)0x53, (byte)0x8D, (byte)0xB7, (byte)0x32, (byte)0x90, (byte)0x6E, (byte)0xEE, (byte)0xCD, (byte)0xEA, (byte)0x7E },
+ new byte[]{ (byte)0x1B, (byte)0xEF, (byte)0x4F, (byte)0xDA, (byte)0x61, (byte)0x27, (byte)0x41, (byte)0xE2, (byte)0xD0, (byte)0x7C, (byte)0x2E, (byte)0x5E, (byte)0x43, (byte)0x8F, (byte)0xC2, (byte)0x67 },
+ new byte[]{ (byte)0x3B, (byte)0x0B, (byte)0xC7, (byte)0x1F, (byte)0xE2, (byte)0xFD, (byte)0x5F, (byte)0x67, (byte)0x07, (byte)0xCC, (byte)0xCA, (byte)0xAF, (byte)0xB0, (byte)0xD9, (byte)0x24, (byte)0x29 },
+ new byte[]{ (byte)0xEE, (byte)0x65, (byte)0xD4, (byte)0xB9, (byte)0xCA, (byte)0x8F, (byte)0xDB, (byte)0xEC, (byte)0xE9, (byte)0x7F, (byte)0x86, (byte)0xE6, (byte)0xF1, (byte)0x63, (byte)0x4D, (byte)0xAB },
+ new byte[]{ (byte)0x33, (byte)0x7E, (byte)0x03, (byte)0xAD, (byte)0x4F, (byte)0x40, (byte)0x2A, (byte)0x5B, (byte)0x64, (byte)0xCD, (byte)0xB7, (byte)0xD4, (byte)0x84, (byte)0xBF, (byte)0x30, (byte)0x1C },
+ new byte[]{ (byte)0x00, (byte)0x98, (byte)0xF6, (byte)0x8D, (byte)0x2E, (byte)0x8B, (byte)0x02, (byte)0x69, (byte)0xBF, (byte)0x23, (byte)0x17, (byte)0x94, (byte)0xB9, (byte)0x0B, (byte)0xCC, (byte)0xB2 },
+ new byte[]{ (byte)0x8A, (byte)0x2D, (byte)0x9D, (byte)0x5C, (byte)0xC8, (byte)0x9E, (byte)0xAA, (byte)0x4A, (byte)0x72, (byte)0x55, (byte)0x6F, (byte)0xDE, (byte)0xA6, (byte)0x78, (byte)0x04, (byte)0xFA },
+ new byte[]{ (byte)0xD4, (byte)0x9F, (byte)0x12, (byte)0x29, (byte)0x2E, (byte)0x4F, (byte)0xFA, (byte)0x0E, (byte)0x12, (byte)0x2A, (byte)0x77, (byte)0x6B, (byte)0x2B, (byte)0x9F, (byte)0xB4, (byte)0xDF },
+ new byte[]{ (byte)0xEE, (byte)0x12, (byte)0x6A, (byte)0xBB, (byte)0xAE, (byte)0x11, (byte)0xD6, (byte)0x32, (byte)0x36, (byte)0xA2, (byte)0x49, (byte)0xF4, (byte)0x44, (byte)0x03, (byte)0xA1, (byte)0x1E },
+ new byte[]{ (byte)0xA6, (byte)0xEC, (byte)0xA8, (byte)0x9C, (byte)0xC9, (byte)0x00, (byte)0x96, (byte)0x5F, (byte)0x84, (byte)0x00, (byte)0x05, (byte)0x4B, (byte)0x88, (byte)0x49, (byte)0x04, (byte)0xAF },
+ new byte[]{ (byte)0xEC, (byte)0x93, (byte)0xE5, (byte)0x27, (byte)0xE3, (byte)0xC7, (byte)0xA2, (byte)0x78, (byte)0x4F, (byte)0x9C, (byte)0x19, (byte)0x9D, (byte)0xD8, (byte)0x5E, (byte)0x02, (byte)0x21 },
+ new byte[]{ (byte)0x73, (byte)0x01, (byte)0xD4, (byte)0x82, (byte)0xCD, (byte)0x2E, (byte)0x28, (byte)0xB9, (byte)0xB7, (byte)0xC9, (byte)0x59, (byte)0xA7, (byte)0xF8, (byte)0xAA, (byte)0x3A, (byte)0xBF },
+ new byte[]{ (byte)0x6B, (byte)0x7D, (byte)0x30, (byte)0x10, (byte)0xD9, (byte)0xEF, (byte)0xF2, (byte)0x37, (byte)0x17, (byte)0xB0, (byte)0x86, (byte)0x61, (byte)0x0D, (byte)0x70, (byte)0x60, (byte)0x62 },
+ new byte[]{ (byte)0xC6, (byte)0x9A, (byte)0xFC, (byte)0xF6, (byte)0x53, (byte)0x91, (byte)0xC2, (byte)0x81, (byte)0x43, (byte)0x04, (byte)0x30, (byte)0x21, (byte)0xC2, (byte)0x45, (byte)0xCA, (byte)0x5A },
+ new byte[]{ (byte)0x3A, (byte)0x94, (byte)0xD1, (byte)0x36, (byte)0xE8, (byte)0x92, (byte)0xAF, (byte)0x2C, (byte)0xBB, (byte)0x68, (byte)0x6B, (byte)0x22, (byte)0x3C, (byte)0x97, (byte)0x23, (byte)0x92 },
+ new byte[]{ (byte)0xB4, (byte)0x71, (byte)0x10, (byte)0xE5, (byte)0x58, (byte)0xB9, (byte)0xBA, (byte)0x6C, (byte)0xEB, (byte)0x86, (byte)0x58, (byte)0x22, (byte)0x38, (byte)0x92, (byte)0xBF, (byte)0xD3 },
+ new byte[]{ (byte)0x8D, (byte)0x12, (byte)0xE1, (byte)0x24, (byte)0xDD, (byte)0xFD, (byte)0x3D, (byte)0x93, (byte)0x77, (byte)0xC6, (byte)0xF0, (byte)0xAE, (byte)0xE5, (byte)0x3C, (byte)0x86, (byte)0xDB },
+ new byte[]{ (byte)0xB1, (byte)0x12, (byte)0x22, (byte)0xCB, (byte)0xE3, (byte)0x8D, (byte)0xE4, (byte)0x83, (byte)0x9C, (byte)0xA0, (byte)0xEB, (byte)0xFF, (byte)0x68, (byte)0x62, (byte)0x60, (byte)0xBB },
+ new byte[]{ (byte)0x7D, (byte)0xF7, (byte)0x2B, (byte)0xC7, (byte)0x4E, (byte)0x1A, (byte)0xB9, (byte)0x2D, (byte)0x9C, (byte)0xD1, (byte)0xE4, (byte)0xE2, (byte)0xDC, (byte)0xD3, (byte)0x4B, (byte)0x73 },
+ new byte[]{ (byte)0x4E, (byte)0x92, (byte)0xB3, (byte)0x2C, (byte)0xC4, (byte)0x15, (byte)0x14, (byte)0x4B, (byte)0x43, (byte)0x1B, (byte)0x30, (byte)0x61, (byte)0xC3, (byte)0x47, (byte)0xBB, (byte)0x43 },
+ new byte[]{ (byte)0x99, (byte)0x68, (byte)0xEB, (byte)0x16, (byte)0xDD, (byte)0x31, (byte)0xB2, (byte)0x03, (byte)0xF6, (byte)0xEF, (byte)0x07, (byte)0xE7, (byte)0xA8, (byte)0x75, (byte)0xA7, (byte)0xDB },
+ new byte[]{ (byte)0x2C, (byte)0x47, (byte)0xCA, (byte)0x7E, (byte)0x02, (byte)0x23, (byte)0x5E, (byte)0x8E, (byte)0x77, (byte)0x59, (byte)0x75, (byte)0x3C, (byte)0x4B, (byte)0x61, (byte)0xF3, (byte)0x6D },
+ new byte[]{ (byte)0xF9, (byte)0x17, (byte)0x86, (byte)0xB8, (byte)0xB9, (byte)0xE5, (byte)0x1B, (byte)0x6D, (byte)0x77, (byte)0x7D, (byte)0xDE, (byte)0xD6, (byte)0x17, (byte)0x5A, (byte)0xA7, (byte)0xCD },
+ new byte[]{ (byte)0x5D, (byte)0xEE, (byte)0x46, (byte)0xA9, (byte)0x9D, (byte)0x06, (byte)0x6C, (byte)0x9D, (byte)0xAA, (byte)0xE9, (byte)0xA8, (byte)0x6B, (byte)0xF0, (byte)0x43, (byte)0x6B, (byte)0xEC },
+ new byte[]{ (byte)0xC1, (byte)0x27, (byte)0xF3, (byte)0x3B, (byte)0x59, (byte)0x11, (byte)0x53, (byte)0xA2, (byte)0x2B, (byte)0x33, (byte)0x57, (byte)0xF9, (byte)0x50, (byte)0x69, (byte)0x1E, (byte)0xCB },
+ new byte[]{ (byte)0xD9, (byte)0xD0, (byte)0x0E, (byte)0x60, (byte)0x53, (byte)0x03, (byte)0xED, (byte)0xE4, (byte)0x9C, (byte)0x61, (byte)0xDA, (byte)0x00, (byte)0x75, (byte)0x0C, (byte)0xEE, (byte)0x2C },
+ new byte[]{ (byte)0x50, (byte)0xA3, (byte)0xA4, (byte)0x63, (byte)0xBC, (byte)0xBA, (byte)0xBB, (byte)0x80, (byte)0xAB, (byte)0x0C, (byte)0xE9, (byte)0x96, (byte)0xA1, (byte)0xA5, (byte)0xB1, (byte)0xF0 },
+ new byte[]{ (byte)0x39, (byte)0xCA, (byte)0x8D, (byte)0x93, (byte)0x30, (byte)0xDE, (byte)0x0D, (byte)0xAB, (byte)0x88, (byte)0x29, (byte)0x96, (byte)0x5E, (byte)0x02, (byte)0xB1, (byte)0x3D, (byte)0xAE },
+ new byte[]{ (byte)0x42, (byte)0xB4, (byte)0x75, (byte)0x2E, (byte)0xA8, (byte)0xF3, (byte)0x14, (byte)0x88, (byte)0x0B, (byte)0xA4, (byte)0x54, (byte)0xD5, (byte)0x38, (byte)0x8F, (byte)0xBB, (byte)0x17 },
+ new byte[]{ (byte)0xF6, (byte)0x16, (byte)0x0A, (byte)0x36, (byte)0x79, (byte)0xB7, (byte)0xB6, (byte)0xAE, (byte)0xD7, (byte)0x7F, (byte)0x42, (byte)0x5F, (byte)0x5B, (byte)0x8A, (byte)0xBB, (byte)0x34 },
+ new byte[]{ (byte)0xDE, (byte)0xAF, (byte)0xBA, (byte)0xFF, (byte)0x18, (byte)0x59, (byte)0xCE, (byte)0x43, (byte)0x38, (byte)0x54, (byte)0xE5, (byte)0xCB, (byte)0x41, (byte)0x52, (byte)0xF6, (byte)0x26 },
+ new byte[]{ (byte)0x78, (byte)0xC9, (byte)0x9E, (byte)0x83, (byte)0xF7, (byte)0x9C, (byte)0xCA, (byte)0xA2, (byte)0x6A, (byte)0x02, (byte)0xF3, (byte)0xB9, (byte)0x54, (byte)0x9A, (byte)0xE9, (byte)0x4C },
+ new byte[]{ (byte)0x35, (byte)0x12, (byte)0x90, (byte)0x22, (byte)0x28, (byte)0x6E, (byte)0xC0, (byte)0x40, (byte)0xBE, (byte)0xF7, (byte)0xDF, (byte)0x1B, (byte)0x1A, (byte)0xA5, (byte)0x51, (byte)0xAE },
+ new byte[]{ (byte)0xCF, (byte)0x59, (byte)0xA6, (byte)0x48, (byte)0x0F, (byte)0xBC, (byte)0x73, (byte)0xC1, (byte)0x2B, (byte)0xD2, (byte)0x7E, (byte)0xBA, (byte)0x3C, (byte)0x61, (byte)0xC1, (byte)0xA0 },
+ new byte[]{ (byte)0xA1, (byte)0x9D, (byte)0xC5, (byte)0xE9, (byte)0xFD, (byte)0xBD, (byte)0xD6, (byte)0x4A, (byte)0x88, (byte)0x82, (byte)0x28, (byte)0x02, (byte)0x03, (byte)0xCC, (byte)0x6A, (byte)0x75 },
+ };
+
+ private static final byte[][] S = new byte[][]{
+ { (byte)0x63, (byte)0x7C, (byte)0x77, (byte)0x7B, (byte)0xF2, (byte)0x6B, (byte)0x6F, (byte)0xC5, (byte)0x30, (byte)0x01, (byte)0x67, (byte)0x2B, (byte)0xFE, (byte)0xD7, (byte)0xAB, (byte)0x76 },
+ { (byte)0xCA, (byte)0x82, (byte)0xC9, (byte)0x7D, (byte)0xFA, (byte)0x59, (byte)0x47, (byte)0xF0, (byte)0xAD, (byte)0xD4, (byte)0xA2, (byte)0xAF, (byte)0x9C, (byte)0xA4, (byte)0x72, (byte)0xC0 },
+ { (byte)0xB7, (byte)0xFD, (byte)0x93, (byte)0x26, (byte)0x36, (byte)0x3F, (byte)0xF7, (byte)0xCC, (byte)0x34, (byte)0xA5, (byte)0xE5, (byte)0xF1, (byte)0x71, (byte)0xD8, (byte)0x31, (byte)0x15 },
+ { (byte)0x04, (byte)0xC7, (byte)0x23, (byte)0xC3, (byte)0x18, (byte)0x96, (byte)0x05, (byte)0x9A, (byte)0x07, (byte)0x12, (byte)0x80, (byte)0xE2, (byte)0xEB, (byte)0x27, (byte)0xB2, (byte)0x75 },
+ { (byte)0x09, (byte)0x83, (byte)0x2C, (byte)0x1A, (byte)0x1B, (byte)0x6E, (byte)0x5A, (byte)0xA0, (byte)0x52, (byte)0x3B, (byte)0xD6, (byte)0xB3, (byte)0x29, (byte)0xE3, (byte)0x2F, (byte)0x84 },
+ { (byte)0x53, (byte)0xD1, (byte)0x00, (byte)0xED, (byte)0x20, (byte)0xFC, (byte)0xB1, (byte)0x5B, (byte)0x6A, (byte)0xCB, (byte)0xBE, (byte)0x39, (byte)0x4A, (byte)0x4C, (byte)0x58, (byte)0xCF },
+ { (byte)0xD0, (byte)0xEF, (byte)0xAA, (byte)0xFB, (byte)0x43, (byte)0x4D, (byte)0x33, (byte)0x85, (byte)0x45, (byte)0xF9, (byte)0x02, (byte)0x7F, (byte)0x50, (byte)0x3C, (byte)0x9F, (byte)0xA8 },
+ { (byte)0x51, (byte)0xA3, (byte)0x40, (byte)0x8F, (byte)0x92, (byte)0x9D, (byte)0x38, (byte)0xF5, (byte)0xBC, (byte)0xB6, (byte)0xDA, (byte)0x21, (byte)0x10, (byte)0xFF, (byte)0xF3, (byte)0xD2 },
+ { (byte)0xCD, (byte)0x0C, (byte)0x13, (byte)0xEC, (byte)0x5F, (byte)0x97, (byte)0x44, (byte)0x17, (byte)0xC4, (byte)0xA7, (byte)0x7E, (byte)0x3D, (byte)0x64, (byte)0x5D, (byte)0x19, (byte)0x73 },
+ { (byte)0x60, (byte)0x81, (byte)0x4F, (byte)0xDC, (byte)0x22, (byte)0x2A, (byte)0x90, (byte)0x88, (byte)0x46, (byte)0xEE, (byte)0xB8, (byte)0x14, (byte)0xDE, (byte)0x5E, (byte)0x0B, (byte)0xDB },
+ { (byte)0xE0, (byte)0x32, (byte)0x3A, (byte)0x0A, (byte)0x49, (byte)0x06, (byte)0x24, (byte)0x5C, (byte)0xC2, (byte)0xD3, (byte)0xAC, (byte)0x62, (byte)0x91, (byte)0x95, (byte)0xE4, (byte)0x79 },
+ { (byte)0xE7, (byte)0xC8, (byte)0x37, (byte)0x6D, (byte)0x8D, (byte)0xD5, (byte)0x4E, (byte)0xA9, (byte)0x6C, (byte)0x56, (byte)0xF4, (byte)0xEA, (byte)0x65, (byte)0x7A, (byte)0xAE, (byte)0x08 },
+ { (byte)0xBA, (byte)0x78, (byte)0x25, (byte)0x2E, (byte)0x1C, (byte)0xA6, (byte)0xB4, (byte)0xC6, (byte)0xE8, (byte)0xDD, (byte)0x74, (byte)0x1F, (byte)0x4B, (byte)0xBD, (byte)0x8B, (byte)0x8A },
+ { (byte)0x70, (byte)0x3E, (byte)0xB5, (byte)0x66, (byte)0x48, (byte)0x03, (byte)0xF6, (byte)0x0E, (byte)0x61, (byte)0x35, (byte)0x57, (byte)0xB9, (byte)0x86, (byte)0xC1, (byte)0x1D, (byte)0x9E },
+ { (byte)0xE1, (byte)0xF8, (byte)0x98, (byte)0x11, (byte)0x69, (byte)0xD9, (byte)0x8E, (byte)0x94, (byte)0x9B, (byte)0x1E, (byte)0x87, (byte)0xE9, (byte)0xCE, (byte)0x55, (byte)0x28, (byte)0xDF },
+ { (byte)0x8C, (byte)0xA1, (byte)0x89, (byte)0x0D, (byte)0xBF, (byte)0xE6, (byte)0x42, (byte)0x68, (byte)0x41, (byte)0x99, (byte)0x2D, (byte)0x0F, (byte)0xB0, (byte)0x54, (byte)0xBB, (byte)0x16 },
+ };
+
+ static byte sBox(byte x)
+ {
+ return S[(((x & 0xFF) >>> 4))][x & 0xF];
+ }
+
+ static byte[] subBytes(byte[] s)
+ {
+ byte[] out = new byte[s.length];
+ out[0] = sBox(s[0]);
+ out[1] = sBox(s[1]);
+ out[2] = sBox(s[2]);
+ out[3] = sBox(s[3]);
+ out[4] = sBox(s[4]);
+ out[5] = sBox(s[5]);
+ out[6] = sBox(s[6]);
+ out[7] = sBox(s[7]);
+ out[8] = sBox(s[8]);
+ out[9] = sBox(s[9]);
+ out[10] = sBox(s[10]);
+ out[11] = sBox(s[11]);
+ out[12] = sBox(s[12]);
+ out[13] = sBox(s[13]);
+ out[14] = sBox(s[14]);
+ out[15] = sBox(s[15]);
+ return out;
+ }
+
+ static byte[] shiftRows(byte[] s)
+ {
+ return new byte[]{
+ s[0], s[5], s[10], s[15],
+ s[4], s[9], s[14], s[3],
+ s[8], s[13], s[2], s[7],
+ s[12], s[1], s[6], s[11]
+ };
+ }
+
+ static byte[] aesEnc(byte[] s, byte[] rk)
+ {
+ s = subBytes(s);
+ s = shiftRows(s);
+ s = mixColumns(s);
+ Bytes.xorTo(16, rk, s);
+ return s;
+ }
+
+ static byte mulX(byte p)
+ {
+ return (byte)(((p & 0x7F) << 1) ^ (((p & 0x80) >> 7) * 0x1B));
+ }
+
+ private static byte[] mixColumns(byte[] s)
+ {
+ byte[] out = new byte[s.length];
+ int j = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ out[j++] = (byte)(mulX(s[4 * i]) ^ mulX(s[4 * i + 1]) ^ s[4 * i + 1] ^ s[4 * i + 2] ^ s[4 * i + 3]);
+ out[j++] = (byte)(s[4 * i] ^ mulX(s[4 * i + 1]) ^ mulX(s[4 * i + 2]) ^ s[4 * i + 2] ^ s[4 * i + 3]);
+ out[j++] = (byte)(s[4 * i] ^ s[4 * i + 1] ^ mulX(s[4 * i + 2]) ^ mulX(s[4 * i + 3]) ^ s[4 * i + 3]);
+ out[j++] = (byte)(mulX(s[4 * i]) ^ s[4 * i] ^ s[4 * i + 1] ^ s[4 * i + 2] ^ mulX(s[4 * i + 3]));
+ }
+ return out;
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_SIZE;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/ISAPDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/ISAPDigest.java
new file mode 100644
index 0000000..9120e75
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/ISAPDigest.java
@@ -0,0 +1,146 @@
+package org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.util.Pack;
+
+/**
+ * ISAP Hash v2, https://isap.iaik.tugraz.at/
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/isap-spec-final.pdf
+ * <p>
+ * ISAP Hash v2 with reference to C Reference Impl from: https://github.com/isap-lwc/isap-code-package
+ * </p>
+ */
+
+public class ISAPDigest
+ implements Digest
+{
+ private long x0, x1, x2, x3, x4;
+ private long t0, t1, t2, t3, t4;
+ private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+
+ private void ROUND(long C)
+ {
+ t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
+ t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
+ t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
+ t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
+ t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
+ x0 = t0 ^ ROTR(t0, 19) ^ ROTR(t0, 28);
+ x1 = t1 ^ ROTR(t1, 39) ^ ROTR(t1, 61);
+ x2 = ~(t2 ^ ROTR(t2, 1) ^ ROTR(t2, 6));
+ x3 = t3 ^ ROTR(t3, 10) ^ ROTR(t3, 17);
+ x4 = t4 ^ ROTR(t4, 7) ^ ROTR(t4, 41);
+ }
+
+ private void P12()
+ {
+ ROUND(0xf0);
+ ROUND(0xe1);
+ ROUND(0xd2);
+ ROUND(0xc3);
+ ROUND(0xb4);
+ ROUND(0xa5);
+ ROUND(0x96);
+ ROUND(0x87);
+ ROUND(0x78);
+ ROUND(0x69);
+ ROUND(0x5a);
+ ROUND(0x4b);
+ }
+
+ private long ROTR(long x, long n)
+ {
+ return (x >>> n) | (x << (64 - n));
+ }
+
+ protected long U64BIG(long x)
+ {
+ return ((ROTR(x, 8) & (0xFF000000FF000000L)) | (ROTR(x, 24) & (0x00FF000000FF0000L)) |
+ (ROTR(x, 40) & (0x0000FF000000FF00L)) | (ROTR(x, 56) & (0x000000FF000000FFL)));
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return "ISAP Hash";
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return 32;
+ }
+
+ @Override
+ public void update(byte input)
+ {
+ buffer.write(input);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+ }
+
+ @Override
+ public int doFinal(byte[] out, int outOff)
+ {
+ if (32 + outOff > out.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ t0 = t1 = t2 = t3 = t4 = 0;
+ /* init state */
+ x0 = -1255492011513352131L;
+ x1 = -8380609354527731710L;
+ x2 = -5437372128236807582L;
+ x3 = 4834782570098516968L;
+ x4 = 3787428097924915520L;
+ /* absorb */
+ byte[] input = buffer.toByteArray();
+ int len = input.length;
+ long[] in64 = new long[len >> 3];
+ Pack.littleEndianToLong(input, 0, in64, 0, in64.length);
+ int idx = 0;
+ while (len >= 8)
+ {
+ x0 ^= U64BIG(in64[idx++]);
+ P12();
+ len -= 8;
+ }
+ /* absorb final input block */
+ x0 ^= 0x80L << ((7 - len) << 3);
+ while (len > 0)
+ {
+ x0 ^= (input[(idx << 3) + --len] & 0xFFL) << ((7 - len) << 3);
+ }
+ P12();
+ // squeeze
+ long[] out64 = new long[4];
+ for (idx = 0; idx < 3; ++idx)
+ {
+ out64[idx] = U64BIG(x0);
+ P12();
+ }
+ /* squeeze final output block */
+ out64[idx] = U64BIG(x0);
+ Pack.longToLittleEndian(out64, out, outOff);
+ buffer.reset();
+ return 32;
+ }
+
+ @Override
+ public void reset()
+ {
+ buffer.reset();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/LongDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/LongDigest.java
index 8ea474b..9fba7aa 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/LongDigest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/LongDigest.java
@@ -1,5 +1,7 @@
package org.bouncycastle.crypto.digests;
+import org.bouncycastle.crypto.CryptoServiceProperties;
+import org.bouncycastle.crypto.CryptoServicePurpose;
import org.bouncycastle.crypto.ExtendedDigest;
import org.bouncycastle.util.Memoable;
import org.bouncycastle.util.Pack;
@@ -12,6 +14,8 @@
{
private static final int BYTE_LENGTH = 128;
+ protected final CryptoServicePurpose purpose;
+
private byte[] xBuf = new byte[8];
private int xBufOff;
@@ -28,6 +32,16 @@
*/
protected LongDigest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Constructor for variable length word
+ */
+ protected LongDigest(CryptoServicePurpose purpose)
+ {
+ this.purpose = purpose;
+
xBufOff = 0;
reset();
@@ -40,6 +54,8 @@
*/
protected LongDigest(LongDigest t)
{
+ this.purpose = t.purpose;
+
copyIn(t);
}
@@ -147,7 +163,7 @@
//
// process whole words.
//
- while (len > xBuf.length)
+ while (len >= xBuf.length)
{
processWord(in, inOff);
@@ -406,4 +422,5 @@
0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L
};
+ protected abstract CryptoServiceProperties cryptoServiceProperties();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD4Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD4Digest.java
index 093e35d..89b4424 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD4Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD4Digest.java
@@ -1,3 +1,4 @@
+// BEGIN Android-changed: maintain old behaviour
package org.bouncycastle.crypto.digests;
@@ -289,3 +290,4 @@
copyIn(d);
}
}
+// END Android-changed: maintain old behaviour
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java
index 417c4ba..6f8cbf3 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java
@@ -1,3 +1,4 @@
+// BEGIN Android-changed: maintain old behaviour
package org.bouncycastle.crypto.digests;
@@ -359,3 +360,4 @@
return state;
}
}
+// END Android-changed: maintain old behaviour
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java
new file mode 100644
index 0000000..853a93d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java
@@ -0,0 +1,219 @@
+package org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Bytes;
+
+/**
+ * Photon-Beetle, https://www.isical.ac.in/~lightweight/beetle/
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/photon-beetle-spec-final.pdf
+ * <p>
+ * Photon-Beetle with reference to C Reference Impl from: https://github.com/PHOTON-Beetle/Software
+ * </p>
+ */
+public class PhotonBeetleDigest
+ implements Digest
+{
+ private byte[] state;
+ private byte[][] state_2d;
+ private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ private final int INITIAL_RATE_INBYTES = 16;
+ private int RATE_INBYTES = 4;
+ private int SQUEEZE_RATE_INBYTES = 16;
+ private int STATE_INBYTES = 32;
+ private int TAG_INBYTES = 32;
+ private int LAST_THREE_BITS_OFFSET = 5;
+ private int ROUND = 12;
+ private int D = 8;
+ private int Dq = 3;
+ private int Dr = 7;
+ private int DSquare = 64;
+ private int S = 4;
+ private int S_1 = 3;
+ private byte[][] RC = {//[D][12]
+ {1, 3, 7, 14, 13, 11, 6, 12, 9, 2, 5, 10},
+ {0, 2, 6, 15, 12, 10, 7, 13, 8, 3, 4, 11},
+ {2, 0, 4, 13, 14, 8, 5, 15, 10, 1, 6, 9},
+ {6, 4, 0, 9, 10, 12, 1, 11, 14, 5, 2, 13},
+ {14, 12, 8, 1, 2, 4, 9, 3, 6, 13, 10, 5},
+ {15, 13, 9, 0, 3, 5, 8, 2, 7, 12, 11, 4},
+ {13, 15, 11, 2, 1, 7, 10, 0, 5, 14, 9, 6},
+ {9, 11, 15, 6, 5, 3, 14, 4, 1, 10, 13, 2}
+ };
+ private byte[][] MixColMatrix = { //[D][D]
+ {2, 4, 2, 11, 2, 8, 5, 6},
+ {12, 9, 8, 13, 7, 7, 5, 2},
+ {4, 4, 13, 13, 9, 4, 13, 9},
+ {1, 6, 5, 1, 12, 13, 15, 14},
+ {15, 12, 9, 13, 14, 5, 14, 13},
+ {9, 14, 5, 15, 4, 12, 9, 6},
+ {12, 2, 2, 10, 3, 1, 1, 14},
+ {15, 1, 13, 10, 5, 10, 2, 3}
+ };
+
+ private byte[] sbox = {12, 5, 6, 11, 9, 0, 10, 13, 3, 14, 15, 8, 4, 7, 1, 2};
+
+ public PhotonBeetleDigest()
+ {
+ state = new byte[STATE_INBYTES];
+ state_2d = new byte[D][D];
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return "Photon-Beetle Hash";
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return TAG_INBYTES;
+ }
+
+ @Override
+ public void update(byte input)
+ {
+ buffer.write(input);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+ }
+
+ @Override
+ public int doFinal(byte[] output, int outOff)
+ {
+ if (32 + outOff > output.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ byte[] input = buffer.toByteArray();
+ int inlen = input.length;
+ if (inlen == 0)
+ {
+ state[STATE_INBYTES - 1] ^= 1 << LAST_THREE_BITS_OFFSET;
+ }
+ else if (inlen <= INITIAL_RATE_INBYTES)
+ {
+ System.arraycopy(input, 0, state, 0, inlen);
+ if (inlen < INITIAL_RATE_INBYTES)
+ {
+ state[inlen] ^= 0x01; // ozs
+ }
+ state[STATE_INBYTES - 1] ^= (inlen < INITIAL_RATE_INBYTES ? (byte)1 : (byte)2) << LAST_THREE_BITS_OFFSET;
+ }
+ else
+ {
+ System.arraycopy(input, 0, state, 0, INITIAL_RATE_INBYTES);
+ inlen -= INITIAL_RATE_INBYTES;
+ int Dlen_inblocks = (inlen + RATE_INBYTES - 1) / RATE_INBYTES;
+ int i, LastDBlocklen;
+ for (i = 0; i < Dlen_inblocks - 1; i++)
+ {
+ PHOTON_Permutation();
+ Bytes.xorTo(RATE_INBYTES, input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, state, 0);
+ }
+ PHOTON_Permutation();
+ LastDBlocklen = inlen - i * RATE_INBYTES;
+ Bytes.xorTo(LastDBlocklen, input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, state, 0);
+ if (LastDBlocklen < RATE_INBYTES)
+ {
+ state[LastDBlocklen] ^= 0x01; // ozs
+ }
+ state[STATE_INBYTES - 1] ^= (inlen % RATE_INBYTES == 0 ? (byte)1 : (byte)2) << LAST_THREE_BITS_OFFSET;
+ }
+ PHOTON_Permutation();
+ System.arraycopy(state, 0, output, outOff, SQUEEZE_RATE_INBYTES);
+ PHOTON_Permutation();
+ System.arraycopy(state, 0, output, outOff + SQUEEZE_RATE_INBYTES, TAG_INBYTES - SQUEEZE_RATE_INBYTES);
+ return TAG_INBYTES;
+ }
+
+ @Override
+ public void reset()
+ {
+ buffer.reset();
+ Arrays.fill(state, (byte)0);
+ }
+
+ void PHOTON_Permutation()
+ {
+ int i, j, k, l;
+ for (i = 0; i < DSquare; i++)
+ {
+ state_2d[i >>> Dq][i & Dr] = (byte)(((state[i >> 1] & 0xFF) >>> (4 * (i & 1))) & 0xf);
+ }
+ for (int round = 0; round < ROUND; round++)
+ {
+ //AddKey
+ for (i = 0; i < D; i++)
+ {
+ state_2d[i][0] ^= RC[i][round];
+ }
+ //SubCell
+ for (i = 0; i < D; i++)
+ {
+ for (j = 0; j < D; j++)
+ {
+ state_2d[i][j] = sbox[state_2d[i][j]];
+ }
+ }
+ //ShiftRow
+ for (i = 1; i < D; i++)
+ {
+ System.arraycopy(state_2d[i], 0, state, 0, D);
+ System.arraycopy(state, i, state_2d[i], 0, D - i);
+ System.arraycopy(state, 0, state_2d[i], D - i, i);
+ }
+ //MixColumn
+ for (j = 0; j < D; j++)
+ {
+ for (i = 0; i < D; i++)
+ {
+ byte sum = 0;
+ for (k = 0; k < D; k++)
+ {
+ int x = MixColMatrix[i][k], ret = 0, b = state_2d[k][j];
+ for (l = 0; l < S; l++)
+ {
+ if (((b >>> l) & 1) != 0)
+ {
+ ret ^= x;
+ }
+ if (((x >>> S_1) & 1) != 0)
+ {
+ x <<= 1;
+ x ^= 0x3;
+ }
+ else
+ {
+ x <<= 1;
+ }
+ }
+ sum ^= ret & 15;
+ }
+ state[i] = sum;
+ }
+ for (i = 0; i < D; i++)
+ {
+ state_2d[i][j] = state[i];
+ }
+ }
+ }
+ for (i = 0; i < DSquare; i += 2)
+ {
+ state[i >>> 1] = (byte)(((state_2d[i >>> Dq][i & Dr] & 0xf)) | ((state_2d[i >>> Dq][(i + 1) & Dr] & 0xf) << 4));
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java
index 4290d20..25df8ca 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java
@@ -1,3 +1,4 @@
+// BEGIN Android-changed: maintain old behaviour
package org.bouncycastle.crypto.digests;
import org.bouncycastle.util.Memoable;
@@ -348,6 +349,4 @@
}
}
-
-
-
+// END Android-changed: maintain old behaviour
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA224Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA224Digest.java
index c0fbd45..0127986 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA224Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA224Digest.java
@@ -1,3 +1,4 @@
+// BEGIN Android-changed: maintain old behaviour
package org.bouncycastle.crypto.digests;
@@ -358,4 +359,4 @@
return state;
}
}
-
+// END Android-changed: maintain old behaviour
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
index 0fb1050..84cf094 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
@@ -1,6 +1,12 @@
+// BEGIN Android-changed: adapt to old version of GeneralDigest
package org.bouncycastle.crypto.digests;
+import org.bouncycastle.crypto.CryptoServiceProperties;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.SavableDigest;
import org.bouncycastle.util.Memoable;
import org.bouncycastle.util.Pack;
@@ -18,20 +24,60 @@
*/
public class SHA256Digest
extends GeneralDigest
- implements EncodableDigest
+ implements SavableDigest
{
private static final int DIGEST_LENGTH = 32;
+ protected final CryptoServicePurpose purpose;
private int H1, H2, H3, H4, H5, H6, H7, H8;
private int[] X = new int[64];
private int xOff;
+ public static SavableDigest newInstance()
+ {
+ return new SHA256Digest();
+ }
+
+ public static SavableDigest newInstance(CryptoServicePurpose purpose)
+ {
+ return new SHA256Digest(purpose);
+ }
+
+ public static SavableDigest newInstance(Digest digest)
+ {
+ if (digest instanceof SHA256Digest)
+ {
+ return new SHA256Digest((SHA256Digest) digest);
+ }
+
+ throw new IllegalArgumentException("receiver digest not available for input type " + (digest != null ? digest.getClass().getName() : "null"));
+ }
+
+ public static SavableDigest newInstance(byte[] encoded)
+ {
+ return new SHA256Digest(encoded);
+ }
+
/**
* Standard constructor
*/
public SHA256Digest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Standard constructor, with purpose
+ */
+ public SHA256Digest(CryptoServicePurpose purpose)
+ {
+ super();
+
+ this.purpose = purpose;
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
+
reset();
}
@@ -43,6 +89,8 @@
{
super(t);
+ this.purpose = CryptoServicePurpose.ANY;
+
copyIn(t);
}
@@ -72,6 +120,8 @@
{
super(encodedState);
+ this.purpose = CryptoServicePurpose.ANY;
+
H1 = Pack.bigEndianToInt(encodedState, 16);
H2 = Pack.bigEndianToInt(encodedState, 20);
H3 = Pack.bigEndianToInt(encodedState, 24);
@@ -103,13 +153,7 @@
byte[] in,
int inOff)
{
- // Note: Inlined for performance
-// X[xOff] = Pack.bigEndianToInt(in, inOff);
- int n = in[inOff] << 24;
- n |= (in[++inOff] & 0xff) << 16;
- n |= (in[++inOff] & 0xff) << 8;
- n |= (in[++inOff] & 0xff);
- X[xOff] = n;
+ X[xOff] = Pack.bigEndianToInt(in, inOff);
if (++xOff == 16)
{
@@ -129,9 +173,7 @@
X[15] = (int)(bitLength & 0xffffffff);
}
- public int doFinal(
- byte[] out,
- int outOff)
+ public int doFinal(byte[] out, int outOff)
{
finish();
@@ -199,7 +241,7 @@
int g = H7;
int h = H8;
- int t = 0;
+ int t = 0;
for(int i = 0; i < 8; i ++)
{
// t = 8 * i
@@ -332,7 +374,7 @@
public byte[] getEncodedState()
{
- byte[] state = new byte[52 + xOff * 4];
+ byte[] state = new byte[52 + xOff * 4 + 1];
super.populateState(state);
@@ -351,7 +393,14 @@
Pack.intToBigEndian(X[i], state, 52 + (i * 4));
}
+ state[state.length - 1] = (byte)purpose.ordinal();
+
return state;
}
-}
+ protected CryptoServiceProperties cryptoServiceProperties()
+ {
+ return Utils.getDefaultProperties(this, 256, purpose);
+ }
+}
+// END Android-changed: adapt to old version of GeneralDigest
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java
index 0c814b1..c69b578 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java
@@ -1,5 +1,8 @@
package org.bouncycastle.crypto.digests;
+import org.bouncycastle.crypto.CryptoServiceProperties;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.util.Memoable;
import org.bouncycastle.util.Pack;
@@ -25,6 +28,19 @@
*/
public SHA384Digest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Standard constructor, with purpose
+ */
+ public SHA384Digest(CryptoServicePurpose purpose)
+ {
+ super(purpose);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
+
+ reset();
}
/**
@@ -34,6 +50,8 @@
public SHA384Digest(SHA384Digest t)
{
super(t);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
/**
@@ -43,7 +61,11 @@
*/
public SHA384Digest(byte[] encodedState)
{
+ super(CryptoServicePurpose.values()[encodedState[encodedState.length - 1]]);
+
restoreState(encodedState);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
public String getAlgorithmName()
@@ -109,8 +131,16 @@
public byte[] getEncodedState()
{
- byte[] encoded = new byte[getEncodedStateSize()];
+ byte[] encoded = new byte[getEncodedStateSize() + 1];
super.populateState(encoded);
+
+ encoded[encoded.length - 1] = (byte)purpose.ordinal();
+
return encoded;
}
+
+ protected CryptoServiceProperties cryptoServiceProperties()
+ {
+ return Utils.getDefaultProperties(this, 256, purpose);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java
index dea3d88..0fab188 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java
@@ -1,5 +1,8 @@
package org.bouncycastle.crypto.digests;
+import org.bouncycastle.crypto.CryptoServiceProperties;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.util.Memoable;
import org.bouncycastle.util.Pack;
@@ -25,6 +28,19 @@
*/
public SHA512Digest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Standard constructor, with purpose
+ */
+ public SHA512Digest(CryptoServicePurpose purpose)
+ {
+ super(purpose);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
+
+ reset();
}
/**
@@ -34,6 +50,8 @@
public SHA512Digest(SHA512Digest t)
{
super(t);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
/**
@@ -43,7 +61,11 @@
*/
public SHA512Digest(byte[] encodedState)
{
+ super(CryptoServicePurpose.values()[encodedState[encodedState.length - 1]]);
+
restoreState(encodedState);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
public String getAlgorithmName()
@@ -111,9 +133,17 @@
public byte[] getEncodedState()
{
- byte[] encoded = new byte[getEncodedStateSize()];
+ byte[] encoded = new byte[getEncodedStateSize() + 1];
super.populateState(encoded);
+
+ encoded[encoded.length - 1] = (byte)purpose.ordinal();
+
return encoded;
}
+
+ protected CryptoServiceProperties cryptoServiceProperties()
+ {
+ return Utils.getDefaultProperties(this, 256, purpose);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/Utils.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/Utils.java
new file mode 100644
index 0000000..cad69c3
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/Utils.java
@@ -0,0 +1,97 @@
+package org.bouncycastle.crypto.digests;
+
+import org.bouncycastle.crypto.CryptoServiceProperties;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.Digest;
+
+class Utils
+{
+ static CryptoServiceProperties getDefaultProperties(Digest digest, CryptoServicePurpose purpose)
+ {
+ return new DefaultProperties(digest.getDigestSize() * 4, digest.getAlgorithmName(), purpose);
+ }
+
+ static CryptoServiceProperties getDefaultProperties(Digest digest, int prfBitsOfSecurity, CryptoServicePurpose purpose)
+ {
+ return new DefaultPropertiesWithPRF(digest.getDigestSize() * 4, prfBitsOfSecurity, digest.getAlgorithmName(), purpose);
+ }
+
+ // Service Definitions
+ private static class DefaultPropertiesWithPRF
+ implements CryptoServiceProperties
+ {
+ private final int bitsOfSecurity;
+ private final int prfBitsOfSecurity;
+ private final String algorithmName;
+ private final CryptoServicePurpose purpose;
+
+ public DefaultPropertiesWithPRF(int bitsOfSecurity, int prfBitsOfSecurity, String algorithmName, CryptoServicePurpose purpose)
+ {
+ this.bitsOfSecurity = bitsOfSecurity;
+ this.prfBitsOfSecurity = prfBitsOfSecurity;
+ this.algorithmName = algorithmName;
+ this.purpose = purpose;
+ }
+
+ public int bitsOfSecurity()
+ {
+ if (purpose == CryptoServicePurpose.PRF)
+ {
+ return prfBitsOfSecurity;
+ }
+
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return algorithmName;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return purpose;
+ }
+
+ public Object getParams()
+ {
+ return null;
+ }
+ }
+
+ // Service Definitions
+ private static class DefaultProperties
+ implements CryptoServiceProperties
+ {
+ private final int bitsOfSecurity;
+ private final String algorithmName;
+ private final CryptoServicePurpose purpose;
+
+ public DefaultProperties(int bitsOfSecurity, String algorithmName, CryptoServicePurpose purpose)
+ {
+ this.bitsOfSecurity = bitsOfSecurity;
+ this.algorithmName = algorithmName;
+ this.purpose = purpose;
+ }
+
+ public int bitsOfSecurity()
+ {
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return algorithmName;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return purpose;
+ }
+
+ public Object getParams()
+ {
+ return null;
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/XofUtils.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/XofUtils.java
index 6e06a47..d9dbab9 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/XofUtils.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/XofUtils.java
@@ -1,27 +1,29 @@
package org.bouncycastle.crypto.digests;
+import org.bouncycastle.util.Arrays;
+
public class XofUtils
{
public static byte[] leftEncode(long strLen)
{
- byte n = 1;
+ byte n = 1;
long v = strLen;
- while ((v >>= 8) != 0)
+ while ((v >>= 8) != 0)
{
- n++;
- }
+ n++;
+ }
byte[] b = new byte[n + 1];
- b[0] = n;
+ b[0] = n;
- for (int i = 1; i <= n; i++)
- {
- b[i] = (byte)(strLen >> (8 * (n - i)));
- }
+ for (int i = 1; i <= n; i++)
+ {
+ b[i] = (byte)(strLen >> (8 * (n - i)));
+ }
- return b;
+ return b;
}
public static byte[] rightEncode(long strLen)
@@ -45,4 +47,18 @@
return b;
}
+
+ static byte[] encode(byte X)
+ {
+ return Arrays.concatenate(XofUtils.leftEncode(8), new byte[] { X });
+ }
+
+ static byte[] encode(byte[] in, int inOff, int len)
+ {
+ if (in.length == len)
+ {
+ return Arrays.concatenate(XofUtils.leftEncode(len * 8), in);
+ }
+ return Arrays.concatenate(XofUtils.leftEncode(len * 8), Arrays.copyOfRange(in, inOff, inOff + len));
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/XoodyakDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/XoodyakDigest.java
new file mode 100644
index 0000000..476dee3
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/XoodyakDigest.java
@@ -0,0 +1,206 @@
+package org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Pack;
+
+/**
+ * Xoodyak v1, https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/xoodyak-spec-final.pdf
+ * <p>
+ * Xoodyak with reference to C Reference Impl from: https://github.com/XKCP/XKCP
+ * </p>
+ */
+
+public class XoodyakDigest
+ implements Digest
+{
+ private byte[] state;
+ private int phase;
+ private MODE mode;
+ private int Rabsorb;
+ private final int f_bPrime = 48;
+ private final int Rhash = 16;
+ private final int PhaseDown = 1;
+ private final int PhaseUp = 2;
+ private final int NLANES = 12;
+ private final int NROWS = 3;
+ private final int NCOLUMS = 4;
+ private final int MAXROUNDS = 12;
+ private final int TAGLEN = 16;
+ private final int[] RC = {0x00000058, 0x00000038, 0x000003C0, 0x000000D0, 0x00000120, 0x00000014, 0x00000060,
+ 0x0000002C, 0x00000380, 0x000000F0, 0x000001A0, 0x00000012};
+ private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+
+ enum MODE
+ {
+ ModeHash,
+ ModeKeyed
+ }
+
+ public XoodyakDigest()
+ {
+ state = new byte[48];
+ reset();
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return "Xoodyak Hash";
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return 32;
+ }
+
+ @Override
+ public void update(byte input)
+ {
+ buffer.write(input);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+
+ }
+
+ @Override
+ public int doFinal(byte[] output, int outOff)
+ {
+ if (32 + outOff > output.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ byte[] input = buffer.toByteArray();
+ int inOff = 0;
+ int len = buffer.size();
+ int Cd = 0x03;
+ int splitLen;
+ do
+ {
+ if (phase != PhaseUp)
+ {
+ Up(null, 0, 0, 0);
+ }
+ splitLen = Math.min(len, Rabsorb);
+ Down(input, inOff, splitLen, Cd);
+ Cd = 0;
+ inOff += splitLen;
+ len -= splitLen;
+ }
+ while (len != 0);
+ Up(output, outOff, TAGLEN, 0x40);
+ Down(null, 0, 0, 0);
+ Up(output, outOff + TAGLEN, TAGLEN, 0);
+ return 32;
+ }
+
+ @Override
+ public void reset()
+ {
+ Arrays.fill(state, (byte)0);
+ phase = PhaseUp;
+ mode = MODE.ModeHash;
+ Rabsorb = Rhash;
+ buffer.reset();
+ }
+
+ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
+ {
+ if (mode != MODE.ModeHash)
+ {
+ state[f_bPrime - 1] ^= Cu;
+ }
+ int[] a = new int[NLANES];
+ Pack.littleEndianToInt(state, 0, a, 0, a.length);
+ int x, y;
+ int[] b = new int[NLANES];
+ int[] p = new int[NCOLUMS];
+ int[] e = new int[NCOLUMS];
+ for (int i = 0; i < MAXROUNDS; ++i)
+ {
+ /* Theta: Column Parity Mixer */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ p[x] = a[index(x, 0)] ^ a[index(x, 1)] ^ a[index(x, 2)];
+ }
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ y = p[(x + 3) & 3];
+ e[x] = ROTL32(y, 5) ^ ROTL32(y, 14);
+ }
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ for (y = 0; y < NROWS; ++y)
+ {
+ a[index(x, y)] ^= e[x];
+ }
+ }
+ /* Rho-west: plane shift */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ b[index(x, 0)] = a[index(x, 0)];
+ b[index(x, 1)] = a[index(x + 3, 1)];
+ b[index(x, 2)] = ROTL32(a[index(x, 2)], 11);
+ }
+ /* Iota: round ant */
+ b[0] ^= RC[i];
+ /* Chi: non linear layer */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ for (y = 0; y < NROWS; ++y)
+ {
+ a[index(x, y)] = b[index(x, y)] ^ (~b[index(x, y + 1)] & b[index(x, y + 2)]);
+ }
+ }
+ /* Rho-east: plane shift */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ b[index(x, 0)] = a[index(x, 0)];
+ b[index(x, 1)] = ROTL32(a[index(x, 1)], 1);
+ b[index(x, 2)] = ROTL32(a[index(x + 2, 2)], 8);
+ }
+ System.arraycopy(b, 0, a, 0, NLANES);
+ }
+ Pack.intToLittleEndian(a, 0, a.length, state, 0);
+ phase = PhaseUp;
+ if (Yi != null)
+ {
+ System.arraycopy(state, 0, Yi, YiOff, YiLen);
+ }
+ }
+
+ void Down(byte[] Xi, int XiOff, int XiLen, int Cd)
+ {
+ for (int i = 0; i < XiLen; i++)
+ {
+ state[i] ^= Xi[XiOff++];
+ }
+ state[XiLen] ^= 0x01;
+ state[f_bPrime - 1] ^= (mode == MODE.ModeHash) ? (Cd & 0x01) : Cd;
+ phase = PhaseDown;
+ }
+
+ private int index(int x, int y)
+ {
+ return (((y % NROWS) * NCOLUMS) + ((x) % NCOLUMS));
+ }
+
+ private int ROTL32(int a, int offset)
+ {
+ return (a << (offset & 31)) ^ (a >>> ((32 - (offset)) & 31));
+ }
+
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java b/bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
index 43ea0a7..910240b 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
@@ -83,10 +83,15 @@
*
static X9ECParametersHolder curve25519 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new Curve25519());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new Curve25519());
+ ECCurve curve = getCurve();
/*
* NOTE: Curve25519 was specified in Montgomery form. Rewriting in Weierstrass form
@@ -109,10 +114,15 @@
*
static X9ECParametersHolder secp128r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP128R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
- ECCurve curve = configureCurve(new SecP128R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -124,9 +134,8 @@
*
static X9ECParametersHolder secp160k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
@@ -140,7 +149,13 @@
new BigInteger("9162fbe73984472a0a9d0590", 16),
new BigInteger("96341f1138933bc2f503fd44", 16),
176));
- ECCurve curve = configureCurveGLV(new SecP160K1Curve(), glv);
+ return configureCurveGLV(new SecP160K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -152,10 +167,15 @@
*
static X9ECParametersHolder secp160r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP160R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
- ECCurve curve = configureCurve(new SecP160R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -167,10 +187,15 @@
*
static X9ECParametersHolder secp160r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP160R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
- ECCurve curve = configureCurve(new SecP160R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -184,9 +209,8 @@
*/
static X9ECParametersHolder secp192k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
@@ -200,7 +224,13 @@
new BigInteger("71169be7330b3038edb025f1d0f9", 16),
new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
208));
- ECCurve curve = configureCurveGLV(new SecP192K1Curve(), glv);
+ return configureCurveGLV(new SecP192K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -212,10 +242,15 @@
*/
static X9ECParametersHolder secp192r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP192R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
- ECCurve curve = configureCurve(new SecP192R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -227,9 +262,8 @@
*/
static X9ECParametersHolder secp224k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
@@ -243,7 +277,13 @@
new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
240));
- ECCurve curve = configureCurveGLV(new SecP224K1Curve(), glv);
+ return configureCurveGLV(new SecP224K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -255,10 +295,15 @@
*/
static X9ECParametersHolder secp224r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP224R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
- ECCurve curve = configureCurve(new SecP224R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -270,9 +315,8 @@
*/
static X9ECParametersHolder secp256k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
@@ -286,7 +330,13 @@
new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
272));
- ECCurve curve = configureCurveGLV(new SecP256K1Curve(), glv);
+ return configureCurveGLV(new SecP256K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -298,10 +348,15 @@
*/
static X9ECParametersHolder secp256r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP256R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
- ECCurve curve = configureCurve(new SecP256R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -313,10 +368,15 @@
*/
static X9ECParametersHolder secp384r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP384R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
- ECCurve curve = configureCurve(new SecP384R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
@@ -329,10 +389,15 @@
*/
static X9ECParametersHolder secp521r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP521R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
- ECCurve curve = configureCurve(new SecP521R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
+ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
@@ -347,10 +412,15 @@
*
static X9ECParametersHolder sect113r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT113R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
- ECCurve curve = configureCurve(new SecT113R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -362,10 +432,15 @@
*
static X9ECParametersHolder sect113r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT113R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
- ECCurve curve = configureCurve(new SecT113R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -377,10 +452,15 @@
*
static X9ECParametersHolder sect131r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT131R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
- ECCurve curve = configureCurve(new SecT131R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -392,10 +472,15 @@
*
static X9ECParametersHolder sect131r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT131R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
- ECCurve curve = configureCurve(new SecT131R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -407,10 +492,15 @@
*
static X9ECParametersHolder sect163k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT163K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT163K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -422,10 +512,15 @@
*
static X9ECParametersHolder sect163r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT163R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
- ECCurve curve = configureCurve(new SecT163R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -437,10 +532,15 @@
*
static X9ECParametersHolder sect163r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT163R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
- ECCurve curve = configureCurve(new SecT163R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -452,10 +552,15 @@
*
static X9ECParametersHolder sect193r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT193R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
- ECCurve curve = configureCurve(new SecT193R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -467,10 +572,15 @@
*
static X9ECParametersHolder sect193r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT193R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
- ECCurve curve = configureCurve(new SecT193R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -482,10 +592,15 @@
*
static X9ECParametersHolder sect233k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT233K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT233K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -497,10 +612,15 @@
*
static X9ECParametersHolder sect233r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT233R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
- ECCurve curve = configureCurve(new SecT233R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -512,10 +632,15 @@
*
static X9ECParametersHolder sect239k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT239K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT239K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -527,10 +652,15 @@
*
static X9ECParametersHolder sect283k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT283K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT283K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
+ "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
@@ -543,10 +673,15 @@
*
static X9ECParametersHolder sect283r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT283R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
- ECCurve curve = configureCurve(new SecT283R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
+ "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
@@ -559,10 +694,15 @@
*
static X9ECParametersHolder sect409k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT409K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT409K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
+ "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
@@ -575,10 +715,15 @@
*
static X9ECParametersHolder sect409r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT409R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
- ECCurve curve = configureCurve(new SecT409R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
+ "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
@@ -591,10 +736,15 @@
*
static X9ECParametersHolder sect571k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT571K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT571K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
+ "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
@@ -607,10 +757,15 @@
*
static X9ECParametersHolder sect571r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT571R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
- ECCurve curve = configureCurve(new SecT571R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
+ "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
@@ -623,10 +778,15 @@
*
static X9ECParametersHolder sm2p256v1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SM2P256V1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SM2P256V1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0432C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -636,6 +796,7 @@
// END Android-removed: Unsupported curves
+
static final Hashtable nameToCurve = new Hashtable();
static final Hashtable nameToOID = new Hashtable();
static final Hashtable oidToCurve = new Hashtable();
@@ -742,10 +903,15 @@
public static X9ECParameters getByName(String name)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)nameToCurve.get(Strings.toLowerCase(name));
+ X9ECParametersHolder holder = getByNameLazy(name);
return holder == null ? null : holder.getParameters();
}
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ return (X9ECParametersHolder)nameToCurve.get(Strings.toLowerCase(name));
+ }
+
/**
* return the X9ECParameters object for the named curve represented by the passed in object
* identifier. Null if the curve isn't present.
@@ -755,10 +921,15 @@
*/
public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)oidToCurve.get(oid);
+ X9ECParametersHolder holder = getByOIDLazy(oid);
return holder == null ? null : holder.getParameters();
}
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return (X9ECParametersHolder)oidToCurve.get(oid);
+ }
+
/**
* return the object identifier signified by the passed in name. Null if there is no object
* identifier associated with name.
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
index a38da9a..2e32b25 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
@@ -13,6 +13,7 @@
// import org.bouncycastle.crypto.util.DigestFactory;
import org.bouncycastle.crypto.digests.AndroidDigestFactory;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Pack;
/**
* Optimal Asymmetric Encryption Padding (OAEP) - see PKCS 1 V 2.
@@ -225,7 +226,9 @@
// on encryption, we need to make sure our decrypted block comes back
// the same size.
//
- boolean wrongData = (block.length < (2 * defHash.length) + 1);
+
+ // i.e. wrong when block.length < (2 * defHash.length) + 1
+ int wrongMask = (block.length - ((2 * defHash.length) + 1)) >> 31;
if (data.length <= block.length)
{
@@ -234,7 +237,7 @@
else
{
System.arraycopy(data, 0, block, 0, block.length);
- wrongData = true;
+ wrongMask |= 1;
}
//
@@ -262,39 +265,38 @@
// check the hash of the encoding params.
// long check to try to avoid this been a source of a timing attack.
//
- boolean defHashWrong = false;
-
for (int i = 0; i != defHash.length; i++)
{
- if (defHash[i] != block[defHash.length + i])
- {
- defHashWrong = true;
- }
+ wrongMask |= defHash[i] ^ block[defHash.length + i];
}
//
// find the data block
//
- int start = block.length;
+ int start = -1;
for (int index = 2 * defHash.length; index != block.length; index++)
{
- if (block[index] != 0 & start == block.length)
- {
- start = index;
- }
+ int octet = block[index] & 0xFF;
+
+ // i.e. mask will be 0xFFFFFFFF if octet is non-zero and start is (still) negative, else 0.
+ int shouldSetMask = (-octet & start) >> 31;
+
+ start += index & shouldSetMask;
}
- boolean dataStartWrong = (start > (block.length - 1) | block[start] != 1);
+ wrongMask |= start >> 31;
+ ++start;
+ wrongMask |= block[start] ^ 1;
- start++;
-
- if (defHashWrong | wrongData | dataStartWrong)
+ if (wrongMask != 0)
{
Arrays.fill(block, (byte)0);
throw new InvalidCipherTextException("data wrong");
}
+ ++start;
+
//
// extract the data block
//
@@ -307,19 +309,6 @@
}
/**
- * int to octet string.
- */
- private void ItoOSP(
- int i,
- byte[] sp)
- {
- sp[0] = (byte)(i >>> 24);
- sp[1] = (byte)(i >>> 16);
- sp[2] = (byte)(i >>> 8);
- sp[3] = (byte)(i >>> 0);
- }
-
- /**
* mask generator function, as described in PKCS1v2.
*/
private byte[] maskGeneratorFunction1(
@@ -337,7 +326,7 @@
while (counter < (length / hashBuf.length))
{
- ItoOSP(counter, C);
+ Pack.intToBigEndian(counter, C, 0);
mgf1Hash.update(Z, zOff, zLen);
mgf1Hash.update(C, 0, C.length);
@@ -350,7 +339,7 @@
if ((counter * hashBuf.length) < length)
{
- ItoOSP(counter, C);
+ Pack.intToBigEndian(counter, C, 0);
mgf1Hash.update(Z, zOff, zLen);
mgf1Hash.update(C, 0, C.length);
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 02a1ff1..470f81c 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
@@ -233,52 +233,86 @@
}
/**
- * Checks if the argument is a correctly PKCS#1.5 encoded Plaintext
- * for encryption.
- *
- * @param encoded The Plaintext.
- * @param pLen Expected length of the plaintext.
- * @return Either 0, if the encoding is correct, or -1, if it is incorrect.
+ * Check the argument is a valid encoding with type 1. Returns the plaintext length if valid, or -1 if invalid.
*/
- private static int checkPkcs1Encoding(byte[] encoded, int pLen)
+ private static int checkPkcs1Encoding1(byte[] buf)
{
- int correct = 0;
- /*
- * Check if the first two bytes are 0 2
- */
- correct |= (encoded[0] ^ 2);
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
- /*
- * Now the padding check, check for no 0 byte in the padding
- */
- int plen = encoded.length - (
- pLen /* Length of the PMS */
- + 1 /* Final 0-byte before PMS */
- );
+ // The first byte should be 0x01
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x01);
- for (int i = 1; i < plen; i++)
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
{
- int tmp = encoded[i];
- tmp |= tmp >> 1;
- tmp |= tmp >> 2;
- tmp |= tmp >> 4;
- correct |= (tmp & 1) - 1;
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ int is0xFFMask = ((padByte ^ 0xFF) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ badPadSign |= ~(foundZeroMask | is0xFFMask);
}
- /*
- * Make sure the padding ends with a 0 byte.
- */
- correct |= encoded[encoded.length - (pLen + 1)];
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
- /*
- * Return 0 or 1, depending on the result.
- */
- correct |= correct >> 1;
- correct |= correct >> 2;
- correct |= correct >> 4;
- return ~((correct & 1) - 1);
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
}
+ /**
+ * Check the argument is a valid encoding with type 2. Returns the plaintext length if valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding2(byte[] buf)
+ {
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
+
+ // The first byte should be 0x02
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x02);
+
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
+ {
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ }
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
+ }
+
+ /**
+ * Check the argument is a valid encoding with type 2 of a plaintext with the given length. Returns 0 if
+ * valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding2(byte[] buf, int plaintextLength)
+ {
+ // The first byte should be 0x02
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x02);
+
+ int lastPadPos = buf.length - 1 - plaintextLength;
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ // All pad bytes before the last one should be non-zero
+ for (int i = 1; i < lastPadPos; ++i)
+ {
+ badPadSign |= (buf[i] & 0xFF) - 1;
+ }
+
+ // Last pad byte should be zero
+ badPadSign |= -(buf[lastPadPos] & 0xFF);
+
+ return badPadSign >> 31;
+ }
/**
* Decode PKCS#1.5 encoding, and return a random value if the padding is not correct.
@@ -298,36 +332,43 @@
throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
}
- byte[] block = engine.processBlock(in, inOff, inLen);
- byte[] random;
- if (this.fallback == null)
+ int plaintextLength = this.pLen;
+
+ byte[] random = fallback;
+ if (fallback == null)
{
- random = new byte[this.pLen];
+ random = new byte[plaintextLength];
this.random.nextBytes(random);
}
- else
+
+ int badPadMask = 0;
+ int strictBlockSize = engine.getOutputBlockSize();
+ byte[] block = engine.processBlock(in, inOff, inLen);
+
+ byte[] data = block;
+ if (block.length != strictBlockSize)
{
- random = fallback;
+ if (useStrictLength || block.length < strictBlockSize)
+ {
+ data = blockBuffer;
+ }
}
- byte[] data = (useStrictLength & (block.length != engine.getOutputBlockSize())) ? blockBuffer : block;
+ badPadMask |= checkPkcs1Encoding2(data, plaintextLength);
- /*
- * Check the padding.
- */
- int correct = PKCS1Encoding.checkPkcs1Encoding(data, this.pLen);
-
- /*
- * Now, to a constant time constant memory copy of the decrypted value
- * or the random value, depending on the validity of the padding.
- */
- byte[] result = new byte[this.pLen];
- for (int i = 0; i < this.pLen; i++)
+ /*
+ * Now, to a constant time constant memory copy of the decrypted value
+ * or the random value, depending on the validity of the padding.
+ */
+ int dataOff = data.length - plaintextLength;
+ byte[] result = new byte[plaintextLength];
+ for (int i = 0; i < plaintextLength; ++i)
{
- result[i] = (byte)((data[i + (data.length - pLen)] & (~correct)) | (random[i] & correct));
+ result[i] = (byte)((data[dataOff + i] & ~badPadMask) | (random[i] & badPadMask));
}
- Arrays.fill(data, (byte)0);
+ Arrays.fill(block, (byte)0);
+ Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0);
return result;
}
@@ -335,95 +376,50 @@
/**
* @throws InvalidCipherTextException if the decrypted block is not in PKCS1 format.
*/
- private byte[] decodeBlock(
- byte[] in,
- int inOff,
- int inLen)
+ private byte[] decodeBlock(byte[] in, int inOff, int inLen)
throws InvalidCipherTextException
{
/*
* If the length of the expected plaintext is known, we use a constant-time decryption.
* If the decryption fails, we return a random value.
*/
- if (this.pLen != -1)
+ if (forPrivateKey && this.pLen != -1)
{
return this.decodeBlockOrRandom(in, inOff, inLen);
}
+ int strictBlockSize = engine.getOutputBlockSize();
byte[] block = engine.processBlock(in, inOff, inLen);
- boolean incorrectLength = (useStrictLength & (block.length != engine.getOutputBlockSize()));
- byte[] data;
- if (block.length < getOutputBlockSize())
+ boolean incorrectLength = useStrictLength & (block.length != strictBlockSize);
+
+ byte[] data = block;
+ if (block.length < strictBlockSize)
{
data = blockBuffer;
}
- else
+
+ int plaintextLength = forPrivateKey ? checkPkcs1Encoding2(data) : checkPkcs1Encoding1(data);
+
+ try
{
- data = block;
- }
-
- byte type = data[0];
-
- boolean badType;
- if (forPrivateKey)
- {
- badType = (type != 2);
- }
- else
- {
- badType = (type != 1);
- }
-
- //
- // find and extract the message block.
- //
- int start = findStart(type, data);
-
- start++; // data should start at the next byte
-
- if (badType | start < HEADER_LENGTH)
- {
- Arrays.fill(data, (byte)0);
- throw new InvalidCipherTextException("block incorrect");
- }
-
- // if we get this far, it's likely to be a genuine encoding error
- if (incorrectLength)
- {
- Arrays.fill(data, (byte)0);
- throw new InvalidCipherTextException("block incorrect size");
- }
-
- byte[] result = new byte[data.length - start];
-
- System.arraycopy(data, start, result, 0, result.length);
-
- return result;
- }
-
- private int findStart(byte type, byte[] block)
- throws InvalidCipherTextException
- {
- int start = -1;
- boolean padErr = false;
-
- for (int i = 1; i != block.length; i++)
- {
- byte pad = block[i];
-
- if (pad == 0 & start < 0)
+ if (plaintextLength < 0)
{
- start = i;
+ throw new InvalidCipherTextException("block incorrect");
}
- padErr |= (type == 1 & start < 0 & pad != (byte)0xff);
- }
+ if (incorrectLength)
+ {
+ throw new InvalidCipherTextException("block incorrect size");
+ }
- if (padErr)
+ byte[] result = new byte[plaintextLength];
+ System.arraycopy(data, data.length - plaintextLength, result, 0, plaintextLength);
+ return result;
+ }
+ finally
{
- return -1;
+ Arrays.fill(block, (byte)0);
+ Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0);
}
-
- return start;
}
}
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 0b491ab..ac2eb9a 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java
@@ -1,9 +1,12 @@
package org.bouncycastle.crypto.engines;
-import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.DefaultMultiBlockCipher;
+import org.bouncycastle.crypto.MultiBlockCipher;
import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Pack;
@@ -14,7 +17,7 @@
* For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
- * <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
+ * <a href="https://fp.gladman.plus.com/cryptography_technology/rijndael/">https://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
*
* There are three levels of tradeoff of speed vs memory
* Because java has no preprocessor, they are written as three separate classes from which to choose
@@ -32,7 +35,7 @@
*
*/
public class AESEngine
- implements BlockCipher
+ extends DefaultMultiBlockCipher
{
// The S box
private static final byte[] S = {
@@ -412,7 +415,6 @@
private int ROUNDS;
private int[][] WorkingKey = null;
- private int C0, C1, C2, C3;
private boolean forEncryption;
private byte[] s;
@@ -420,10 +422,22 @@
private static final int BLOCK_SIZE = 16;
/**
+ * Return an AESEngine.
+ *
+ * @return an AES ECB mode cipher.
+ */
+ public static MultiBlockCipher newInstance()
+ {
+ return new AESEngine();
+ }
+
+ /**
* default constructor - 128 bit block size.
+ * @deprecated use AESEngine.newInstance()
*/
public AESEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 256));
}
/**
@@ -450,6 +464,9 @@
{
s = Arrays.clone(Si);
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, Utils.getPurpose(forEncryption)));
+
return;
}
@@ -466,38 +483,30 @@
return BLOCK_SIZE;
}
- public int processBlock(
- byte[] in,
- int inOff,
- byte[] out,
- int outOff)
+ public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
{
if (WorkingKey == null)
{
throw new IllegalStateException("AES engine not initialised");
}
- if ((inOff + (32 / 2)) > in.length)
+ if (inOff > (in.length - BLOCK_SIZE))
{
throw new DataLengthException("input buffer too short");
}
- if ((outOff + (32 / 2)) > out.length)
+ if (outOff > (out.length - BLOCK_SIZE))
{
throw new OutputLengthException("output buffer too short");
}
if (forEncryption)
{
- unpackBlock(in, inOff);
- encryptBlock(WorkingKey);
- packBlock(out, outOff);
+ encryptBlock(in, inOff, out, outOff, WorkingKey);
}
else
{
- unpackBlock(in, inOff);
- decryptBlock(WorkingKey);
- packBlock(out, outOff);
+ decryptBlock(in, inOff, out, outOff, WorkingKey);
}
return BLOCK_SIZE;
@@ -507,68 +516,18 @@
{
}
- private void unpackBlock(
- byte[] bytes,
- int off)
+ private void encryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- int index = off;
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- C0 = (bytes[index++] & 0xff);
- C0 |= (bytes[index++] & 0xff) << 8;
- C0 |= (bytes[index++] & 0xff) << 16;
- C0 |= bytes[index++] << 24;
+ int t0 = C0 ^ KW[0][0];
+ int t1 = C1 ^ KW[0][1];
+ int t2 = C2 ^ KW[0][2];
- C1 = (bytes[index++] & 0xff);
- C1 |= (bytes[index++] & 0xff) << 8;
- C1 |= (bytes[index++] & 0xff) << 16;
- C1 |= bytes[index++] << 24;
-
- C2 = (bytes[index++] & 0xff);
- C2 |= (bytes[index++] & 0xff) << 8;
- C2 |= (bytes[index++] & 0xff) << 16;
- C2 |= bytes[index++] << 24;
-
- C3 = (bytes[index++] & 0xff);
- C3 |= (bytes[index++] & 0xff) << 8;
- C3 |= (bytes[index++] & 0xff) << 16;
- C3 |= bytes[index++] << 24;
- }
-
- private void packBlock(
- byte[] bytes,
- int off)
- {
- int index = off;
-
- bytes[index++] = (byte)C0;
- bytes[index++] = (byte)(C0 >> 8);
- bytes[index++] = (byte)(C0 >> 16);
- bytes[index++] = (byte)(C0 >> 24);
-
- bytes[index++] = (byte)C1;
- bytes[index++] = (byte)(C1 >> 8);
- bytes[index++] = (byte)(C1 >> 16);
- bytes[index++] = (byte)(C1 >> 24);
-
- bytes[index++] = (byte)C2;
- bytes[index++] = (byte)(C2 >> 8);
- bytes[index++] = (byte)(C2 >> 16);
- bytes[index++] = (byte)(C2 >> 24);
-
- bytes[index++] = (byte)C3;
- bytes[index++] = (byte)(C3 >> 8);
- bytes[index++] = (byte)(C3 >> 16);
- bytes[index++] = (byte)(C3 >> 24);
- }
-
-
- private void encryptBlock(int[][] KW)
- {
- int t0 = this.C0 ^ KW[0][0];
- int t1 = this.C1 ^ KW[0][1];
- int t2 = this.C2 ^ KW[0][2];
-
- int r = 1, r0, r1, r2, r3 = this.C3 ^ KW[0][3];
+ int r = 1, r0, r1, r2, r3 = C3 ^ KW[0][3];
while (r < ROUNDS - 1)
{
r0 = T0[t0&255] ^ shift(T0[(t1>>8)&255], 24) ^ shift(T0[(t2>>16)&255], 16) ^ shift(T0[(r3>>24)&255], 8) ^ KW[r][0];
@@ -588,19 +547,29 @@
// the final round's table is a simple function of S so we don't use a whole other four tables for it
- this.C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[r][0];
- this.C1 = (s[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[r][1];
- this.C2 = (s[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2];
- this.C3 = (s[r3&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3];
+ C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[r][0];
+ C1 = (s[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[r][1];
+ C2 = (s[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2];
+ C3 = (s[r3&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
}
- private void decryptBlock(int[][] KW)
+ private void decryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- int t0 = this.C0 ^ KW[ROUNDS][0];
- int t1 = this.C1 ^ KW[ROUNDS][1];
- int t2 = this.C2 ^ KW[ROUNDS][2];
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- int r = ROUNDS - 1, r0, r1, r2, r3 = this.C3 ^ KW[ROUNDS][3];
+ int t0 = C0 ^ KW[ROUNDS][0];
+ int t1 = C1 ^ KW[ROUNDS][1];
+ int t2 = C2 ^ KW[ROUNDS][2];
+
+ int r = ROUNDS - 1, r0, r1, r2, r3 = C3 ^ KW[ROUNDS][3];
while (r > 1)
{
r0 = Tinv0[t0&255] ^ shift(Tinv0[(r3>>8)&255], 24) ^ shift(Tinv0[(t2>>16)&255], 16) ^ shift(Tinv0[(t1>>24)&255], 8) ^ KW[r][0];
@@ -620,9 +589,23 @@
// the final round's table is a simple function of Si so we don't use a whole other four tables for it
- this.C0 = (Si[r0&255]&255) ^ ((s[(r3>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0];
- this.C1 = (s[r1&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (s[(r2>>24)&255]<<24) ^ KW[0][1];
- this.C2 = (s[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[0][2];
- this.C3 = (Si[r3&255]&255) ^ ((s[(r2>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[0][3];
+ C0 = (Si[r0&255]&255) ^ ((s[(r3>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0];
+ C1 = (s[r1&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (s[(r2>>24)&255]<<24) ^ KW[0][1];
+ C2 = (s[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[0][2];
+ C3 = (Si[r3&255]&255) ^ ((s[(r2>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[0][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
+ }
+
+ private int bitsOfSecurity()
+ {
+ if (WorkingKey == null)
+ {
+ return 256;
+ }
+ return (WorkingKey.length - 7) << 5;
}
}
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 b73e0a5..1d41763 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
@@ -2,8 +2,10 @@
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.Pack;
@@ -13,7 +15,7 @@
* For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
- * <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
+ * <a href="https://fp.gladman.plus.com/cryptography_technology/rijndael/">https://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
*
* There are three levels of tradeoff of speed vs memory
* Because java has no preprocessor, they are written as three separate classes from which to choose
@@ -741,7 +743,6 @@
private int ROUNDS;
private int[][] WorkingKey = null;
- private int C0, C1, C2, C3;
private boolean forEncryption;
private static final int BLOCK_SIZE = 16;
@@ -751,6 +752,7 @@
*/
public AESFastEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 256));
}
/**
@@ -769,6 +771,7 @@
{
WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption);
this.forEncryption = forEncryption;
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, Utils.getPurpose(forEncryption)));
return;
}
@@ -785,40 +788,32 @@
return BLOCK_SIZE;
}
- public int processBlock(
- byte[] in,
- int inOff,
- byte[] out,
- int outOff)
+ public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
{
if (WorkingKey == null)
{
throw new IllegalStateException("AES engine not initialised");
}
- if ((inOff + (32 / 2)) > in.length)
+ if (inOff > (in.length - BLOCK_SIZE))
{
throw new DataLengthException("input buffer too short");
}
- if ((outOff + (32 / 2)) > out.length)
+ if (outOff > (out.length - BLOCK_SIZE))
{
throw new OutputLengthException("output buffer too short");
}
- unpackBlock(in, inOff);
-
if (forEncryption)
{
- encryptBlock(WorkingKey);
+ encryptBlock(in, inOff, out, outOff, WorkingKey);
}
else
{
- decryptBlock(WorkingKey);
+ decryptBlock(in, inOff, out, outOff, WorkingKey);
}
- packBlock(out, outOff);
-
return BLOCK_SIZE;
}
@@ -826,27 +821,16 @@
{
}
- private void unpackBlock(byte[] bytes, int off)
+ private void encryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- this.C0 = Pack.littleEndianToInt(bytes, off);
- this.C1 = Pack.littleEndianToInt(bytes, off + 4);
- this.C2 = Pack.littleEndianToInt(bytes, off + 8);
- this.C3 = Pack.littleEndianToInt(bytes, off + 12);
- }
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- private void packBlock(byte[] bytes, int off)
- {
- Pack.intToLittleEndian(this.C0, bytes, off);
- Pack.intToLittleEndian(this.C1, bytes, off + 4);
- Pack.intToLittleEndian(this.C2, bytes, off + 8);
- Pack.intToLittleEndian(this.C3, bytes, off + 12);
- }
-
- private void encryptBlock(int[][] KW)
- {
- int t0 = this.C0 ^ KW[0][0];
- int t1 = this.C1 ^ KW[0][1];
- int t2 = this.C2 ^ KW[0][2];
+ int t0 = C0 ^ KW[0][0];
+ int t1 = C1 ^ KW[0][1];
+ int t2 = C2 ^ KW[0][2];
/*
* Fast engine has precomputed rotr(T0, 8/16/24) tables T1/T2/T3.
@@ -855,7 +839,7 @@
* avoids additional array range checks on 3 more arrays (which on HotSpot are more
* expensive than the offset additions).
*/
- int r = 1, r0, r1, r2, r3 = this.C3 ^ KW[0][3];
+ int r = 1, r0, r1, r2, r3 = C3 ^ KW[0][3];
int i0, i1, i2, i3;
while (r < ROUNDS - 1)
@@ -913,28 +897,38 @@
i0 = r0; i1 = r1 >>> 8; i2 = r2 >>> 16; i3 = r3 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][0];
+ C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][0];
i0 = r1; i1 = r2 >>> 8; i2 = r3 >>> 16; i3 = r0 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][1];
+ C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][1];
i0 = r2; i1 = r3 >>> 8; i2 = r0 >>> 16; i3 = r1 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][2];
+ C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][2];
i0 = r3; i1 = r0 >>> 8; i2 = r1 >>> 16; i3 = r2 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][3];
+ C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
}
- private void decryptBlock(int[][] KW)
+ private void decryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- int t0 = this.C0 ^ KW[ROUNDS][0];
- int t1 = this.C1 ^ KW[ROUNDS][1];
- int t2 = this.C2 ^ KW[ROUNDS][2];
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- int r = ROUNDS - 1, r0, r1, r2, r3 = this.C3 ^ KW[ROUNDS][3];
+ int t0 = C0 ^ KW[ROUNDS][0];
+ int t1 = C1 ^ KW[ROUNDS][1];
+ int t2 = C2 ^ KW[ROUNDS][2];
+
+ int r = ROUNDS - 1, r0, r1, r2, r3 = C3 ^ KW[ROUNDS][3];
int i0, i1, i2, i3;
while (r > 1)
@@ -992,18 +986,33 @@
i0 = r0; i1 = r3 >>> 8; i2 = r2 >>> 16; i3 = r1 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][0];
+ C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][0];
i0 = r1; i1 = r0 >>> 8; i2 = r3 >>> 16; i3 = r2 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][1];
+ C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][1];
i0 = r2; i1 = r1 >>> 8; i2 = r0 >>> 16; i3 = r3 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][2];
+ C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][2];
i0 = r3; i1 = r2 >>> 8; i2 = r1 >>> 16; i3 = r0 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][3];
+ C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
+ }
+
+ // Service Definitions
+ private int bitsOfSecurity()
+ {
+ if (WorkingKey == null)
+ {
+ return 256;
+ }
+ return (WorkingKey.length - 7) << 5;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java
index b80d653..cf70e87 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java
@@ -14,16 +14,16 @@
*/
public AESWrapEngine()
{
- super(new AESEngine());
+ super(AESEngine.newInstance());
}
/**
- * Create an AESWrapEngine where the underlying cipher is set to decrypt for wrapping, encrypt for unwrapping.
+ * Create an AESWrapEngine where the underlying cipher is (optionally) set to decrypt for wrapping, encrypt for unwrapping.
*
* @param useReverseDirection true if underlying cipher should be used in decryption mode, false otherwise.
*/
public AESWrapEngine(boolean useReverseDirection)
{
- super(new AESEngine(), useReverseDirection);
+ super(AESEngine.newInstance(), useReverseDirection);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AsconEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AsconEngine.java
new file mode 100644
index 0000000..e4d705f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AsconEngine.java
@@ -0,0 +1,738 @@
+package org.bouncycastle.crypto.engines;
+
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
+import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import org.bouncycastle.crypto.modes.AEADCipher;
+import org.bouncycastle.crypto.params.AEADParameters;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.params.ParametersWithIV;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Longs;
+import org.bouncycastle.util.Pack;
+
+/**
+ * ASCON AEAD v1.2, https://ascon.iaik.tugraz.at/
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf
+ * <p>
+ * ASCON AEAD v1.2 with reference to C Reference Impl from: https://github.com/ascon/ascon-c
+ * </p>
+ */
+public class AsconEngine
+ implements AEADCipher
+{
+ public enum AsconParameters
+ {
+ ascon80pq,
+ ascon128a,
+ ascon128
+ }
+
+ private enum State
+ {
+ Uninitialized,
+ EncInit,
+ EncAad,
+ EncData,
+ EncFinal,
+ DecInit,
+ DecAad,
+ DecData,
+ DecFinal,
+ }
+
+ private final AsconParameters asconParameters;
+ private State m_state = State.Uninitialized;
+ private byte[] mac;
+ private byte[] initialAssociatedText;
+ private final String algorithmName;
+ private final int CRYPTO_KEYBYTES;
+ private final int CRYPTO_ABYTES;
+ private final int ASCON_AEAD_RATE;
+ private final int nr;
+ private long K0;
+ private long K1;
+ private long K2;
+ private long N0;
+ private long N1;
+ private final long ASCON_IV;
+ private long x0;
+ private long x1;
+ private long x2;
+ private long x3;
+ private long x4;
+ private final int m_bufferSizeDecrypt;
+ private final byte[] m_buf;
+ private int m_bufPos = 0;
+
+ public AsconEngine(AsconParameters asconParameters)
+ {
+ this.asconParameters = asconParameters;
+ switch (asconParameters)
+ {
+ case ascon80pq:
+ CRYPTO_KEYBYTES = 20;
+ CRYPTO_ABYTES = 16;
+ ASCON_AEAD_RATE = 8;
+ ASCON_IV = 0xa0400c0600000000L;
+ algorithmName = "Ascon-80pq AEAD";
+ break;
+ case ascon128a:
+ CRYPTO_KEYBYTES = 16;
+ CRYPTO_ABYTES = 16;
+ ASCON_AEAD_RATE = 16;
+ ASCON_IV = 0x80800c0800000000L;
+ algorithmName = "Ascon-128a AEAD";
+ break;
+ case ascon128:
+ CRYPTO_KEYBYTES = 16;
+ CRYPTO_ABYTES = 16;
+ ASCON_AEAD_RATE = 8;
+ ASCON_IV = 0x80400c0600000000L;
+ algorithmName = "Ascon-128 AEAD";
+ break;
+ default:
+ throw new IllegalArgumentException("invalid parameter setting for ASCON AEAD");
+ }
+ nr = (ASCON_AEAD_RATE == 8) ? 6 : 8;
+ m_bufferSizeDecrypt = ASCON_AEAD_RATE + CRYPTO_ABYTES;
+ m_buf = new byte[m_bufferSizeDecrypt];
+ }
+
+ private long PAD(int i)
+ {
+ return 0x80L << (56 - (i << 3));
+ }
+
+ private void ROUND(long C)
+ {
+ long t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
+ long t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
+ long t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
+ long t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
+ long t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
+ x0 = t0 ^ Longs.rotateRight(t0, 19) ^ Longs.rotateRight(t0, 28);
+ x1 = t1 ^ Longs.rotateRight(t1, 39) ^ Longs.rotateRight(t1, 61);
+ x2 = ~(t2 ^ Longs.rotateRight(t2, 1) ^ Longs.rotateRight(t2, 6));
+ x3 = t3 ^ Longs.rotateRight(t3, 10) ^ Longs.rotateRight(t3, 17);
+ x4 = t4 ^ Longs.rotateRight(t4, 7) ^ Longs.rotateRight(t4, 41);
+ }
+
+ private void P(int nr)
+ {
+ if (nr >= 8)
+ {
+ if (nr == 12)
+ {
+ ROUND(0xf0L);
+ ROUND(0xe1L);
+ ROUND(0xd2L);
+ ROUND(0xc3L);
+ }
+ ROUND(0xb4L);
+ ROUND(0xa5L);
+ }
+ ROUND(0x96L);
+ ROUND(0x87L);
+ ROUND(0x78L);
+ ROUND(0x69L);
+ ROUND(0x5aL);
+ ROUND(0x4bL);
+ }
+
+ private void ascon_aeadinit()
+ {
+ /* initialize */
+ x0 = ASCON_IV;
+ if (CRYPTO_KEYBYTES == 20)
+ {
+ x0 ^= K0;
+ }
+ x1 = K1;
+ x2 = K2;
+ x3 = N0;
+ x4 = N1;
+ P(12);
+ if (CRYPTO_KEYBYTES == 20)
+ {
+ x2 ^= K0;
+ }
+ x3 ^= K1;
+ x4 ^= K2;
+ }
+
+ private void checkAAD()
+ {
+ switch (m_state)
+ {
+ case DecInit:
+ m_state = State.DecAad;
+ break;
+ case EncInit:
+ m_state = State.EncAad;
+ break;
+ case DecAad:
+ case EncAad:
+ break;
+ case EncFinal:
+ throw new IllegalStateException(getAlgorithmName() + " cannot be reused for encryption");
+ default:
+ throw new IllegalStateException(getAlgorithmName() + " needs to be initialized");
+ }
+ }
+
+ private boolean checkData()
+ {
+ switch (m_state)
+ {
+ case DecInit:
+ case DecAad:
+ finishAAD(State.DecData);
+ return false;
+ case EncInit:
+ case EncAad:
+ finishAAD(State.EncData);
+ return true;
+ case DecData:
+ return false;
+ case EncData:
+ return true;
+ case EncFinal:
+ throw new IllegalStateException(getAlgorithmName() + " cannot be reused for encryption");
+ default:
+ throw new IllegalStateException(getAlgorithmName() + " needs to be initialized");
+ }
+ }
+
+ private void processBufferAAD(byte[] buffer, int inOff)
+ {
+ x0 ^= Pack.bigEndianToLong(buffer, inOff);
+ if (ASCON_AEAD_RATE == 16)
+ {
+ x1 ^= Pack.bigEndianToLong(buffer, 8 + inOff);
+ }
+ P(nr);
+ }
+
+ private void finishAAD(State nextState)
+ {
+ // State indicates whether we ever received AAD
+ switch (m_state)
+ {
+ case DecAad:
+ case EncAad:
+ m_buf[m_bufPos] = (byte)0x80;
+ if (m_bufPos >= 8) // ASCON_AEAD_RATE == 16 is implied
+ {
+ x0 ^= Pack.bigEndianToLong(m_buf, 0);
+ x1 ^= Pack.bigEndianToLong(m_buf, 8) & (-1L << (56 - ((m_bufPos - 8) << 3)));
+ }
+ else
+ {
+ x0 ^= Pack.bigEndianToLong(m_buf, 0) & (-1L << (56 - (m_bufPos << 3)));
+ }
+ P(nr);
+ break;
+ default:
+ break;
+ }
+ // domain separation
+ x4 ^= 1L;
+ m_bufPos = 0;
+ m_state = nextState;
+ }
+
+ private void processBufferDecrypt(byte[] buffer, int bufOff, byte[] output, int outOff)
+ {
+ if (outOff + ASCON_AEAD_RATE > output.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ long t0 = Pack.bigEndianToLong(buffer, bufOff);
+ Pack.longToBigEndian(x0 ^ t0, output, outOff);
+ x0 = t0;
+
+ if (ASCON_AEAD_RATE == 16)
+ {
+ long t1 = Pack.bigEndianToLong(buffer, bufOff + 8);
+ Pack.longToBigEndian(x1 ^ t1, output, outOff + 8);
+ x1 = t1;
+ }
+ P(nr);
+ }
+
+ private void processBufferEncrypt(byte[] buffer, int bufOff, byte[] output, int outOff)
+ {
+ if (outOff + ASCON_AEAD_RATE > output.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ x0 ^= Pack.bigEndianToLong(buffer, bufOff);
+ Pack.longToBigEndian(x0, output, outOff);
+
+ if (ASCON_AEAD_RATE == 16)
+ {
+ x1 ^= Pack.bigEndianToLong(buffer, bufOff + 8);
+ Pack.longToBigEndian(x1, output, outOff + 8);
+ }
+
+ P(nr);
+ }
+
+ private void processFinalDecrypt(byte[] input, int inOff, int inLen, byte[] output, int outOff)
+ {
+ if (inLen >= 8) // ASCON_AEAD_RATE == 16 is implied
+ {
+ long c0 = Pack.bigEndianToLong(input, inOff);
+ x0 ^= c0;
+ Pack.longToBigEndian(x0, output, outOff);
+ x0 = c0;
+ inOff += 8;
+ outOff += 8;
+ inLen -= 8;
+ x1 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ long c1 = Pack.littleEndianToLong_High(input, inOff, inLen);
+ x1 ^= c1;
+ Pack.longToLittleEndian_High(x1, output, outOff, inLen);
+ x1 &= -1L >>> (inLen << 3);
+ x1 ^= c1;
+ }
+ }
+ else
+ {
+ x0 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ long c0 = Pack.littleEndianToLong_High(input, inOff, inLen);
+ x0 ^= c0;
+ Pack.longToLittleEndian_High(x0, output, outOff, inLen);
+ x0 &= -1L >>> (inLen << 3);
+ x0 ^= c0;
+ }
+ }
+
+ finishData(State.DecFinal);
+ }
+
+ private void processFinalEncrypt(byte[] input, int inOff, int inLen, byte[] output, int outOff)
+ {
+ if (inLen >= 8) // ASCON_AEAD_RATE == 16 is implied
+ {
+ x0 ^= Pack.bigEndianToLong(input, inOff);
+ Pack.longToBigEndian(x0, output, outOff);
+ inOff += 8;
+ outOff += 8;
+ inLen -= 8;
+ x1 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ x1 ^= Pack.littleEndianToLong_High(input, inOff, inLen);
+ Pack.longToLittleEndian_High(x1, output, outOff, inLen);
+ }
+ }
+ else
+ {
+ x0 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ x0 ^= Pack.littleEndianToLong_High(input, inOff, inLen);
+ Pack.longToLittleEndian_High(x0, output, outOff, inLen);
+ }
+ }
+ finishData(State.EncFinal);
+ }
+
+ private void finishData(State nextState)
+ {
+ switch (asconParameters)
+ {
+ case ascon128:
+ x1 ^= K1;
+ x2 ^= K2;
+ break;
+ case ascon128a:
+ x2 ^= K1;
+ x3 ^= K2;
+ break;
+ case ascon80pq:
+ x1 ^= (K0 << 32 | K1 >> 32);
+ x2 ^= (K1 << 32 | K2 >> 32);
+ x3 ^= K2 << 32;
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ P(12);
+ x3 ^= K1;
+ x4 ^= K2;
+
+ m_state = nextState;
+ }
+
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException
+ {
+ KeyParameter key;
+ byte[] npub;
+ if (params instanceof AEADParameters)
+ {
+ AEADParameters aeadParameters = (AEADParameters)params;
+ key = aeadParameters.getKey();
+ npub = aeadParameters.getNonce();
+ initialAssociatedText = aeadParameters.getAssociatedText();
+
+ int macSizeBits = aeadParameters.getMacSize();
+ if (macSizeBits != CRYPTO_ABYTES * 8)
+ {
+ throw new IllegalArgumentException("Invalid value for MAC size: " + macSizeBits);
+ }
+ }
+ else if (params instanceof ParametersWithIV)
+ {
+ ParametersWithIV withIV = (ParametersWithIV)params;
+ key = (KeyParameter)withIV.getParameters();
+ npub = withIV.getIV();
+ initialAssociatedText = null;
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid parameters passed to Ascon");
+ }
+
+ if (key == null)
+ {
+ throw new IllegalArgumentException("Ascon Init parameters must include a key");
+ }
+ if (npub == null || npub.length != CRYPTO_ABYTES)
+ {
+ throw new IllegalArgumentException(asconParameters + " requires exactly " + CRYPTO_ABYTES + " bytes of IV");
+ }
+
+ byte[] k = key.getKey();
+ if (k.length != CRYPTO_KEYBYTES)
+ {
+ throw new IllegalArgumentException(asconParameters + " key must be " + CRYPTO_KEYBYTES + " bytes long");
+ }
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(
+ this.getAlgorithmName(), 128, params, Utils.getPurpose(forEncryption)));
+ N0 = Pack.bigEndianToLong(npub, 0);
+ N1 = Pack.bigEndianToLong(npub, 8);
+ if (CRYPTO_KEYBYTES == 16)
+ {
+ K1 = Pack.bigEndianToLong(k, 0);
+ K2 = Pack.bigEndianToLong(k, 8);
+ }
+ else if (CRYPTO_KEYBYTES == 20)
+ {
+ K0 = Pack.bigEndianToInt(k, 0);
+ K1 = Pack.bigEndianToLong(k, 4);
+ K2 = Pack.bigEndianToLong(k, 12);
+ }
+ else
+ {
+ throw new IllegalStateException();
+ }
+
+ m_state = forEncryption ? State.EncInit : State.DecInit;
+
+ reset(true);
+ }
+
+ public String getAlgorithmName()
+ {
+ return algorithmName;
+ }
+
+ public String getAlgorithmVersion()
+ {
+ return "v1.2";
+ }
+
+ public void processAADByte(byte in)
+ {
+ checkAAD();
+ m_buf[m_bufPos] = in;
+ if (++m_bufPos == ASCON_AEAD_RATE)
+ {
+ processBufferAAD(m_buf, 0);
+ }
+ }
+
+ public void processAADBytes(byte[] inBytes, int inOff, int len)
+ {
+ if ((inOff + len) > inBytes.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ // Don't enter AAD state until we actually get input
+ if (len <= 0)
+ {
+ return;
+ }
+ checkAAD();
+ if (m_bufPos > 0)
+ {
+ int available = ASCON_AEAD_RATE - m_bufPos;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return;
+ }
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, available);
+ inOff += available;
+ len -= available;
+ processBufferAAD(m_buf, 0);
+ //m_bufPos = 0;
+ }
+ while (len >= ASCON_AEAD_RATE)
+ {
+ processBufferAAD(inBytes, inOff);
+ inOff += ASCON_AEAD_RATE;
+ len -= ASCON_AEAD_RATE;
+ }
+ System.arraycopy(inBytes, inOff, m_buf, 0, len);
+ m_bufPos = len;
+ }
+
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ return processBytes(new byte[]{in}, 0, 1, out, outOff);
+ }
+
+ public int processBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff)
+ throws DataLengthException
+ {
+ if ((inOff + len) > inBytes.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ boolean forEncryption = checkData();
+ int resultLength = 0;
+
+ if (forEncryption)
+ {
+ if (m_bufPos > 0)
+ {
+ int available = ASCON_AEAD_RATE - m_bufPos;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return 0;
+ }
+
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, available);
+ inOff += available;
+ len -= available;
+
+ processBufferEncrypt(m_buf, 0, outBytes, outOff);
+ resultLength = ASCON_AEAD_RATE;
+ //m_bufPos = 0;
+ }
+
+ while (len >= ASCON_AEAD_RATE)
+ {
+ processBufferEncrypt(inBytes, inOff, outBytes, outOff + resultLength);
+ inOff += ASCON_AEAD_RATE;
+ len -= ASCON_AEAD_RATE;
+ resultLength += ASCON_AEAD_RATE;
+ }
+ }
+ else
+ {
+ int available = m_bufferSizeDecrypt - m_bufPos;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return 0;
+ }
+
+ // NOTE: Need 'while' here because ASCON_AEAD_RATE < CRYPTO_ABYTES in some parameter sets
+ while (m_bufPos >= ASCON_AEAD_RATE)
+ {
+ processBufferDecrypt(m_buf, 0, outBytes, outOff + resultLength);
+ m_bufPos -= ASCON_AEAD_RATE;
+ System.arraycopy(m_buf, ASCON_AEAD_RATE, m_buf, 0, m_bufPos);
+ resultLength += ASCON_AEAD_RATE;
+
+ available += ASCON_AEAD_RATE;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return resultLength;
+ }
+ }
+
+ available = ASCON_AEAD_RATE - m_bufPos;
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, available);
+ inOff += available;
+ len -= available;
+ processBufferDecrypt(m_buf, 0, outBytes, outOff + resultLength);
+ resultLength += ASCON_AEAD_RATE;
+ //m_bufPos = 0;
+
+ while (len >= m_bufferSizeDecrypt)
+ {
+ processBufferDecrypt(inBytes, inOff, outBytes, outOff + resultLength);
+ inOff += ASCON_AEAD_RATE;
+ len -= ASCON_AEAD_RATE;
+ resultLength += ASCON_AEAD_RATE;
+ }
+ }
+
+ System.arraycopy(inBytes, inOff, m_buf, 0, len);
+ m_bufPos = len;
+
+ return resultLength;
+ }
+
+ public int doFinal(byte[] outBytes, int outOff)
+ throws IllegalStateException, InvalidCipherTextException, DataLengthException
+ {
+ boolean forEncryption = checkData();
+ int resultLength;
+ if (forEncryption)
+ {
+ resultLength = m_bufPos + CRYPTO_ABYTES;
+ if (outOff + resultLength > outBytes.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ processFinalEncrypt(m_buf, 0, m_bufPos, outBytes, outOff);
+ mac = new byte[CRYPTO_ABYTES];
+ Pack.longToBigEndian(x3, mac, 0);
+ Pack.longToBigEndian(x4, mac, 8);
+ System.arraycopy(mac, 0, outBytes, outOff + m_bufPos, CRYPTO_ABYTES);
+ reset(false);
+ }
+ else
+ {
+ if (m_bufPos < CRYPTO_ABYTES)
+ {
+ throw new InvalidCipherTextException("data too short");
+ }
+ m_bufPos -= CRYPTO_ABYTES;
+ resultLength = m_bufPos;
+ if (outOff + resultLength > outBytes.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ processFinalDecrypt(m_buf, 0, m_bufPos, outBytes, outOff);
+ x3 ^= Pack.bigEndianToLong(m_buf, m_bufPos);
+ x4 ^= Pack.bigEndianToLong(m_buf, m_bufPos + 8);
+ if ((x3 | x4) != 0L)
+ {
+ throw new InvalidCipherTextException("mac check in " + getAlgorithmName() + " failed");
+ }
+ reset(true);
+ }
+ return resultLength;
+ }
+
+ public byte[] getMac()
+ {
+ return mac;
+ }
+
+ public int getUpdateOutputSize(int len)
+ {
+ int total = Math.max(0, len);
+ switch (m_state)
+ {
+ case DecInit:
+ case DecAad:
+ total = Math.max(0, total - CRYPTO_ABYTES);
+ break;
+ case DecData:
+ case DecFinal:
+ total = Math.max(0, total + m_bufPos - CRYPTO_ABYTES);
+ break;
+ case EncData:
+ case EncFinal:
+ total += m_bufPos;
+ break;
+ default:
+ break;
+ }
+ return total - total % ASCON_AEAD_RATE;
+ }
+
+ public int getOutputSize(int len)
+ {
+ int total = Math.max(0, len);
+
+ switch (m_state)
+ {
+ case DecInit:
+ case DecAad:
+ return Math.max(0, total - CRYPTO_ABYTES);
+ case DecData:
+ case DecFinal:
+ return Math.max(0, total + m_bufPos - CRYPTO_ABYTES);
+ case EncData:
+ case EncFinal:
+ return total + m_bufPos + CRYPTO_ABYTES;
+ default:
+ return total + CRYPTO_ABYTES;
+ }
+ }
+
+ public void reset()
+ {
+ reset(true);
+ }
+
+ private void reset(boolean clearMac)
+ {
+ if (clearMac)
+ {
+ mac = null;
+ }
+ Arrays.clear(m_buf);
+ m_bufPos = 0;
+
+ switch (m_state)
+ {
+ case DecInit:
+ case EncInit:
+ break;
+ case DecAad:
+ case DecData:
+ case DecFinal:
+ m_state = State.DecInit;
+ break;
+ case EncAad:
+ case EncData:
+ case EncFinal:
+ m_state = State.EncFinal;
+ return;
+ default:
+ throw new IllegalStateException(getAlgorithmName() + " needs to be initialized");
+ }
+ ascon_aeadinit();
+ if (initialAssociatedText != null)
+ {
+ processAADBytes(initialAssociatedText, 0, initialAssociatedText.length);
+ }
+ }
+
+ public int getKeyBytesSize()
+ {
+ return CRYPTO_KEYBYTES;
+ }
+
+ public int getIVBytesSize()
+ {
+ return CRYPTO_ABYTES;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java
index 33918c2..c44c57f 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java
@@ -2,8 +2,11 @@
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.KeyParameter;
/**
@@ -315,6 +318,7 @@
S2 = new int[SBOX_SK];
S3 = new int[SBOX_SK];
P = new int[P_SZ];
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity()));
}
/**
@@ -335,6 +339,7 @@
this.workingKey = ((KeyParameter)params).getKey();
setKey(this.workingKey);
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, getPurpose()));
return;
}
@@ -431,6 +436,11 @@
private void setKey(byte[] key)
{
+ if (key.length < 4 || key.length > 56)
+ {
+ throw new IllegalArgumentException("key length must be in range 32 to 448 bits");
+ }
+
/*
* - comments are from _Applied Crypto_, Schneier, p338
* please be careful comparing the two, AC numbers the
@@ -575,4 +585,22 @@
b[offset + 1] = (byte)(in >> 16);
b[offset] = (byte)(in >> 24);
}
+
+ private int bitsOfSecurity()
+ {
+ if (workingKey == null)
+ {
+ return 256;
+ }
+ return (workingKey.length > 32) ? 256 : workingKey.length * 8;
+ }
+
+ private CryptoServicePurpose getPurpose()
+ {
+ if (workingKey == null)
+ {
+ return CryptoServicePurpose.ANY;
+ }
+ return encrypting ? CryptoServicePurpose.ENCRYPTION : CryptoServicePurpose.DECRYPTION;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESBase.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESBase.java
new file mode 100644
index 0000000..c7f05e2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESBase.java
@@ -0,0 +1,407 @@
+package org.bouncycastle.crypto.engines;
+
+import org.bouncycastle.util.Pack;
+
+/**
+ * a class that provides a basic DES engine.
+ */
+class DESBase
+{
+ protected static final int BLOCK_SIZE = 8;
+
+ /**
+ * standard constructor.
+ */
+ public DESBase()
+ {
+ }
+
+ /**
+ * what follows is mainly taken from "Applied Cryptography", by
+ * Bruce Schneier, however it also bears great resemblance to Richard
+ * Outerbridge's D3DES...
+ */
+
+// private static final short[] Df_Key =
+// {
+// 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+// 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+// 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
+// };
+
+ private static final short[] bytebit =
+ {
+ 0200, 0100, 040, 020, 010, 04, 02, 01
+ };
+
+ private static final int[] bigbyte =
+ {
+ 0x800000, 0x400000, 0x200000, 0x100000,
+ 0x80000, 0x40000, 0x20000, 0x10000,
+ 0x8000, 0x4000, 0x2000, 0x1000,
+ 0x800, 0x400, 0x200, 0x100,
+ 0x80, 0x40, 0x20, 0x10,
+ 0x8, 0x4, 0x2, 0x1
+ };
+
+ /*
+ * Use the key schedule specified in the Standard (ANSI X3.92-1981).
+ */
+
+ private static final byte[] pc1 =
+ {
+ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
+ 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
+ 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
+ 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
+ };
+
+ private static final byte[] totrot =
+ {
+ 1, 2, 4, 6, 8, 10, 12, 14,
+ 15, 17, 19, 21, 23, 25, 27, 28
+ };
+
+ private static final byte[] pc2 =
+ {
+ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
+ 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
+ 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
+ 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
+ };
+
+ private static final int[] SP1 = {
+ 0x01010400, 0x00000000, 0x00010000, 0x01010404,
+ 0x01010004, 0x00010404, 0x00000004, 0x00010000,
+ 0x00000400, 0x01010400, 0x01010404, 0x00000400,
+ 0x01000404, 0x01010004, 0x01000000, 0x00000004,
+ 0x00000404, 0x01000400, 0x01000400, 0x00010400,
+ 0x00010400, 0x01010000, 0x01010000, 0x01000404,
+ 0x00010004, 0x01000004, 0x01000004, 0x00010004,
+ 0x00000000, 0x00000404, 0x00010404, 0x01000000,
+ 0x00010000, 0x01010404, 0x00000004, 0x01010000,
+ 0x01010400, 0x01000000, 0x01000000, 0x00000400,
+ 0x01010004, 0x00010000, 0x00010400, 0x01000004,
+ 0x00000400, 0x00000004, 0x01000404, 0x00010404,
+ 0x01010404, 0x00010004, 0x01010000, 0x01000404,
+ 0x01000004, 0x00000404, 0x00010404, 0x01010400,
+ 0x00000404, 0x01000400, 0x01000400, 0x00000000,
+ 0x00010004, 0x00010400, 0x00000000, 0x01010004
+ };
+
+ private static final int[] SP2 = {
+ 0x80108020, 0x80008000, 0x00008000, 0x00108020,
+ 0x00100000, 0x00000020, 0x80100020, 0x80008020,
+ 0x80000020, 0x80108020, 0x80108000, 0x80000000,
+ 0x80008000, 0x00100000, 0x00000020, 0x80100020,
+ 0x00108000, 0x00100020, 0x80008020, 0x00000000,
+ 0x80000000, 0x00008000, 0x00108020, 0x80100000,
+ 0x00100020, 0x80000020, 0x00000000, 0x00108000,
+ 0x00008020, 0x80108000, 0x80100000, 0x00008020,
+ 0x00000000, 0x00108020, 0x80100020, 0x00100000,
+ 0x80008020, 0x80100000, 0x80108000, 0x00008000,
+ 0x80100000, 0x80008000, 0x00000020, 0x80108020,
+ 0x00108020, 0x00000020, 0x00008000, 0x80000000,
+ 0x00008020, 0x80108000, 0x00100000, 0x80000020,
+ 0x00100020, 0x80008020, 0x80000020, 0x00100020,
+ 0x00108000, 0x00000000, 0x80008000, 0x00008020,
+ 0x80000000, 0x80100020, 0x80108020, 0x00108000
+ };
+
+ private static final int[] SP3 = {
+ 0x00000208, 0x08020200, 0x00000000, 0x08020008,
+ 0x08000200, 0x00000000, 0x00020208, 0x08000200,
+ 0x00020008, 0x08000008, 0x08000008, 0x00020000,
+ 0x08020208, 0x00020008, 0x08020000, 0x00000208,
+ 0x08000000, 0x00000008, 0x08020200, 0x00000200,
+ 0x00020200, 0x08020000, 0x08020008, 0x00020208,
+ 0x08000208, 0x00020200, 0x00020000, 0x08000208,
+ 0x00000008, 0x08020208, 0x00000200, 0x08000000,
+ 0x08020200, 0x08000000, 0x00020008, 0x00000208,
+ 0x00020000, 0x08020200, 0x08000200, 0x00000000,
+ 0x00000200, 0x00020008, 0x08020208, 0x08000200,
+ 0x08000008, 0x00000200, 0x00000000, 0x08020008,
+ 0x08000208, 0x00020000, 0x08000000, 0x08020208,
+ 0x00000008, 0x00020208, 0x00020200, 0x08000008,
+ 0x08020000, 0x08000208, 0x00000208, 0x08020000,
+ 0x00020208, 0x00000008, 0x08020008, 0x00020200
+ };
+
+ private static final int[] SP4 = {
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802080, 0x00800081, 0x00800001, 0x00002001,
+ 0x00000000, 0x00802000, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00800080, 0x00800001,
+ 0x00000001, 0x00002000, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002001, 0x00002080,
+ 0x00800081, 0x00000001, 0x00002080, 0x00800080,
+ 0x00002000, 0x00802080, 0x00802081, 0x00000081,
+ 0x00800080, 0x00800001, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00000000, 0x00802000,
+ 0x00002080, 0x00800080, 0x00800081, 0x00000001,
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802081, 0x00000081, 0x00000001, 0x00002000,
+ 0x00800001, 0x00002001, 0x00802080, 0x00800081,
+ 0x00002001, 0x00002080, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002000, 0x00802080
+ };
+
+ private static final int[] SP5 = {
+ 0x00000100, 0x02080100, 0x02080000, 0x42000100,
+ 0x00080000, 0x00000100, 0x40000000, 0x02080000,
+ 0x40080100, 0x00080000, 0x02000100, 0x40080100,
+ 0x42000100, 0x42080000, 0x00080100, 0x40000000,
+ 0x02000000, 0x40080000, 0x40080000, 0x00000000,
+ 0x40000100, 0x42080100, 0x42080100, 0x02000100,
+ 0x42080000, 0x40000100, 0x00000000, 0x42000000,
+ 0x02080100, 0x02000000, 0x42000000, 0x00080100,
+ 0x00080000, 0x42000100, 0x00000100, 0x02000000,
+ 0x40000000, 0x02080000, 0x42000100, 0x40080100,
+ 0x02000100, 0x40000000, 0x42080000, 0x02080100,
+ 0x40080100, 0x00000100, 0x02000000, 0x42080000,
+ 0x42080100, 0x00080100, 0x42000000, 0x42080100,
+ 0x02080000, 0x00000000, 0x40080000, 0x42000000,
+ 0x00080100, 0x02000100, 0x40000100, 0x00080000,
+ 0x00000000, 0x40080000, 0x02080100, 0x40000100
+ };
+
+ private static final int[] SP6 = {
+ 0x20000010, 0x20400000, 0x00004000, 0x20404010,
+ 0x20400000, 0x00000010, 0x20404010, 0x00400000,
+ 0x20004000, 0x00404010, 0x00400000, 0x20000010,
+ 0x00400010, 0x20004000, 0x20000000, 0x00004010,
+ 0x00000000, 0x00400010, 0x20004010, 0x00004000,
+ 0x00404000, 0x20004010, 0x00000010, 0x20400010,
+ 0x20400010, 0x00000000, 0x00404010, 0x20404000,
+ 0x00004010, 0x00404000, 0x20404000, 0x20000000,
+ 0x20004000, 0x00000010, 0x20400010, 0x00404000,
+ 0x20404010, 0x00400000, 0x00004010, 0x20000010,
+ 0x00400000, 0x20004000, 0x20000000, 0x00004010,
+ 0x20000010, 0x20404010, 0x00404000, 0x20400000,
+ 0x00404010, 0x20404000, 0x00000000, 0x20400010,
+ 0x00000010, 0x00004000, 0x20400000, 0x00404010,
+ 0x00004000, 0x00400010, 0x20004010, 0x00000000,
+ 0x20404000, 0x20000000, 0x00400010, 0x20004010
+ };
+
+ private static final int[] SP7 = {
+ 0x00200000, 0x04200002, 0x04000802, 0x00000000,
+ 0x00000800, 0x04000802, 0x00200802, 0x04200800,
+ 0x04200802, 0x00200000, 0x00000000, 0x04000002,
+ 0x00000002, 0x04000000, 0x04200002, 0x00000802,
+ 0x04000800, 0x00200802, 0x00200002, 0x04000800,
+ 0x04000002, 0x04200000, 0x04200800, 0x00200002,
+ 0x04200000, 0x00000800, 0x00000802, 0x04200802,
+ 0x00200800, 0x00000002, 0x04000000, 0x00200800,
+ 0x04000000, 0x00200800, 0x00200000, 0x04000802,
+ 0x04000802, 0x04200002, 0x04200002, 0x00000002,
+ 0x00200002, 0x04000000, 0x04000800, 0x00200000,
+ 0x04200800, 0x00000802, 0x00200802, 0x04200800,
+ 0x00000802, 0x04000002, 0x04200802, 0x04200000,
+ 0x00200800, 0x00000000, 0x00000002, 0x04200802,
+ 0x00000000, 0x00200802, 0x04200000, 0x00000800,
+ 0x04000002, 0x04000800, 0x00000800, 0x00200002
+ };
+
+ private static final int[] SP8 = {
+ 0x10001040, 0x00001000, 0x00040000, 0x10041040,
+ 0x10000000, 0x10001040, 0x00000040, 0x10000000,
+ 0x00040040, 0x10040000, 0x10041040, 0x00041000,
+ 0x10041000, 0x00041040, 0x00001000, 0x00000040,
+ 0x10040000, 0x10000040, 0x10001000, 0x00001040,
+ 0x00041000, 0x00040040, 0x10040040, 0x10041000,
+ 0x00001040, 0x00000000, 0x00000000, 0x10040040,
+ 0x10000040, 0x10001000, 0x00041040, 0x00040000,
+ 0x00041040, 0x00040000, 0x10041000, 0x00001000,
+ 0x00000040, 0x10040040, 0x00001000, 0x00041040,
+ 0x10001000, 0x00000040, 0x10000040, 0x10040000,
+ 0x10040040, 0x10000000, 0x00040000, 0x10001040,
+ 0x00000000, 0x10041040, 0x00040040, 0x10000040,
+ 0x10040000, 0x10001000, 0x10001040, 0x00000000,
+ 0x10041040, 0x00041000, 0x00041000, 0x00001040,
+ 0x00001040, 0x00040040, 0x10000000, 0x10041000
+ };
+
+ /**
+ * generate an integer based working key based on our secret key
+ * and what we processing we are planning to do.
+ *
+ * Acknowledgements for this routine go to James Gillogly & Phil Karn.
+ * (whoever, and wherever they are!).
+ */
+ protected int[] generateWorkingKey(
+ boolean encrypting,
+ byte[] key)
+ {
+ int[] newKey = new int[32];
+ boolean[] pc1m = new boolean[56],
+ pcr = new boolean[56];
+
+ for (int j = 0; j < 56; j++)
+ {
+ int l = pc1[j];
+
+ pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0);
+ }
+
+ for (int i = 0; i < 16; i++)
+ {
+ int l, m, n;
+
+ if (encrypting)
+ {
+ m = i << 1;
+ }
+ else
+ {
+ m = (15 - i) << 1;
+ }
+
+ n = m + 1;
+ newKey[m] = newKey[n] = 0;
+
+ for (int j = 0; j < 28; j++)
+ {
+ l = j + totrot[i];
+ if (l < 28)
+ {
+ pcr[j] = pc1m[l];
+ }
+ else
+ {
+ pcr[j] = pc1m[l - 28];
+ }
+ }
+
+ for (int j = 28; j < 56; j++)
+ {
+ l = j + totrot[i];
+ if (l < 56)
+ {
+ pcr[j] = pc1m[l];
+ }
+ else
+ {
+ pcr[j] = pc1m[l - 28];
+ }
+ }
+
+ for (int j = 0; j < 24; j++)
+ {
+ if (pcr[pc2[j]])
+ {
+ newKey[m] |= bigbyte[j];
+ }
+
+ if (pcr[pc2[j + 24]])
+ {
+ newKey[n] |= bigbyte[j];
+ }
+ }
+ }
+
+ //
+ // store the processed key
+ //
+ for (int i = 0; i != 32; i += 2)
+ {
+ int i1, i2;
+
+ i1 = newKey[i];
+ i2 = newKey[i + 1];
+
+ newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10)
+ | ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6);
+
+ newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16)
+ | ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f);
+ }
+
+ return newKey;
+ }
+
+ /**
+ * the DES engine.
+ */
+ protected void desFunc(
+ int[] wKey,
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ int work, right, left;
+
+ left = Pack.bigEndianToInt(in, inOff);
+ right = Pack.bigEndianToInt(in, inOff + 4);
+
+ work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
+ right ^= work;
+ left ^= (work << 4);
+ work = ((left >>> 16) ^ right) & 0x0000ffff;
+ right ^= work;
+ left ^= (work << 16);
+ work = ((right >>> 2) ^ left) & 0x33333333;
+ left ^= work;
+ right ^= (work << 2);
+ work = ((right >>> 8) ^ left) & 0x00ff00ff;
+ left ^= work;
+ right ^= (work << 8);
+ right = (right << 1) | (right >>> 31);
+ work = (left ^ right) & 0xaaaaaaaa;
+ left ^= work;
+ right ^= work;
+ left = (left << 1) | (left >>> 31);
+
+ for (int round = 0; round < 8; round++)
+ {
+ int fval;
+
+ work = (right << 28) | (right >>> 4);
+ work ^= wKey[round * 4 + 0];
+ fval = SP7[ work & 0x3f];
+ fval |= SP5[(work >>> 8) & 0x3f];
+ fval |= SP3[(work >>> 16) & 0x3f];
+ fval |= SP1[(work >>> 24) & 0x3f];
+ work = right ^ wKey[round * 4 + 1];
+ fval |= SP8[ work & 0x3f];
+ fval |= SP6[(work >>> 8) & 0x3f];
+ fval |= SP4[(work >>> 16) & 0x3f];
+ fval |= SP2[(work >>> 24) & 0x3f];
+ left ^= fval;
+ work = (left << 28) | (left >>> 4);
+ work ^= wKey[round * 4 + 2];
+ fval = SP7[ work & 0x3f];
+ fval |= SP5[(work >>> 8) & 0x3f];
+ fval |= SP3[(work >>> 16) & 0x3f];
+ fval |= SP1[(work >>> 24) & 0x3f];
+ work = left ^ wKey[round * 4 + 3];
+ fval |= SP8[ work & 0x3f];
+ fval |= SP6[(work >>> 8) & 0x3f];
+ fval |= SP4[(work >>> 16) & 0x3f];
+ fval |= SP2[(work >>> 24) & 0x3f];
+ right ^= fval;
+ }
+
+ right = (right << 31) | (right >>> 1);
+ work = (left ^ right) & 0xaaaaaaaa;
+ left ^= work;
+ right ^= work;
+ left = (left << 31) | (left >>> 1);
+ work = ((left >>> 8) ^ right) & 0x00ff00ff;
+ right ^= work;
+ left ^= (work << 8);
+ work = ((left >>> 2) ^ right) & 0x33333333;
+ right ^= work;
+ left ^= (work << 2);
+ work = ((right >>> 16) ^ left) & 0x0000ffff;
+ left ^= work;
+ right ^= (work << 16);
+ work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
+ left ^= work;
+ right ^= (work << 4);
+
+ Pack.intToBigEndian(right, out, outOff);
+ Pack.intToBigEndian(left, out, outOff + 4);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java
index 58ea618..51ba9bd 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java
@@ -2,8 +2,10 @@
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.Pack;
@@ -11,10 +13,12 @@
* a class that provides a basic DES engine.
*/
public class DESEngine
+ extends DESBase
implements BlockCipher
{
protected static final int BLOCK_SIZE = 8;
+ private boolean forEncryption;
private int[] workingKey = null;
/**
@@ -22,6 +26,7 @@
*/
public DESEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 56));
}
/**
@@ -38,14 +43,17 @@
{
if (params instanceof KeyParameter)
{
- if (((KeyParameter)params).getKey().length > 8)
+ if (((KeyParameter)params).getKeyLength() > 8)
{
throw new IllegalArgumentException("DES key too long - should be 8 bytes");
}
-
+
+ forEncryption = encrypting;
workingKey = generateWorkingKey(encrypting,
((KeyParameter)params).getKey());
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 56, params, Utils.getPurpose(forEncryption)));
+
return;
}
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 513eccd..09cab6b 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeEngine.java
@@ -1,42 +1,47 @@
package org.bouncycastle.crypto.engines;
+import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.KeyParameter;
/**
* a class that provides a basic DESede (or Triple DES) engine.
*/
public class DESedeEngine
- extends DESEngine
+ extends DESBase
+ implements BlockCipher
{
- protected static final int BLOCK_SIZE = 8;
+ protected static final int BLOCK_SIZE = 8;
- private int[] workingKey1 = null;
- private int[] workingKey2 = null;
- private int[] workingKey3 = null;
+ private int[] workingKey1 = null;
+ private int[] workingKey2 = null;
+ private int[] workingKey3 = null;
- private boolean forEncryption;
+ private boolean forEncryption;
/**
* standard constructor.
*/
public DESedeEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity()));
}
/**
* initialise a DESede cipher.
*
* @param encrypting whether or not we are for encryption.
- * @param params the parameters required to set up the cipher.
- * @exception IllegalArgumentException if the params argument is
- * inappropriate.
+ * @param params the parameters required to set up the cipher.
+ * @throws IllegalArgumentException if the params argument is
+ * inappropriate.
*/
public void init(
- boolean encrypting,
- CipherParameters params)
+ boolean encrypting,
+ CipherParameters params)
{
if (!(params instanceof KeyParameter))
{
@@ -70,6 +75,8 @@
{
workingKey3 = workingKey1;
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, Utils.getPurpose(forEncryption)));
}
public String getAlgorithmName()
@@ -124,4 +131,14 @@
public void reset()
{
}
+
+ // Service Definitions
+ private int bitsOfSecurity()
+ {
+ if (workingKey1 != null && workingKey1 == workingKey3)
+ {
+ return 80;
+ }
+ return 112;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
index 9978d35..c4ee7b3 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
@@ -182,8 +182,8 @@
System.arraycopy(this.iv, 0, TEMP2, 0, this.iv.length);
System.arraycopy(TEMP1, 0, TEMP2, this.iv.length, TEMP1.length);
- // Reverse the order of the octets in TEMP2 and call the result TEMP3.
- byte[] TEMP3 = reverse(TEMP2);
+ // Reverse the order of the octets in TEMP2.
+ Arrays.reverseInPlace(TEMP2);
// Encrypt TEMP3 in CBC mode using the KEK and an initialization vector
// of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired
@@ -192,12 +192,12 @@
this.engine.init(true, param2);
- for (int currentBytePos = 0; currentBytePos != TEMP3.length; currentBytePos += blockSize)
+ for (int currentBytePos = 0; currentBytePos != TEMP2.length; currentBytePos += blockSize)
{
- engine.processBlock(TEMP3, currentBytePos, TEMP3, currentBytePos);
+ engine.processBlock(TEMP2, currentBytePos, TEMP2, currentBytePos);
}
- return TEMP3;
+ return TEMP2;
}
/**
@@ -250,15 +250,15 @@
this.engine.init(false, param2);
- byte TEMP3[] = new byte[inLen];
+ byte TEMP2[] = new byte[inLen];
for (int currentBytePos = 0; currentBytePos != inLen; currentBytePos += blockSize)
{
- engine.processBlock(in, inOff + currentBytePos, TEMP3, currentBytePos);
+ engine.processBlock(in, inOff + currentBytePos, TEMP2, currentBytePos);
}
- // Reverse the order of the octets in TEMP3 and call the result TEMP2.
- byte[] TEMP2 = reverse(TEMP3);
+ // Reverse the order of the octets in TEMP2.
+ Arrays.reverseInPlace(TEMP2);
// Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets.
this.iv = new byte[8];
@@ -341,14 +341,4 @@
{
return Arrays.constantTimeAreEqual(calculateCMSKeyChecksum(key), checksum);
}
-
- private static byte[] reverse(byte[] bs)
- {
- byte[] result = new byte[bs.length];
- for (int i = 0; i < bs.length; i++)
- {
- result[i] = bs[bs.length - (i + 1)];
- }
- return result;
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC2Engine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC2Engine.java
index 02cb881..bd63b4d 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC2Engine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC2Engine.java
@@ -1,9 +1,7 @@
package org.bouncycastle.crypto.engines;
-import org.bouncycastle.crypto.BlockCipher;
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.DataLengthException;
-import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.crypto.*;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.RC2Parameters;
@@ -122,17 +120,18 @@
CipherParameters params)
{
this.encrypting = encrypting;
-
+ byte[] key;
if (params instanceof RC2Parameters)
{
RC2Parameters param = (RC2Parameters)params;
workingKey = generateWorkingKey(param.getKey(),
param.getEffectiveKeyBits());
+ key = param.getKey();
}
else if (params instanceof KeyParameter)
{
- byte[] key = ((KeyParameter)params).getKey();
+ key = ((KeyParameter)params).getKey();
workingKey = generateWorkingKey(key, key.length * 8);
}
@@ -141,6 +140,7 @@
throw new IllegalArgumentException("invalid parameter passed to RC2 init - " + params.getClass().getName());
}
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), key.length * 8, params, Utils.getPurpose(encrypting)));
}
public void reset()
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC4Engine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC4Engine.java
index c1ceaa4..cbdaa31 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC4Engine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC4Engine.java
@@ -1,12 +1,15 @@
package org.bouncycastle.crypto.engines;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.StreamCipher;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.KeyParameter;
-public class RC4Engine implements StreamCipher
+public class RC4Engine
+ implements StreamCipher
{
private final static int STATE_LENGTH = 256;
@@ -19,6 +22,12 @@
private int x = 0;
private int y = 0;
private byte[] workingKey = null;
+ private boolean forEncryption;
+
+ public RC4Engine()
+ {
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 20));
+ }
/**
* initialise a RC4 cipher.
@@ -30,8 +39,7 @@
*/
public void init(
boolean forEncryption,
- CipherParameters params
- )
+ CipherParameters params)
{
if (params instanceof KeyParameter)
{
@@ -40,9 +48,12 @@
* symmetrical, so the 'forEncryption' is
* irrelevant.
*/
- workingKey = ((KeyParameter)params).getKey();
+ this.workingKey = ((KeyParameter)params).getKey();
+ this.forEncryption = forEncryption;
setKey(workingKey);
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 20, params, Utils.getPurpose(forEncryption)));
+
return;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
index 46e5cbe..955c4cc 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
@@ -20,14 +20,15 @@
public class RFC3394WrapEngine
implements Wrapper
{
- private BlockCipher engine;
- private boolean wrapCipherMode;
- private KeyParameter param;
- private boolean forWrapping;
+ private static final byte[] DEFAULT_IV = { (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6,
+ (byte)0xa6, (byte)0xa6 };
- private byte[] iv = {
- (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6,
- (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6 };
+ private final BlockCipher engine;
+ private final boolean wrapCipherMode;
+ private final byte[] iv = new byte[8];
+
+ private KeyParameter param = null;
+ private boolean forWrapping = true;
/**
* Create a RFC 3394 WrapEngine specifying the encrypt for wrapping, decrypt for unwrapping.
@@ -48,7 +49,7 @@
public RFC3394WrapEngine(BlockCipher engine, boolean useReverseDirection)
{
this.engine = engine;
- this.wrapCipherMode = (useReverseDirection) ? false : true;
+ this.wrapCipherMode = !useReverseDirection;
}
public void init(
@@ -65,15 +66,24 @@
if (param instanceof KeyParameter)
{
this.param = (KeyParameter)param;
+ System.arraycopy(DEFAULT_IV, 0, iv, 0, 8);
}
else if (param instanceof ParametersWithIV)
{
- this.iv = ((ParametersWithIV)param).getIV();
- this.param = (KeyParameter)((ParametersWithIV) param).getParameters();
- if (this.iv.length != 8)
+ ParametersWithIV withIV = (ParametersWithIV)param;
+
+ byte[] iv = withIV.getIV();
+ if (iv.length != 8)
{
throw new IllegalArgumentException("IV not equal to 8");
}
+
+ this.param = (KeyParameter)withIV.getParameters();
+ System.arraycopy(iv, 0, this.iv, 0, 8);
+ }
+ else
+ {
+ // TODO Throw an exception for bad parameters?
}
}
@@ -91,6 +101,10 @@
{
throw new IllegalStateException("not set for wrapping");
}
+ if (inLen < 8)
+ {
+ throw new DataLengthException("wrap data must be at least 8 bytes");
+ }
int n = inLen / 8;
@@ -99,34 +113,41 @@
throw new DataLengthException("wrap data must be a multiple of 8 bytes");
}
- byte[] block = new byte[inLen + iv.length];
- byte[] buf = new byte[8 + iv.length];
+ engine.init(wrapCipherMode, param);
+ byte[] block = new byte[inLen + iv.length];
System.arraycopy(iv, 0, block, 0, iv.length);
System.arraycopy(in, inOff, block, iv.length, inLen);
- engine.init(wrapCipherMode, param);
-
- for (int j = 0; j != 6; j++)
+ if (n == 1)
{
- for (int i = 1; i <= n; i++)
+ engine.processBlock(block, 0, block, 0);
+ }
+ else
+ {
+ byte[] buf = new byte[8 + iv.length];
+
+ for (int j = 0; j != 6; j++)
{
- System.arraycopy(block, 0, buf, 0, iv.length);
- System.arraycopy(block, 8 * i, buf, iv.length, 8);
- engine.processBlock(buf, 0, buf, 0);
-
- int t = n * j + i;
- for (int k = 1; t != 0; k++)
+ for (int i = 1; i <= n; i++)
{
- byte v = (byte)t;
+ System.arraycopy(block, 0, buf, 0, iv.length);
+ System.arraycopy(block, 8 * i, buf, iv.length, 8);
+ engine.processBlock(buf, 0, buf, 0);
- buf[iv.length - k] ^= v;
+ int t = n * j + i;
+ for (int k = 1; t != 0; k++)
+ {
+ byte v = (byte)t;
- t >>>= 8;
+ buf[iv.length - k] ^= v;
+
+ t >>>= 8;
+ }
+
+ System.arraycopy(buf, 0, block, 0, 8);
+ System.arraycopy(buf, 8, block, 8 * i, 8);
}
-
- System.arraycopy(buf, 0, block, 0, 8);
- System.arraycopy(buf, 8, block, 8 * i, 8);
}
}
@@ -143,6 +164,10 @@
{
throw new IllegalStateException("not set for unwrapping");
}
+ if (inLen < 16)
+ {
+ throw new InvalidCipherTextException("unwrap data too short");
+ }
int n = inLen / 8;
@@ -151,43 +176,89 @@
throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes");
}
- byte[] block = new byte[inLen - iv.length];
- byte[] a = new byte[iv.length];
- byte[] buf = new byte[8 + iv.length];
-
- System.arraycopy(in, inOff, a, 0, iv.length);
- System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length);
-
engine.init(!wrapCipherMode, param);
+ byte[] block = new byte[inLen - iv.length];
+ byte[] a = new byte[iv.length];
+ byte[] buf = new byte[8 + iv.length];
+
n = n - 1;
- for (int j = 5; j >= 0; j--)
+ if (n == 1)
{
- for (int i = n; i >= 1; i--)
+ engine.processBlock(in, inOff, buf, 0);
+ System.arraycopy(buf, 0, a, 0, iv.length);
+ System.arraycopy(buf, iv.length, block, 0, 8);
+ }
+ else
+ {
+ System.arraycopy(in, inOff, a, 0, iv.length);
+ System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length);
+
+ for (int j = 5; j >= 0; j--)
{
- System.arraycopy(a, 0, buf, 0, iv.length);
- System.arraycopy(block, 8 * (i - 1), buf, iv.length, 8);
-
- int t = n * j + i;
- for (int k = 1; t != 0; k++)
+ for (int i = n; i >= 1; i--)
{
- byte v = (byte)t;
-
- buf[iv.length - k] ^= v;
-
- t >>>= 8;
+ System.arraycopy(a, 0, buf, 0, iv.length);
+ System.arraycopy(block, 8 * (i - 1), buf, iv.length, 8);
+
+ int t = n * j + i;
+ for (int k = 1; t != 0; k++)
+ {
+ byte v = (byte)t;
+
+ buf[iv.length - k] ^= v;
+
+ t >>>= 8;
+ }
+
+ engine.processBlock(buf, 0, buf, 0);
+ System.arraycopy(buf, 0, a, 0, 8);
+ System.arraycopy(buf, 8, block, 8 * (i - 1), 8);
}
-
- engine.processBlock(buf, 0, buf, 0);
- System.arraycopy(buf, 0, a, 0, 8);
- System.arraycopy(buf, 8, block, 8 * (i - 1), 8);
}
}
- if (!Arrays.constantTimeAreEqual(a, iv))
+ if (n != 1)
{
- throw new InvalidCipherTextException("checksum failed");
+ if (!Arrays.constantTimeAreEqual(a, iv))
+ {
+ throw new InvalidCipherTextException("checksum failed");
+ }
+ }
+ else
+ {
+ // TODO: old (incorrect) backwards compatible unwrap - will be removed.
+ if (!Arrays.constantTimeAreEqual(a, iv))
+ {
+ System.arraycopy(in, inOff, a, 0, iv.length);
+ System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length);
+
+ for (int j = 5; j >= 0; j--)
+ {
+ System.arraycopy(a, 0, buf, 0, iv.length);
+ System.arraycopy(block, 0, buf, iv.length, 8);
+
+ int t = n * j + 1;
+ for (int k = 1; t != 0; k++)
+ {
+ byte v = (byte)t;
+
+ buf[iv.length - k] ^= v;
+
+ t >>>= 8;
+ }
+
+ engine.processBlock(buf, 0, buf, 0);
+ System.arraycopy(buf, 0, a, 0, 8);
+ System.arraycopy(buf, 8, block, 0, 8);
+ }
+
+ if (!Arrays.constantTimeAreEqual(a, iv))
+ {
+ throw new InvalidCipherTextException("checksum failed");
+ }
+ }
}
return block;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java
index cc42899..3b9edb9 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java
@@ -110,39 +110,31 @@
}
BigInteger input = core.convertInput(in, inOff, inLen);
+ BigInteger result = processInput(input);
+ return core.convertOutput(result);
+ }
- BigInteger result;
+ private BigInteger processInput(BigInteger input)
+ {
if (key instanceof RSAPrivateCrtKeyParameters)
{
- RSAPrivateCrtKeyParameters k = (RSAPrivateCrtKeyParameters)key;
+ RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)key;
- BigInteger e = k.getPublicExponent();
+ BigInteger e = crtKey.getPublicExponent();
if (e != null) // can't do blinding without a public exponent
{
- BigInteger m = k.getModulus();
+ BigInteger m = crtKey.getModulus();
+
BigInteger r = BigIntegers.createRandomInRange(ONE, m.subtract(ONE), random);
+ BigInteger blind = r.modPow(e, m);
+ BigInteger unblind = BigIntegers.modOddInverse(m, r);
- BigInteger blindedInput = r.modPow(e, m).multiply(input).mod(m);
+ BigInteger blindedInput = blind.multiply(input).mod(m);
BigInteger blindedResult = core.processBlock(blindedInput);
-
- BigInteger rInv = BigIntegers.modOddInverse(m, r);
- result = blindedResult.multiply(rInv).mod(m);
- // defence against Arjen Lenstra’s CRT attack
- if (!input.equals(result.modPow(e, m)))
- {
- throw new IllegalStateException("RSA engine faulty decryption/signing detected");
- }
- }
- else
- {
- result = core.processBlock(input);
+ return unblind.multiply(blindedResult).mod(m);
}
}
- else
- {
- result = core.processBlock(input);
- }
- return core.convertOutput(result);
+ return core.processBlock(input);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java
index ca482d9..0525948 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java
@@ -3,7 +3,11 @@
import java.math.BigInteger;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.constraints.ConstraintUtils;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
@@ -15,21 +19,21 @@
class RSACoreEngine
{
private RSAKeyParameters key;
- private boolean forEncryption;
+ private boolean forEncryption;
/**
* initialise the RSA engine.
*
* @param forEncryption true if we are encrypting, false otherwise.
- * @param param the necessary RSA key parameters.
+ * @param param the necessary RSA key parameters.
*/
public void init(
- boolean forEncryption,
+ boolean forEncryption,
CipherParameters param)
{
if (param instanceof ParametersWithRandom)
{
- ParametersWithRandom rParam = (ParametersWithRandom)param;
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
key = (RSAKeyParameters)rParam.getParameters();
}
@@ -39,6 +43,8 @@
}
this.forEncryption = forEncryption;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("RSA", ConstraintUtils.bitsOfSecurityFor(key.getModulus()), key, getPurpose(key.isPrivate(), forEncryption)));
}
/**
@@ -50,7 +56,7 @@
*/
public int getInputBlockSize()
{
- int bitSize = key.getModulus().bitLength();
+ int bitSize = key.getModulus().bitLength();
if (forEncryption)
{
@@ -71,7 +77,7 @@
*/
public int getOutputBlockSize()
{
- int bitSize = key.getModulus().bitLength();
+ int bitSize = key.getModulus().bitLength();
if (forEncryption)
{
@@ -84,9 +90,9 @@
}
public BigInteger convertInput(
- byte[] in,
- int inOff,
- int inLen)
+ byte[] in,
+ int inOff,
+ int inLen)
{
if (inLen > (getInputBlockSize() + 1))
{
@@ -97,7 +103,7 @@
throw new DataLengthException("input too large for RSA cipher.");
}
- byte[] block;
+ byte[] block;
if (inOff != 0 || inLen != in.length)
{
@@ -122,13 +128,13 @@
public byte[] convertOutput(
BigInteger result)
{
- byte[] output = result.toByteArray();
+ byte[] output = result.toByteArray();
if (forEncryption)
{
if (output[0] == 0 && output.length > getOutputBlockSize()) // have ended up with an extra zero byte, copy down.
{
- byte[] tmp = new byte[output.length - 1];
+ byte[] tmp = new byte[output.length - 1];
System.arraycopy(output, 1, tmp, 0, tmp.length);
@@ -137,7 +143,7 @@
if (output.length < getOutputBlockSize()) // have ended up with less bytes than normal, lengthen
{
- byte[] tmp = new byte[getOutputBlockSize()];
+ byte[] tmp = new byte[getOutputBlockSize()];
System.arraycopy(output, 0, tmp, tmp.length - output.length, output.length);
@@ -148,7 +154,7 @@
}
else
{
- byte[] rv;
+ byte[] rv;
if (output[0] == 0) // have ended up with an extra zero byte, copy down.
{
rv = new byte[output.length - 1];
@@ -179,35 +185,64 @@
//
RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)key;
- BigInteger p = crtKey.getP();
- BigInteger q = crtKey.getQ();
- BigInteger dP = crtKey.getDP();
- BigInteger dQ = crtKey.getDQ();
- BigInteger qInv = crtKey.getQInv();
+ BigInteger e = crtKey.getPublicExponent();
+ if (e != null) // can't apply fault-attack countermeasure without public exponent
+ {
+ BigInteger p = crtKey.getP();
+ BigInteger q = crtKey.getQ();
+ BigInteger dP = crtKey.getDP();
+ BigInteger dQ = crtKey.getDQ();
+ BigInteger qInv = crtKey.getQInv();
- BigInteger mP, mQ, h, m;
+ BigInteger mP, mQ, h, m;
- // mP = ((input mod p) ^ dP)) mod p
- mP = (input.remainder(p)).modPow(dP, p);
+ // mP = ((input mod p) ^ dP)) mod p
+ mP = (input.remainder(p)).modPow(dP, p);
- // mQ = ((input mod q) ^ dQ)) mod q
- mQ = (input.remainder(q)).modPow(dQ, q);
+ // mQ = ((input mod q) ^ dQ)) mod q
+ mQ = (input.remainder(q)).modPow(dQ, q);
- // h = qInv * (mP - mQ) mod p
- h = mP.subtract(mQ);
- h = h.multiply(qInv);
- h = h.mod(p); // mod (in Java) returns the positive residual
+ // h = qInv * (mP - mQ) mod p
+ h = mP.subtract(mQ);
+ h = h.multiply(qInv);
+ h = h.mod(p); // mod (in Java) returns the positive residual
- // m = h * q + mQ
- m = h.multiply(q);
- m = m.add(mQ);
+ // m = h * q + mQ
+ m = h.multiply(q).add(mQ);
- return m;
+ // defence against Arjen Lenstra’s CRT attack
+ BigInteger check = m.modPow(e, crtKey.getModulus());
+ if (!check.equals(input))
+ {
+ throw new IllegalStateException("RSA engine faulty decryption/signing detected");
+ }
+
+ return m;
+ }
}
- else
+
+ return input.modPow(key.getExponent(), key.getModulus());
+ }
+
+ private CryptoServicePurpose getPurpose(boolean isPrivate, boolean forEncryption)
+ {
+ boolean isSigning = isPrivate && forEncryption;
+ boolean isEncryption = !isPrivate && forEncryption;
+ boolean isVerifying = !isPrivate && !forEncryption;
+
+ if (isSigning)
{
- return input.modPow(
- key.getExponent(), key.getModulus());
+ return CryptoServicePurpose.SIGNING;
}
+ if (isEncryption)
+ {
+ return CryptoServicePurpose.ENCRYPTION;
+ }
+ if (isVerifying)
+ {
+ return CryptoServicePurpose.VERIFYING;
+ }
+
+ return CryptoServicePurpose.DECRYPTION;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/TwofishEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/TwofishEngine.java
index 31ac087..97b4321 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/TwofishEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/TwofishEngine.java
@@ -2,9 +2,13 @@
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.util.Integers;
+import org.bouncycastle.util.Pack;
/**
* A class that provides Twofish encryption operations.
@@ -224,6 +228,8 @@
public TwofishEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 256));
+
// calculate the MDS matrix
int[] m1 = new int[2];
int[] mX = new int[2];
@@ -272,7 +278,21 @@
{
this.encrypting = encrypting;
this.workingKey = ((KeyParameter)params).getKey();
- this.k64Cnt = (this.workingKey.length / 8); // pre-padded ?
+
+ int keyBits = this.workingKey.length * 8;
+ switch (keyBits)
+ {
+ case 128:
+ case 192:
+ case 256:
+ break;
+ default:
+ throw new IllegalArgumentException("Key length not 128/192/256 bits.");
+ }
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), keyBits, params, Utils.getPurpose(encrypting)));
+
+ this.k64Cnt = this.workingKey.length / 8;
setKey(this.workingKey);
return;
@@ -344,28 +364,16 @@
int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4
gSubKeys = new int[TOTAL_SUBKEYS];
- if (k64Cnt < 1)
- {
- throw new IllegalArgumentException("Key size less than 64 bits");
- }
-
- if (k64Cnt > 4)
- {
- throw new IllegalArgumentException("Key size larger than 256 bits");
- }
-
/*
- * k64Cnt is the number of 8 byte blocks (64 chunks)
- * that are in the input key. The input key is a
- * maximum of 32 bytes (256 bits), so the range
- * for k64Cnt is 1..4
+ * k64Cnt is the number of 8 byte blocks (64 chunks) that are in the input key.
+ * The input key is 16, 24 or 32 bytes, so the range for k64Cnt is 2..4
*/
for (int i=0; i<k64Cnt ; i++)
{
int p = i* 8;
- k32e[i] = BytesTo32Bits(key, p);
- k32o[i] = BytesTo32Bits(key, p+4);
+ k32e[i] = Pack.littleEndianToInt(key, p);
+ k32o[i] = Pack.littleEndianToInt(key, p + 4);
sBoxKeys[k64Cnt-1-i] = RS_MDS_Encode(k32e[i], k32o[i]);
}
@@ -376,7 +384,7 @@
q = i*SK_STEP;
A = F32(q, k32e);
B = F32(q+SK_BUMP, k32o);
- B = B << 8 | B >>> 24;
+ B = Integers.rotateLeft(B, 8);
A += B;
gSubKeys[i*2] = A;
A += B;
@@ -448,10 +456,10 @@
byte[] dst,
int dstIndex)
{
- int x0 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[INPUT_WHITEN];
- int x1 = BytesTo32Bits(src, srcIndex + 4) ^ gSubKeys[INPUT_WHITEN + 1];
- int x2 = BytesTo32Bits(src, srcIndex + 8) ^ gSubKeys[INPUT_WHITEN + 2];
- int x3 = BytesTo32Bits(src, srcIndex + 12) ^ gSubKeys[INPUT_WHITEN + 3];
+ int x0 = Pack.littleEndianToInt(src, srcIndex) ^ gSubKeys[INPUT_WHITEN];
+ int x1 = Pack.littleEndianToInt(src, srcIndex + 4) ^ gSubKeys[INPUT_WHITEN + 1];
+ int x2 = Pack.littleEndianToInt(src, srcIndex + 8) ^ gSubKeys[INPUT_WHITEN + 2];
+ int x3 = Pack.littleEndianToInt(src, srcIndex + 12) ^ gSubKeys[INPUT_WHITEN + 3];
int k = ROUND_SUBKEYS;
int t0, t1;
@@ -460,20 +468,20 @@
t0 = Fe32_0(x0);
t1 = Fe32_3(x1);
x2 ^= t0 + t1 + gSubKeys[k++];
- x2 = x2 >>>1 | x2 << 31;
- x3 = (x3 << 1 | x3 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
+ x2 = Integers.rotateRight(x2, 1);
+ x3 = Integers.rotateLeft(x3, 1) ^ (t0 + 2*t1 + gSubKeys[k++]);
t0 = Fe32_0(x2);
t1 = Fe32_3(x3);
x0 ^= t0 + t1 + gSubKeys[k++];
- x0 = x0 >>>1 | x0 << 31;
- x1 = (x1 << 1 | x1 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
+ x0 = Integers.rotateRight(x0, 1);
+ x1 = Integers.rotateLeft(x1, 1) ^ (t0 + 2*t1 + gSubKeys[k++]);
}
- Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex);
- Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4);
- Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8);
- Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12);
+ Pack.intToLittleEndian(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex);
+ Pack.intToLittleEndian(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4);
+ Pack.intToLittleEndian(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8);
+ Pack.intToLittleEndian(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12);
}
/**
@@ -487,10 +495,10 @@
byte[] dst,
int dstIndex)
{
- int x2 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN];
- int x3 = BytesTo32Bits(src, srcIndex+4) ^ gSubKeys[OUTPUT_WHITEN + 1];
- int x0 = BytesTo32Bits(src, srcIndex+8) ^ gSubKeys[OUTPUT_WHITEN + 2];
- int x1 = BytesTo32Bits(src, srcIndex+12) ^ gSubKeys[OUTPUT_WHITEN + 3];
+ int x2 = Pack.littleEndianToInt(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN];
+ int x3 = Pack.littleEndianToInt(src, srcIndex + 4) ^ gSubKeys[OUTPUT_WHITEN + 1];
+ int x0 = Pack.littleEndianToInt(src, srcIndex + 8) ^ gSubKeys[OUTPUT_WHITEN + 2];
+ int x1 = Pack.littleEndianToInt(src, srcIndex + 12) ^ gSubKeys[OUTPUT_WHITEN + 3];
int k = ROUND_SUBKEYS + 2 * ROUNDS -1 ;
int t0, t1;
@@ -499,20 +507,20 @@
t0 = Fe32_0(x2);
t1 = Fe32_3(x3);
x1 ^= t0 + 2*t1 + gSubKeys[k--];
- x0 = (x0 << 1 | x0 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
- x1 = x1 >>>1 | x1 << 31;
+ x0 = Integers.rotateLeft(x0, 1) ^ (t0 + t1 + gSubKeys[k--]);
+ x1 = Integers.rotateRight(x1, 1);
t0 = Fe32_0(x0);
t1 = Fe32_3(x1);
x3 ^= t0 + 2*t1 + gSubKeys[k--];
- x2 = (x2 << 1 | x2 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
- x3 = x3 >>>1 | x3 << 31;
+ x2 = Integers.rotateLeft(x2, 1) ^ (t0 + t1 + gSubKeys[k--]);
+ x3 = Integers.rotateRight(x3, 1);
}
- Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex);
- Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4);
- Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8);
- Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12);
+ Pack.intToLittleEndian(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex);
+ Pack.intToLittleEndian(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4);
+ Pack.intToLittleEndian(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8);
+ Pack.intToLittleEndian(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12);
}
/*
@@ -661,20 +669,4 @@
gSBox[ 0x200 + 2*((x >>> 8) & 0xff) ] ^
gSBox[ 0x201 + 2*((x >>> 16) & 0xff) ];
}
-
- private int BytesTo32Bits(byte[] b, int p)
- {
- return ((b[p] & 0xff)) |
- ((b[p+1] & 0xff) << 8) |
- ((b[p+2] & 0xff) << 16) |
- ((b[p+3] & 0xff) << 24);
- }
-
- private void Bits32ToBytes(int in, byte[] b, int offset)
- {
- b[offset] = (byte)in;
- b[offset + 1] = (byte)(in >> 8);
- b[offset + 2] = (byte)(in >> 16);
- b[offset + 3] = (byte)(in >> 24);
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/Utils.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/Utils.java
new file mode 100644
index 0000000..4d50f5d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/Utils.java
@@ -0,0 +1,11 @@
+package org.bouncycastle.crypto.engines;
+
+import org.bouncycastle.crypto.CryptoServicePurpose;
+
+class Utils
+{
+ static CryptoServicePurpose getPurpose(boolean forEncryption)
+ {
+ return forEncryption ? CryptoServicePurpose.ENCRYPTION : CryptoServicePurpose.DECRYPTION;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/Zuc128CoreEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/Zuc128CoreEngine.java
new file mode 100644
index 0000000..7e2eeca
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/Zuc128CoreEngine.java
@@ -0,0 +1,575 @@
+package org.bouncycastle.crypto.engines;
+
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
+import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.OutputLengthException;
+import org.bouncycastle.crypto.StreamCipher;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.params.ParametersWithIV;
+import org.bouncycastle.util.Memoable;
+
+/**
+ * Zuc128Engine implementation.
+ * Based on https://www.gsma.com/aboutus/wp-content/uploads/2014/12/eea3eia3zucv16.pdf
+ */
+public class Zuc128CoreEngine
+ implements StreamCipher, Memoable
+{
+ /* the s-boxes */
+ private static final byte[] S0 = new byte[]{
+ (byte)0x3e, (byte)0x72, (byte)0x5b, (byte)0x47, (byte)0xca, (byte)0xe0, (byte)0x00, (byte)0x33, (byte)0x04, (byte)0xd1, (byte)0x54, (byte)0x98, (byte)0x09, (byte)0xb9, (byte)0x6d, (byte)0xcb,
+ (byte)0x7b, (byte)0x1b, (byte)0xf9, (byte)0x32, (byte)0xaf, (byte)0x9d, (byte)0x6a, (byte)0xa5, (byte)0xb8, (byte)0x2d, (byte)0xfc, (byte)0x1d, (byte)0x08, (byte)0x53, (byte)0x03, (byte)0x90,
+ (byte)0x4d, (byte)0x4e, (byte)0x84, (byte)0x99, (byte)0xe4, (byte)0xce, (byte)0xd9, (byte)0x91, (byte)0xdd, (byte)0xb6, (byte)0x85, (byte)0x48, (byte)0x8b, (byte)0x29, (byte)0x6e, (byte)0xac,
+ (byte)0xcd, (byte)0xc1, (byte)0xf8, (byte)0x1e, (byte)0x73, (byte)0x43, (byte)0x69, (byte)0xc6, (byte)0xb5, (byte)0xbd, (byte)0xfd, (byte)0x39, (byte)0x63, (byte)0x20, (byte)0xd4, (byte)0x38,
+ (byte)0x76, (byte)0x7d, (byte)0xb2, (byte)0xa7, (byte)0xcf, (byte)0xed, (byte)0x57, (byte)0xc5, (byte)0xf3, (byte)0x2c, (byte)0xbb, (byte)0x14, (byte)0x21, (byte)0x06, (byte)0x55, (byte)0x9b,
+ (byte)0xe3, (byte)0xef, (byte)0x5e, (byte)0x31, (byte)0x4f, (byte)0x7f, (byte)0x5a, (byte)0xa4, (byte)0x0d, (byte)0x82, (byte)0x51, (byte)0x49, (byte)0x5f, (byte)0xba, (byte)0x58, (byte)0x1c,
+ (byte)0x4a, (byte)0x16, (byte)0xd5, (byte)0x17, (byte)0xa8, (byte)0x92, (byte)0x24, (byte)0x1f, (byte)0x8c, (byte)0xff, (byte)0xd8, (byte)0xae, (byte)0x2e, (byte)0x01, (byte)0xd3, (byte)0xad,
+ (byte)0x3b, (byte)0x4b, (byte)0xda, (byte)0x46, (byte)0xeb, (byte)0xc9, (byte)0xde, (byte)0x9a, (byte)0x8f, (byte)0x87, (byte)0xd7, (byte)0x3a, (byte)0x80, (byte)0x6f, (byte)0x2f, (byte)0xc8,
+ (byte)0xb1, (byte)0xb4, (byte)0x37, (byte)0xf7, (byte)0x0a, (byte)0x22, (byte)0x13, (byte)0x28, (byte)0x7c, (byte)0xcc, (byte)0x3c, (byte)0x89, (byte)0xc7, (byte)0xc3, (byte)0x96, (byte)0x56,
+ (byte)0x07, (byte)0xbf, (byte)0x7e, (byte)0xf0, (byte)0x0b, (byte)0x2b, (byte)0x97, (byte)0x52, (byte)0x35, (byte)0x41, (byte)0x79, (byte)0x61, (byte)0xa6, (byte)0x4c, (byte)0x10, (byte)0xfe,
+ (byte)0xbc, (byte)0x26, (byte)0x95, (byte)0x88, (byte)0x8a, (byte)0xb0, (byte)0xa3, (byte)0xfb, (byte)0xc0, (byte)0x18, (byte)0x94, (byte)0xf2, (byte)0xe1, (byte)0xe5, (byte)0xe9, (byte)0x5d,
+ (byte)0xd0, (byte)0xdc, (byte)0x11, (byte)0x66, (byte)0x64, (byte)0x5c, (byte)0xec, (byte)0x59, (byte)0x42, (byte)0x75, (byte)0x12, (byte)0xf5, (byte)0x74, (byte)0x9c, (byte)0xaa, (byte)0x23,
+ (byte)0x0e, (byte)0x86, (byte)0xab, (byte)0xbe, (byte)0x2a, (byte)0x02, (byte)0xe7, (byte)0x67, (byte)0xe6, (byte)0x44, (byte)0xa2, (byte)0x6c, (byte)0xc2, (byte)0x93, (byte)0x9f, (byte)0xf1,
+ (byte)0xf6, (byte)0xfa, (byte)0x36, (byte)0xd2, (byte)0x50, (byte)0x68, (byte)0x9e, (byte)0x62, (byte)0x71, (byte)0x15, (byte)0x3d, (byte)0xd6, (byte)0x40, (byte)0xc4, (byte)0xe2, (byte)0x0f,
+ (byte)0x8e, (byte)0x83, (byte)0x77, (byte)0x6b, (byte)0x25, (byte)0x05, (byte)0x3f, (byte)0x0c, (byte)0x30, (byte)0xea, (byte)0x70, (byte)0xb7, (byte)0xa1, (byte)0xe8, (byte)0xa9, (byte)0x65,
+ (byte)0x8d, (byte)0x27, (byte)0x1a, (byte)0xdb, (byte)0x81, (byte)0xb3, (byte)0xa0, (byte)0xf4, (byte)0x45, (byte)0x7a, (byte)0x19, (byte)0xdf, (byte)0xee, (byte)0x78, (byte)0x34, (byte)0x60
+ };
+
+ private static final byte[] S1 = new byte[]{
+ (byte)0x55, (byte)0xc2, (byte)0x63, (byte)0x71, (byte)0x3b, (byte)0xc8, (byte)0x47, (byte)0x86, (byte)0x9f, (byte)0x3c, (byte)0xda, (byte)0x5b, (byte)0x29, (byte)0xaa, (byte)0xfd, (byte)0x77,
+ (byte)0x8c, (byte)0xc5, (byte)0x94, (byte)0x0c, (byte)0xa6, (byte)0x1a, (byte)0x13, (byte)0x00, (byte)0xe3, (byte)0xa8, (byte)0x16, (byte)0x72, (byte)0x40, (byte)0xf9, (byte)0xf8, (byte)0x42,
+ (byte)0x44, (byte)0x26, (byte)0x68, (byte)0x96, (byte)0x81, (byte)0xd9, (byte)0x45, (byte)0x3e, (byte)0x10, (byte)0x76, (byte)0xc6, (byte)0xa7, (byte)0x8b, (byte)0x39, (byte)0x43, (byte)0xe1,
+ (byte)0x3a, (byte)0xb5, (byte)0x56, (byte)0x2a, (byte)0xc0, (byte)0x6d, (byte)0xb3, (byte)0x05, (byte)0x22, (byte)0x66, (byte)0xbf, (byte)0xdc, (byte)0x0b, (byte)0xfa, (byte)0x62, (byte)0x48,
+ (byte)0xdd, (byte)0x20, (byte)0x11, (byte)0x06, (byte)0x36, (byte)0xc9, (byte)0xc1, (byte)0xcf, (byte)0xf6, (byte)0x27, (byte)0x52, (byte)0xbb, (byte)0x69, (byte)0xf5, (byte)0xd4, (byte)0x87,
+ (byte)0x7f, (byte)0x84, (byte)0x4c, (byte)0xd2, (byte)0x9c, (byte)0x57, (byte)0xa4, (byte)0xbc, (byte)0x4f, (byte)0x9a, (byte)0xdf, (byte)0xfe, (byte)0xd6, (byte)0x8d, (byte)0x7a, (byte)0xeb,
+ (byte)0x2b, (byte)0x53, (byte)0xd8, (byte)0x5c, (byte)0xa1, (byte)0x14, (byte)0x17, (byte)0xfb, (byte)0x23, (byte)0xd5, (byte)0x7d, (byte)0x30, (byte)0x67, (byte)0x73, (byte)0x08, (byte)0x09,
+ (byte)0xee, (byte)0xb7, (byte)0x70, (byte)0x3f, (byte)0x61, (byte)0xb2, (byte)0x19, (byte)0x8e, (byte)0x4e, (byte)0xe5, (byte)0x4b, (byte)0x93, (byte)0x8f, (byte)0x5d, (byte)0xdb, (byte)0xa9,
+ (byte)0xad, (byte)0xf1, (byte)0xae, (byte)0x2e, (byte)0xcb, (byte)0x0d, (byte)0xfc, (byte)0xf4, (byte)0x2d, (byte)0x46, (byte)0x6e, (byte)0x1d, (byte)0x97, (byte)0xe8, (byte)0xd1, (byte)0xe9,
+ (byte)0x4d, (byte)0x37, (byte)0xa5, (byte)0x75, (byte)0x5e, (byte)0x83, (byte)0x9e, (byte)0xab, (byte)0x82, (byte)0x9d, (byte)0xb9, (byte)0x1c, (byte)0xe0, (byte)0xcd, (byte)0x49, (byte)0x89,
+ (byte)0x01, (byte)0xb6, (byte)0xbd, (byte)0x58, (byte)0x24, (byte)0xa2, (byte)0x5f, (byte)0x38, (byte)0x78, (byte)0x99, (byte)0x15, (byte)0x90, (byte)0x50, (byte)0xb8, (byte)0x95, (byte)0xe4,
+ (byte)0xd0, (byte)0x91, (byte)0xc7, (byte)0xce, (byte)0xed, (byte)0x0f, (byte)0xb4, (byte)0x6f, (byte)0xa0, (byte)0xcc, (byte)0xf0, (byte)0x02, (byte)0x4a, (byte)0x79, (byte)0xc3, (byte)0xde,
+ (byte)0xa3, (byte)0xef, (byte)0xea, (byte)0x51, (byte)0xe6, (byte)0x6b, (byte)0x18, (byte)0xec, (byte)0x1b, (byte)0x2c, (byte)0x80, (byte)0xf7, (byte)0x74, (byte)0xe7, (byte)0xff, (byte)0x21,
+ (byte)0x5a, (byte)0x6a, (byte)0x54, (byte)0x1e, (byte)0x41, (byte)0x31, (byte)0x92, (byte)0x35, (byte)0xc4, (byte)0x33, (byte)0x07, (byte)0x0a, (byte)0xba, (byte)0x7e, (byte)0x0e, (byte)0x34,
+ (byte)0x88, (byte)0xb1, (byte)0x98, (byte)0x7c, (byte)0xf3, (byte)0x3d, (byte)0x60, (byte)0x6c, (byte)0x7b, (byte)0xca, (byte)0xd3, (byte)0x1f, (byte)0x32, (byte)0x65, (byte)0x04, (byte)0x28,
+ (byte)0x64, (byte)0xbe, (byte)0x85, (byte)0x9b, (byte)0x2f, (byte)0x59, (byte)0x8a, (byte)0xd7, (byte)0xb0, (byte)0x25, (byte)0xac, (byte)0xaf, (byte)0x12, (byte)0x03, (byte)0xe2, (byte)0xf2
+ };
+
+ /* the constants D */
+ private static final short[] EK_d = new short[]{
+ 0x44D7, 0x26BC, 0x626B, 0x135E, 0x5789, 0x35E2, 0x7135, 0x09AF,
+ 0x4D78, 0x2F13, 0x6BC4, 0x1AF1, 0x5E26, 0x3C4D, 0x789A, 0x47AC
+ };
+
+ /**
+ * State.
+ */
+ private final int[] LFSR = new int[16];
+ private final int[] F = new int[2];
+ private final int[] BRC = new int[4];
+
+ /**
+ * index of next byte in keyStream.
+ */
+ private int theIndex;
+
+ /**
+ * Advanced stream.
+ */
+ private final byte[] keyStream = new byte[4]; // Integer.BYTES
+
+ /**
+ * The iterations.
+ */
+ private int theIterations;
+
+ /**
+ * Reset state.
+ */
+ private Zuc128CoreEngine theResetState;
+
+ /**
+ * Constructor.
+ */
+ protected Zuc128CoreEngine()
+ {
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param pSource the source engine
+ */
+ protected Zuc128CoreEngine(final Zuc128CoreEngine pSource)
+ {
+ reset(pSource);
+ }
+
+ /**
+ * initialise a Snow3G cipher.
+ *
+ * @param forEncryption whether or not we are for encryption.
+ * @param params the parameters required to set up the cipher.
+ * @throws IllegalArgumentException if the params argument is inappropriate.
+ */
+ public void init(final boolean forEncryption,
+ final CipherParameters params)
+ {
+ /*
+ * encryption and decryption is completely symmetrical.
+ */
+
+ /* Determine parameters */
+ CipherParameters myParams = params;
+ byte[] newKey = null;
+ byte[] newIV = null;
+ if ((myParams instanceof ParametersWithIV))
+ {
+ final ParametersWithIV ivParams = (ParametersWithIV)myParams;
+ newIV = ivParams.getIV();
+ myParams = ivParams.getParameters();
+ }
+ if (myParams instanceof KeyParameter)
+ {
+ final KeyParameter keyParam = (KeyParameter)myParams;
+ newKey = keyParam.getKey();
+ }
+
+ /* Initialise engine and mark as initialised */
+ theIndex = 0;
+ theIterations = 0;
+ setKeyAndIV(newKey, newIV);
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), newKey.length * 8,
+ params, forEncryption ? CryptoServicePurpose.ENCRYPTION : CryptoServicePurpose.DECRYPTION));
+
+ /* Save reset state */
+ theResetState = (Zuc128CoreEngine)copy();
+ }
+
+ /**
+ * Obtain Max iterations.
+ *
+ * @return the maximum iterations
+ */
+ protected int getMaxIterations()
+ {
+ return 2047;
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc-128";
+ }
+
+ /**
+ * Process bytes.
+ *
+ * @param in the input buffer
+ * @param inOff the starting offset in the input buffer
+ * @param len the length of data in the input buffer
+ * @param out the output buffer
+ * @param outOff the starting offset in the output buffer
+ * @return the number of bytes returned in the output buffer
+ */
+ public int processBytes(final byte[] in,
+ final int inOff,
+ final int len,
+ final byte[] out,
+ final int outOff)
+ {
+ /* Check for errors */
+ if (theResetState == null)
+ {
+ throw new IllegalStateException(getAlgorithmName() + " not initialised");
+ }
+ if ((inOff + len) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ if ((outOff + len) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ /* Loop through the input bytes */
+ for (int i = 0; i < len; i++)
+ {
+ out[i + outOff] = returnByte(in[i + inOff]);
+ }
+ return len;
+ }
+
+ /**
+ * Reset the engine.
+ */
+ public void reset()
+ {
+ if (theResetState != null)
+ {
+ reset(theResetState);
+ }
+ }
+
+ /**
+ * Process single byte.
+ *
+ * @param in the input byte
+ * @return the output byte
+ */
+ public byte returnByte(final byte in)
+ {
+ /* Make the keyStream if required */
+ if (theIndex == 0)
+ {
+ makeKeyStream();
+ }
+
+ /* Map the next byte and adjust index */
+ final byte out = (byte)(keyStream[theIndex] ^ in);
+ theIndex = (theIndex + 1) % 4; // Integer.BYTES
+
+ /* Return the mapped character */
+ return out;
+ }
+
+ /**
+ * Encode a 32-bit value into a buffer (little-endian).
+ *
+ * @param val the value to encode
+ * @param buf the output buffer
+ * @param off the output offset
+ */
+ public static void encode32be(int val, byte[] buf, int off)
+ {
+ buf[off] = (byte)(val >> 24);
+ buf[off + 1] = (byte)(val >> 16);
+ buf[off + 2] = (byte)(val >> 8);
+ buf[off + 3] = (byte)val;
+ }
+
+ /* ����������������������- */
+
+ /**
+ * Modular add c = a + b mod (2^31 � 1).
+ *
+ * @param a value A
+ * @param b value B
+ * @return the result
+ */
+ private int AddM(final int a, final int b)
+ {
+ final int c = a + b;
+ return (c & 0x7FFFFFFF) + (c >>> 31);
+ }
+
+ /**
+ * Multiply by power of two.
+ *
+ * @param x input value
+ * @param k the power of two
+ * @return the result
+ */
+ private static int MulByPow2(final int x, final int k)
+ {
+ return ((((x) << k) | ((x) >>> (31 - k))) & 0x7FFFFFFF);
+ }
+
+ /**
+ * LFSR with initialisation mode.
+ *
+ * @param u
+ */
+ private void LFSRWithInitialisationMode(final int u)
+ {
+ int f = LFSR[0];
+ int v = MulByPow2(LFSR[0], 8);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[4], 20);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[10], 21);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[13], 17);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[15], 15);
+ f = AddM(f, v);
+ f = AddM(f, u);
+
+ /* update the state */
+ LFSR[0] = LFSR[1];
+ LFSR[1] = LFSR[2];
+ LFSR[2] = LFSR[3];
+ LFSR[3] = LFSR[4];
+ LFSR[4] = LFSR[5];
+ LFSR[5] = LFSR[6];
+ LFSR[6] = LFSR[7];
+ LFSR[7] = LFSR[8];
+ LFSR[8] = LFSR[9];
+ LFSR[9] = LFSR[10];
+ LFSR[10] = LFSR[11];
+ LFSR[11] = LFSR[12];
+ LFSR[12] = LFSR[13];
+ LFSR[13] = LFSR[14];
+ LFSR[14] = LFSR[15];
+ LFSR[15] = f;
+ }
+
+ /**
+ * LFSR with work mode.
+ */
+ private void LFSRWithWorkMode()
+ {
+ int f, v;
+ f = LFSR[0];
+ v = MulByPow2(LFSR[0], 8);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[4], 20);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[10], 21);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[13], 17);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[15], 15);
+ f = AddM(f, v);
+
+ /* update the state */
+ LFSR[0] = LFSR[1];
+ LFSR[1] = LFSR[2];
+ LFSR[2] = LFSR[3];
+ LFSR[3] = LFSR[4];
+ LFSR[4] = LFSR[5];
+ LFSR[5] = LFSR[6];
+ LFSR[6] = LFSR[7];
+ LFSR[7] = LFSR[8];
+ LFSR[8] = LFSR[9];
+ LFSR[9] = LFSR[10];
+ LFSR[10] = LFSR[11];
+ LFSR[11] = LFSR[12];
+ LFSR[12] = LFSR[13];
+ LFSR[13] = LFSR[14];
+ LFSR[14] = LFSR[15];
+ LFSR[15] = f;
+ }
+
+ /**
+ * BitReorganization.
+ */
+ private void BitReorganization()
+ {
+ BRC[0] = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
+ BRC[1] = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
+ BRC[2] = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
+ BRC[3] = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >>> 15);
+ }
+
+ /**
+ * Rotate integer.
+ *
+ * @param a the integer
+ * @param k the shift
+ * @return the result
+ */
+ static int ROT(int a, int k)
+ {
+ return (((a) << k) | ((a) >>> (32 - k)));
+ }
+
+ /**
+ * L1.
+ *
+ * @param X the input integer.
+ * @return the result
+ */
+ private static int L1(final int X)
+ {
+ return (X ^ ROT(X, 2) ^ ROT(X, 10) ^ ROT(X, 18) ^ ROT(X, 24));
+ }
+
+ /**
+ * L2.
+ *
+ * @param X the input integer.
+ * @return the result
+ */
+ private static int L2(final int X)
+ {
+ return (X ^ ROT(X, 8) ^ ROT(X, 14) ^ ROT(X, 22) ^ ROT(X, 30));
+ }
+
+ /**
+ * Build a 32-bit integer from constituent parts.
+ *
+ * @param a part A
+ * @param b part B
+ * @param c part C
+ * @param d part D
+ * @return the built integer
+ */
+ private static int MAKEU32(final byte a,
+ final byte b,
+ final byte c,
+ final byte d)
+ {
+ return (((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF)));
+ }
+
+ /**
+ * F.
+ */
+ int F()
+ {
+ int W, W1, W2, u, v;
+ W = (BRC[0] ^ F[0]) + F[1];
+ W1 = F[0] + BRC[1];
+ W2 = F[1] ^ BRC[2];
+ u = L1((W1 << 16) | (W2 >>> 16));
+ v = L2((W2 << 16) | (W1 >>> 16));
+ F[0] = MAKEU32(S0[u >>> 24], S1[(u >>> 16) & 0xFF],
+ S0[(u >>> 8) & 0xFF], S1[u & 0xFF]);
+ F[1] = MAKEU32(S0[v >>> 24], S1[(v >>> 16) & 0xFF],
+ S0[(v >>> 8) & 0xFF], S1[v & 0xFF]);
+ return W;
+ }
+
+ /**
+ * Build a 31-bit integer from constituent parts.
+ *
+ * @param a part A
+ * @param b part B
+ * @param c part C
+ * @return the built integer
+ */
+ private static int MAKEU31(final byte a,
+ final short b,
+ final byte c)
+ {
+ return (((a & 0xFF) << 23) | ((b & 0xFFFF) << 8) | (c & 0xFF));
+ }
+
+ /**
+ * Process key and IV into LFSR.
+ *
+ * @param pLFSR the LFSR
+ * @param k the key
+ * @param iv the iv
+ */
+ protected void setKeyAndIV(final int[] pLFSR,
+ final byte[] k,
+ final byte[] iv)
+ {
+ /* Check lengths */
+ if (k == null || k.length != 16)
+ {
+ throw new IllegalArgumentException("A key of 16 bytes is needed");
+ }
+ if (iv == null || iv.length != 16)
+ {
+ throw new IllegalArgumentException("An IV of 16 bytes is needed");
+ }
+
+ /* expand key */
+ LFSR[0] = MAKEU31(k[0], EK_d[0], iv[0]);
+ LFSR[1] = MAKEU31(k[1], EK_d[1], iv[1]);
+ LFSR[2] = MAKEU31(k[2], EK_d[2], iv[2]);
+ LFSR[3] = MAKEU31(k[3], EK_d[3], iv[3]);
+ LFSR[4] = MAKEU31(k[4], EK_d[4], iv[4]);
+ LFSR[5] = MAKEU31(k[5], EK_d[5], iv[5]);
+ LFSR[6] = MAKEU31(k[6], EK_d[6], iv[6]);
+ LFSR[7] = MAKEU31(k[7], EK_d[7], iv[7]);
+ LFSR[8] = MAKEU31(k[8], EK_d[8], iv[8]);
+ LFSR[9] = MAKEU31(k[9], EK_d[9], iv[9]);
+ LFSR[10] = MAKEU31(k[10], EK_d[10], iv[10]);
+ LFSR[11] = MAKEU31(k[11], EK_d[11], iv[11]);
+ LFSR[12] = MAKEU31(k[12], EK_d[12], iv[12]);
+ LFSR[13] = MAKEU31(k[13], EK_d[13], iv[13]);
+ LFSR[14] = MAKEU31(k[14], EK_d[14], iv[14]);
+ LFSR[15] = MAKEU31(k[15], EK_d[15], iv[15]);
+ }
+
+ /**
+ * Process key and IV.
+ *
+ * @param k the key
+ * @param iv the IV
+ */
+ private void setKeyAndIV(final byte[] k,
+ final byte[] iv)
+ {
+ /* Initialise LFSR */
+ setKeyAndIV(LFSR, k, iv);
+
+ /* set F_R1 and F_R2 to zero */
+ F[0] = 0;
+ F[1] = 0;
+ int nCount = 32;
+ while (nCount > 0)
+ {
+ BitReorganization();
+ final int w = F();
+ LFSRWithInitialisationMode(w >>> 1);
+ nCount--;
+ }
+ BitReorganization();
+ F(); /* discard the output of F */
+ LFSRWithWorkMode();
+ }
+
+ /**
+ * Create the next byte keyStream.
+ */
+ private void makeKeyStream()
+ {
+ encode32be(makeKeyStreamWord(), keyStream, 0);
+ }
+
+ /**
+ * Create the next keyStream word.
+ *
+ * @return the next word
+ */
+ protected int makeKeyStreamWord()
+ {
+ if (theIterations++ >= getMaxIterations())
+ {
+ throw new IllegalStateException("Too much data processed by singleKey/IV");
+ }
+ BitReorganization();
+ final int result = F() ^ BRC[3];
+ LFSRWithWorkMode();
+ return result;
+ }
+
+ /**
+ * Create a copy of the engine.
+ *
+ * @return the copy
+ */
+ public Memoable copy()
+ {
+ return new Zuc128CoreEngine(this);
+ }
+
+ /**
+ * Reset from saved engine state.
+ *
+ * @param pState the state to restore
+ */
+ public void reset(final Memoable pState)
+ {
+ final Zuc128CoreEngine e = (Zuc128CoreEngine)pState;
+ System.arraycopy(e.LFSR, 0, LFSR, 0, LFSR.length);
+ System.arraycopy(e.F, 0, F, 0, F.length);
+ System.arraycopy(e.BRC, 0, BRC, 0, BRC.length);
+ System.arraycopy(e.keyStream, 0, keyStream, 0, keyStream.length);
+ theIndex = e.theIndex;
+ theIterations = e.theIterations;
+ theResetState = e;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/Zuc256CoreEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/Zuc256CoreEngine.java
new file mode 100644
index 0000000..c42a72e
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/Zuc256CoreEngine.java
@@ -0,0 +1,181 @@
+package org.bouncycastle.crypto.engines;
+
+import org.bouncycastle.util.Memoable;
+
+/**
+ * Zuc256 implementation.
+ * Based on https://www.is.cas.cn/ztzl2016/zouchongzhi/201801/W020180126529970733243.pdf
+ */
+public class Zuc256CoreEngine
+ extends Zuc128CoreEngine
+{
+ /* the constants D */
+ private static final byte[] EK_d = new byte[]{
+ 0x22, 0x2f, 0x24, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100010, 0b0101111, 0b0100100, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /* the constants D for 32 bit Mac*/
+ private static final byte[] EK_d32 = new byte[]{
+ 0x22, 0x2f, 0x25, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100010, 0b0101111, 0b0100101, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /* the constants D for 64 bit Mac */
+ private static final byte[] EK_d64 = new byte[]{
+ 0x23, 0x2f, 0x24, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100011, 0b0101111, 0b0100100, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /* the constants D for 128 bit Mac */
+ private static final byte[] EK_d128 = new byte[]{
+ 0x23, 0x2f, 0x25, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100011, 0b0101111, 0b0100101, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /**
+ * The selected D constants.
+ */
+ private byte[] theD;
+
+ /**
+ * Constructor for streamCipher.
+ */
+ protected Zuc256CoreEngine()
+ {
+ theD = EK_d;
+ }
+
+ /**
+ * Constructor for Mac.
+ *
+ * @param pLength the Mac length
+ */
+ protected Zuc256CoreEngine(final int pLength)
+ {
+ switch (pLength)
+ {
+ case 32:
+ theD = EK_d32;
+ break;
+ case 64:
+ theD = EK_d64;
+ break;
+ case 128:
+ theD = EK_d128;
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported length: " + pLength);
+ }
+ }
+
+ /**
+ * Constructor for Memoable.
+ *
+ * @param pSource the source engine
+ */
+ protected Zuc256CoreEngine(final Zuc256CoreEngine pSource)
+ {
+ super(pSource);
+ }
+
+ /**
+ * Obtain Max iterations.
+ *
+ * @return the maximum iterations
+ */
+ protected int getMaxIterations()
+ {
+ return 625;
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc-256";
+ }
+
+ /**
+ * Build a 31-bit integer from constituent parts.
+ *
+ * @param a part A
+ * @param b part B
+ * @param c part C
+ * @param d part D
+ * @return the built integer
+ */
+ private static int MAKEU31(byte a, byte b, byte c, byte d)
+ {
+ return (((a & 0xFF) << 23) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | (d & 0xFF));
+ }
+
+ /**
+ * Process key and IV into LFSR.
+ *
+ * @param pLFSR the LFSR
+ * @param k the key
+ * @param iv the iv
+ */
+ protected void setKeyAndIV(final int[] pLFSR,
+ final byte[] k,
+ final byte[] iv)
+ {
+ /* Check lengths */
+ if (k == null || k.length != 32)
+ {
+ throw new IllegalArgumentException("A key of 32 bytes is needed");
+ }
+ if (iv == null || iv.length != 25)
+ {
+ throw new IllegalArgumentException("An IV of 25 bytes is needed");
+ }
+
+ /* expand key and IV */
+ pLFSR[0] = MAKEU31(k[0], theD[0], k[21], k[16]);
+ pLFSR[1] = MAKEU31(k[1], theD[1], k[22], k[17]);
+ pLFSR[2] = MAKEU31(k[2], theD[2], k[23], k[18]);
+ pLFSR[3] = MAKEU31(k[3], theD[3], k[24], k[19]);
+ pLFSR[4] = MAKEU31(k[4], theD[4], k[25], k[20]);
+ pLFSR[5] = MAKEU31(iv[0], (byte)(theD[5] | (iv[17] & 0x3F)), k[5], k[26]);
+ pLFSR[6] = MAKEU31(iv[1], (byte)(theD[6] | (iv[18] & 0x3F)), k[6], k[27]);
+ pLFSR[7] = MAKEU31(iv[10], (byte)(theD[7] | (iv[19] & 0x3F)), k[7], iv[2]);
+ pLFSR[8] = MAKEU31(k[8], (byte)(theD[8] | (iv[20] & 0x3F)), iv[3], iv[11]);
+ pLFSR[9] = MAKEU31(k[9], (byte)(theD[9] | (iv[21] & 0x3F)), iv[12], iv[4]);
+ pLFSR[10] = MAKEU31(iv[5], (byte)(theD[10] | (iv[22] & 0x3F)), k[10], k[28]);
+ pLFSR[11] = MAKEU31(k[11], (byte)(theD[11] | (iv[23] & 0x3F)), iv[6], iv[13]);
+ pLFSR[12] = MAKEU31(k[12], (byte)(theD[12] | (iv[24] & 0x3F)), iv[7], iv[14]);
+ pLFSR[13] = MAKEU31(k[13], theD[13], iv[15], iv[8]);
+ pLFSR[14] = MAKEU31(k[14], (byte)(theD[14] | ((k[31] >>> 4) & 0xF)), iv[16], iv[9]);
+ pLFSR[15] = MAKEU31(k[15], (byte)(theD[15] | (k[31] & 0xF)), k[30], k[29]);
+ }
+
+ /**
+ * Create a copy of the engine.
+ *
+ * @return the copy
+ */
+ public Memoable copy()
+ {
+ return new Zuc256CoreEngine(this);
+ }
+
+ /**
+ * Reset from saved engine state.
+ *
+ * @param pState the state to restore
+ */
+ public void reset(final Memoable pState)
+ {
+ final Zuc256CoreEngine e = (Zuc256CoreEngine)pState;
+ super.reset(pState);
+ theD = e.theD;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/Zuc256Engine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/Zuc256Engine.java
new file mode 100644
index 0000000..c80610c
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/Zuc256Engine.java
@@ -0,0 +1,49 @@
+package org.bouncycastle.crypto.engines;
+
+import org.bouncycastle.util.Memoable;
+
+/**
+ * Zuc256 implementation.
+ * Based on https://www.is.cas.cn/ztzl2016/zouchongzhi/201801/W020180126529970733243.pdf
+ */
+public final class Zuc256Engine
+ extends Zuc256CoreEngine
+{
+ /**
+ * Constructor for streamCipher.
+ */
+ public Zuc256Engine()
+ {
+ super();
+ }
+
+ /**
+ * Constructor for Mac.
+ *
+ * @param pLength the Mac length
+ */
+ public Zuc256Engine(final int pLength)
+ {
+ super(pLength);
+ }
+
+ /**
+ * Constructor for Memoable.
+ *
+ * @param pSource the source engine
+ */
+ private Zuc256Engine(final Zuc256Engine pSource)
+ {
+ super(pSource);
+ }
+
+ /**
+ * Create a copy of the engine.
+ *
+ * @return the copy
+ */
+ public Memoable copy()
+ {
+ return new Zuc256Engine(this);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESKeyGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESKeyGenerator.java
index 7111118..ba68ef7 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESKeyGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESKeyGenerator.java
@@ -1,7 +1,10 @@
package org.bouncycastle.crypto.generators;
import org.bouncycastle.crypto.CipherKeyGenerator;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.KeyGenerationParameters;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.DESParameters;
public class DESKeyGenerator
@@ -29,6 +32,8 @@
+ (DESParameters.DES_KEY_LENGTH * 8)
+ " bits long.");
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DESKeyGen", 56, null, CryptoServicePurpose.KEYGEN));
}
public byte[] generateKey()
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
index 19a2ecf..9ba8a55 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
@@ -1,6 +1,9 @@
package org.bouncycastle.crypto.generators;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.KeyGenerationParameters;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.DESedeParameters;
public class DESedeKeyGenerator
@@ -39,6 +42,8 @@
+ (2 * 8 * DESedeParameters.DES_KEY_LENGTH)
+ " bits long.");
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DESedeKeyGen", 112, null, CryptoServicePurpose.KEYGEN));
}
public byte[] generateKey()
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java
index f93428e..ca7a712 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java
@@ -1,15 +1,19 @@
package org.bouncycastle.crypto.generators;
+import java.math.BigInteger;
+
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.KeyGenerationParameters;
+import org.bouncycastle.crypto.constraints.ConstraintUtils;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.DHKeyGenerationParameters;
import org.bouncycastle.crypto.params.DHParameters;
import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
import org.bouncycastle.crypto.params.DHPublicKeyParameters;
-import java.math.BigInteger;
-
/**
* a basic Diffie-Hellman key pair generator.
*
@@ -25,6 +29,8 @@
KeyGenerationParameters param)
{
this.param = (DHKeyGenerationParameters)param;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DHBasicKeyGen", ConstraintUtils.bitsOfSecurityFor(this.param.getParameters().getP()), this.param.getParameters(), CryptoServicePurpose.KEYGEN));
}
public AsymmetricCipherKeyPair generateKeyPair()
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java
index ff3df35..d0a36e6 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java
@@ -5,7 +5,11 @@
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.KeyGenerationParameters;
+import org.bouncycastle.crypto.constraints.ConstraintUtils;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.DSAKeyGenerationParameters;
import org.bouncycastle.crypto.params.DSAParameters;
import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
@@ -30,6 +34,8 @@
KeyGenerationParameters param)
{
this.param = (DSAKeyGenerationParameters)param;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DSAKeyGen", ConstraintUtils.bitsOfSecurityFor(this.param.getParameters().getP()), this.param.getParameters(), CryptoServicePurpose.KEYGEN));
}
public AsymmetricCipherKeyPair generateKeyPair()
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
index 1712db7..f622687 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
@@ -5,7 +5,11 @@
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.KeyGenerationParameters;
+import org.bouncycastle.crypto.constraints.ConstraintUtils;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
@@ -20,9 +24,20 @@
public class ECKeyPairGenerator
implements AsymmetricCipherKeyPairGenerator, ECConstants
{
+ private final String name;
ECDomainParameters params;
SecureRandom random;
+ public ECKeyPairGenerator()
+ {
+ this("ECKeyGen");
+ }
+
+ protected ECKeyPairGenerator(String name)
+ {
+ this.name = name;
+ }
+
public void init(
KeyGenerationParameters param)
{
@@ -30,6 +45,8 @@
this.random = ecP.getRandom();
this.params = ecP.getDomainParameters();
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(name, ConstraintUtils.bitsOfSecurityFor(this.params.getCurve()), ecP.getDomainParameters(), CryptoServicePurpose.KEYGEN));
}
/**
@@ -47,7 +64,7 @@
{
d = BigIntegers.createRandomBigInteger(nBitLength, random);
- if (d.compareTo(ONE) < 0 || (d.compareTo(n) >= 0))
+ if (isOutOfRangeD(d, n))
{
continue;
}
@@ -67,6 +84,11 @@
new ECPrivateKeyParameters(d, params));
}
+ protected boolean isOutOfRangeD(BigInteger d, BigInteger n)
+ {
+ return d.compareTo(ONE) < 0 || (d.compareTo(n) >= 0);
+ }
+
protected ECMultiplier createBasePointMultiplier()
{
return new FixedPointCombMultiplier();
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
index 3e850c1..e891b3d 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
@@ -12,8 +12,9 @@
/**
* Generator for PBE derived keys and ivs as usd by OpenSSL.
* <p>
- * The scheme is a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an
- * iteration count of 1.
+ * Originally this scheme was a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an
+ * iteration count of 1. The default digest was changed to SHA-256 with OpenSSL 1.1.0. This
+ * implementation still defaults to MD5, but the digest can now be set.
* <p>
*/
public class OpenSSLPBEParametersGenerator
@@ -24,7 +25,7 @@
private Digest digest = AndroidDigestFactory.getMD5();
/**
- * Construct a OpenSSL Parameters generator.
+ * Construct a OpenSSL Parameters generator.
*/
public OpenSSLPBEParametersGenerator()
{
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
index 6d5fc97..55a03e9 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
@@ -4,7 +4,11 @@
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.KeyGenerationParameters;
+import org.bouncycastle.crypto.constraints.ConstraintUtils;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
@@ -25,6 +29,8 @@
public void init(KeyGenerationParameters param)
{
this.param = (RSAKeyGenerationParameters)param;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("RSAKeyGen", ConstraintUtils.bitsOfSecurityForFF(param.getStrength()), null, CryptoServicePurpose.KEYGEN));
}
public AsymmetricCipherKeyPair generateKeyPair()
@@ -91,12 +97,12 @@
continue;
}
- /*
+ /*
* Require a minimum weight of the NAF representation, since low-weight composites may
- * be weak against a version of the number-field-sieve for factoring.
- *
- * See "The number field sieve for integers of low weight", Oliver Schirokauer.
- */
+ * be weak against a version of the number-field-sieve for factoring.
+ *
+ * See "The number field sieve for integers of low weight", Oliver Schirokauer.
+ */
if (WNafUtil.getNafWeight(n) < minWeight)
{
p = chooseRandomPrime(pbitlength, e, squaredBound);
@@ -142,8 +148,8 @@
qInv = BigIntegers.modOddInverse(p, q);
result = new AsymmetricCipherKeyPair(
- new RSAKeyParameters(false, n, e),
- new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv));
+ new RSAKeyParameters(false, n, e, true),
+ new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv, true));
}
return result;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/SM2KeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/SM2KeyPairGenerator.java
new file mode 100644
index 0000000..31c922f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/SM2KeyPairGenerator.java
@@ -0,0 +1,36 @@
+package org.bouncycastle.crypto.generators;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
+import org.bouncycastle.crypto.KeyGenerationParameters;
+import org.bouncycastle.crypto.constraints.ConstraintUtils;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
+import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import org.bouncycastle.math.ec.ECConstants;
+import org.bouncycastle.math.ec.ECMultiplier;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.FixedPointCombMultiplier;
+import org.bouncycastle.math.ec.WNafUtil;
+import org.bouncycastle.util.BigIntegers;
+
+public class SM2KeyPairGenerator
+ extends ECKeyPairGenerator
+{
+ public SM2KeyPairGenerator()
+ {
+ super("SM2KeyGen");
+ }
+
+ protected boolean isOutOfRangeD(BigInteger d, BigInteger n)
+ {
+ return d.compareTo(ONE) < 0 || (d.compareTo(n.subtract(BigIntegers.ONE)) >= 0);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java b/bcprov/src/main/java/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java
index 9bf6cb0..9087807 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java
@@ -92,7 +92,7 @@
throw new IllegalArgumentException("MAC size must be multiple of 8");
}
- this.cipher = new CBCBlockCipher(cipher);
+ this.cipher = CBCBlockCipher.newInstance(cipher);
this.padding = padding;
this.macSize = macSizeInBits / 8;
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 5868262..c17c8f2 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/macs/HMac.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/macs/HMac.java
@@ -216,15 +216,15 @@
*/
public void reset()
{
- /*
- * reset the underlying digest.
- */
- digest.reset();
-
- /*
- * reinitialize the digest.
- */
- digest.update(inputPad, 0, inputPad.length);
+ if (ipadState != null)
+ {
+ ((Memoable)digest).reset(ipadState);
+ }
+ else
+ {
+ digest.reset();
+ digest.update(inputPad, 0, inputPad.length);
+ }
}
private static void xorPad(byte[] pad, int len, byte n)
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/macs/Zuc128Mac.java b/bcprov/src/main/java/org/bouncycastle/crypto/macs/Zuc128Mac.java
new file mode 100644
index 0000000..199ac23
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/macs/Zuc128Mac.java
@@ -0,0 +1,245 @@
+package org.bouncycastle.crypto.macs;
+
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.Mac;
+import org.bouncycastle.crypto.engines.Zuc128CoreEngine;
+
+/**
+ * Zuc128 Mac implementation.
+ * Based on https://www.qtc.jp/3GPP/Specs/eea3eia3specificationv16.pdf
+ */
+public final class Zuc128Mac
+ implements Mac
+{
+ /**
+ * The Maximum Bit Mask.
+ */
+ private static final int TOPBIT = 0x80;
+
+ /**
+ * The Zuc128 Engine.
+ */
+ private final InternalZuc128Engine theEngine;
+
+ /**
+ * The calculated Mac in words.
+ */
+ private int theMac;
+
+ /**
+ * The active keyStream.
+ */
+ private final int[] theKeyStream;
+
+ /**
+ * The initialised state.
+ */
+ private Zuc128CoreEngine theState;
+
+ /**
+ * The current word index.
+ */
+ private int theWordIndex;
+
+ /**
+ * The current byte index.
+ */
+ private int theByteIndex;
+
+ /**
+ * Constructor.
+ */
+ public Zuc128Mac()
+ {
+ theEngine = new InternalZuc128Engine();
+ theKeyStream = new int[2];
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc128Mac";
+ }
+
+ /**
+ * Obtain Mac Size.
+ *
+ * @return the size in Bytes
+ */
+ public int getMacSize()
+ {
+ return 4; // Integer.Bytes
+ }
+
+ /**
+ * Initialise the Mac.
+ *
+ * @param pParams the parameters
+ */
+ public void init(final CipherParameters pParams)
+ {
+ /* Initialise the engine */
+ theEngine.init(true, pParams);
+ theState = (Zuc128CoreEngine)theEngine.copy();
+ initKeyStream();
+ }
+
+ /**
+ * Initialise the keyStream.
+ */
+ private void initKeyStream()
+ {
+ /* Initialise the Mac */
+ theMac = 0;
+
+ /* Initialise the KeyStream */
+ for (int i = 0; i < theKeyStream.length - 1; i++)
+ {
+ theKeyStream[i] = theEngine.createKeyStreamWord();
+ }
+ theWordIndex = theKeyStream.length - 1;
+ theByteIndex = 3; //Integer.BYTES - 1;
+ }
+
+ /**
+ * Update the mac with a single byte.
+ *
+ * @param in the byte to update with
+ */
+ public void update(final byte in)
+ {
+ /* shift for next byte */
+ shift4NextByte();
+
+ /* Loop through the bits */
+ final int bitBase = theByteIndex * 8; //Byte.SIZE;
+ for (int bitMask = TOPBIT, bitNo = 0; bitMask > 0; bitMask >>= 1, bitNo++)
+ {
+ /* If the bit is set */
+ if ((in & bitMask) != 0)
+ {
+ /* update theMac */
+ updateMac(bitBase + bitNo);
+ }
+ }
+ }
+
+ /**
+ * Shift for next byte.
+ */
+ private void shift4NextByte()
+ {
+ /* Adjust the byte index */
+ theByteIndex = (theByteIndex + 1) % 4; //Integer.BYTES;
+
+ /* Adjust keyStream if required */
+ if (theByteIndex == 0)
+ {
+ theKeyStream[theWordIndex] = theEngine.createKeyStreamWord();
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ }
+ }
+
+ /**
+ * Update the Mac.
+ *
+ * @param bitNo the bit number
+ */
+ private void updateMac(final int bitNo)
+ {
+ /* Update the Mac */
+ theMac ^= getKeyStreamWord(bitNo);
+ }
+
+ /**
+ * Obtain the keyStreamWord.
+ *
+ * @param bitNo the bitNumber
+ * @return the word
+ */
+ private int getKeyStreamWord(final int bitNo)
+ {
+ /* Access the first word and return it if this is bit 0 */
+ final int myFirst = theKeyStream[theWordIndex];
+ if (bitNo == 0)
+ {
+ return myFirst;
+ }
+
+ /* Access the second word */
+ final int mySecond = theKeyStream[(theWordIndex + 1) % theKeyStream.length];
+ return (myFirst << bitNo) | (mySecond >>> (32 - bitNo)); // Integer.SIZE - bitNo
+ }
+
+ /**
+ * Update the mac.
+ *
+ * @param in the input buffer
+ * @param inOff the starting offset in the input buffer
+ * @param len the length of data to process
+ */
+ public void update(final byte[] in, final int inOff, final int len)
+ {
+ for (int byteNo = 0; byteNo < len; byteNo++)
+ {
+ update(in[inOff + byteNo]);
+ }
+ }
+
+ /**
+ * Obtain the final word.
+ *
+ * @return the final word
+ */
+ private int getFinalWord()
+ {
+ if (theByteIndex != 0)
+ {
+ return theEngine.createKeyStreamWord();
+ }
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ return theKeyStream[theWordIndex];
+ }
+
+ /**
+ * Finalize the mac.
+ *
+ * @param out the output buffer
+ * @param outOff the starting offset in the input buffer
+ * @return the size of the mac
+ */
+ public int doFinal(final byte[] out, final int outOff)
+ {
+ /* Finish the Mac and output it */
+ shift4NextByte();
+ theMac ^= getKeyStreamWord(theByteIndex * 8); //Byte.SIZE
+ theMac ^= getFinalWord();
+ Zuc128CoreEngine.encode32be(theMac, out, outOff);
+
+ /* Reset the Mac */
+ reset();
+ return getMacSize();
+ }
+
+ public void reset()
+ {
+ if (theState != null)
+ {
+ theEngine.reset(theState);
+ }
+ initKeyStream();
+ }
+
+ private static class InternalZuc128Engine
+ extends Zuc128CoreEngine
+ {
+ int createKeyStreamWord()
+ {
+ return super.makeKeyStreamWord();
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/macs/Zuc256Mac.java b/bcprov/src/main/java/org/bouncycastle/crypto/macs/Zuc256Mac.java
new file mode 100644
index 0000000..26313d5
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/macs/Zuc256Mac.java
@@ -0,0 +1,274 @@
+package org.bouncycastle.crypto.macs;
+
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.Mac;
+import org.bouncycastle.crypto.engines.Zuc256CoreEngine;
+
+/**
+ * Zuc256 Mac implementation.
+ * Based on https://www.is.cas.cn/ztzl2016/zouchongzhi/201801/W020180126529970733243.pdf
+ */
+public final class Zuc256Mac
+ implements Mac
+{
+ /**
+ * The Maximum Bit Mask.
+ */
+ private static final int TOPBIT = 0x80;
+
+ /**
+ * The Zuc256 Engine.
+ */
+ private final InternalZuc256Engine theEngine;
+
+ /**
+ * The mac length.
+ */
+ private final int theMacLength;
+
+ /**
+ * The calculated Mac in words.
+ */
+ private final int[] theMac;
+
+ /**
+ * The active keyStream.
+ */
+ private final int[] theKeyStream;
+
+ /**
+ * The initialised state.
+ */
+ private Zuc256CoreEngine theState;
+
+ /**
+ * The current word index.
+ */
+ private int theWordIndex;
+
+ /**
+ * The current byte index.
+ */
+ private int theByteIndex;
+
+ /**
+ * Constructor.
+ *
+ * @param pLength the bit length of the Mac
+ */
+ public Zuc256Mac(final int pLength)
+ {
+ theEngine = new InternalZuc256Engine(pLength);
+ theMacLength = pLength;
+ final int numWords = pLength / 32; // Integer.SIZE
+ theMac = new int[numWords];
+ theKeyStream = new int[numWords + 1];
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc256Mac-" + theMacLength;
+ }
+
+ /**
+ * Obtain Mac Size.
+ *
+ * @return the size in Bytes
+ */
+ public int getMacSize()
+ {
+ return theMacLength / 8; //Byte.SIZE
+ }
+
+ /**
+ * Initialise the Mac.
+ *
+ * @param pParams the parameters
+ */
+ public void init(final CipherParameters pParams)
+ {
+ /* Initialise the engine */
+ theEngine.init(true, pParams);
+ theState = (Zuc256CoreEngine)theEngine.copy();
+ initKeyStream();
+ }
+
+ /**
+ * Initialise the keyStream.
+ */
+ private void initKeyStream()
+ {
+ /* Initialise the Mac */
+ for (int i = 0; i < theMac.length; i++)
+ {
+ theMac[i] = theEngine.createKeyStreamWord();
+ }
+
+ /* Initialise the KeyStream */
+ for (int i = 0; i < theKeyStream.length - 1; i++)
+ {
+ theKeyStream[i] = theEngine.createKeyStreamWord();
+ }
+ theWordIndex = theKeyStream.length - 1;
+ theByteIndex = 4 - 1; // Integer.SIZE
+ }
+
+ /**
+ * Update the mac with a single byte.
+ *
+ * @param in the byte to update with
+ */
+ public void update(final byte in)
+ {
+ /* shift for next byte */
+ shift4NextByte();
+
+ /* Loop through the bits */
+ final int bitBase = theByteIndex * 8; //Byte.SIZE;
+ for (int bitMask = TOPBIT, bitNo = 0; bitMask > 0; bitMask >>= 1, bitNo++)
+ {
+ /* If the bit is set */
+ if ((in & bitMask) != 0)
+ {
+ /* update theMac */
+ updateMac(bitBase + bitNo);
+ }
+ }
+ }
+
+ /**
+ * Shift for next byte.
+ */
+ private void shift4NextByte()
+ {
+ /* Adjust the byte index */
+ theByteIndex = (theByteIndex + 1) % 4; //Integer.BYTES
+
+ /* Adjust keyStream if required */
+ if (theByteIndex == 0)
+ {
+ theKeyStream[theWordIndex] = theEngine.createKeyStreamWord();
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ }
+ }
+
+ /**
+ * Shift for final update.
+ */
+ private void shift4Final()
+ {
+ /* Adjust the byte index */
+ theByteIndex = (theByteIndex + 1) % 4; //Integer.BYTES
+
+ /* No need to read another word to the keyStream */
+ if (theByteIndex == 0)
+ {
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ }
+ }
+
+ /**
+ * Update the Mac.
+ *
+ * @param bitNo the bit number
+ */
+ private void updateMac(final int bitNo)
+ {
+ /* Loop through the Mac */
+ for (int wordNo = 0; wordNo < theMac.length; wordNo++)
+ {
+ theMac[wordNo] ^= getKeyStreamWord(wordNo, bitNo);
+ }
+ }
+
+ /**
+ * Obtain the keyStreamWord.
+ *
+ * @param wordNo the wordNumber
+ * @param bitNo the bitNumber
+ * @return the word
+ */
+ private int getKeyStreamWord(final int wordNo, final int bitNo)
+ {
+ /* Access the first word and return it if this is bit 0 */
+ final int myFirst = theKeyStream[(theWordIndex + wordNo) % theKeyStream.length];
+ if (bitNo == 0)
+ {
+ return myFirst;
+ }
+
+ /* Access the second word */
+ final int mySecond = theKeyStream[(theWordIndex + wordNo + 1) % theKeyStream.length];
+ return (myFirst << bitNo) | (mySecond >>> (32 - bitNo)); //Integer.SIZE - bitNo
+ }
+
+ /**
+ * Update the mac.
+ *
+ * @param in the input buffer
+ * @param inOff the starting offset in the input buffer
+ * @param len the length of data to process
+ */
+ public void update(final byte[] in, final int inOff, final int len)
+ {
+ for (int byteNo = 0; byteNo < len; byteNo++)
+ {
+ update(in[inOff + byteNo]);
+ }
+ }
+
+ /**
+ * Finalize the mac.
+ *
+ * @param out the output buffer
+ * @param outOff the starting offset in the output buffer
+ * @return the size of the mac
+ */
+ public int doFinal(final byte[] out, final int outOff)
+ {
+ /* shift for final update */
+ shift4Final();
+
+ /* Finish the Mac and output it */
+ updateMac(theByteIndex * 8); //Byte.SIZE)
+ for (int i = 0; i < theMac.length; i++)
+ {
+ Zuc256CoreEngine.encode32be(theMac[i], out, outOff + i * 4); //Integer.BYTES)
+ }
+
+ /* Reset the Mac */
+ reset();
+ return getMacSize();
+ }
+
+ /**
+ * Reset the Mac.
+ */
+ public void reset()
+ {
+ if (theState != null)
+ {
+ theEngine.reset(theState);
+ }
+ initKeyStream();
+ }
+
+ private static class InternalZuc256Engine
+ extends Zuc256CoreEngine
+ {
+ public InternalZuc256Engine(int pLength)
+ {
+ super(pLength);
+ }
+
+ int createKeyStreamWord()
+ {
+ return super.makeKeyStreamWord();
+ }
+ }
+}
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 d4800e6..130ff78 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CBCBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CBCBlockCipher.java
@@ -3,6 +3,7 @@
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.DefaultMultiBlockCipher;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.Arrays;
@@ -10,7 +11,8 @@
* implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher.
*/
public class CBCBlockCipher
- implements BlockCipher
+ extends DefaultMultiBlockCipher
+ implements CBCModeCipher
{
private byte[] IV;
private byte[] cbcV;
@@ -21,9 +23,20 @@
private boolean encrypting;
/**
+ * Return a new CBC mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the CBC mode.
+ */
+ public static CBCModeCipher newInstance(BlockCipher cipher)
+ {
+ return new CBCBlockCipher(cipher);
+ }
+
+ /**
* Basic constructor.
*
* @param cipher the block cipher to be used as the basis of chaining.
+ * @deprecated use the CBCBlockCipher.newInstance() static method.
*/
public CBCBlockCipher(
BlockCipher cipher)
@@ -77,31 +90,23 @@
System.arraycopy(iv, 0, IV, 0, iv.length);
- reset();
-
- // if null it's an IV changed only.
- if (ivParam.getParameters() != null)
- {
- cipher.init(encrypting, ivParam.getParameters());
- }
- else if (oldEncrypting != encrypting)
- {
- throw new IllegalArgumentException("cannot change encrypting state without providing key.");
- }
+ params = ivParam.getParameters();
}
else
{
- reset();
+ Arrays.fill(IV, (byte)0);
+ }
- // if it's null, key is to be reused.
- if (params != null)
- {
- cipher.init(encrypting, params);
- }
- else if (oldEncrypting != encrypting)
- {
- throw new IllegalArgumentException("cannot change encrypting state without providing key.");
- }
+ reset();
+
+ // if null it's an IV changed only (key is to be reused).
+ if (params != null)
+ {
+ cipher.init(encrypting, params);
+ }
+ else if (oldEncrypting != encrypting)
+ {
+ throw new IllegalArgumentException("cannot change encrypting state without providing key.");
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CBCModeCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CBCModeCipher.java
new file mode 100644
index 0000000..682b580
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CBCModeCipher.java
@@ -0,0 +1,15 @@
+package org.bouncycastle.crypto.modes;
+
+import org.bouncycastle.crypto.BlockCipher;
+import org.bouncycastle.crypto.MultiBlockCipher;
+
+public interface CBCModeCipher
+ extends MultiBlockCipher
+{
+ /**
+ * return the underlying block cipher that we are wrapping.
+ *
+ * @return the underlying block cipher that we are wrapping.
+ */
+ BlockCipher getUnderlyingCipher();
+}
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 00e1a78..1ac255b 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
@@ -20,7 +20,7 @@
* <b>Note</b>: this mode is a packet mode - it needs all the data up front.
*/
public class CCMBlockCipher
- implements AEADBlockCipher
+ implements CCMModeCipher
{
private BlockCipher cipher;
private int blockSize;
@@ -34,9 +34,20 @@
private ExposedByteArrayOutputStream data = new ExposedByteArrayOutputStream();
/**
+ * Return a new CCM mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the CCM mode.
+ */
+ public static CCMModeCipher newInstance(BlockCipher cipher)
+ {
+ return new CCMBlockCipher(cipher);
+ }
+
+ /**
* Basic constructor.
*
* @param c the block cipher to be used.
+ * @deprecated use the CCMBlockCipher.newInstance() static method.
*/
public CCMBlockCipher(BlockCipher c)
{
@@ -260,7 +271,7 @@
iv[0] = (byte)((q - 1) & 0x7);
System.arraycopy(nonce, 0, iv, 1, nonce.length);
- BlockCipher ctrCipher = new SICBlockCipher(cipher);
+ BlockCipher ctrCipher = SICBlockCipher.newInstance(cipher);
ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv));
int outputLen;
@@ -454,7 +465,7 @@
return getAssociatedTextLength() > 0;
}
- private class ExposedByteArrayOutputStream
+ private static class ExposedByteArrayOutputStream
extends ByteArrayOutputStream
{
public ExposedByteArrayOutputStream()
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMModeCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMModeCipher.java
new file mode 100644
index 0000000..d96ac05
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMModeCipher.java
@@ -0,0 +1,6 @@
+package org.bouncycastle.crypto.modes;
+
+public interface CCMModeCipher
+ extends AEADBlockCipher
+{
+}
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 b11716f..1bfaef9 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java
@@ -12,6 +12,7 @@
*/
public class CFBBlockCipher
extends StreamBlockCipher
+ implements CFBModeCipher
{
private byte[] IV;
private byte[] cfbV;
@@ -24,11 +25,23 @@
private int byteCount;
/**
+ * Return a new CFB mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the CFB mode.
+ * @param blockSize the block size (in bits) used for the CFB mode.
+ */
+ public static CFBModeCipher newInstance(BlockCipher cipher, int blockSize)
+ {
+ return new CFBBlockCipher(cipher, blockSize);
+ }
+
+ /**
* Basic constructor.
*
* @param cipher the block cipher to be used as the basis of the
* feedback mode.
* @param bitBlockSize the block size in bits (note: a multiple of 8)
+ * @deprecated use the equivalent CFBBlockCipher.newInstance() static method.
*/
public CFBBlockCipher(
BlockCipher cipher,
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBModeCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBModeCipher.java
new file mode 100644
index 0000000..4ef78ce
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBModeCipher.java
@@ -0,0 +1,9 @@
+package org.bouncycastle.crypto.modes;
+
+import org.bouncycastle.crypto.MultiBlockCipher;
+import org.bouncycastle.crypto.StreamCipher;
+
+public interface CFBModeCipher
+ extends MultiBlockCipher, StreamCipher
+{
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CTRModeCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CTRModeCipher.java
new file mode 100644
index 0000000..13fd97e
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CTRModeCipher.java
@@ -0,0 +1,16 @@
+package org.bouncycastle.crypto.modes;
+
+import org.bouncycastle.crypto.BlockCipher;
+import org.bouncycastle.crypto.MultiBlockCipher;
+import org.bouncycastle.crypto.SkippingStreamCipher;
+
+public interface CTRModeCipher
+ extends MultiBlockCipher, SkippingStreamCipher
+{
+ /**
+ * return the underlying block cipher that we are wrapping.
+ *
+ * @return the underlying block cipher that we are wrapping.
+ */
+ BlockCipher getUnderlyingCipher();
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java
index ea80706..af1fa46 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java
@@ -1,8 +1,8 @@
package org.bouncycastle.crypto.modes;
import org.bouncycastle.crypto.BlockCipher;
-import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.StreamBlockCipher;
@@ -12,7 +12,7 @@
* be used to produce cipher text which is the same length as the plain text.
*/
public class CTSBlockCipher
- extends BufferedBlockCipher
+ extends DefaultBufferedBlockCipher
{
private int blockSize;
@@ -221,9 +221,9 @@
buf[i] ^= block[i - blockSize];
}
- if (cipher instanceof CBCBlockCipher)
+ if (cipher instanceof CBCModeCipher)
{
- BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher();
+ BlockCipher c = ((CBCModeCipher)cipher).getUnderlyingCipher();
c.processBlock(buf, blockSize, out, outOff);
}
@@ -250,9 +250,9 @@
if (bufOff > blockSize)
{
- if (cipher instanceof CBCBlockCipher)
+ if (cipher instanceof CBCModeCipher)
{
- BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher();
+ BlockCipher c = ((CBCModeCipher)cipher).getUnderlyingCipher();
c.processBlock(buf, 0, block, 0);
}
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 75343d8..9f39995 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
@@ -21,7 +21,7 @@
* NIST Special Publication 800-38D.
*/
public class GCMBlockCipher
- implements AEADBlockCipher
+ implements GCMModeCipher
{
private static final int BLOCK_SIZE = 16;
// BEGIN Android-added: Max input size limitation from NIST.
@@ -58,11 +58,45 @@
private long atLength;
private long atLengthPre;
+ /**
+ * Return a new GCM mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the GCM mode.
+ */
+ public static GCMModeCipher newInstance(BlockCipher cipher)
+ {
+ return new GCMBlockCipher(cipher);
+ }
+
+ /**
+ * Return a new GCM mode cipher based on the passed in base cipher and multiplier.
+ *
+ * @param cipher the base cipher for the GCM mode.
+ * @param m the GCM multiplier to use.
+ */
+ public static GCMModeCipher newInstance(BlockCipher cipher, GCMMultiplier m)
+ {
+ return new GCMBlockCipher(cipher, m);
+ }
+
+ /**
+ * Base constructor - GCM mode over base cipher c.
+ *
+ * @param c the base cipher.
+ * @deprecated use the GCMBlockCipher.newInstance() static method.
+ */
public GCMBlockCipher(BlockCipher c)
{
this(c, null);
}
+ /**
+ * Base constructor - GCM mode over base cipher c over base multiplier m.
+ *
+ * @param c the base cipher.
+ * @param m the GCM multiplier to use.
+ * @deprecated use the CBCBlockCipher.newInstance() static method.
+ */
public GCMBlockCipher(BlockCipher c, GCMMultiplier m)
{
if (c.getBlockSize() != BLOCK_SIZE)
@@ -287,17 +321,35 @@
}
// END Android-added: Max input size limitation from NIST.
- for (int i = 0; i < len; ++i)
+ if (atBlockPos > 0)
{
- atBlock[atBlockPos] = in[inOff + i];
- if (++atBlockPos == BLOCK_SIZE)
+ int available = BLOCK_SIZE - atBlockPos;
+ if (len < available)
{
- // Hash each block as it fills
- gHASHBlock(S_at, atBlock);
- atBlockPos = 0;
- atLength += BLOCK_SIZE;
+ System.arraycopy(in, inOff, atBlock, atBlockPos, len);
+ atBlockPos += len;
+ return;
}
+
+ System.arraycopy(in, inOff, atBlock, atBlockPos, available);
+ gHASHBlock(S_at, atBlock);
+ atLength += BLOCK_SIZE;
+ inOff += available;
+ len -= available;
+ //atBlockPos = 0;
}
+
+ int inLimit = inOff + len - BLOCK_SIZE;
+
+ while (inOff <= inLimit)
+ {
+ gHASHBlock(S_at, in, inOff);
+ atLength += BLOCK_SIZE;
+ inOff += BLOCK_SIZE;
+ }
+
+ atBlockPos = BLOCK_SIZE + inLimit - inOff;
+ System.arraycopy(in, inOff, atBlock, 0, atBlockPos);
}
private void initCipher()
@@ -334,13 +386,14 @@
bufBlock[bufOff] = in;
if (++bufOff == bufBlock.length)
{
- processBlock(bufBlock, 0, out, outOff);
if (forEncryption)
{
+ encryptBlock(bufBlock, 0, out, outOff);
bufOff = 0;
}
else
{
+ decryptBlock(bufBlock, 0, out, outOff);
System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize);
bufOff = macSize;
}
@@ -368,49 +421,79 @@
if (forEncryption)
{
- if (bufOff != 0)
+ if (bufOff > 0)
{
- while (len > 0)
+ int available = BLOCK_SIZE - bufOff;
+ if (len < available)
{
- --len;
- bufBlock[bufOff] = in[inOff++];
- if (++bufOff == BLOCK_SIZE)
- {
- processBlock(bufBlock, 0, out, outOff);
- bufOff = 0;
- resultLen += BLOCK_SIZE;
- break;
- }
+ System.arraycopy(in, inOff, bufBlock, bufOff, len);
+ bufOff += len;
+ return 0;
}
+
+ System.arraycopy(in, inOff, bufBlock, bufOff, available);
+ encryptBlock(bufBlock, 0, out, outOff);
+ inOff += available;
+ len -= available;
+ resultLen = BLOCK_SIZE;
+ //bufOff = 0;
}
- while (len >= BLOCK_SIZE)
+ int inLimit = inOff + len - BLOCK_SIZE;
+
+ while (inOff <= inLimit)
{
- processBlock(in, inOff, out, outOff + resultLen);
+ encryptBlock(in, inOff, out, outOff + resultLen);
inOff += BLOCK_SIZE;
- len -= BLOCK_SIZE;
resultLen += BLOCK_SIZE;
}
- if (len > 0)
- {
- System.arraycopy(in, inOff, bufBlock, 0, len);
- bufOff = len;
- }
+ bufOff = BLOCK_SIZE + inLimit - inOff;
+ System.arraycopy(in, inOff, bufBlock, 0, bufOff);
}
else
{
- for (int i = 0; i < len; ++i)
+ int available = bufBlock.length - bufOff;
+ if (len < available)
{
- bufBlock[bufOff] = in[inOff + i];
- if (++bufOff == bufBlock.length)
+ System.arraycopy(in, inOff, bufBlock, bufOff, len);
+ bufOff += len;
+ return 0;
+ }
+
+ if (bufOff >= BLOCK_SIZE)
+ {
+ decryptBlock(bufBlock, 0, out, outOff);
+ System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, bufOff -= BLOCK_SIZE);
+ resultLen = BLOCK_SIZE;
+
+ available += BLOCK_SIZE;
+ if (len < available)
{
- processBlock(bufBlock, 0, out, outOff + resultLen);
- System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize);
- bufOff = macSize;
- resultLen += BLOCK_SIZE;
+ System.arraycopy(in, inOff, bufBlock, bufOff, len);
+ bufOff += len;
+ return resultLen;
}
}
+
+ int inLimit = inOff + len - bufBlock.length;
+
+ available = BLOCK_SIZE - bufOff;
+ System.arraycopy(in, inOff, bufBlock, bufOff, available);
+ decryptBlock(bufBlock, 0, out, outOff + resultLen);
+ inOff += available;
+ resultLen += BLOCK_SIZE;
+ //bufOff = 0;
+
+ while (inOff <= inLimit)
+ {
+ decryptBlock(in, inOff, out, outOff + resultLen);
+ inOff += BLOCK_SIZE;
+ resultLen += BLOCK_SIZE;
+ }
+
+ bufOff = bufBlock.length + inLimit - inOff;
+ System.arraycopy(in, inOff, bufBlock, 0, bufOff);
}
return resultLen;
@@ -583,7 +666,7 @@
}
}
- private void processBlock(byte[] buf, int bufOff, byte[] out, int outOff)
+ private void decryptBlock(byte[] buf, int bufOff, byte[] out, int outOff)
{
if ((out.length - outOff) < BLOCK_SIZE)
{
@@ -597,18 +680,30 @@
byte[] ctrBlock = new byte[BLOCK_SIZE];
getNextCTRBlock(ctrBlock);
- if (forEncryption)
+ gHASHBlock(S, buf, bufOff);
+ GCMUtil.xor(ctrBlock, 0, buf, bufOff, out, outOff);
+
+ totalLength += BLOCK_SIZE;
+ }
+
+ private void encryptBlock(byte[] buf, int bufOff, byte[] out, int outOff)
+ {
+ if ((out.length - outOff) < BLOCK_SIZE)
{
- GCMUtil.xor(ctrBlock, buf, bufOff);
- gHASHBlock(S, ctrBlock);
- System.arraycopy(ctrBlock, 0, out, outOff, BLOCK_SIZE);
+ throw new OutputLengthException("Output buffer too short");
}
- else
+ if (totalLength == 0)
{
- gHASHBlock(S, buf, bufOff);
- GCMUtil.xor(ctrBlock, 0, buf, bufOff, out, outOff);
+ initCipher();
}
+ byte[] ctrBlock = new byte[BLOCK_SIZE];
+
+ getNextCTRBlock(ctrBlock);
+ GCMUtil.xor(ctrBlock, buf, bufOff);
+ gHASHBlock(S, ctrBlock);
+ System.arraycopy(ctrBlock, 0, out, outOff, BLOCK_SIZE);
+
totalLength += BLOCK_SIZE;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMModeCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMModeCipher.java
new file mode 100644
index 0000000..b45459a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMModeCipher.java
@@ -0,0 +1,6 @@
+package org.bouncycastle.crypto.modes;
+
+public interface GCMModeCipher
+ extends AEADBlockCipher
+{
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java
new file mode 100644
index 0000000..404629b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java
@@ -0,0 +1,971 @@
+package org.bouncycastle.crypto.modes;
+
+import java.io.ByteArrayOutputStream;
+
+import org.bouncycastle.crypto.BlockCipher;
+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.AESEngine;
+import org.bouncycastle.crypto.modes.gcm.GCMMultiplier;
+import org.bouncycastle.crypto.modes.gcm.Tables4kGCMMultiplier;
+import org.bouncycastle.crypto.params.AEADParameters;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.params.ParametersWithIV;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Bytes;
+import org.bouncycastle.util.Integers;
+import org.bouncycastle.util.Longs;
+import org.bouncycastle.util.Pack;
+
+/**
+ * GCM-SIV Mode.
+ * <p>It should be noted that the specified limit of 2<sup>36</sup> bytes is not supported. This is because all bytes are
+ * cached in a <b>ByteArrayOutputStream</b> object (which has a limit of a little less than 2<sup>31</sup> bytes),
+ * and are output on the <b>doFinal</b>() call (which can only process a maximum of 2<sup>31</sup> bytes).</p>
+ * <p>The practical limit of 2<sup>31</sup> - 24 bytes is policed, and attempts to breach the limit will be rejected</p>
+ * <p>In order to properly support the higher limit, an extended form of <b>ByteArrayOutputStream</b> would be needed
+ * which would use multiple arrays to store the data. In addition, a new <b>doOutput</b> method would be required (similar
+ * to that in <b>XOF</b> digests), which would allow the data to be output over multiple calls. Alternatively an extended
+ * form of <b>ByteArrayInputStream</b> could be used to deliver the data.</p>
+ */
+public class GCMSIVBlockCipher
+ implements AEADBlockCipher
+{
+ /**
+ * The buffer length.
+ */
+ private static final int BUFLEN = 16;
+
+ /**
+ * The halfBuffer length.
+ */
+ private static final int HALFBUFLEN = BUFLEN >> 1;
+
+ /**
+ * The nonce length.
+ */
+ private static final int NONCELEN = 12;
+
+ /**
+ * The maximum data length (AEAD/PlainText). Due to implementation constraints this is restricted to the maximum
+ * array length (https://programming.guide/java/array-maximum-length.html) minus the BUFLEN to allow for the MAC
+ */
+ private static final int MAX_DATALEN = Integer.MAX_VALUE - 8 - BUFLEN;
+
+ /**
+ * The top bit mask.
+ */
+ private static final byte MASK = (byte) 0x80;
+
+ /**
+ * The addition constant.
+ */
+ private static final byte ADD = (byte) 0xE1;
+
+ /**
+ * The initialisation flag.
+ */
+ private static final int INIT = 1;
+
+ /**
+ * The aeadComplete flag.
+ */
+ private static final int AEAD_COMPLETE = 2;
+
+ /**
+ * The cipher.
+ */
+ private final BlockCipher theCipher;
+
+ /**
+ * The multiplier.
+ */
+ private final GCMMultiplier theMultiplier;
+
+ /**
+ * The gHash buffer.
+ */
+ private final byte[] theGHash = new byte[BUFLEN];
+
+ /**
+ * The reverse buffer.
+ */
+ private final byte[] theReverse = new byte[BUFLEN];
+
+ /**
+ * The aeadHasher.
+ */
+ private final GCMSIVHasher theAEADHasher;
+
+ /**
+ * The dataHasher.
+ */
+ private final GCMSIVHasher theDataHasher;
+
+ /**
+ * The plainDataStream.
+ */
+ private GCMSIVCache thePlain;
+
+ /**
+ * The encryptedDataStream (decryption only).
+ */
+ private GCMSIVCache theEncData;
+
+ /**
+ * Are we encrypting?
+ */
+ private boolean forEncryption;
+
+ /**
+ * The initialAEAD.
+ */
+ private byte[] theInitialAEAD;
+
+ /**
+ * The nonce.
+ */
+ private byte[] theNonce;
+
+ /**
+ * The flags.
+ */
+ private int theFlags;
+
+ // defined fixed
+ private byte[] macBlock = new byte[16];
+
+ /**
+ * Constructor.
+ */
+ public GCMSIVBlockCipher()
+ {
+ this(AESEngine.newInstance());
+ }
+
+ /**
+ * Constructor.
+ * @param pCipher the underlying cipher
+ */
+ public GCMSIVBlockCipher(final BlockCipher pCipher)
+ {
+ this(pCipher, new Tables4kGCMMultiplier());
+ }
+
+ /**
+ * Constructor.
+ * @param pCipher the underlying cipher
+ * @param pMultiplier the multiplier
+ */
+ public GCMSIVBlockCipher(final BlockCipher pCipher,
+ final GCMMultiplier pMultiplier)
+ {
+ /* Ensure that the cipher is the correct size */
+ if (pCipher.getBlockSize() != BUFLEN)
+ {
+ throw new IllegalArgumentException("Cipher required with a block size of " + BUFLEN + ".");
+ }
+
+ /* Store parameters */
+ theCipher = pCipher;
+ theMultiplier = pMultiplier;
+
+ /* Create the hashers */
+ theAEADHasher = new GCMSIVHasher();
+ theDataHasher = new GCMSIVHasher();
+ }
+
+ public BlockCipher getUnderlyingCipher()
+ {
+ return theCipher;
+ }
+
+ public void init(final boolean pEncrypt,
+ final CipherParameters cipherParameters) throws IllegalArgumentException
+ {
+ /* Set defaults */
+ byte[] myInitialAEAD = null;
+ byte[] myNonce = null;
+ KeyParameter myKey = null;
+
+ /* Access parameters */
+ if (cipherParameters instanceof AEADParameters)
+ {
+ final AEADParameters myAEAD = (AEADParameters) cipherParameters;
+ myInitialAEAD = myAEAD.getAssociatedText();
+ myNonce = myAEAD.getNonce();
+ myKey = myAEAD.getKey();
+ }
+ else if (cipherParameters instanceof ParametersWithIV)
+ {
+ final ParametersWithIV myParms = (ParametersWithIV) cipherParameters;
+ myNonce = myParms.getIV();
+ myKey = (KeyParameter) myParms.getParameters();
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid parameters passed to GCM-SIV");
+ }
+
+ /* Check nonceSize */
+ if (myNonce == null || myNonce.length != NONCELEN)
+ {
+ throw new IllegalArgumentException("Invalid nonce");
+ }
+
+ /* Check keysize */
+ if (myKey == null
+ || (myKey.getKeyLength() != BUFLEN
+ && myKey.getKeyLength() != (BUFLEN << 1)))
+ {
+ throw new IllegalArgumentException("Invalid key");
+ }
+
+ /* Reset details */
+ forEncryption = pEncrypt;
+ theInitialAEAD = myInitialAEAD;
+ theNonce = myNonce;
+
+ /* Initialise the keys */
+ deriveKeys(myKey);
+ resetStreams();
+ }
+
+ public String getAlgorithmName()
+ {
+ return theCipher.getAlgorithmName() + "-GCM-SIV";
+ }
+
+ /**
+ * check AEAD status.
+ * @param pLen the aeadLength
+ */
+ private void checkAEADStatus(final int pLen)
+ {
+ /* Check we are initialised */
+ if ((theFlags & INIT) == 0)
+ {
+ throw new IllegalStateException("Cipher is not initialised");
+ }
+
+ /* Check AAD is allowed */
+ if ((theFlags & AEAD_COMPLETE) != 0)
+ {
+ throw new IllegalStateException("AEAD data cannot be processed after ordinary data");
+ }
+
+ /* Make sure that we haven't breached AEAD data limit */
+ if (theAEADHasher.getBytesProcessed() + Long.MIN_VALUE
+ > (MAX_DATALEN - pLen) + Long.MIN_VALUE)
+ {
+ throw new IllegalStateException("AEAD byte count exceeded");
+ }
+ }
+
+ /**
+ * check status.
+ * @param pLen the dataLength
+ */
+ private void checkStatus(final int pLen)
+ {
+ /* Check we are initialised */
+ if ((theFlags & INIT) == 0)
+ {
+ throw new IllegalStateException("Cipher is not initialised");
+ }
+
+ /* Complete the AEAD section if this is the first data */
+ if ((theFlags & AEAD_COMPLETE) == 0)
+ {
+ theAEADHasher.completeHash();
+ theFlags |= AEAD_COMPLETE;
+ }
+
+ /* Make sure that we haven't breached data limit */
+ long dataLimit = MAX_DATALEN;
+ long currBytes = thePlain.size();
+ if (!forEncryption)
+ {
+ dataLimit += BUFLEN;
+ currBytes = theEncData.size();
+ }
+ if (currBytes + Long.MIN_VALUE
+ > (dataLimit - pLen) + Long.MIN_VALUE)
+ {
+ throw new IllegalStateException("byte count exceeded");
+ }
+ }
+
+ public void processAADByte(final byte pByte)
+ {
+ /* Check that we can supply AEAD */
+ checkAEADStatus(1);
+
+ /* Process the aead */
+ theAEADHasher.updateHash(pByte);
+ }
+
+ public void processAADBytes(final byte[] pData,
+ final int pOffset,
+ final int pLen)
+ {
+ /* Check that we can supply AEAD */
+ checkAEADStatus(pLen);
+
+ /* Check input buffer */
+ checkBuffer(pData, pOffset, pLen, false);
+
+ /* Process the aead */
+ theAEADHasher.updateHash(pData, pOffset, pLen);
+ }
+
+ public int processByte(final byte pByte,
+ final byte[] pOutput,
+ final int pOutOffset) throws DataLengthException
+ {
+ /* Check that we have initialised */
+ checkStatus(1);
+
+ /* Store the data */
+ if (forEncryption)
+ {
+ thePlain.write(pByte);
+ theDataHasher.updateHash(pByte);
+ }
+ else
+ {
+ theEncData.write(pByte);
+ }
+
+ /* No data returned */
+ return 0;
+ }
+
+ public int processBytes(final byte[] pData,
+ final int pOffset,
+ final int pLen,
+ final byte[] pOutput,
+ final int pOutOffset) throws DataLengthException
+ {
+ /* Check that we have initialised */
+ checkStatus(pLen);
+
+ /* Check input buffer */
+ checkBuffer(pData, pOffset, pLen, false);
+
+ /* Store the data */
+ if (forEncryption)
+ {
+ thePlain.write(pData, pOffset, pLen);
+ theDataHasher.updateHash(pData, pOffset, pLen);
+ }
+ else
+ {
+ theEncData.write(pData, pOffset, pLen);
+ }
+
+ /* No data returned */
+ return 0;
+ }
+
+ public int doFinal(final byte[] pOutput,
+ final int pOffset) throws IllegalStateException, InvalidCipherTextException
+ {
+ /* Check that we have initialised */
+ checkStatus(0);
+
+ /* Check output buffer */
+ checkBuffer(pOutput, pOffset, getOutputSize(0), true);
+
+ /* If we are encrypting */
+ if (forEncryption)
+ {
+ /* Derive the tag */
+ final byte[] myTag = calculateTag();
+
+ /* encrypt the plain text */
+ final int myDataLen = BUFLEN + encryptPlain(myTag, pOutput, pOffset);
+
+ /* Add the tag to the output */
+ System.arraycopy(myTag, 0, pOutput, pOffset + thePlain.size(), BUFLEN);
+
+ System.arraycopy(myTag, 0, macBlock, 0, macBlock.length);
+
+ /* Reset the streams */
+ resetStreams();
+ return myDataLen;
+
+ /* else we are decrypting */
+ }
+ else
+ {
+ /* decrypt to plain text */
+ decryptPlain();
+
+ /* Release plain text */
+ final int myDataLen = thePlain.size();
+ final byte[] mySrc = thePlain.getBuffer();
+ System.arraycopy(mySrc, 0, pOutput, pOffset, myDataLen);
+
+ /* Reset the streams */
+ resetStreams();
+ return myDataLen;
+ }
+ }
+
+ public byte[] getMac()
+ {
+ return Arrays.clone(macBlock);
+ }
+
+ public int getUpdateOutputSize(final int pLen)
+ {
+ return 0;
+ }
+
+ public int getOutputSize(final int pLen)
+ {
+ if (forEncryption)
+ {
+ return pLen + thePlain.size() + BUFLEN;
+ }
+ final int myCurr = pLen + theEncData.size();
+ return myCurr > BUFLEN ? myCurr - BUFLEN : 0;
+ }
+
+ public void reset()
+ {
+ resetStreams();
+ }
+
+ /**
+ * Reset Streams.
+ */
+ private void resetStreams()
+ {
+ /* Clear the plainText buffer */
+ if (thePlain != null)
+ {
+ thePlain.clearBuffer();
+ }
+
+ /* Reset hashers */
+ theAEADHasher.reset();
+ theDataHasher.reset();
+
+ /* Recreate streams (to release memory) */
+ thePlain = new GCMSIVCache();
+ theEncData = forEncryption ? null : new GCMSIVCache();
+
+ /* Initialise AEAD if required */
+ theFlags &= ~AEAD_COMPLETE;
+ Arrays.fill(theGHash, (byte) 0);
+ if (theInitialAEAD != null)
+ {
+ theAEADHasher.updateHash(theInitialAEAD, 0, theInitialAEAD.length);
+ }
+ }
+
+ /**
+ * Obtain buffer length (allowing for null).
+ * @param pBuffer the buffere
+ * @return the length
+ */
+ private static int bufLength(final byte[] pBuffer)
+ {
+ return pBuffer == null ? 0 : pBuffer.length;
+ }
+
+ /**
+ * Check buffer.
+ * @param pBuffer the buffer
+ * @param pOffset the offset
+ * @param pLen the length
+ * @param pOutput is this an output buffer?
+ */
+ private static void checkBuffer(final byte[] pBuffer,
+ final int pOffset,
+ final int pLen,
+ final boolean pOutput)
+ {
+ /* Access lengths */
+ final int myBufLen = bufLength(pBuffer);
+ final int myLast = pOffset + pLen;
+
+ /* Check for negative values and buffer overflow */
+ final boolean badLen = pLen < 0 || pOffset < 0 || myLast < 0;
+ if (badLen || myLast > myBufLen)
+ {
+ throw pOutput
+ ? new OutputLengthException("Output buffer too short.")
+ : new DataLengthException("Input buffer too short.");
+ }
+ }
+
+ /**
+ * encrypt data stream.
+ * @param pCounter the counter
+ * @param pTarget the target buffer
+ * @param pOffset the target offset
+ * @return the length of data encrypted
+ */
+ private int encryptPlain(final byte[] pCounter,
+ final byte[] pTarget,
+ final int pOffset)
+ {
+ /* Access buffer and length */
+ final byte[] mySrc = thePlain.getBuffer();
+ final byte[] myCounter = Arrays.clone(pCounter);
+ myCounter[BUFLEN - 1] |= MASK;
+ final byte[] myMask = new byte[BUFLEN];
+ int myRemaining = thePlain.size();
+ int myOff = 0;
+
+ /* While we have data to process */
+ while (myRemaining > 0)
+ {
+ /* Generate the next mask */
+ theCipher.processBlock(myCounter, 0, myMask, 0);
+
+ /* Xor data into mask */
+ final int myLen = Math.min(BUFLEN, myRemaining);
+ xorBlock(myMask, mySrc, myOff, myLen);
+
+ /* Copy encrypted data to output */
+ System.arraycopy(myMask, 0, pTarget, pOffset + myOff, myLen);
+
+ /* Adjust counters */
+ myRemaining -= myLen;
+ myOff += myLen;
+ incrementCounter(myCounter);
+ }
+
+ /* Return the amount of data processed */
+ return thePlain.size();
+ }
+
+ /**
+ * decrypt data stream.
+ * @throws InvalidCipherTextException on data too short or mac check failed
+ */
+ private void decryptPlain() throws InvalidCipherTextException
+ {
+ /* Access buffer and length */
+ final byte[] mySrc = theEncData.getBuffer();
+ int myRemaining = theEncData.size() - BUFLEN;
+
+ /* Check for insufficient data */
+ if (myRemaining < 0)
+ {
+ throw new InvalidCipherTextException("Data too short");
+ }
+
+ /* Access counter */
+ final byte[] myExpected = Arrays.copyOfRange(mySrc, myRemaining, myRemaining + BUFLEN);
+ final byte[] myCounter = Arrays.clone(myExpected);
+ myCounter[BUFLEN - 1] |= MASK;
+ final byte[] myMask = new byte[BUFLEN];
+ int myOff = 0;
+
+ /* While we have data to process */
+ while (myRemaining > 0)
+ {
+ /* Generate the next mask */
+ theCipher.processBlock(myCounter, 0, myMask, 0);
+
+ /* Xor data into mask */
+ final int myLen = Math.min(BUFLEN, myRemaining);
+ xorBlock(myMask, mySrc, myOff, myLen);
+
+ /* Write data to plain dataStream */
+ thePlain.write(myMask, 0, myLen);
+ theDataHasher.updateHash(myMask, 0, myLen);
+
+ /* Adjust counters */
+ myRemaining -= myLen;
+ myOff += myLen;
+ incrementCounter(myCounter);
+ }
+
+ /* Derive and check the tag */
+ final byte[] myTag = calculateTag();
+ if (!Arrays.constantTimeAreEqual(myTag, myExpected))
+ {
+ reset();
+ throw new InvalidCipherTextException("mac check failed");
+ }
+
+ System.arraycopy(myTag, 0, macBlock, 0, macBlock.length);
+ }
+
+ /**
+ * calculate tag.
+ * @return the calculated tag
+ */
+ private byte[] calculateTag()
+ {
+ /* Complete the hash */
+ theDataHasher.completeHash();
+ final byte[] myPolyVal = completePolyVal();
+
+ /* calculate polyVal */
+ final byte[] myResult = new byte[BUFLEN];
+
+ /* Fold in the nonce */
+ for (int i = 0; i < NONCELEN; i++)
+ {
+ myPolyVal[i] ^= theNonce[i];
+ }
+
+ /* Clear top bit */
+ myPolyVal[BUFLEN - 1] &= (MASK - 1);
+
+ /* Calculate tag and return it */
+ theCipher.processBlock(myPolyVal, 0, myResult, 0);
+ return myResult;
+ }
+
+ /**
+ * complete polyVAL.
+ * @return the calculated value
+ */
+ private byte[] completePolyVal()
+ {
+ /* Build the polyVal result */
+ final byte[] myResult = new byte[BUFLEN];
+ gHashLengths();
+ fillReverse(theGHash, 0, BUFLEN, myResult);
+ return myResult;
+ }
+
+ /**
+ * process lengths.
+ */
+ private void gHashLengths()
+ {
+ /* Create reversed bigEndian buffer to keep it simple */
+ final byte[] myIn = new byte[BUFLEN];
+ Pack.longToBigEndian(Bytes.SIZE * theDataHasher.getBytesProcessed(), myIn, 0);
+ Pack.longToBigEndian(Bytes.SIZE * theAEADHasher.getBytesProcessed(), myIn, Longs.BYTES);
+
+ /* hash value */
+ gHASH(myIn);
+ }
+
+ /**
+ * perform the next GHASH step.
+ * @param pNext the next value
+ */
+ private void gHASH(final byte[] pNext)
+ {
+ xorBlock(theGHash, pNext);
+ theMultiplier.multiplyH(theGHash);
+ }
+
+ /**
+ * Byte reverse a buffer.
+ * @param pInput the input buffer
+ * @param pOffset the offset
+ * @param pLength the length of data (<= BUFLEN)
+ * @param pOutput the output buffer
+ */
+ private static void fillReverse(final byte[] pInput,
+ final int pOffset,
+ final int pLength,
+ final byte[] pOutput)
+ {
+ /* Loop through the buffer */
+ for (int i = 0, j = BUFLEN - 1; i < pLength; i++, j--)
+ {
+ /* Copy byte */
+ pOutput[j] = pInput[pOffset + i];
+ }
+ }
+
+ /**
+ * xor a full block buffer.
+ * @param pLeft the left operand and result
+ * @param pRight the right operand
+ */
+ private static void xorBlock(final byte[] pLeft,
+ final byte[] pRight)
+ {
+ /* Loop through the bytes */
+ for (int i = 0; i < BUFLEN; i++)
+ {
+ pLeft[i] ^= pRight[i];
+ }
+ }
+
+ /**
+ * xor a partial block buffer.
+ * @param pLeft the left operand and result
+ * @param pRight the right operand
+ * @param pOffset the offset in the right operand
+ * @param pLength the length of data in the right operand
+ */
+ private static void xorBlock(final byte[] pLeft,
+ final byte[] pRight,
+ final int pOffset,
+ final int pLength)
+ {
+ /* Loop through the bytes */
+ for (int i = 0; i < pLength; i++)
+ {
+ pLeft[i] ^= pRight[i + pOffset];
+ }
+ }
+
+ /**
+ * increment the counter.
+ * @param pCounter the counter to increment
+ */
+ private static void incrementCounter(final byte[] pCounter)
+ {
+ /* Loop through the bytes incrementing counter */
+ for (int i = 0; i < Integers.BYTES; i++)
+ {
+ if (++pCounter[i] != 0)
+ {
+ break;
+ }
+ }
+ }
+
+ /**
+ * multiply by X.
+ * @param pValue the value to adjust
+ */
+ private static void mulX(final byte[] pValue)
+ {
+ /* Loop through the bytes */
+ byte myMask = (byte) 0;
+ for (int i = 0; i < BUFLEN; i++)
+ {
+ final byte myValue = pValue[i];
+ pValue[i] = (byte) (((myValue >> 1) & ~MASK) | myMask);
+ myMask = (myValue & 1) == 0 ? 0 : MASK;
+ }
+
+ /* Xor in addition if last bit was set */
+ if (myMask != 0)
+ {
+ pValue[0] ^= ADD;
+ }
+ }
+
+ /**
+ * Derive Keys.
+ * @param pKey the keyGeneration key
+ */
+ private void deriveKeys(final KeyParameter pKey)
+ {
+ /* Create the buffers */
+ final byte[] myIn = new byte[BUFLEN];
+ final byte[] myOut = new byte[BUFLEN];
+ final byte[] myResult = new byte[BUFLEN];
+ final byte[] myEncKey = new byte[pKey.getKeyLength()];
+
+ /* Prepare for encryption */
+ System.arraycopy(theNonce, 0, myIn, BUFLEN - NONCELEN, NONCELEN);
+ theCipher.init(true, pKey);
+
+ /* Derive authentication key */
+ int myOff = 0;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myResult, myOff, HALFBUFLEN);
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myResult, myOff, HALFBUFLEN);
+
+ /* Derive encryption key */
+ myIn[0]++;
+ myOff = 0;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+
+ /* If we have a 32byte key */
+ if (myEncKey.length == BUFLEN << 1)
+ {
+ /* Derive remainder of encryption key */
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+ }
+
+ /* Initialise the Cipher */
+ theCipher.init(true, new KeyParameter(myEncKey));
+
+ /* Initialise the multiplier */
+ fillReverse(myResult, 0, BUFLEN, myOut);
+ mulX(myOut);
+ theMultiplier.init(myOut);
+ theFlags |= INIT;
+ }
+
+ /**
+ * GCMSIVCache.
+ */
+ private static class GCMSIVCache
+ extends ByteArrayOutputStream
+ {
+ /**
+ * Constructor.
+ */
+ GCMSIVCache()
+ {
+ }
+
+ /**
+ * Obtain the buffer.
+ * @return the buffer
+ */
+ byte[] getBuffer()
+ {
+ return this.buf;
+ }
+
+ /**
+ * Clear the buffer.
+ */
+ void clearBuffer()
+ {
+ Arrays.fill(getBuffer(), (byte) 0);
+ }
+ }
+
+ /**
+ * Hash Control.
+ */
+ private class GCMSIVHasher
+ {
+ /**
+ * Cache.
+ */
+ private final byte[] theBuffer = new byte[BUFLEN];
+
+ /**
+ * Single byte cache.
+ */
+ private final byte[] theByte = new byte[1];
+
+ /**
+ * Count of active bytes in cache.
+ */
+ private int numActive;
+
+ /**
+ * Count of hashed bytes.
+ */
+ private long numHashed;
+
+ /**
+ * Obtain the count of bytes hashed.
+ * @return the count
+ */
+ long getBytesProcessed()
+ {
+ return numHashed;
+ }
+
+ /**
+ * Reset the hasher.
+ */
+ void reset()
+ {
+ numActive = 0;
+ numHashed = 0;
+ }
+
+ /**
+ * update hash.
+ * @param pByte the byte
+ */
+ void updateHash(final byte pByte)
+ {
+ theByte[0] = pByte;
+ updateHash(theByte, 0, 1);
+ }
+
+ /**
+ * update hash.
+ * @param pBuffer the buffer
+ * @param pOffset the offset within the buffer
+ * @param pLen the length of data
+ */
+ void updateHash(final byte[] pBuffer,
+ final int pOffset,
+ final int pLen)
+ {
+ /* If we should process the cache */
+ final int mySpace = BUFLEN - numActive;
+ int numProcessed = 0;
+ int myRemaining = pLen;
+ if (numActive > 0
+ && pLen >= mySpace)
+ {
+ /* Copy data into the cache and hash it */
+ System.arraycopy(pBuffer, pOffset, theBuffer, numActive, mySpace);
+ fillReverse(theBuffer, 0, BUFLEN, theReverse);
+ gHASH(theReverse);
+
+ /* Adjust counters */
+ numProcessed += mySpace;
+ myRemaining -= mySpace;
+ numActive = 0;
+ }
+
+ /* While we have full blocks */
+ while (myRemaining >= BUFLEN)
+ {
+ /* Access the next data */
+ fillReverse(pBuffer, pOffset + numProcessed, BUFLEN, theReverse);
+ gHASH(theReverse);
+
+ /* Adjust counters */
+ numProcessed += BUFLEN;
+ myRemaining -= BUFLEN;
+ }
+
+ /* If we have remaining data */
+ if (myRemaining > 0)
+ {
+ /* Copy data into the cache */
+ System.arraycopy(pBuffer, pOffset + numProcessed, theBuffer, numActive, myRemaining);
+ numActive += myRemaining;
+ }
+
+ /* Adjust the number of bytes processed */
+ numHashed += pLen;
+ }
+
+ /**
+ * complete hash.
+ */
+ void completeHash()
+ {
+ /* If we have remaining data */
+ if (numActive > 0)
+ {
+ /* Access the next data */
+ Arrays.fill(theReverse, (byte) 0);
+ fillReverse(theBuffer, 0, numActive, theReverse);
+
+ /* hash value */
+ gHASH(theReverse);
+ }
+ }
+ }
+ }
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 ae4256f..8b20136 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java
@@ -3,7 +3,7 @@
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
-import org.bouncycastle.crypto.SkippingStreamCipher;
+import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.StreamBlockCipher;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.Arrays;
@@ -15,7 +15,7 @@
*/
public class SICBlockCipher
extends StreamBlockCipher
- implements SkippingStreamCipher
+ implements CTRModeCipher
{
private final BlockCipher cipher;
private final int blockSize;
@@ -26,9 +26,20 @@
private int byteCount;
/**
+ * Return a new SIC/CTR mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the SIC/CTR mode.
+ */
+ public static CTRModeCipher newInstance(BlockCipher cipher)
+ {
+ return new SICBlockCipher(cipher);
+ }
+
+ /**
* Basic constructor.
*
* @param c the block cipher to be used.
+ * @deprecated use newInstance() method.
*/
public SICBlockCipher(BlockCipher c)
{
@@ -91,16 +102,75 @@
public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
throws DataLengthException, IllegalStateException
{
- processBytes(in, inOff, blockSize, out, outOff);
+ if (byteCount != 0)
+ {
+ processBytes(in, inOff, blockSize, out, outOff);
+ return blockSize;
+ }
+ if (inOff + blockSize > in.length)
+ {
+ throw new DataLengthException("input buffer too small");
+ }
+ if (outOff + blockSize > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ cipher.processBlock(counter, 0, counterOut, 0);
+ for (int i = 0; i < blockSize; ++i)
+ {
+ out[outOff + i] = (byte)(in[inOff + i] ^ counterOut[i]);
+ }
+ incrementCounter();
return blockSize;
}
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ if (inOff + len > in.length)
+ {
+ throw new DataLengthException("input buffer too small");
+ }
+ if (outOff + len > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ for (int i = 0; i < len; ++i)
+ {
+ byte next;
+
+ if (byteCount == 0)
+ {
+ checkLastIncrement();
+
+ cipher.processBlock(counter, 0, counterOut, 0);
+ next = (byte)(in[inOff + i] ^ counterOut[byteCount++]);
+ }
+ else
+ {
+ next = (byte)(in[inOff + i] ^ counterOut[byteCount++]);
+ if (byteCount == counter.length)
+ {
+ byteCount = 0;
+ incrementCounter();
+ }
+ }
+ out[outOff + i] = next;
+ }
+
+ return len;
+ }
+
protected byte calculateByte(byte in)
throws DataLengthException, IllegalStateException
{
if (byteCount == 0)
{
+ checkLastIncrement();
+
cipher.processBlock(counter, 0, counterOut, 0);
return (byte)(counterOut[byteCount++] ^ in);
@@ -111,10 +181,7 @@
if (byteCount == counter.length)
{
byteCount = 0;
-
- incrementCounterAt(0);
-
- checkCounter();
+ incrementCounter();
}
return rv;
@@ -125,7 +192,7 @@
// if the IV is the same as the blocksize we assume the user knows what they are doing
if (IV.length < blockSize)
{
- for (int i = 0; i != IV.length; i++)
+ for (int i = IV.length - 1; i >= 0; i--)
{
if (counter[i] != IV[i])
{
@@ -135,6 +202,30 @@
}
}
+ private void checkLastIncrement()
+ {
+ // if the IV is the same as the blocksize we assume the user knows what they are doing
+ if (IV.length < blockSize)
+ {
+ if (counter[IV.length - 1] != IV[IV.length - 1])
+ {
+ throw new IllegalStateException("Counter in CTR/SIC mode out of range.");
+ }
+ }
+ }
+
+ private void incrementCounter()
+ {
+ int i = counter.length;
+ while (--i >= 0)
+ {
+ if (++counter[i] != 0)
+ {
+ break;
+ }
+ }
+ }
+
private void incrementCounterAt(int pos)
{
int i = counter.length - pos;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java
index 7316a04..5fdeded 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java
@@ -1,7 +1,5 @@
package org.bouncycastle.crypto.modes.gcm;
-import org.bouncycastle.util.Arrays;
-
public class BasicGCMExponentiator
implements GCMExponentiator
{
@@ -19,7 +17,9 @@
if (pow > 0)
{
- long[] powX = Arrays.clone(x);
+ long[] powX = new long[GCMUtil.SIZE_LONGS];
+ GCMUtil.copy(x, powX);
+
do
{
if ((pow & 1L) != 0)
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
index 4d13820..d7c4ef8 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
@@ -6,76 +6,119 @@
public abstract class GCMUtil
{
+ public static final int SIZE_BYTES = 16;
+ public static final int SIZE_INTS = 4;
+ public static final int SIZE_LONGS = 2;
+
private static final int E1 = 0xe1000000;
private static final long E1L = (E1 & 0xFFFFFFFFL) << 32;
public static byte[] oneAsBytes()
{
- byte[] tmp = new byte[16];
+ byte[] tmp = new byte[SIZE_BYTES];
tmp[0] = (byte)0x80;
return tmp;
}
public static int[] oneAsInts()
{
- int[] tmp = new int[4];
+ int[] tmp = new int[SIZE_INTS];
tmp[0] = 1 << 31;
return tmp;
}
public static long[] oneAsLongs()
{
- long[] tmp = new long[2];
+ long[] tmp = new long[SIZE_LONGS];
tmp[0] = 1L << 63;
return tmp;
}
+ public static byte areEqual(byte[] x, byte[] y)
+ {
+ int d = 0;
+ for (int i = 0; i < SIZE_BYTES; ++i)
+ {
+ d |= x[i] ^ y[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (byte)((d - 1) >> 31);
+ }
+
+ public static int areEqual(int[] x, int[] y)
+ {
+ int d = 0;
+ d |= x[0] ^ y[0];
+ d |= x[1] ^ y[1];
+ d |= x[2] ^ y[2];
+ d |= x[3] ^ y[3];
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static long areEqual(long[] x, long[] y)
+ {
+ long d = 0L;
+ d |= x[0] ^ y[0];
+ d |= x[1] ^ y[1];
+ d = (d >>> 1) | (d & 1L);
+ return (d - 1L) >> 63;
+ }
+
public static byte[] asBytes(int[] x)
{
- byte[] z = new byte[16];
- Pack.intToBigEndian(x, z, 0);
+ byte[] z = new byte[SIZE_BYTES];
+ Pack.intToBigEndian(x, 0, SIZE_INTS, z, 0);
return z;
}
public static void asBytes(int[] x, byte[] z)
{
- Pack.intToBigEndian(x, z, 0);
+ Pack.intToBigEndian(x, 0, SIZE_INTS, z, 0);
}
public static byte[] asBytes(long[] x)
{
- byte[] z = new byte[16];
- Pack.longToBigEndian(x, z, 0);
+ byte[] z = new byte[SIZE_BYTES];
+ Pack.longToBigEndian(x, 0, SIZE_LONGS, z, 0);
return z;
}
public static void asBytes(long[] x, byte[] z)
{
- Pack.longToBigEndian(x, z, 0);
+ Pack.longToBigEndian(x, 0, SIZE_LONGS, z, 0);
}
public static int[] asInts(byte[] x)
{
- int[] z = new int[4];
- Pack.bigEndianToInt(x, 0, z);
+ int[] z = new int[SIZE_INTS];
+ Pack.bigEndianToInt(x, 0, z, 0, SIZE_INTS);
return z;
}
public static void asInts(byte[] x, int[] z)
{
- Pack.bigEndianToInt(x, 0, z);
+ Pack.bigEndianToInt(x, 0, z, 0, SIZE_INTS);
}
public static long[] asLongs(byte[] x)
{
- long[] z = new long[2];
- Pack.bigEndianToLong(x, 0, z);
+ long[] z = new long[SIZE_LONGS];
+ Pack.bigEndianToLong(x, 0, z, 0, SIZE_LONGS);
return z;
}
public static void asLongs(byte[] x, long[] z)
{
- Pack.bigEndianToLong(x, 0, z);
+ Pack.bigEndianToLong(x, 0, z, 0, SIZE_LONGS);
+ }
+
+ public static void copy(byte[] x, byte[] z)
+ {
+ for (int i = 0; i < SIZE_BYTES; ++i)
+ {
+ z[i] = x[i];
+ }
}
public static void copy(int[] x, int[] z)
@@ -103,10 +146,48 @@
public static void multiply(byte[] x, byte[] y)
{
- long[] t1 = GCMUtil.asLongs(x);
- long[] t2 = GCMUtil.asLongs(y);
- GCMUtil.multiply(t1, t2);
- GCMUtil.asBytes(t1, x);
+ long[] t1 = asLongs(x);
+ long[] t2 = asLongs(y);
+ multiply(t1, t2);
+ asBytes(t1, x);
+ }
+
+ static void multiply(byte[] x, long[] y)
+ {
+ /*
+ * "Three-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
+ *
+ * Without access to the high part of a 64x64 product x * y, we use a bit reversal to calculate it:
+ * rev(x) * rev(y) == rev((x * y) << 1)
+ */
+
+ long x0 = Pack.bigEndianToLong(x, 0);
+ long x1 = Pack.bigEndianToLong(x, 8);
+ long y0 = y[0], y1 = y[1];
+ long x0r = Longs.reverse(x0), x1r = Longs.reverse(x1);
+ long y0r = Longs.reverse(y0), y1r = Longs.reverse(y1);
+
+ long h0 = Longs.reverse(implMul64(x0r, y0r));
+ long h1 = implMul64(x0, y0) << 1;
+ long h2 = Longs.reverse(implMul64(x1r, y1r));
+ long h3 = implMul64(x1, y1) << 1;
+ long h4 = Longs.reverse(implMul64(x0r ^ x1r, y0r ^ y1r));
+ long h5 = implMul64(x0 ^ x1, y0 ^ y1) << 1;
+
+ long z0 = h0;
+ long z1 = h1 ^ h0 ^ h2 ^ h4;
+ long z2 = h2 ^ h1 ^ h3 ^ h5;
+ long z3 = h3;
+
+ z1 ^= z3 ^ (z3 >>> 1) ^ (z3 >>> 2) ^ (z3 >>> 7);
+// z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57);
+ z2 ^= (z3 << 62) ^ (z3 << 57);
+
+ z0 ^= z2 ^ (z2 >>> 1) ^ (z2 >>> 2) ^ (z2 >>> 7);
+ z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
+
+ Pack.longToBigEndian(z0, x, 0);
+ Pack.longToBigEndian(z1, x, 8);
}
public static void multiply(int[] x, int[] y)
@@ -114,7 +195,7 @@
int y0 = y[0], y1 = y[1], y2 = y[2], y3 = y[3];
int z0 = 0, z1 = 0, z2 = 0, z3 = 0;
- for (int i = 0; i < 4; ++i)
+ for (int i = 0; i < SIZE_INTS; ++i)
{
int bits = x[i];
for (int j = 0; j < 32; ++j)
@@ -297,16 +378,24 @@
y[1] = (x1 >>> 8) | (x0 << 56);
}
+ public static void multiplyP16(long[] x)
+ {
+ long x0 = x[0], x1 = x[1];
+ long c = x1 << 48;
+ x[0] = (x0 >>> 16) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
+ x[1] = (x1 >>> 16) | (x0 << 48);
+ }
+
public static long[] pAsLongs()
{
- long[] tmp = new long[2];
+ long[] tmp = new long[SIZE_LONGS];
tmp[0] = 1L << 62;
return tmp;
}
public static void square(long[] x, long[] z)
{
- long[] t = new long[4];
+ long[] t = new long[SIZE_LONGS * 2];
Interleave.expand64To128Rev(x[0], t, 0);
Interleave.expand64To128Rev(x[1], t, 2);
@@ -332,7 +421,7 @@
x[i] ^= y[i]; ++i;
x[i] ^= y[i]; ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(byte[] x, byte[] y, int yOff)
@@ -345,7 +434,7 @@
x[i] ^= y[yOff + i]; ++i;
x[i] ^= y[yOff + i]; ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff)
@@ -358,7 +447,7 @@
z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(byte[] x, byte[] y, int yOff, int yLen)
@@ -387,7 +476,7 @@
z[i] = (byte)(x[i] ^ y[i]); ++i;
z[i] = (byte)(x[i] ^ y[i]); ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(int[] x, int[] y)
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
index b8766bd..1a22a04 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java
@@ -1,26 +1,25 @@
package org.bouncycastle.crypto.modes.gcm;
-import java.util.Vector;
-
-import org.bouncycastle.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
public class Tables1kGCMExponentiator
implements GCMExponentiator
{
// A lookup table of the power-of-two powers of 'x'
// - lookupPowX2[i] = x^(2^i)
- private Vector lookupPowX2;
+ private List lookupPowX2;
public void init(byte[] x)
{
long[] y = GCMUtil.asLongs(x);
- if (lookupPowX2 != null && Arrays.areEqual(y, (long[])lookupPowX2.elementAt(0)))
+ if (lookupPowX2 != null && 0L != GCMUtil.areEqual(y, (long[])lookupPowX2.get(0)))
{
return;
}
- lookupPowX2 = new Vector(8);
- lookupPowX2.addElement(y);
+ lookupPowX2 = new ArrayList(8);
+ lookupPowX2.add(y);
}
public void exponentiateX(long pow, byte[] output)
@@ -31,8 +30,7 @@
{
if ((pow & 1L) != 0)
{
- ensureAvailable(bit);
- GCMUtil.multiply(y, (long[])lookupPowX2.elementAt(bit));
+ GCMUtil.multiply(y, getPowX2(bit));
}
++bit;
pow >>>= 1;
@@ -41,19 +39,22 @@
GCMUtil.asBytes(y, output);
}
- private void ensureAvailable(int bit)
+ private long[] getPowX2(int bit)
{
- int count = lookupPowX2.size();
- if (count <= bit)
+ int last = lookupPowX2.size() - 1;
+ if (last < bit)
{
- long[] tmp = (long[])lookupPowX2.elementAt(count - 1);
+ long[] prev = (long[])lookupPowX2.get(last);
do
{
- tmp = Arrays.clone(tmp);
- GCMUtil.square(tmp, tmp);
- lookupPowX2.addElement(tmp);
+ long[] next = new long[GCMUtil.SIZE_LONGS];
+ GCMUtil.square(prev, next);
+ lookupPowX2.add(next);
+ prev = next;
}
- while (++count <= bit);
+ while (++last < bit);
}
+
+ return (long[])lookupPowX2.get(bit);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java
index e5ea748..760c8e2 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java
@@ -1,6 +1,5 @@
package org.bouncycastle.crypto.modes.gcm;
-import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Pack;
public class Tables4kGCMMultiplier
@@ -15,12 +14,13 @@
{
T = new long[256][2];
}
- else if (Arrays.areEqual(this.H, H))
+ else if (0 != GCMUtil.areEqual(this.H, H))
{
return;
}
- this.H = Arrays.clone(H);
+ this.H = new byte[GCMUtil.SIZE_BYTES];
+ GCMUtil.copy(H, this.H);
// T[0] = 0
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 6c3ae26..e2061ea 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,6 +1,5 @@
package org.bouncycastle.crypto.modes.gcm;
-import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Pack;
public class Tables8kGCMMultiplier
@@ -13,16 +12,17 @@
{
if (T == null)
{
- T = new long[32][16][2];
+ T = new long[2][256][2];
}
- else if (Arrays.areEqual(this.H, H))
+ else if (0 != GCMUtil.areEqual(this.H, H))
{
return;
}
- this.H = Arrays.clone(H);
+ this.H = new byte[GCMUtil.SIZE_BYTES];
+ GCMUtil.copy(H, this.H);
- for (int i = 0; i < 32; ++i)
+ for (int i = 0; i < 2; ++i)
{
long[][] t = T[i];
@@ -30,17 +30,17 @@
if (i == 0)
{
- // t[1] = H.p^3
+ // t[1] = H.p^7
GCMUtil.asLongs(this.H, t[1]);
- GCMUtil.multiplyP3(t[1], t[1]);
+ GCMUtil.multiplyP7(t[1], t[1]);
}
else
{
- // t[1] = T[i-1][1].p^4
- GCMUtil.multiplyP4(T[i - 1][1], t[1]);
+ // t[1] = T[i-1][1].p^8
+ GCMUtil.multiplyP8(T[i - 1][1], t[1]);
}
- for (int n = 2; n < 16; n += 2)
+ for (int n = 2; n < 256; n += 2)
{
// t[2.n] = t[n].p^-1
GCMUtil.divideP(t[n >> 1], t[n]);
@@ -49,28 +49,33 @@
GCMUtil.xor(t[n], t[1], t[n + 1]);
}
}
-
}
public void multiplyH(byte[] x)
{
+ long[][] T0 = T[0], T1 = T[1];
+
// long[] z = new long[2];
-// for (int i = 15; i >= 0; --i)
+// for (int i = 14; i >= 0; i -= 2)
// {
-// GCMUtil.xor(z, T[i + i + 1][(x[i] & 0x0F)]);
-// GCMUtil.xor(z, T[i + i ][(x[i] & 0xF0) >>> 4]);
+// GCMUtil.multiplyP16(z);
+// GCMUtil.xor(z, T0[x[i] & 0xFF]);
+// GCMUtil.xor(z, T1[x[i + 1] & 0xFF]);
// }
// Pack.longToBigEndian(z, x, 0);
- long z0 = 0, z1 = 0;
+ long[] u = T0[x[14] & 0xFF];
+ long[] v = T1[x[15] & 0xFF];
+ long z0 = u[0] ^ v[0], z1 = u[1] ^ v[1];
- for (int i = 15; i >= 0; --i)
+ for (int i = 12; i >= 0; i -= 2)
{
- long[] u = T[i + i + 1][(x[i] & 0x0F)];
- long[] v = T[i + i ][(x[i] & 0xF0) >>> 4];
+ u = T0[x[i] & 0xFF];
+ v = T1[x[i + 1] & 0xFF];
- z0 ^= u[0] ^ v[0];
- z1 ^= u[1] ^ v[1];
+ long c = z1 << 48;
+ z1 = u[1] ^ v[1] ^ ((z1 >>> 16) | (z0 << 48));
+ z0 = u[0] ^ v[0] ^ (z0 >>> 16) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
}
Pack.longToBigEndian(z0, x, 0);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
index 0ad1e38..ff2f375 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
@@ -61,9 +61,11 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in[in.length - 1] & 0xff;
+ int count = in[in.length - 1] & 0xFF;
+ int position = in.length - count;
- if (count > in.length)
+ int failed = (position | (count - 1)) >> 31;
+ if (failed != 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java
index 54c31a9..716dfe7 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java
@@ -60,18 +60,20 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in.length - 1;
-
- while (count > 0 && in[count] == 0)
+ int position = -1, still00Mask = -1;
+ int i = in.length;
+ while (--i >= 0)
{
- count--;
+ int next = in[i] & 0xFF;
+ int match00Mask = ((next ^ 0x00) - 1) >> 31;
+ int match80Mask = ((next ^ 0x80) - 1) >> 31;
+ position ^= (i ^ position) & (still00Mask & match80Mask);
+ still00Mask &= match00Mask;
}
-
- if (in[count] != (byte)0x80)
+ if (position < 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
-
- return in.length - count;
+ return in.length - position;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PKCS7Padding.java b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PKCS7Padding.java
index 8b30398..e1e4b52 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PKCS7Padding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PKCS7Padding.java
@@ -56,18 +56,16 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in[in.length - 1] & 0xff;
- byte countAsbyte = (byte)count;
+ byte countAsByte = in[in.length - 1];
+ int count = countAsByte & 0xFF;
+ int position = in.length - count;
- // constant time version
- boolean failed = (count > in.length | count == 0);
-
- for (int i = 0; i < in.length; i++)
+ int failed = (position | (count - 1)) >> 31;
+ for (int i = 0; i < in.length; ++i)
{
- failed |= (in.length - i <= count) & (in[i] != countAsbyte);
+ failed |= (in[i] ^ countAsByte) & ~((i - position) >> 31);
}
-
- if (failed)
+ if (failed != 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
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 d5928f7..28ec78b 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java
@@ -1,9 +1,9 @@
package org.bouncycastle.crypto.paddings;
import org.bouncycastle.crypto.BlockCipher;
-import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.params.ParametersWithRandom;
@@ -16,7 +16,7 @@
* The default padding mechanism used is the one outlined in PKCS5/PKCS7.
*/
public class PaddedBufferedBlockCipher
- extends BufferedBlockCipher
+ extends DefaultBufferedBlockCipher
{
BlockCipherPadding padding;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/TBCPadding.java b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/TBCPadding.java
index 219912f..90975a0 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/TBCPadding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/TBCPadding.java
@@ -76,14 +76,15 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- byte code = in[in.length - 1];
-
- int index = in.length - 1;
- while (index > 0 && in[index - 1] == code)
+ int i = in.length;
+ int code = in[--i] & 0xFF, count = 1, countingMask = -1;
+ while (--i >= 0)
{
- index--;
+ int next = in[i] & 0xFF;
+ int matchMask = ((next ^ code) - 1) >> 31;
+ countingMask &= matchMask;
+ count -= countingMask;
}
-
- return in.length - index;
+ return count;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/X923Padding.java b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/X923Padding.java
index d4d34aa..cf960e3 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/X923Padding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/X923Padding.java
@@ -68,9 +68,11 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in[in.length - 1] & 0xff;
+ int count = in[in.length - 1] & 0xFF;
+ int position = in.length - count;
- if (count > in.length)
+ int failed = (position | (count - 1)) >> 31;
+ if (failed != 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ZeroBytePadding.java b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ZeroBytePadding.java
index c756028..908ce19 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ZeroBytePadding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ZeroBytePadding.java
@@ -56,18 +56,15 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in.length;
-
- while (count > 0)
+ int count = 0, still00Mask = -1;
+ int i = in.length;
+ while (--i >= 0)
{
- if (in[count - 1] != 0)
- {
- break;
- }
-
- count--;
+ int next = in[i] & 0xFF;
+ int match00Mask = ((next ^ 0x00) - 1) >> 31;
+ still00Mask &= match00Mask;
+ count -= still00Mask;
}
-
- return in.length - count;
+ return count;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/Blake3Parameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/Blake3Parameters.java
new file mode 100644
index 0000000..e0e4000
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/Blake3Parameters.java
@@ -0,0 +1,84 @@
+package org.bouncycastle.crypto.params;
+
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.util.Arrays;
+
+/**
+ * Blake3 Parameters.
+ */
+public class Blake3Parameters
+ implements CipherParameters
+{
+ /**
+ * The key length.
+ */
+ private static final int KEYLEN = 32;
+
+ /**
+ * The key.
+ */
+ private byte[] theKey;
+
+ /**
+ * The context.
+ */
+ private byte[] theContext;
+
+ /**
+ * Create a key parameter.
+ * @param pContext the context
+ * @return the parameter
+ */
+ public static Blake3Parameters context(final byte[] pContext)
+ {
+ if (pContext == null)
+ {
+ throw new IllegalArgumentException("Invalid context");
+ }
+ final Blake3Parameters myParams = new Blake3Parameters();
+ myParams.theContext = Arrays.clone(pContext);
+ return myParams;
+ }
+
+ /**
+ * Create a key parameter.
+ * @param pKey the key
+ * @return the parameter
+ */
+ public static Blake3Parameters key(final byte[] pKey)
+ {
+ if (pKey == null || pKey.length != KEYLEN)
+ {
+ throw new IllegalArgumentException("Invalid keyLength");
+ }
+ final Blake3Parameters myParams = new Blake3Parameters();
+ myParams.theKey = Arrays.clone(pKey);
+ return myParams;
+ }
+
+ /**
+ * Obtain the key.
+ * @return the key
+ */
+ public byte[] getKey()
+ {
+ return Arrays.clone(theKey);
+ }
+
+ /**
+ * Clear the key bytes.
+ */
+ public void clearKey()
+ {
+ Arrays.fill(theKey, (byte) 0);
+ }
+
+ /**
+ * Obtain the salt.
+ * @return the salt
+ */
+ public byte[] getContext()
+ {
+ return Arrays.clone(theContext);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/FPEParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/FPEParameters.java
new file mode 100644
index 0000000..e5357a1
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/FPEParameters.java
@@ -0,0 +1,57 @@
+package org.bouncycastle.crypto.params;
+
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.util.RadixConverter;
+import org.bouncycastle.util.Arrays;
+
+public final class FPEParameters
+ implements CipherParameters
+{
+ private final KeyParameter key;
+ private final RadixConverter radixConverter;
+ private final byte[] tweak;
+ private final boolean useInverse;
+
+ public FPEParameters(KeyParameter key, int radix, byte[] tweak)
+ {
+ this(key, radix, tweak, false);
+ }
+
+ public FPEParameters(KeyParameter key, int radix, byte[] tweak, boolean useInverse)
+ {
+ this(key, new RadixConverter(radix), tweak, useInverse);
+ }
+
+ public FPEParameters(KeyParameter key, RadixConverter radixConverter, byte[] tweak, boolean useInverse)
+ {
+ this.key = key;
+ this.radixConverter = radixConverter;
+ this.tweak = Arrays.clone(tweak);
+ this.useInverse = useInverse;
+ }
+
+ public KeyParameter getKey()
+ {
+ return key;
+ }
+
+ public int getRadix()
+ {
+ return radixConverter.getRadix();
+ }
+
+ public RadixConverter getRadixConverter()
+ {
+ return radixConverter;
+ }
+
+ public byte[] getTweak()
+ {
+ return Arrays.clone(tweak);
+ }
+
+ public boolean isUsingInverseFunction()
+ {
+ return useInverse;
+ }
+}
\ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java
index 5c4fe0e..e163995 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java
@@ -1,6 +1,7 @@
package org.bouncycastle.crypto.params;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.util.Arrays;
public class KeyParameter
implements CipherParameters
@@ -18,13 +19,38 @@
int keyOff,
int keyLen)
{
- this.key = new byte[keyLen];
+ this(keyLen);
System.arraycopy(key, keyOff, this.key, 0, keyLen);
}
+ private KeyParameter(int length)
+ {
+ this.key = new byte[length];
+ }
+
+ public void copyTo(byte[] buf, int off, int len)
+ {
+ if (key.length != len)
+ throw new IllegalArgumentException("len");
+
+ System.arraycopy(key, 0, buf, off, len);
+ }
+
public byte[] getKey()
{
return key;
}
+
+ public int getKeyLength()
+ {
+ return key.length;
+ }
+
+ public KeyParameter reverse()
+ {
+ KeyParameter reversed = new KeyParameter(key.length);
+ Arrays.reverse(this.key, reversed.key);
+ return reversed;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java
index 911f200..65b0b84 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java
@@ -2,11 +2,16 @@
import java.math.BigInteger;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
+import org.bouncycastle.math.Primes;
+import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.Properties;
public class RSAKeyParameters
extends AsymmetricKeyParameter
{
+ private static final BigIntegers.Cache validated = new BigIntegers.Cache();
+
// Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
"8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
@@ -25,6 +30,15 @@
BigInteger modulus,
BigInteger exponent)
{
+ this(isPrivate, modulus, exponent, false);
+ }
+
+ public RSAKeyParameters(
+ boolean isPrivate,
+ BigInteger modulus,
+ BigInteger exponent,
+ boolean isInternal)
+ {
super(isPrivate);
if (!isPrivate)
@@ -34,13 +48,20 @@
throw new IllegalArgumentException("RSA publicExponent is even");
}
}
-
- this.modulus = validate(modulus);
+
+ this.modulus = validated.contains(modulus) ? modulus : validate(modulus, isInternal);
this.exponent = exponent;
- }
+ }
- private BigInteger validate(BigInteger modulus)
+ private BigInteger validate(BigInteger modulus, boolean isInternal)
{
+ if (isInternal)
+ {
+ validated.add(modulus);
+
+ return modulus;
+ }
+
if ((modulus.intValue() & 1) == 0)
{
throw new IllegalArgumentException("RSA modulus is even");
@@ -53,16 +74,45 @@
return modulus;
}
+ int maxBitLength = Properties.asInteger("org.bouncycastle.rsa.max_size", 15360);
+
+ int modBitLength = modulus.bitLength();
+ if (maxBitLength < modBitLength)
+ {
+ throw new IllegalArgumentException("modulus value out of range");
+ }
+
if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE))
{
throw new IllegalArgumentException("RSA modulus has a small prime factor");
}
- // TODO: add additional primePower/Composite test - expensive!!
+ int bits = modulus.bitLength() / 2;
+ int iterations = Properties.asInteger("org.bouncycastle.rsa.max_mr_tests", getMRIterations(bits));
+ if (iterations > 0)
+ {
+ Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), iterations);
+ if (!mr.isProvablyComposite())
+ {
+ throw new IllegalArgumentException("RSA modulus is not composite");
+ }
+ }
+
+ validated.add(modulus);
+
return modulus;
}
+ private static int getMRIterations(int bits)
+ {
+ int iterations = bits >= 1536 ? 3
+ : bits >= 1024 ? 4
+ : bits >= 512 ? 7
+ : 50;
+ return iterations;
+ }
+
public BigInteger getModulus()
{
return modulus;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java
index b61cb5c..612cc09 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java
@@ -16,6 +16,19 @@
*
*/
public RSAPrivateCrtKeyParameters(
+ BigInteger modulus,
+ BigInteger publicExponent,
+ BigInteger privateExponent,
+ BigInteger p,
+ BigInteger q,
+ BigInteger dP,
+ BigInteger dQ,
+ BigInteger qInv)
+ {
+ this(modulus, publicExponent, privateExponent, p, q, dP, dQ, qInv, false);
+ }
+
+ public RSAPrivateCrtKeyParameters(
BigInteger modulus,
BigInteger publicExponent,
BigInteger privateExponent,
@@ -23,9 +36,10 @@
BigInteger q,
BigInteger dP,
BigInteger dQ,
- BigInteger qInv)
+ BigInteger qInv,
+ boolean isInternal)
{
- super(true, modulus, privateExponent);
+ super(true, modulus, privateExponent, isInternal);
this.e = publicExponent;
this.p = p;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java
index 314a096..b84895d 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java
@@ -68,6 +68,8 @@
this.key = (DSAPublicKeyParameters)param;
}
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("DSA", key, forSigning));
+
this.random = initSecureRandom(forSigning && !kCalculator.isDeterministic(), providedRandom);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
index c8f687b..c962d1c 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
@@ -74,6 +74,8 @@
this.key = (ECPublicKeyParameters)param;
}
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("ECDSA", key, forSigning));
+
this.random = initSecureRandom(forSigning && !kCalculator.isDeterministic(), providedRandom);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/Utils.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/Utils.java
new file mode 100644
index 0000000..9f411dc
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/Utils.java
@@ -0,0 +1,40 @@
+package org.bouncycastle.crypto.signers;
+
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServiceProperties;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.constraints.ConstraintUtils;
+import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import org.bouncycastle.crypto.params.DSAKeyParameters;
+import org.bouncycastle.crypto.params.ECKeyParameters;
+// Android-removed: unsupported algorithm
+// import org.bouncycastle.crypto.params.GOST3410KeyParameters;
+
+class Utils
+{
+ static CryptoServiceProperties getDefaultProperties(String algorithm, DSAKeyParameters k, boolean forSigning)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getP()), k, getPurpose(forSigning));
+ }
+
+ // Android-removed: unsupported algorithm
+ // static CryptoServiceProperties getDefaultProperties(String algorithm, GOST3410KeyParameters k, boolean forSigning)
+ // {
+ // return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getP()), k, getPurpose(forSigning));
+ // }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, ECKeyParameters k, boolean forSigning)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getCurve()), k, getPurpose(forSigning));
+ }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, int bitsOfSecurity, CipherParameters k, boolean forSigning)
+ {
+ return new DefaultServiceProperties(algorithm, bitsOfSecurity, k, getPurpose(forSigning));
+ }
+
+ static CryptoServicePurpose getPurpose(boolean forSigning)
+ {
+ return forSigning ? CryptoServicePurpose.SIGNING : CryptoServicePurpose.VERIFYING;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/util/BasicAlphabetMapper.java b/bcprov/src/main/java/org/bouncycastle/crypto/util/BasicAlphabetMapper.java
new file mode 100644
index 0000000..d03cc73
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/BasicAlphabetMapper.java
@@ -0,0 +1,105 @@
+package org.bouncycastle.crypto.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.bouncycastle.crypto.AlphabetMapper;
+
+/**
+ * A basic alphabet mapper that just creates a mapper based on the
+ * passed in array of characters.
+ */
+public class BasicAlphabetMapper
+ implements AlphabetMapper
+{
+ private Map<Character, Integer> indexMap = new HashMap<Character, Integer>();
+ private Map<Integer, Character> charMap = new HashMap<Integer, Character>();
+
+ /**
+ * Base constructor.
+ *
+ * @param alphabet a String of characters making up the alphabet.
+ */
+ public BasicAlphabetMapper(String alphabet)
+ {
+ this(alphabet.toCharArray());
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param alphabet an array of characters making up the alphabet.
+ */
+ public BasicAlphabetMapper(char[] alphabet)
+ {
+ for (int i = 0; i != alphabet.length; i++)
+ {
+ if (indexMap.containsKey(alphabet[i]))
+ {
+ throw new IllegalArgumentException("duplicate key detected in alphabet: " + alphabet[i]);
+ }
+ indexMap.put(alphabet[i], i);
+ charMap.put(i, alphabet[i]);
+ }
+ }
+
+ public int getRadix()
+ {
+ return indexMap.size();
+ }
+
+ public byte[] convertToIndexes(char[] input)
+ {
+ byte[] out;
+
+ if (indexMap.size() <= 256)
+ {
+ out = new byte[input.length];
+ for (int i = 0; i != input.length; i++)
+ {
+ out[i] = indexMap.get(input[i]).byteValue();
+ }
+ }
+ else
+ {
+ out = new byte[input.length * 2];
+ for (int i = 0; i != input.length; i++)
+ {
+ int idx = indexMap.get(input[i]);
+ out[i * 2] = (byte)((idx >> 8) & 0xff);
+ out[i * 2 + 1] = (byte)(idx & 0xff);
+ }
+ }
+
+ return out;
+ }
+
+ public char[] convertToChars(byte[] input)
+ {
+ char[] out;
+
+ if (charMap.size() <= 256)
+ {
+ out = new char[input.length];
+ for (int i = 0; i != input.length; i++)
+ {
+ out[i] = charMap.get(input[i] & 0xff);
+ }
+ }
+ else
+ {
+ if ((input.length & 0x1) != 0)
+ {
+ throw new IllegalArgumentException("two byte radix and input string odd length");
+ }
+
+ out = new char[input.length / 2];
+ for (int i = 0; i != input.length; i += 2)
+ {
+ out[i / 2] = charMap.get(((input[i] << 8) & 0xff00) | (input[i + 1] & 0xff));
+ }
+ }
+
+ return out;
+ }
+}
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 900c6c3..94f2b5c 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java
@@ -68,6 +68,14 @@
public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData)
throws IOException
{
+ if (privateKeyInfoData == null)
+ {
+ throw new IllegalArgumentException("privateKeyInfoData array null");
+ }
+ if (privateKeyInfoData.length == 0)
+ {
+ throw new IllegalArgumentException("privateKeyInfoData array empty");
+ }
return createKey(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(privateKeyInfoData)));
}
@@ -95,6 +103,11 @@
public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo)
throws IOException
{
+ if (keyInfo == null)
+ {
+ throw new IllegalArgumentException("keyInfo argument null");
+ }
+
AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm();
ASN1ObjectIdentifier algOID = algId.getAlgorithm();
@@ -137,12 +150,12 @@
else if (algOID.equals(X9ObjectIdentifiers.id_dsa))
{
ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
- ASN1Encodable de = algId.getParameters();
+ ASN1Encodable algParameters = algId.getParameters();
DSAParameters parameters = null;
- if (de != null)
+ if (algParameters != null)
{
- DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive());
+ DSAParameter params = DSAParameter.getInstance(algParameters.toASN1Primitive());
parameters = new DSAParameters(params.getP(), params.getQ(), params.getG());
}
@@ -182,32 +195,44 @@
/*
else if (algOID.equals(EdECObjectIdentifiers.id_X25519))
{
- return new X25519PrivateKeyParameters(getRawKey(keyInfo, X25519PrivateKeyParameters.KEY_SIZE), 0);
+ // Java 11 bug: exact length of X25519/X448 secret used in Java 11
+ if (X25519PrivateKeyParameters.KEY_SIZE == keyInfo.getPrivateKeyLength())
+ {
+ return new X25519PrivateKeyParameters(keyInfo.getPrivateKey().getOctets());
+ }
+
+ return new X25519PrivateKeyParameters(getRawKey(keyInfo));
}
else if (algOID.equals(EdECObjectIdentifiers.id_X448))
{
- return new X448PrivateKeyParameters(getRawKey(keyInfo, X448PrivateKeyParameters.KEY_SIZE), 0);
+ // Java 11 bug: exact length of X25519/X448 secret used in Java 11
+ if (X448PrivateKeyParameters.KEY_SIZE == keyInfo.getPrivateKeyLength())
+ {
+ return new X448PrivateKeyParameters(keyInfo.getPrivateKey().getOctets());
+ }
+
+ return new X448PrivateKeyParameters(getRawKey(keyInfo));
}
else if (algOID.equals(EdECObjectIdentifiers.id_Ed25519))
{
- return new Ed25519PrivateKeyParameters(getRawKey(keyInfo, Ed25519PrivateKeyParameters.KEY_SIZE), 0);
+ return new Ed25519PrivateKeyParameters(getRawKey(keyInfo));
}
else if (algOID.equals(EdECObjectIdentifiers.id_Ed448))
{
- return new Ed448PrivateKeyParameters(getRawKey(keyInfo, Ed448PrivateKeyParameters.KEY_SIZE), 0);
+ return new Ed448PrivateKeyParameters(getRawKey(keyInfo));
}
else if (
algOID.equals(CryptoProObjectIdentifiers.gostR3410_2001) ||
algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) ||
algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256))
{
- GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters());
+ ASN1Encodable algParameters = algId.getParameters();
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(algParameters);
ECGOST3410Parameters ecSpec = null;
BigInteger d = null;
- ASN1Primitive p = keyInfo.getPrivateKeyAlgorithm().getParameters().toASN1Primitive();
+ ASN1Primitive p = algParameters.toASN1Primitive();
if (p instanceof ASN1Sequence && (ASN1Sequence.getInstance(p).size() == 2 || ASN1Sequence.getInstance(p).size() == 3))
{
-
X9ECParameters ecP = ECGOST3410NamedCurves.getByOIDX9(gostParams.getPublicKeyParamSet());
ecSpec = new ECGOST3410Parameters(
@@ -216,11 +241,12 @@
gostParams.getPublicKeyParamSet(),
gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet());
- ASN1OctetString privEnc = keyInfo.getPrivateKey();
- if (privEnc.getOctets().length == 32 || privEnc.getOctets().length == 64)
+ int privateKeyLength = keyInfo.getPrivateKeyLength();
+
+ if (privateKeyLength == 32 || privateKeyLength == 64)
{
- d = new BigInteger(1, Arrays.reverse(privEnc.getOctets()));
+ d = new BigInteger(1, Arrays.reverse(keyInfo.getPrivateKey().getOctets()));
}
else
{
@@ -238,7 +264,7 @@
}
else
{
- X962Parameters params = X962Parameters.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters());
+ X962Parameters params = X962Parameters.getInstance(algId.getParameters());
if (params.isNamedCurve())
{
@@ -294,14 +320,8 @@
}
}
- private static byte[] getRawKey(PrivateKeyInfo keyInfo, int expectedSize)
- throws IOException
+ private static byte[] getRawKey(PrivateKeyInfo keyInfo) throws IOException
{
- byte[] result = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets();
- if (expectedSize != result.length)
- {
- throw new RuntimeException("private key encoding has incorrect length");
- }
- return result;
+ return ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets();
}
}
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 1a42913..8495cd8 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java
@@ -6,13 +6,13 @@
import java.util.HashMap;
import java.util.Map;
+import org.bouncycastle.asn1.ASN1BitString;
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.DERBitString;
import org.bouncycastle.asn1.DEROctetString;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
@@ -113,6 +113,14 @@
public static AsymmetricKeyParameter createKey(byte[] keyInfoData)
throws IOException
{
+ if (keyInfoData == null)
+ {
+ throw new IllegalArgumentException("keyInfoData array null");
+ }
+ if (keyInfoData.length == 0)
+ {
+ throw new IllegalArgumentException("keyInfoData array empty");
+ }
return createKey(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(keyInfoData)));
}
@@ -139,6 +147,10 @@
public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo)
throws IOException
{
+ if (keyInfo == null)
+ {
+ throw new IllegalArgumentException("keyInfo argument null");
+ }
return createKey(keyInfo, null);
}
@@ -153,6 +165,11 @@
public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Object defaultParams)
throws IOException
{
+ if (keyInfo == null)
+ {
+ throw new IllegalArgumentException("keyInfo argument null");
+ }
+
AlgorithmIdentifier algID = keyInfo.getAlgorithm();
SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algID.getAlgorithm());
@@ -304,7 +321,7 @@
dParams = new ECDomainParameters(x9);
}
- DERBitString bits = keyInfo.getPublicKeyData();
+ ASN1BitString bits = keyInfo.getPublicKeyData();
byte[] data = bits.getBytes();
ASN1OctetString key = new DEROctetString(data);
@@ -481,7 +498,7 @@
}
BigInteger b = new BigInteger(1, b_bytes);
DSTU4145BinaryField field = binary.getField();
- ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), b);
+ ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), b, null, null);
byte[] g_bytes = binary.getG();
if (algOid.equals(UAObjectIdentifiers.dstu4145le))
{
@@ -514,7 +531,7 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new X25519PublicKeyParameters(getRawKey(keyInfo, defaultParams, X25519PublicKeyParameters.KEY_SIZE), 0);
+ return new X25519PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
@@ -523,7 +540,7 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new X448PublicKeyParameters(getRawKey(keyInfo, defaultParams, X448PublicKeyParameters.KEY_SIZE), 0);
+ return new X448PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
@@ -532,7 +549,7 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new Ed25519PublicKeyParameters(getRawKey(keyInfo, defaultParams, Ed25519PublicKeyParameters.KEY_SIZE), 0);
+ return new Ed25519PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
@@ -541,24 +558,19 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new Ed448PublicKeyParameters(getRawKey(keyInfo, defaultParams, Ed448PublicKeyParameters.KEY_SIZE), 0);
+ return new Ed448PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
*/
// END Android-removed: Unsupported algorithms
- private static byte[] getRawKey(SubjectPublicKeyInfo keyInfo, Object defaultParams, int expectedSize)
+ private static byte[] getRawKey(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
/*
* TODO[RFC 8422]
* - Require defaultParams == null?
* - Require keyInfo.getAlgorithm().getParameters() == null?
*/
- byte[] result = keyInfo.getPublicKeyData().getOctets();
- if (expectedSize != result.length)
- {
- throw new RuntimeException("public key encoding has incorrect length");
- }
- return result;
+ return keyInfo.getPublicKeyData().getOctets();
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/util/RadixConverter.java b/bcprov/src/main/java/org/bouncycastle/crypto/util/RadixConverter.java
new file mode 100644
index 0000000..9263dfb
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/RadixConverter.java
@@ -0,0 +1,188 @@
+package org.bouncycastle.crypto.util;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.util.BigIntegers;
+
+/**
+ * Utility class to convert decimal numbers (BigInteger) into a number in the base provided and the other way round.
+ * <p>For an application of this see the FPE parameter classes.</p>
+ */
+public class RadixConverter
+{
+
+ /*
+ The conversions in this class are more complex than the standard ways of converting between basis because we want to improve the performance by limiting the
+ operations on BigInteger which are not very efficient.
+ The general idea is to perform math operations on primitive long as much as we can and just work with BigInteger when necessary.
+ Converting between basis uses the fact that a number in base 'B' have a unique representation in polynomial form.
+
+ num = ... + r8B^8 + r7B^7 + r6B^6 + r5B^5 + r4B^4 + r3B^3 + r2B^2 + r1B + r0
+
+ We can compute how many digits in base 'B' can fit in a long. For example, for a radix R=2^16 the number of digits 'n' that we can fit into a long is the
+ max 'n' that still satisfies: R^n < Long.MAX_VALUE (i.e. 2^63 -1). In this case 'n' is 3. To convert 'num' from its decimal representation to base 'B'
+ representation we can write down 'num' in a polynomial form of B^3:
+
+ num = (((...)B^3 + r8B^2 + r7B + r6)B^3 + r5B^2 + r4B + r3)B^3 + (r2B^2 + r1B + r0)
+
+ B^3 would be our intermediate base. We can convert numbers in base B^3 while operating on primitive long.
+ To convert a decimal num to its representation in base B we can first build its B^3 representation and then figure out the digits in base B from the single
+ digit in base B^3. num % B^3 gives us a single digit in base B^3 which corresponds to a group of 3 digits in base B.
+
+ An equivalent way of writing the polynomial form of num would be:
+
+ num = (...)B^9 + (r8B^8 + r7B^7 + r6B^6)B^6 + (r5B^5 + r4B^4 + r3)B^3 + (r2B^2 + r1B + r0)
+
+ In this form it becomes clear that to obtain 'num' from a sequence of digits, one can group the digits in group of 3 and compute the corresponding decimal
+ number for the group in base B. We can then multiply the decimal numbers by the corresponding power of B^3 and sum up the result to obtain the decimal
+ representation of num in base B,
+ */
+ private static final double LOG_LONG_MAX_VALUE = Math.log(Long.MAX_VALUE);
+ private static final int DEFAULT_POWERS_TO_CACHE = 10;
+ // the max number of digits in base 'radix' that fits in a long
+ private final int digitsGroupLength;
+ // the total number of digits combination in a group. radix ^ digitsGroupLength
+ private final BigInteger digitsGroupSpaceSize;
+ private final int radix;
+ private final BigInteger[] digitsGroupSpacePowers;
+
+ /**
+ * @param radix the radix to use for base conversions
+ * @param numberOfCachedPowers number of intermediate base powers to precompute and cache.
+ */
+ public RadixConverter(int radix, int numberOfCachedPowers)
+ {
+ this.radix = radix;
+ // solves radix^n < Long.MAX_VALUE to find n (maxDigitsFitsInLong)
+ this.digitsGroupLength = (int)Math.floor(LOG_LONG_MAX_VALUE / Math.log(radix));
+ this.digitsGroupSpaceSize = BigInteger.valueOf(radix).pow(digitsGroupLength);
+ this.digitsGroupSpacePowers = precomputeDigitsGroupPowers(numberOfCachedPowers, digitsGroupSpaceSize);
+ }
+
+ /**
+ * @param radix the radix to use for base conversions.
+ */
+ public RadixConverter(int radix)
+ {
+ this(radix, DEFAULT_POWERS_TO_CACHE);
+ }
+
+ public int getRadix()
+ {
+ return radix;
+ }
+
+ public void toEncoding(BigInteger number, int messageLength, short[] out)
+ {
+ if (number.signum() < 0)
+ {
+ throw new IllegalArgumentException();
+ }
+ // convert number into its representation in base 'radix'.
+ // writes leading '0' if the messageLength is greater than the number of digits required to encode in base 'radix'
+ int digitIndex = messageLength - 1;
+ do
+ {
+ if (number.equals(BigInteger.ZERO))
+ {
+ out[digitIndex--] = 0;
+ continue;
+ }
+ BigInteger[] quotientAndRemainder = number.divideAndRemainder(digitsGroupSpaceSize);
+ number = quotientAndRemainder[0];
+ digitIndex = toEncoding(quotientAndRemainder[1].longValue(), digitIndex, out);
+ }
+ while (digitIndex >= 0);
+ if (number.signum() != 0)
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private int toEncoding(long number, int digitIndex, short[] out)
+ {
+ for (int i = 0; i < digitsGroupLength && digitIndex >= 0; i++)
+ {
+ if (number == 0)
+ {
+ out[digitIndex--] = 0;
+ continue;
+ }
+ out[digitIndex--] = (short)(number % radix);
+ number = number / radix;
+ }
+ if (number != 0)
+ {
+ throw new IllegalStateException("Failed to convert decimal number");
+ }
+ return digitIndex;
+ }
+
+ public BigInteger fromEncoding(short[] digits)
+ {
+ // from a sequence of digits in base 'radix' to a decimal number
+ // iterate through groups of digits right to left
+ // digitsGroupLength = 2; digits: [22, 45, 11, 31, 24]
+ // groups are, in order of iteration: [31, 24], [45, 11], [22]
+ BigInteger currentGroupCardinality = BigIntegers.ONE;
+ BigInteger res = null;
+ int indexGroup = 0;
+ int numberOfDigits = digits.length;
+ for (int groupStartDigitIndex = numberOfDigits - digitsGroupLength;
+ groupStartDigitIndex > -digitsGroupLength;
+ groupStartDigitIndex = groupStartDigitIndex - digitsGroupLength)
+ {
+ int actualDigitsInGroup = digitsGroupLength;
+ if (groupStartDigitIndex < 0)
+ {
+ // last group might contain fewer digits so adjust offsets
+ actualDigitsInGroup = digitsGroupLength + groupStartDigitIndex;
+ groupStartDigitIndex = 0;
+ }
+ int groupEndDigitIndex = Math.min(groupStartDigitIndex + actualDigitsInGroup, numberOfDigits);
+ long groupInBaseRadix = fromEncoding(groupStartDigitIndex, groupEndDigitIndex, digits);
+ BigInteger bigInteger = BigInteger.valueOf(groupInBaseRadix);
+ if (indexGroup == 0)
+ {
+ res = bigInteger;
+ }
+ else
+ {
+ currentGroupCardinality =
+ indexGroup <= digitsGroupSpacePowers.length
+ ? digitsGroupSpacePowers[indexGroup - 1]
+ : currentGroupCardinality.multiply(digitsGroupSpaceSize);
+ res = res.add(bigInteger.multiply(currentGroupCardinality));
+ }
+ indexGroup++;
+ }
+ return res;
+ }
+
+ public int getDigitsGroupLength()
+ {
+ return digitsGroupLength;
+ }
+
+ private long fromEncoding(int groupStartDigitIndex, int groupEndDigitIndex, short[] digits)
+ {
+ long decimalNumber = 0;
+ for (int digitIndex = groupStartDigitIndex; digitIndex < groupEndDigitIndex; digitIndex++)
+ {
+ decimalNumber = (decimalNumber * radix) + (digits[digitIndex] & 0xFFFF);
+ }
+ return decimalNumber;
+ }
+
+ private BigInteger[] precomputeDigitsGroupPowers(int numberOfCachedPowers, BigInteger digitsGroupSpaceSize)
+ {
+ BigInteger[] cachedPowers = new BigInteger[numberOfCachedPowers];
+ BigInteger currentPower = digitsGroupSpaceSize;
+ for (int i = 0; i < numberOfCachedPowers; i++)
+ {
+ cachedPowers[i] = currentPower;
+ currentPower = currentPower.multiply(digitsGroupSpaceSize);
+ }
+ return cachedPowers;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/util/SSHNamedCurves.java b/bcprov/src/main/java/org/bouncycastle/crypto/util/SSHNamedCurves.java
index 25d0c6c..e6a0e56 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/util/SSHNamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/SSHNamedCurves.java
@@ -69,8 +69,8 @@
while (e.hasMoreElements())
{
String name = (String)e.nextElement();
- X9ECParameters parameters = CustomNamedCurves.getByName(name);
- put(parameters.getCurve(), name);
+ ECCurve curve = CustomNamedCurves.getByNameLazy(name).getCurve();
+ put(curve, name);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java b/bcprov/src/main/java/org/bouncycastle/internal/asn1/cms/GCMParameters.java
similarity index 90%
rename from bcprov/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java
rename to bcprov/src/main/java/org/bouncycastle/internal/asn1/cms/GCMParameters.java
index 76a98dc..de88211 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/internal/asn1/cms/GCMParameters.java
@@ -1,4 +1,4 @@
-package org.bouncycastle.asn1.cms;
+package org.bouncycastle.internal.asn1.cms;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
@@ -31,8 +31,8 @@
* Accepted inputs:
* <ul>
* <li> null → null
- * <li> {@link org.bouncycastle.asn1.cms.GCMParameters} object
- * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(Object) ASN1Sequence} input formats with GCMParameters structure inside
+ * <li> {@link GCMParameters} object
+ * <li> {@link ASN1Sequence#getInstance(Object) ASN1Sequence} input formats with GCMParameters structure inside
* </ul>
*
* @param obj the object we want converted.
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java
similarity index 95%
rename from bcprov/src/main/java/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java
rename to bcprov/src/main/java/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java
index 6b75fde..aa54635 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java
@@ -1,4 +1,4 @@
-package org.bouncycastle.asn1.isismtt;
+package org.bouncycastle.internal.asn1.isismtt;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -103,8 +103,6 @@
* </pre>
* <p>
* OID: 1.3.36.8.3.8
- *
- * @see org.bouncycastle.asn1.isismtt.x509.Restriction
*/
static final ASN1ObjectIdentifier id_isismtt_at_restriction = id_isismtt_at.branch("8");
@@ -129,8 +127,6 @@
* returned in this extension.
* <p>
* OID: 1.3.36.8.3.10
- *
- * @see org.bouncycastle.asn1.isismtt.ocsp.RequestedCertificate
*/
static final ASN1ObjectIdentifier id_isismtt_at_requestedCertificate = id_isismtt_at.branch("10");
@@ -159,8 +155,7 @@
* Hash of a certificate in OCSP.
* <p>
* OID: 1.3.36.8.3.13
- *
- * @see org.bouncycastle.asn1.isismtt.ocsp.CertHash
+ *
*/
static final ASN1ObjectIdentifier id_isismtt_at_certHash = id_isismtt_at.branch("13");
@@ -186,8 +181,7 @@
* </pre>
* <p>
* OID: 1.3.36.8.3.15
- *
- * @see org.bouncycastle.asn1.isismtt.x509.AdditionalInformationSyntax
+ *
*/
static final ASN1ObjectIdentifier id_isismtt_at_additionalInformation = id_isismtt_at.branch("15");
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/EndEntityType.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/EndEntityType.java
deleted file mode 100644
index 622f75e..0000000
--- a/bcprov/src/main/java/org/bouncycastle/its/asn1/EndEntityType.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.bouncycastle.its.asn1;
-
-import org.bouncycastle.asn1.ASN1BitString;
-import org.bouncycastle.asn1.ASN1Object;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.DERBitString;
-
-/**
- * <pre>
- * EndEntityType ::= BIT STRING { app(0), enrol(1) } (SIZE (8)) (ALL EXCEPT ())
- * </pre>
- */
-public class EndEntityType
- extends ASN1Object
-{
- public static final int app = (1 << 7);
- public static final int enrol = (1 << 6);
-
- private final ASN1BitString type;
-
- public EndEntityType(int type)
- {
- if (type != app && type != enrol)
- {
- throw new IllegalArgumentException("value out of range");
- }
-
- this.type = new DERBitString(type);
- }
-
- private EndEntityType(DERBitString str)
- {
- this.type = str;
- }
-
- public static EndEntityType getInstance(Object src)
- {
- if (src instanceof EndEntityType)
- {
- return (EndEntityType)src;
- }
- else if (src != null)
- {
- return new EndEntityType(DERBitString.getInstance(src));
- }
-
- return null;
- }
-
- public ASN1Primitive toASN1Primitive()
- {
- return type;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/PsidGroupPermissions.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/PsidGroupPermissions.java
deleted file mode 100644
index 2519614..0000000
--- a/bcprov/src/main/java/org/bouncycastle/its/asn1/PsidGroupPermissions.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.bouncycastle.its.asn1;
-
-import java.math.BigInteger;
-
-import org.bouncycastle.asn1.ASN1Integer;
-import org.bouncycastle.asn1.ASN1Object;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.ASN1Sequence;
-
-/**
- * <pre>
- * PsidGroupPermissions ::= SEQUENCE {
- * subjectPermissions SubjectPermissions,
- * minChainLength INTEGER DEFAULT 1,
- * chainLengthRange INTEGER DEFAULT 0,
- * eeType EndEntityType DEFAULT (app)
- * }
- * </pre>
- */
-public class PsidGroupPermissions
- extends ASN1Object
-{
- private final SubjectPermissions subjectPermissions;
- private final BigInteger minChainLength;
- private final BigInteger chainLengthRange;
- private final Object eeType;
-
- private PsidGroupPermissions(ASN1Sequence seq)
- {
- if (seq.size() != 2)
- {
- throw new IllegalArgumentException("sequence not length 2");
- }
-
- this.subjectPermissions = SubjectPermissions.getInstance(seq.getObjectAt(0));
- this.minChainLength = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue();
- this.chainLengthRange = ASN1Integer.getInstance(seq.getObjectAt(2)).getValue();
- this.eeType = EndEntityType.getInstance(seq.getObjectAt(3));
- }
-
- public static PsidGroupPermissions getInstance(Object src)
- {
- if (src instanceof PsidGroupPermissions)
- {
- return (PsidGroupPermissions)src;
- }
- else if (src != null)
- {
- return new PsidGroupPermissions(ASN1Sequence.getInstance(src));
- }
-
- return null;
- }
-
- public ASN1Primitive toASN1Primitive()
- {
- return null;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/BCLoadStoreParameter.java b/bcprov/src/main/java/org/bouncycastle/jcajce/BCLoadStoreParameter.java
new file mode 100644
index 0000000..0a299cb
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/BCLoadStoreParameter.java
@@ -0,0 +1,71 @@
+package org.bouncycastle.jcajce;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
+
+public class BCLoadStoreParameter
+ implements KeyStore.LoadStoreParameter
+{
+ private final InputStream in;
+ private final OutputStream out;
+ private final KeyStore.ProtectionParameter protectionParameter;
+
+ /**
+ * Base constructor for
+ *
+ * @param out
+ * @param password
+ */
+ public BCLoadStoreParameter(OutputStream out, char[] password)
+ {
+ this(out, new KeyStore.PasswordProtection(password));
+ }
+
+ public BCLoadStoreParameter(InputStream in, char[] password)
+ {
+ this(in, new KeyStore.PasswordProtection(password));
+ }
+
+ public BCLoadStoreParameter(InputStream in, KeyStore.ProtectionParameter protectionParameter)
+ {
+ this(in, null, protectionParameter);
+ }
+
+ public BCLoadStoreParameter(OutputStream out, KeyStore.ProtectionParameter protectionParameter)
+ {
+ this(null, out, protectionParameter);
+ }
+
+ BCLoadStoreParameter(InputStream in, OutputStream out, KeyStore.ProtectionParameter protectionParameter)
+ {
+ this.in = in;
+ this.out = out;
+ this.protectionParameter = protectionParameter;
+ }
+
+ public KeyStore.ProtectionParameter getProtectionParameter()
+ {
+ return protectionParameter;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ if (out == null)
+ {
+ throw new UnsupportedOperationException("parameter not configured for storage - no OutputStream");
+ }
+
+ return out;
+ }
+
+ public InputStream getInputStream()
+ {
+ if (out != null)
+ {
+ throw new UnsupportedOperationException("parameter configured for storage OutputStream present");
+ }
+
+ return in;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java
index e30881f..038eed6 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java
@@ -73,7 +73,7 @@
try
{
return new PrivateKeyInfo(
- new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_composite_key), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
}
catch (IOException e)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java
index 6a1ed2c..7491ad5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java
@@ -73,7 +73,7 @@
try
{
return new SubjectPublicKeyInfo(
- new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_composite_key), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
}
catch (IOException e)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/ExternalPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/ExternalPublicKey.java
new file mode 100644
index 0000000..668f464
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/ExternalPublicKey.java
@@ -0,0 +1,103 @@
+package org.bouncycastle.jcajce;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
+import org.bouncycastle.asn1.bc.ExternalValue;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.jcajce.util.MessageDigestUtils;
+import org.bouncycastle.util.Arrays;
+
+/**
+ * Wrapper class which returns an "ExternalValue" for the public key encoding. In this case
+ * the key encoding is a hash and the actual key needs to be looked up somewhere else. Useful
+ * for where the public keys are really large but it's required to keep certificates small.
+ */
+public class ExternalPublicKey
+ implements PublicKey
+{
+ private final GeneralName location;
+ private final AlgorithmIdentifier digestAlg;
+ private final byte[] digest;
+
+ /**
+ * Base constructor with fundamental contents.
+ *
+ * @param location location URI for the actual public key.
+ * @param digestAlg hashing algorithm used to hash the actual public key encoding.
+ * @param digest digest of the actual public key.
+ */
+ public ExternalPublicKey(GeneralName location, AlgorithmIdentifier digestAlg, byte[] digest)
+ {
+ this.location = location;
+ this.digestAlg = digestAlg;
+ this.digest = Arrays.clone(digest);
+ }
+
+ /**
+ * Helper constructor with JCA contents.
+ *
+ * @param key the public key we are externalising.
+ * @param location location URI for the actual public key.
+ * @param digest digest to use for hashing the key.
+ */
+ // Android-removed: unsupported
+ // public ExternalPublicKey(PublicKey key, GeneralName location, MessageDigest digest)
+ // {
+ // this(location, MessageDigestUtils.getDigestAlgID(digest.getAlgorithm()), digest.digest(key.getEncoded()));
+ // }
+
+ /**
+ * Base constructor with ASN.1 structure.
+ *
+ * @param extKey structure with location, hashing algorithm and hash for the public key.
+ */
+ public ExternalPublicKey(ExternalValue extKey)
+ {
+ this(extKey.getLocation(), extKey.getHashAlg(), extKey.getHashValue());
+ }
+
+ /**
+ * Return "ExternalKey"
+ *
+ * @return "ExternalKey"
+ */
+ public String getAlgorithm()
+ {
+ return "ExternalKey";
+ }
+
+ /**
+ * Return "X.509" (DER encoded SubjectPublicKeyInfo)
+ *
+ * @return "X.509"
+ */
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ /**
+ * Return a SubjectPublicKeyInfo structure containing an ExternalValue encoding for the key.
+ *
+ * @return a DER encoding of SubjectPublicKeyInfo containing an ExternalValue structure.
+ */
+ public byte[] getEncoded()
+ {
+ try
+ {
+ return new SubjectPublicKeyInfo(
+ new AlgorithmIdentifier(BCObjectIdentifiers.external_value),
+ new ExternalValue(location, digestAlg, digest)).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode composite key: " + e.getMessage());
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/SecretKeyWithEncapsulation.java b/bcprov/src/main/java/org/bouncycastle/jcajce/SecretKeyWithEncapsulation.java
new file mode 100644
index 0000000..aae15b4
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/SecretKeyWithEncapsulation.java
@@ -0,0 +1,77 @@
+package org.bouncycastle.jcajce;
+
+import javax.crypto.SecretKey;
+
+import org.bouncycastle.util.Arrays;
+
+/**
+ * Carrier class for a KEM/KTS secret key plus its encapsulation.
+ */
+public final class SecretKeyWithEncapsulation
+ implements SecretKey
+{
+ private final SecretKey secretKey;
+ private final byte[] encapsulation;
+
+ /**
+ * Basic constructor.
+ *
+ * @param secretKey the secret key that was arrived at.
+ * @param encapsulation the encapsulation the key data was carried in.
+ */
+ public SecretKeyWithEncapsulation(SecretKey secretKey, byte[] encapsulation)
+ {
+ this.secretKey = secretKey;
+ this.encapsulation = Arrays.clone(encapsulation);
+ }
+
+ /**
+ * Return the algorithm for the agreed secret key.
+ *
+ * @return the secret key value.
+ */
+ public String getAlgorithm()
+ {
+ return secretKey.getAlgorithm();
+ }
+
+ /**
+ * Return the format for the agreed secret key.
+ *
+ * @return the secret key format.
+ */
+ public String getFormat()
+ {
+ return secretKey.getFormat();
+ }
+
+ /**
+ * Return the encoding of the agreed secret key.
+ *
+ * @return the secret key encoding.
+ */
+ public byte[] getEncoded()
+ {
+ return secretKey.getEncoded();
+ }
+
+ /**
+ * Return the encapsulation that carried the key material used in creating the agreed secret key.
+ *
+ * @return the encrypted encapsulation of the agreed secret key.
+ */
+ public byte[] getEncapsulation()
+ {
+ return Arrays.clone(encapsulation);
+ }
+
+ public boolean equals(Object o)
+ {
+ return secretKey.equals(o);
+ }
+
+ public int hashCode()
+ {
+ return secretKey.hashCode();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java b/bcprov/src/main/java/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java
index f092df1..9d82ddf 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java
@@ -5,6 +5,8 @@
import java.security.Signature;
import java.security.SignatureException;
+import org.bouncycastle.util.Exceptions;
+
class SignatureUpdatingOutputStream
extends OutputStream
{
@@ -24,7 +26,7 @@
}
catch (SignatureException e)
{
- throw new IOException(e.getMessage());
+ throw Exceptions.ioException(e.getMessage(), e);
}
}
@@ -37,7 +39,7 @@
}
catch (SignatureException e)
{
- throw new IOException(e.getMessage());
+ throw Exceptions.ioException(e.getMessage(), e);
}
}
@@ -50,7 +52,7 @@
}
catch (SignatureException e)
{
- throw new IOException(e.getMessage());
+ throw Exceptions.ioException(e.getMessage(), e);
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java
new file mode 100644
index 0000000..db24653
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java
@@ -0,0 +1,139 @@
+package org.bouncycastle.jcajce.provider.asymmetric;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.jcajce.CompositePrivateKey;
+import org.bouncycastle.jcajce.CompositePublicKey;
+import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+
+public class COMPOSITE
+{
+ private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric.COMPOSITE";
+
+ private static final Map<String, String> compositeAttributes = new HashMap<String, String>();
+
+ static
+ {
+ compositeAttributes.put("SupportedKeyClasses", "org.bouncycastle.jcajce.CompositePublicKey|org.bouncycastle.jcajce.CompositePrivateKey");
+ compositeAttributes.put("SupportedKeyFormats", "PKCS#8|X.509");
+ }
+
+ private static AsymmetricKeyInfoConverter baseConverter;
+
+ public static class KeyFactory
+ extends BaseKeyFactorySpi
+ {
+ protected Key engineTranslateKey(Key key)
+ throws InvalidKeyException
+ {
+ try
+ {
+ if (key instanceof PrivateKey)
+ {
+ return generatePrivate(PrivateKeyInfo.getInstance(key.getEncoded()));
+ }
+ else if (key instanceof PublicKey)
+ {
+ return generatePublic(SubjectPublicKeyInfo.getInstance(key.getEncoded()));
+ }
+ }
+ catch (IOException e)
+ {
+ throw new InvalidKeyException("key could not be parsed: " + e.getMessage());
+ }
+
+ throw new InvalidKeyException("key not recognized");
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePrivate(keyInfo);
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePublic(keyInfo);
+ }
+ }
+
+ private static class CompositeKeyInfoConverter
+ implements AsymmetricKeyInfoConverter
+ {
+ private final ConfigurableProvider provider;
+
+ public CompositeKeyInfoConverter(ConfigurableProvider provider)
+ {
+ this.provider = provider;
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(keyInfo.parsePrivateKey());
+ PrivateKey[] privKeys = new PrivateKey[keySeq.size()];
+
+ for (int i = 0; i != keySeq.size(); i++)
+ {
+ PrivateKeyInfo privInfo = PrivateKeyInfo.getInstance(keySeq.getObjectAt(i));
+
+ privKeys[i] = provider.getKeyInfoConverter(
+ privInfo.getPrivateKeyAlgorithm().getAlgorithm()).generatePrivate(privInfo);
+ }
+
+ return new CompositePrivateKey(privKeys);
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(keyInfo.getPublicKeyData().getBytes());
+ PublicKey[] pubKeys = new PublicKey[keySeq.size()];
+
+ for (int i = 0; i != keySeq.size(); i++)
+ {
+ SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(keySeq.getObjectAt(i));
+
+ pubKeys[i] = provider.getKeyInfoConverter((pubInfo.getAlgorithm().getAlgorithm())).generatePublic(pubInfo);
+ }
+
+ return new CompositePublicKey(pubKeys);
+ }
+ }
+
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyFactory.COMPOSITE", PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory." + MiscObjectIdentifiers.id_alg_composite, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory.OID." + MiscObjectIdentifiers.id_alg_composite, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory." + MiscObjectIdentifiers.id_composite_key, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory.OID." + MiscObjectIdentifiers.id_composite_key, PREFIX + "$KeyFactory");
+
+ baseConverter = new CompositeKeyInfoConverter(provider);
+
+ provider.addKeyInfoConverter(MiscObjectIdentifiers.id_alg_composite, baseConverter);
+ provider.addKeyInfoConverter(MiscObjectIdentifiers.id_composite_key, baseConverter);
+ }
+ }
+}
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 6323b75..c95d233 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
@@ -17,7 +17,7 @@
public Mappings()
{
}
-
+
public void configure(ConfigurableProvider provider)
{
provider.addAlgorithm("AlgorithmParameters.DSA", PREFIX + "AlgorithmParametersSpi");
@@ -84,6 +84,8 @@
provider.addAlgorithm("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA");
// END Android-changed: Change primary ID from DSA to SHA1withDSA
+ // addSignatureAlgorithm(provider, "RIPEMD160", "DSA", PREFIX + "DSASigner$dsaRMD160");
+
AsymmetricKeyInfoConverter keyFact = new KeyFactorySpi();
for (int i = 0; i != DSAUtil.dsaOids.length; i++)
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 f900e90..aee8c39 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
@@ -11,6 +11,9 @@
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
// END Android-removed: Unsupported algorithms
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.cms.CMSObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.eac.EACObjectIdentifiers;
import org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi;
import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
@@ -43,77 +46,73 @@
/*
provider.addAlgorithm("AlgorithmParameters.EC", PREFIX + "AlgorithmParametersSpi");
- provider.addAttributes("KeyAgreement.ECDH", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH");
- provider.addAttributes("KeyAgreement.ECDHC", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHC", PREFIX + "KeyAgreementSpi$DHC");
- provider.addAttributes("KeyAgreement.ECCDH", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDH", PREFIX + "KeyAgreementSpi$DHC");
+ provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECDHC", PREFIX + "KeyAgreementSpi$DHC", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDH", PREFIX + "KeyAgreementSpi$DHC", generalEcAttributes);
+
+ provider.addAlgorithm("KeyAgreement.ECCDHU", PREFIX + "KeyAgreementSpi$DHUC", generalEcAttributes);
- provider.addAttributes("KeyAgreement.ECCDHU", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHU", PREFIX + "KeyAgreementSpi$DHUC");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA1CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA256CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA384CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA512CKDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA1CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA256CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA384CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA512CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512CKDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512KDF");
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA1KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA224KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA256KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA384KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA512KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA1KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA224KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA256KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA384KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA512KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF");
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA1, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA224, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA256, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA384, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA512, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA1, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA224, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA256, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA384, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA512, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF");
-
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_RIPEMD160, PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHRIPEMD160KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_RIPEMD160, PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHRIPEMD160KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF", generalEcAttributes);
registerOid(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC", new KeyFactorySpi.EC());
@@ -151,25 +150,25 @@
if (!Properties.isOverrideSet("org.bouncycastle.ec.disable_mqv"))
{
- provider.addAlgorithm("KeyAgreement.ECMQV", PREFIX + "KeyAgreementSpi$MQV");
+ provider.addAlgorithm("KeyAgreement.ECMQV", PREFIX + "KeyAgreementSpi$MQV", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512CKDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512CKDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512KDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA1KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA224KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA256KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA384KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA512KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA1KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA224KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA256KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA384KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA512KDFAndSharedInfo", generalEcAttributes);
registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
@@ -203,17 +202,42 @@
provider.addAlgorithm("KeyPairGenerator.ECDHC", PREFIX + "KeyPairGeneratorSpi$ECDHC");
provider.addAlgorithm("KeyPairGenerator.ECIES", PREFIX + "KeyPairGeneratorSpi$ECDH");
- provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES");
+ provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA1", PREFIX + "IESCipher$ECIES", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA1", PREFIX + "IESCipher$ECIES", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA256", PREFIX + "IESCipher$ECIESwithSHA256", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA256", PREFIX + "IESCipher$ECIESwithSHA256", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA384", PREFIX + "IESCipher$ECIESwithSHA384", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA384", PREFIX + "IESCipher$ECIESwithSHA384", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA512", PREFIX + "IESCipher$ECIESwithSHA512", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA512", PREFIX + "IESCipher$ECIESwithSHA512", generalEcAttributes);
- provider.addAlgorithm("Cipher.ECIESwithAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC");
- provider.addAlgorithm("Cipher.ECIESWITHAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC");
- provider.addAlgorithm("Cipher.ECIESwithDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
- provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
+ provider.addAlgorithm("Cipher.ECIESwithAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA1andAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA1ANDAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA256andAES-CBC", PREFIX + "IESCipher$ECIESwithSHA256andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA256ANDAES-CBC", PREFIX + "IESCipher$ECIESwithSHA256andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA384andAES-CBC", PREFIX + "IESCipher$ECIESwithSHA384andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA384ANDAES-CBC", PREFIX + "IESCipher$ECIESwithSHA384andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA512andAES-CBC", PREFIX + "IESCipher$ECIESwithSHA512andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA512ANDAES-CBC", PREFIX + "IESCipher$ECIESwithSHA512andAESCBC", generalEcAttributes);
- provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA");
+ provider.addAlgorithm("Cipher.ECIESwithDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA1andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA1ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA256andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA256andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA256ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA256andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA384andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA384andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA384ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA384andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA512andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA512andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA512ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA512andDESedeCBC", generalEcAttributes);
- provider.addAlgorithm("Signature.SHA1withECDSA", PREFIX + "SignatureSpi$ecDSA");
- provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone");
+ provider.addAlgorithm("Cipher.ETSIKEMWITHSHA256", PREFIX + "IESKEMCipher$KEMwithSHA256", generalEcAttributes);
+
+ provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA", generalEcAttributes);
+ provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone", generalEcAttributes);
provider.addAlgorithm("Alg.Alias.Signature.ECDSA", "SHA1withECDSA");
provider.addAlgorithm("Alg.Alias.Signature.ECDSAwithSHA1", "SHA1withECDSA");
@@ -224,16 +248,16 @@
provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
provider.addAlgorithm("Alg.Alias.Signature." + TeleTrusTObjectIdentifiers.ecSignWithSha1, "ECDSA");
- provider.addAlgorithm("Signature.ECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
- provider.addAlgorithm("Signature.SHA1WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
- provider.addAlgorithm("Signature.SHA224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA224");
- provider.addAlgorithm("Signature.SHA256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA256");
- provider.addAlgorithm("Signature.SHA384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA384");
- provider.addAlgorithm("Signature.SHA512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512");
- provider.addAlgorithm("Signature.SHA3-224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_224");
- provider.addAlgorithm("Signature.SHA3-256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_256");
- provider.addAlgorithm("Signature.SHA3-384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_384");
- provider.addAlgorithm("Signature.SHA3-512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_512");
+ provider.addAlgorithm("Signature.ECDDSA", PREFIX + "SignatureSpi$ecDetDSA", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA1WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA224", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA256", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA384", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_224", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_256", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_384", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_512", generalEcAttributes);
provider.addAlgorithm("Alg.Alias.Signature.DETECDSA", "ECDDSA");
provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHDETECDSA", "SHA1WITHECDDSA");
@@ -242,22 +266,29 @@
provider.addAlgorithm("Alg.Alias.Signature.SHA384WITHDETECDSA", "SHA384WITHECDDSA");
provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHDETECDSA", "SHA512WITHECDDSA");
- addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224);
- addSignatureAlgorithm(provider, "SHA256", "ECDSA", PREFIX + "SignatureSpi$ecDSA256", X9ObjectIdentifiers.ecdsa_with_SHA256);
- addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384);
- addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512);
- addSignatureAlgorithm(provider, "SHA3-224", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_224", NISTObjectIdentifiers.id_ecdsa_with_sha3_224);
- addSignatureAlgorithm(provider, "SHA3-256", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_256", NISTObjectIdentifiers.id_ecdsa_with_sha3_256);
- addSignatureAlgorithm(provider, "SHA3-384", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_384", NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
- addSignatureAlgorithm(provider, "SHA3-512", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_512", NISTObjectIdentifiers.id_ecdsa_with_sha3_512);
+ addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA256", "ECDSA", PREFIX + "SignatureSpi$ecDSA256", X9ObjectIdentifiers.ecdsa_with_SHA256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-224", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_224", NISTObjectIdentifiers.id_ecdsa_with_sha3_224, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-256", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_256", NISTObjectIdentifiers.id_ecdsa_with_sha3_256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-384", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_384", NISTObjectIdentifiers.id_ecdsa_with_sha3_384, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-512", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_512", NISTObjectIdentifiers.id_ecdsa_with_sha3_512, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHAKE128", "ECDSA", PREFIX + "SignatureSpi$ecDSAShake128", CMSObjectIdentifiers.id_ecdsa_with_shake128, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHAKE256", "ECDSA", PREFIX + "SignatureSpi$ecDSAShake256", CMSObjectIdentifiers.id_ecdsa_with_shake256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "RIPEMD160", "ECDSA", PREFIX + "SignatureSpi$ecDSARipeMD160",TeleTrusTObjectIdentifiers.ecSignWithRipemd160, generalEcAttributes);
- addSignatureAlgorithm(provider, "RIPEMD160", "ECDSA", PREFIX + "SignatureSpi$ecDSARipeMD160",TeleTrusTObjectIdentifiers.ecSignWithRipemd160);
+ provider.addAlgorithm("Signature.SHA1WITHECNR", PREFIX + "SignatureSpi$ecNR", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA224WITHECNR", PREFIX + "SignatureSpi$ecNR224", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA256WITHECNR", PREFIX + "SignatureSpi$ecNR256", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA384WITHECNR", PREFIX + "SignatureSpi$ecNR384", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA512WITHECNR", PREFIX + "SignatureSpi$ecNR512", generalEcAttributes);
- provider.addAlgorithm("Signature.SHA1WITHECNR", PREFIX + "SignatureSpi$ecNR");
- provider.addAlgorithm("Signature.SHA224WITHECNR", PREFIX + "SignatureSpi$ecNR224");
- provider.addAlgorithm("Signature.SHA256WITHECNR", PREFIX + "SignatureSpi$ecNR256");
- provider.addAlgorithm("Signature.SHA384WITHECNR", PREFIX + "SignatureSpi$ecNR384");
- provider.addAlgorithm("Signature.SHA512WITHECNR", PREFIX + "SignatureSpi$ecNR512");
+ addSignatureAlgorithm(provider, "SHA1", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA224", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA224", EACObjectIdentifiers.id_TA_ECDSA_SHA_224, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA256", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA256", EACObjectIdentifiers.id_TA_ECDSA_SHA_256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA384", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA384", EACObjectIdentifiers.id_TA_ECDSA_SHA_384, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA512", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA512", EACObjectIdentifiers.id_TA_ECDSA_SHA_512, generalEcAttributes);
addSignatureAlgorithm(provider, "SHA1", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1);
addSignatureAlgorithm(provider, "SHA224", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA224", EACObjectIdentifiers.id_TA_ECDSA_SHA_224);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EXTERNAL.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EXTERNAL.java
new file mode 100644
index 0000000..46d3e5e
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EXTERNAL.java
@@ -0,0 +1,118 @@
+package org.bouncycastle.jcajce.provider.asymmetric;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
+import org.bouncycastle.asn1.bc.ExternalValue;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.jcajce.ExternalPublicKey;
+import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+
+public class EXTERNAL
+{
+ private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric.EXTERNAL";
+
+ private static final Map<String, String> externalAttributes = new HashMap<String, String>();
+
+ static
+ {
+ externalAttributes.put("SupportedKeyClasses", "org.bouncycastle.jcajce.ExternalPublicKey");
+ externalAttributes.put("SupportedKeyFormats", "X.509");
+ }
+
+ private static AsymmetricKeyInfoConverter baseConverter;
+
+ public static class KeyFactory
+ extends BaseKeyFactorySpi
+ {
+ protected Key engineTranslateKey(Key key)
+ throws InvalidKeyException
+ {
+ try
+ {
+ if (key instanceof PrivateKey)
+ {
+ return generatePrivate(PrivateKeyInfo.getInstance(key.getEncoded()));
+ }
+ else if (key instanceof PublicKey)
+ {
+ return generatePublic(SubjectPublicKeyInfo.getInstance(key.getEncoded()));
+ }
+ }
+ catch (IOException e)
+ {
+ throw new InvalidKeyException("key could not be parsed: " + e.getMessage());
+ }
+
+ throw new InvalidKeyException("key not recognized");
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePrivate(keyInfo);
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePublic(keyInfo);
+ }
+ }
+
+ private static class ExternalKeyInfoConverter
+ implements AsymmetricKeyInfoConverter
+ {
+ private final ConfigurableProvider provider;
+
+ public ExternalKeyInfoConverter(ConfigurableProvider provider)
+ {
+ this.provider = provider;
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ throw new UnsupportedOperationException("no support for private key");
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ ExternalValue extKey = ExternalValue.getInstance(keyInfo.parsePublicKey());
+
+ // TODO: maybe implement some sort of cache lookup?
+
+ return new ExternalPublicKey(extKey);
+ }
+ }
+
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyFactory.EXTERNAL", PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory." + BCObjectIdentifiers.external_value, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory.OID." + BCObjectIdentifiers.external_value, PREFIX + "$KeyFactory");
+
+ baseConverter = new ExternalKeyInfoConverter(provider);
+
+ provider.addKeyInfoConverter(BCObjectIdentifiers.external_value, baseConverter);
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/LMS.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/LMS.java
new file mode 100644
index 0000000..11bbf8e
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/LMS.java
@@ -0,0 +1,30 @@
+package org.bouncycastle.jcajce.provider.asymmetric;
+
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+
+public class LMS
+{
+ private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".lms.";
+
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyFactory.LMS", PREFIX + "LMSKeyFactorySpi");
+ provider.addAlgorithm("Alg.Alias.KeyFactory." + PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, "LMS");
+
+ provider.addAlgorithm("KeyPairGenerator.LMS", PREFIX + "LMSKeyPairGeneratorSpi");
+ provider.addAlgorithm("Alg.Alias.KeyPairGenerator." + PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, "LMS");
+
+ provider.addAlgorithm("Signature.LMS", PREFIX + "LMSSignatureSpi$generic");
+ provider.addAlgorithm("Alg.Alias.Signature." + PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, "LMS");
+ }
+ }
+}
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 b9afff8..6db61ae 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
@@ -10,6 +10,7 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.cms.CMSObjectIdentifiers;
import org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi;
import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
@@ -23,7 +24,7 @@
static
{
- generalRsaAttributes.put("SupportedKeyClasses", "javax.crypto.interfaces.RSAPublicKey|javax.crypto.interfaces.RSAPrivateKey");
+ generalRsaAttributes.put("SupportedKeyClasses", "java.security.interfaces.RSAPublicKey|java.security.interfaces.RSAPrivateKey");
generalRsaAttributes.put("SupportedKeyFormats", "PKCS#8|X.509");
}
@@ -73,8 +74,8 @@
// BEGIN Android-removed: Unsupported algorithms
/*
provider.addAlgorithm("Cipher.RSA/PKCS1", PREFIX + "CipherSpi$PKCS1v1_5Padding");
- provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.rsaEncryption, PREFIX + "CipherSpi$PKCS1v1_5Padding");
- provider.addAlgorithm("Cipher", X509ObjectIdentifiers.id_ea_rsa, PREFIX + "CipherSpi$PKCS1v1_5Padding");
+ provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.rsaEncryption, PREFIX + "CipherSpi$PKCS1v1_5Padding", generalRsaAttributes);
+ provider.addAlgorithm("Cipher", X509ObjectIdentifiers.id_ea_rsa, PREFIX + "CipherSpi$PKCS1v1_5Padding", generalRsaAttributes);
provider.addAlgorithm("Cipher.RSA/1", PREFIX + "CipherSpi$PKCS1v1_5Padding_PrivateOnly");
provider.addAlgorithm("Cipher.RSA/2", PREFIX + "CipherSpi$PKCS1v1_5Padding_PublicOnly");
provider.addAlgorithm("Cipher.RSA/OAEP", PREFIX + "CipherSpi$OAEPPadding");
@@ -115,12 +116,12 @@
registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSAES_OAEP, "OAEP");
registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSASSA_PSS, "PSS");
- provider.addAlgorithm("Signature.RSASSA-PSS", PREFIX + "PSSSignatureSpi$PSSwithRSA");
- provider.addAlgorithm("Signature." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA");
- provider.addAlgorithm("Signature.OID." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA");
+ provider.addAlgorithm("Signature.RSASSA-PSS", PREFIX + "PSSSignatureSpi$PSSwithRSA", generalRsaAttributes);
+ provider.addAlgorithm("Alg.Alias.Signature." + PKCSObjectIdentifiers.id_RSASSA_PSS, "RSASSA-PSS");
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + PKCSObjectIdentifiers.id_RSASSA_PSS, "RSASSA-PSS");
- provider.addAlgorithm("Signature.RSA", PREFIX + "DigestSignatureSpi$noneRSA");
- provider.addAlgorithm("Signature.RAWRSASSA-PSS", PREFIX + "PSSSignatureSpi$nonePSS");
+ provider.addAlgorithm("Signature.RSA", PREFIX + "DigestSignatureSpi$noneRSA", generalRsaAttributes);
+ provider.addAlgorithm("Signature.RAWRSASSA-PSS", PREFIX + "PSSSignatureSpi$nonePSS", generalRsaAttributes);
provider.addAlgorithm("Alg.Alias.Signature.RAWRSA", "RSA");
provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSA", "RSA");
@@ -130,17 +131,43 @@
provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSAANDMGF1", "RAWRSASSA-PSS");
provider.addAlgorithm("Alg.Alias.Signature.RSAPSS", "RSASSA-PSS");
- addPSSSignature(provider, "SHA224", PREFIX + "PSSSignatureSpi$SHA224withRSA");
- addPSSSignature(provider, "SHA256", PREFIX + "PSSSignatureSpi$SHA256withRSA");
- addPSSSignature(provider, "SHA384", PREFIX + "PSSSignatureSpi$SHA384withRSA");
- addPSSSignature(provider, "SHA512", PREFIX + "PSSSignatureSpi$SHA512withRSA");
- addPSSSignature(provider, "SHA512(224)", PREFIX + "PSSSignatureSpi$SHA512_224withRSA");
- addPSSSignature(provider, "SHA512(256)", PREFIX + "PSSSignatureSpi$SHA512_256withRSA");
+ addPSSSignature(provider, "SHA224", "MGF1", PREFIX + "PSSSignatureSpi$SHA224withRSA");
+ addPSSSignature(provider, "SHA256", "MGF1", PREFIX + "PSSSignatureSpi$SHA256withRSA");
+ addPSSSignature(provider, "SHA384", "MGF1", PREFIX + "PSSSignatureSpi$SHA384withRSA");
+ addPSSSignature(provider, "SHA512", "MGF1", PREFIX + "PSSSignatureSpi$SHA512withRSA");
+ addPSSSignature(provider, "SHA512(224)", "MGF1", PREFIX + "PSSSignatureSpi$SHA512_224withRSA");
+ addPSSSignature(provider, "SHA512(256)", "MGF1", PREFIX + "PSSSignatureSpi$SHA512_256withRSA");
- addPSSSignature(provider, "SHA3-224", PREFIX + "PSSSignatureSpi$SHA3_224withRSA");
- addPSSSignature(provider, "SHA3-256", PREFIX + "PSSSignatureSpi$SHA3_256withRSA");
- addPSSSignature(provider, "SHA3-384", PREFIX + "PSSSignatureSpi$SHA3_384withRSA");
- addPSSSignature(provider, "SHA3-512", PREFIX + "PSSSignatureSpi$SHA3_512withRSA");
+ addPSSSignature(provider, "SHA3-224", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_224withRSA");
+ addPSSSignature(provider, "SHA3-256", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_256withRSA");
+ addPSSSignature(provider, "SHA3-384", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_384withRSA");
+ addPSSSignature(provider, "SHA3-512", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_512withRSA");
+ addPSSSignature(provider, "SHAKE128", PREFIX + "PSSSignatureSpi$SHAKE128WithRSAPSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128);
+ addPSSSignature(provider, "SHAKE256", PREFIX + "PSSSignatureSpi$SHAKE256WithRSAPSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256);
+
+ addPSSSignature(provider, "SHA224", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA224withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA256", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA256withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA384", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA384withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA512", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA512withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA512(224)", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA512_224withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA512(256)", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA512_256withRSAandSHAKE128");
+
+ addPSSSignature(provider, "SHA224", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA224withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA256", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA256withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA384", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA384withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA512", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA512withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA512(224)", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA512_224withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA512(256)", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA512_256withRSAandSHAKE256");
+
+ addPSSSignature(provider, "SHA3-224", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_224withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA3-256", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_256withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA3-384", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_384withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA3-512", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_512withRSAandSHAKE128");
+
+ addPSSSignature(provider, "SHA3-224", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_224withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA3-256", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_256withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA3-384", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_384withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA3-512", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_512withRSAandSHAKE256");
if (provider.hasAlgorithm("MessageDigest", "MD2"))
{
@@ -163,7 +190,9 @@
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1withRSA/PSS", "PSS");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1WITHRSAANDMGF1", "PSS");
- addPSSSignature(provider, "SHA1", PREFIX + "PSSSignatureSpi$SHA1withRSA");
+ addPSSSignature(provider, "SHA1", "MGF1", PREFIX + "PSSSignatureSpi$SHA1withRSA");
+ addPSSSignature(provider, "SHA1", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA1withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA1", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA1withRSAandSHAKE256");
addDigestSignature(provider, "SHA1", PREFIX + "DigestSignatureSpi$SHA1", PKCSObjectIdentifiers.sha1WithRSAEncryption);
addISO9796Signature(provider, "SHA1", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption");
@@ -263,6 +292,7 @@
provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
}
+ provider.addAttributes("Signature." + mainName, generalRsaAttributes);
}
private void addISO9796Signature(
@@ -273,12 +303,37 @@
provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/ISO9796-2", digest + "WITHRSA/ISO9796-2");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/ISO9796-2", digest + "WITHRSA/ISO9796-2");
provider.addAlgorithm("Signature." + digest + "WITHRSA/ISO9796-2", className);
+ provider.addAttributes("Signature." + digest + "WITHRSA/ISO9796-2", generalRsaAttributes);
+ }
+
+ private void addPSSSignature(
+ ConfigurableProvider provider,
+ String digest, String mgf,
+ String className)
+ {
+ String stem = "WITHRSAAND" + mgf;
+ if (mgf.equals("MGF1"))
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WITHRSA/PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSASSA-PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSASSA-PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WITHRSASSA-PSS", digest + stem);
+ }
+
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSAand" + mgf, digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSAAnd" + mgf, digest + stem);
+
+ provider.addAlgorithm("Signature." + digest + "WITHRSAAND" + mgf, className);
+ provider.addAttributes("Signature." + digest + "WITHRSAAND" + mgf, generalRsaAttributes);
}
private void addPSSSignature(
ConfigurableProvider provider,
String digest,
- String className)
+ String className,
+ ASN1ObjectIdentifier sigOid)
{
provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/PSS", digest + "WITHRSAANDMGF1");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/PSS", digest + "WITHRSAANDMGF1");
@@ -299,6 +354,7 @@
provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/X9.31", digest + "WITHRSA/X9.31");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/X9.31", digest + "WITHRSA/X9.31");
provider.addAlgorithm("Signature." + digest + "WITHRSA/X9.31", className);
+ provider.addAttributes("Signature." + digest + "WITHRSA/X9.31", generalRsaAttributes);
}
}
}
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 502854d..6a61e76 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
@@ -40,6 +40,7 @@
// import org.bouncycastle.jcajce.spec.DHUParameterSpec;
// import org.bouncycastle.jcajce.spec.MQVParameterSpec;
import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec;
+import org.bouncycastle.util.BigIntegers;
/**
* Diffie-Hellman key agreement. There's actually a better way of doing this
@@ -115,30 +116,9 @@
//
int expectedLength = (p.bitLength() + 7) / 8;
- byte[] tmp = r.toByteArray();
-
- if (tmp.length == expectedLength)
- {
- return tmp;
- }
-
- if (tmp[0] == 0 && tmp.length == expectedLength + 1)
- {
- byte[] rv = new byte[tmp.length - 1];
-
- System.arraycopy(tmp, 1, rv, 0, rv.length);
- return rv;
- }
-
- // tmp must be shorter than expectedLength
- // pad to the left with zeros.
- byte[] rv = new byte[expectedLength];
-
- System.arraycopy(tmp, 0, rv, rv.length - tmp.length, tmp.length);
-
- return rv;
+ return BigIntegers.asUnsignedByteArray(expectedLength, r);
}
-
+
protected Key engineDoPhase(
Key key,
boolean lastPhase)
@@ -266,7 +246,7 @@
return super.engineGenerateSecret(algorithm);
}
- protected void engineInit(
+ protected void doInitFromKey(
Key key,
AlgorithmParameterSpec params,
SecureRandom random)
@@ -385,7 +365,7 @@
this.result = bigIntToBytes(x);
}
- protected byte[] calcSecret()
+ protected byte[] doCalcSecret()
{
return result;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java
index 1cc7cb3..d3a8ec4 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java
@@ -67,7 +67,7 @@
}
else
{
- pGen = new DSAParametersGenerator(new SHA256Digest());
+ pGen = new DSAParametersGenerator(SHA256Digest.newInstance());
}
if (random == null)
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
index b50c49e..0571f3d 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
@@ -1,5 +1,5 @@
-package org.bouncycastle.jcajce.provider.asymmetric.dsa;
+package org.bouncycastle.jcajce.provider.asymmetric.dsa;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
@@ -9,7 +9,6 @@
import java.security.SignatureException;
import java.security.SignatureSpi;
import java.security.spec.AlgorithmParameterSpec;
-
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.crypto.CipherParameters;
@@ -28,7 +27,6 @@
// import org.bouncycastle.crypto.util.DigestFactory;
import org.bouncycastle.crypto.digests.AndroidDigestFactory;
import org.bouncycastle.util.Arrays;
-
public class DSASigner
extends SignatureSpi
implements PKCSObjectIdentifiers, X509ObjectIdentifiers
@@ -37,7 +35,6 @@
private DSAExt signer;
private DSAEncoding encoding = StandardDSAEncoding.INSTANCE;
private SecureRandom random;
-
protected DSASigner(
Digest digest,
DSAExt signer)
@@ -45,17 +42,14 @@
this.digest = digest;
this.signer = signer;
}
-
protected void engineInitVerify(
PublicKey publicKey)
throws InvalidKeyException
{
CipherParameters param = DSAUtil.generatePublicKeyParameter(publicKey);
-
digest.reset();
signer.init(false, param);
}
-
protected void engineInitSign(
PrivateKey privateKey,
SecureRandom random)
@@ -64,53 +58,43 @@
this.random = random;
engineInitSign(privateKey);
}
-
protected void engineInitSign(
PrivateKey privateKey)
throws InvalidKeyException
{
CipherParameters param = DSAUtil.generatePrivateKeyParameter(privateKey);
-
// Android-added: Check DSA keys when generated
DSAParameters dsaParam = ((DSAKeyParameters) param).getParameters();
checkKey(dsaParam);
-
if (random != null)
{
param = new ParametersWithRandom(param, random);
}
-
digest.reset();
signer.init(true, param);
}
-
protected void engineUpdate(
byte b)
throws SignatureException
{
digest.update(b);
}
-
protected void engineUpdate(
byte[] b,
int off,
- int len)
+ int len)
throws SignatureException
{
digest.update(b, off, len);
}
-
protected byte[] engineSign()
throws SignatureException
{
byte[] hash = new byte[digest.getDigestSize()];
-
digest.doFinal(hash, 0);
-
try
{
BigInteger[] sig = signer.generateSignature(hash);
-
return encoding.encode(signer.getOrder(), sig[0], sig[1]);
}
catch (Exception e)
@@ -118,17 +102,13 @@
throw new SignatureException(e.toString());
}
}
-
protected boolean engineVerify(
- byte[] sigBytes)
+ byte[] sigBytes)
throws SignatureException
{
byte[] hash = new byte[digest.getDigestSize()];
-
digest.doFinal(hash, 0);
-
BigInteger[] sig;
-
try
{
sig = encoding.decode(signer.getOrder(), sigBytes);
@@ -137,27 +117,22 @@
{
throw new SignatureException("error decoding signature bytes.");
}
-
return signer.verifySignature(hash, sig[0], sig[1]);
}
-
protected AlgorithmParameters engineGetParameters()
{
return null;
}
-
protected void engineSetParameter(
AlgorithmParameterSpec params)
{
throw new UnsupportedOperationException("engineSetParameter unsupported");
}
-
// BEGIN Android-added: Check DSA keys when generated
protected void checkKey(DSAParameters params) throws InvalidKeyException {
int valueL = params.getP().bitLength();
int valueN = params.getQ().bitLength();
int digestSize = digest.getDigestSize();
-
// The checks are consistent with DSAParametersGenerator's init method.
if ((valueL < 1024 || valueL > 3072) || valueL % 1024 != 0) {
throw new InvalidKeyException("valueL values must be between 1024 and 3072 and a multiple of 1024");
@@ -172,7 +147,6 @@
throw new InvalidKeyException("Key is too strong for this signature algorithm");
}
}
-
// END Android-added: Check DSA keys when generated
/**
* @deprecated replaced with #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
@@ -183,7 +157,6 @@
{
throw new UnsupportedOperationException("engineSetParameter unsupported");
}
-
/**
* @deprecated
*/
@@ -192,7 +165,6 @@
{
throw new UnsupportedOperationException("engineGetParameter unsupported");
}
-
static public class stdDSA
extends DSASigner
{
@@ -203,7 +175,6 @@
super(AndroidDigestFactory.getSHA1(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
// BEGIN Android-removed: Unsupported algorithm
/*
static public class detDSA
@@ -214,6 +185,14 @@
super(DigestFactory.createSHA1(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA1())));
}
}
+ static public class dsaRMD160
+ extends DSASigner
+ {
+ public dsaRMD160()
+ {
+ super(new RIPEMD160Digest(), new org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
*/
// END Android-removed: Unsupported algorithm
@@ -227,7 +206,6 @@
super(AndroidDigestFactory.getSHA224(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
// BEGIN Android-removed: Unsupported algorithm
/*
static public class detDSA224
@@ -240,7 +218,6 @@
}
*/
// END Android-removed: Unsupported algorithm
-
static public class dsa256
extends DSASigner
{
@@ -251,7 +228,6 @@
super(AndroidDigestFactory.getSHA256(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
// BEGIN Android-removed: Unsupported algorithms
/*
static public class detDSA256
@@ -262,7 +238,6 @@
super(DigestFactory.createSHA256(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA256())));
}
}
-
static public class dsa384
extends DSASigner
{
@@ -271,7 +246,6 @@
super(DigestFactory.createSHA384(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSA384
extends DSASigner
{
@@ -280,7 +254,6 @@
super(DigestFactory.createSHA384(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA384())));
}
}
-
static public class dsa512
extends DSASigner
{
@@ -289,7 +262,6 @@
super(DigestFactory.createSHA512(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSA512
extends DSASigner
{
@@ -298,7 +270,6 @@
super(DigestFactory.createSHA512(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA512())));
}
}
-
static public class dsaSha3_224
extends DSASigner
{
@@ -307,7 +278,6 @@
super(DigestFactory.createSHA3_224(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_224
extends DSASigner
{
@@ -316,7 +286,6 @@
super(DigestFactory.createSHA3_224(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_224())));
}
}
-
static public class dsaSha3_256
extends DSASigner
{
@@ -325,7 +294,6 @@
super(DigestFactory.createSHA3_256(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_256
extends DSASigner
{
@@ -334,7 +302,6 @@
super(DigestFactory.createSHA3_256(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_256())));
}
}
-
static public class dsaSha3_384
extends DSASigner
{
@@ -343,7 +310,6 @@
super(DigestFactory.createSHA3_384(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_384
extends DSASigner
{
@@ -352,7 +318,6 @@
super(DigestFactory.createSHA3_384(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_384())));
}
}
-
static public class dsaSha3_512
extends DSASigner
{
@@ -361,7 +326,6 @@
super(DigestFactory.createSHA3_512(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_512
extends DSASigner
{
@@ -372,7 +336,6 @@
}
*/
// END Android-removed: Unsupported algorithms
-
static public class noneDSA
extends DSASigner
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
index a7ed3e0..0b640f5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
@@ -148,7 +148,7 @@
else if (strength > 1024)
{
dsaParams = new DSAParameterGenerationParameters(strength, 256, certainty, random);
- pGen = new DSAParametersGenerator(new SHA256Digest());
+ pGen = new DSAParametersGenerator(SHA256Digest.newInstance());
pGen.init(dsaParams);
}
else
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
index 7d84ecb..7f55c78 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
@@ -15,6 +15,7 @@
import org.bouncycastle.asn1.x9.X9ECPoint;
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.math.ec.ECCurve;
@@ -37,12 +38,14 @@
if (algorithmParameterSpec instanceof ECGenParameterSpec)
{
ECGenParameterSpec ecGenParameterSpec = (ECGenParameterSpec)algorithmParameterSpec;
- X9ECParameters params = ECUtils.getDomainParametersFromGenSpec(ecGenParameterSpec);
+ ProviderConfiguration configuration = BouncyCastleProvider.CONFIGURATION;
- if (params == null)
+ X9ECParameters params = ECUtils.getDomainParametersFromGenSpec(ecGenParameterSpec, configuration);
+ if (null == params)
{
throw new InvalidParameterSpecException("EC curve name not recognized: " + ecGenParameterSpec.getName());
}
+
curveName = ecGenParameterSpec.getName();
ECParameterSpec baseSpec = EC5Util.convertToSpec(params);
ecParameterSpec = new ECNamedCurveSpec(curveName,
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 e1d737a..444b215 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
@@ -10,18 +10,20 @@
import java.security.spec.EllipticCurve;
import java.util.Enumeration;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.crypto.params.ECNamedDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
@@ -30,23 +32,29 @@
import org.bouncycastle.jce.interfaces.ECPointEncoder;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.util.Arrays;
public class BCECPrivateKey
implements ECPrivateKey, org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder
{
static final long serialVersionUID = 994553197664784084L;
- private String algorithm = "EC";
- private boolean withCompression;
+ private String algorithm = "EC";
+ private boolean withCompression;
- private transient BigInteger d;
- private transient ECParameterSpec ecSpec;
- private transient ProviderConfiguration configuration;
- private transient DERBitString publicKey;
+ private transient BigInteger d;
+ private transient ECParameterSpec ecSpec;
+ private transient ProviderConfiguration configuration;
+ private transient ASN1BitString publicKey;
+ private transient PrivateKeyInfo privateKeyInfo;
+ private transient byte[] encoding;
+ private transient ECPrivateKeyParameters baseKey;
private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
protected BCECPrivateKey()
{
}
@@ -59,6 +67,7 @@
this.algorithm = key.getAlgorithm();
this.ecSpec = key.getParams();
this.configuration = configuration;
+ this.baseKey = convertToBaseKey(this);
}
public BCECPrivateKey(
@@ -84,6 +93,7 @@
}
this.configuration = configuration;
+ this.baseKey = convertToBaseKey(this);
}
@@ -96,6 +106,7 @@
this.d = spec.getS();
this.ecSpec = spec.getParams();
this.configuration = configuration;
+ this.baseKey = convertToBaseKey(this);
}
public BCECPrivateKey(
@@ -109,6 +120,7 @@
this.attrCarrier = key.attrCarrier;
this.publicKey = key.publicKey;
this.configuration = key.configuration;
+ this.baseKey = key.baseKey;
}
public BCECPrivateKey(
@@ -121,6 +133,7 @@
this.algorithm = algorithm;
this.d = params.getD();
this.configuration = configuration;
+ this.baseKey = params;
if (spec == null)
{
@@ -151,6 +164,7 @@
this.algorithm = algorithm;
this.d = params.getD();
this.configuration = configuration;
+ this.baseKey = params;
if (spec == null)
{
@@ -189,10 +203,11 @@
this.d = params.getD();
this.ecSpec = null;
this.configuration = configuration;
+ this.baseKey = params;
}
BCECPrivateKey(
- String algorithm,
+ String algorithm,
PrivateKeyInfo info,
ProviderConfiguration configuration)
throws IOException
@@ -213,7 +228,7 @@
ASN1Encodable privKey = info.parsePrivateKey();
if (privKey instanceof ASN1Integer)
{
- ASN1Integer derD = ASN1Integer.getInstance(privKey);
+ ASN1Integer derD = ASN1Integer.getInstance(privKey);
this.d = derD.getValue();
}
@@ -224,6 +239,7 @@
this.d = ec.getKey();
this.publicKey = ec.getPublicKey();
}
+ this.baseKey = convertToBaseKey(this);
}
public String getAlgorithm()
@@ -249,40 +265,71 @@
*/
public byte[] getEncoded()
{
- X962Parameters params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
+ if (encoding == null)
+ {
+ PrivateKeyInfo info = getPrivateKeyInfo();
- int orderBitLength;
- if (ecSpec == null)
- {
- orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS());
- }
- else
- {
- orderBitLength = ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS());
- }
-
- PrivateKeyInfo info;
- org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
+ if (info == null)
+ {
+ return null;
+ }
- if (publicKey != null)
- {
- keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params);
- }
- else
- {
- keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
+ try
+ {
+ encoding = info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
}
- try
- {
- info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure);
+ return Arrays.clone(encoding);
+ }
- return info.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
+ private PrivateKeyInfo getPrivateKeyInfo()
+ {
+ if (privateKeyInfo == null)
{
- return null;
+ X962Parameters params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
+
+ int orderBitLength;
+ if (ecSpec == null)
+ {
+ orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS());
+ }
+ else
+ {
+ orderBitLength = ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS());
+ }
+
+ org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
+
+ if (publicKey != null)
+ {
+ keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params);
+ }
+ else
+ {
+ keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
+ }
+
+ try
+ {
+ privateKeyInfo = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
}
+
+ return privateKeyInfo;
+ }
+
+ public ECPrivateKeyParameters engineGetKeyParameters()
+ {
+ return baseKey;
}
public ECParameterSpec getParams()
@@ -296,7 +343,6 @@
{
return null;
}
-
return EC5Util.convertSpec(ecSpec);
}
@@ -319,10 +365,10 @@
{
return d;
}
-
+
public void setBagAttribute(
ASN1ObjectIdentifier oid,
- ASN1Encodable attribute)
+ ASN1Encodable attribute)
{
attrCarrier.setBagAttribute(oid, attribute);
}
@@ -340,19 +386,37 @@
public void setPointFormat(String style)
{
- withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
}
public boolean equals(Object o)
{
- if (!(o instanceof BCECPrivateKey))
+ if (o instanceof ECPrivateKey)
{
- return false;
+ ECPrivateKey other = (ECPrivateKey)o;
+
+ PrivateKeyInfo info = this.getPrivateKeyInfo();
+ PrivateKeyInfo otherInfo = (other instanceof BCECPrivateKey) ? ((BCECPrivateKey)other).getPrivateKeyInfo() : PrivateKeyInfo.getInstance(other.getEncoded());
+
+ if (info == null || otherInfo == null)
+ {
+ return false;
+ }
+
+ try
+ {
+ boolean algEquals = Arrays.constantTimeAreEqual(info.getPrivateKeyAlgorithm().getEncoded(), otherInfo.getPrivateKeyAlgorithm().getEncoded());
+ boolean keyEquals = Arrays.constantTimeAreEqual(this.getS().toByteArray(), other.getS().toByteArray());
+
+ return algEquals & keyEquals;
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
}
- BCECPrivateKey other = (BCECPrivateKey)o;
-
- return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec()));
+ return false;
}
public int hashCode()
@@ -365,7 +429,7 @@
return ECUtil.privateKeyToString("EC", d, engineGetSpec());
}
- private DERBitString getPublicKeyDetails(BCECPublicKey pub)
+ private ASN1BitString getPublicKeyDetails(BCECPublicKey pub)
{
try
{
@@ -402,4 +466,31 @@
out.writeObject(this.getEncoded());
}
+
+ private static ECPrivateKeyParameters convertToBaseKey(BCECPrivateKey key)
+ {
+ org.bouncycastle.jce.interfaces.ECPrivateKey k = (org.bouncycastle.jce.interfaces.ECPrivateKey)key;
+ org.bouncycastle.jce.spec.ECParameterSpec s = k.getParameters();
+
+ if (s == null)
+ {
+ s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+ }
+
+ if (k.getParameters() instanceof ECNamedCurveParameterSpec)
+ {
+ String name = ((ECNamedCurveParameterSpec)k.getParameters()).getName();
+ if (name != null)
+ {
+ return new ECPrivateKeyParameters(
+ k.getD(),
+ new ECNamedDomainParameters(ECNamedCurveTable.getOID(name),
+ s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
+ }
+ }
+
+ return new ECPrivateKeyParameters(
+ k.getD(),
+ new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
index cad65c4..bb66f71 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
@@ -9,9 +9,9 @@
import java.security.spec.ECPublicKeySpec;
import java.security.spec.EllipticCurve;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
@@ -28,6 +28,7 @@
import org.bouncycastle.jce.interfaces.ECPointEncoder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Properties;
public class BCECPublicKey
@@ -41,6 +42,8 @@
private transient ECPublicKeyParameters ecPublicKey;
private transient ECParameterSpec ecSpec;
private transient ProviderConfiguration configuration;
+ private transient byte[] encoding;
+ private transient boolean oldPcSet;
public BCECPublicKey(
String algorithm,
@@ -193,7 +196,7 @@
ECCurve curve = EC5Util.getCurve(configuration, params);
ecSpec = EC5Util.convertToSpec(params, curve);
- DERBitString bits = info.getPublicKeyData();
+ ASN1BitString bits = info.getPublicKeyData();
byte[] data = bits.getBytes();
ASN1OctetString key = new DEROctetString(data);
@@ -235,16 +238,23 @@
public byte[] getEncoded()
{
- boolean compress = withCompression || Properties.isOverrideSet("org.bouncycastle.ec.enable_pc");
+ boolean pcSet = Properties.isOverrideSet("org.bouncycastle.ec.enable_pc");
+ if (encoding == null || oldPcSet != pcSet)
+ {
+ boolean compress = withCompression || pcSet;
- AlgorithmIdentifier algId = new AlgorithmIdentifier(
- X9ObjectIdentifiers.id_ecPublicKey,
- ECUtils.getDomainParametersFromName(ecSpec, compress));
+ AlgorithmIdentifier algId = new AlgorithmIdentifier(
+ X9ObjectIdentifiers.id_ecPublicKey,
+ ECUtils.getDomainParametersFromName(ecSpec, compress));
- byte[] pubKeyOctets = ecPublicKey.getQ().getEncoded(compress);
+ byte[] pubKeyOctets = ecPublicKey.getQ().getEncoded(compress);
- // stored curve is null if ImplicitlyCa
- return KeyUtil.getEncodedSubjectPublicKeyInfo(algId, pubKeyOctets);
+ // stored curve is null if ImplicitlyCa
+ encoding = KeyUtil.getEncodedSubjectPublicKeyInfo(algId, pubKeyOctets);
+ oldPcSet = pcSet;
+ }
+
+ return Arrays.clone(encoding);
}
public ECParameterSpec getParams()
@@ -302,18 +312,26 @@
public void setPointFormat(String style)
{
withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ encoding = null;
}
public boolean equals(Object o)
{
- if (!(o instanceof BCECPublicKey))
+ if (o instanceof BCECPublicKey)
{
- return false;
+ BCECPublicKey other = (BCECPublicKey)o;
+
+ return ecPublicKey.getQ().equals(other.ecPublicKey.getQ()) && (engineGetSpec().equals(other.engineGetSpec()));
}
- BCECPublicKey other = (BCECPublicKey)o;
+ if (o instanceof ECPublicKey)
+ {
+ ECPublicKey other = (ECPublicKey)o;
- return ecPublicKey.getQ().equals(other.ecPublicKey.getQ()) && (engineGetSpec().equals(other.engineGetSpec()));
+ return Arrays.areEqual(getEncoded(), other.getEncoded());
+ }
+
+ return false;
}
public int hashCode()
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
index 4070b1c..ec97fe1 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
@@ -2,9 +2,11 @@
import java.math.BigInteger;
import java.security.InvalidKeyException;
+import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
+import java.util.Map;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERNull;
@@ -14,6 +16,7 @@
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.math.ec.ECCurve;
@@ -26,39 +29,49 @@
return (key instanceof BCECPublicKey) ? ((BCECPublicKey)key).engineGetKeyParameters() : ECUtil.generatePublicKeyParameter(key);
}
- static X9ECParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec)
+ static AsymmetricKeyParameter generatePrivateKeyParameter(
+ PrivateKey key)
+ throws InvalidKeyException
{
- return getDomainParametersFromName(genSpec.getName());
+ return (key instanceof BCECPrivateKey) ? ((BCECPrivateKey)key).engineGetKeyParameters() : ECUtil.generatePrivateKeyParameter(key);
}
- static X9ECParameters getDomainParametersFromName(String curveName)
+ static X9ECParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec, ProviderConfiguration configuration)
{
- X9ECParameters domainParameters;
- try
+ return getDomainParametersFromName(genSpec.getName(), configuration);
+ }
+
+ static X9ECParameters getDomainParametersFromName(String curveName, ProviderConfiguration configuration)
+ {
+ if (null == curveName || curveName.length() < 1)
{
- if (curveName.charAt(0) >= '0' && curveName.charAt(0) <= '2')
+ return null;
+ }
+
+ int spacePos = curveName.indexOf(' ');
+ if (spacePos > 0)
+ {
+ curveName = curveName.substring(spacePos + 1);
+ }
+
+ ASN1ObjectIdentifier oid = getOID(curveName);
+ if (null == oid)
+ {
+ return ECUtil.getNamedCurveByName(curveName);
+ }
+
+ X9ECParameters x9 = ECUtil.getNamedCurveByOid(oid);
+ if (null == x9)
+ {
+ if (null != configuration)
{
- ASN1ObjectIdentifier oidID = new ASN1ObjectIdentifier(curveName);
- domainParameters = ECUtil.getNamedCurveByOid(oidID);
- }
- else
- {
- if (curveName.indexOf(' ') > 0)
- {
- curveName = curveName.substring(curveName.indexOf(' ') + 1);
- domainParameters = ECUtil.getNamedCurveByName(curveName);
- }
- else
- {
- domainParameters = ECUtil.getNamedCurveByName(curveName);
- }
+ Map extraCurves = configuration.getAdditionalECParameters();
+
+ x9 = (X9ECParameters)extraCurves.get(oid);
}
}
- catch (IllegalArgumentException ex)
- {
- domainParameters = ECUtil.getNamedCurveByName(curveName);
- }
- return domainParameters;
+
+ return x9;
}
static X962Parameters getDomainParametersFromName(ECParameterSpec ecSpec, boolean withCompression)
@@ -94,4 +107,20 @@
return params;
}
+
+ private static ASN1ObjectIdentifier getOID(String curveName)
+ {
+ char firstChar = curveName.charAt(0);
+ if (firstChar >= '0' && firstChar <= '2')
+ {
+ try
+ {
+ return new ASN1ObjectIdentifier(curveName);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ return null;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java
new file mode 100644
index 0000000..e1d509a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java
@@ -0,0 +1,249 @@
+package org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.util.Hashtable;
+
+import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
+import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
+import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
+import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
+import org.bouncycastle.jce.spec.ECNamedCurveSpec;
+import org.bouncycastle.jce.spec.ECParameterSpec;
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.util.Integers;
+
+public abstract class GMKeyPairGeneratorSpi
+ extends java.security.KeyPairGenerator
+{
+ public GMKeyPairGeneratorSpi(String algorithmName)
+ {
+ super(algorithmName);
+ }
+
+ public static class BaseSM2
+ extends GMKeyPairGeneratorSpi
+ {
+ ECKeyGenerationParameters param;
+ ECKeyPairGenerator engine = new ECKeyPairGenerator();
+ Object ecParams = null;
+ int strength = 239;
+ SecureRandom random = CryptoServicesRegistrar.getSecureRandom();
+ boolean initialised = false;
+ String algorithm;
+ ProviderConfiguration configuration;
+
+ static private Hashtable ecParameters;
+
+ static
+ {
+ ecParameters = new Hashtable();
+
+ ecParameters.put(Integers.valueOf(192), new ECNamedCurveGenParameterSpec("prime192v1")); // a.k.a P-192
+ ecParameters.put(Integers.valueOf(239), new ECNamedCurveGenParameterSpec("prime239v1"));
+ ecParameters.put(Integers.valueOf(256), new ECNamedCurveGenParameterSpec("prime256v1")); // a.k.a P-256
+
+ ecParameters.put(Integers.valueOf(224), new ECNamedCurveGenParameterSpec("P-224"));
+ ecParameters.put(Integers.valueOf(384), new ECNamedCurveGenParameterSpec("P-384"));
+ ecParameters.put(Integers.valueOf(521), new ECNamedCurveGenParameterSpec("P-521"));
+ }
+
+ public BaseSM2()
+ {
+ super("EC");
+ this.algorithm = "EC";
+ this.configuration = BouncyCastleProvider.CONFIGURATION;
+ }
+
+ public BaseSM2(
+ String algorithm,
+ ProviderConfiguration configuration)
+ {
+ super(algorithm);
+ this.algorithm = algorithm;
+ this.configuration = configuration;
+ }
+
+ public void initialize(
+ int strength,
+ SecureRandom random)
+ {
+ this.strength = strength;
+ this.random = random;
+
+ ECNamedCurveGenParameterSpec ecParams = (ECNamedCurveGenParameterSpec)ecParameters.get(Integers.valueOf(strength));
+ if (ecParams == null)
+ {
+ throw new InvalidParameterException("unknown key size.");
+ }
+
+ try
+ {
+ initialize(ecParams, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ throw new InvalidParameterException("key size not configurable.");
+ }
+ }
+
+ public void initialize(
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ if (params == null)
+ {
+ ECParameterSpec implicitCA = configuration.getEcImplicitlyCa();
+ if (implicitCA == null)
+ {
+ throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set");
+ }
+
+ this.ecParams = null;
+ this.param = createKeyGenParamsBC(implicitCA, random);
+ }
+ else if (params instanceof ECParameterSpec)
+ {
+ this.ecParams = params;
+ this.param = createKeyGenParamsBC((ECParameterSpec)params, random);
+ }
+ else if (params instanceof java.security.spec.ECParameterSpec)
+ {
+ this.ecParams = params;
+ this.param = createKeyGenParamsJCE((java.security.spec.ECParameterSpec)params, random);
+ }
+ else if (params instanceof ECGenParameterSpec)
+ {
+ initializeNamedCurve(((ECGenParameterSpec)params).getName(), random);
+ }
+ else if (params instanceof ECNamedCurveGenParameterSpec)
+ {
+ initializeNamedCurve(((ECNamedCurveGenParameterSpec)params).getName(), random);
+ }
+ else
+ {
+ String name = ECUtil.getNameFrom(params);
+
+ if (name != null)
+ {
+ initializeNamedCurve(name, random);
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("invalid parameterSpec: " + params);
+ }
+ }
+
+ engine.init(param);
+ initialised = true;
+ }
+
+ public KeyPair generateKeyPair()
+ {
+ if (!initialised)
+ {
+ initialize(strength, new SecureRandom());
+ }
+
+ AsymmetricCipherKeyPair pair = engine.generateKeyPair();
+ ECPublicKeyParameters pub = (ECPublicKeyParameters)pair.getPublic();
+ ECPrivateKeyParameters priv = (ECPrivateKeyParameters)pair.getPrivate();
+
+ if (ecParams instanceof ECParameterSpec)
+ {
+ ECParameterSpec p = (ECParameterSpec)ecParams;
+
+ BCECPublicKey pubKey = new BCECPublicKey(algorithm, pub, p, configuration);
+ return new KeyPair(pubKey,
+ new BCECPrivateKey(algorithm, priv, pubKey, p, configuration));
+ }
+ else if (ecParams == null)
+ {
+ return new KeyPair(new BCECPublicKey(algorithm, pub, configuration),
+ new BCECPrivateKey(algorithm, priv, configuration));
+ }
+ else
+ {
+ java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams;
+
+ BCECPublicKey pubKey = new BCECPublicKey(algorithm, pub, p, configuration);
+
+ return new KeyPair(pubKey, new BCECPrivateKey(algorithm, priv, pubKey, p, configuration));
+ }
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsBC(ECParameterSpec p, SecureRandom r)
+ {
+ return new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH()), r);
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsJCE(java.security.spec.ECParameterSpec p, SecureRandom r)
+ {
+ if (p instanceof ECNamedCurveSpec)
+ {
+ String curveName = ((ECNamedCurveSpec)p).getName();
+
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null != x9)
+ {
+ return createKeyGenParamsJCE(x9, r);
+ }
+ }
+
+ ECCurve curve = EC5Util.convertCurve(p.getCurve());
+ ECPoint g = EC5Util.convertPoint(curve, p.getGenerator());
+ BigInteger n = p.getOrder();
+ BigInteger h = BigInteger.valueOf(p.getCofactor());
+ ECDomainParameters dp = new ECDomainParameters(curve, g, n, h);
+ return new ECKeyGenerationParameters(dp, r);
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsJCE(X9ECParameters x9, SecureRandom r)
+ {
+ ECDomainParameters dp = new ECDomainParameters(x9.getCurve(), x9.getG(), x9.getN(), x9.getH());
+
+ return new ECKeyGenerationParameters(dp, r);
+ }
+
+ protected void initializeNamedCurve(String curveName, SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null == x9)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
+ }
+
+ // Work-around for JDK bug -- it won't look up named curves properly if seed is present
+ byte[] seed = null; //p.getSeed();
+
+ this.ecParams = new ECNamedCurveSpec(curveName, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), seed);
+ this.param = createKeyGenParamsJCE(x9, random);
+ }
+ }
+
+ public static class SM2
+ extends BaseSM2
+ {
+ public SM2()
+ {
+ super("SM2", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+}
\ No newline at end of file
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 7070df8..b4faf37 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
@@ -195,21 +195,18 @@
return null;
}
- protected void engineInit(
- Key key,
- AlgorithmParameterSpec params,
- SecureRandom random)
+ protected void doInitFromKey(Key key, AlgorithmParameterSpec parameterSpec, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
// Android-removed: Unsupported algorithms
- // if (params != null &&
- // !(params instanceof MQVParameterSpec || params instanceof UserKeyingMaterialSpec || params instanceof DHUParameterSpec))
- if (params != null && !(params instanceof UserKeyingMaterialSpec))
+ // if (parameterSpec != null &&
+ // !(parameterSpec instanceof MQVParameterSpec || parameterSpec instanceof UserKeyingMaterialSpec || params instanceof DHUParameterSpec))
+ if (parameterSpec != null && !(parameterSpec instanceof UserKeyingMaterialSpec))
{
throw new InvalidAlgorithmParameterException("No algorithm parameters supported");
}
- initFromKey(key, params);
+ initFromKey(key, parameterSpec);
}
protected void engineInit(
@@ -249,9 +246,9 @@
{
MQVPrivateKey mqvPrivKey = (MQVPrivateKey)key;
staticPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey());
+ ECUtils.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey());
ephemPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey());
+ ECUtils.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey());
ephemPubKey = null;
if (mqvPrivKey.getEphemeralPublicKey() != null)
@@ -265,9 +262,9 @@
MQVParameterSpec mqvParameterSpec = (MQVParameterSpec)parameterSpec;
staticPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ ECUtils.generatePrivateKeyParameter((PrivateKey)key);
ephemPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(mqvParameterSpec.getEphemeralPrivateKey());
+ ECUtils.generatePrivateKeyParameter(mqvParameterSpec.getEphemeralPrivateKey());
ephemPubKey = null;
if (mqvParameterSpec.getEphemeralPublicKey() != null)
@@ -299,9 +296,9 @@
ECPublicKeyParameters ephemPubKey;
staticPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ ECUtils.generatePrivateKeyParameter((PrivateKey)key);
ephemPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(dheParameterSpec.getEphemeralPrivateKey());
+ ECUtils.generatePrivateKeyParameter(dheParameterSpec.getEphemeralPrivateKey());
ephemPubKey = null;
if (dheParameterSpec.getEphemeralPublicKey() != null)
@@ -330,7 +327,7 @@
{
throw new InvalidAlgorithmParameterException("no KDF specified for UserKeyingMaterialSpec");
}
- ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtils.generatePrivateKeyParameter((PrivateKey)key);
this.parameters = privKey.getParameters();
ukmParameters = (parameterSpec instanceof UserKeyingMaterialSpec) ? ((UserKeyingMaterialSpec)parameterSpec).getUserKeyingMaterial() : null;
((BasicAgreement)agreement).init(privKey);
@@ -344,7 +341,7 @@
return fullName.substring(fullName.lastIndexOf('.') + 1);
}
- protected byte[] calcSecret()
+ protected byte[] doCalcSecret()
{
return Arrays.clone(result);
}
@@ -757,8 +754,8 @@
{
super("ECKAEGwithSHA1KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA1()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -770,8 +767,8 @@
{
super("ECKAEGwithRIPEMD160KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(new RIPEMD160Digest()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -783,8 +780,8 @@
{
super("ECKAEGwithSHA224KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA224()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -796,8 +793,8 @@
{
super("ECKAEGwithSHA256KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA256()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -809,8 +806,8 @@
{
super("ECKAEGwithSHA384KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA384()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
index 9a5f0ed..d16f62f 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
@@ -237,7 +237,11 @@
try
{
- return new BCECPrivateKey(algorithm, new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ecKey.getParameters()), ecKey), configuration);
+ return new BCECPrivateKey(algorithm,
+ new PrivateKeyInfo(
+ new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ecKey.getParametersObject()),
+ ecKey),
+ configuration);
}
catch (IOException e)
{
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 6636662..e17fe03 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
@@ -8,10 +8,7 @@
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.util.Hashtable;
-import java.util.Map;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
@@ -56,7 +53,8 @@
static private Hashtable ecParameters;
- static {
+ static
+ {
ecParameters = new Hashtable();
ecParameters.put(Integers.valueOf(192), new ECGenParameterSpec("prime192v1")); // a.k.a P-192
@@ -213,13 +211,12 @@
{
if (p instanceof ECNamedCurveSpec)
{
- X9ECParameters x9P = ECUtils.getDomainParametersFromName(((ECNamedCurveSpec)p).getName());
+ String curveName = ((ECNamedCurveSpec)p).getName();
- if (x9P != null)
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null != x9)
{
- ECDomainParameters dp = new ECDomainParameters(x9P.getCurve(), x9P.getG(), x9P.getN(), x9P.getH());
-
- return new ECKeyGenerationParameters(dp, r);
+ return createKeyGenParamsJCE(x9, r);
}
}
@@ -231,48 +228,27 @@
return new ECKeyGenerationParameters(dp, r);
}
- protected ECNamedCurveSpec createNamedCurveSpec(String curveName)
- throws InvalidAlgorithmParameterException
+ protected ECKeyGenerationParameters createKeyGenParamsJCE(X9ECParameters x9, SecureRandom r)
{
- // NOTE: Don't bother with custom curves here as the curve will be converted to JCE type shortly
+ ECDomainParameters dp = new ECDomainParameters(x9.getCurve(), x9.getG(), x9.getN(), x9.getH());
- X9ECParameters p = ECUtils.getDomainParametersFromName(curveName);
- if (p == null)
- {
- try
- {
- // Check whether it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug)
- p = ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(curveName));
- if (p == null)
- {
- Map extraCurves = configuration.getAdditionalECParameters();
-
- p = (X9ECParameters)extraCurves.get(new ASN1ObjectIdentifier(curveName));
-
- if (p == null)
- {
- throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName);
- }
- }
- }
- catch (IllegalArgumentException ex)
- {
- throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
- }
- }
-
- // Work-around for JDK bug -- it won't look up named curves properly if seed is present
- byte[] seed = null; //p.getSeed();
-
- return new ECNamedCurveSpec(curveName, p.getCurve(), p.getG(), p.getN(), p.getH(), seed);
+ return new ECKeyGenerationParameters(dp, r);
}
protected void initializeNamedCurve(String curveName, SecureRandom random)
throws InvalidAlgorithmParameterException
{
- ECNamedCurveSpec namedCurve = createNamedCurveSpec(curveName);
- this.ecParams = namedCurve;
- this.param = createKeyGenParamsJCE(namedCurve, random);
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null == x9)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
+ }
+
+ // Work-around for JDK bug -- it won't look up named curves properly if seed is present
+ byte[] seed = null; //p.getSeed();
+
+ this.ecParams = new ECNamedCurveSpec(curveName, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), seed);
+ this.param = createKeyGenParamsJCE(x9, random);
}
}
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 9635e18..427dae9 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
@@ -11,6 +11,7 @@
import org.bouncycastle.crypto.digests.NullDigest;
// BEGIN Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
+// import org.bouncycastle.crypto.digests.SHAKEDigest;
// END Android-removed: Unsupported algorithms
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.signers.DSAEncoding;
@@ -25,7 +26,6 @@
// import org.bouncycastle.crypto.util.DigestFactory;
import org.bouncycastle.crypto.digests.AndroidDigestFactory;
import org.bouncycastle.jcajce.provider.asymmetric.util.DSABase;
-import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
public class SignatureSpi
extends DSABase
@@ -48,7 +48,7 @@
PrivateKey privateKey)
throws InvalidKeyException
{
- CipherParameters param = ECUtil.generatePrivateKeyParameter(privateKey);
+ CipherParameters param = ECUtils.generatePrivateKeyParameter(privateKey);
digest.reset();
@@ -275,6 +275,26 @@
}
}
+ static public class ecDSAShake128
+ extends SignatureSpi
+ {
+ public ecDSAShake128()
+ {
+ // RFC 8702 specifies deterministic DSA
+ super(new SHAKEDigest(128), new ECDSASigner(new HMacDSAKCalculator(new SHAKEDigest(128))), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDSAShake256
+ extends SignatureSpi
+ {
+ public ecDSAShake256()
+ {
+ // RFC 8702 specifies deterministic DSA
+ super(new SHAKEDigest(256), new ECDSASigner(new HMacDSAKCalculator(new SHAKEDigest(256))), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
static public class ecNR
extends SignatureSpi
{
@@ -373,6 +393,41 @@
super(new RIPEMD160Digest(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
}
}
+ static public class ecCVCDSA3_224
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_224()
+ {
+ super(DigestFactory.createSHA3_224(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA3_256
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_256()
+ {
+ super(DigestFactory.createSHA3_256(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA3_384
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_384()
+ {
+ super(DigestFactory.createSHA3_384(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA3_512
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_512()
+ {
+ super(DigestFactory.createSHA3_512(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
}
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 fc37d6e..baa4ed9 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
@@ -11,9 +11,11 @@
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
@@ -174,16 +176,36 @@
throws IOException
{
PSSParameterSpec pssSpec = currentSpec;
- AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(
- DigestFactory.getOID(pssSpec.getDigestAlgorithm()),
- DERNull.INSTANCE);
- MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters();
- AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
- PKCSObjectIdentifiers.id_mgf1,
- new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
- RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField()));
+ ASN1ObjectIdentifier digOid = DigestFactory.getOID(pssSpec.getDigestAlgorithm());
+ AlgorithmIdentifier hashAlgorithm;
+ // RFC 8072
+ if (NISTObjectIdentifiers.id_shake128.equals(digOid) || NISTObjectIdentifiers.id_shake256.equals(digOid))
+ {
+ hashAlgorithm = new AlgorithmIdentifier(digOid);
+ }
+ else
+ {
+ hashAlgorithm = new AlgorithmIdentifier(digOid, DERNull.INSTANCE);
+ }
- return pssP.getEncoded("DER");
+ MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters();
+ if (mgfSpec != null)
+ {
+ AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
+ PKCSObjectIdentifiers.id_mgf1,
+ new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
+ RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField()));
+
+ return pssP.getEncoded("DER");
+ }
+ else
+ {
+ AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
+ pssSpec.getMGFAlgorithm().equals("SHAKE128") ? NISTObjectIdentifiers.id_shake128 : NISTObjectIdentifiers.id_shake256);
+ RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField()));
+
+ return pssP.getEncoded("DER");
+ }
}
protected byte[] engineGetEncoded(
@@ -231,17 +253,29 @@
{
RSASSAPSSparams pssP = RSASSAPSSparams.getInstance(params);
- if (!pssP.getMaskGenAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1))
+ ASN1ObjectIdentifier mgfOid = pssP.getMaskGenAlgorithm().getAlgorithm();
+ if (mgfOid.equals(PKCSObjectIdentifiers.id_mgf1))
+ {
+ currentSpec = new PSSParameterSpec(
+ MessageDigestUtils.getDigestName(pssP.getHashAlgorithm().getAlgorithm()),
+ PSSParameterSpec.DEFAULT.getMGFAlgorithm(),
+ new MGF1ParameterSpec(MessageDigestUtils.getDigestName(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getAlgorithm())),
+ pssP.getSaltLength().intValue(),
+ pssP.getTrailerField().intValue());
+ }
+ else if (mgfOid.equals(NISTObjectIdentifiers.id_shake128) || mgfOid.equals(NISTObjectIdentifiers.id_shake256))
+ {
+ currentSpec = new PSSParameterSpec(
+ MessageDigestUtils.getDigestName(pssP.getHashAlgorithm().getAlgorithm()),
+ mgfOid.equals(NISTObjectIdentifiers.id_shake128) ? "SHAKE128" : "SHAKE256",
+ null,
+ pssP.getSaltLength().intValue(),
+ pssP.getTrailerField().intValue());
+ }
+ else
{
throw new IOException("unknown mask generation function: " + pssP.getMaskGenAlgorithm().getAlgorithm());
}
-
- currentSpec = new PSSParameterSpec(
- MessageDigestUtils.getDigestName(pssP.getHashAlgorithm().getAlgorithm()),
- PSSParameterSpec.DEFAULT.getMGFAlgorithm(),
- new MGF1ParameterSpec(MessageDigestUtils.getDigestName(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getAlgorithm())),
- pssP.getSaltLength().intValue(),
- pssP.getTrailerField().intValue());
}
catch (ClassCastException e)
{
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 274f6fa..141bbff 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
@@ -30,7 +30,6 @@
// Android-removed: Unsupported algorithm
// import org.bouncycastle.crypto.encodings.ISO9796d1Encoding;
import org.bouncycastle.crypto.encodings.OAEPEncoding;
-import org.bouncycastle.crypto.encodings.PKCS1Encoding;
import org.bouncycastle.crypto.engines.RSABlindedEngine;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi;
@@ -205,7 +204,7 @@
}
else if (pad.equals("PKCS1PADDING"))
{
- cipher = new PKCS1Encoding(new RSABlindedEngine());
+ cipher = new CustomPKCS1Encoding(new RSABlindedEngine());
}
// BEGIN Android-removed: Unsupported algorithm
// else if (pad.equals("ISO9796-1PADDING"))
@@ -542,15 +541,26 @@
{
try
{
- return cipher.processBlock(bOut.getBuf(), 0, bOut.size());
- }
- catch (InvalidCipherTextException e)
- {
- throw new BadBlockException("unable to decrypt block", e);
- }
- catch (ArrayIndexOutOfBoundsException e)
- {
- throw new BadBlockException("unable to decrypt block", e);
+ byte[] output;
+ try
+ {
+ output = cipher.processBlock(bOut.getBuf(), 0, bOut.size());
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new BadBlockException("unable to decrypt block", e);
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ throw new BadBlockException("unable to decrypt block", e);
+ }
+
+ if (output == null)
+ {
+ throw new BadBlockException("unable to decrypt block", null);
+ }
+
+ return output;
}
finally
{
@@ -578,7 +588,7 @@
{
public PKCS1v1_5Padding()
{
- super(new PKCS1Encoding(new RSABlindedEngine()));
+ super(new CustomPKCS1Encoding(new RSABlindedEngine()));
}
}
@@ -587,7 +597,7 @@
{
public PKCS1v1_5Padding_PrivateOnly()
{
- super(false, true, new PKCS1Encoding(new RSABlindedEngine()));
+ super(false, true, new CustomPKCS1Encoding(new RSABlindedEngine()));
}
}
@@ -596,7 +606,7 @@
{
public PKCS1v1_5Padding_PublicOnly()
{
- super(true, false, new PKCS1Encoding(new RSABlindedEngine()));
+ super(true, false, new CustomPKCS1Encoding(new RSABlindedEngine()));
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java
new file mode 100644
index 0000000..1fc4334
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java
@@ -0,0 +1,263 @@
+package org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.security.SecureRandom;
+
+import org.bouncycastle.crypto.AsymmetricBlockCipher;
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.encodings.PKCS1Encoding;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Properties;
+
+/**
+ * this does your basic PKCS 1 v1.5 padding - whether or not you should be using this
+ * depends on your application - see PKCS1 Version 2 for details.
+ */
+class CustomPKCS1Encoding
+ implements AsymmetricBlockCipher
+{
+ private static final int HEADER_LENGTH = 10;
+
+ private SecureRandom random;
+ private AsymmetricBlockCipher engine;
+ private boolean forEncryption;
+ private boolean forPrivateKey;
+ private boolean useStrictLength;
+ private byte[] blockBuffer;
+
+ /**
+ * Basic constructor.
+ *
+ * @param cipher
+ */
+ CustomPKCS1Encoding(AsymmetricBlockCipher cipher)
+ {
+ this.engine = cipher;
+ this.useStrictLength = useStrict();
+ }
+
+ //
+ // for J2ME compatibility
+ //
+ private boolean useStrict()
+ {
+ if (Properties.isOverrideSetTo(PKCS1Encoding.NOT_STRICT_LENGTH_ENABLED_PROPERTY, true))
+ {
+ return false;
+ }
+
+ return !Properties.isOverrideSetTo(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY, false);
+ }
+
+ public AsymmetricBlockCipher getUnderlyingCipher()
+ {
+ return engine;
+ }
+
+ public void init(boolean forEncryption, CipherParameters param)
+ {
+ AsymmetricKeyParameter kParam;
+
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+ this.random = rParam.getRandom();
+ kParam = (AsymmetricKeyParameter)rParam.getParameters();
+ }
+ else
+ {
+ kParam = (AsymmetricKeyParameter)param;
+ if (!kParam.isPrivate() && forEncryption)
+ {
+ this.random = CryptoServicesRegistrar.getSecureRandom();
+ }
+ }
+
+ engine.init(forEncryption, param);
+
+ this.forPrivateKey = kParam.isPrivate();
+ this.forEncryption = forEncryption;
+ this.blockBuffer = new byte[engine.getOutputBlockSize()];
+ }
+
+ public int getInputBlockSize()
+ {
+ int baseBlockSize = engine.getInputBlockSize();
+
+ if (forEncryption)
+ {
+ return baseBlockSize - HEADER_LENGTH;
+ }
+ else
+ {
+ return baseBlockSize;
+ }
+ }
+
+ public int getOutputBlockSize()
+ {
+ int baseBlockSize = engine.getOutputBlockSize();
+
+ if (forEncryption)
+ {
+ return baseBlockSize;
+ }
+ else
+ {
+ return baseBlockSize - HEADER_LENGTH;
+ }
+ }
+
+ public byte[] processBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException
+ {
+ if (forEncryption)
+ {
+ return encodeBlock(in, inOff, inLen);
+ }
+ else
+ {
+ return decodeBlock(in, inOff, inLen);
+ }
+ }
+
+ private byte[] encodeBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException
+ {
+ if (inLen > getInputBlockSize())
+ {
+ throw new IllegalArgumentException("input data too large");
+ }
+
+ byte[] block = new byte[engine.getInputBlockSize()];
+
+ if (forPrivateKey)
+ {
+ block[0] = 0x01; // type code 1
+
+ for (int i = 1; i != block.length - inLen - 1; i++)
+ {
+ block[i] = (byte)0xFF;
+ }
+ }
+ else
+ {
+ random.nextBytes(block); // random fill
+
+ block[0] = 0x02; // type code 2
+
+ //
+ // a zero byte marks the end of the padding, so all
+ // the pad bytes must be non-zero.
+ //
+ for (int i = 1; i != block.length - inLen - 1; i++)
+ {
+ while (block[i] == 0)
+ {
+ block[i] = (byte)random.nextInt();
+ }
+ }
+ }
+
+ block[block.length - inLen - 1] = 0x00; // mark the end of the padding
+ System.arraycopy(in, inOff, block, block.length - inLen, inLen);
+
+ return engine.processBlock(block, 0, block.length);
+ }
+
+ /**
+ * Check the argument is a valid encoding with type 1. Returns the plaintext length if valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding1(byte[] buf)
+ {
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
+
+ // The first byte should be 0x01
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x01);
+
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
+ {
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ int is0xFFMask = ((padByte ^ 0xFF) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ badPadSign |= ~(foundZeroMask | is0xFFMask);
+ }
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
+ }
+
+ /**
+ * Check the argument is a valid encoding with type 2. Returns the plaintext length if valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding2(byte[] buf)
+ {
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
+
+ // The first byte should be 0x02
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x02);
+
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
+ {
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ }
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
+ }
+
+ /**
+ * @throws InvalidCipherTextException if the decrypted block is not in PKCS1 format.
+ */
+ private byte[] decodeBlock(byte[] in, int inOff, int inLen)
+ throws InvalidCipherTextException
+ {
+ int strictBlockSize = engine.getOutputBlockSize();
+ byte[] block = engine.processBlock(in, inOff, inLen);
+
+ boolean incorrectLength = useStrictLength & (block.length != strictBlockSize);
+
+ byte[] data = block;
+ if (block.length < strictBlockSize)
+ {
+ data = blockBuffer;
+ }
+
+ int plaintextLength = forPrivateKey ? checkPkcs1Encoding2(data) : checkPkcs1Encoding1(data);
+
+ try
+ {
+ if (plaintextLength < 0 | incorrectLength)
+ {
+ // Special behaviour to avoid throw/catch/throw in CipherSpi
+ return null;
+ }
+
+ byte[] result = new byte[plaintextLength];
+ System.arraycopy(data, data.length - plaintextLength, result, 0, plaintextLength);
+ return result;
+ }
+ finally
+ {
+ Arrays.fill(block, (byte)0);
+ Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0);
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
index b449dc5..850031c 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
@@ -1,6 +1,11 @@
package org.bouncycastle.jcajce.provider.asymmetric.util;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
@@ -26,6 +31,7 @@
// import org.bouncycastle.crypto.agreement.kdf.DHKEKGenerator;
import org.bouncycastle.crypto.params.DESParameters;
import org.bouncycastle.crypto.params.KDFParameters;
+import org.bouncycastle.jcajce.spec.HybridValueParameterSpec;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Integers;
import org.bouncycastle.util.Strings;
@@ -148,6 +154,7 @@
protected final DerivationFunction kdf;
protected byte[] ukmParameters;
+ private HybridValueParameterSpec hybridSpec;
public BaseAgreementSpi(String kaAlgorithm, DerivationFunction kdf)
{
@@ -221,6 +228,40 @@
}
}
+ protected void engineInit(
+ Key key,
+ SecureRandom random)
+ throws InvalidKeyException
+ {
+ try
+ {
+ doInitFromKey(key, null, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ // this should never occur.
+ throw new InvalidKeyException(e.getMessage());
+ }
+ }
+
+ protected void engineInit(
+ Key key,
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ if (params instanceof HybridValueParameterSpec)
+ {
+ this.hybridSpec = (HybridValueParameterSpec)params;
+ doInitFromKey(key, hybridSpec.getBaseParameterSpec(), random);
+ }
+ else
+ {
+ this.hybridSpec = null;
+ doInitFromKey(key, params, random);
+ }
+ }
+
protected byte[] engineGenerateSecret()
throws IllegalStateException
{
@@ -347,5 +388,26 @@
}
}
- protected abstract byte[] calcSecret();
+ private byte[] calcSecret()
+ {
+ if (hybridSpec != null)
+ {
+ // Set Z' to Z || T
+ byte[] s = doCalcSecret();
+ byte[] sec = Arrays.concatenate(s, hybridSpec.getT());
+
+ Arrays.clear(s);
+
+ return sec;
+ }
+ else
+ {
+ return doCalcSecret();
+ }
+ }
+
+ protected abstract byte[] doCalcSecret();
+
+ protected abstract void doInitFromKey(Key key, AlgorithmParameterSpec parameterSpec, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
index 7741339..a01f9a8 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
@@ -19,6 +19,7 @@
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.asn1.x9.X9ECParametersHolder;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
@@ -35,20 +36,41 @@
public class EC5Util
{
- private static Map customCurves = new HashMap();
-
- static
+ private static class CustomCurves
{
- Enumeration e = CustomNamedCurves.getNames();
- while (e.hasMoreElements())
- {
- String name = (String)e.nextElement();
+ private static Map CURVE_MAP = createCurveMap();
- X9ECParameters curveParams = ECNamedCurveTable.getByName(name);
- if (curveParams != null) // there may not be a regular curve, may just be a custom curve.
+ private static Map createCurveMap()
+ {
+ Map map = new HashMap();
+
+ Enumeration e = CustomNamedCurves.getNames();
+ while (e.hasMoreElements())
{
- customCurves.put(curveParams.getCurve(), CustomNamedCurves.getByName(name).getCurve());
+ String name = (String)e.nextElement();
+
+ X9ECParametersHolder curveParams = ECNamedCurveTable.getByNameLazy(name);
+ if (curveParams != null) // there may not be a regular curve, may just be a custom curve.
+ {
+ ECCurve curve = curveParams.getCurve();
+ if (ECAlgorithms.isFpCurve(curve))
+ {
+ map.put(curve, CustomNamedCurves.getByNameLazy(name).getCurve());
+ }
+ }
}
+
+ ECCurve c_25519 = CustomNamedCurves.getByNameLazy("Curve25519").getCurve();
+
+ map.put(new ECCurve.Fp(
+ c_25519.getField().getCharacteristic(),
+ c_25519.getA().toBigInteger(),
+ c_25519.getB().toBigInteger(),
+ c_25519.getOrder(),
+ c_25519.getCofactor(),
+ true), c_25519);
+
+ return map;
}
// BEGIN Android-removed: Unsupported curves
@@ -65,6 +87,11 @@
), c_25519);
*/
// END Android-removed: Unsupported curves
+ static ECCurve substitute(ECCurve c)
+ {
+ ECCurve custom = (ECCurve)CURVE_MAP.get(c);
+ return null != custom ? custom : c;
+ }
}
public static ECCurve getCurve(
@@ -276,21 +303,14 @@
if (field instanceof ECFieldFp)
{
- ECCurve.Fp curve = new ECCurve.Fp(((ECFieldFp)field).getP(), a, b);
-
- if (customCurves.containsKey(curve))
- {
- return (ECCurve)customCurves.get(curve);
- }
-
- return curve;
+ return CustomCurves.substitute(new ECCurve.Fp(((ECFieldFp)field).getP(), a, b, null, null));
}
else
{
ECFieldF2m fieldF2m = (ECFieldF2m)field;
int m = fieldF2m.getM();
int ks[] = ECUtil.convertMidTerms(fieldF2m.getMidTermsOfReductionPolynomial());
- return new ECCurve.F2m(m, ks[0], ks[1], ks[2], a, b);
+ return new ECCurve.F2m(m, ks[0], ks[1], ks[2], a, b, null, null);
}
}
@@ -304,7 +324,7 @@
{
Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
int[] exponents = poly.getExponentsPresent();
- int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
+ int[] ks = Arrays.reverseInPlace(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
return new ECFieldF2m(poly.getDegree(), ks);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
index 5ab9163..c1c93b8 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
@@ -291,6 +291,11 @@
{
if (order == null) // implicitly CA
{
+ if (configuration == null)
+ {
+ return privateValue.bitLength(); // a guess but better than an exception!
+ }
+
ECParameterSpec implicitCA = configuration.getEcImplicitlyCa();
if (implicitCA == null)
@@ -309,26 +314,24 @@
public static ASN1ObjectIdentifier getNamedCurveOid(
String curveName)
{
- String name = curveName;
+ if (null == curveName || curveName.length() < 1)
+ {
+ return null;
+ }
- int spacePos = name.indexOf(' ');
+ int spacePos = curveName.indexOf(' ');
if (spacePos > 0)
{
- name = name.substring(spacePos + 1);
+ curveName = curveName.substring(spacePos + 1);
}
- try
+ ASN1ObjectIdentifier oid = getOID(curveName);
+ if (null != oid)
{
- if (name.charAt(0) >= '0' && name.charAt(0) <= '2')
- {
- return new ASN1ObjectIdentifier(name);
- }
- }
- catch (IllegalArgumentException ex)
- {
+ return oid;
}
- return ECNamedCurveTable.getOID(name);
+ return ECNamedCurveTable.getOID(curveName);
}
public static ASN1ObjectIdentifier getNamedCurveOid(
@@ -446,4 +449,20 @@
}
});
}
+
+ private static ASN1ObjectIdentifier getOID(String curveName)
+ {
+ char firstChar = curveName.charAt(0);
+ if (firstChar >= '0' && firstChar <= '2')
+ {
+ try
+ {
+ return new ASN1ObjectIdentifier(curveName);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ return null;
+ }
}
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 4b84ddd..9a1d13a 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
@@ -63,10 +63,11 @@
}
private java.security.cert.Certificate readPEMCertificate(
- InputStream in)
+ InputStream in,
+ boolean isFirst)
throws IOException, CertificateParsingException
{
- return getCertificate(PEM_CERT_PARSER.readPEMObject(in));
+ return getCertificate(PEM_CERT_PARSER.readPEMObject(in, isFirst));
}
private java.security.cert.Certificate getCertificate(ASN1Sequence seq)
@@ -121,10 +122,11 @@
}
private CRL readPEMCRL(
- InputStream in)
+ InputStream in,
+ boolean isFirst)
throws IOException, CRLException
{
- return getCRL(PEM_CRL_PARSER.readPEMObject(in));
+ return getCRL(PEM_CRL_PARSER.readPEMObject(in, isFirst));
}
private CRL readDERCRL(
@@ -179,6 +181,14 @@
InputStream in)
throws CertificateException
{
+ return doGenerateCertificate(in, true);
+ }
+
+ private java.security.cert.Certificate doGenerateCertificate(
+ InputStream in,
+ boolean isFirst)
+ throws CertificateException
+ {
if (currentStream == null)
{
currentStream = in;
@@ -252,7 +262,7 @@
if (tag != 0x30) // assume ascii PEM encoded.
{
- return readPEMCertificate(pis);
+ return readPEMCertificate(pis, isFirst);
}
else
{
@@ -284,7 +294,8 @@
// Android-changed: Read from original stream
// while ((cert = engineGenerateCertificate(in)) != null)
- while ((cert = engineGenerateCertificate(inStream)) != null)
+ // if we do read some certificates we'll return them even if junk at end of file
+ while ((cert = doGenerateCertificate(inStream, certs.isEmpty())) != null)
{
certs.add(cert);
}
@@ -300,6 +311,18 @@
InputStream in)
throws CRLException
{
+ return doGenerateCRL(in, true);
+ }
+
+ /**
+ * Generates a certificate revocation list (CRL) object and initializes
+ * it with the data read from the input stream inStream.
+ */
+ private CRL doGenerateCRL(
+ InputStream in,
+ boolean isFirst)
+ throws CRLException
+ {
if (currentCrlStream == null)
{
currentCrlStream = in;
@@ -351,7 +374,7 @@
pis.reset();
if (tag != 0x30) // assume ascii PEM encoded.
{
- return readPEMCRL(pis);
+ return readPEMCRL(pis, isFirst);
}
else
{ // lazy evaluate to help processing of large CRLs
@@ -385,7 +408,8 @@
List crls = new ArrayList();
BufferedInputStream in = new BufferedInputStream(inStream);
- while ((crl = engineGenerateCRL(in)) != null)
+ // if we do read some certificates we'll return them even if junk at end of file
+ while ((crl = doGenerateCRL(in, crls.isEmpty())) != null)
{
crls.add(crl);
}
@@ -433,7 +457,7 @@
return new PKIXCertPath(certificates);
}
- private class ExCertificateException
+ private static class ExCertificateException
extends CertificateException
{
private Throwable cause;
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
index 36c7159..305643e 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
@@ -13,7 +13,7 @@
* current PEM object.
*
*/
- private class Boundaries
+ private static class Boundaries
{
private final String _header;
private final String _footer;
@@ -112,7 +112,8 @@
}
ASN1Sequence readPEMObject(
- InputStream in)
+ InputStream in,
+ boolean isFirst)
throws IOException
{
String line;
@@ -131,6 +132,11 @@
if (header == null)
{
+ if (!isFirst)
+ {
+ // just ignore the data
+ return null;
+ }
throw new IOException("malformed PEM data: no header found");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
index e6c8fe9..e73374d 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
@@ -28,6 +28,7 @@
import javax.security.auth.x500.X500Principal;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1InputStream;
@@ -36,7 +37,6 @@
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.util.ASN1Dump;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
@@ -158,19 +158,6 @@
return null;
}
- public byte[] getEncoded()
- throws CRLException
- {
- try
- {
- return c.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- throw new CRLException(e.toString());
- }
- }
-
public void verify(PublicKey key)
throws CRLException, NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException, SignatureException
@@ -255,7 +242,7 @@
{
List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != pubKeys.size(); i++)
@@ -277,7 +264,7 @@
checkSignature(
(PublicKey)pubKeys.get(i), signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
catch (SignatureException e)
@@ -299,7 +286,7 @@
else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
{
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != sigSeq.size(); i++)
@@ -316,7 +303,7 @@
checkSignature(
key, signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
index 6bc0324..08c6f52 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
@@ -5,25 +5,42 @@
import org.bouncycastle.asn1.x509.CertificateList;
import org.bouncycastle.jcajce.util.JcaJceHelper;
+/**
+ * This class exists to let {@link #equals(Object)} and {@link #hashCode()} methods be delegated efficiently
+ * to the platform default implementations (especially important for compatibility of {@link #hashCode()}
+ * calculations). Those methods fall back to calling {@link #getEncoded()} for third-party subclasses, and
+ * this class allows us to avoid cloning the return value of {@link #getEncoded()} for those callers.
+ */
class X509CRLInternal extends X509CRLImpl
{
private final byte[] encoding;
+ private final CRLException exception;
X509CRLInternal(JcaJceHelper bcHelper, CertificateList c, String sigAlgName, byte[] sigAlgParams, boolean isIndirect,
- byte[] encoding)
+ byte[] encoding, CRLException exception)
{
super(bcHelper, c, sigAlgName, sigAlgParams, isIndirect);
this.encoding = encoding;
+ this.exception = exception;
}
public byte[] getEncoded() throws CRLException
{
+ if (null != exception)
+ {
+ throw exception;
+ }
+
if (null == encoding)
{
throw new CRLException();
}
+ /*
+ * NOTE: Don't clone this return value. See class javadoc for details. Any necessary cloning is
+ * handled by the X509CRLObject that is holding this instance.
+ */
return encoding;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
index 3a1af42..8e4efe2 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
@@ -1,5 +1,6 @@
package org.bouncycastle.jcajce.provider.asymmetric.x509;
+import java.io.IOException;
import java.security.cert.CRLException;
import org.bouncycastle.asn1.ASN1BitString;
@@ -9,6 +10,7 @@
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
import org.bouncycastle.jcajce.util.JcaJceHelper;
+import org.bouncycastle.util.Arrays;
class X509CRLObject
extends X509CRLImpl
@@ -24,6 +26,11 @@
super(bcHelper, c, createSigAlgName(c), createSigAlgParams(c), isIndirectCRL(c));
}
+ public byte[] getEncoded() throws CRLException
+ {
+ return Arrays.clone(getInternalCRL().getEncoded());
+ }
+
public boolean equals(Object other)
{
if (this == other)
@@ -50,6 +57,8 @@
return false;
}
}
+
+ return getInternalCRL().equals(otherBC.getInternalCRL());
}
return getInternalCRL().equals(other);
@@ -76,17 +85,19 @@
}
}
- byte[] encoding;
+ byte[] encoding = null;
+ CRLException exception = null;
try
{
- encoding = getEncoded();
+ encoding = c.getEncoded(ASN1Encoding.DER);
}
- catch (CRLException e)
+ catch (IOException e)
{
- encoding = null;
+ exception = new X509CRLException(e);
}
- X509CRLInternal temp = new X509CRLInternal(bcHelper, c, sigAlgName,sigAlgParams, isIndirect, encoding);
+ X509CRLInternal temp = new X509CRLInternal(bcHelper, c, sigAlgName,sigAlgParams, isIndirect, encoding,
+ exception);
synchronized (cacheLock)
{
@@ -107,7 +118,7 @@
}
catch (Exception e)
{
- throw new CRLException("CRL contents invalid: " + e);
+ throw new X509CRLException("CRL contents invalid: " + e.getMessage(), e);
}
}
@@ -146,4 +157,26 @@
throw new ExtCRLException("Exception reading IssuingDistributionPoint", e);
}
}
+
+ private static class X509CRLException
+ extends CRLException
+ {
+ private final Throwable cause;
+
+ X509CRLException(String msg, Throwable cause)
+ {
+ super(msg);
+ this.cause = cause;
+ }
+
+ X509CRLException(Throwable cause)
+ {
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
index 4907fb5..be27fa8 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
@@ -31,16 +31,17 @@
import javax.security.auth.x500.X500Principal;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.ASN1IA5String;
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.ASN1String;
-import org.bouncycastle.asn1.DERBitString;
-import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
@@ -64,6 +65,7 @@
import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Exceptions;
import org.bouncycastle.util.Integers;
import org.bouncycastle.util.Properties;
import org.bouncycastle.util.Strings;
@@ -78,7 +80,6 @@
protected boolean[] keyUsage;
protected String sigAlgName;
protected byte[] sigAlgParams;
-
X509CertificateImpl(JcaJceHelper bcHelper, org.bouncycastle.asn1.x509.Certificate c,
BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams)
{
@@ -229,7 +230,7 @@
public boolean[] getIssuerUniqueID()
{
- DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getIssuerUniqueId();
if (id != null)
{
@@ -249,7 +250,7 @@
public boolean[] getSubjectUniqueID()
{
- DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getSubjectUniqueId();
if (id != null)
{
@@ -297,29 +298,21 @@
throw new CertificateParsingException("error processing extended key usage extension");
}
}
-
+
public int getBasicConstraints()
{
- if (basicConstraints != null)
+ if (basicConstraints == null || !basicConstraints.isCA())
{
- if (basicConstraints.isCA())
- {
- if (basicConstraints.getPathLenConstraint() == null)
- {
- return Integer.MAX_VALUE;
- }
- else
- {
- return basicConstraints.getPathLenConstraint().intValue();
- }
- }
- else
- {
- return -1;
- }
+ return -1;
}
- return -1;
+ ASN1Integer pathLenConstraint = basicConstraints.getPathLenConstraintInteger();
+ if (pathLenConstraint == null)
+ {
+ return Integer.MAX_VALUE;
+ }
+
+ return pathLenConstraint.intPositiveValueExact();
}
public Collection getSubjectAlternativeNames()
@@ -374,7 +367,7 @@
}
catch (Exception e)
{
- throw new IllegalStateException("error parsing " + e.toString());
+ throw Exceptions.illegalStateException("error parsing " + e.getMessage(), e);
}
}
@@ -460,20 +453,7 @@
}
catch (IOException e)
{
- return null; // should never happen...
- }
- }
-
- public byte[] getEncoded()
- throws CertificateEncodingException
- {
- try
- {
- return c.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- throw new CertificateEncodingException(e.toString());
+ throw Exceptions.illegalStateException("failed to recover public key: " + e.getMessage(), e);
}
}
@@ -526,15 +506,15 @@
}
else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
{
- buf.append(new NetscapeCertType(DERBitString.getInstance(dIn.readObject()))).append(nl);
+ buf.append(new NetscapeCertType(ASN1BitString.getInstance(dIn.readObject()))).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
{
- buf.append(new NetscapeRevocationURL(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ buf.append(new NetscapeRevocationURL(ASN1IA5String.getInstance(dIn.readObject()))).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
{
- buf.append(new VerisignCzagExtension(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ buf.append(new VerisignCzagExtension(ASN1IA5String.getInstance(dIn.readObject()))).append(nl);
}
else
{
@@ -646,7 +626,7 @@
{
List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != pubKeys.size(); i++)
@@ -667,7 +647,7 @@
checkSignature(
(PublicKey)pubKeys.get(i), signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
catch (SignatureException e)
@@ -689,7 +669,7 @@
else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
{
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != sigSeq.size(); i++)
@@ -706,7 +686,7 @@
checkSignature(
key, signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
index b6d8ada..63d3b89 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
@@ -5,25 +5,43 @@
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.jcajce.util.JcaJceHelper;
+/**
+ * This class exists to let {@link #equals(Object)} and {@link #hashCode()} methods be delegated efficiently
+ * to the platform default implementations (especially important for compatibility of {@link #hashCode()}
+ * calculations). Those methods fall back to calling {@link #getEncoded()} for third-party subclasses, and
+ * this class allows us to avoid cloning the return value of {@link #getEncoded()} for those callers.
+ */
class X509CertificateInternal extends X509CertificateImpl
{
private final byte[] encoding;
+ private final CertificateEncodingException exception;
X509CertificateInternal(JcaJceHelper bcHelper, org.bouncycastle.asn1.x509.Certificate c,
- BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams, byte[] encoding)
+ BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams, byte[] encoding,
+ CertificateEncodingException exception)
{
super(bcHelper, c, basicConstraints, keyUsage, sigAlgName, sigAlgParams);
this.encoding = encoding;
+ this.exception = exception;
}
public byte[] getEncoded() throws CertificateEncodingException
{
+ if (null != exception)
+ {
+ throw exception;
+ }
+
if (null == encoding)
{
throw new CertificateEncodingException();
}
+ /*
+ * NOTE: Don't clone this return value. See class javadoc for details. Any necessary cloning is
+ * handled by the X509CertificateObject that is holding this instance.
+ */
return encoding;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
index f90da30..38b33b2 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
@@ -1,56 +1,21 @@
package org.bouncycastle.jcajce.provider.asymmetric.x509;
-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;
-import java.security.Principal;
-import java.security.Provider;
import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Encoding;
-import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1OutputStream;
import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.ASN1Sequence;
-import org.bouncycastle.asn1.ASN1String;
-import org.bouncycastle.asn1.DERBitString;
-import org.bouncycastle.asn1.DERIA5String;
-import org.bouncycastle.asn1.DERNull;
-import org.bouncycastle.asn1.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;
@@ -61,12 +26,8 @@
// END Android-added: Unknown reason
import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.util.Integers;
-import org.bouncycastle.util.Strings;
-import org.bouncycastle.util.encoders.Hex;
+import org.bouncycastle.util.Arrays;
class X509CertificateObject
extends X509CertificateImpl
@@ -253,6 +214,8 @@
return false;
}
}
+
+ return getInternalCertificate().equals(otherBC.getInternalCertificate());
}
return getInternalCertificate().equals(other);
@@ -317,18 +280,19 @@
}
}
- byte[] encoding;
+ byte[] encoding = null;
+ CertificateEncodingException exception = null;
try
{
- encoding = getEncoded();
+ encoding = c.getEncoded(ASN1Encoding.DER);
}
- catch (CertificateEncodingException e)
+ catch (IOException e)
{
- encoding = null;
+ exception = new X509CertificateEncodingException(e);
}
X509CertificateInternal temp = new X509CertificateInternal(bcHelper, c, basicConstraints, keyUsage, sigAlgName,
- sigAlgParams, encoding);
+ sigAlgParams, encoding, exception);
synchronized (cacheLock)
{
@@ -370,7 +334,7 @@
return null;
}
- ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(extOctets));
+ ASN1BitString bits = ASN1BitString.getInstance(ASN1Primitive.fromByteArray(extOctets));
byte[] bytes = bits.getBytes();
int length = (bytes.length * 8) - bits.getPadBits();
@@ -419,4 +383,20 @@
throw new CertificateParsingException("cannot construct SigAlgParams: " + e);
}
}
+
+ private static class X509CertificateEncodingException
+ extends CertificateEncodingException
+ {
+ private final Throwable cause;
+
+ X509CertificateEncodingException(Throwable cause)
+ {
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
index f83f213..e893b40 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
@@ -180,6 +180,11 @@
static void prettyPrintSignature(byte[] sig, StringBuffer buf, String nl)
{
+ // -DM Hex.toHexString
+ // -DM Hex.toHexString
+ // -DM Hex.toHexString
+ // -DM Hex.toHexString
+
if (sig.length > 20)
{
buf.append(" Signature: ").append(Hex.toHexString(sig, 0, 20)).append(nl);
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 831b497..a119425 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
@@ -45,8 +45,12 @@
void addAlgorithm(String key, String value);
+ void addAlgorithm(String key, String value, Map<String, String> attributes);
+
void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className);
+ void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className, Map<String, String> attributes);
+
boolean hasAlgorithm(String type, String name);
void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
index 9c3bddc..b388569 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
@@ -1,5 +1,6 @@
package org.bouncycastle.jcajce.provider.digest;
+import java.security.DigestException;
import java.security.MessageDigest;
import org.bouncycastle.crypto.Digest;
@@ -65,4 +66,16 @@
return digestBytes;
}
+
+ public int engineDigest(byte[] buf, int off, int len) throws DigestException
+ {
+ if (len < digestSize)
+ throw new DigestException("partial digests not returned");
+ if (buf.length - off < digestSize)
+ throw new DigestException("insufficient space in the output buffer to store the digest");
+
+ digest.doFinal(buf, off);
+
+ return digestSize;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java
index 2325f59..a196f3b 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java
@@ -23,6 +23,19 @@
provider.addAlgorithm("Alg.Alias.KeyGenerator.HMAC/" + algorithm, mainName);
}
+ protected void addKMACAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String algorithmClassName,
+ String keyGeneratorClassName)
+ {
+ String mainName = "KMAC" + algorithm;
+
+ provider.addAlgorithm("Mac." + mainName, algorithmClassName);
+ provider.addAlgorithm("KeyGenerator." + mainName, keyGeneratorClassName);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.KMAC" + algorithm, mainName);
+ }
+
protected void addHMACAlias(
ConfigurableProvider provider,
String algorithm,
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/Haraka.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/Haraka.java
new file mode 100644
index 0000000..7877da6
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/Haraka.java
@@ -0,0 +1,67 @@
+package org.bouncycastle.jcajce.provider.digest;
+
+import org.bouncycastle.crypto.digests.Haraka256Digest;
+import org.bouncycastle.crypto.digests.Haraka512Digest;
+import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+
+public class Haraka
+{
+ private Haraka()
+ {
+
+ }
+
+ static public class Digest256
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest256()
+ {
+ super(new Haraka256Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest256 d = (Digest256)super.clone();
+ d.digest = new Haraka256Digest((Haraka256Digest)digest);
+
+ return d;
+ }
+ }
+
+ static public class Digest512
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest512()
+ {
+ super(new Haraka512Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest512 d = (Digest512)super.clone();
+ d.digest = new Haraka512Digest((Haraka512Digest)digest);
+
+ return d;
+ }
+ }
+
+ public static class Mappings
+ extends DigestAlgorithmProvider
+ {
+ private static final String PREFIX = Haraka.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("MessageDigest.HARAKA-256", PREFIX + "$Digest256");
+ provider.addAlgorithm("MessageDigest.HARAKA-512", PREFIX + "$Digest512");
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java
index ae4c82f..da58b08 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java
@@ -23,14 +23,14 @@
{
public Digest()
{
- super(new SHA256Digest());
+ super(SHA256Digest.newInstance());
}
public Object clone()
throws CloneNotSupportedException
{
Digest d = (Digest)super.clone();
- d.digest = new SHA256Digest((SHA256Digest)digest);
+ d.digest = SHA256Digest.newInstance(digest);
return d;
}
@@ -41,7 +41,7 @@
{
public HashMac()
{
- super(new HMac(new SHA256Digest()));
+ super(new HMac(SHA256Digest.newInstance()));
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java
index 335d0d6..203195c 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java
@@ -176,10 +176,16 @@
provider.addAlgorithm("MessageDigest.SHA-512/224", PREFIX + "$DigestT224");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512/224", "SHA-512/224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512224", "SHA-512/224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA-512(224)", "SHA-512/224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512(224)", "SHA-512/224");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_224, "SHA-512/224");
provider.addAlgorithm("MessageDigest.SHA-512/256", PREFIX + "$DigestT256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512/256", "SHA-512/256");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512256", "SHA-512/256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA-512(256)", "SHA-512/256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512(256)", "SHA-512/256");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_256, "SHA-512/256");
provider.addAlgorithm("Mac.OLDHMACSHA512", PREFIX + "$OldSHA512");
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/drbg/EntropyDaemon.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/drbg/EntropyDaemon.java
new file mode 100644
index 0000000..856b16a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/drbg/EntropyDaemon.java
@@ -0,0 +1,65 @@
+package org.bouncycastle.jcajce.provider.drbg;
+
+import java.util.LinkedList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+class EntropyDaemon
+ implements Runnable
+{
+ private static final Logger LOG = Logger.getLogger(EntropyDaemon.class.getName());
+
+ private final LinkedList<Runnable> tasks = new LinkedList<Runnable>();
+
+ public EntropyDaemon()
+ {
+ }
+
+ void addTask(Runnable task)
+ {
+ synchronized (tasks)
+ {
+ tasks.add(task);
+ }
+ }
+
+ public void run()
+ {
+ while (!Thread.currentThread().isInterrupted())
+ {
+ Runnable task;
+ synchronized (tasks)
+ {
+ task = tasks.poll();
+ }
+
+ if (task != null)
+ {
+ try
+ {
+ task.run();
+ }
+ catch (Throwable e)
+ {
+ // ignore
+ }
+ }
+ else
+ {
+ try
+ {
+ Thread.sleep(5000);
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ if (LOG.isLoggable(Level.FINE))
+ {
+ LOG.fine("entropy thread interrupted - exiting");
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/BC.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/BC.java
index 5bc0aa8..f84bc67 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/BC.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/BC.java
@@ -2,6 +2,7 @@
import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+import org.bouncycastle.util.Properties;
public class BC
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
index 5ec21c8..2434da2 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
@@ -57,6 +57,7 @@
import org.bouncycastle.jce.interfaces.BCKeyStore;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Properties;
import org.bouncycastle.util.io.Streams;
import org.bouncycastle.util.io.TeeOutputStream;
@@ -394,6 +395,11 @@
{
byte[] enc = key.getEncoded();
+ if (enc == null)
+ {
+ throw new IOException("unable to store encoding of protected key");
+ }
+
if (key instanceof PrivateKey)
{
dOut.write(KEY_PRIVATE);
@@ -672,9 +678,18 @@
Certificate[] chain)
throws KeyStoreException
{
- if ((key instanceof PrivateKey) && (chain == null))
+ if ((key instanceof PrivateKey))
{
- throw new KeyStoreException("no certificate chain for private key");
+ if (chain == null)
+ {
+ throw new KeyStoreException("no certificate chain for private key");
+ }
+ if (key.getEncoded() == null)
+ {
+ // we ingore the password as the key is already protected.
+ table.put(alias, new StoreEntry(alias, new Date(), KEY, key, chain));
+ return;
+ }
}
try
@@ -1118,6 +1133,10 @@
public Version1()
{
super(1);
+ if (!Properties.isOverrideSet("org.bouncycastle.bks.enable_v1"))
+ {
+ throw new IllegalStateException("BKS-V1 not enabled");
+ }
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
index 263c63d..5077097 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
@@ -2,6 +2,7 @@
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
+import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -46,6 +47,7 @@
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
+import org.bouncycastle.asn1.ASN1BMPString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
@@ -65,6 +67,7 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.GOST28147Parameters;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
// import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
@@ -83,9 +86,13 @@
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.bouncycastle.asn1.x509.DigestInfo;
+import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.Extensions;
+import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.Digest;
@@ -96,6 +103,9 @@
import org.bouncycastle.jcajce.PKCS12StoreParameter;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
+// import org.bouncycastle.jcajce.BCLoadStoreParameter;
+import org.bouncycastle.jcajce.provider.keystore.util.AdaptingKeyStoreSpi;
+import org.bouncycastle.jcajce.provider.keystore.util.ParameterUtil;
import org.bouncycastle.jcajce.spec.PBKDF2KeySpec;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
@@ -129,7 +139,7 @@
private static final DefaultSecretKeyProvider keySizeProvider = new DefaultSecretKeyProvider();
private IgnoresCaseHashtable keys = new IgnoresCaseHashtable();
- private Hashtable localIds = new Hashtable();
+ private IgnoresCaseHashtable localIds = new IgnoresCaseHashtable();
private IgnoresCaseHashtable certs = new IgnoresCaseHashtable();
private Hashtable chainCerts = new Hashtable();
private Hashtable keyCerts = new Hashtable();
@@ -253,6 +263,12 @@
this.random = rand;
}
+ public boolean engineProbe(InputStream stream)
+ throws IOException
+ {
+ return false;
+ }
+
public Enumeration engineAliases()
{
Hashtable tab = new Hashtable();
@@ -291,25 +307,23 @@
String alias)
throws KeyStoreException
{
- Key k = (Key)keys.remove(alias);
-
- Certificate c = (Certificate)certs.remove(alias);
-
- if (c != null)
+ Certificate cert = (Certificate)certs.remove(alias);
+ if (cert != null)
{
- chainCerts.remove(new CertId(c.getPublicKey()));
+ chainCerts.remove(new CertId(cert.getPublicKey()));
}
- if (k != null)
+ Key key = (Key)keys.remove(alias);
+ if (key != null)
{
String id = (String)localIds.remove(alias);
if (id != null)
{
- c = (Certificate)keyCerts.remove(id);
- }
- if (c != null)
- {
- chainCerts.remove(new CertId(c.getPublicKey()));
+ Certificate keyCert = (Certificate)keyCerts.remove(id);
+ if (keyCert != null)
+ {
+ chainCerts.remove(new CertId(keyCert.getPublicKey()));
+ }
}
}
}
@@ -654,7 +668,7 @@
try
{
- SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm);
+ SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm);
PBEParameterSpec defParams = new PBEParameterSpec(
pbeParams.getIV(),
pbeParams.getIterations().intValue());
@@ -704,7 +718,7 @@
throw new IOException("exception decrypting data - " + e.toString());
}
}
- else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2))
+ else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2))
{
try
{
@@ -767,6 +781,31 @@
return cipher;
}
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public void engineLoad(KeyStore.LoadStoreParameter loadStoreParameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (loadStoreParameter == null)
+ {
+ engineLoad(null, null);
+ }
+ else if (loadStoreParameter instanceof BCLoadStoreParameter)
+ {
+ BCLoadStoreParameter bcParam = (BCLoadStoreParameter)loadStoreParameter;
+
+ engineLoad(bcParam.getInputStream(), ParameterUtil.extractPassword(loadStoreParameter));
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "no support for 'param' of type " + loadStoreParameter.getClass().getName());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
public void engineLoad(
InputStream stream,
char[] password)
@@ -782,7 +821,10 @@
bufIn.mark(10);
int head = bufIn.read();
-
+ if (head < 0)
+ {
+ throw new EOFException("no data in keystore stream");
+ }
if (head != 0x30)
{
throw new IOException("stream does not represent a PKCS12 key store");
@@ -791,7 +833,7 @@
bufIn.reset();
ASN1InputStream bIn = new ASN1InputStream(bufIn);
-
+
Pfx bag;
try
{
@@ -868,7 +910,7 @@
// END Android-removed: keep v1.61 behaviour to keep backwards-compatibility
keys = new IgnoresCaseHashtable();
- localIds = new Hashtable();
+ localIds = new IgnoresCaseHashtable();
if (info.getContentType().equals(data))
{
@@ -888,86 +930,19 @@
SafeBag b = SafeBag.getInstance(seq.getObjectAt(j));
if (b.getBagId().equals(pkcs8ShroudedKeyBag))
{
- org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
- PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
-
- //
- // set the attributes on the key
- //
- String alias = null;
- ASN1OctetString localId = null;
-
- if (b.getBagAttributes() != null)
- {
- Enumeration e = b.getBagAttributes().getObjects();
- while (e.hasMoreElements())
- {
- ASN1Sequence sq = (ASN1Sequence)e.nextElement();
- ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0);
- ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
- ASN1Primitive attr = null;
-
- if (attrSet.size() > 0)
- {
- attr = (ASN1Primitive)attrSet.getObjectAt(0);
-
- if (privKey instanceof PKCS12BagAttributeCarrier)
- {
- PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
- ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
- if (existing != null)
- {
- // OK, but the value has to be the same
- if (!existing.toASN1Primitive().equals(attr))
- {
- throw new IOException(
- "attempt to add existing attribute with different value");
- }
- }
- else
- {
- bagAttr.setBagAttribute(aOid, attr);
- }
- }
- }
-
- if (aOid.equals(pkcs_9_at_friendlyName))
- {
- alias = ((DERBMPString)attr).getString();
- keys.put(alias, privKey);
- }
- else if (aOid.equals(pkcs_9_at_localKeyId))
- {
- localId = (ASN1OctetString)attr;
- }
- }
- }
-
- if (localId != null)
- {
- String name = new String(Hex.encode(localId.getOctets()));
-
- if (alias == null)
- {
- keys.put(name, privKey);
- }
- else
- {
- localIds.put(alias, name);
- }
- }
- else
- {
- unmarkedKey = true;
- keys.put("unmarked", privKey);
- }
+ unmarkedKey = processShroudedKeyBag(b, password, wrongPKCS12Zero);
}
else if (b.getBagId().equals(certBag))
{
chain.addElement(b);
}
+ else if (b.getBagId().equals(keyBag))
+ {
+ processKeyBag(b);
+ }
else
{
+ // -DM 2 System.out.println
System.out.println("extra in data " + b.getBagId());
System.out.println(ASN1Dump.dumpAsString(b));
}
@@ -983,137 +958,21 @@
for (int j = 0; j != seq.size(); j++)
{
SafeBag b = SafeBag.getInstance(seq.getObjectAt(j));
-
if (b.getBagId().equals(certBag))
{
chain.addElement(b);
}
else if (b.getBagId().equals(pkcs8ShroudedKeyBag))
{
- org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
- PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
-
- //
- // set the attributes on the key
- //
- PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
- String alias = null;
- ASN1OctetString localId = null;
-
- Enumeration e = b.getBagAttributes().getObjects();
- while (e.hasMoreElements())
- {
- ASN1Sequence sq = (ASN1Sequence)e.nextElement();
- ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0);
- ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
- ASN1Primitive attr = null;
-
- if (attrSet.size() > 0)
- {
- attr = (ASN1Primitive)attrSet.getObjectAt(0);
-
- ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
- if (existing != null)
- {
- // OK, but the value has to be the same
- if (!existing.toASN1Primitive().equals(attr))
- {
- throw new IOException(
- "attempt to add existing attribute with different value");
- }
- }
- else
- {
- bagAttr.setBagAttribute(aOid, attr);
- }
- }
-
- if (aOid.equals(pkcs_9_at_friendlyName))
- {
- alias = ((DERBMPString)attr).getString();
- keys.put(alias, privKey);
- }
- else if (aOid.equals(pkcs_9_at_localKeyId))
- {
- localId = (ASN1OctetString)attr;
- }
- }
-
- String name = new String(Hex.encode(localId.getOctets()));
-
- if (alias == null)
- {
- keys.put(name, privKey);
- }
- else
- {
- localIds.put(alias, name);
- }
+ unmarkedKey = processShroudedKeyBag(b, password, wrongPKCS12Zero);
}
else if (b.getBagId().equals(keyBag))
{
- org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue());
- PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo);
-
- //
- // set the attributes on the key
- //
- PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
- String alias = null;
- ASN1OctetString localId = null;
-
- Enumeration e = b.getBagAttributes().getObjects();
- while (e.hasMoreElements())
- {
- ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement());
- ASN1ObjectIdentifier aOid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0));
- ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1));
- ASN1Primitive attr = null;
-
- if (attrSet.size() > 0)
- {
- attr = (ASN1Primitive)attrSet.getObjectAt(0);
-
- ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
- if (existing != null)
- {
- // OK, but the value has to be the same
- if (!existing.toASN1Primitive().equals(attr))
- {
- throw new IOException(
- "attempt to add existing attribute with different value");
- }
- }
- else
- {
- bagAttr.setBagAttribute(aOid, attr);
- }
-
- if (aOid.equals(pkcs_9_at_friendlyName))
- {
- alias = ((DERBMPString)attr).getString();
- keys.put(alias, privKey);
- }
- else if (aOid.equals(pkcs_9_at_localKeyId))
- {
- localId = (ASN1OctetString)attr;
- }
- }
- }
-
- String name = new String(Hex.encode(localId.getOctets()));
-
- if (alias == null)
- {
- keys.put(name, privKey);
- }
- else
- {
- localIds.put(alias, name);
- }
+ processKeyBag(b);
}
else
{
+ // -DM 2 System.out.println
System.out.println("extra in encryptedData " + b.getBagId());
System.out.println(ASN1Dump.dumpAsString(b));
}
@@ -1121,6 +980,7 @@
}
else
{
+ // -DM 2 System.out.println
System.out.println("extra " + c[i].getContentType().getId());
System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent()));
}
@@ -1181,6 +1041,17 @@
ASN1Encodable existing = bagAttr.getBagAttribute(oid);
if (existing != null)
{
+ // we've found more than one - one might be incorrect
+ if (oid.equals(pkcs_9_at_localKeyId))
+ {
+ // -DM Hex.toHexString
+ String id = Hex.toHexString(((ASN1OctetString)attr).getOctets());
+ if (!(keys.keys.containsKey(id) || localIds.keys.containsKey(id)))
+ {
+ continue; // ignore this one - it's not valid
+ }
+ }
+
// OK, but the value has to be the same
if (!existing.toASN1Primitive().equals(attr))
{
@@ -1190,13 +1061,20 @@
}
else
{
- bagAttr.setBagAttribute(oid, attr);
+ if (attrSet.size() > 1)
+ {
+ bagAttr.setBagAttribute(oid, attrSet);
+ }
+ else
+ {
+ bagAttr.setBagAttribute(oid, attr);
+ }
}
}
if (oid.equals(pkcs_9_at_friendlyName))
{
- alias = ((DERBMPString)attr).getString();
+ alias = ((ASN1BMPString)attr).getString();
}
else if (oid.equals(pkcs_9_at_localKeyId))
{
@@ -1237,6 +1115,149 @@
}
}
+ private boolean processShroudedKeyBag(SafeBag b, char[] password, boolean wrongPKCS12Zero)
+ throws IOException
+ {
+ org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
+ PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
+
+ //
+ // set the attributes on the key
+ //
+ String alias = null;
+ ASN1OctetString localId = null;
+
+ if (b.getBagAttributes() != null)
+ {
+ Enumeration e = b.getBagAttributes().getObjects();
+ while (e.hasMoreElements())
+ {
+ ASN1Sequence sq = (ASN1Sequence)e.nextElement();
+ ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0);
+ ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
+ ASN1Primitive attr = null;
+
+ if (attrSet.size() > 0)
+ {
+ attr = (ASN1Primitive)attrSet.getObjectAt(0);
+
+ if (privKey instanceof PKCS12BagAttributeCarrier)
+ {
+ PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
+ ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
+ if (existing != null)
+ {
+ // OK, but the value has to be the same
+ if (!existing.toASN1Primitive().equals(attr))
+ {
+ throw new IOException(
+ "attempt to add existing attribute with different value");
+ }
+ }
+ else
+ {
+ bagAttr.setBagAttribute(aOid, attr);
+ }
+ }
+ }
+
+ if (aOid.equals(pkcs_9_at_friendlyName))
+ {
+ alias = ((ASN1BMPString)attr).getString();
+ keys.put(alias, privKey);
+ }
+ else if (aOid.equals(pkcs_9_at_localKeyId))
+ {
+ localId = (ASN1OctetString)attr;
+ }
+ }
+ }
+
+ if (localId != null)
+ {
+ String name = new String(Hex.encode(localId.getOctets()));
+
+ if (alias == null)
+ {
+ keys.put(name, privKey);
+ }
+ else
+ {
+ localIds.put(alias, name);
+ }
+ return false; // key properly marked
+ }
+ else
+ {
+ keys.put("unmarked", privKey);
+ return true; // key properly marked
+ }
+ }
+
+ private void processKeyBag(SafeBag b)
+ throws IOException
+ {
+ org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue());
+ PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo);
+
+ //
+ // set the attributes on the key
+ //
+ PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
+ String alias = null;
+ ASN1OctetString localId = null;
+
+ Enumeration e = b.getBagAttributes().getObjects();
+ while (e.hasMoreElements())
+ {
+ ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement());
+ ASN1ObjectIdentifier aOid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0));
+ ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1));
+ ASN1Primitive attr = null;
+
+ if (attrSet.size() > 0)
+ {
+ attr = (ASN1Primitive)attrSet.getObjectAt(0);
+
+ ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
+ if (existing != null)
+ {
+ // OK, but the value has to be the same
+ if (!existing.toASN1Primitive().equals(attr))
+ {
+ throw new IOException(
+ "attempt to add existing attribute with different value");
+ }
+ }
+ else
+ {
+ bagAttr.setBagAttribute(aOid, attr);
+ }
+
+ if (aOid.equals(pkcs_9_at_friendlyName))
+ {
+ alias = ((ASN1BMPString)attr).getString();
+ keys.put(alias, privKey);
+ }
+ else if (aOid.equals(pkcs_9_at_localKeyId))
+ {
+ localId = (ASN1OctetString)attr;
+ }
+ }
+ }
+
+ String name = new String(Hex.encode(localId.getOctets()));
+
+ if (alias == null)
+ {
+ keys.put(name, privKey);
+ }
+ else
+ {
+ localIds.put(alias, name);
+ }
+ }
+
private int validateIterationCount(BigInteger i)
{
int count = i.intValue();
@@ -1318,7 +1339,55 @@
// See CtsKeystoreTestCases:android.keystore.cts.KeyStoreTest
if (password == null)
{
- throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
+ if (password == null)
+ {
+ Enumeration cs = certs.keys();
+
+ ASN1EncodableVector certSeq = new ASN1EncodableVector();
+
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ String certId = (String)cs.nextElement();
+ Certificate cert = (Certificate)certs.get(certId);
+
+ SafeBag sBag = createSafeBag(certId, cert);
+
+ certSeq.add(sBag);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ if (useDEREncoding)
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.DER);
+ }
+ else
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.BER);
+ }
+
+ return;
+ }
+ }
+ else
+ {
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied for PKCS#12 KeyStore");
+ }
}
/*
if (keys.size() == 0)
@@ -1405,7 +1474,7 @@
//
// make sure we are using the local alias on store
//
- DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ ASN1BMPString nm = (ASN1BMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(name))
{
bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name));
@@ -1496,7 +1565,7 @@
//
// make sure we are using the local alias on store
//
- DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ ASN1BMPString nm = (ASN1BMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(name))
{
bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name));
@@ -1629,6 +1698,7 @@
}
}
+
SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
certSeq.add(sBag);
@@ -1702,7 +1772,7 @@
//
// make sure we are using the local alias on store
//
- DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ ASN1BMPString nm = (ASN1BMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(certId))
{
if (certId != null)
@@ -1746,6 +1816,43 @@
fName.add(new DERSequence(fSeq));
}
+ // Android-removed: unsupported
+ // add the trusted usage attribute - needed for Oracle key stores
+ // if (cert instanceof X509Certificate)
+ // {
+ // TBSCertificate tbsCert = TBSCertificate.getInstance(((X509Certificate)cert).getTBSCertificate());
+ // Extensions exts = tbsCert.getExtensions();
+ // if (exts != null)
+ // {
+ // Extension extUsage = exts.getExtension(Extension.extendedKeyUsage);
+ // if (extUsage != null)
+ // {
+ // ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ // // oracle trusted key usage OID.
+ // fSeq.add(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage);
+ // fSeq.add(new DERSet(ExtendedKeyUsage.getInstance(extUsage.getParsedValue()).getUsages()));
+ // fName.add(new DERSequence(fSeq));
+ // }
+ // else
+ // {
+ // ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ // fSeq.add(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage);
+ // fSeq.add(new DERSet(KeyPurposeId.anyExtendedKeyUsage));
+ // fName.add(new DERSequence(fSeq));
+ // }
+ // }
+ // else
+ // {
+ // ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ // fSeq.add(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage);
+ // fSeq.add(new DERSet(KeyPurposeId.anyExtendedKeyUsage));
+ // fName.add(new DERSequence(fSeq));
+ // }
+ // }
+
return new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
}
@@ -1753,19 +1860,19 @@
{
Set usedSet = new HashSet();
- for (Enumeration en = keys.keys(); en.hasMoreElements();)
+ for (Enumeration en = keys.keys(); en.hasMoreElements(); )
{
String alias = (String)en.nextElement();
- Certificate[] certs = engineGetCertificateChain(alias);
+ Certificate[] certs = engineGetCertificateChain(alias);
- for (int i = 0; i != certs.length; i++)
- {
- usedSet.add(certs[i]);
- }
+ for (int i = 0; i != certs.length; i++)
+ {
+ usedSet.add(certs[i]);
+ }
}
- for (Enumeration en = certs.keys(); en.hasMoreElements();)
+ for (Enumeration en = certs.keys(); en.hasMoreElements(); )
{
String alias = (String)en.nextElement();
@@ -1797,13 +1904,14 @@
return mac.doFinal();
}
+ // Android-changed: Use default provider for JCA algorithms instead of BC
public static class BCPKCS12KeyStore
extends PKCS12KeyStoreSpi
{
public BCPKCS12KeyStore()
{
// Android-changed: Use default provider for JCA algorithms instead of BC
- // Was: super(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
+ // Was: super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC));
super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
}
}
@@ -1811,29 +1919,29 @@
// BEGIN Android-removed: Unsupported algorithms
/*
public static class BCPKCS12KeyStore3DES
- extends PKCS12KeyStoreSpi
+ extends AdaptingKeyStoreSpi
{
public BCPKCS12KeyStore3DES()
{
- super(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC);
+ super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC));
}
}
public static class DefPKCS12KeyStore
- extends PKCS12KeyStoreSpi
+ extends AdaptingKeyStoreSpi
{
public DefPKCS12KeyStore()
{
- super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
+ super(new DefaultJcaJceHelper(), new PKCS12KeyStoreSpi(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC));
}
}
public static class DefPKCS12KeyStore3DES
- extends PKCS12KeyStoreSpi
+ extends AdaptingKeyStoreSpi
{
public DefPKCS12KeyStore3DES()
{
- super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC);
+ super(new DefaultJcaJceHelper(), new PKCS12KeyStoreSpi(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC));
}
}
*/
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/util/AdaptingKeyStoreSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/util/AdaptingKeyStoreSpi.java
new file mode 100644
index 0000000..74e34d3
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/util/AdaptingKeyStoreSpi.java
@@ -0,0 +1,184 @@
+package org.bouncycastle.jcajce.provider.keystore.util;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Enumeration;
+
+import org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
+import org.bouncycastle.util.Properties;
+
+/**
+ * Implements a certificate only JKS key store.
+ */
+public class AdaptingKeyStoreSpi
+ extends KeyStoreSpi
+{
+ public static final String COMPAT_OVERRIDE = "keystore.type.compat";
+
+ private final JKSKeyStoreSpi jksStore;
+ private final KeyStoreSpi primaryStore;
+
+ private KeyStoreSpi keyStoreSpi;
+
+ public AdaptingKeyStoreSpi(JcaJceHelper helper, KeyStoreSpi primaryStore)
+ {
+ this.jksStore = new JKSKeyStoreSpi(helper);
+ this.primaryStore = primaryStore;
+ this.keyStoreSpi = primaryStore;
+ }
+
+ public boolean engineProbe(InputStream stream)
+ throws IOException
+ {
+ if (keyStoreSpi instanceof PKCS12KeyStoreSpi)
+ {
+ return ((PKCS12KeyStoreSpi)keyStoreSpi).engineProbe(stream);
+ }
+ return false;
+ }
+
+ public Key engineGetKey(String alias, char[] password)
+ throws NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ return keyStoreSpi.engineGetKey(alias, password);
+ }
+
+ public Certificate[] engineGetCertificateChain(String alias)
+ {
+ return keyStoreSpi.engineGetCertificateChain(alias);
+ }
+
+ public Certificate engineGetCertificate(String alias)
+ {
+ return keyStoreSpi.engineGetCertificate(alias);
+ }
+
+ public Date engineGetCreationDate(String alias)
+ {
+ return keyStoreSpi.engineGetCreationDate(alias);
+ }
+
+ public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
+ }
+
+ public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineSetKeyEntry(alias, key, chain);
+ }
+
+ public void engineSetCertificateEntry(String alias, Certificate cert)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineSetCertificateEntry(alias, cert);
+ }
+
+ public void engineDeleteEntry(String alias)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineDeleteEntry(alias);
+ }
+
+ public Enumeration<String> engineAliases()
+ {
+ return keyStoreSpi.engineAliases();
+ }
+
+ public boolean engineContainsAlias(String alias)
+ {
+ return keyStoreSpi.engineContainsAlias(alias);
+ }
+
+ public int engineSize()
+ {
+ return keyStoreSpi.engineSize();
+ }
+
+ public boolean engineIsKeyEntry(String alias)
+ {
+ return keyStoreSpi.engineIsKeyEntry(alias);
+ }
+
+ public boolean engineIsCertificateEntry(String alias)
+ {
+ return keyStoreSpi.engineIsCertificateEntry(alias);
+ }
+
+ public String engineGetCertificateAlias(Certificate cert)
+ {
+ return keyStoreSpi.engineGetCertificateAlias(cert);
+ }
+
+ public void engineStore(OutputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ keyStoreSpi.engineStore(stream, password);
+ }
+
+ public void engineStore(KeyStore.LoadStoreParameter parameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ keyStoreSpi.engineStore(parameter);
+ }
+
+ public void engineLoad(InputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (stream == null)
+ {
+ keyStoreSpi = primaryStore;
+ keyStoreSpi.engineLoad(null, password);
+ }
+ else
+ {
+ // the FIPS BCFKS/JKS compatibility is explicit and doesn't use the override.
+ if (Properties.isOverrideSet(COMPAT_OVERRIDE) || !(primaryStore instanceof PKCS12KeyStoreSpi))
+ {
+ if (!stream.markSupported())
+ {
+ stream = new BufferedInputStream(stream);
+ }
+
+ stream.mark(8);
+ if (jksStore.engineProbe(stream))
+ {
+ keyStoreSpi = jksStore;
+ }
+ else
+ {
+ keyStoreSpi = primaryStore;
+ }
+
+ stream.reset();
+ }
+ else
+ {
+ keyStoreSpi = primaryStore;
+ }
+
+ keyStoreSpi.engineLoad(stream, password);
+ }
+ }
+
+ public void engineLoad(KeyStore.LoadStoreParameter parameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ keyStoreSpi.engineLoad(parameter);
+ }
+}
+
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/util/JKSKeyStoreSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/util/JKSKeyStoreSpi.java
new file mode 100644
index 0000000..db27a40
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/util/JKSKeyStoreSpi.java
@@ -0,0 +1,426 @@
+package org.bouncycastle.jcajce.provider.keystore.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.jcajce.BCLoadStoreParameter;
+import org.bouncycastle.jcajce.provider.util.DigestFactory;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+import org.bouncycastle.util.io.Streams;
+
+/**
+ * Implements a certificate only JKS key store.
+ */
+public class JKSKeyStoreSpi
+ extends KeyStoreSpi
+{
+ private static final String NOT_IMPLEMENTED_MESSAGE = "BC JKS store is read-only and only supports certificate entries";
+
+ private final Hashtable<String, BCJKSTrustedCertEntry> certificateEntries = new Hashtable<String, BCJKSTrustedCertEntry>();
+ private final JcaJceHelper helper;
+
+ public JKSKeyStoreSpi(JcaJceHelper helper)
+ {
+ this.helper = helper;
+ }
+
+ public boolean engineProbe(InputStream stream)
+ throws IOException
+ {
+ DataInputStream storeStream;
+ if (stream instanceof DataInputStream)
+ {
+ storeStream = (DataInputStream)stream;
+ }
+ else
+ {
+ storeStream = new DataInputStream(stream);
+ }
+
+ int magic = storeStream.readInt();
+ int storeVersion = storeStream.readInt();
+ return magic == (int)0x0000feedfeedL && (storeVersion == 1 || storeVersion == 2);
+ }
+
+ public Key engineGetKey(String alias, char[] password)
+ throws NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ return null; // by definition
+ }
+
+ public Certificate[] engineGetCertificateChain(String alias)
+ {
+ return null; // by definition
+ }
+
+ public Certificate engineGetCertificate(String alias)
+ {
+ synchronized (certificateEntries)
+ {
+ BCJKSTrustedCertEntry ent = certificateEntries.get(alias);
+ if (ent != null)
+ {
+ return ent.cert;
+ }
+ }
+ return null;
+ }
+
+ public Date engineGetCreationDate(String alias)
+ {
+ synchronized (certificateEntries)
+ {
+ BCJKSTrustedCertEntry ent = certificateEntries.get(alias);
+ if (ent != null)
+ {
+ return ent.date;
+ }
+ }
+ return null;
+ }
+
+ public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineSetCertificateEntry(String alias, Certificate cert)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineDeleteEntry(String alias)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public Enumeration<String> engineAliases()
+ {
+ synchronized (certificateEntries)
+ {
+ return certificateEntries.keys();
+ }
+ }
+
+ public boolean engineContainsAlias(String alias)
+ {
+ if (alias == null)
+ {
+ throw new NullPointerException("alias value is null");
+ }
+
+ synchronized (certificateEntries)
+ {
+ return certificateEntries.containsKey(alias);
+ }
+ }
+
+ public int engineSize()
+ {
+ return certificateEntries.size();
+ }
+
+ public boolean engineIsKeyEntry(String alias)
+ {
+ return false; // by definition
+ }
+
+ public boolean engineIsCertificateEntry(String alias)
+ {
+ synchronized (certificateEntries)
+ {
+ return certificateEntries.containsKey(alias);
+ }
+ }
+
+ public String engineGetCertificateAlias(Certificate cert)
+ {
+ synchronized (certificateEntries)
+ {
+ for (Iterator<Map.Entry<String, BCJKSTrustedCertEntry>> it = certificateEntries.entrySet().iterator(); it.hasNext(); )
+ {
+ Map.Entry<String, BCJKSTrustedCertEntry> entry = it.next();
+ if (entry.getValue().cert.equals(cert))
+ {
+ return entry.getKey();
+ }
+ }
+ return null;
+ }
+ }
+
+ public void engineStore(OutputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ throw new IOException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineLoad(KeyStore.LoadStoreParameter loadStoreParameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (loadStoreParameter == null)
+ {
+ engineLoad(null, null);
+ }
+ else if (loadStoreParameter instanceof BCLoadStoreParameter)
+ {
+ BCLoadStoreParameter bcParam = (BCLoadStoreParameter)loadStoreParameter;
+
+ engineLoad(bcParam.getInputStream(), ParameterUtil.extractPassword(loadStoreParameter));
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "no support for 'param' of type " + loadStoreParameter.getClass().getName());
+ }
+ }
+
+ public void engineLoad(InputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (stream == null)
+ {
+ return;
+ }
+
+ ErasableByteStream storeStream = validateStream(stream, password);
+
+ synchronized (certificateEntries)
+ {
+ try
+ {
+ DataInputStream dIn = new DataInputStream(storeStream);
+
+ int magic = dIn.readInt();
+ int storeVersion = dIn.readInt();
+ if (magic == (int)0x0000feedfeedL)
+ {
+ CertificateFactory certFact = null;
+ Hashtable certFactories = null;
+
+ switch (storeVersion)
+ {
+ case 1: // all certs X.509
+ certFact = createCertFactory("X.509");
+ break;
+ case 2: // provision for format in store.
+ certFactories = new Hashtable();
+ break;
+ default:
+ throw new IllegalStateException("unable to discern store version");
+ }
+
+ int numEntries = dIn.readInt();
+ for (int t = 0; t < numEntries; t++)
+ {
+ int tag = dIn.readInt();
+ switch (tag)
+ {
+ case 1: // we can't process keys
+ throw new IOException(NOT_IMPLEMENTED_MESSAGE);
+ case 2: // certificate
+ String alias = dIn.readUTF();
+ Date date = new Date(dIn.readLong());
+
+ if (storeVersion == 2)
+ {
+ String certFormat = dIn.readUTF();
+ if (certFactories.containsKey(certFormat))
+ {
+ certFact = (CertificateFactory)certFactories.get(certFormat);
+ }
+ else
+ {
+ certFact = createCertFactory(certFormat);
+ certFactories.put(certFormat, certFact);
+ }
+ }
+
+ int l = dIn.readInt();
+ byte[] certData = new byte[l];
+ dIn.readFully(certData);
+
+ ErasableByteStream certStream = new ErasableByteStream(certData, 0, certData.length);
+ Certificate cert;
+ try
+ {
+ cert = certFact.generateCertificate(certStream);
+
+ if (certStream.available() != 0)
+ {
+ throw new IOException("password incorrect or store tampered with");
+ }
+ }
+ finally
+ {
+ certStream.erase();
+ }
+
+ certificateEntries.put(alias, new BCJKSTrustedCertEntry(date, cert));
+ break;
+ default:
+ throw new IllegalStateException("unable to discern entry type");
+ }
+ }
+ }
+
+ if (storeStream.available() != 0)
+ {
+ throw new IOException("password incorrect or store tampered with");
+ }
+ }
+ finally
+ {
+ storeStream.erase();
+ }
+ }
+ }
+
+ private CertificateFactory createCertFactory(String certFormat)
+ throws CertificateException
+ {
+ if (helper != null)
+ {
+ try
+ {
+ return helper.createCertificateFactory(certFormat);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new CertificateException(e.toString());
+ }
+ }
+ else
+ {
+ return CertificateFactory.getInstance(certFormat);
+ }
+ }
+
+ /**
+ * Process password updates the digest with the password.
+ *
+ * @param digest The digest instance.
+ * @param password The password.
+ */
+ private void addPassword(Digest digest, char[] password)
+ throws IOException
+ {
+ for (int i = 0; i < password.length; ++i)
+ {
+ digest.update((byte)(password[i] >> 8));
+ digest.update((byte)password[i]);
+ }
+
+ //
+ // This "Mighty Aphrodite" string goes all the way back to the
+ // first java betas in the mid 90's, why who knows? But see
+ // https://cryptosense.com/mighty-aphrodite-dark-secrets-of-the-java-keystore/
+ //
+ digest.update(Strings.toByteArray("Mighty Aphrodite"), 0, 16);
+ }
+
+ /**
+ * Validate password takes the checksum of the store and will either.
+ * 1. If password is null, load the store into memory, return the result.
+ * 2. If password is not null, load the store into memory, test the checksum, and if successful return
+ * a new input stream instance of the store.
+ * 3. Fail if there is a password and an invalid checksum.
+ *
+ * @param inputStream The input stream.
+ * @param password the password.
+ * @return Either the passed in input stream or a new input stream.
+ * @throws IOException
+ */
+ private ErasableByteStream validateStream(InputStream inputStream, char[] password)
+ throws IOException
+ {
+ Digest checksumCalculator = DigestFactory.getDigest("SHA-1");
+ byte[] rawStore = Streams.readAll(inputStream);
+
+ if (password != null)
+ {
+ addPassword(checksumCalculator, password);
+ checksumCalculator.update(rawStore, 0, rawStore.length - checksumCalculator.getDigestSize());
+
+ byte[] checksum = new byte[checksumCalculator.getDigestSize()];
+
+ checksumCalculator.doFinal(checksum, 0);
+
+ byte[] streamChecksum = new byte[checksum.length];
+ System.arraycopy(rawStore, rawStore.length - checksum.length, streamChecksum, 0, checksum.length);
+
+ if (!Arrays.constantTimeAreEqual(checksum, streamChecksum))
+ {
+ Arrays.fill(rawStore, (byte)0);
+ throw new IOException("password incorrect or store tampered with");
+ }
+
+ return new ErasableByteStream(rawStore, 0, rawStore.length - checksum.length);
+ }
+
+ return new ErasableByteStream(rawStore, 0, rawStore.length - checksumCalculator.getDigestSize());
+ }
+
+ /**
+ * BCJKSTrustedCertEntry is a internal container for the certificate entry.
+ */
+ private static final class BCJKSTrustedCertEntry
+ {
+ final Date date;
+ final Certificate cert;
+
+ public BCJKSTrustedCertEntry(Date date, Certificate cert)
+ {
+ this.date = date;
+ this.cert = cert;
+ }
+ }
+
+ private static final class ErasableByteStream
+ extends ByteArrayInputStream
+ {
+ public ErasableByteStream(byte[] buf, int offSet, int length)
+ {
+ super(buf, offSet, length);
+ }
+
+ public void erase()
+ {
+ // this will also erase the checksum from memory.
+ Arrays.fill(buf, (byte)0);
+ }
+ }
+
+
+}
+
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/util/ParameterUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/util/ParameterUtil.java
new file mode 100644
index 0000000..1028dac
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/util/ParameterUtil.java
@@ -0,0 +1,49 @@
+package org.bouncycastle.jcajce.provider.keystore.util;
+
+import java.io.IOException;
+import java.security.KeyStore;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+public class ParameterUtil
+{
+ public static char[] extractPassword(KeyStore.LoadStoreParameter bcParam)
+ throws IOException
+ {
+ KeyStore.ProtectionParameter protParam = bcParam.getProtectionParameter();
+
+ if (protParam == null)
+ {
+ return null;
+ }
+ else if (protParam instanceof KeyStore.PasswordProtection)
+ {
+ return ((KeyStore.PasswordProtection)protParam).getPassword();
+ }
+ else if (protParam instanceof KeyStore.CallbackHandlerProtection)
+ {
+ CallbackHandler handler = ((KeyStore.CallbackHandlerProtection)protParam).getCallbackHandler();
+
+ PasswordCallback passwordCallback = new PasswordCallback("password: ", false);
+
+ try
+ {
+ handler.handle(new Callback[]{passwordCallback});
+
+ return passwordCallback.getPassword();
+ }
+ catch (UnsupportedCallbackException e)
+ {
+ throw new IllegalArgumentException("PasswordCallback not recognised: " + e.getMessage(), e);
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "no support for protection parameter of type " + protParam.getClass().getName());
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java
index d25ed90..90a9a42 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java
@@ -18,16 +18,13 @@
import javax.crypto.NoSuchPaddingException;
// END Android-added: Needed for setting padding with GCM
import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
-// Android-removed: Unsupported algorithms
-// import org.bouncycastle.asn1.cms.CCMParameters;
-import org.bouncycastle.asn1.cms.GCMParameters;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.crypto.BlockCipher;
-import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CipherKeyGenerator;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.engines.AESEngine;
@@ -42,9 +39,13 @@
import org.bouncycastle.crypto.modes.CBCBlockCipher;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.modes.CCMBlockCipher;
+// import org.bouncycastle.crypto.modes.CCMModeCipher;
import org.bouncycastle.crypto.modes.CFBBlockCipher;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.modes.OFBBlockCipher;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.internal.asn1.cms.CCMParameters;
+import org.bouncycastle.internal.asn1.cms.GCMParameters;
import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator;
@@ -74,7 +75,7 @@
private AES()
{
}
-
+
public static class ECB
extends BaseBlockCipher
{
@@ -84,18 +85,18 @@
{
public BlockCipher get()
{
- return new AESEngine();
+ return AESEngine.newInstance();
}
});
}
}
public static class CBC
- extends BaseBlockCipher
+ extends BaseBlockCipher
{
public CBC()
{
- super(new CBCBlockCipher(new AESEngine()), 128);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 128);
}
}
@@ -104,7 +105,7 @@
{
public CFB()
{
- super(new BufferedBlockCipher(new CFBBlockCipher(new AESEngine(), 128)), 128);
+ super(new DefaultBufferedBlockCipher(CFBBlockCipher.newInstance(AESEngine.newInstance(), 128)), 128);
}
}
@@ -113,7 +114,7 @@
{
public OFB()
{
- super(new BufferedBlockCipher(new OFBBlockCipher(new AESEngine(), 128)), 128);
+ super(new DefaultBufferedBlockCipher(new OFBBlockCipher(AESEngine.newInstance(), 128)), 128);
}
}
@@ -142,7 +143,7 @@
{
public CCM()
{
- super(new CCMBlockCipher(new AESEngine()), false, 12);
+ super(CCMBlockCipher.newInstance(AESEngine.newInstance()), false, 12);
}
}
@@ -151,7 +152,7 @@
{
public AESCMAC()
{
- super(new CMac(new AESEngine()));
+ super(new CMac(AESEngine.newInstance()));
}
}
@@ -160,7 +161,7 @@
{
public AESGMAC()
{
- super(new GMac(new GCMBlockCipher(new AESEngine())));
+ super(new GMac(GCMBlockCipher.newInstance(AESEngine.newInstance())));
}
}
@@ -175,7 +176,7 @@
private static class CCMMac
implements Mac
{
- private final CCMBlockCipher ccm = new CCMBlockCipher(new AESEngine());
+ private final CCMModeCipher ccm = CCMBlockCipher.newInstance(AESEngine.newInstance());
private int macLength = 8;
@@ -230,7 +231,7 @@
}
static public class KeyFactory
- extends BaseSecretKeyFactory
+ extends BaseSecretKeyFactory
{
public KeyFactory()
{
@@ -243,7 +244,7 @@
{
public Poly1305()
{
- super(new org.bouncycastle.crypto.macs.Poly1305(new AESEngine()));
+ super(new org.bouncycastle.crypto.macs.Poly1305(AESEngine.newInstance()));
}
}
@@ -283,7 +284,7 @@
{
public RFC3211Wrap()
{
- super(new RFC3211WrapEngine(new AESEngine()), 16);
+ super(new RFC3211WrapEngine(AESEngine.newInstance()), 16);
}
}
@@ -292,7 +293,7 @@
{
public RFC5649Wrap()
{
- super(new RFC5649WrapEngine(new AESEngine()));
+ super(new RFC5649WrapEngine(AESEngine.newInstance()));
}
}
*/
@@ -306,7 +307,7 @@
{
public PBEWithAESCBC()
{
- super(new CBCBlockCipher(new AESEngine()));
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()));
}
}
@@ -318,7 +319,7 @@
{
public PBEWithSHA1AESCBC128()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 128, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 128, 16);
}
}
@@ -327,7 +328,7 @@
{
public PBEWithSHA1AESCBC192()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 192, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 192, 16);
}
}
@@ -336,7 +337,7 @@
{
public PBEWithSHA1AESCBC256()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 256, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 256, 16);
}
}
@@ -348,7 +349,7 @@
{
public PBEWithSHA256AESCBC128()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 128, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 128, 16);
}
}
@@ -357,7 +358,7 @@
{
public PBEWithSHA256AESCBC192()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 192, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 192, 16);
}
}
@@ -366,7 +367,7 @@
{
public PBEWithSHA256AESCBC256()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 256, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 256, 16);
}
}
@@ -431,7 +432,7 @@
super("PBEWithSHA1And128BitAES-CBC-BC", null, true, PKCS12, SHA1, 128, 128);
}
}
-
+
/**
* PBEWithSHA1And192BitAES-BC
*/
@@ -443,7 +444,7 @@
super("PBEWithSHA1And192BitAES-CBC-BC", null, true, PKCS12, SHA1, 192, 128);
}
}
-
+
/**
* PBEWithSHA1And256BitAES-BC
*/
@@ -455,7 +456,7 @@
super("PBEWithSHA1And256BitAES-CBC-BC", null, true, PKCS12, SHA1, 256, 128);
}
}
-
+
/**
* PBEWithSHA256And128BitAES-BC
*/
@@ -467,7 +468,7 @@
super("PBEWithSHA256And128BitAES-CBC-BC", null, true, PKCS12, SHA256, 128, 128);
}
}
-
+
/**
* PBEWithSHA256And192BitAES-BC
*/
@@ -479,7 +480,7 @@
super("PBEWithSHA256And192BitAES-CBC-BC", null, true, PKCS12, SHA256, 192, 128);
}
}
-
+
/**
* PBEWithSHA256And256BitAES-BC
*/
@@ -491,7 +492,7 @@
super("PBEWithSHA256And256BitAES-CBC-BC", null, true, PKCS12, SHA256, 256, 128);
}
}
-
+
/**
* PBEWithMD5And128BitAES-OpenSSL
*/
@@ -503,7 +504,7 @@
super("PBEWithMD5And128BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 128, 128);
}
}
-
+
/**
* PBEWithMD5And192BitAES-OpenSSL
*/
@@ -515,7 +516,7 @@
super("PBEWithMD5And192BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 192, 128);
}
}
-
+
/**
* PBEWithMD5And256BitAES-OpenSSL
*/
@@ -543,7 +544,7 @@
protected AlgorithmParameters engineGenerateParameters()
{
- byte[] iv = new byte[16];
+ byte[] iv = new byte[16];
if (random == null)
{
@@ -582,7 +583,7 @@
protected AlgorithmParameters engineGenerateParameters()
{
- byte[] iv = new byte[12];
+ byte[] iv = new byte[12];
if (random == null)
{
@@ -621,7 +622,7 @@
protected AlgorithmParameters engineGenerateParameters()
{
- byte[] nonce = new byte[12];
+ byte[] nonce = new byte[12];
if (random == null)
{
@@ -723,7 +724,7 @@
{
if (paramSpec == AlgorithmParameterSpec.class || GcmSpecUtil.isGcmSpec(paramSpec))
{
- if (GcmSpecUtil.gcmSpecExists())
+ if (GcmSpecUtil.gcmSpecExtractable())
{
return GcmSpecUtil.extractGcmSpec(gcmParams.toASN1Primitive());
}
@@ -810,7 +811,7 @@
{
if (paramSpec == AlgorithmParameterSpec.class || GcmSpecUtil.isGcmSpec(paramSpec))
{
- if (GcmSpecUtil.gcmSpecExists())
+ if (GcmSpecUtil.gcmSpecExtractable())
{
return GcmSpecUtil.extractGcmSpec(ccmParams.toASN1Primitive());
}
@@ -835,7 +836,7 @@
extends SymmetricAlgorithmProvider
{
private static final String PREFIX = AES.class.getName();
-
+
/**
* These three got introduced in some messages as a result of a typo in an
* early document. We don't produce anything using these OID values, but we'll
@@ -997,31 +998,31 @@
provider.addAlgorithm("Cipher.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC128");
provider.addAlgorithm("Cipher.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC192");
provider.addAlgorithm("Cipher.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC256");
-
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
provider.addAlgorithm("Cipher.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
provider.addAlgorithm("Cipher.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
@@ -1035,48 +1036,48 @@
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And128BitAESCBCOpenSSL");
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And192BitAESCBCOpenSSL");
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND256BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And256BitAESCBCOpenSSL");
-
+
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND128BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd128BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND192BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd192BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND256BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd256BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And128BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And192BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And256BitAESBC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc, "PBEWITHSHAAND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc, "PBEWITHSHAAND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc, "PBEWITHSHAAND256BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc, "PBEWITHSHA256AND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc, "PBEWITHSHA256AND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc, "PBEWITHSHA256AND256BITAES-CBC-BC");
-
+
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND192BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND256BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND128BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND192BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND256BITAES-CBC-BC", "PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND128BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND192BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND256BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND128BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND192BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND256BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC","PKCS12PBE");
-
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND128BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND192BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND256BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND128BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND192BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND256BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC", "PKCS12PBE");
+
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), "PKCS12PBE");
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java
deleted file mode 100644
index a28cf3e..0000000
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.bouncycastle.jcajce.provider.symmetric;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
-
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.cms.GCMParameters;
-import org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil;
-import org.bouncycastle.util.Integers;
-
-class GcmSpecUtil
-{
- static final Class gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
-
- static boolean gcmSpecExists()
- {
- return gcmSpecClass != null;
- }
-
- static boolean isGcmSpec(AlgorithmParameterSpec paramSpec)
- {
- return gcmSpecClass != null && gcmSpecClass.isInstance(paramSpec);
- }
-
- static boolean isGcmSpec(Class paramSpecClass)
- {
- return gcmSpecClass == paramSpecClass;
- }
-
- static AlgorithmParameterSpec extractGcmSpec(ASN1Primitive spec)
- throws InvalidParameterSpecException
- {
- try
- {
- GCMParameters gcmParams = GCMParameters.getInstance(spec);
- Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
-
- return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() });
- }
- catch (NoSuchMethodException e)
- {
- throw new InvalidParameterSpecException("No constructor found!"); // should never happen
- }
- catch (Exception e)
- {
- throw new InvalidParameterSpecException("Construction failed: " + e.getMessage()); // should never happen
- }
- }
-
- static GCMParameters extractGcmParameters(AlgorithmParameterSpec paramSpec)
- throws InvalidParameterSpecException
- {
- try
- {
- Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
- Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
-
- return new GCMParameters((byte[])iv.invoke(paramSpec, new Object[0]), ((Integer)tLen.invoke(paramSpec, new Object[0])).intValue() / 8);
- }
- catch (Exception e)
- {
- throw new InvalidParameterSpecException("Cannot process GCMParameterSpec");
- }
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
index e384134..3e317a2 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
@@ -545,6 +545,15 @@
super("PBKDF2", PKCS5S2_UTF8, SM3);
}
}
+
+ public static class PBKDF2withSM3
+ extends BasePBKDF2
+ {
+ public PBKDF2withSM3()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, SM3);
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
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 d4756df..240e003 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
@@ -69,19 +69,23 @@
public String getAlgorithm()
{
+ String rv = this.algorithm;
+
checkDestroyed(this);
- return algorithm;
+ return rv;
}
public String getFormat()
{
+ checkDestroyed(this);
+
return "RAW";
}
public byte[] getEncoded()
{
- checkDestroyed(this);
+ byte[] enc;
if (param != null)
{
@@ -96,58 +100,72 @@
kParam = (KeyParameter)param;
}
- return kParam.getKey();
+ enc = kParam.getKey();
}
else
{
if (type == PBE.PKCS12)
{
- return PBEParametersGenerator.PKCS12PasswordToBytes(password);
+ enc = PBEParametersGenerator.PKCS12PasswordToBytes(password);
}
else if (type == PBE.PKCS5S2_UTF8)
{
- return PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password);
+ enc = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password);
}
else
{
- return PBEParametersGenerator.PKCS5PasswordToBytes(password);
+ enc = PBEParametersGenerator.PKCS5PasswordToBytes(password);
}
}
+
+ checkDestroyed(this);
+
+ return enc;
}
int getType()
{
+ int rv = type;
+
checkDestroyed(this);
- return type;
+ return rv;
}
int getDigest()
{
+ int rv = digest;
+
checkDestroyed(this);
- return digest;
+ return rv;
}
int getKeySize()
{
+ int rv = keySize;
+
checkDestroyed(this);
- return keySize;
+ return rv;
}
public int getIvSize()
{
+ int rv = ivSize;
+
checkDestroyed(this);
- return ivSize;
+ return rv;
}
public CipherParameters getParam()
{
+ CipherParameters rv = param;
+
checkDestroyed(this);
- return param;
+ return rv;
}
/* (non-Javadoc)
@@ -155,14 +173,16 @@
*/
public char[] getPassword()
{
+ char[] clone = Arrays.clone(password);
+
checkDestroyed(this);
- if (password == null)
+ if (clone == null)
{
throw new IllegalStateException("no password available");
}
- return Arrays.clone(password);
+ return clone;
}
/* (non-Javadoc)
@@ -170,9 +190,11 @@
*/
public byte[] getSalt()
{
+ byte[] clone = Arrays.clone(salt);
+
checkDestroyed(this);
- return Arrays.clone(salt);
+ return clone;
}
/* (non-Javadoc)
@@ -180,16 +202,20 @@
*/
public int getIterationCount()
{
+ int rv = iterationCount;
+
checkDestroyed(this);
- return iterationCount;
+ return rv;
}
public ASN1ObjectIdentifier getOID()
{
+ ASN1ObjectIdentifier rv = oid;
+
checkDestroyed(this);
- return oid;
+ return rv;
}
public void setTryWrongPKCS12Zero(boolean tryWrong)
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 7dadfa7..4af5297 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
@@ -28,17 +28,20 @@
// import javax.crypto.spec.RC5ParameterSpec;
import org.bouncycastle.asn1.DEROctetString;
-import org.bouncycastle.asn1.cms.GCMParameters;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.OutputLengthException;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.engines.DSTU7624Engine;
+// import org.bouncycastle.crypto.fpe.FPEEngine;
+// import org.bouncycastle.crypto.fpe.FPEFF1Engine;
+// import org.bouncycastle.crypto.fpe.FPEFF3_1Engine;
import org.bouncycastle.crypto.modes.AEADBlockCipher;
import org.bouncycastle.crypto.modes.AEADCipher;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
@@ -50,6 +53,7 @@
// import org.bouncycastle.crypto.modes.GCFBBlockCipher;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.modes.GCMSIVBlockCipher;
// import org.bouncycastle.crypto.modes.GOFBBlockCipher;
// import org.bouncycastle.crypto.modes.KCCMBlockCipher;
// import org.bouncycastle.crypto.modes.KCTRBlockCipher;
@@ -59,6 +63,8 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher;
// import org.bouncycastle.crypto.modes.PGPCFBBlockCipher;
+import org.bouncycastle.crypto.paddings.PKCS7Padding;
+// import org.bouncycastle.crypto.params.FPEParameters;
import org.bouncycastle.crypto.modes.SICBlockCipher;
import org.bouncycastle.crypto.paddings.BlockCipherPadding;
import org.bouncycastle.crypto.paddings.ISO10126d2Padding;
@@ -84,6 +90,8 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
// import org.bouncycastle.jcajce.spec.RepeatedSecretKeySpec;
+import org.bouncycastle.internal.asn1.cms.GCMParameters;
+// import org.bouncycastle.jcajce.spec.FPEParameterSpec;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Strings;
@@ -92,7 +100,6 @@
implements PBE
{
private static final int BUF_SIZE = 512;
- private static final Class gcmSpecClass = ClassUtil.loadClass(BaseBlockCipher.class, "javax.crypto.spec.GCMParameterSpec");
//
// specs we can handle.
@@ -102,7 +109,7 @@
// Android-removed: Unsupported alhorithms
// RC2ParameterSpec.class,
// RC5ParameterSpec.class,
- gcmSpecClass,
+ GcmSpecUtil.gcmSpecClass,
// Android-removed: unsupported algorithms
// GOST28147ParameterSpec.class,
IvParameterSpec.class,
@@ -166,7 +173,14 @@
AEADBlockCipher engine)
{
this.baseEngine = engine.getUnderlyingCipher();
- this.ivLength = baseEngine.getBlockSize();
+ if (engine.getAlgorithmName().indexOf("GCM") >= 0)
+ {
+ this.ivLength = 12;
+ }
+ else
+ {
+ this.ivLength = baseEngine.getBlockSize();
+ }
this.cipher = new AEADGenericBlockCipher(engine);
}
@@ -348,7 +362,7 @@
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(
- new CBCBlockCipher(baseEngine));
+ CBCBlockCipher.newInstance(baseEngine));
}
else if (modeName.startsWith("OFB"))
{
@@ -374,12 +388,12 @@
int wordSize = Integer.parseInt(modeName.substring(3));
cipher = new BufferedGenericBlockCipher(
- new CFBBlockCipher(baseEngine, wordSize));
+ CFBBlockCipher.newInstance(baseEngine, wordSize));
}
else
{
cipher = new BufferedGenericBlockCipher(
- new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
+ CFBBlockCipher.newInstance(baseEngine, 8 * baseEngine.getBlockSize()));
}
}
// BEGIN Android-removed: Unsupported modes
@@ -403,6 +417,18 @@
cipher = new BufferedGenericBlockCipher(
new OpenPGPCFBBlockCipher(baseEngine));
}
+ else if (modeName.equals("FF1"))
+ {
+ ivLength = 0;
+ cipher = new BufferedFPEBlockCipher(
+ new FPEFF1Engine(baseEngine));
+ }
+ else if (modeName.equals("FF3-1"))
+ {
+ ivLength = 0;
+ cipher = new BufferedFPEBlockCipher(
+ new FPEFF3_1Engine(baseEngine));
+ }
else if (modeName.equals("SIC"))
{
ivLength = baseEngine.getBlockSize();
@@ -411,8 +437,8 @@
throw new IllegalArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
}
fixedIv = false;
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new SICBlockCipher(baseEngine)));
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
+ SICBlockCipher.newInstance(baseEngine)));
}
*/
// END Android-removed: Unsupported modes
@@ -424,14 +450,14 @@
/*
if (baseEngine instanceof DSTU7624Engine)
{
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
new KCTRBlockCipher(baseEngine)));
}
else
{
*/
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new SICBlockCipher(baseEngine)));
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
+ SICBlockCipher.newInstance(baseEngine)));
/*
}
*/
@@ -441,13 +467,13 @@
else if (modeName.equals("GOFB"))
{
ivLength = baseEngine.getBlockSize();
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
new GOFBBlockCipher(baseEngine)));
}
else if (modeName.equals("GCFB"))
{
ivLength = baseEngine.getBlockSize();
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
new GCFBBlockCipher(baseEngine)));
}
*/
@@ -455,7 +481,7 @@
else if (modeName.equals("CTS"))
{
ivLength = baseEngine.getBlockSize();
- cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(new CBCBlockCipher(baseEngine)));
+ cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(CBCBlockCipher.newInstance(baseEngine)));
}
else if (modeName.equals("CCM"))
{
@@ -469,7 +495,7 @@
else
{
*/
- cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine));
+ cipher = new AEADGenericBlockCipher(CCMBlockCipher.newInstance(baseEngine));
/*
}
*/
@@ -505,12 +531,13 @@
/*
if (baseEngine instanceof DSTU7624Engine)
{
+ ivLength = baseEngine.getBlockSize();
cipher = new AEADGenericBlockCipher(new KGCMBlockCipher(baseEngine));
}
else
{
*/
- cipher = new AEADGenericBlockCipher(new GCMBlockCipher(baseEngine));
+ cipher = new AEADGenericBlockCipher(GCMBlockCipher.newInstance(baseEngine));
/*
}
*/
@@ -536,7 +563,7 @@
{
if (cipher.wrapOnNoPadding())
{
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(cipher.getUnderlyingCipher()));
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(cipher.getUnderlyingCipher()));
}
}
else if (paddingName.equals("WITHCTS") || paddingName.equals("CTSPADDING") || paddingName.equals("CS3PADDING"))
@@ -845,7 +872,7 @@
GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
param = new ParametersWithSBox(
- new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox());
+ new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSBox());
if (gost28147Param.getIV() != null && ivLength != 0)
{
@@ -918,9 +945,15 @@
ivParam = (ParametersWithIV)param;
}
}
+ else if (params instanceof FPEParameterSpec)
+ {
+ FPEParameterSpec spec = (FPEParameterSpec)params;
+
+ param = new FPEParameters((KeyParameter)param, spec.getRadixConverter(), spec.getTweak(), spec.isUsingInverseFunction());
+ }
*/
// END Android-removed: Unsupported algorithms
- else if (gcmSpecClass != null && gcmSpecClass.isInstance(params))
+ else if (GcmSpecUtil.isGcmSpec(params))
{
if (!isAEADModeName(modeName) && !(cipher instanceof AEADGenericBlockCipher))
{
@@ -1044,7 +1077,7 @@
// need to pick up IV and SBox.
GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
- param = new ParametersWithSBox(param, gost28147Param.getSbox());
+ param = new ParametersWithSBox(param, gost28147Param.getSBox());
if (gost28147Param.getIV() != null && ivLength != 0)
{
@@ -1071,7 +1104,7 @@
// need to pick up IV and SBox.
GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
- param = new ParametersWithSBox(param, gost28147Param.getSbox());
+ param = new ParametersWithSBox(param, gost28147Param.getSBox());
if (gost28147Param.getIV() != null && ivLength != 0)
{
@@ -1347,7 +1380,7 @@
BufferedGenericBlockCipher(org.bouncycastle.crypto.BlockCipher cipher)
{
- this.cipher = new PaddedBufferedBlockCipher(cipher);
+ this(cipher, new PKCS7Padding());
}
BufferedGenericBlockCipher(org.bouncycastle.crypto.BlockCipher cipher, BlockCipherPadding padding)
@@ -1417,6 +1450,85 @@
}
}
+ // BEGIN Android-removed: unsupported
+ // private static class BufferedFPEBlockCipher
+ // implements GenericBlockCipher
+ // {
+ // private FPEEngine cipher;
+ // private ErasableOutputStream eOut = new ErasableOutputStream();
+
+ // BufferedFPEBlockCipher(FPEEngine cipher)
+ // {
+ // this.cipher = cipher;
+ // }
+
+ // public void init(boolean forEncryption, CipherParameters params)
+ // throws IllegalArgumentException
+ // {
+ // cipher.init(forEncryption, params);
+ // }
+
+ // public boolean wrapOnNoPadding()
+ // {
+ // return false;
+ // }
+
+ // public String getAlgorithmName()
+ // {
+ // return cipher.getAlgorithmName();
+ // }
+
+ // public org.bouncycastle.crypto.BlockCipher getUnderlyingCipher()
+ // {
+ // throw new IllegalStateException("not applicable for FPE");
+ // }
+
+ // public int getOutputSize(int len)
+ // {
+ // return eOut.size() + len;
+ // }
+
+ // public int getUpdateOutputSize(int len)
+ // {
+ // return 0;
+ // }
+
+ // public void updateAAD(byte[] input, int offset, int length)
+ // {
+ // throw new UnsupportedOperationException("AAD is not supported in the current mode.");
+ // }
+
+ // public int processByte(byte in, byte[] out, int outOff)
+ // throws DataLengthException
+ // {
+ // eOut.write(in);
+
+ // return 0;
+ // }
+
+ // public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ // throws DataLengthException
+ // {
+ // eOut.write(in, inOff, len);
+
+ // return 0;
+ // }
+
+ // public int doFinal(byte[] out, int outOff)
+ // throws IllegalStateException, BadPaddingException
+ // {
+ // try
+ // {
+ // return cipher.processBlock(eOut.getBuf(), 0, eOut.size(), out, outOff);
+ // }
+ // finally
+ // {
+ // eOut.erase();
+ // }
+ // }
+ // }
+ // END Android-removed: unsupported
+
private static class AEADGenericBlockCipher
implements GenericBlockCipher
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
index 9f5ac19..757b612 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
@@ -32,8 +32,6 @@
public class BaseMac
extends MacSpi implements PBE
{
- private static final Class gcmSpecClass = ClassUtil.loadClass(BaseMac.class, "javax.crypto.spec.GCMParameterSpec");
-
private Mac macEngine;
private int scheme = PKCS12;
@@ -211,7 +209,7 @@
{
param = new KeyParameter(key.getEncoded());
}
- else if (gcmSpecClass != null && gcmSpecClass.isAssignableFrom(params.getClass()))
+ else if (GcmSpecUtil.isGcmSpec(params))
{
param = GcmSpecUtil.extractAeadParameters(keyParam, params);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java
index 37ea08b..71344f8 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java
@@ -23,7 +23,9 @@
{
try
{
- return Class.forName(className);
+ ClassLoader classLoader = ClassLoader.getSystemClassLoader();
+
+ return classLoader.loadClass(className);
}
catch (Exception e)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
index 6cf2020..497ebc0 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
@@ -10,32 +10,55 @@
import java.security.spec.InvalidParameterSpecException;
import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.cms.GCMParameters;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.internal.asn1.cms.GCMParameters;
import org.bouncycastle.util.Integers;
public class GcmSpecUtil
{
- static final Class gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
-
- static final Method tLen;
- static final Method iv;
+ static final Class gcmSpecClass;
+ private static final Constructor constructor;
+ private static final Method tLen;
+ private static final Method iv;
static
{
+ gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
+
if (gcmSpecClass != null)
{
+ constructor = extractConstructor();
tLen = extractMethod("getTLen");
iv = extractMethod("getIV");
}
else
{
+ constructor = null;
tLen = null;
iv = null;
}
}
+ private static Constructor extractConstructor()
+ {
+ try
+ {
+ return (Constructor)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return gcmSpecClass.getConstructor(new Class[]{ Integer.TYPE, byte[].class });
+ }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ return null;
+ }
+ }
+
private static Method extractMethod(final String name)
{
try
@@ -60,6 +83,11 @@
return gcmSpecClass != null;
}
+ public static boolean gcmSpecExtractable()
+ {
+ return constructor != null;
+ }
+
public static boolean isGcmSpec(AlgorithmParameterSpec paramSpec)
{
return gcmSpecClass != null && gcmSpecClass.isInstance(paramSpec);
@@ -76,14 +104,9 @@
try
{
GCMParameters gcmParams = GCMParameters.getInstance(spec);
- Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() });
}
- catch (NoSuchMethodException e)
- {
- throw new InvalidParameterSpecException("No constructor found!"); // should never happen
- }
catch (Exception e)
{
throw new InvalidParameterSpecException("Construction failed: " + e.getMessage()); // should never happen
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 a0621cf..e3c1d50 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
@@ -14,6 +14,7 @@
import javax.crypto.spec.PBEParameterSpec;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicePurpose;
import org.bouncycastle.crypto.PBEParametersGenerator;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.digests.GOST3411Digest;
@@ -103,25 +104,25 @@
{
// Android-removed: Unsupported algorithms
// case MD2:
- // generator = new PKCS5S2ParametersGenerator(new MD2Digest());
+ // generator = new PKCS5S2ParametersGenerator(new MD2Digest(CryptoServicePurpose.PRF));
// break;
case MD5:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createMD5());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createMD5PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getMD5());
break;
case SHA1:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA1());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA1PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA1());
break;
// BEGIN Android-removed: Unsupported algorithms
/*
case RIPEMD160:
- generator = new PKCS5S2ParametersGenerator(new RIPEMD160Digest());
+ generator = new PKCS5S2ParametersGenerator(new RIPEMD160Digest(CryptoServicePurpose.PRF));
break;
case TIGER:
- generator = new PKCS5S2ParametersGenerator(new TigerDigest());
+ generator = new PKCS5S2ParametersGenerator(new TigerDigest(CryptoServicePurpose.PRF));
break;
*/
// END Android-removed: Unsupported algorithms
@@ -132,36 +133,43 @@
break;
// Android-removed: Unsupported algorithms
// case GOST3411:
+ // generator = new PKCS5S2ParametersGenerator(new GOST3411Digest(CryptoServicePurpose.PRF));
+ // break;
+ // Android-removed: Unsupported algorithms
+ // case GOST3411:
// generator = new PKCS5S2ParametersGenerator(new GOST3411Digest());
// break;
case SHA224:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA224());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA224PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA224());
break;
case SHA384:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA384());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA384PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA384());
break;
case SHA512:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA512());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA512PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA512());
break;
// BEGIN Android-removed: Unsupported algorithms
/*
case SHA3_224:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_224());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_224PRF());
break;
case SHA3_256:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_256());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_256PRF());
break;
case SHA3_384:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_384());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_384PRF());
break;
case SHA3_512:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_512());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_512PRF());
+ break;
+ case SM3:
+ generator = new PKCS5S2ParametersGenerator(new SM3Digest(CryptoServicePurpose.PRF));
break;
case SM3:
generator = new PKCS5S2ParametersGenerator(new SM3Digest());
@@ -178,50 +186,54 @@
{
// Android-removed: Unsupported algorithms
// case MD2:
- // generator = new PKCS12ParametersGenerator(new MD2Digest());
+ // generator = new PKCS12ParametersGenerator(new MD2Digest(CryptoServicePurpose.PRF));
// break;
case MD5:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createMD5());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createMD5PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getMD5());
break;
case SHA1:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA1());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA1PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA1());
break;
// BEGIN Android-removed: Unsupported algorithms
/*
case RIPEMD160:
- generator = new PKCS12ParametersGenerator(new RIPEMD160Digest());
+ generator = new PKCS12ParametersGenerator(new RIPEMD160Digest(CryptoServicePurpose.PRF));
break;
case TIGER:
- generator = new PKCS12ParametersGenerator(new TigerDigest());
+ generator = new PKCS12ParametersGenerator(new TigerDigest(CryptoServicePurpose.PRF));
break;
*/
// END Android-removed: Unsupported algorithms
case SHA256:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA256());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA256PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA256());
break;
// Android-removed: Unsupported algorithms
// case GOST3411:
+ // generator = new PKCS12ParametersGenerator(new GOST3411Digest(CryptoServicePurpose.PRF));
+ // break;
+ // Android-removed: Unsupported algorithms
+ // case GOST3411:
// generator = new PKCS12ParametersGenerator(new GOST3411Digest());
// break;
case SHA224:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA224());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA224PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA224());
break;
case SHA384:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA384());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA384PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA384());
break;
case SHA512:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA512());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA512PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA512());
break;
default:
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java
index fc4cf4f..4d912ac 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java
@@ -1,5 +1,7 @@
package org.bouncycastle.jcajce.provider.util;
+import java.util.Map;
+
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
@@ -17,6 +19,24 @@
provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, algorithm);
}
+ protected void addSignatureAlias(
+ ConfigurableProvider provider,
+ String algorithm,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, algorithm);
+ }
+
+ protected void addSignatureAlgorithm(
+ ConfigurableProvider provider,
+ String digest,
+ String algorithm,
+ String className)
+ {
+ addSignatureAlgorithm(provider, digest, algorithm, className, null);
+ }
+
protected void addSignatureAlgorithm(
ConfigurableProvider provider,
String digest,
@@ -33,8 +53,103 @@
provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation1, mainName);
provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation2, mainName);
provider.addAlgorithm("Alg.Alias.Signature." + alias, mainName);
- provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
- provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
+ }
+ }
+
+ protected void addSignatureAlgorithm(
+ ConfigurableProvider provider,
+ String digest,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid,
+ Map<String, String> attributes)
+ {
+ String mainName = digest + "WITH" + algorithm;
+ String jdk11Variation1 = digest + "with" + algorithm;
+ String jdk11Variation2 = digest + "With" + algorithm;
+ String alias = digest + "/" + algorithm;
+
+ provider.addAlgorithm("Signature." + mainName, className);
+ provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation1, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation2, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + alias, mainName);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
+ }
+ provider.addAttributes("Signature." + mainName, attributes);
+ }
+
+ protected void addKeyPairGeneratorAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("KeyPairGenerator." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyPairGenerator." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.KeyPairGenerator.OID." + oid, algorithm);
+ }
+ }
+
+ protected void addKeyFactoryAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid,
+ AsymmetricKeyInfoConverter keyInfoConverter)
+ {
+ provider.addAlgorithm("KeyFactory." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyFactory." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.KeyFactory.OID." + oid, algorithm);
+
+ provider.addKeyInfoConverter(oid, keyInfoConverter);
+ }
+ }
+
+ protected void addKeyGeneratorAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("KeyGenerator." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyGenerator." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.OID." + oid, algorithm);
+ }
+ }
+
+ protected void addCipherAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("Cipher." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.Cipher." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.Cipher.OID." + oid, algorithm);
+ }
+ }
+
+ protected void registerKeyFactoryOid(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name, AsymmetricKeyInfoConverter keyFactory)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyFactory." + oid, name);
+ provider.addAlgorithm("Alg.Alias.KeyFactory.OID." + oid, name);
+
+ provider.addKeyInfoConverter(oid, keyFactory);
}
protected void registerOid(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name, AsymmetricKeyInfoConverter keyFactory)
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java
index 552a6e6..f442aeb 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java
@@ -31,6 +31,8 @@
private static Set sha3_256 = new HashSet();
private static Set sha3_384 = new HashSet();
private static Set sha3_512 = new HashSet();
+ private static Set shake128 = new HashSet();
+ private static Set shake256 = new HashSet();
*/
// END Android-removed: Unsupported algorithms
@@ -82,6 +84,18 @@
sha3_512.add("SHA3-512");
sha3_512.add(NISTObjectIdentifiers.id_sha3_512.getId());
+
+ shake128.add("SHAKE128");
+ shake128.add(NISTObjectIdentifiers.id_shake128.getId());
+
+ shake256.add("SHAKE256");
+ shake256.add(NISTObjectIdentifiers.id_shake256.getId());
+
+ oids.put("SHAKE128", NISTObjectIdentifiers.id_shake128);
+ oids.put(NISTObjectIdentifiers.id_shake128.getId(), NISTObjectIdentifiers.id_shake128);
+
+ oids.put("SHAKE256", NISTObjectIdentifiers.id_shake256);
+ oids.put(NISTObjectIdentifiers.id_shake256.getId(), NISTObjectIdentifiers.id_shake256);
*/
// END Android-removed: Unsupported algorithms
@@ -198,6 +212,14 @@
{
return org.bouncycastle.crypto.util.DigestFactory.createSHA3_512();
}
+ if (shake128.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHAKE128();
+ }
+ if (shake256.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHAKE256();
+ }
*/
// END Android-removed: Unsupported algorithms
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/FPEParameterSpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/FPEParameterSpec.java
new file mode 100644
index 0000000..f24de23
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/FPEParameterSpec.java
@@ -0,0 +1,51 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.bouncycastle.crypto.util.RadixConverter;
+import org.bouncycastle.util.Arrays;
+
+public class FPEParameterSpec
+ implements AlgorithmParameterSpec
+{
+ private final RadixConverter radixConverter;
+ private final byte[] tweak;
+ private final boolean useInverse;
+
+ public FPEParameterSpec(int radix, byte[] tweak)
+ {
+ this(radix, tweak, false);
+ }
+
+ public FPEParameterSpec(int radix, byte[] tweak, boolean useInverse)
+ {
+ this(new RadixConverter(radix), tweak, useInverse);
+ }
+
+ public FPEParameterSpec(RadixConverter radixConverter, byte[] tweak, boolean useInverse)
+ {
+ this.radixConverter = radixConverter;
+ this.tweak = Arrays.clone(tweak);
+ this.useInverse = useInverse;
+ }
+
+ public int getRadix()
+ {
+ return radixConverter.getRadix();
+ }
+
+ public RadixConverter getRadixConverter()
+ {
+ return radixConverter;
+ }
+
+ public byte[] getTweak()
+ {
+ return Arrays.clone(tweak);
+ }
+
+ public boolean isUsingInverseFunction()
+ {
+ return useInverse;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java
new file mode 100644
index 0000000..6bf3835
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java
@@ -0,0 +1,97 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.security.auth.Destroyable;
+
+import org.bouncycastle.util.Arrays;
+
+/**
+ * SP 800-56C Hybrid Value spec, to allow the secret in a key agreement to be
+ * created as "Z | T" where T is some other secret value as described in Section 2.
+ * <p>
+ * Get methods throw IllegalStateException if destroy() is called.
+ * </p>
+ */
+public class HybridValueParameterSpec
+ implements AlgorithmParameterSpec, Destroyable
+{
+ private final AtomicBoolean hasBeenDestroyed = new AtomicBoolean(false);
+
+ private volatile byte[] t;
+ private volatile AlgorithmParameterSpec baseSpec;
+
+ /**
+ * Create a spec with T set to t and the spec for the KDF in the agreement to baseSpec.
+ * Note: the t value is not copied.
+ *
+ * @param t a shared secret to be concatenated with the agreement's Z value.
+ * @param baseSpec the base spec for the agreements KDF.
+ */
+ public HybridValueParameterSpec(byte[] t, AlgorithmParameterSpec baseSpec)
+ {
+ this.t = t;
+ this.baseSpec = baseSpec;
+ }
+
+ /**
+ * Return a reference to the T value.
+ *
+ * @return a reference to T.
+ */
+ public byte[] getT()
+ {
+ byte[] tVal = t;
+
+ checkDestroyed();
+
+ return tVal;
+ }
+
+ /**
+ * Return the base parameter spec.
+ *
+ * @return base spec to be applied to the KDF.
+ */
+ public AlgorithmParameterSpec getBaseParameterSpec()
+ {
+ AlgorithmParameterSpec rv = this.baseSpec;
+
+ checkDestroyed();
+
+ return rv;
+ }
+
+ /**
+ * Return true if the destroy() method is called and the contents are
+ * erased.
+ *
+ * @return true if destroyed, false otherwise.
+ */
+ public boolean isDestroyed()
+ {
+ return this.hasBeenDestroyed.get();
+ }
+
+ /**
+ * Destroy this parameter spec, explicitly erasing its contents.
+ */
+ public void destroy()
+ {
+ if (!hasBeenDestroyed.getAndSet(true))
+ {
+ Arrays.clear(t);
+ this.t = null;
+ this.baseSpec = null;
+ }
+ }
+
+ private void checkDestroyed()
+ {
+ if (isDestroyed())
+ {
+ throw new IllegalStateException("spec has been destroyed");
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/IESKEMParameterSpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/IESKEMParameterSpec.java
new file mode 100644
index 0000000..11ca348
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/IESKEMParameterSpec.java
@@ -0,0 +1,51 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.bouncycastle.util.Arrays;
+
+/**
+ * Parameter spec for an integrated encryptor KEM, as in IEEE_Std_1609_2
+ */
+public class IESKEMParameterSpec
+ implements AlgorithmParameterSpec
+{
+ private final byte[] recipientInfo;
+ private final boolean usePointCompression;
+
+
+ /**
+ * Set the IESKEM parameters.
+ *
+ * @param recipientInfo recipient data.
+ */
+ public IESKEMParameterSpec(
+ byte[] recipientInfo)
+ {
+ this(recipientInfo, false);
+ }
+
+ /**
+ * Set the IESKEM parameters - specifying point compression.
+ *
+ * @param recipientInfo recipient data.
+ * @param usePointCompression use point compression on output (ignored on input).
+ */
+ public IESKEMParameterSpec(
+ byte[] recipientInfo,
+ boolean usePointCompression)
+ {
+ this.recipientInfo = Arrays.clone(recipientInfo);
+ this.usePointCompression = usePointCompression;
+ }
+
+ public byte[] getRecipientInfo()
+ {
+ return Arrays.clone(recipientInfo);
+ }
+
+ public boolean hasUsePointCompression()
+ {
+ return usePointCompression;
+ }
+}
\ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/KEMExtractSpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/KEMExtractSpec.java
new file mode 100644
index 0000000..6ece51e
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/KEMExtractSpec.java
@@ -0,0 +1,48 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.security.PrivateKey;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.bouncycastle.util.Arrays;
+
+public class KEMExtractSpec
+ implements AlgorithmParameterSpec
+{
+ private final PrivateKey privateKey;
+ private final byte[] encapsulation;
+ private final String keyAlgorithmName;
+ private final int keySizeInBits;
+
+ public KEMExtractSpec(PrivateKey privateKey, byte[] encapsulation, String keyAlgorithmName)
+ {
+ this(privateKey, encapsulation, keyAlgorithmName, 256);
+ }
+
+ public KEMExtractSpec(PrivateKey privateKey, byte[] encapsulation, String keyAlgorithmName, int keySizeInBits)
+ {
+ this.privateKey = privateKey;
+ this.encapsulation = Arrays.clone(encapsulation);
+ this.keyAlgorithmName = keyAlgorithmName;
+ this.keySizeInBits = keySizeInBits;
+ }
+
+ public byte[] getEncapsulation()
+ {
+ return Arrays.clone(encapsulation);
+ }
+
+ public PrivateKey getPrivateKey()
+ {
+ return privateKey;
+ }
+
+ public String getKeyAlgorithmName()
+ {
+ return keyAlgorithmName;
+ }
+
+ public int getKeySize()
+ {
+ return keySizeInBits;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java
new file mode 100644
index 0000000..a5ea3f0
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java
@@ -0,0 +1,39 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.security.PublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+
+public class KEMGenerateSpec
+ implements AlgorithmParameterSpec
+{
+ private final PublicKey publicKey;
+ private final String keyAlgorithmName;
+ private final int keySizeInBits;
+
+ public KEMGenerateSpec(PublicKey publicKey, String keyAlgorithmName)
+ {
+ this(publicKey, keyAlgorithmName, 256);
+ }
+
+ public KEMGenerateSpec(PublicKey publicKey, String keyAlgorithmName, int keySizeInBits)
+ {
+ this.publicKey = publicKey;
+ this.keyAlgorithmName = keyAlgorithmName;
+ this.keySizeInBits = keySizeInBits;
+ }
+
+ public PublicKey getPublicKey()
+ {
+ return publicKey;
+ }
+
+ public String getKeyAlgorithmName()
+ {
+ return keyAlgorithmName;
+ }
+
+ public int getKeySize()
+ {
+ return keySizeInBits;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/RawEncodedKeySpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/RawEncodedKeySpec.java
new file mode 100644
index 0000000..27e75e1
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/RawEncodedKeySpec.java
@@ -0,0 +1,25 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.security.spec.EncodedKeySpec;
+
+/**
+ * An encoded key spec that just wraps the minimal data for a public/private key representation.
+ */
+public class RawEncodedKeySpec
+ extends EncodedKeySpec
+{
+ /**
+ * Base constructor - just the minimal data.
+ *
+ * @param bytes the public/private key data.
+ */
+ public RawEncodedKeySpec(byte[] bytes)
+ {
+ super(bytes);
+ }
+
+ public String getFormat()
+ {
+ return "RAW";
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
index d813531..c63ea02 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
@@ -8,14 +8,47 @@
implements AlgorithmParameterSpec
{
private final byte[] userKeyingMaterial;
+ private final byte[] salt;
+ /**
+ * Base constructor.
+ *
+ * @param userKeyingMaterial the bytes to be mixed in to the key agreement's KDF.
+ */
public UserKeyingMaterialSpec(byte[] userKeyingMaterial)
{
- this.userKeyingMaterial = Arrays.clone(userKeyingMaterial);
+ this(userKeyingMaterial, null);
}
+ /**
+ * Base constructor.
+ *
+ * @param userKeyingMaterial the bytes to be mixed in to the key agreement's KDF.
+ * @param salt the salt to use with the underlying KDF.
+ */
+ public UserKeyingMaterialSpec(byte[] userKeyingMaterial, byte[] salt)
+ {
+ this.userKeyingMaterial = Arrays.clone(userKeyingMaterial);
+ this.salt = Arrays.clone(salt);
+ }
+
+ /**
+ * Return a copy of the key material in this object.
+ *
+ * @return the user keying material.
+ */
public byte[] getUserKeyingMaterial()
{
return Arrays.clone(userKeyingMaterial);
}
+
+ /**
+ * Return a copy of the salt in this object.
+ *
+ * @return the KDF salt.
+ */
+ public byte[] getSalt()
+ {
+ return Arrays.clone(salt);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/ECKeyUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/ECKeyUtil.java
index a37e4e1..3dd71c3 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/ECKeyUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/ECKeyUtil.java
@@ -11,6 +11,7 @@
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.asn1.x9.X9ECParametersHolder;
import org.bouncycastle.asn1.x9.X9ECPoint;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
@@ -68,10 +69,10 @@
{
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
- X9ECParameters x9 = CustomNamedCurves.getByOID(oid);
+ X9ECParametersHolder x9 = CustomNamedCurves.getByOIDLazy(oid);
if (x9 == null)
{
- x9 = ECNamedCurveTable.getByOID(oid);
+ x9 = ECNamedCurveTable.getByOIDLazy(oid);
}
curve = x9.getCurve();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java
index e20d1f1..5d091cf 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java
@@ -14,11 +14,17 @@
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+// import org.bouncycastle.asn1.DERNull;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+// import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
public class MessageDigestUtils
{
private static Map<ASN1ObjectIdentifier, String> digestOidMap = new HashMap<ASN1ObjectIdentifier, String>();
+ // Android-removed: Unsupported algorithms
+ // private static Map<String, AlgorithmIdentifier> digestAlgIdMap = new HashMap<String, AlgorithmIdentifier>();
+
static
{
// BEGIN Android-removed: Unsupported algorithms
@@ -33,6 +39,8 @@
digestOidMap.put(NISTObjectIdentifiers.id_sha512, "SHA-512");
// BEGIN Android-removed: Unsupported algorithms
/*
+ digestOidMap.put(NISTObjectIdentifiers.id_sha512_224, "SHA-512(224)");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha512_256, "SHA-512(256)");
digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD-128");
digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD-160");
digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD-128");
@@ -45,11 +53,51 @@
digestOidMap.put(NISTObjectIdentifiers.id_sha3_256, "SHA3-256");
digestOidMap.put(NISTObjectIdentifiers.id_sha3_384, "SHA3-384");
digestOidMap.put(NISTObjectIdentifiers.id_sha3_512, "SHA3-512");
+ digestOidMap.put(NISTObjectIdentifiers.id_shake128, "SHAKE128");
+ digestOidMap.put(NISTObjectIdentifiers.id_shake256, "SHAKE256");
digestOidMap.put(GMObjectIdentifiers.sm3, "SM3");
+ digestOidMap.put(MiscObjectIdentifiers.blake3_256, "BLAKE3-256");
+
+ digestAlgIdMap.put("SHA-1", new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE));
+ digestAlgIdMap.put("SHA-224", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224));
+ digestAlgIdMap.put("SHA224", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224));
+ digestAlgIdMap.put("SHA-256", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256));
+ digestAlgIdMap.put("SHA256", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256));
+ digestAlgIdMap.put("SHA-384", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384));
+ digestAlgIdMap.put("SHA384", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384));
+ digestAlgIdMap.put("SHA-512", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512));
+ digestAlgIdMap.put("SHA512", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512));
+ digestAlgIdMap.put("SHA3-224", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_224));
+ digestAlgIdMap.put("SHA3-256", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256));
+ digestAlgIdMap.put("SHA3-384", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_384));
+ digestAlgIdMap.put("SHA3-512", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_512));
+ digestAlgIdMap.put("BLAKE3-256", new AlgorithmIdentifier(MiscObjectIdentifiers.blake3_256));
*/
// END Android-removed: Unsupported algorithms
}
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ * Attempt to find a standard JCA name for the digest represented by the passed in OID.
+ *
+ * @param digestName name of the digest algorithm of interest.
+ * @return an algorithm identifier representing the digest.
+ public static AlgorithmIdentifier getDigestAlgID(String digestName)
+ {
+ if (digestAlgIdMap.containsKey(digestName))
+ {
+ return (AlgorithmIdentifier)digestAlgIdMap.get(digestName);
+ }
+ throw new IllegalArgumentException("unknown digest: " + digestName);
+ }
+
+ public static AlgorithmIdentifier getDigestAlgID(String digestName)
+ {
+ throw new IllegalArgumentException("unknown digest: " + digestName);
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
/**
* Attempt to find a standard JCA name for the digest represented by the passed in OID.
*
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java b/bcprov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java
index 5ad207a..1165dc5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java
@@ -21,32 +21,35 @@
public static ECNamedCurveParameterSpec getParameterSpec(
String name)
{
- X9ECParameters ecP = org.bouncycastle.crypto.ec.CustomNamedCurves.getByName(name);
+ ASN1ObjectIdentifier oid;
+ try
+ {
+ oid = possibleOID(name) ? new ASN1ObjectIdentifier(name) : null;
+ }
+ catch (IllegalArgumentException e)
+ {
+ oid = null;
+ }
+
+ X9ECParameters ecP;
+ if (oid != null)
+ {
+ ecP = org.bouncycastle.crypto.ec.CustomNamedCurves.getByOID(oid);
+ }
+ else
+ {
+ ecP = org.bouncycastle.crypto.ec.CustomNamedCurves.getByName(name);
+ }
+
if (ecP == null)
{
- try
+ if (oid != null)
{
- ecP = org.bouncycastle.crypto.ec.CustomNamedCurves.getByOID(new ASN1ObjectIdentifier(name));
+ ecP = org.bouncycastle.asn1.x9.ECNamedCurveTable.getByOID(oid);
}
- catch (IllegalArgumentException e)
- {
- // ignore - not an oid
- }
-
- if (ecP == null)
+ else
{
ecP = org.bouncycastle.asn1.x9.ECNamedCurveTable.getByName(name);
- if (ecP == null)
- {
- try
- {
- ecP = org.bouncycastle.asn1.x9.ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(name));
- }
- catch (IllegalArgumentException e)
- {
- // ignore - not an oid
- }
- }
}
}
@@ -73,4 +76,21 @@
{
return org.bouncycastle.asn1.x9.ECNamedCurveTable.getNames();
}
+
+ private static boolean possibleOID(
+ String identifier)
+ {
+ if (identifier.length() < 3 || identifier.charAt(1) != '.')
+ {
+ return false;
+ }
+
+ char first = identifier.charAt(0);
+ if (first < '0' || first > '2')
+ {
+ return false;
+ }
+
+ return true;
+ }
}
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 0c9de93..b284481 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
@@ -17,6 +17,7 @@
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.ASN1IA5String;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
@@ -103,7 +104,7 @@
+ pkac.size());
}
- challenge = ((DERIA5String)pkac.getObjectAt(1)).getString();
+ challenge = ((ASN1IA5String)pkac.getObjectAt(1)).getString();
//this could be dangerous, as ASN.1 decoding/encoding
//could potentially alter the bytes
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 7f9285b..a651da6 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
@@ -12,12 +12,20 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
// import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.crypto.CryptoServiceConstraintsException;
+import org.bouncycastle.crypto.CryptoServiceProperties;
+import org.bouncycastle.crypto.CryptoServicePurpose;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil;
@@ -34,6 +42,16 @@
// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSKeyFactorySpi;
// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSMTKeyFactorySpi;
// import org.bouncycastle.pqc.jcajce.provider.lms.LMSKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.bike.BIKEKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.cmce.CMCEKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.dilithium.DilithiumKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.falcon.FalconKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.hqc.HQCKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.kyber.KyberKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.ntru.NTRUKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.picnic.PicnicKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.sphincsplus.SPHINCSPlusKeyFactorySpi;
+import org.bouncycastle.util.Strings;
/**
* To add the provider at runtime use:
@@ -62,7 +80,9 @@
public final class BouncyCastleProvider extends Provider
implements ConfigurableProvider
{
- private static String info = "BouncyCastle Security Provider v1.68";
+ private static final Logger LOG = Logger.getLogger(BouncyCastleProvider.class.getName());
+
+ private static String info = "BouncyCastle Security Provider v1.77";
public static final String PROVIDER_NAME = "BC";
@@ -87,17 +107,27 @@
private static final String[] SYMMETRIC_MACS =
{
// Android-removed: Unsupported algorithms
- // "SipHash", "Poly1305"
+ // "SipHash", "SipHash128", "Poly1305"
};
- private static final String[] SYMMETRIC_CIPHERS =
+ private static final CryptoServiceProperties[] SYMMETRIC_CIPHERS =
{
// Android-changed: Unsupported algorithms
- // "AES", "ARC4", "ARIA", "Blowfish", "Camellia", "CAST5", "CAST6", "ChaCha", "DES", "DESede",
- // "GOST28147", "Grainv1", "Grain128", "HC128", "HC256", "IDEA", "Noekeon", "RC2", "RC5",
- // "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Shacal2", "Skipjack", "SM4", "TEA", "Twofish", "Threefish",
- // "VMPC", "VMPCKSA3", "XTEA", "XSalsa20", "OpenSSLPBKDF", "DSTU7624", "GOST3412_2015"
- "AES", "ARC4", "Blowfish", "DES", "DESede", "RC2", "Twofish",
+ // TODO: these numbers need a bit more work, we cap at 256 bits.
+ // service("ARIA", 256), service("Camellia", 256), service("CAST5", 128),
+ // service("CAST6", 256), service("ChaCha", 128), service("GOST28147", 128),
+ // service("Grainv1", 128), service("Grain128", 128), service("HC128", 128),
+ // service("HC256", 256), service("IDEA", 128), service("Noekeon", 128),
+ // service("RC6", 256), service("Rijndael", 256), service("Salsa20", 128),
+ // service("SEED", 128), service("Serpent", 256), service("Shacal2", 128),
+ // service("Skipjack", 80), service("SM4", 128), service("TEA", 128),
+ // service("RC5", 128), service("Threefish", 128), service("VMPC", 128),
+ // service("VMPCKSA3", 128), service("XTEA", 128), service("XSalsa20", 128),
+ // service("OpenSSLPBKDF", 128), service("DSTU7624", 256), service("GOST3412_2015", 256),
+ // service("Zuc", 128)
+ service("AES", 256), service("ARC4", 20), service("Blowfish", 128),
+ service("DES", 56), service("DESede", 112), service("RC2", 128),
+ service("Twofish", 256)
};
/*
@@ -110,14 +140,14 @@
private static final String[] ASYMMETRIC_GENERIC =
{
// Android-changed: Unsupported algorithms
- // "X509", "IES", "COMPOSITE"
+ // "X509", "IES", "COMPOSITE", "EXTERNAL"
"X509"
};
private static final String[] ASYMMETRIC_CIPHERS =
{
// Android-changed: Unsupported algorithms
- // "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC"
+ // "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC", "LMS", "SPHINCSPlus", "Dilithium", "Falcon", "NTRU"
"DSA", "DH", "EC", "RSA",
};
@@ -153,6 +183,8 @@
// "DRBG"
// };
+ private Map<String, Service> serviceMap = new ConcurrentHashMap<String, Service>();
+
/**
* Construct a new provider. This should only be required when
* using runtime registration of the provider using the
@@ -160,7 +192,7 @@
*/
public BouncyCastleProvider()
{
- super(PROVIDER_NAME, 1.68, info);
+ super(PROVIDER_NAME, 1.77, info);
AccessController.doPrivileged(new PrivilegedAction()
{
@@ -226,13 +258,9 @@
put("Cipher.OLDPBEWITHSHAANDTWOFISH-CBC", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$OldPBEWithSHAAndTwofish");
// Certification Path API
- put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi");
- put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
- put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
- put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
-
if (revChkClass != null)
{
+ put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi");
put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi_8");
put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi_8");
@@ -259,33 +287,149 @@
// put("CertStore.Multi", "org.bouncycastle.jce.provider.MultiCertStoreSpi");
// put("Alg.Alias.CertStore.X509LDAP", "LDAP");
// END Android-removed: Unsupported algorithms
+
+ getService("SecureRandom", "DEFAULT"); // prime for new SecureRandom() on 1.8 JVMs.
+ }
+
+ public final Service getService(final String type, final String algorithm)
+ {
+ String upperCaseAlgName = Strings.toUpperCase(algorithm);
+ final String key = type + "." + upperCaseAlgName;
+
+ Service service = serviceMap.get(key);
+
+ if (service == null)
+ {
+ synchronized (this)
+ {
+ if (!serviceMap.containsKey(key))
+ {
+ service = AccessController.doPrivileged(new PrivilegedAction<Service>()
+ {
+ @Override
+ public Service run()
+ {
+ Service service = BouncyCastleProvider.super.getService(type, algorithm);
+ if (service == null)
+ {
+ return null;
+ }
+ serviceMap.put(key, service);
+ // remove legacy entry and swap to service entry
+ BouncyCastleProvider.super.remove(service.getType() + "." + service.getAlgorithm());
+ BouncyCastleProvider.super.putService(service);
+
+ return service;
+ }
+ });
+ }
+ else
+ {
+ service = serviceMap.get(key);
+ }
+ }
+ }
+
+ return service;
}
private void loadAlgorithms(String packageName, String[] names)
{
for (int i = 0; i != names.length; i++)
{
- Class clazz = ClassUtil.loadClass(BouncyCastleProvider.class, packageName + names[i] + "$Mappings");
+ loadServiceClass(packageName, names[i]);
+ }
+ }
- if (clazz != null)
+ private void loadAlgorithms(String packageName, CryptoServiceProperties[] services)
+ {
+ for (int i = 0; i != services.length; i++)
+ {
+ CryptoServiceProperties service = services[i];
+ try
{
- try
+ CryptoServicesRegistrar.checkConstraints(service);
+
+ loadServiceClass(packageName, service.getServiceName());
+ }
+ catch (CryptoServiceConstraintsException e)
+ {
+ if (LOG.isLoggable(Level.FINE))
{
- ((AlgorithmProvider)clazz.newInstance()).configure(this);
- }
- catch (Exception e)
- { // this should never ever happen!!
- throw new InternalError("cannot create instance of "
- + packageName + names[i] + "$Mappings : " + e);
+ LOG.fine("service for " + service.getServiceName() + " ignored due to constraints");
}
}
}
}
+ private void loadServiceClass(String packageName, String serviceName)
+ {
+ Class clazz = ClassUtil.loadClass(BouncyCastleProvider.class, packageName + serviceName + "$Mappings");
+
+ if (clazz != null)
+ {
+ try
+ {
+ ((AlgorithmProvider)clazz.newInstance()).configure(this);
+ }
+ catch (Exception e)
+ { // this should never ever happen!!
+ throw new InternalError("cannot create instance of "
+ + packageName + serviceName + "$Mappings : " + e);
+ }
+ }
+ }
// BEGIN Android-removed: Unsupported algorithms
/*
+
private void loadPQCKeys()
{
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192s, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256s, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(new ASN1ObjectIdentifier("1.3.9999.6.4.10"), new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128f, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192f, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f, new SPHINCSPlusKeyFactorySpi());
+
addKeyInfoConverter(PQCObjectIdentifiers.sphincs256, new Sphincs256KeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.newHope, new NHKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.xmss, new XMSSKeyFactorySpi());
@@ -298,6 +442,37 @@
addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_I, new QTESLAKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_III, new QTESLAKeyFactorySpi());
addKeyInfoConverter(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, new LMSKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.picnic_key, new PicnicKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.falcon_512, new FalconKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.falcon_1024, new FalconKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium2, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium3, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium5, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium2_aes, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium3_aes, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium5_aes, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber512, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber768, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber1024, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece348864_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece460896_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece6688128_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece6960119_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece8192128_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.bike128, new BIKEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.bike192, new BIKEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.bike256, new BIKEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.hqc128, new HQCKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.hqc192, new HQCKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.hqc256, new HQCKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber1024, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber512_aes, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber768_aes, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber1024_aes, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhps2048509, new NTRUKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhps2048677, new NTRUKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhps4096821, new NTRUKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhrss701, new NTRUKeyFactorySpi());
}
*/
// END Android-removed: Unsupported algorithms
@@ -325,12 +500,25 @@
put(key, value);
}
+ public void addAlgorithm(String key, String value, Map<String, String> attributes)
+ {
+ addAlgorithm(key, value);
+ addAttributes(key, attributes);
+ }
+
public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className)
{
addAlgorithm(type + "." + oid, className);
addAlgorithm(type + ".OID." + oid, className);
}
+ public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className, Map<String, String> attributes)
+ {
+ addAlgorithm(type, oid, className);
+ addAttributes(type + "." + oid, attributes);
+ addAttributes(type + ".OID." + oid, attributes);
+ }
+
public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter)
{
synchronized (keyInfoConverters)
@@ -346,6 +534,8 @@
public void addAttributes(String key, Map<String, String> attributeMap)
{
+ put(key + " ImplementedIn", "Software");
+
for (Iterator it = attributeMap.keySet().iterator(); it.hasNext();)
{
String attributeName = (String)it.next();
@@ -386,6 +576,11 @@
}
// Android-removed: see above
/*
+ if (publicKeyInfo.getAlgorithm().getAlgorithm().on(BCObjectIdentifiers.picnic_key))
+ {
+ return new PicnicKeyFactorySpi().generatePublic(publicKeyInfo);
+ }
+
AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(publicKeyInfo.getAlgorithm().getAlgorithm());
if (converter == null)
@@ -459,4 +654,42 @@
return privateProvider;
}
// END Android-added: Allow algorithms to be provided privately for BC internals.
+ private static CryptoServiceProperties service(String name, int bitsOfSecurity)
+ {
+ return new JcaCryptoService(name, bitsOfSecurity);
+ }
+
+ private static class JcaCryptoService
+ implements CryptoServiceProperties
+ {
+
+ private final String name;
+ private final int bitsOfSecurity;
+
+ JcaCryptoService(String name, int bitsOfSecurity)
+ {
+ this.name = name;
+ this.bitsOfSecurity = bitsOfSecurity;
+ }
+
+ public int bitsOfSecurity()
+ {
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return name;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return CryptoServicePurpose.ANY;
+ }
+
+ public Object getParams()
+ {
+ 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 6f74c72..8fe3807 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
@@ -44,7 +44,6 @@
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Enumerated;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
-import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
@@ -54,7 +53,6 @@
import org.bouncycastle.asn1.ASN1String;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
-import org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.RFC4519Style;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
@@ -68,6 +66,7 @@
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.PolicyInformation;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.internal.asn1.isismtt.ISISMTTObjectIdentifiers;
import org.bouncycastle.jcajce.PKIXCRLStore;
import org.bouncycastle.jcajce.PKIXCRLStoreSelector;
import org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
@@ -83,7 +82,6 @@
import org.bouncycastle.util.Store;
import org.bouncycastle.util.StoreException;
import org.bouncycastle.x509.X509AttributeCertificate;
-import org.bouncycastle.x509.extension.X509ExtensionUtil;
class CertPathValidatorUtilities
{
@@ -776,7 +774,7 @@
for (int j = 0; j < genNames.length; j++)
{
- GeneralName name = genNames[i];
+ GeneralName name = genNames[j];
if (name.getTagNo() == GeneralName.uniformResourceIdentifier)
{
try
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 d4fa285..32e3043 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEDHPrivateKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEDHPrivateKey.java
@@ -19,7 +19,7 @@
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x9.DHDomainParameters;
+import org.bouncycastle.asn1.x9.DomainParameters;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
@@ -81,9 +81,9 @@
}
else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
{
- DHDomainParameters params = DHDomainParameters.getInstance(seq);
+ DomainParameters params = DomainParameters.getInstance(seq);
- this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue());
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
}
else
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEDHPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEDHPublicKey.java
index 3e6a09a..2fdc5fb 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEDHPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEDHPublicKey.java
@@ -16,7 +16,7 @@
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.asn1.x9.DHDomainParameters;
+import org.bouncycastle.asn1.x9.DomainParameters;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.params.DHPublicKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
@@ -76,8 +76,8 @@
this.y = derY.getValue();
- ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithmId().getParameters());
- ASN1ObjectIdentifier id = info.getAlgorithmId().getAlgorithm();
+ ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithm().getParameters());
+ ASN1ObjectIdentifier id = info.getAlgorithm().getAlgorithm();
// we need the PKCS check to handle older keys marked with the X9 oid.
if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement) || isPKCSParam(seq))
@@ -95,9 +95,9 @@
}
else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
{
- DHDomainParameters params = DHDomainParameters.getInstance(seq);
+ DomainParameters params = DomainParameters.getInstance(seq);
- this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue());
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
}
else
{
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 26616b4..d4c8b9f 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java
@@ -6,24 +6,21 @@
import java.math.BigInteger;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.EllipticCurve;
import java.util.Enumeration;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.ASN1Sequence;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERNull;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
-import org.bouncycastle.asn1.sec.ECPrivateKeyStructure;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X962Parameters;
@@ -49,7 +46,7 @@
private ECParameterSpec ecSpec;
private boolean withCompression;
- private DERBitString publicKey;
+ private ASN1BitString publicKey;
private PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
@@ -214,6 +211,7 @@
else
*/
// END Android-removed: Unsupported algorithms
+ if (ecP != null)
{
EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed());
@@ -250,7 +248,7 @@
}
else
{
- ECPrivateKeyStructure ec = new ECPrivateKeyStructure((ASN1Sequence)privKey);
+ org.bouncycastle.asn1.sec.ECPrivateKey ec = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(privKey);
this.d = ec.getKey();
this.publicKey = ec.getPublicKey();
@@ -310,15 +308,25 @@
}
PrivateKeyInfo info;
- ECPrivateKeyStructure keyStructure;
+ org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
- if (publicKey != null)
+ int orderBitLength;
+ if (ecSpec == null)
{
- keyStructure = new ECPrivateKeyStructure(this.getS(), publicKey, params);
+ orderBitLength = ECUtil.getOrderBitLength(null, null, this.getS());
}
else
{
- keyStructure = new ECPrivateKeyStructure(this.getS(), params);
+ orderBitLength = ECUtil.getOrderBitLength(null, ecSpec.getOrder(), this.getS());
+ }
+
+ if (publicKey != null)
+ {
+ keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params);
+ }
+ else
+ {
+ keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
}
try
@@ -430,7 +438,7 @@
}
- private DERBitString getPublicKeyDetails(JCEECPublicKey pub)
+ private ASN1BitString getPublicKeyDetails(JCEECPublicKey pub)
{
try
{
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 67a8cd7..bad0015 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java
@@ -10,11 +10,11 @@
import java.security.spec.ECPublicKeySpec;
import java.security.spec.EllipticCurve;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DEROctetString;
// Android-removed: Unsupported algorithms
@@ -188,7 +188,7 @@
if (algID.getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001))
{
- DERBitString bits = info.getPublicKeyData();
+ ASN1BitString bits = info.getPublicKeyData();
ASN1OctetString key;
this.algorithm = "ECGOST3410";
@@ -269,7 +269,7 @@
ecP.getH().intValue());
}
- DERBitString bits = info.getPublicKeyData();
+ ASN1BitString bits = info.getPublicKeyData();
byte[] data = bits.getBytes();
ASN1OctetString key = new DEROctetString(data);
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java
index c192532..1599ceb 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java
@@ -40,8 +40,9 @@
for (Iterator it = initialSet.iterator(); it.hasNext();)
{
X509CRL crl = (X509CRL)it.next();
-
- if (crl.getNextUpdate().after(validityDate))
+
+ Date nextUpdate = crl.getNextUpdate();
+ if (nextUpdate == null || nextUpdate.after(validityDate))
{
X509Certificate cert = crlselect.getCertificateChecking();
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 f3c8d16..52f5ff8 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
@@ -1,7 +1,6 @@
package org.bouncycastle.jce.provider;
import java.io.IOException;
-import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.security.cert.CertPath;
@@ -2098,18 +2097,12 @@
throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
index);
}
- if (bc != null)
+ if (bc != null && bc.isCA()) // if there is a path len constraint and we're not a CA, ignore it! (yes, it happens).
{
- BigInteger _pathLengthConstraint = bc.getPathLenConstraint();
-
- if (_pathLengthConstraint != null)
+ ASN1Integer pathLenConstraint = bc.getPathLenConstraintInteger();
+ if (pathLenConstraint != null)
{
- int _plc = _pathLengthConstraint.intValue();
-
- if (_plc < maxPathLength)
- {
- return _plc;
- }
+ maxPathLength = Math.min(maxPathLength, pathLenConstraint.intPositiveValueExact());
}
}
return maxPathLength;
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 d5e2338..bbfacab 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java
@@ -23,7 +23,6 @@
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.TBSCertList;
-import org.bouncycastle.asn1.x509.X509Extension;
import org.bouncycastle.util.Strings;
/**
@@ -286,11 +285,11 @@
buf.append(" critical(").append(ext.isCritical()).append(") ");
try
{
- if (oid.equals(X509Extension.reasonCode))
+ if (oid.equals(Extension.reasonCode))
{
buf.append(CRLReason.getInstance(ASN1Enumerated.getInstance(dIn.readObject()))).append(nl);
}
- else if (oid.equals(X509Extension.certificateIssuer))
+ else if (oid.equals(Extension.certificateIssuer))
{
buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java
index 4bbd512..7fd1a79 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java
@@ -34,13 +34,13 @@
import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.ASN1IA5String;
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.ASN1String;
-import org.bouncycastle.asn1.DERBitString;
-import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
@@ -107,7 +107,7 @@
byte[] bytes = this.getExtensionBytes("2.5.29.15");
if (bytes != null)
{
- ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes));
+ ASN1BitString bits = ASN1BitString.getInstance(ASN1Primitive.fromByteArray(bytes));
bytes = bits.getBytes();
int length = (bytes.length * 8) - bits.getPadBits();
@@ -290,7 +290,7 @@
public boolean[] getIssuerUniqueID()
{
- DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getIssuerUniqueId();
if (id != null)
{
@@ -310,7 +310,7 @@
public boolean[] getSubjectUniqueID()
{
- DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getSubjectUniqueId();
if (id != null)
{
@@ -364,26 +364,18 @@
public int getBasicConstraints()
{
- if (basicConstraints != null)
+ if (basicConstraints == null || !basicConstraints.isCA())
{
- if (basicConstraints.isCA())
- {
- if (basicConstraints.getPathLenConstraint() == null)
- {
- return Integer.MAX_VALUE;
- }
- else
- {
- return basicConstraints.getPathLenConstraint().intValue();
- }
- }
- else
- {
- return -1;
- }
+ return -1;
}
- return -1;
+ ASN1Integer pathLenConstraint = basicConstraints.getPathLenConstraintInteger();
+ if (pathLenConstraint == null)
+ {
+ return Integer.MAX_VALUE;
+ }
+
+ return pathLenConstraint.intPositiveValueExact();
}
public Collection getSubjectAlternativeNames()
@@ -709,15 +701,15 @@
}
else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
{
- buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl);
+ buf.append(new NetscapeCertType((ASN1BitString)dIn.readObject())).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
{
- buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl);
+ buf.append(new NetscapeRevocationURL((ASN1IA5String)dIn.readObject())).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
{
- buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl);
+ buf.append(new VerisignCzagExtension((ASN1IA5String)dIn.readObject())).append(nl);
}
else
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java b/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
index 0be2ca9..6bc0298 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
@@ -43,7 +43,7 @@
{
Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
int[] exponents = poly.getExponentsPresent();
- int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
+ int[] ks = Arrays.reverseInPlace(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
return new ECFieldF2m(poly.getDegree(), ks);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
index 8f00c6b..04bde03 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
@@ -2,9 +2,14 @@
import java.math.BigInteger;
import java.security.SecureRandom;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.Random;
+import java.util.Set;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
+import org.bouncycastle.math.Primes;
import org.bouncycastle.math.ec.endo.ECEndomorphism;
import org.bouncycastle.math.ec.endo.GLVEndomorphism;
import org.bouncycastle.math.field.FiniteField;
@@ -12,6 +17,7 @@
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.Integers;
+import org.bouncycastle.util.Properties;
/**
* base class for an elliptic curve
@@ -668,6 +674,8 @@
public static class Fp extends AbstractFp
{
private static final int FP_DEFAULT_COORDS = ECCurve.COORD_JACOBIAN_MODIFIED;
+ private static final Set<BigInteger> knownQs = Collections.synchronizedSet(new HashSet<BigInteger>());
+ private static final BigIntegers.Cache validatedQs = new BigIntegers.Cache();
BigInteger q, r;
ECPoint.Fp infinity;
@@ -682,9 +690,44 @@
public Fp(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor)
{
+ this(q, a, b, order, cofactor, false);
+ }
+
+ public Fp(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor, boolean isInternal)
+ {
super(q);
- this.q = q;
+ if (isInternal)
+ {
+ this.q = q;
+ knownQs.add(q);
+ }
+ else if (knownQs.contains(q) || validatedQs.contains(q))
+ {
+ this.q = q;
+ }
+ else
+ {
+ int maxBitLength = Properties.asInteger("org.bouncycastle.ec.fp_max_size", 1042); // 2 * 521
+ int certainty = Properties.asInteger("org.bouncycastle.ec.fp_certainty", 100);
+
+ int qBitLength = q.bitLength();
+ if (maxBitLength < qBitLength)
+ {
+ throw new IllegalArgumentException("Fp q value out of range");
+ }
+
+ if (Primes.hasAnySmallFactors(q) || !Primes.isMRProbablePrime(
+ q, CryptoServicesRegistrar.getSecureRandom(), getNumberOfIterations(qBitLength, certainty)))
+ {
+ throw new IllegalArgumentException("Fp q value not prime");
+ }
+
+ validatedQs.add(q);
+
+ this.q = q;
+ }
+
this.r = ECFieldElement.Fp.calculateResidue(q);
this.infinity = new ECPoint.Fp(this, null, null);
@@ -741,6 +784,11 @@
public ECFieldElement fromBigInteger(BigInteger x)
{
+ if (x == null || x.signum() < 0 || x.compareTo(q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for Fp field element");
+ }
+
return new ECFieldElement.Fp(this.q, this.r, x);
}
@@ -797,32 +845,11 @@
private static FiniteField buildField(int m, int k1, int k2, int k3)
{
- if (k1 == 0)
- {
- throw new IllegalArgumentException("k1 must be > 0");
- }
+ int[] exponents = (k2 | k3) == 0
+ ? new int[]{ 0, k1, m }
+ : new int[]{ 0, k1, k2, k3, m };
- if (k2 == 0)
- {
- if (k3 != 0)
- {
- throw new IllegalArgumentException("k3 must be 0 if k2 == 0");
- }
-
- return FiniteFields.getBinaryExtensionField(new int[]{ 0, k1, m });
- }
-
- if (k2 <= k1)
- {
- throw new IllegalArgumentException("k2 must be > k1");
- }
-
- if (k3 <= k2)
- {
- throw new IllegalArgumentException("k3 must be > k2");
- }
-
- return FiniteFields.getBinaryExtensionField(new int[]{ 0, k1, k2, k3, m });
+ return FiniteFields.getBinaryExtensionField(exponents);
}
protected AbstractF2m(int m, int k1, int k2, int k3)
@@ -915,7 +942,7 @@
y = this.getB().sqrt();
}
else
- {
+ {
ECFieldElement beta = x.square().invert().multiply(this.getB()).add(this.getA()).add(x);
ECFieldElement z = solveQuadraticEquation(beta);
if (z != null)
@@ -1275,7 +1302,16 @@
public ECFieldElement fromBigInteger(BigInteger x)
{
- return new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, x);
+ if (x == null || x.signum() < 0 || x.bitLength() > m)
+ {
+ throw new IllegalArgumentException("x value invalid in F2m field element");
+ }
+
+ int[] ks = (k2 | k3) == 0
+ ? new int[]{ k1 }
+ : new int[]{ k1, k2, k3 };
+
+ return new ECFieldElement.F2m(m, ks, new LongArray(x));
}
protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
@@ -1390,4 +1426,36 @@
};
}
}
+
+ private static int getNumberOfIterations(int bits, int certainty)
+ {
+ /*
+ * NOTE: We enforce a minimum 'certainty' of 100 for bits >= 1024 (else 80). Where the
+ * certainty is higher than the FIPS 186-4 tables (C.2/C.3) cater to, extra iterations
+ * are added at the "worst case rate" for the excess.
+ */
+ if (bits >= 1536)
+ {
+ return certainty <= 100 ? 3
+ : certainty <= 128 ? 4
+ : 4 + (certainty - 128 + 1) / 2;
+ }
+ else if (bits >= 1024)
+ {
+ return certainty <= 100 ? 4
+ : certainty <= 112 ? 5
+ : 5 + (certainty - 112 + 1) / 2;
+ }
+ else if (bits >= 512)
+ {
+ return certainty <= 80 ? 5
+ : certainty <= 100 ? 7
+ : 7 + (certainty - 100 + 1) / 2;
+ }
+ else
+ {
+ return certainty <= 80 ? 40
+ : 40 + (certainty - 80 + 1) / 2;
+ }
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java
index 43c83e0..ef22212 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java
@@ -110,21 +110,8 @@
return null;
}
- /**
- * @deprecated Use ECCurve.fromBigInteger to construct field elements
- */
- public Fp(BigInteger q, BigInteger x)
- {
- this(q, calculateResidue(q), x);
- }
-
Fp(BigInteger q, BigInteger r, BigInteger x)
{
- if (x == null || x.signum() < 0 || x.compareTo(q) >= 0)
- {
- throw new IllegalArgumentException("x value invalid in Fp field element");
- }
-
this.q = q;
this.r = r;
this.x = x;
@@ -612,59 +599,6 @@
*/
LongArray x;
- /**
- * Constructor for PPB.
- * @param m The exponent <code>m</code> of
- * <code>F<sub>2<sup>m</sup></sub></code>.
- * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> +
- * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
- * represents the reduction polynomial <code>f(z)</code>.
- * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> +
- * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
- * represents the reduction polynomial <code>f(z)</code>.
- * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> +
- * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
- * represents the reduction polynomial <code>f(z)</code>.
- * @param x The BigInteger representing the value of the field element.
- * @deprecated Use ECCurve.fromBigInteger to construct field elements
- */
- public F2m(
- int m,
- int k1,
- int k2,
- int k3,
- BigInteger x)
- {
- if (x == null || x.signum() < 0 || x.bitLength() > m)
- {
- throw new IllegalArgumentException("x value invalid in F2m field element");
- }
-
- if ((k2 == 0) && (k3 == 0))
- {
- this.representation = TPB;
- this.ks = new int[]{ k1 };
- }
- else
- {
- if (k2 >= k3)
- {
- throw new IllegalArgumentException(
- "k2 must be smaller than k3");
- }
- if (k2 <= 0)
- {
- throw new IllegalArgumentException(
- "k2 must be larger than 0");
- }
- this.representation = PPB;
- this.ks = new int[]{ k1, k2, k3 };
- }
-
- this.m = m;
- this.x = new LongArray(x);
- }
-
F2m(int m, int[] ks, LongArray x)
{
this.m = m;
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/Tnaf.java b/bcprov/src/main/java/org/bouncycastle/math/ec/Tnaf.java
index aef0cf7..e2f65cc 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/Tnaf.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/Tnaf.java
@@ -2,6 +2,8 @@
import java.math.BigInteger;
+import org.bouncycastle.util.BigIntegers;
+
/**
* Class holding methods for point multiplication based on the window
* τ-adic nonadjacent form (WTNAF). The algorithms are based on the
@@ -28,20 +30,19 @@
public static final byte WIDTH = 4;
/**
- * 2<sup>4</sup>
- */
- public static final byte POW_2_WIDTH = 16;
-
- /**
* The <code>α<sub>u</sub></code>'s for <code>a=0</code> as an array
* of <code>ZTauElement</code>s.
*/
- public static final ZTauElement[] alpha0 = {
- null,
- new ZTauElement(ECConstants.ONE, ECConstants.ZERO), null,
- new ZTauElement(MINUS_THREE, MINUS_ONE), null,
- new ZTauElement(MINUS_ONE, MINUS_ONE), null,
- new ZTauElement(ECConstants.ONE, MINUS_ONE), null
+ public static final ZTauElement[] alpha0 =
+ {
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ZERO),
+ null, new ZTauElement(MINUS_THREE, MINUS_ONE),
+ null, new ZTauElement(MINUS_ONE, MINUS_ONE),
+ null, new ZTauElement(ECConstants.ONE, MINUS_ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ONE),
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ONE),
+ null, new ZTauElement(ECConstants.THREE, ECConstants.ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ZERO),
};
/**
@@ -56,11 +57,16 @@
* The <code>α<sub>u</sub></code>'s for <code>a=1</code> as an array
* of <code>ZTauElement</code>s.
*/
- public static final ZTauElement[] alpha1 = {null,
- new ZTauElement(ECConstants.ONE, ECConstants.ZERO), null,
- new ZTauElement(MINUS_THREE, ECConstants.ONE), null,
- new ZTauElement(MINUS_ONE, ECConstants.ONE), null,
- new ZTauElement(ECConstants.ONE, ECConstants.ONE), null
+ public static final ZTauElement[] alpha1 =
+ {
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ZERO),
+ null, new ZTauElement(MINUS_THREE, ECConstants.ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ONE),
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ONE),
+ null, new ZTauElement(MINUS_ONE, MINUS_ONE),
+ null, new ZTauElement(ECConstants.ONE, MINUS_ONE),
+ null, new ZTauElement(ECConstants.THREE, MINUS_ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ZERO),
};
/**
@@ -81,31 +87,29 @@
*/
public static BigInteger norm(final byte mu, ZTauElement lambda)
{
- BigInteger norm;
-
// s1 = u^2
BigInteger s1 = lambda.u.multiply(lambda.u);
// s2 = u * v
- BigInteger s2 = lambda.u.multiply(lambda.v);
+// BigInteger s2 = lambda.u.multiply(lambda.v);
// s3 = 2 * v^2
- BigInteger s3 = lambda.v.multiply(lambda.v).shiftLeft(1);
+// BigInteger s3 = lambda.v.multiply(lambda.v).shiftLeft(1);
if (mu == 1)
{
- norm = s1.add(s2).add(s3);
+// return s1.add(s2).add(s3);
+ return lambda.v.shiftLeft(1).add(lambda.u).multiply(lambda.v).add(s1);
}
else if (mu == -1)
{
- norm = s1.subtract(s2).add(s3);
+// return s1.subtract(s2).add(s3);
+ return lambda.v.shiftLeft(1).subtract(lambda.u).multiply(lambda.v).add(s1);
}
else
{
throw new IllegalArgumentException("mu must be 1 or -1");
}
-
- return norm;
}
/**
@@ -451,10 +455,7 @@
throw new IllegalArgumentException("mu must be 1 or -1");
}
- BigInteger u0;
- BigInteger u1;
- BigInteger u2;
-
+ BigInteger u0, u1, u2;
if (doV)
{
u0 = ECConstants.TWO;
@@ -469,26 +470,18 @@
for (int i = 1; i < k; i++)
{
// u2 = mu*u1 - 2*u0;
- BigInteger s = null;
- if (mu == 1)
+ BigInteger s = u1;
+ if (mu < 0)
{
- s = u1;
+ s = s.negate();
}
- else
- {
- // mu == -1
- s = u1.negate();
- }
-
+
u2 = s.subtract(u0.shiftLeft(1));
u0 = u1;
u1 = u2;
-// System.out.println(i + ": " + u2);
-// System.out.println();
}
- BigInteger[] retVal = {u0, u1};
- return retVal;
+ return new BigInteger[]{ u0, u1 };
}
/**
@@ -519,11 +512,7 @@
BigInteger[] us = getLucas(mu, w, false);
BigInteger twoToW = ECConstants.ZERO.setBit(w);
BigInteger u1invert = us[1].modInverse(twoToW);
- BigInteger tw;
- tw = ECConstants.TWO.multiply(us[0]).multiply(u1invert).mod(twoToW);
-// System.out.println("mu = " + mu);
-// System.out.println("tw = " + tw);
- return tw;
+ return us[0].shiftLeft(1).multiply(u1invert).mod(twoToW);
}
}
@@ -542,22 +531,7 @@
throw new IllegalArgumentException("si is defined for Koblitz curves only");
}
- int m = curve.getFieldSize();
- int a = curve.getA().toBigInteger().intValue();
- byte mu = getMu(a);
- int shifts = getShiftsForCofactor(curve.getCofactor());
- int index = m + 3 - a;
- BigInteger[] ui = getLucas(mu, index, false);
- if (mu == 1)
- {
- ui[0] = ui[0].negate();
- ui[1] = ui[1].negate();
- }
-
- BigInteger dividend0 = ECConstants.ONE.add(ui[1]).shiftRight(shifts);
- BigInteger dividend1 = ECConstants.ONE.add(ui[0]).shiftRight(shifts).negate();
-
- return new BigInteger[] { dividend0, dividend1 };
+ return getSi(curve.getFieldSize(), curve.getA().toBigInteger().intValue(), curve.getCofactor());
}
public static BigInteger[] getSi(int fieldSize, int curveA, BigInteger cofactor)
@@ -608,9 +582,11 @@
* modular reduction.
* @return <code>ρ := k partmod (τ<sup>m</sup> - 1)/(τ - 1)</code>
*/
- public static ZTauElement partModReduction(BigInteger k, int m, byte a,
- BigInteger[] s, byte mu, byte c)
+ public static ZTauElement partModReduction(ECCurve.AbstractF2m curve, BigInteger k, byte a, byte mu, byte c)
{
+ int m = curve.getFieldSize();
+ BigInteger[] s = curve.getSi();
+
// d0 = s[0] + mu*s[1]; mu is either 1 or -1
BigInteger d0;
if (mu == 1)
@@ -622,20 +598,29 @@
d0 = s[0].subtract(s[1]);
}
- BigInteger[] v = getLucas(mu, m, true);
- BigInteger vm = v[1];
+ BigInteger vm;
+ if (curve.isKoblitz())
+ {
+ /*
+ * Jerome A. Solinas, "Improved Algorithms for Arithmetic on Anomalous Binary Curves", (21).
+ */
+ vm = ECConstants.ONE.shiftLeft(m).add(ECConstants.ONE).subtract(
+ curve.getOrder().multiply(curve.getCofactor()));
+ }
+ else
+ {
+ BigInteger[] v = getLucas(mu, m, true);
+ vm = v[1];
+ }
- SimpleBigDecimal lambda0 = approximateDivisionByN(
- k, s[0], vm, a, m, c);
-
- SimpleBigDecimal lambda1 = approximateDivisionByN(
- k, s[1], vm, a, m, c);
+ SimpleBigDecimal lambda0 = approximateDivisionByN(k, s[0], vm, a, m, c);
+ SimpleBigDecimal lambda1 = approximateDivisionByN(k, s[1], vm, a, m, c);
ZTauElement q = round(lambda0, lambda1, mu);
// r0 = n - d0*q0 - 2*s1*q1
BigInteger r0 = k.subtract(d0.multiply(q.u)).subtract(
- BigInteger.valueOf(2).multiply(s[1]).multiply(q.v));
+ s[1].multiply(q.v).shiftLeft(1));
// r1 = s1*q0 - s0*q1
BigInteger r1 = s[1].multiply(q.u).subtract(s[0].multiply(q.v));
@@ -654,11 +639,10 @@
public static ECPoint.AbstractF2m multiplyRTnaf(ECPoint.AbstractF2m p, BigInteger k)
{
ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m) p.getCurve();
- int m = curve.getFieldSize();
int a = curve.getA().toBigInteger().intValue();
byte mu = getMu(a);
- BigInteger[] s = curve.getSi();
- ZTauElement rho = partModReduction(k, m, (byte)a, s, mu, (byte)10);
+
+ ZTauElement rho = partModReduction(curve, k, (byte)a, mu, (byte)10);
return multiplyTnaf(p, rho);
}
@@ -675,12 +659,11 @@
public static ECPoint.AbstractF2m multiplyTnaf(ECPoint.AbstractF2m p, ZTauElement lambda)
{
ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
+ ECPoint.AbstractF2m pNeg = (ECPoint.AbstractF2m)p.negate();
byte mu = getMu(curve.getA());
byte[] u = tauAdicNaf(mu, lambda);
- ECPoint.AbstractF2m q = multiplyFromTnaf(p, u);
-
- return q;
+ return multiplyFromTnaf(p, pNeg, u);
}
/**
@@ -692,11 +675,10 @@
* @param u The the TNAF of <code>λ</code>..
* @return <code>λ * p</code>
*/
- public static ECPoint.AbstractF2m multiplyFromTnaf(ECPoint.AbstractF2m p, byte[] u)
+ public static ECPoint.AbstractF2m multiplyFromTnaf(ECPoint.AbstractF2m p, ECPoint.AbstractF2m pNeg, byte[] u)
{
ECCurve curve = p.getCurve();
ECPoint.AbstractF2m q = (ECPoint.AbstractF2m)curve.getInfinity();
- ECPoint.AbstractF2m pNeg = (ECPoint.AbstractF2m)p.negate();
int tauCount = 0;
for (int i = u.length - 1; i >= 0; i--)
{
@@ -732,10 +714,9 @@
* @return The <code>[τ]</code>-adic window NAF of
* <code>λ</code>.
*/
- public static byte[] tauAdicWNaf(byte mu, ZTauElement lambda,
- byte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha)
+ public static byte[] tauAdicWNaf(byte mu, ZTauElement lambda, int width, int tw, ZTauElement[] alpha)
{
- if (!((mu == 1) || (mu == -1)))
+ if (!(mu == 1 || mu == -1))
{
throw new IllegalArgumentException("mu must be 1 or -1");
}
@@ -751,75 +732,72 @@
// The array holding the TNAF
byte[] u = new byte[maxLength];
- // 2^(width - 1)
- BigInteger pow2wMin1 = pow2w.shiftRight(1);
+ int pow2Width = 1 << width;
+ int pow2Mask = pow2Width - 1;
+ int s = 32 - width;
// Split lambda into two BigIntegers to simplify calculations
- BigInteger r0 = lambda.u;
- BigInteger r1 = lambda.v;
- int i = 0;
+ BigInteger R0 = lambda.u;
+ BigInteger R1 = lambda.v;
+ int uPos = 0;
// while lambda <> (0, 0)
- while (!((r0.equals(ECConstants.ZERO))&&(r1.equals(ECConstants.ZERO))))
+ while (R0.bitLength() > 62 || R1.bitLength() > 62)
{
- // if r0 is odd
- if (r0.testBit(0))
+ if (R0.testBit(0))
{
- // uUnMod = r0 + r1*tw mod 2^width
- BigInteger uUnMod
- = r0.add(r1.multiply(tw)).mod(pow2w);
-
- byte uLocal;
- // if uUnMod >= 2^(width - 1)
- if (uUnMod.compareTo(pow2wMin1) >= 0)
- {
- uLocal = (byte) uUnMod.subtract(pow2w).intValue();
- }
- else
- {
- uLocal = (byte) uUnMod.intValue();
- }
- // uLocal is now in [-2^(width-1), 2^(width-1)-1]
+ int uVal = R0.intValue() + (R1.intValue() * tw);
+ int alphaPos = uVal & pow2Mask;
- u[i] = uLocal;
- boolean s = true;
- if (uLocal < 0)
- {
- s = false;
- uLocal = (byte)-uLocal;
- }
- // uLocal is now >= 0
-
- if (s)
- {
- r0 = r0.subtract(alpha[uLocal].u);
- r1 = r1.subtract(alpha[uLocal].v);
- }
- else
- {
- r0 = r0.add(alpha[uLocal].u);
- r1 = r1.add(alpha[uLocal].v);
- }
- }
- else
- {
- u[i] = 0;
+ u[uPos] = (byte)((uVal << s) >> s);
+ R0 = R0.subtract(alpha[alphaPos].u);
+ R1 = R1.subtract(alpha[alphaPos].v);
}
- BigInteger t = r0;
+ ++uPos;
+ BigInteger t = R0.shiftRight(1);
if (mu == 1)
{
- r0 = r1.add(r0.shiftRight(1));
+ R0 = R1.add(t);
}
- else
+ else // mu == -1
{
- // mu == -1
- r0 = r1.subtract(r0.shiftRight(1));
+ R0 = R1.subtract(t);
}
- r1 = t.shiftRight(1).negate();
- i++;
+ R1 = t.negate();
}
+
+ long r0_64 = BigIntegers.longValueExact(R0);
+ long r1_64 = BigIntegers.longValueExact(R1);
+
+ // while lambda <> (0, 0)
+ while ((r0_64 | r1_64) != 0L)
+ {
+ if ((r0_64 & 1L) != 0L)
+ {
+ int uVal = (int)r0_64 + ((int)r1_64 * tw);
+ int alphaPos = uVal & pow2Mask;
+
+ u[uPos] = (byte)((uVal << s) >> s);
+ r0_64 -= alpha[alphaPos].u.intValue();
+ r1_64 -= alpha[alphaPos].v.intValue();
+ }
+
+ ++uPos;
+
+ long t_64 = r0_64 >> 1;
+ if (mu == 1)
+ {
+ r0_64 = r1_64 + t_64;
+ }
+ else // mu == -1
+ {
+ r0_64 = r1_64 - t_64;
+ }
+ r1_64 = -t_64;
+ }
+
return u;
}
@@ -831,6 +809,7 @@
*/
public static ECPoint.AbstractF2m[] getPreComp(ECPoint.AbstractF2m p, byte a)
{
+ ECPoint.AbstractF2m pNeg = (ECPoint.AbstractF2m)p.negate();
byte[][] alphaTnaf = (a == 0) ? Tnaf.alpha0Tnaf : Tnaf.alpha1Tnaf;
ECPoint.AbstractF2m[] pu = new ECPoint.AbstractF2m[(alphaTnaf.length + 1) >>> 1];
@@ -839,7 +818,7 @@
int precompLen = alphaTnaf.length;
for (int i = 3; i < precompLen; i += 2)
{
- pu[i >>> 1] = Tnaf.multiplyFromTnaf(p, alphaTnaf[i]);
+ pu[i >>> 1] = Tnaf.multiplyFromTnaf(p, pNeg, alphaTnaf[i]);
}
p.getCurve().normalizeAll(pu);
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafMultiplier.java b/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafMultiplier.java
index 0438e1d..f30a4bd 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafMultiplier.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafMultiplier.java
@@ -29,12 +29,10 @@
ECPoint.AbstractF2m p = (ECPoint.AbstractF2m)point;
ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
- int m = curve.getFieldSize();
byte a = curve.getA().toBigInteger().byteValue();
byte mu = Tnaf.getMu(a);
- BigInteger[] s = curve.getSi();
- ZTauElement rho = Tnaf.partModReduction(k, m, a, s, mu, (byte)10);
+ ZTauElement rho = Tnaf.partModReduction(curve, k, a, mu, (byte)10);
return multiplyWTnaf(p, rho, a, mu);
}
@@ -55,8 +53,7 @@
BigInteger tw = Tnaf.getTw(mu, Tnaf.WIDTH);
- byte[]u = Tnaf.tauAdicWNaf(mu, lambda, Tnaf.WIDTH,
- BigInteger.valueOf(Tnaf.POW_2_WIDTH), tw, alpha);
+ byte[] u = Tnaf.tauAdicWNaf(mu, lambda, Tnaf.WIDTH, tw.intValue(), alpha);
return multiplyFromWTnaf(p, u);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
index 8afbb31..fe41c13 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
@@ -98,6 +98,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ Nat256.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
{
int c = Nat256.mulAddTo(x, y, zz);
@@ -171,6 +177,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ Nat256.square(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -186,6 +198,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ Nat256.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat256.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat256.sub(x, y, z);
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
index c04ce87..6809956 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
@@ -146,49 +146,51 @@
return this;
}
+ int[] tt0 = Nat256.createExt();
+
int[] x2 = Nat256.create();
- SecP256K1Field.square(x1, x2);
- SecP256K1Field.multiply(x2, x1, x2);
+ SecP256K1Field.square(x1, x2, tt0);
+ SecP256K1Field.multiply(x2, x1, x2, tt0);
int[] x3 = Nat256.create();
- SecP256K1Field.square(x2, x3);
- SecP256K1Field.multiply(x3, x1, x3);
+ SecP256K1Field.square(x2, x3, tt0);
+ SecP256K1Field.multiply(x3, x1, x3, tt0);
int[] x6 = Nat256.create();
- SecP256K1Field.squareN(x3, 3, x6);
- SecP256K1Field.multiply(x6, x3, x6);
+ SecP256K1Field.squareN(x3, 3, x6, tt0);
+ SecP256K1Field.multiply(x6, x3, x6, tt0);
int[] x9 = x6;
- SecP256K1Field.squareN(x6, 3, x9);
- SecP256K1Field.multiply(x9, x3, x9);
+ SecP256K1Field.squareN(x6, 3, x9, tt0);
+ SecP256K1Field.multiply(x9, x3, x9, tt0);
int[] x11 = x9;
- SecP256K1Field.squareN(x9, 2, x11);
- SecP256K1Field.multiply(x11, x2, x11);
+ SecP256K1Field.squareN(x9, 2, x11, tt0);
+ SecP256K1Field.multiply(x11, x2, x11, tt0);
int[] x22 = Nat256.create();
- SecP256K1Field.squareN(x11, 11, x22);
- SecP256K1Field.multiply(x22, x11, x22);
+ SecP256K1Field.squareN(x11, 11, x22, tt0);
+ SecP256K1Field.multiply(x22, x11, x22, tt0);
int[] x44 = x11;
- SecP256K1Field.squareN(x22, 22, x44);
- SecP256K1Field.multiply(x44, x22, x44);
+ SecP256K1Field.squareN(x22, 22, x44, tt0);
+ SecP256K1Field.multiply(x44, x22, x44, tt0);
int[] x88 = Nat256.create();
- SecP256K1Field.squareN(x44, 44, x88);
- SecP256K1Field.multiply(x88, x44, x88);
+ SecP256K1Field.squareN(x44, 44, x88, tt0);
+ SecP256K1Field.multiply(x88, x44, x88, tt0);
int[] x176 = Nat256.create();
- SecP256K1Field.squareN(x88, 88, x176);
- SecP256K1Field.multiply(x176, x88, x176);
+ SecP256K1Field.squareN(x88, 88, x176, tt0);
+ SecP256K1Field.multiply(x176, x88, x176, tt0);
int[] x220 = x88;
- SecP256K1Field.squareN(x176, 44, x220);
- SecP256K1Field.multiply(x220, x44, x220);
+ SecP256K1Field.squareN(x176, 44, x220, tt0);
+ SecP256K1Field.multiply(x220, x44, x220, tt0);
int[] x223 = x44;
- SecP256K1Field.squareN(x220, 3, x223);
- SecP256K1Field.multiply(x223, x3, x223);
+ SecP256K1Field.squareN(x220, 3, x223, tt0);
+ SecP256K1Field.multiply(x223, x3, x223, tt0);
int[] t1 = x223;
- SecP256K1Field.squareN(t1, 23, t1);
- SecP256K1Field.multiply(t1, x22, t1);
- SecP256K1Field.squareN(t1, 6, t1);
- SecP256K1Field.multiply(t1, x2, t1);
- SecP256K1Field.squareN(t1, 2, t1);
+ SecP256K1Field.squareN(t1, 23, t1, tt0);
+ SecP256K1Field.multiply(t1, x22, t1, tt0);
+ SecP256K1Field.squareN(t1, 6, t1, tt0);
+ SecP256K1Field.multiply(t1, x2, t1, tt0);
+ SecP256K1Field.squareN(t1, 2, t1, tt0);
int[] t2 = x2;
- SecP256K1Field.square(t1, t2);
+ SecP256K1Field.square(t1, t2, tt0);
return Nat256.eq(x1, t2) ? new SecP256K1FieldElement(t1) : null;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
index 0ec55e0..e8cb06e 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
@@ -48,6 +48,7 @@
SecP256K1FieldElement Z2 = (SecP256K1FieldElement)b.getZCoord(0);
int c;
+ int[] tt0 = Nat256.createExt();
int[] tt1 = Nat256.createExt();
int[] t2 = Nat256.create();
int[] t3 = Nat256.create();
@@ -63,13 +64,13 @@
else
{
S2 = t3;
- SecP256K1Field.square(Z1.x, S2);
+ SecP256K1Field.square(Z1.x, S2, tt0);
U2 = t2;
- SecP256K1Field.multiply(S2, X2.x, U2);
+ SecP256K1Field.multiply(S2, X2.x, U2, tt0);
- SecP256K1Field.multiply(S2, Z1.x, S2);
- SecP256K1Field.multiply(S2, Y2.x, S2);
+ SecP256K1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP256K1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -82,13 +83,13 @@
else
{
S1 = t4;
- SecP256K1Field.square(Z2.x, S1);
+ SecP256K1Field.square(Z2.x, S1, tt0);
U1 = tt1;
- SecP256K1Field.multiply(S1, X1.x, U1);
+ SecP256K1Field.multiply(S1, X1.x, U1, tt0);
- SecP256K1Field.multiply(S1, Z2.x, S1);
- SecP256K1Field.multiply(S1, Y1.x, S1);
+ SecP256K1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP256K1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat256.create();
@@ -111,13 +112,13 @@
}
int[] HSquared = t3;
- SecP256K1Field.square(H, HSquared);
+ SecP256K1Field.square(H, HSquared, tt0);
int[] G = Nat256.create();
- SecP256K1Field.multiply(HSquared, H, G);
+ SecP256K1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP256K1Field.multiply(HSquared, U1, V);
+ SecP256K1Field.multiply(HSquared, U1, V, tt0);
SecP256K1Field.negate(G, G);
Nat256.mul(S1, G, tt1);
@@ -126,7 +127,7 @@
SecP256K1Field.reduce32(c, G);
SecP256K1FieldElement X3 = new SecP256K1FieldElement(t4);
- SecP256K1Field.square(R, X3.x);
+ SecP256K1Field.square(R, X3.x, tt0);
SecP256K1Field.subtract(X3.x, G, X3.x);
SecP256K1FieldElement Y3 = new SecP256K1FieldElement(G);
@@ -137,11 +138,11 @@
SecP256K1FieldElement Z3 = new SecP256K1FieldElement(H);
if (!Z1IsOne)
{
- SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP256K1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP256K1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
@@ -168,20 +169,21 @@
SecP256K1FieldElement X1 = (SecP256K1FieldElement)this.x, Z1 = (SecP256K1FieldElement)this.zs[0];
int c;
+ int[] tt0 = Nat256.createExt();
int[] Y1Squared = Nat256.create();
- SecP256K1Field.square(Y1.x, Y1Squared);
+ SecP256K1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat256.create();
- SecP256K1Field.square(Y1Squared, T);
+ SecP256K1Field.square(Y1Squared, T, tt0);
int[] M = Nat256.create();
- SecP256K1Field.square(X1.x, M);
+ SecP256K1Field.square(X1.x, M, tt0);
c = Nat256.addBothTo(M, M, M);
SecP256K1Field.reduce32(c, M);
int[] S = Y1Squared;
- SecP256K1Field.multiply(Y1Squared, X1.x, S);
+ SecP256K1Field.multiply(Y1Squared, X1.x, S, tt0);
c = Nat.shiftUpBits(8, S, 2, 0);
SecP256K1Field.reduce32(c, S);
@@ -190,20 +192,20 @@
SecP256K1Field.reduce32(c, t1);
SecP256K1FieldElement X3 = new SecP256K1FieldElement(T);
- SecP256K1Field.square(M, X3.x);
+ SecP256K1Field.square(M, X3.x, tt0);
SecP256K1Field.subtract(X3.x, S, X3.x);
SecP256K1Field.subtract(X3.x, S, X3.x);
SecP256K1FieldElement Y3 = new SecP256K1FieldElement(S);
SecP256K1Field.subtract(S, X3.x, Y3.x);
- SecP256K1Field.multiply(Y3.x, M, Y3.x);
+ SecP256K1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP256K1Field.subtract(Y3.x, t1, Y3.x);
SecP256K1FieldElement Z3 = new SecP256K1FieldElement(M);
SecP256K1Field.twice(Y1.x, Z3.x);
if (!Z1.isOne())
{
- SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP256K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
index 6b780fd..298bdd4 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
@@ -94,6 +94,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ Nat256.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
{
int c = Nat256.mulAddTo(x, y, zz);
@@ -240,6 +246,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ Nat256.square(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -255,6 +267,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ Nat256.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat256.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat256.sub(x, y, z);
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
index f2ad785..50cff26 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
@@ -137,32 +137,33 @@
return this;
}
+ int[] tt0 = Nat256.createExt();
int[] t1 = Nat256.create();
int[] t2 = Nat256.create();
- SecP256R1Field.square(x1, t1);
- SecP256R1Field.multiply(t1, x1, t1);
+ SecP256R1Field.square(x1, t1, tt0);
+ SecP256R1Field.multiply(t1, x1, t1, tt0);
- SecP256R1Field.squareN(t1, 2, t2);
- SecP256R1Field.multiply(t2, t1, t2);
+ SecP256R1Field.squareN(t1, 2, t2, tt0);
+ SecP256R1Field.multiply(t2, t1, t2, tt0);
- SecP256R1Field.squareN(t2, 4, t1);
- SecP256R1Field.multiply(t1, t2, t1);
+ SecP256R1Field.squareN(t2, 4, t1, tt0);
+ SecP256R1Field.multiply(t1, t2, t1, tt0);
- SecP256R1Field.squareN(t1, 8, t2);
- SecP256R1Field.multiply(t2, t1, t2);
+ SecP256R1Field.squareN(t1, 8, t2, tt0);
+ SecP256R1Field.multiply(t2, t1, t2, tt0);
- SecP256R1Field.squareN(t2, 16, t1);
- SecP256R1Field.multiply(t1, t2, t1);
+ SecP256R1Field.squareN(t2, 16, t1, tt0);
+ SecP256R1Field.multiply(t1, t2, t1, tt0);
- SecP256R1Field.squareN(t1, 32, t1);
- SecP256R1Field.multiply(t1, x1, t1);
+ SecP256R1Field.squareN(t1, 32, t1, tt0);
+ SecP256R1Field.multiply(t1, x1, t1, tt0);
- SecP256R1Field.squareN(t1, 96, t1);
- SecP256R1Field.multiply(t1, x1, t1);
+ SecP256R1Field.squareN(t1, 96, t1, tt0);
+ SecP256R1Field.multiply(t1, x1, t1, tt0);
- SecP256R1Field.squareN(t1, 94, t1);
- SecP256R1Field.square(t1, t2);
+ SecP256R1Field.squareN(t1, 94, t1, tt0);
+ SecP256R1Field.square(t1, t2, tt0);
return Nat256.eq(x1, t2) ? new SecP256R1FieldElement(t1) : null;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
index 7f39a4e..1c38eab 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
@@ -47,6 +47,7 @@
SecP256R1FieldElement Z2 = (SecP256R1FieldElement)b.getZCoord(0);
int c;
+ int[] tt0 = Nat256.createExt();
int[] tt1 = Nat256.createExt();
int[] t2 = Nat256.create();
int[] t3 = Nat256.create();
@@ -62,13 +63,13 @@
else
{
S2 = t3;
- SecP256R1Field.square(Z1.x, S2);
+ SecP256R1Field.square(Z1.x, S2, tt0);
U2 = t2;
- SecP256R1Field.multiply(S2, X2.x, U2);
+ SecP256R1Field.multiply(S2, X2.x, U2, tt0);
- SecP256R1Field.multiply(S2, Z1.x, S2);
- SecP256R1Field.multiply(S2, Y2.x, S2);
+ SecP256R1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP256R1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -81,13 +82,13 @@
else
{
S1 = t4;
- SecP256R1Field.square(Z2.x, S1);
+ SecP256R1Field.square(Z2.x, S1, tt0);
U1 = tt1;
- SecP256R1Field.multiply(S1, X1.x, U1);
+ SecP256R1Field.multiply(S1, X1.x, U1, tt0);
- SecP256R1Field.multiply(S1, Z2.x, S1);
- SecP256R1Field.multiply(S1, Y1.x, S1);
+ SecP256R1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP256R1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat256.create();
@@ -110,13 +111,13 @@
}
int[] HSquared = t3;
- SecP256R1Field.square(H, HSquared);
+ SecP256R1Field.square(H, HSquared, tt0);
int[] G = Nat256.create();
- SecP256R1Field.multiply(HSquared, H, G);
+ SecP256R1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP256R1Field.multiply(HSquared, U1, V);
+ SecP256R1Field.multiply(HSquared, U1, V, tt0);
SecP256R1Field.negate(G, G);
Nat256.mul(S1, G, tt1);
@@ -125,7 +126,7 @@
SecP256R1Field.reduce32(c, G);
SecP256R1FieldElement X3 = new SecP256R1FieldElement(t4);
- SecP256R1Field.square(R, X3.x);
+ SecP256R1Field.square(R, X3.x, tt0);
SecP256R1Field.subtract(X3.x, G, X3.x);
SecP256R1FieldElement Y3 = new SecP256R1FieldElement(G);
@@ -136,11 +137,11 @@
SecP256R1FieldElement Z3 = new SecP256R1FieldElement(H);
if (!Z1IsOne)
{
- SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP256R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP256R1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
@@ -166,14 +167,15 @@
SecP256R1FieldElement X1 = (SecP256R1FieldElement)this.x, Z1 = (SecP256R1FieldElement)this.zs[0];
int c;
+ int[] tt0 = Nat256.createExt();
int[] t1 = Nat256.create();
int[] t2 = Nat256.create();
int[] Y1Squared = Nat256.create();
- SecP256R1Field.square(Y1.x, Y1Squared);
+ SecP256R1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat256.create();
- SecP256R1Field.square(Y1Squared, T);
+ SecP256R1Field.square(Y1Squared, T, tt0);
boolean Z1IsOne = Z1.isOne();
@@ -181,19 +183,19 @@
if (!Z1IsOne)
{
Z1Squared = t2;
- SecP256R1Field.square(Z1.x, Z1Squared);
+ SecP256R1Field.square(Z1.x, Z1Squared, tt0);
}
SecP256R1Field.subtract(X1.x, Z1Squared, t1);
int[] M = t2;
SecP256R1Field.add(X1.x, Z1Squared, M);
- SecP256R1Field.multiply(M, t1, M);
+ SecP256R1Field.multiply(M, t1, M, tt0);
c = Nat256.addBothTo(M, M, M);
SecP256R1Field.reduce32(c, M);
int[] S = Y1Squared;
- SecP256R1Field.multiply(Y1Squared, X1.x, S);
+ SecP256R1Field.multiply(Y1Squared, X1.x, S, tt0);
c = Nat.shiftUpBits(8, S, 2, 0);
SecP256R1Field.reduce32(c, S);
@@ -201,20 +203,20 @@
SecP256R1Field.reduce32(c, t1);
SecP256R1FieldElement X3 = new SecP256R1FieldElement(T);
- SecP256R1Field.square(M, X3.x);
+ SecP256R1Field.square(M, X3.x, tt0);
SecP256R1Field.subtract(X3.x, S, X3.x);
SecP256R1Field.subtract(X3.x, S, X3.x);
SecP256R1FieldElement Y3 = new SecP256R1FieldElement(S);
SecP256R1Field.subtract(S, X3.x, Y3.x);
- SecP256R1Field.multiply(Y3.x, M, Y3.x);
+ SecP256R1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP256R1Field.subtract(Y3.x, t1, Y3.x);
SecP256R1FieldElement Z3 = new SecP256R1FieldElement(M);
SecP256R1Field.twice(Y1.x, Z3.x);
if (!Z1IsOne)
{
- SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP256R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
index 83852e8..4afab65 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
@@ -100,6 +100,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ Nat384.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void negate(int[] x, int[] z)
{
if (0 != isZero(x))
@@ -236,6 +242,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ Nat384.square(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -251,6 +263,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ Nat384.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat384.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat.sub(12, x, y, z);
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
index 77623c1..7cfa2e3 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
@@ -137,54 +137,55 @@
return this;
}
+ int[] tt0 = Nat.create(24);
int[] t1 = Nat.create(12);
int[] t2 = Nat.create(12);
int[] t3 = Nat.create(12);
int[] t4 = Nat.create(12);
- SecP384R1Field.square(x1, t1);
- SecP384R1Field.multiply(t1, x1, t1);
+ SecP384R1Field.square(x1, t1, tt0);
+ SecP384R1Field.multiply(t1, x1, t1, tt0);
- SecP384R1Field.squareN(t1, 2, t2);
- SecP384R1Field.multiply(t2, t1, t2);
+ SecP384R1Field.squareN(t1, 2, t2, tt0);
+ SecP384R1Field.multiply(t2, t1, t2, tt0);
- SecP384R1Field.square(t2, t2);
- SecP384R1Field.multiply(t2, x1, t2);
+ SecP384R1Field.square(t2, t2, tt0);
+ SecP384R1Field.multiply(t2, x1, t2, tt0);
- SecP384R1Field.squareN(t2, 5, t3);
- SecP384R1Field.multiply(t3, t2, t3);
+ SecP384R1Field.squareN(t2, 5, t3, tt0);
+ SecP384R1Field.multiply(t3, t2, t3, tt0);
- SecP384R1Field.squareN(t3, 5, t4);
- SecP384R1Field.multiply(t4, t2, t4);
+ SecP384R1Field.squareN(t3, 5, t4, tt0);
+ SecP384R1Field.multiply(t4, t2, t4, tt0);
- SecP384R1Field.squareN(t4, 15, t2);
- SecP384R1Field.multiply(t2, t4, t2);
+ SecP384R1Field.squareN(t4, 15, t2, tt0);
+ SecP384R1Field.multiply(t2, t4, t2, tt0);
- SecP384R1Field.squareN(t2, 2, t3);
- SecP384R1Field.multiply(t1, t3, t1);
+ SecP384R1Field.squareN(t2, 2, t3, tt0);
+ SecP384R1Field.multiply(t1, t3, t1, tt0);
- SecP384R1Field.squareN(t3, 28, t3);
- SecP384R1Field.multiply(t2, t3, t2);
+ SecP384R1Field.squareN(t3, 28, t3, tt0);
+ SecP384R1Field.multiply(t2, t3, t2, tt0);
- SecP384R1Field.squareN(t2, 60, t3);
- SecP384R1Field.multiply(t3, t2, t3);
+ SecP384R1Field.squareN(t2, 60, t3, tt0);
+ SecP384R1Field.multiply(t3, t2, t3, tt0);
int[] r = t2;
- SecP384R1Field.squareN(t3, 120, r);
- SecP384R1Field.multiply(r, t3, r);
+ SecP384R1Field.squareN(t3, 120, r, tt0);
+ SecP384R1Field.multiply(r, t3, r, tt0);
- SecP384R1Field.squareN(r, 15, r);
- SecP384R1Field.multiply(r, t4, r);
+ SecP384R1Field.squareN(r, 15, r, tt0);
+ SecP384R1Field.multiply(r, t4, r, tt0);
- SecP384R1Field.squareN(r, 33, r);
- SecP384R1Field.multiply(r, t1, r);
+ SecP384R1Field.squareN(r, 33, r, tt0);
+ SecP384R1Field.multiply(r, t1, r, tt0);
- SecP384R1Field.squareN(r, 64, r);
- SecP384R1Field.multiply(r, x1, r);
+ SecP384R1Field.squareN(r, 64, r, tt0);
+ SecP384R1Field.multiply(r, x1, r, tt0);
- SecP384R1Field.squareN(r, 30, t1);
- SecP384R1Field.square(t1, t2);
+ SecP384R1Field.squareN(r, 30, t1, tt0);
+ SecP384R1Field.square(t1, t2, tt0);
return Nat.eq(12, x1, t2) ? new SecP384R1FieldElement(t1) : null;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
index d234cb5..e54029d 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
@@ -47,6 +47,7 @@
SecP384R1FieldElement Z2 = (SecP384R1FieldElement)b.getZCoord(0);
int c;
+ int[] tt0 = Nat.create(24);
int[] tt1 = Nat.create(24);
int[] tt2 = Nat.create(24);
int[] t3 = Nat.create(12);
@@ -62,13 +63,13 @@
else
{
S2 = t3;
- SecP384R1Field.square(Z1.x, S2);
+ SecP384R1Field.square(Z1.x, S2, tt0);
U2 = tt2;
- SecP384R1Field.multiply(S2, X2.x, U2);
+ SecP384R1Field.multiply(S2, X2.x, U2, tt0);
- SecP384R1Field.multiply(S2, Z1.x, S2);
- SecP384R1Field.multiply(S2, Y2.x, S2);
+ SecP384R1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP384R1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -81,13 +82,13 @@
else
{
S1 = t4;
- SecP384R1Field.square(Z2.x, S1);
+ SecP384R1Field.square(Z2.x, S1, tt0);
U1 = tt1;
- SecP384R1Field.multiply(S1, X1.x, U1);
+ SecP384R1Field.multiply(S1, X1.x, U1, tt0);
- SecP384R1Field.multiply(S1, Z2.x, S1);
- SecP384R1Field.multiply(S1, Y1.x, S1);
+ SecP384R1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP384R1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat.create(12);
@@ -110,13 +111,13 @@
}
int[] HSquared = t3;
- SecP384R1Field.square(H, HSquared);
+ SecP384R1Field.square(H, HSquared, tt0);
int[] G = Nat.create(12);
- SecP384R1Field.multiply(HSquared, H, G);
+ SecP384R1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP384R1Field.multiply(HSquared, U1, V);
+ SecP384R1Field.multiply(HSquared, U1, V, tt0);
SecP384R1Field.negate(G, G);
Nat384.mul(S1, G, tt1);
@@ -125,7 +126,7 @@
SecP384R1Field.reduce32(c, G);
SecP384R1FieldElement X3 = new SecP384R1FieldElement(t4);
- SecP384R1Field.square(R, X3.x);
+ SecP384R1Field.square(R, X3.x, tt0);
SecP384R1Field.subtract(X3.x, G, X3.x);
SecP384R1FieldElement Y3 = new SecP384R1FieldElement(G);
@@ -137,11 +138,11 @@
SecP384R1FieldElement Z3 = new SecP384R1FieldElement(H);
if (!Z1IsOne)
{
- SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP384R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP384R1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
@@ -167,14 +168,15 @@
SecP384R1FieldElement X1 = (SecP384R1FieldElement)this.x, Z1 = (SecP384R1FieldElement)this.zs[0];
int c;
+ int[] tt0 = Nat.create(24);
int[] t1 = Nat.create(12);
int[] t2 = Nat.create(12);
int[] Y1Squared = Nat.create(12);
- SecP384R1Field.square(Y1.x, Y1Squared);
+ SecP384R1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat.create(12);
- SecP384R1Field.square(Y1Squared, T);
+ SecP384R1Field.square(Y1Squared, T, tt0);
boolean Z1IsOne = Z1.isOne();
@@ -182,19 +184,19 @@
if (!Z1IsOne)
{
Z1Squared = t2;
- SecP384R1Field.square(Z1.x, Z1Squared);
+ SecP384R1Field.square(Z1.x, Z1Squared, tt0);
}
SecP384R1Field.subtract(X1.x, Z1Squared, t1);
int[] M = t2;
SecP384R1Field.add(X1.x, Z1Squared, M);
- SecP384R1Field.multiply(M, t1, M);
+ SecP384R1Field.multiply(M, t1, M, tt0);
c = Nat.addBothTo(12, M, M, M);
SecP384R1Field.reduce32(c, M);
int[] S = Y1Squared;
- SecP384R1Field.multiply(Y1Squared, X1.x, S);
+ SecP384R1Field.multiply(Y1Squared, X1.x, S, tt0);
c = Nat.shiftUpBits(12, S, 2, 0);
SecP384R1Field.reduce32(c, S);
@@ -202,20 +204,20 @@
SecP384R1Field.reduce32(c, t1);
SecP384R1FieldElement X3 = new SecP384R1FieldElement(T);
- SecP384R1Field.square(M, X3.x);
+ SecP384R1Field.square(M, X3.x, tt0);
SecP384R1Field.subtract(X3.x, S, X3.x);
SecP384R1Field.subtract(X3.x, S, X3.x);
SecP384R1FieldElement Y3 = new SecP384R1FieldElement(S);
SecP384R1Field.subtract(S, X3.x, Y3.x);
- SecP384R1Field.multiply(Y3.x, M, Y3.x);
+ SecP384R1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP384R1Field.subtract(Y3.x, t1, Y3.x);
SecP384R1FieldElement Z3 = new SecP384R1FieldElement(M);
SecP384R1Field.twice(Y1.x, Z3.x);
if (!Z1IsOne)
{
- SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP384R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
index 62f2591..1f39f3d 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
@@ -77,6 +77,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ implMultiply(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void negate(int[] x, int[] z)
{
if (0 != isZero(x))
@@ -145,6 +151,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ implSquare(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -160,6 +172,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ implSquare(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ implSquare(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat.sub(16, x, y, z) + x[16] - y[16];
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
index be52b34..3a91fc7 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
@@ -138,11 +138,12 @@
return this;
}
+ int[] tt0 = Nat.create(33);
int[] t1 = Nat.create(17);
int[] t2 = Nat.create(17);
- SecP521R1Field.squareN(x1, 519, t1);
- SecP521R1Field.square(t1, t2);
+ SecP521R1Field.squareN(x1, 519, t1, tt0);
+ SecP521R1Field.square(t1, t2, tt0);
return Nat.eq(17, x1, t2) ? new SecP521R1FieldElement(t1) : null;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
index d695cda..025e137 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
@@ -45,6 +45,7 @@
SecP521R1FieldElement Z1 = (SecP521R1FieldElement)this.zs[0];
SecP521R1FieldElement Z2 = (SecP521R1FieldElement)b.getZCoord(0);
+ int[] tt0 = Nat.create(33);
int[] t1 = Nat.create(17);
int[] t2 = Nat.create(17);
int[] t3 = Nat.create(17);
@@ -60,13 +61,13 @@
else
{
S2 = t3;
- SecP521R1Field.square(Z1.x, S2);
+ SecP521R1Field.square(Z1.x, S2, tt0);
U2 = t2;
- SecP521R1Field.multiply(S2, X2.x, U2);
+ SecP521R1Field.multiply(S2, X2.x, U2, tt0);
- SecP521R1Field.multiply(S2, Z1.x, S2);
- SecP521R1Field.multiply(S2, Y2.x, S2);
+ SecP521R1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP521R1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -79,13 +80,13 @@
else
{
S1 = t4;
- SecP521R1Field.square(Z2.x, S1);
+ SecP521R1Field.square(Z2.x, S1, tt0);
U1 = t1;
- SecP521R1Field.multiply(S1, X1.x, U1);
+ SecP521R1Field.multiply(S1, X1.x, U1, tt0);
- SecP521R1Field.multiply(S1, Z2.x, S1);
- SecP521R1Field.multiply(S1, Y1.x, S1);
+ SecP521R1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP521R1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat.create(17);
@@ -108,35 +109,35 @@
}
int[] HSquared = t3;
- SecP521R1Field.square(H, HSquared);
+ SecP521R1Field.square(H, HSquared, tt0);
int[] G = Nat.create(17);
- SecP521R1Field.multiply(HSquared, H, G);
+ SecP521R1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP521R1Field.multiply(HSquared, U1, V);
+ SecP521R1Field.multiply(HSquared, U1, V, tt0);
- SecP521R1Field.multiply(S1, G, t1);
+ SecP521R1Field.multiply(S1, G, t1, tt0);
SecP521R1FieldElement X3 = new SecP521R1FieldElement(t4);
- SecP521R1Field.square(R, X3.x);
+ SecP521R1Field.square(R, X3.x, tt0);
SecP521R1Field.add(X3.x, G, X3.x);
SecP521R1Field.subtract(X3.x, V, X3.x);
SecP521R1Field.subtract(X3.x, V, X3.x);
SecP521R1FieldElement Y3 = new SecP521R1FieldElement(G);
SecP521R1Field.subtract(V, X3.x, Y3.x);
- SecP521R1Field.multiply(Y3.x, R, t2);
+ SecP521R1Field.multiply(Y3.x, R, t2, tt0);
SecP521R1Field.subtract(t2, t1, Y3.x);
SecP521R1FieldElement Z3 = new SecP521R1FieldElement(H);
if (!Z1IsOne)
{
- SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP521R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP521R1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
@@ -161,14 +162,15 @@
SecP521R1FieldElement X1 = (SecP521R1FieldElement)this.x, Z1 = (SecP521R1FieldElement)this.zs[0];
+ int[] tt0 = Nat.create(33);
int[] t1 = Nat.create(17);
int[] t2 = Nat.create(17);
int[] Y1Squared = Nat.create(17);
- SecP521R1Field.square(Y1.x, Y1Squared);
+ SecP521R1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat.create(17);
- SecP521R1Field.square(Y1Squared, T);
+ SecP521R1Field.square(Y1Squared, T, tt0);
boolean Z1IsOne = Z1.isOne();
@@ -176,19 +178,19 @@
if (!Z1IsOne)
{
Z1Squared = t2;
- SecP521R1Field.square(Z1.x, Z1Squared);
+ SecP521R1Field.square(Z1.x, Z1Squared, tt0);
}
SecP521R1Field.subtract(X1.x, Z1Squared, t1);
int[] M = t2;
SecP521R1Field.add(X1.x, Z1Squared, M);
- SecP521R1Field.multiply(M, t1, M);
+ SecP521R1Field.multiply(M, t1, M, tt0);
Nat.addBothTo(17, M, M, M);
SecP521R1Field.reduce23(M);
int[] S = Y1Squared;
- SecP521R1Field.multiply(Y1Squared, X1.x, S);
+ SecP521R1Field.multiply(Y1Squared, X1.x, S, tt0);
Nat.shiftUpBits(17, S, 2, 0);
SecP521R1Field.reduce23(S);
@@ -196,20 +198,20 @@
SecP521R1Field.reduce23(t1);
SecP521R1FieldElement X3 = new SecP521R1FieldElement(T);
- SecP521R1Field.square(M, X3.x);
+ SecP521R1Field.square(M, X3.x, tt0);
SecP521R1Field.subtract(X3.x, S, X3.x);
SecP521R1Field.subtract(X3.x, S, X3.x);
SecP521R1FieldElement Y3 = new SecP521R1FieldElement(S);
SecP521R1Field.subtract(S, X3.x, Y3.x);
- SecP521R1Field.multiply(Y3.x, M, Y3.x);
+ SecP521R1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP521R1Field.subtract(Y3.x, t1, Y3.x);
SecP521R1FieldElement Z3 = new SecP521R1FieldElement(M);
SecP521R1Field.twice(Y1.x, Z3.x);
if (!Z1IsOne)
{
- SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP521R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
index 55cc4c8..7367a31 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
@@ -7,17 +7,6 @@
protected final BigInteger beta, lambda;
protected final ScalarSplitParameters splitParams;
- /**
- * @deprecated Use constructor taking a {@link ScalarSplitParameters} instead.
- */
- public GLVTypeBParameters(BigInteger beta, BigInteger lambda, BigInteger[] v1, BigInteger[] v2, BigInteger g1,
- BigInteger g2, int bits)
- {
- this.beta = beta;
- this.lambda = lambda;
- this.splitParams = new ScalarSplitParameters(v1, v2, g1, g2, bits);
- }
-
public GLVTypeBParameters(BigInteger beta, BigInteger lambda, ScalarSplitParameters splitParams)
{
this.beta = beta;
@@ -39,60 +28,4 @@
{
return splitParams;
}
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV1A()
- {
- return getSplitParams().getV1A();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV1B()
- {
- return getSplitParams().getV1B();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV2A()
- {
- return getSplitParams().getV2A();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV2B()
- {
- return getSplitParams().getV2B();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getG1()
- {
- return getSplitParams().getG1();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getG2()
- {
- return getSplitParams().getG2();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public int getBits()
- {
- return getSplitParams().getBits();
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/field/FiniteFields.java b/bcprov/src/main/java/org/bouncycastle/math/field/FiniteFields.java
index c71eda7..e324885 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/field/FiniteFields.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/field/FiniteFields.java
@@ -2,6 +2,8 @@
import java.math.BigInteger;
+import org.bouncycastle.util.BigIntegers;
+
public abstract class FiniteFields
{
static final FiniteField GF_2 = new PrimeField(BigInteger.valueOf(2));
@@ -39,7 +41,7 @@
if (bitLength < 3)
{
- switch (characteristic.intValue())
+ switch (BigIntegers.intValueExact(characteristic))
{
case 2:
return GF_2;
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Mod.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Mod.java
index fc8f3c8..c956aea 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Mod.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Mod.java
@@ -14,17 +14,6 @@
private static final int M30 = 0x3FFFFFFF;
private static final long M32L = 0xFFFFFFFFL;
- /** @deprecated Will be removed. */
- public static void add(int[] p, int[] x, int[] y, int[] z)
- {
- int len = p.length;
- int c = Nat.add(len, x, y, z);
- if (c != 0)
- {
- Nat.subFrom(len, p, z);
- }
- }
-
public static void checkedModOddInverse(int[] m, int[] x, int[] z)
{
if (0 == modOddInverse(m, x, z))
@@ -54,12 +43,6 @@
return x;
}
- /** @deprecated Use {@link #checkedModOddInverseVar(int[], int[], int[])} instead. */
- public static void invert(int[] m, int[] x, int[] z)
- {
- checkedModOddInverseVar(m, x, z);
- }
-
public static int modOddInverse(int[] m, int[] x, int[] z)
{
int len32 = m.length;
@@ -82,13 +65,13 @@
encode30(bits, m, 0, M, 0);
System.arraycopy(M, 0, F, 0, len30);
- int eta = -1;
+ int delta = 0;
int m0Inv32 = inverse32(M[0]);
int maxDivsteps = getMaximumDivsteps(bits);
for (int divSteps = 0; divSteps < maxDivsteps; divSteps += 30)
{
- eta = divsteps30(eta, F[0], G[0], t);
+ delta = divsteps30(delta, F[0], G[0], t);
updateDE30(len30, D, E, t, m0Inv32, M);
updateFG30(len30, F, G, t);
}
@@ -228,17 +211,6 @@
return s;
}
- /** @deprecated Will be removed. */
- public static void subtract(int[] p, int[] x, int[] y, int[] z)
- {
- int len = p.length;
- int c = Nat.sub(len, x, y, z);
- if (c != 0)
- {
- Nat.addTo(len, p, z);
- }
- }
-
private static int add30(int len30, int[] D, int[] M)
{
// assert len30 > 0;
@@ -276,7 +248,6 @@
// assert len30 > 0;
// assert D.length >= len30;
// assert M.length >= len30;
-
int last = len30 - 1;
{
@@ -331,38 +302,38 @@
}
}
- private static int divsteps30(int eta, int f0, int g0, int[] t)
+ private static int divsteps30(int delta, int f0, int g0, int[] t)
{
- int u = 1, v = 0, q = 0, r = 1;
+ int u = 1 << 30, v = 0, q = 0, r = 1 << 30;
int f = f0, g = g0;
for (int i = 0; i < 30; ++i)
{
// assert (f & 1) == 1;
-// assert (u * f0 + v * g0) == f << i;
-// assert (q * f0 + r * g0) == g << i;
+// assert ((u >> (30 - i)) * f0 + (v >> (30 - i)) * g0) == f << i;
+// assert ((q >> (30 - i)) * f0 + (r >> (30 - i)) * g0) == g << i;
- int c1 = eta >> 31;
+ int c1 = delta >> 31;
int c2 = -(g & 1);
- int x = (f ^ c1) - c1;
- int y = (u ^ c1) - c1;
- int z = (v ^ c1) - c1;
+ int x = f ^ c1;
+ int y = u ^ c1;
+ int z = v ^ c1;
- g += x & c2;
- q += y & c2;
- r += z & c2;
+ g -= x & c2;
+ q -= y & c2;
+ r -= z & c2;
- c1 &= c2;
- eta = (eta ^ c1) - (c1 + 1);
+ c2 &= ~c1;
+ delta = (delta ^ c2) - (c2 - 1);
- f += g & c1;
- u += q & c1;
- v += r & c1;
+ f += g & c2;
+ u += q & c2;
+ v += r & c2;
g >>= 1;
- u <<= 1;
- v <<= 1;
+ q >>= 1;
+ r >>= 1;
}
t[0] = u;
@@ -370,7 +341,7 @@
t[2] = q;
t[3] = r;
- return eta;
+ return delta;
}
private static int divsteps30Var(int eta, int f0, int g0, int[] t)
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java
index 28745df..592dd61 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java
@@ -232,6 +232,19 @@
return (int)c;
}
+ public static int caddTo(int len, int mask, int[] x, int[] z)
+ {
+ long MASK = -(mask & 1) & M;
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (z[i] & M) + (x[i] & MASK);
+ z[i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
public static void cmov(int len, int mask, int[] x, int xOff, int[] z, int zOff)
{
mask = -(mask & 1);
@@ -1125,41 +1138,6 @@
shiftUpBit(extLen, zz, zzOff, x[xOff] << 31);
}
- /**
- * @deprecated Use {@link #squareWordAddTo(int[], int, int[])} instead.
- */
- public static int squareWordAdd(int[] x, int xPos, int[] z)
- {
- long c = 0, xVal = x[xPos] & M;
- int i = 0;
- do
- {
- c += xVal * (x[i] & M) + (z[xPos + i] & M);
- z[xPos + i] = (int)c;
- c >>>= 32;
- }
- while (++i < xPos);
- return (int)c;
- }
-
- /**
- * @deprecated Use {@link #squareWordAddTo(int[], int, int, int[], int)} instead.
- */
- public static int squareWordAdd(int[] x, int xOff, int xPos, int[] z, int zOff)
- {
- long c = 0, xVal = x[xOff + xPos] & M;
- int i = 0;
- do
- {
- c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M);
- z[xPos + zOff] = (int)c;
- c >>>= 32;
- ++zOff;
- }
- while (++i < xPos);
- return (int)c;
- }
-
public static int squareWordAddTo(int[] x, int xPos, int[] z)
{
long c = 0, xVal = x[xPos] & M;
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java
index e4b7d5e..3610442 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java
@@ -143,6 +143,33 @@
return (int)c;
}
+ public static int addTo(int[] x, int[] z, int cIn)
+ {
+ long c = cIn & M;
+ c += (x[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
{
long c = cIn & M;
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java
index 20b17cd..ed46d05 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java
@@ -158,6 +158,36 @@
return (int)c;
}
+ public static int addTo(int[] x, int[] z, int cIn)
+ {
+ long c = cIn & M;
+ c += (x[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ c += (x[7] & M) + (z[7] & M);
+ z[7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
{
long c = cIn & M;
@@ -602,6 +632,77 @@
}
}
+ public static void mul128(int[] x, int[] y128, int[] zz)
+ {
+ long x_0 = x[0] & M;
+ long x_1 = x[1] & M;
+ long x_2 = x[2] & M;
+ long x_3 = x[3] & M;
+ long x_4 = x[4] & M;
+ long x_5 = x[5] & M;
+ long x_6 = x[6] & M;
+ long x_7 = x[7] & M;
+
+ {
+ long c = 0, y_0 = y128[0] & M;
+ c += y_0 * x_0;
+ zz[0] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_1;
+ zz[1] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_2;
+ zz[2] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_3;
+ zz[3] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_4;
+ zz[4] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_5;
+ zz[5] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_6;
+ zz[6] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_7;
+ zz[7] = (int)c;
+ c >>>= 32;
+ zz[8] = (int)c;
+ }
+
+ for (int i = 1; i < 4; ++i)
+ {
+ long c = 0, y_i = y128[i] & M;
+ c += y_i * x_0 + (zz[i + 0] & M);
+ zz[i + 0] = (int)c;
+ c >>>= 32;
+ c += y_i * x_1 + (zz[i + 1] & M);
+ zz[i + 1] = (int)c;
+ c >>>= 32;
+ c += y_i * x_2 + (zz[i + 2] & M);
+ zz[i + 2] = (int)c;
+ c >>>= 32;
+ c += y_i * x_3 + (zz[i + 3] & M);
+ zz[i + 3] = (int)c;
+ c >>>= 32;
+ c += y_i * x_4 + (zz[i + 4] & M);
+ zz[i + 4] = (int)c;
+ c >>>= 32;
+ c += y_i * x_5 + (zz[i + 5] & M);
+ zz[i + 5] = (int)c;
+ c >>>= 32;
+ c += y_i * x_6 + (zz[i + 6] & M);
+ zz[i + 6] = (int)c;
+ c >>>= 32;
+ c += y_i * x_7 + (zz[i + 7] & M);
+ zz[i + 7] = (int)c;
+ c >>>= 32;
+ zz[i + 8] = (int)c;
+ }
+ }
+
public static int mulAddTo(int[] x, int[] y, int[] zz)
{
long y_0 = y[0] & M;
@@ -1347,6 +1448,36 @@
return (int)c;
}
+ public static int subFrom(int[] x, int[] z, int cIn)
+ {
+ long c = cIn & M;
+ c += (z[0] & M) - (x[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - (x[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M) - (x[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (z[3] & M) - (x[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) - (x[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M) - (x[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ c += (z[6] & M) - (x[6] & M);
+ z[6] = (int)c;
+ c >>= 32;
+ c += (z[7] & M) - (x[7] & M);
+ z[7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
public static int subFrom(int[] x, int xOff, int[] z, int zOff)
{
long c = 0;
@@ -1377,6 +1508,36 @@
return (int)c;
}
+ public static int subFrom(int[] x, int xOff, int[] z, int zOff, int cIn)
+ {
+ long c = cIn & M;
+ c += (z[zOff + 0] & M) - (x[xOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 1] & M) - (x[xOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 2] & M) - (x[xOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 3] & M) - (x[xOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 4] & M) - (x[xOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 5] & M) - (x[xOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 6] & M) - (x[xOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 7] & M) - (x[xOff + 7] & M);
+ z[zOff + 7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
public static BigInteger toBigInteger(int[] x)
{
byte[] bs = new byte[32];
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
index 6e52c36..27371dd 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
@@ -149,6 +149,47 @@
return 0 == d;
}
+ /**
+ * A constant time equals comparison - does not terminate early if
+ * comparison fails. For best results always pass the expected value
+ * as the first parameter.
+ *
+ * @param expected first array
+ * @param supplied second array
+ * @return true if arrays equal, false otherwise.
+ */
+ public static boolean constantTimeAreEqual(
+ char[] expected,
+ char[] supplied)
+ {
+ if (expected == null || supplied == null)
+ {
+ return false;
+ }
+
+ if (expected == supplied)
+ {
+ return true;
+ }
+
+ int len = Math.min(expected.length, supplied.length);
+
+ int nonEqual = expected.length ^ supplied.length;
+
+ // do the char-wise comparison
+ for (int i = 0; i != len; i++)
+ {
+ nonEqual |= (expected[i] ^ supplied[i]);
+ }
+ // If supplied is longer than expected, iterate over rest of supplied with NOPs
+ for (int i = len; i < supplied.length; i++)
+ {
+ nonEqual |= ((byte)supplied[i] ^ (byte)~supplied[i]);
+ }
+
+ return nonEqual == 0;
+ }
+
public static int compareUnsigned(byte[] a, byte[] b)
{
if (a == b)
@@ -274,14 +315,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(byte[], int, int, byte)} instead.
- */
- public static void fill(byte[] a, int fromIndex, byte val)
- {
- fill(a, fromIndex, a.length, val);
- }
-
public static void fill(byte[] a, int fromIndex, int toIndex, byte val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -302,14 +335,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(int[], int, int, int)} instead.
- */
- public static void fill(int[] a, int fromIndex, int val)
- {
- java.util.Arrays.fill(a, fromIndex, a.length, val);
- }
-
public static void fill(int[] a, int fromIndex, int toIndex, int val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -320,14 +345,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(long[], int, int, long)} instead.
- */
- public static void fill(long[] a, int fromIndex, long val)
- {
- java.util.Arrays.fill(a, fromIndex, a.length, val);
- }
-
public static void fill(long[] a, int fromIndex, int toIndex, long val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -348,14 +365,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(short[], int, int, short)} instead.
- */
- public static void fill(short[] a, int fromIndex, short val)
- {
- java.util.Arrays.fill(a, fromIndex, a.length, val);
- }
-
public static void fill(short[] a, int fromIndex, int toIndex, short val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -794,9 +803,7 @@
int newLength = to - from;
if (newLength < 0)
{
- StringBuffer sb = new StringBuffer(from);
- sb.append(" > ").append(to);
- throw new IllegalArgumentException(sb.toString());
+ throw new IllegalArgumentException(from + " > " + to);
}
return newLength;
}
@@ -1063,6 +1070,80 @@
return result;
}
+ public static void reverse(byte[] input, byte[] output)
+ {
+ int last = input.length - 1;
+ for (int i = 0; i <= last; ++i)
+ {
+ output[i] = input[last - i];
+ }
+ }
+
+ public static byte[] reverseInPlace(byte[] a)
+ {
+ if (null == a)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length - 1;
+ while (p1 < p2)
+ {
+ byte t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+
+ return a;
+ }
+
+ public static void reverseInPlace(byte[] a, int aOff, int aLen)
+ {
+ int p1 = aOff, p2 = aOff + aLen - 1;
+ while (p1 < p2)
+ {
+ byte t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+ }
+
+ public static short[] reverseInPlace(short[] a)
+ {
+ if (null == a)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length - 1;
+ while (p1 < p2)
+ {
+ short t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+
+ return a;
+ }
+
+ public static int[] reverseInPlace(int[] a)
+ {
+ if (null == a)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length - 1;
+ while (p1 < p2)
+ {
+ int t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+
+ return a;
+ }
+
/**
* Iterator backed by a specific array.
*/
diff --git a/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java b/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java
index 46e2bb0..fe0891b 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java
@@ -2,6 +2,11 @@
import java.math.BigInteger;
import java.security.SecureRandom;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.bouncycastle.math.raw.Mod;
+import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
@@ -21,7 +26,7 @@
/**
* Return the passed in value as an unsigned byte array.
- *
+ *
* @param value the value to be converted.
* @return a byte array without a leading zero byte if present in the signed encoding.
*/
@@ -29,16 +34,15 @@
BigInteger value)
{
byte[] bytes = value.toByteArray();
-
if (bytes[0] == 0 && bytes.length != 1)
{
byte[] tmp = new byte[bytes.length - 1];
-
+
System.arraycopy(bytes, 1, tmp, 0, tmp.length);
-
+
return tmp;
}
-
+
return bytes;
}
@@ -46,10 +50,8 @@
* Return the passed in value as an unsigned byte array of the specified length, padded with
* leading zeros as necessary..
*
- * @param length
- * the fixed length of the result
- * @param value
- * the value to be converted.
+ * @param length the fixed length of the result
+ * @param value the value to be converted.
* @return a byte array padded to a fixed length with leading zeros.
*/
public static byte[] asUnsignedByteArray(int length, BigInteger value)
@@ -77,14 +79,10 @@
* Write the passed in value as unsigned bytes to the specified buffer range, padded with
* leading zeros as necessary.
*
- * @param value
- * the value to be converted.
- * @param buf
- * the buffer to which the value is written.
- * @param off
- * the start offset in array <code>buf</code> at which the data is written.
- * @param len
- * the fixed length of data written (possibly padded with leading zeros).
+ * @param value the value to be converted.
+ * @param buf the buffer to which the value is written.
+ * @param off the start offset in array <code>buf</code> at which the data is written.
+ * @param len the fixed length of data written (possibly padded with leading zeros).
*/
public static void asUnsignedByteArray(BigInteger value, byte[] buf, int off, int len)
{
@@ -104,22 +102,23 @@
}
int padLen = len - count;
- Arrays.fill(buf, off, off + padLen, (byte)0x00);
+ Arrays.fill(buf, off, off + padLen, (byte)0x00);
System.arraycopy(bytes, start, buf, off + padLen, count);
}
+
/**
* Return a random BigInteger not less than 'min' and not greater than 'max'
- *
- * @param min the least value that may be generated
- * @param max the greatest value that may be generated
+ *
+ * @param min the least value that may be generated
+ * @param max the greatest value that may be generated
* @param random the source of randomness
* @return a random BigInteger value in the range [min,max]
*/
public static BigInteger createRandomInRange(
- BigInteger min,
- BigInteger max,
- SecureRandom random)
+ BigInteger min,
+ BigInteger max,
+ SecureRandom random)
{
int cmp = min.compareTo(max);
if (cmp >= 0)
@@ -150,6 +149,7 @@
return createRandomBigInteger(max.subtract(min).bitLength() - 1, random).add(min);
}
+
public static BigInteger fromUnsignedByteArray(byte[] buf)
{
return new BigInteger(1, buf);
@@ -166,6 +166,28 @@
return new BigInteger(1, mag);
}
+ public static byte byteValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.byteValueExact instead
+ if (x.bitLength() > 7)
+ {
+ throw new ArithmeticException("BigInteger out of int range");
+ }
+
+ return x.byteValue();
+ }
+
+ public static short shortValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.shortValueExact instead
+ if (x.bitLength() > 15)
+ {
+ throw new ArithmeticException("BigInteger out of int range");
+ }
+
+ return x.shortValue();
+ }
+
public static int intValueExact(BigInteger x)
{
// Since Java 1.8 could use BigInteger.intValueExact instead
@@ -174,7 +196,7 @@
throw new ArithmeticException("BigInteger out of int range");
}
- return x.intValue();
+ return x.intValue();
}
public static long longValueExact(BigInteger x)
@@ -185,7 +207,7 @@
throw new ArithmeticException("BigInteger out of long range");
}
- return x.longValue();
+ return x.longValue();
}
public static BigInteger modOddInverse(BigInteger M, BigInteger X)
@@ -264,7 +286,7 @@
* Return a positive BigInteger in the range of 0 to 2**bitLength - 1.
*
* @param bitLength maximum bit length for the generated BigInteger.
- * @param random a source of randomness.
+ * @param random a source of randomness.
* @return a positive BigInteger
*/
public static BigInteger createRandomBigInteger(int bitLength, SecureRandom random)
@@ -274,7 +296,7 @@
// Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
- "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
+ "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
+ "73d893fa424cd2edc8636a6c3285e022b0e3866a565ae8108eed8591cd4fe8d2"
+ "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8"
+ "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f",
@@ -285,7 +307,7 @@
* Return a prime number candidate of the specified bit length.
*
* @param bitLength bit length for the generated BigInteger.
- * @param random a source of randomness.
+ * @param random a source of randomness.
* @return a positive BigInteger of numBits length
*/
public static BigInteger createRandomPrime(int bitLength, int certainty, SecureRandom random)
@@ -347,4 +369,38 @@
return rv;
}
+
+ public static class Cache
+ {
+ private final Map<BigInteger, Boolean> values = new WeakHashMap<BigInteger, Boolean>();
+ private final BigInteger[] preserve = new BigInteger[8];
+
+ private int preserveCounter = 0;
+
+ public synchronized void add(BigInteger value)
+ {
+ values.put(value, Boolean.TRUE);
+ preserve[preserveCounter] = value;
+ preserveCounter = (preserveCounter + 1) % preserve.length;
+ }
+
+ public synchronized boolean contains(BigInteger value)
+ {
+ return values.containsKey(value);
+ }
+
+ public synchronized int size()
+ {
+ return values.size();
+ }
+
+ public synchronized void clear()
+ {
+ values.clear();
+ for (int i = 0; i != preserve.length; i++)
+ {
+ preserve[i] = null;
+ }
+ }
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Bytes.java b/bcprov/src/main/java/org/bouncycastle/util/Bytes.java
new file mode 100644
index 0000000..4db8575
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/util/Bytes.java
@@ -0,0 +1,42 @@
+package org.bouncycastle.util;
+
+/**
+ * Utility methods and constants for bytes.
+ */
+public class Bytes
+{
+ public static final int BYTES = 1;
+ public static final int SIZE = Byte.SIZE;
+
+ public static void xor(int len, byte[] x, byte[] y, byte[] z)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] = (byte)(x[i] ^ y[i]);
+ }
+ }
+
+ public static void xor(int len, byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]);
+ }
+ }
+
+ public static void xorTo(int len, byte[] x, byte[] z)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] ^= x[i];
+ }
+ }
+
+ public static void xorTo(int len, byte[] x, int xOff, byte[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[zOff + i] ^= x[xOff + i];
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Characters.java b/bcprov/src/main/java/org/bouncycastle/util/Characters.java
new file mode 100644
index 0000000..828c464
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/util/Characters.java
@@ -0,0 +1,9 @@
+package org.bouncycastle.util;
+
+public class Characters
+{
+ public static Character valueOf(char c)
+ {
+ return Character.valueOf(c);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Exceptions.java b/bcprov/src/main/java/org/bouncycastle/util/Exceptions.java
new file mode 100644
index 0000000..74ef192
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/util/Exceptions.java
@@ -0,0 +1,22 @@
+package org.bouncycastle.util;
+
+import java.io.IOException;
+
+public class Exceptions
+{
+ public static IllegalArgumentException illegalArgumentException(String message, Throwable cause)
+ {
+ return new IllegalArgumentException(message, cause);
+ }
+
+ public static IllegalStateException illegalStateException(String message, Throwable cause)
+ {
+ return new IllegalStateException(message, cause);
+ }
+
+ public static IOException ioException(String message, Throwable cause)
+ {
+ return new IOException(message, cause);
+ }
+
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/IPAddress.java b/bcprov/src/main/java/org/bouncycastle/util/IPAddress.java
index 8f57263..5dbf1d0 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/IPAddress.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/IPAddress.java
@@ -12,8 +12,7 @@
*
* @return true if a valid address, false otherwise
*/
- public static boolean isValid(
- String address)
+ public static boolean isValid(String address)
{
return isValidIPv4(address) || isValidIPv6(address);
}
@@ -25,8 +24,7 @@
*
* @return true if a valid address with netmask, false otherwise
*/
- public static boolean isValidWithNetMask(
- String address)
+ public static boolean isValidWithNetMask(String address)
{
return isValidIPv4WithNetmask(address) || isValidIPv6WithNetmask(address);
}
@@ -38,79 +36,42 @@
*
* @return true if a valid IPv4 address, false otherwise
*/
- public static boolean isValidIPv4(
- String address)
+ public static boolean isValidIPv4(String address)
{
- if (address.length() == 0)
+ int length = address.length();
+ if (length < 7 || length > 15)
{
return false;
}
- int octet;
- int octets = 0;
-
- String temp = address+".";
-
- int pos;
- int start = 0;
- while (start < temp.length()
- && (pos = temp.indexOf('.', start)) > start)
+ int pos = 0;
+ for (int octetIndex = 0; octetIndex < 3; ++octetIndex)
{
- if (octets == 4)
+ int end = address.indexOf('.', pos);
+
+ if (!isParseableIPv4Octet(address, pos, end))
{
return false;
}
- try
- {
- octet = Integer.parseInt(temp.substring(start, pos));
- }
- catch (NumberFormatException ex)
- {
- return false;
- }
- if (octet < 0 || octet > 255)
- {
- return false;
- }
- start = pos + 1;
- octets++;
+
+ pos = end + 1;
}
- return octets == 4;
+ return isParseableIPv4Octet(address, pos, length);
}
- public static boolean isValidIPv4WithNetmask(
- String address)
+ public static boolean isValidIPv4WithNetmask(String address)
{
int index = address.indexOf("/");
- String mask = address.substring(index + 1);
-
- return (index > 0) && isValidIPv4(address.substring(0, index))
- && (isValidIPv4(mask) || isMaskValue(mask, 32));
- }
-
- public static boolean isValidIPv6WithNetmask(
- String address)
- {
- int index = address.indexOf("/");
- String mask = address.substring(index + 1);
-
- return (index > 0) && (isValidIPv6(address.substring(0, index))
- && (isValidIPv6(mask) || isMaskValue(mask, 128)));
- }
-
- private static boolean isMaskValue(String component, int size)
- {
- try
- {
- int value = Integer.parseInt(component);
-
- return value >= 0 && value <= size;
- }
- catch (NumberFormatException e)
+ if (index < 1)
{
return false;
}
+
+ String before = address.substring(0, index);
+ String after = address.substring(index + 1);
+
+ return isValidIPv4(before) && (isValidIPv4(after) || isParseableIPv4Mask(after));
}
/**
@@ -120,72 +81,131 @@
*
* @return true if a valid IPv6 address, false otherwise
*/
- public static boolean isValidIPv6(
- String address)
+ public static boolean isValidIPv6(String address)
{
if (address.length() == 0)
{
return false;
}
- int octet;
- int octets = 0;
+ char firstChar = address.charAt(0);
+ if (firstChar != ':' && Character.digit(firstChar, 16) < 0)
+ {
+ return false;
+ }
+ int segmentCount = 0;
String temp = address + ":";
boolean doubleColonFound = false;
- int pos;
- int start = 0;
- while (start < temp.length()
- && (pos = temp.indexOf(':', start)) >= start)
+
+ int pos = 0, end;
+ while (pos < temp.length() && (end = temp.indexOf(':', pos)) >= pos)
{
- if (octets == 8)
+ if (segmentCount == 8)
{
return false;
}
- if (start != pos)
+ if (pos != end)
{
- String value = temp.substring(start, pos);
+ String value = temp.substring(pos, end);
- if (pos == (temp.length() - 1) && value.indexOf('.') > 0)
+ if (end == temp.length() - 1 && value.indexOf('.') > 0)
{
+ // add an extra one as address covers 2 words.
+ if (++segmentCount == 8)
+ {
+ return false;
+ }
if (!isValidIPv4(value))
{
return false;
}
-
- octets++; // add an extra one as address covers 2 words.
}
- else
+ else if (!isParseableIPv6Segment(temp, pos, end))
{
- try
- {
- octet = Integer.parseInt(temp.substring(start, pos), 16);
- }
- catch (NumberFormatException ex)
- {
- return false;
- }
- if (octet < 0 || octet > 0xffff)
- {
- return false;
- }
+ return false;
}
}
else
{
- if (pos != 1 && pos != temp.length() - 1 && doubleColonFound)
+ if (end != 1 && end != temp.length() - 1 && doubleColonFound)
{
return false;
}
doubleColonFound = true;
}
- start = pos + 1;
- octets++;
+
+ pos = end + 1;
+ ++segmentCount;
}
- return octets == 8 || doubleColonFound;
+ return segmentCount == 8 || doubleColonFound;
+ }
+
+ public static boolean isValidIPv6WithNetmask(String address)
+ {
+ int index = address.indexOf("/");
+ if (index < 1)
+ {
+ return false;
+ }
+
+ String before = address.substring(0, index);
+ String after = address.substring(index + 1);
+
+ return isValidIPv6(before) && (isValidIPv6(after) || isParseableIPv6Mask(after));
+ }
+
+ private static boolean isParseableIPv4Mask(String s)
+ {
+ return isParseable(s, 0, s.length(), 10, 2, false, 0, 32);
+ }
+
+ private static boolean isParseableIPv4Octet(String s, int pos, int end)
+ {
+ return isParseable(s, pos, end, 10, 3, true, 0, 255);
+ }
+
+ private static boolean isParseableIPv6Mask(String s)
+ {
+ return isParseable(s, 0, s.length(), 10, 3, false, 1, 128);
+ }
+
+ private static boolean isParseableIPv6Segment(String s, int pos, int end)
+ {
+ return isParseable(s, pos, end, 16, 4, true, 0x0000, 0xFFFF);
+ }
+
+ private static boolean isParseable(String s, int pos, int end, int radix, int maxLength, boolean allowLeadingZero,
+ int minValue, int maxValue)
+ {
+ int length = end - pos;
+ if (length < 1 | length > maxLength)
+ {
+ return false;
+ }
+
+ boolean checkLeadingZero = length > 1 & !allowLeadingZero;
+ if (checkLeadingZero && Character.digit(s.charAt(pos), radix) <= 0)
+ {
+ return false;
+ }
+
+ int value = 0;
+ while (pos < end)
+ {
+ char c = s.charAt(pos++);
+ int d = Character.digit(c, radix);
+ if (d < 0)
+ {
+ return false;
+ }
+
+ value *= radix;
+ value += d;
+ }
+
+ return value >= minValue & value <= maxValue;
}
}
-
-
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Integers.java b/bcprov/src/main/java/org/bouncycastle/util/Integers.java
index fdacb51..9af524b 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Integers.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Integers.java
@@ -1,10 +1,28 @@
package org.bouncycastle.util;
/**
- * Utility methods for ints.
+ * Utility methods and constants for ints.
*/
public class Integers
{
+ public static final int BYTES = 4;
+ public static final int SIZE = Integer.SIZE;
+
+ public static int bitCount(int i)
+ {
+ return Integer.bitCount(i);
+ }
+
+ public static int highestOneBit(int i)
+ {
+ return Integer.highestOneBit(i);
+ }
+
+ public static int lowestOneBit(int i)
+ {
+ return Integer.lowestOneBit(i);
+ }
+
public static int numberOfLeadingZeros(int i)
{
return Integer.numberOfLeadingZeros(i);
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Longs.java b/bcprov/src/main/java/org/bouncycastle/util/Longs.java
index 2e50210..443e310 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Longs.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Longs.java
@@ -1,7 +1,33 @@
package org.bouncycastle.util;
+/**
+ * Utility methods and constants for longs.
+ */
public class Longs
{
+ public static final int BYTES = 8;
+ public static final int SIZE = Long.SIZE;
+
+ public static long highestOneBit(long i)
+ {
+ return Long.highestOneBit(i);
+ }
+
+ public static long lowestOneBit(long i)
+ {
+ return Long.lowestOneBit(i);
+ }
+
+ public static int numberOfLeadingZeros(long i)
+ {
+ return Long.numberOfLeadingZeros(i);
+ }
+
+ public static int numberOfTrailingZeros(long i)
+ {
+ return Long.numberOfTrailingZeros(i);
+ }
+
public static long reverse(long i)
{
return Long.reverse(i);
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Memoable.java b/bcprov/src/main/java/org/bouncycastle/util/Memoable.java
index bf40f4e..a6eede9 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Memoable.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Memoable.java
@@ -2,7 +2,7 @@
/**
* Interface for Memoable objects. Memoable objects allow the taking of a snapshot of their internal state
- * via the copy() method and then reseting the object back to that state later using the reset() method.
+ * via the copy() method and then resetting the object back to that state later using the reset() method.
*/
public interface Memoable
{
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Pack.java b/bcprov/src/main/java/org/bouncycastle/util/Pack.java
index d0eeef4..a2ce48f 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Pack.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Pack.java
@@ -147,7 +147,6 @@
* @param bs The target.
* @param off Position in target to start.
* @param bytes number of bytes to write.
- *
* @deprecated Will be removed
*/
public static void longToBigEndian(long value, byte[] bs, int off, int bytes)
@@ -175,6 +174,25 @@
return n;
}
+ public static int littleEndianToInt_High(byte[] bs, int off, int len)
+ {
+ return littleEndianToInt_Low(bs, off, len) << ((4 - len) << 3);
+ }
+
+ public static int littleEndianToInt_Low(byte[] bs, int off, int len)
+ {
+// assert 1 <= len && len <= 4;
+
+ int result = bs[off] & 0xff;
+ int pos = 0;
+ for (int i = 1; i < len; ++i)
+ {
+ pos += 8;
+ result |= (bs[off + i] & 0xff) << pos;
+ }
+ return result;
+ }
+
public static void littleEndianToInt(byte[] bs, int off, int[] ns)
{
for (int i = 0; i < ns.length; ++i)
@@ -297,6 +315,40 @@
}
}
+ public static void longToLittleEndian_High(long n, byte[] bs, int off, int len)
+ {
+ //Debug.Assert(1 <= len && len <= 8);
+ int pos = 56;
+ bs[off] = (byte)(n >>> pos);
+ for (int i = 1; i < len; ++i)
+ {
+ pos -= 8;
+ bs[off + i] = (byte)(n >>> pos);
+ }
+ }
+
+// public static void longToLittleEndian_Low(long n, byte[] bs, int off, int len)
+// {
+// longToLittleEndian_High(n << ((8 - len) << 3), bs, off, len);
+// }
+
+ public static long littleEndianToLong_High(byte[] bs, int off, int len)
+ {
+ return littleEndianToLong_Low(bs, off, len) << ((8 - len) << 3);
+ }
+
+ public static long littleEndianToLong_Low(byte[] bs, int off, int len)
+ {
+ //Debug.Assert(1 <= len && len <= 8);
+ long result = bs[off] & 0xFF;
+ for (int i = 1; i < len; ++i)
+ {
+ result <<= 8;
+ result |= bs[off + i] & 0xFF;
+ }
+ return result;
+ }
+
public static byte[] longToLittleEndian(long n)
{
byte[] bs = new byte[8];
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Properties.java b/bcprov/src/main/java/org/bouncycastle/util/Properties.java
index b87d3ac..6630de9 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Properties.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Properties.java
@@ -13,10 +13,17 @@
import java.util.StringTokenizer;
/**
- * Utility method for accessing system properties.
+ * Utility method for accessing properties values - properties can be set in java.security,
+ * thread local, and system properties. They are checked for in the same order with
+ * checking stopped as soon as a value is found.
*/
public class Properties
{
+ /**
+ * If set the provider will attempt, where possible, to behave the same way as the oracle one.
+ */
+ public static final String EMULATE_ORACLE = "org.bouncycastle.emulate.oracle";
+
private Properties()
{
}
@@ -115,6 +122,31 @@
return false;
}
+ /**
+ * Return propertyName as an integer, defaultValue used if not defined.
+ *
+ * @param propertyName name of property.
+ * @param defaultValue integer to return if property not defined.
+ * @return value of property, or default if not found, as an int.
+ */
+ public static int asInteger(String propertyName, int defaultValue)
+ {
+ String p = getPropertyValue(propertyName);
+
+ if (p != null)
+ {
+ return Integer.parseInt(p);
+ }
+
+ return defaultValue;
+ }
+
+ /**
+ * Return propertyName as a BigInteger.
+ *
+ * @param propertyName name of property.
+ * @return value of property as a BigInteger, null if not defined.
+ */
public static BigInteger asBigInteger(String propertyName)
{
String p = getPropertyValue(propertyName);
@@ -145,6 +177,13 @@
return Collections.unmodifiableSet(set);
}
+ /**
+ * Return the String value of the property propertyName. Property valuation
+ * starts with java.security, then thread local, then system properties.
+ *
+ * @param propertyName name of property.
+ * @return value of property as a String, null if not defined.
+ */
public static String getPropertyValue(final String propertyName)
{
String val = (String)AccessController.doPrivileged(new PrivilegedAction()
@@ -178,6 +217,18 @@
});
}
+ public static String getPropertyValue(final String propertyName, String defValue)
+ {
+ String rv = getPropertyValue(propertyName);
+
+ if (rv == null)
+ {
+ return defValue;
+ }
+
+ return rv;
+ }
+
private static boolean isSetFalse(String p)
{
if (p == null || p.length() != 5)
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Strings.java b/bcprov/src/main/java/org/bouncycastle/util/Strings.java
index bda9d9a..a568149 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Strings.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Strings.java
@@ -56,6 +56,17 @@
return new String(chars, 0, len);
}
+ public static String fromUTF8ByteArray(byte[] bytes, int off, int length)
+ {
+ char[] chars = new char[length];
+ int len = UTF8.transcodeToUTF16(bytes, off, length, chars);
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Invalid UTF-8 input");
+ }
+ return new String(chars, 0, len);
+ }
+
public static byte[] toUTF8ByteArray(String string)
{
return toUTF8ByteArray(string.toCharArray());
@@ -228,6 +239,37 @@
}
/**
+ * Constant time string comparison.
+ *
+ * @param a a string.
+ * @param b another string to compare to a.
+ *
+ * @return true if a and b represent the same string, false otherwise.
+ */
+ public static boolean constantTimeAreEqual(String a, String b)
+ {
+ boolean isEqual = a.length() == b.length();
+ int len = a.length();
+
+ if (isEqual)
+ {
+ for (int i = 0; i != len; i++)
+ {
+ isEqual &= (a.charAt(i) == b.charAt(i));
+ }
+ }
+ else
+ {
+ for (int i = 0; i != len; i++)
+ {
+ isEqual &= (a.charAt(i) == ' ');
+ }
+ }
+
+ return isEqual;
+ }
+
+ /**
* Convert an array of 8 bit characters into a string.
*
* @param bytes 8 bit characters.
diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/Base32.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base32.java
new file mode 100644
index 0000000..a64502a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base32.java
@@ -0,0 +1,174 @@
+package org.bouncycastle.util.encoders;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.bouncycastle.util.Strings;
+
+/**
+ * Utility class for converting Base32 data to bytes and back again.
+ */
+public class Base32
+{
+ private static final Encoder encoder = new Base32Encoder();
+
+ public static String toBase32String(
+ byte[] data)
+ {
+ return toBase32String(data, 0, data.length);
+ }
+
+ public static String toBase32String(
+ byte[] data,
+ int off,
+ int length)
+ {
+ byte[] encoded = encode(data, off, length);
+ return Strings.fromByteArray(encoded);
+ }
+
+ /**
+ * encode the input data producing a base 32 encoded byte array.
+ *
+ * @return a byte array containing the base 32 encoded data.
+ */
+ public static byte[] encode(
+ byte[] data)
+ {
+ return encode(data, 0, data.length);
+ }
+
+ /**
+ * encode the input data producing a base 32 encoded byte array.
+ *
+ * @return a byte array containing the base 32 encoded data.
+ */
+ public static byte[] encode(
+ byte[] data,
+ int off,
+ int length)
+ {
+ int len = encoder.getEncodedLength(length);
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.encode(data, off, length, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new EncoderException("exception encoding base32 string: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * Encode the byte data to base 32 writing it to the given output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int encode(
+ byte[] data,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.encode(data, 0, data.length, out);
+ }
+
+ /**
+ * Encode the byte data to base 32 writing it to the given output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int encode(
+ byte[] data,
+ int off,
+ int length,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.encode(data, off, length, out);
+ }
+
+ /**
+ * decode the base 32 encoded input data. It is assumed the input data is valid.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ byte[] data)
+ {
+ int len = data.length / 8 * 5;
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.decode(data, 0, data.length, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base32 data: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * decode the base 32 encoded String data - whitespace will be ignored.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ String data)
+ {
+ int len = data.length() / 8 * 5;
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.decode(data, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base32 string: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * decode the base 32 encoded String data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int decode(
+ String data,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.decode(data, out);
+ }
+
+ /**
+ * Decode to an output stream;
+ *
+ * @param base32Data The source data.
+ * @param start Start position.
+ * @param length the length.
+ * @param out The output stream to write to.
+ */
+ public static int decode(byte[] base32Data, int start, int length, OutputStream out)
+ {
+ try
+ {
+ return encoder.decode(base32Data, start, length, out);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base32 data: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/Base32Encoder.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base32Encoder.java
new file mode 100644
index 0000000..d17ed98
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base32Encoder.java
@@ -0,0 +1,453 @@
+package org.bouncycastle.util.encoders;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+/**
+ * A streaming Base32 encoder.
+ */
+public class Base32Encoder
+ implements Encoder
+{
+ private static final byte[] DEAULT_ENCODING_TABLE =
+ {
+ (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+ (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+ (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+ (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+ (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7'
+ };
+
+ private static final byte DEFAULT_PADDING = (byte)'=';
+
+ /*
+ * set up the decoding table.
+ */
+ private final byte[] encodingTable;
+ private final byte padding;
+ private final byte[] decodingTable = new byte[128];
+
+ 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;
+ }
+ }
+
+ /**
+ * Base constructor for RFC 4648, Section 6.
+ */
+ public Base32Encoder()
+ {
+ this.encodingTable = DEAULT_ENCODING_TABLE;
+ this.padding = DEFAULT_PADDING;
+
+ initialiseDecodingTable();
+ }
+
+ /**
+ * Constructor allowing the setting of an alternative alphabet.
+ *
+ * @param encodingTable a 32 entry encoding table to do the mapping.
+ * @param padding the padding value to use.
+ */
+ public Base32Encoder(byte[] encodingTable, byte padding)
+ {
+ if (encodingTable.length != 32)
+ {
+ throw new IllegalArgumentException("encoding table needs to be length 32");
+ }
+
+ this.encodingTable = Arrays.clone(encodingTable);
+ this.padding = padding;
+
+ initialiseDecodingTable();
+ }
+
+ public int encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) throws IOException
+ {
+ int inPos = inOff;
+ int inEnd = inOff + inLen - 4;
+ int outPos = outOff;
+
+ while (inPos < inEnd)
+ {
+ encodeBlock(inBuf, inPos, outBuf, outPos);
+ inPos += 5;
+ outPos += 8;
+ }
+
+ int extra = inLen - (inPos - inOff);
+ if (extra > 0)
+ {
+ byte[] in = new byte[5];
+ System.arraycopy(inBuf, inPos, in, 0, extra);
+ encodeBlock(in, 0, outBuf, outPos);
+ switch (extra)
+ {
+ case 1:
+ outBuf[outPos + 2] = padding;
+ outBuf[outPos + 3] = padding;
+ outBuf[outPos + 4] = padding;
+ outBuf[outPos + 5] = padding;
+ outBuf[outPos + 6] = padding;
+ outBuf[outPos + 7] = padding;
+ break;
+ case 2:
+ outBuf[outPos + 4] = padding;
+ outBuf[outPos + 5] = padding;
+ outBuf[outPos + 6] = padding;
+ outBuf[outPos + 7] = padding;
+ break;
+ case 3:
+ outBuf[outPos + 5] = padding;
+ outBuf[outPos + 6] = padding;
+ outBuf[outPos + 7] = padding;
+ break;
+ case 4:
+ outBuf[outPos + 7] = padding;
+ break;
+ }
+
+ outPos += 8;
+ }
+
+ return outPos - outOff;
+ }
+
+ private void encodeBlock(byte[] inBuf, int inPos, byte[] outBuf, int outPos)
+ {
+ int a1 = inBuf[inPos++];
+ int a2 = inBuf[inPos++] & 0xFF;
+ int a3 = inBuf[inPos++] & 0xFF;
+ int a4 = inBuf[inPos++] & 0xFF;
+ int a5 = inBuf[inPos] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[(a1 >>> 3) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a1 << 2) | (a2 >>> 6)) & 0x1F];
+ outBuf[outPos++] = encodingTable[(a2 >>> 1) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a2 << 4) | (a3 >>> 4)) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a3 << 1) | (a4 >>> 7)) & 0x1F];
+ outBuf[outPos++] = encodingTable[(a4 >>> 2) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a4 << 3) | (a5 >>> 5)) & 0x1F];
+ outBuf[outPos] = encodingTable[a5 & 0x1F];
+ }
+
+ public int getEncodedLength(int inputLength)
+ {
+ return (inputLength + 4) / 5 * 8;
+ }
+
+ public int getMaxDecodedLength(int inputLength)
+ {
+ return inputLength / 8 * 5;
+ }
+
+ /**
+ * encode the input data producing a base 32 output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public int encode(byte[] buf, int off, int len, OutputStream out)
+ throws IOException
+ {
+ if (len < 0)
+ {
+ return 0;
+ }
+
+ byte[] tmp = new byte[72];
+ int remaining = len;
+ while (remaining > 0)
+ {
+ int inLen = Math.min(45, remaining);
+ int outLen = encode(buf, off, inLen, tmp, 0);
+ out.write(tmp, 0, outLen);
+ off += inLen;
+ remaining -= inLen;
+ }
+ return (len + 2) / 3 * 4;
+ }
+
+ private boolean ignore(
+ char c)
+ {
+ return (c == '\n' || c =='\r' || c == '\t' || c == ' ');
+ }
+
+ /**
+ * decode the base 32 encoded byte data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public int decode(
+ byte[] data,
+ int off,
+ int length,
+ OutputStream out)
+ throws IOException
+ {
+ byte b1, b2, b3, b4, b5, b6, b7, b8;
+ byte[] outBuffer = new byte[55];
+ int bufOff = 0;
+ int outLen = 0;
+
+ int end = off + length;
+
+ while (end > off)
+ {
+ if (!ignore((char)data[end - 1]))
+ {
+ break;
+ }
+
+ end--;
+ }
+
+ // empty data!
+ if (end == 0)
+ {
+ return 0;
+ }
+
+ int i = 0;
+ int finish = end;
+
+ while (finish > off && i != 8)
+ {
+ if (!ignore((char)data[finish - 1]))
+ {
+ i++;
+ }
+
+ finish--;
+ }
+
+ i = nextI(data, off, finish);
+
+ while (i < finish)
+ {
+ b1 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b2 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b3 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b4 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b5 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b6 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b7 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b8 = decodingTable[data[i++]];
+
+ if ((b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8) < 0)
+ {
+ throw new IOException("invalid characters encountered in base32 data");
+ }
+
+ outBuffer[bufOff++] = (byte)((b1 << 3) | (b2 >> 2));
+ outBuffer[bufOff++] = (byte)((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ outBuffer[bufOff++] = (byte)((b4 << 4) | (b5 >> 1));
+ outBuffer[bufOff++] = (byte)((b5 << 7) | (b6 << 2) | (b7 >> 3));
+ outBuffer[bufOff++] = (byte)((b7 << 5) | b8);
+
+ if (bufOff == outBuffer.length)
+ {
+ out.write(outBuffer);
+ bufOff = 0;
+ }
+
+ outLen += 5;
+
+ i = nextI(data, i, finish);
+ }
+
+ if (bufOff > 0)
+ {
+ out.write(outBuffer, 0, bufOff);
+ }
+
+ int e0 = nextI(data, i, end);
+ int e1 = nextI(data, e0 + 1, end);
+ int e2 = nextI(data, e1 + 1, end);
+ int e3 = nextI(data, e2 + 1, end);
+ int e4 = nextI(data, e3 + 1, end);
+ int e5 = nextI(data, e4 + 1, end);
+ int e6 = nextI(data, e5 + 1, end);
+ int e7 = nextI(data, e6 + 1, end);
+
+ outLen += decodeLastBlock(out,
+ (char)data[e0], (char)data[e1], (char)data[e2], (char)data[e3],
+ (char)data[e4], (char)data[e5], (char)data[e6], (char)data[e7]);
+
+ return outLen;
+ }
+
+ private int nextI(byte[] data, int i, int finish)
+ {
+ while ((i < finish) && ignore((char)data[i]))
+ {
+ i++;
+ }
+ return i;
+ }
+
+ /**
+ * decode the base 32 encoded String data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public int decode(
+ String data,
+ OutputStream out)
+ throws IOException
+ {
+ byte[] bytes = Strings.toByteArray(data);
+ return decode(bytes, 0, bytes.length, out);
+ }
+
+ private int decodeLastBlock(OutputStream out,
+ char c1, char c2, char c3, char c4,
+ char c5, char c6, char c7, char c8)
+ throws IOException
+ {
+ byte b1, b2, b3, b4, b5, b6, b7, b8;
+
+ if (c8 == padding)
+ {
+ if (c7 != padding)
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+ b5 = decodingTable[c5];
+ b6 = decodingTable[c6];
+ b7 = decodingTable[c7];
+
+ if ((b1 | b2 | b3 | b4 | b5 | b6 | b7) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ out.write((b4 << 4) | (b5 >> 1));
+ out.write((b5 << 7) | (b6 << 2) | (b7 >> 3));
+
+ return 4;
+ }
+ if (c6 != padding)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ if (c5 != padding)
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+ b5 = decodingTable[c5];
+
+ if ((b1 | b2 | b3 | b4 | b5) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ out.write((b4 << 4) | (b5 >> 1));
+
+ return 3;
+ }
+
+ if (c4 != padding)
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+
+ if ((b1 | b2 | b3 | b4) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+
+ return 2;
+ }
+
+ if (c3 != padding)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+
+ if ((b1 | b2) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+
+ return 1;
+ }
+ else
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+ b5 = decodingTable[c5];
+ b6 = decodingTable[c6];
+ b7 = decodingTable[c7];
+ b8 = decodingTable[c8];
+
+ if ((b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ out.write((b4 << 4) | (b5 >> 1));
+ out.write((b5 << 7) | (b6 << 2) | (b7 >> 3));
+ out.write((b7 << 5) | b8);
+
+ return 5;
+ }
+ }
+}
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 e3129f0..72e0a71 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64.java
@@ -49,7 +49,7 @@
int off,
int length)
{
- int len = (length + 2) / 3 * 4;
+ int len = encoder.getEncodedLength(length);
ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
try
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 1af4860..82c2343 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java
@@ -96,24 +96,40 @@
return outPos - outOff;
}
+ public int getEncodedLength(int inputLength)
+ {
+ return (inputLength + 2) / 3 * 4;
+ }
+
+ public int getMaxDecodedLength(int inputLength)
+ {
+ return inputLength / 4 * 3;
+ }
+
/**
* encode the input data producing a base 64 output stream.
*
* @return the number of bytes produced.
*/
- public int encode(byte[] buf, int off, int len, OutputStream out)
+ public int encode(byte[] buf, int off, int len, OutputStream out)
throws IOException
{
- byte[] tmp = new byte[72];
- while (len > 0)
+ if (len < 0)
{
- int inLen = Math.min(54, len);
+ return 0;
+ }
+
+ byte[] tmp = new byte[72];
+ int remaining = len;
+ while (remaining > 0)
+ {
+ int inLen = Math.min(54, remaining);
int outLen = encode(buf, off, inLen, tmp, 0);
out.write(tmp, 0, outLen);
off += inLen;
- len -= inLen;
+ remaining -= inLen;
}
- return ((len + 2) / 3) * 4;
+ return (len + 2) / 3 * 4;
}
private boolean ignore(
diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/Encoder.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/Encoder.java
index b066121..bb63b61 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/encoders/Encoder.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/Encoder.java
@@ -9,6 +9,23 @@
*/
public interface Encoder
{
+ /**
+ * Return the expected output length of the encoding.
+ *
+ * @param inputLength the input length of the data.
+ * @return the output length of an encoding.
+ */
+ int getEncodedLength(int inputLength);
+
+ /**
+ * Return the maximum expected output length of a decoding. If padding
+ * is present the value returned will be greater than the decoded data length.
+ *
+ * @param inputLength the input length of the encoded data.
+ * @return the upper bound of the output length of a decoding.
+ */
+ int getMaxDecodedLength(int inputLength);
+
int encode(byte[] data, int off, int length, OutputStream out) throws IOException;
int decode(byte[] data, int off, int length, OutputStream out) throws IOException;
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 6bdafaf..8823189 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java
@@ -62,6 +62,16 @@
return outPos - outOff;
}
+ public int getEncodedLength(int inputLength)
+ {
+ return inputLength * 2;
+ }
+
+ public int getMaxDecodedLength(int inputLength)
+ {
+ return inputLength / 2;
+ }
+
/**
* encode the input data producing a Hex output stream.
*
@@ -70,14 +80,20 @@
public int encode(byte[] buf, int off, int len, OutputStream out)
throws IOException
{
- byte[] tmp = new byte[72];
- while (len > 0)
+ if (len < 0)
{
- int inLen = Math.min(36, len);
+ return 0;
+ }
+
+ byte[] tmp = new byte[72];
+ int remaining = len;
+ while (remaining > 0)
+ {
+ int inLen = Math.min(36, remaining);
int outLen = encode(buf, off, inLen, tmp, 0);
out.write(tmp, 0, outLen);
off += inLen;
- len -= inLen;
+ remaining -= inLen;
}
return len * 2;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/UTF8.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/UTF8.java
index e64e443..cd9073d 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/encoders/UTF8.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/UTF8.java
@@ -2,7 +2,7 @@
/**
* Utilities for working with UTF-8 encodings.
- *
+ * <p>
* Decoding of UTF-8 is based on a presentation by Bob Steagall at CppCon2018 (see
* https://github.com/BobSteagall/CppCon2018). It uses a Deterministic Finite Automaton (DFA) to
* recognize and decode multi-byte code points.
@@ -71,8 +71,8 @@
fill(transitionTable, S_P4A + 0x9, S_P4A + 0xB, S_CS2);
fill(transitionTable, S_P4B + 0x8, S_P4B + 0x8, S_CS2);
- byte[] firstUnitMasks = { 0x00, 0x00, 0x00, 0x00, 0x1F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07 };
- byte[] firstUnitTransitions = { S_ERR, S_ERR, S_ERR, S_ERR, S_CS1, S_P3A, S_CS2, S_P3B, S_P4A, S_CS3, S_P4B };
+ byte[] firstUnitMasks = {0x00, 0x00, 0x00, 0x00, 0x1F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07};
+ byte[] firstUnitTransitions = {S_ERR, S_ERR, S_ERR, S_ERR, S_CS1, S_P3A, S_CS2, S_P3B, S_P4A, S_CS3, S_P4B};
for (int i = 0x00; i < 0x80; ++i)
{
@@ -94,26 +94,52 @@
* "overlong" encodings, and unmappable code points. In particular, no unmatched surrogates will
* be produced. An error will also result if {@code utf16} is found to be too small to store the
* complete output.
- *
- * @param utf8
- * A non-null array containing a well-formed UTF-8 encoding.
- * @param utf16
- * A non-null array, at least as long as the {@code utf8} array in order to ensure
- * the output will fit.
+ *
+ * @param utf8 A non-null array containing a well-formed UTF-8 encoding.
+ * @param utf16 A non-null array, at least as long as the {@code utf8} array in order to ensure
+ * the output will fit.
* @return The number of UTF-16 code units written to {@code utf16} (beginning from index 0), or
- * else -1 if the input was either malformed or encoded any unmappable characters, or if
- * the {@code utf16} is too small.
+ * else -1 if the input was either malformed or encoded any unmappable characters, or if
+ * the {@code utf16} is too small.
*/
public static int transcodeToUTF16(byte[] utf8, char[] utf16)
{
- int i = 0, j = 0;
+ return transcodeToUTF16(utf8, 0, utf8.length, utf16);
+ }
- while (i < utf8.length)
+ /**
+ * Transcode a UTF-8 encoding into a UTF-16 representation. In the general case the output
+ * {@code utf16} array should be at least as long as the input length from {@code utf8} to handle
+ * arbitrary inputs. The number of output UTF-16 code units is returned, or -1 if any errors are
+ * encountered (in which case an arbitrary amount of data may have been written into the output
+ * array). Errors that will be detected are malformed UTF-8, including incomplete, truncated or
+ * "overlong" encodings, and unmappable code points. In particular, no unmatched surrogates will
+ * be produced. An error will also result if {@code utf16} is found to be too small to store the
+ * complete output.
+ *
+ * @param utf8 A non-null array containing a well-formed UTF-8 encoding.
+ * @param utf8Off start position in the array for the well-formed encoding.
+ * @param utf8Length length in bytes of the well-formed encoding.
+ * @param utf16 A non-null array, at least as long as the {@code utf8} array in order to ensure
+ * the output will fit.
+ * @return The number of UTF-16 code units written to {@code utf16} (beginning from index 0), or
+ * else -1 if the input was either malformed or encoded any unmappable characters, or if
+ * the {@code utf16} is too small.
+ */
+ public static int transcodeToUTF16(byte[] utf8, int utf8Off, int utf8Length, char[] utf16)
+ {
+ int i = utf8Off, j = 0;
+ int maxI = utf8Off + utf8Length;
+
+ while (i < maxI)
{
byte codeUnit = utf8[i++];
if (codeUnit >= 0)
{
- if (j >= utf16.length) { return -1; }
+ if (j >= utf16.length)
+ {
+ return -1;
+ }
utf16[j++] = (char)codeUnit;
continue;
@@ -125,25 +151,37 @@
while (state >= 0)
{
- if (i >= utf8.length) { return -1; }
+ if (i >= maxI)
+ {
+ return -1;
+ }
codeUnit = utf8[i++];
codePoint = (codePoint << 6) | (codeUnit & 0x3F);
state = transitionTable[state + ((codeUnit & 0xFF) >>> 4)];
}
- if (state == S_ERR) { return -1; }
+ if (state == S_ERR)
+ {
+ return -1;
+ }
if (codePoint <= 0xFFFF)
{
- if (j >= utf16.length) { return -1; }
+ if (j >= utf16.length)
+ {
+ return -1;
+ }
// Code points from U+D800 to U+DFFF are caught by the DFA
utf16[j++] = (char)codePoint;
}
else
{
- if (j >= utf16.length - 1) { return -1; }
+ if (j >= utf16.length - 1)
+ {
+ return -1;
+ }
// Code points above U+10FFFF are caught by the DFA
utf16[j++] = (char)(0xD7C0 + (codePoint >>> 10));
diff --git a/bcprov/src/main/java/org/bouncycastle/util/io/Streams.java b/bcprov/src/main/java/org/bouncycastle/util/io/Streams.java
index adb158f..c72a476 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/io/Streams.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/io/Streams.java
@@ -28,6 +28,64 @@
}
/**
+ * Write the full contents of inStr to the destination stream outStr.
+ *
+ * @param inStr source input stream.
+ * @param outStr destination output stream.
+ * @throws IOException in case of underlying IOException.
+ */
+ public static void pipeAll(InputStream inStr, OutputStream outStr)
+ throws IOException
+ {
+ pipeAll(inStr, outStr, BUFFER_SIZE);
+ }
+
+ /**
+ * Write the full contents of inStr to the destination stream outStr.
+ *
+ * @param inStr source input stream.
+ * @param outStr destination output stream.
+ * @param bufferSize the size of temporary buffer to use.
+ * @throws IOException in case of underlying IOException.
+ */
+ public static void pipeAll(InputStream inStr, OutputStream outStr, int bufferSize)
+ throws IOException
+ {
+ byte[] bs = new byte[bufferSize];
+ int numRead;
+ while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ {
+ outStr.write(bs, 0, numRead);
+ }
+ }
+
+ /**
+ * Write up to limit bytes of data from inStr to the destination stream outStr.
+ *
+ * @param inStr source input stream.
+ * @param limit the maximum number of bytes allowed to be read.
+ * @param outStr destination output stream.
+ * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it.
+ */
+ public static long pipeAllLimited(InputStream inStr, long limit, OutputStream outStr)
+ throws IOException
+ {
+ long total = 0;
+ byte[] bs = new byte[BUFFER_SIZE];
+ int numRead;
+ while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ {
+ if ((limit - total) < numRead)
+ {
+ throw new StreamOverflowException("Data Overflow");
+ }
+ total += numRead;
+ outStr.write(bs, 0, numRead);
+ }
+ return total;
+ }
+
+ /**
* Read stream fully, returning contents in a byte array.
*
* @param inStr stream to be read.
@@ -96,51 +154,22 @@
}
totalRead += numRead;
}
+
return totalRead;
}
- /**
- * Write the full contents of inStr to the destination stream outStr.
- *
- * @param inStr source input stream.
- * @param outStr destination output stream.
- * @throws IOException in case of underlying IOException.
- */
- public static void pipeAll(InputStream inStr, OutputStream outStr)
- throws IOException
+ public static void validateBufferArguments(byte[] buf, int off, int len)
{
- byte[] bs = new byte[BUFFER_SIZE];
- int numRead;
- while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ if (buf == null)
{
- outStr.write(bs, 0, numRead);
+ throw new NullPointerException();
}
- }
-
- /**
- * Write up to limit bytes of data from inStr to the destination stream outStr.
- *
- * @param inStr source input stream.
- * @param limit the maximum number of bytes allowed to be read.
- * @param outStr destination output stream.
- * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it.
- */
- public static long pipeAllLimited(InputStream inStr, long limit, OutputStream outStr)
- throws IOException
- {
- long total = 0;
- byte[] bs = new byte[BUFFER_SIZE];
- int numRead;
- while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ int available = buf.length - off;
+ int remaining = available - len;
+ if ((off | len | available | remaining) < 0)
{
- if ((limit - total) < numRead)
- {
- throw new StreamOverflowException("Data Overflow");
- }
- total += numRead;
- outStr.write(bs, 0, numRead);
+ throw new IndexOutOfBoundsException();
}
- return total;
}
public static void writeBufTo(ByteArrayOutputStream buf, OutputStream output)
diff --git a/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemReader.java b/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemReader.java
index 6616fec..7156818 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemReader.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemReader.java
@@ -64,9 +64,9 @@
while ((line = readLine()) != null)
{
- if (line.indexOf(":") >= 0)
+ int index = line.indexOf(':');
+ if (index >= 0)
{
- int index = line.indexOf(':');
String hdr = line.substring(0, index);
String value = line.substring(index + 1).trim();
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java b/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java
index 96a899b..8eb5e98 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java
@@ -21,12 +21,12 @@
import java.util.List;
import java.util.Set;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Sequence;
-import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.x509.AttributeCertificate;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
@@ -123,7 +123,7 @@
public boolean[] getIssuerUniqueID()
{
- DERBitString id = cert.getAcinfo().getIssuerUniqueID();
+ ASN1BitString id = cert.getAcinfo().getIssuerUniqueID();
if (id != null)
{
diff --git a/bcprov/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java b/bcprov/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java
index aaf2f5b..8f243ae 100644
--- a/bcprov/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java
+++ b/bcprov/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java
@@ -1,5 +1,5 @@
-package org.bouncycastle.math.ec.test;
+package org.bouncycastle.math.ec.test;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
@@ -9,7 +9,6 @@
import java.util.List;
import java.util.Random;
import java.util.Set;
-
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
@@ -27,9 +26,7 @@
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.Integers;
import org.bouncycastle.util.encoders.Hex;
-
import android.platform.test.annotations.LargeTest;
-
/**
* Test class for {@link org.bouncycastle.math.ec.ECPoint ECPoint}. All
* literature values are taken from "Guide to elliptic curve cryptography",
@@ -42,34 +39,22 @@
* Random source used to generate random points
*/
private SecureRandom secRand = new SecureRandom();
-
private ECPointTest.Fp fp = null;
-
private ECPointTest.F2m f2m = null;
-
/**
* Nested class containing sample literature values for <code>Fp</code>.
*/
public static class Fp
{
private final BigInteger q = new BigInteger("1063");
-
private final BigInteger a = new BigInteger("4");
-
private final BigInteger b = new BigInteger("20");
-
private final BigInteger n = new BigInteger("38");
-
private final BigInteger h = new BigInteger("1");
-
private final ECCurve curve = new ECCurve.Fp(q, a, b, n, h);
-
private final ECPoint infinity = curve.getInfinity();
-
private final int[] pointSource = { 1, 5, 4, 10, 234, 1024, 817, 912 };
-
private ECPoint[] p = new ECPoint[pointSource.length / 2];
-
/**
* Creates the points on the curve with literature values.
*/
@@ -83,7 +68,6 @@
}
}
}
-
/**
* Nested class containing sample literature values for <code>F2m</code>.
*/
@@ -91,28 +75,18 @@
{
// Irreducible polynomial for TPB z^4 + z + 1
private final int m = 4;
-
private final int k1 = 1;
-
// a = z^3
private final BigInteger aTpb = new BigInteger("1000", 2);
-
// b = z^3 + 1
private final BigInteger bTpb = new BigInteger("1001", 2);
-
private final BigInteger n = new BigInteger("23");
-
private final BigInteger h = new BigInteger("1");
-
private final ECCurve.F2m curve = new ECCurve.F2m(m, k1, aTpb, bTpb, n, h);
-
private final ECPoint.F2m infinity = (ECPoint.F2m) curve.getInfinity();
-
private final String[] pointSource = { "0010", "1111", "1100", "1100",
"0001", "0001", "1011", "0010" };
-
private ECPoint[] p = new ECPoint[pointSource.length / 2];
-
/**
* Creates the points on the curve with literature values.
*/
@@ -126,16 +100,13 @@
}
}
}
-
public void setUp()
{
fp = new ECPointTest.Fp();
fp.createPoints();
-
f2m = new ECPointTest.F2m();
f2m.createPoints();
}
-
/**
* Tests, if inconsistent points can be created, i.e. points with exactly
* one null coordinate (not permitted).
@@ -150,7 +121,6 @@
catch (IllegalArgumentException expected)
{
}
-
try
{
ECPoint bad = fp.curve.createPoint(null, new BigInteger("12"));
@@ -159,7 +129,6 @@
catch (IllegalArgumentException expected)
{
}
-
try
{
ECPoint bad = f2m.curve.createPoint(new BigInteger("1011"), null);
@@ -168,7 +137,6 @@
catch (IllegalArgumentException expected)
{
}
-
try
{
ECPoint bad = f2m.curve.createPoint(null, new BigInteger("1011"));
@@ -178,7 +146,6 @@
{
}
}
-
/**
* Tests <code>ECPoint.add()</code> against literature values.
*
@@ -197,7 +164,6 @@
assertPointsEqual("Adding to infinity failed", p[i], infinity.add(p[i]));
}
}
-
/**
* Calls <code>implTestAdd()</code> for <code>Fp</code> and
* <code>F2m</code>.
@@ -207,7 +173,6 @@
implTestAdd(fp.p, fp.infinity);
implTestAdd(f2m.p, f2m.infinity);
}
-
/**
* Tests <code>ECPoint.twice()</code> against literature values.
*
@@ -219,7 +184,6 @@
assertPointsEqual("Twice incorrect", p[3], p[0].twice());
assertPointsEqual("Add same point incorrect", p[3], p[0].add(p[0]));
}
-
/**
* Calls <code>implTestTwice()</code> for <code>Fp</code> and
* <code>F2m</code>.
@@ -229,7 +193,6 @@
implTestTwice(fp.p);
implTestTwice(f2m.p);
}
-
private void implTestThreeTimes(ECPoint[] p)
{
ECPoint P = p[0];
@@ -237,7 +200,6 @@
assertPointsEqual("ThreeTimes incorrect", _3P, P.threeTimes());
assertPointsEqual("TwicePlus incorrect", _3P, P.twicePlus(P));
}
-
/**
* Calls <code>implTestThreeTimes()</code> for <code>Fp</code> and
* <code>F2m</code>.
@@ -247,7 +209,6 @@
implTestThreeTimes(fp.p);
implTestThreeTimes(f2m.p);
}
-
/**
* Goes through all points on an elliptic curve and checks, if adding a
* point <code>k</code>-times is the same as multiplying the point by
@@ -263,7 +224,6 @@
{
ECPoint adder = infinity;
ECPoint multiplier = infinity;
-
BigInteger i = BigInteger.valueOf(1);
do
{
@@ -275,7 +235,6 @@
}
while (!(adder.equals(infinity)));
}
-
/**
* Calls <code>implTestAllPoints()</code> for the small literature curves,
* both for <code>Fp</code> and <code>F2m</code>.
@@ -286,13 +245,11 @@
{
implTestAllPoints(fp.p[i], fp.infinity);
}
-
for (int i = 0; i < f2m.p.length; i++)
{
implTestAllPoints(f2m.p[i], f2m.infinity);
}
}
-
/**
* Checks, if the point multiplication algorithm of the given point yields
* the same result as point multiplication done by the reference
@@ -312,7 +269,6 @@
ECPoint q = p.multiply(k);
assertPointsEqual("ECPoint.multiply is incorrect", ref, q);
}
-
/**
* Checks, if the point multiplication algorithm of the given point yields
* the same result as point multiplication done by the reference
@@ -329,7 +285,6 @@
{
BigInteger bound = BigInteger.ONE.shiftLeft(numBits);
BigInteger k = BigInteger.ZERO;
-
do
{
ECPoint ref = ECAlgorithms.referenceMultiply(p, k);
@@ -339,7 +294,6 @@
}
while (k.compareTo(bound) < 0);
}
-
/**
* Tests <code>ECPoint.add()</code> and <code>ECPoint.subtract()</code>
* for the given point and the given point at infinity.
@@ -360,7 +314,6 @@
assertPointsEqual("infinity plus infinity is not infinity ", infinity, infinity.add(infinity));
assertPointsEqual("Twice infinity is not infinity ", infinity, infinity.twice());
}
-
/**
* Calls <code>implTestAddSubtract()</code> for literature values, both
* for <code>Fp</code> and <code>F2m</code>.
@@ -371,21 +324,17 @@
for (int iFp = 0; iFp < fp.pointSource.length / 2; iFp++)
{
implTestAddSubtract(fp.p[iFp], fp.infinity);
-
implTestMultiplyAll(fp.p[iFp], fpBits);
implTestMultiplyAll(fp.infinity, fpBits);
}
-
int f2mBits = f2m.curve.getOrder().bitLength();
for (int iF2m = 0; iF2m < f2m.pointSource.length / 2; iF2m++)
{
implTestAddSubtract(f2m.p[iF2m], f2m.infinity);
-
implTestMultiplyAll(f2m.p[iF2m], f2mBits);
implTestMultiplyAll(f2m.infinity, f2mBits);
}
}
-
/**
* Test encoding with and without point compression.
*
@@ -398,25 +347,20 @@
byte[] unCompBarr = p.getEncoded(false);
ECPoint decUnComp = p.getCurve().decodePoint(unCompBarr);
assertPointsEqual("Error decoding uncompressed point", p, decUnComp);
-
// Point compression
byte[] compBarr = p.getEncoded(true);
ECPoint decComp = p.getCurve().decodePoint(compBarr);
assertPointsEqual("Error decoding compressed point", p, decComp);
}
-
private void implAddSubtractMultiplyTwiceEncodingTest(ECCurve curve, ECPoint q, BigInteger n)
{
// Get point at infinity on the curve
ECPoint infinity = curve.getInfinity();
-
implTestAddSubtract(q, infinity);
implTestMultiply(q, n.bitLength());
implTestMultiply(infinity, n.bitLength());
-
int logSize = 32 - Integers.numberOfLeadingZeros(curve.getFieldSize() - 1);
int rounds = Math.max(2, Math.min(10, 32 - 3 * logSize));
-
ECPoint p = q;
for (int i = 0; i < rounds; ++i)
{
@@ -424,7 +368,6 @@
p = p.twice();
}
}
-
private void implSqrtTest(ECCurve c)
{
if (ECAlgorithms.isFpCurve(c))
@@ -432,19 +375,15 @@
BigInteger p = c.getField().getCharacteristic();
BigInteger pMinusOne = p.subtract(ECConstants.ONE);
BigInteger legendreExponent = p.shiftRight(1);
-
ECFieldElement zero = c.fromBigInteger(BigInteger.ZERO);
assertEquals(zero, zero.sqrt());
-
ECFieldElement one = c.fromBigInteger(BigInteger.ONE);
assertEquals(one, one.sqrt());
-
for (int i = 0; i < 20; ++i)
{
BigInteger x = BigIntegers.createRandomInRange(ECConstants.TWO, pMinusOne, secRand);
ECFieldElement fe = c.fromBigInteger(x);
ECFieldElement root = fe.sqrt();
-
if (root == null)
{
assertEquals(pMinusOne, x.modPow(legendreExponent, p));
@@ -469,11 +408,9 @@
}
}
}
-
private void implValidityTest(ECCurve c, ECPoint g)
{
assertTrue(g.isValid());
-
if (ECAlgorithms.isF2mCurve(c))
{
BigInteger h = c.getCofactor();
@@ -489,7 +426,6 @@
assertFalse(bad2.isValid());
ECPoint good2 = bad2.add(order2);
assertTrue(good2.isValid());
-
if (!h.testBit(1))
{
ECFieldElement L = solveQuadraticEquation(c, c.getA());
@@ -513,13 +449,11 @@
}
}
}
-
private void implAddSubtractMultiplyTwiceEncodingTestAllCoords(X9ECParameters x9ECParameters)
{
BigInteger n = x9ECParameters.getN();
ECPoint G = x9ECParameters.getG();
ECCurve C = x9ECParameters.getCurve();
-
int[] coords = ECCurve.getAllCoordinateSystems();
for (int i = 0; i < coords.length; ++i)
{
@@ -528,26 +462,20 @@
{
ECCurve c = C;
ECPoint g = G;
-
if (c.getCoordinateSystem() != coord)
{
c = C.configure().setCoordinateSystem(coord).create();
g = c.importPoint(G);
}
-
// The generator is multiplied by random b to get random q
BigInteger b = new BigInteger(n.bitLength(), secRand);
ECPoint q = g.multiply(b).normalize();
-
implAddSubtractMultiplyTwiceEncodingTest(c, q, n);
-
implSqrtTest(c);
-
implValidityTest(c, g);
}
}
}
-
/**
* Calls <code>implTestAddSubtract()</code>,
* <code>implTestMultiply</code> and <code>implTestEncoding</code> for
@@ -558,15 +486,12 @@
{
Set names = new HashSet(enumToList(ECNamedCurveTable.getNames()));
names.addAll(enumToList(CustomNamedCurves.getNames()));
-
Iterator it = names.iterator();
while (it.hasNext())
{
String name = (String)it.next();
-
X9ECParameters x9A = ECNamedCurveTable.getByName(name);
X9ECParameters x9B = CustomNamedCurves.getByName(name);
-
if (x9A != null && x9B != null)
{
assertEquals(x9A.getCurve().getField(), x9B.getCurve().getField());
@@ -574,31 +499,25 @@
assertEquals(x9A.getCurve().getB().toBigInteger(), x9B.getCurve().getB().toBigInteger());
assertOptionalValuesAgree(x9A.getCurve().getCofactor(), x9B.getCurve().getCofactor());
assertOptionalValuesAgree(x9A.getCurve().getOrder(), x9B.getCurve().getOrder());
-
assertPointsEqual("Custom curve base-point inconsistency", x9A.getG(), x9B.getG());
-
assertEquals(x9A.getH(), x9B.getH());
assertEquals(x9A.getN(), x9B.getN());
assertOptionalValuesAgree(x9A.getSeed(), x9B.getSeed());
-
BigInteger k = new BigInteger(x9A.getN().bitLength(), secRand);
ECPoint pA = x9A.getG().multiply(k);
ECPoint pB = x9B.getG().multiply(k);
assertPointsEqual("Custom curve multiplication inconsistency", pA, pB);
}
-
if (x9A != null)
{
implAddSubtractMultiplyTwiceEncodingTestAllCoords(x9A);
}
-
if (x9B != null)
{
implAddSubtractMultiplyTwiceEncodingTestAllCoords(x9B);
}
}
}
-
public void testExampleFpB0() throws Exception
{
/*
@@ -619,9 +538,7 @@
byte[] S = null;
BigInteger n = p.add(BigInteger.valueOf(1)).shiftRight(2);
BigInteger h = BigInteger.valueOf(4);
-
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
-
X9ECPoint G = configureBasepoint(curve, "04"
// Px
+ "53FC09EE332C29AD0A7990053ED9B52A"
@@ -641,19 +558,15 @@
+ "AC6F1E80164AA989492D979FC5A4D5F2"
+ "13515AD7E9CB99A980BDAD5AD5BB4636"
+ "ADB9B5706A67DCDE75573FD71BEF16D7");
-
X9ECParameters x9 = new X9ECParameters(curve, G, n, h, S);
-
implAddSubtractMultiplyTwiceEncodingTestAllCoords(x9);
}
-
private void assertPointsEqual(String message, ECPoint a, ECPoint b)
{
// NOTE: We intentionally test points for equality in both directions
assertEquals(message, a, b);
assertEquals(message, b, a);
}
-
private void assertOptionalValuesAgree(Object a, Object b)
{
if (a != null && b != null)
@@ -661,7 +574,6 @@
assertEquals(a, b);
}
}
-
private void assertOptionalValuesAgree(byte[] a, byte[] b)
{
if (a != null && b != null)
@@ -669,46 +581,37 @@
assertTrue(Arrays.areEqual(a, b));
}
}
-
private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
{
X9ECPoint G = new X9ECPoint(curve, Hex.decode(encoding));
WNafUtil.configureBasepoint(G.getPoint());
return G;
}
-
private static ECCurve configureCurve(ECCurve curve)
{
return curve;
}
-
private List enumToList(Enumeration en)
{
List rv = new ArrayList();
-
while (en.hasMoreElements())
{
rv.add(en.nextElement());
}
-
return rv;
}
-
private static BigInteger fromHex(
String hex)
{
return new BigInteger(1, Hex.decode(hex));
}
-
private static ECFieldElement solveQuadraticEquation(ECCurve c, ECFieldElement rhs)
{
if (rhs.isZero())
{
return rhs;
}
-
ECFieldElement gamma, z, zeroElement = c.fromBigInteger(ECConstants.ZERO);
-
int m = c.getFieldSize();
Random rand = new Random();
do
@@ -729,12 +632,11 @@
gamma = z.square().add(z);
}
while (gamma.isZero());
-
return z;
}
-
public static Test suite()
{
return new TestSuite(ECPointTest.class);
}
}
+
diff --git a/bouncycastle.version b/bouncycastle.version
index bab63ae..b2db47f 100644
--- a/bouncycastle.version
+++ b/bouncycastle.version
@@ -1,2 +1,2 @@
-BOUNCYCASTLE_JDK=15on
-BOUNCYCASTLE_VERSION=168
+BOUNCYCASTLE_JDK=18on
+BOUNCYCASTLE_VERSION=177
diff --git a/proguard.flags b/proguard.flags
index 4a4ff37..1dae437 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -167,6 +167,7 @@
-keep class com.android.org.bouncycastle.math.ec.ECAlgorithms { public *; }
-keep class com.android.org.bouncycastle.math.ec.ECCurve { public *; }
-keep class com.android.org.bouncycastle.math.ec.ECCurve$Config { public *; }
+-keep class com.android.org.bouncycastle.math.ec.ECCurve$Fp { public *; }
-keep class com.android.org.bouncycastle.math.ec.ECPoint { public *; }
-keep class com.android.org.bouncycastle.math.ec.FixedPointCombMultiplier { public *; }
-keep class com.android.org.bouncycastle.math.raw.Interleave { public *; }
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Absent.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Absent.java
new file mode 100644
index 0000000..d6054e2
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Absent.java
@@ -0,0 +1,47 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * An ASN1 class that encodes to nothing, used in the OER library to deal with the Optional type.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1Absent
+ extends ASN1Primitive
+{
+
+ public static final ASN1Absent INSTANCE = new ASN1Absent();
+
+ private ASN1Absent()
+ {
+
+ }
+
+ public int hashCode()
+ {
+ return 0;
+ }
+
+ boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength(boolean withTag)
+ throws IOException
+ {
+ return 0;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag)
+ throws IOException
+ {
+
+ }
+
+ boolean asn1Equals(ASN1Primitive o)
+ {
+ return o == this;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ApplicationSpecific.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
deleted file mode 100644
index 60cc233..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.encoders.Hex;
-
-/**
- * Base class for an ASN.1 ApplicationSpecific object
- * @hide This class is not part of the Android public SDK API
- */
-public abstract class ASN1ApplicationSpecific
- extends ASN1Primitive
-{
- protected final boolean isConstructed;
- protected final int tag;
- protected final byte[] octets;
-
- ASN1ApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- this.isConstructed = isConstructed;
- this.tag = tag;
- this.octets = Arrays.clone(octets);
- }
-
- /**
- * Return an ASN1ApplicationSpecific from the passed in object, which may be a byte array, or null.
- *
- * @param obj the object to be converted.
- * @return obj's representation as an ASN1ApplicationSpecific object.
- */
- public static ASN1ApplicationSpecific getInstance(Object obj)
- {
- if (obj == null || obj instanceof ASN1ApplicationSpecific)
- {
- return (ASN1ApplicationSpecific)obj;
- }
- else if (obj instanceof byte[])
- {
- try
- {
- return ASN1ApplicationSpecific.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("Failed to construct object from byte[]: " + e.getMessage());
- }
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
- }
-
- protected static int getLengthOfHeader(byte[] data)
- {
- int length = data[1] & 0xff; // TODO: assumes 1 byte tag
-
- if (length == 0x80)
- {
- return 2; // indefinite-length encoding
- }
-
- if (length > 127)
- {
- int size = length & 0x7f;
-
- // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
- if (size > 4)
- {
- throw new IllegalStateException("DER length more than 4 bytes: " + size);
- }
-
- return size + 2;
- }
-
- return 2;
- }
-
- /**
- * Return true if the object is marked as constructed, false otherwise.
- *
- * @return true if constructed, otherwise false.
- */
- public boolean isConstructed()
- {
- return isConstructed;
- }
-
- /**
- * Return the contents of this object as a byte[]
- *
- * @return the encoded contents of the object.
- */
- public byte[] getContents()
- {
- return Arrays.clone(octets);
- }
-
- /**
- * Return the tag number associated with this object,
- *
- * @return the application tag number.
- */
- public int getApplicationTag()
- {
- return tag;
- }
-
- /**
- * Return the enclosed object assuming explicit tagging.
- *
- * @return the resulting object
- * @throws IOException if reconstruction fails.
- */
- public ASN1Primitive getObject()
- throws IOException
- {
- return ASN1Primitive.fromByteArray(getContents());
- }
-
- /**
- * Return the enclosed object assuming implicit tagging.
- *
- * @param derTagNo the type tag that should be applied to the object's contents.
- * @return the resulting object
- * @throws IOException if reconstruction fails.
- */
- public ASN1Primitive getObject(int derTagNo)
- throws IOException
- {
- if (derTagNo >= 0x1f)
- {
- throw new IOException("unsupported tag number");
- }
-
- byte[] orig = this.getEncoded();
- byte[] tmp = replaceTagNumber(derTagNo, orig);
-
- if ((orig[0] & BERTags.CONSTRUCTED) != 0)
- {
- tmp[0] |= BERTags.CONSTRUCTED;
- }
-
- return ASN1Primitive.fromByteArray(tmp);
- }
-
- int encodedLength()
- throws IOException
- {
- return StreamUtil.calculateTagLength(tag) + StreamUtil.calculateBodyLength(octets.length) + octets.length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncoded(withTag, flags, tag, octets);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof ASN1ApplicationSpecific))
- {
- return false;
- }
-
- ASN1ApplicationSpecific other = (ASN1ApplicationSpecific)o;
-
- return isConstructed == other.isConstructed
- && tag == other.tag
- && Arrays.areEqual(octets, other.octets);
- }
-
- public int hashCode()
- {
- return (isConstructed ? 1 : 0) ^ tag ^ Arrays.hashCode(octets);
- }
-
- private byte[] replaceTagNumber(int newTag, byte[] input)
- throws IOException
- {
- int tagNo = input[0] & 0x1f;
- int index = 1;
- //
- // with tagged object tag number is bottom 5 bits, or stored at the start of the content
- //
- if (tagNo == 0x1f)
- {
- int b = input[index++] & 0xff;
-
- // X.690-0207 8.1.2.4.2
- // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
- if ((b & 0x7f) == 0) // Note: -1 will pass
- {
- throw new IOException("corrupted stream - invalid high tag number found");
- }
-
- while ((b & 0x80) != 0)
- {
- b = input[index++] & 0xff;
- }
- }
-
- byte[] tmp = new byte[input.length - index + 1];
-
- System.arraycopy(input, index, tmp, 1, tmp.length - 1);
-
- tmp[0] = (byte)newTag;
-
- return tmp;
- }
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
- sb.append("[");
- if (isConstructed())
- {
- sb.append("CONSTRUCTED ");
- }
- sb.append("APPLICATION ");
- sb.append(Integer.toString(getApplicationTag()));
- sb.append("]");
- // @todo content encoding somehow?
- if (this.octets != null)
- {
- sb.append(" #");
- sb.append(Hex.toHexString(this.octets));
- }
- else
- {
- sb.append(" #null");
- }
- sb.append(" ");
- return sb.toString();
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BMPString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BMPString.java
new file mode 100644
index 0000000..24bc2e4
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BMPString.java
@@ -0,0 +1,215 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * ASN.1 BMPString object encodes BMP (<i>Basic Multilingual Plane</i>) subset
+ * (aka UCS-2) of UNICODE (ISO 10646) characters in codepoints 0 to 65535.
+ * <p>
+ * At ISO-10646:2011 the term "BMP" has been withdrawn, and replaced by
+ * term "UCS-2".
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1BMPString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1BMPString.class, BERTags.BMP_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a BMP String from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1BMPString instance, or null.
+ */
+ public static ASN1BMPString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1BMPString)
+ {
+ return (ASN1BMPString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1BMPString)
+ {
+ return (ASN1BMPString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1BMPString)TYPE.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());
+ }
+
+ /**
+ * Return a BMP String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1BMPString instance.
+ */
+ public static ASN1BMPString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1BMPString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final char[] string;
+
+ ASN1BMPString(String string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ this.string = string.toCharArray();
+ }
+
+ ASN1BMPString(byte[] string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ int byteLen = string.length;
+ if (0 != (byteLen & 1))
+ {
+ throw new IllegalArgumentException("malformed BMPString encoding encountered");
+ }
+
+ int charLen = byteLen / 2;
+ char[] cs = new char[charLen];
+
+ for (int i = 0; i != charLen; i++)
+ {
+ cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
+ }
+
+ this.string = cs;
+ }
+
+ ASN1BMPString(char[] string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ this.string = string;
+ }
+
+ public final String getString()
+ {
+ return new String(string);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1BMPString))
+ {
+ return false;
+ }
+
+ ASN1BMPString that = (ASN1BMPString)other;
+
+ return Arrays.areEqual(this.string, that.string);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, string.length * 2);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ int count = string.length;
+
+ out.writeIdentifier(withTag, BERTags.BMP_STRING);
+ out.writeDL(count * 2);
+
+ byte[] buf = new byte[8];
+
+ int i = 0, limit = count & -4;
+ while (i < limit)
+ {
+ char c0 = string[i], c1 = string[i + 1], c2 = string[i + 2], c3 = string[i + 3];
+ i += 4;
+
+ buf[0] = (byte)(c0 >> 8);
+ buf[1] = (byte)c0;
+ buf[2] = (byte)(c1 >> 8);
+ buf[3] = (byte)c1;
+ buf[4] = (byte)(c2 >> 8);
+ buf[5] = (byte)c2;
+ buf[6] = (byte)(c3 >> 8);
+ buf[7] = (byte)c3;
+
+ out.write(buf, 0, 8);
+ }
+ if (i < count)
+ {
+ int bufPos = 0;
+ do
+ {
+ char c0 = string[i];
+ i += 1;
+
+ buf[bufPos++] = (byte)(c0 >> 8);
+ buf[bufPos++] = (byte)c0;
+ }
+ while (i < count);
+
+ out.write(buf, 0, bufPos);
+ }
+ }
+
+ static ASN1BMPString createPrimitive(byte[] contents)
+ {
+ return new DERBMPString(contents);
+ }
+
+ static ASN1BMPString createPrimitive(char[] string)
+ {
+ // TODO ASN1InputStream has a validator/converter that should be unified in this class somehow
+ return new DERBMPString(string);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitString.java
index 38b6b46..fd02759 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitString.java
@@ -1,12 +1,11 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.EOFException;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.io.Streams;
/**
* Base class for BIT STRING objects
@@ -14,12 +13,57 @@
*/
public abstract class ASN1BitString
extends ASN1Primitive
- implements ASN1String
+ implements ASN1String, ASN1BitStringParser
{
- private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1BitString.class, BERTags.BIT_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
- protected final byte[] data;
- protected final int padBits;
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence.toASN1BitString();
+ }
+ };
+
+ public static ASN1BitString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1BitString)
+ {
+ return (ASN1BitString)obj;
+ }
+// else if (obj instanceof ASN1BitStringParser)
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1BitString)
+ {
+ return (ASN1BitString)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1BitString)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct BIT STRING from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ public static ASN1BitString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1BitString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/**
* @param bitString an int containing the BIT STRING
@@ -101,15 +145,16 @@
return result;
}
- protected ASN1BitString(byte data, int padBits)
+ final byte[] contents;
+
+ ASN1BitString(byte data, int padBits)
{
if (padBits > 7 || padBits < 0)
{
throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
}
- this.data = new byte[]{ data };
- this.padBits = padBits;
+ this.contents = new byte[]{ (byte)padBits, data };
}
/**
@@ -118,9 +163,7 @@
* @param data the octets making up the bit string.
* @param padBits the number of extra bits at the end of the string.
*/
- public ASN1BitString(
- byte[] data,
- int padBits)
+ ASN1BitString(byte[] data, int padBits)
{
if (data == null)
{
@@ -135,8 +178,58 @@
throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
}
- this.data = Arrays.clone(data);
- this.padBits = padBits;
+ this.contents = Arrays.prepend(data, (byte)padBits);
+ }
+
+ ASN1BitString(byte[] contents, boolean check)
+ {
+ if (check)
+ {
+ if (null == contents)
+ {
+ throw new NullPointerException("'contents' cannot be null");
+ }
+ if (contents.length < 1)
+ {
+ throw new IllegalArgumentException("'contents' cannot be empty");
+ }
+
+ int padBits = contents[0] & 0xFF;
+ if (padBits > 0)
+ {
+ if (contents.length < 2)
+ {
+ throw new IllegalArgumentException("zero length data with non-zero pad bits");
+ }
+ if (padBits > 7)
+ {
+ throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
+ }
+ }
+ }
+
+ this.contents = contents;
+ }
+
+ public InputStream getBitStream() throws IOException
+ {
+ return new ByteArrayInputStream(contents, 1, contents.length - 1);
+ }
+
+ public InputStream getOctetStream() throws IOException
+ {
+ int padBits = contents[0] & 0xFF;
+ if (0 != padBits)
+ {
+ throw new IOException("expected octet-aligned bitstring, but found padBits: " + padBits);
+ }
+
+ return getBitStream();
+ }
+
+ public ASN1BitStringParser parser()
+ {
+ return this;
}
/**
@@ -146,8 +239,6 @@
*/
public String getString()
{
- StringBuffer buf = new StringBuffer("#");
-
byte[] string;
try
{
@@ -158,10 +249,14 @@
throw new ASN1ParsingException("Internal error encoding BitString: " + e.getMessage(), e);
}
+ StringBuffer buf = new StringBuffer(1 + string.length * 2);
+ buf.append('#');
+
for (int i = 0; i != string.length; i++)
{
- buf.append(table[(string[i] >>> 4) & 0xf]);
- buf.append(table[string[i] & 0xf]);
+ byte b = string[i];
+ buf.append(table[(b >>> 4) & 0xf]);
+ buf.append(table[b & 0xf]);
}
return buf.toString();
@@ -173,15 +268,16 @@
public int intValue()
{
int value = 0;
- int end = Math.min(4, data.length - 1);
- for (int i = 0; i < end; ++i)
+ int end = Math.min(5, contents.length - 1);
+ for (int i = 1; i < end; ++i)
{
- value |= (data[i] & 0xFF) << (8 * i);
+ value |= (contents[i] & 0xFF) << (8 * (i - 1));
}
- if (0 <= end && end < 4)
+ if (1 <= end && end < 5)
{
- byte der = (byte)(data[end] & (0xFF << padBits));
- value |= (der & 0xFF) << (8 * end);
+ int padBits = contents[0] & 0xFF;
+ byte der = (byte)(contents[end] & (0xFF << padBits));
+ value |= (der & 0xFF) << (8 * (end - 1));
}
return value;
}
@@ -195,30 +291,31 @@
*/
public byte[] getOctets()
{
- if (padBits != 0)
+ if (contents[0] != 0)
{
throw new IllegalStateException("attempt to get non-octet aligned data from BIT STRING");
}
- return Arrays.clone(data);
+ return Arrays.copyOfRange(contents, 1, contents.length);
}
public byte[] getBytes()
{
- if (0 == data.length)
+ if (contents.length == 1)
{
- return data;
+ return ASN1OctetString.EMPTY_OCTETS;
}
- byte[] rv = Arrays.clone(data);
+ int padBits = contents[0] & 0xFF;
+ byte[] rv = Arrays.copyOfRange(contents, 1, contents.length);
// DER requires pad bits be zero
- rv[data.length - 1] &= (0xFF << padBits);
+ rv[rv.length - 1] &= (byte)(0xFF << padBits);
return rv;
}
public int getPadBits()
{
- return padBits;
+ return contents[0] & 0xFF;
}
public String toString()
@@ -228,85 +325,56 @@
public int hashCode()
{
- int end = data.length;
- if (--end < 0)
+ if (contents.length < 2)
{
return 1;
}
- byte der = (byte)(data[end] & (0xFF << padBits));
+ int padBits = contents[0] & 0xFF;
+ int last = contents.length - 1;
- int hc = Arrays.hashCode(data, 0, end);
+ byte lastOctetDER = (byte)(contents[last] & (0xFF << padBits));
+
+ int hc = Arrays.hashCode(contents, 0, last);
hc *= 257;
- hc ^= der;
- return hc ^ padBits;
+ hc ^= lastOctetDER;
+ return hc;
}
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive other)
{
- if (!(o instanceof ASN1BitString))
+ if (!(other instanceof ASN1BitString))
{
return false;
}
- ASN1BitString other = (ASN1BitString)o;
- if (padBits != other.padBits)
+ ASN1BitString that = (ASN1BitString)other;
+ byte[] thisContents = this.contents, thatContents = that.contents;
+
+ int length = thisContents.length;
+ if (thatContents.length != length)
{
return false;
}
- byte[] a = data, b = other.data;
- int end = a.length;
- if (end != b.length)
- {
- return false;
- }
- if (--end < 0)
+ if (length == 1)
{
return true;
}
- for (int i = 0; i < end; ++i)
+
+ int last = length - 1;
+ for (int i = 0; i < last; ++i)
{
- if (a[i] != b[i])
+ if (thisContents[i] != thatContents[i])
{
return false;
}
}
- byte derA = (byte)(a[end] & (0xFF << padBits));
- byte derB = (byte)(b[end] & (0xFF << padBits));
+ int padBits = thisContents[0] & 0xFF;
+ byte thisLastOctetDER = (byte)(thisContents[last] & (0xFF << padBits));
+ byte thatLastOctetDER = (byte)(thatContents[last] & (0xFF << padBits));
- return derA == derB;
- }
-
- static ASN1BitString fromInputStream(int length, InputStream stream)
- throws IOException
- {
- if (length < 1)
- {
- throw new IllegalArgumentException("truncated BIT STRING detected");
- }
-
- int padBits = stream.read();
- byte[] data = new byte[length - 1];
-
- if (data.length != 0)
- {
- if (Streams.readFully(stream, data) != data.length)
- {
- throw new EOFException("EOF encountered in middle of BIT STRING");
- }
-
- if (padBits > 0 && padBits < 8)
- {
- if (data[data.length - 1] != (byte)(data[data.length - 1] & (0xFF << padBits)))
- {
- return new DLBitString(data, padBits);
- }
- }
- }
-
- return new DERBitString(data, padBits);
+ return thisLastOctetDER == thatLastOctetDER;
}
public ASN1Primitive getLoadedObject()
@@ -316,13 +384,37 @@
ASN1Primitive toDERObject()
{
- return new DERBitString(data, padBits);
+ return new DERBitString(contents, false);
}
ASN1Primitive toDLObject()
{
- return new DLBitString(data, padBits);
+ return new DLBitString(contents, false);
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
+ static ASN1BitString createPrimitive(byte[] contents)
+ {
+ int length = contents.length;
+ if (length < 1)
+ {
+ throw new IllegalArgumentException("truncated BIT STRING detected");
+ }
+
+ int padBits = contents[0] & 0xFF;
+ if (padBits > 0)
+ {
+ if (padBits > 7 || length < 2)
+ {
+ throw new IllegalArgumentException("invalid pad bits detected");
+ }
+
+ byte finalOctet = contents[length - 1];
+ if (finalOctet != (byte)(finalOctet & (0xFF << padBits)))
+ {
+ return new DLBitString(contents, false);
+ }
+ }
+
+ return new DERBitString(contents, false);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitStringParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitStringParser.java
new file mode 100644
index 0000000..5305b19
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitStringParser.java
@@ -0,0 +1,42 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A basic parser for a BIT STRING object
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ASN1BitStringParser
+ extends ASN1Encodable, InMemoryRepresentable
+{
+ /**
+ * Return an InputStream representing the contents of the BIT STRING. The final
+ * byte, if any, may include pad bits. See {@link #getPadBits()}.
+ *
+ * @return an InputStream with its source as the BIT STRING content.
+ */
+ public InputStream getBitStream() throws IOException;
+
+ /**
+ * Return an InputStream representing the contents of the BIT STRING, where the
+ * content is expected to be octet-aligned (this will be automatically checked
+ * during parsing).
+ *
+ * @return an InputStream with its source as the BIT STRING content.
+ */
+ public InputStream getOctetStream() throws IOException;
+
+ /**
+ * Return the number of pad bits, if any, in the final byte, if any, read from
+ * {@link #getBitStream()}. This number is in the range zero to seven. That
+ * number of the least significant bits of the final byte, if any, are not part
+ * of the contents and should be ignored. NOTE: Must be called AFTER the stream
+ * has been fully processed. (Does not need to be called if
+ * {@link #getOctetStream()} was used instead of {@link #getBitStream()}).
+ *
+ * @return the number of pad bits. In the range zero to seven.
+ */
+ public int getPadBits();
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Boolean.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Boolean.java
index afb0cad..d6b5cef 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Boolean.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Boolean.java
@@ -18,6 +18,14 @@
public class ASN1Boolean
extends ASN1Primitive
{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Boolean.class, BERTags.BOOLEAN)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
private static final byte FALSE_VALUE = 0x00;
private static final byte TRUE_VALUE = (byte)0xFF;
@@ -46,7 +54,7 @@
byte[] enc = (byte[])obj;
try
{
- return (ASN1Boolean)fromByteArray(enc);
+ return (ASN1Boolean)TYPE.fromByteArray(enc);
}
catch (IOException e)
{
@@ -91,25 +99,16 @@
/**
* Return a Boolean from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1Boolean instance.
*/
- public static ASN1Boolean getInstance(ASN1TaggedObject obj, boolean explicit)
+ public static ASN1Boolean getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1Boolean)
- {
- return getInstance(o);
- }
- else
- {
- return ASN1Boolean.fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1Boolean)TYPE.getContextInstance(taggedObject, explicit);
}
private ASN1Boolean(byte value)
@@ -122,19 +121,19 @@
return value != FALSE_VALUE;
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 3;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, 1);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.BOOLEAN, value);
+ out.writeEncodingDL(withTag, BERTags.BOOLEAN, value);
}
boolean asn1Equals(ASN1Primitive other)
@@ -164,14 +163,14 @@
return isTrue() ? "TRUE" : "FALSE";
}
- static ASN1Boolean fromOctetString(byte[] value)
+ static ASN1Boolean createPrimitive(byte[] contents)
{
- if (value.length != 1)
+ if (contents.length != 1)
{
throw new IllegalArgumentException("BOOLEAN value should have 1 byte in it");
}
- byte b = value[0];
+ byte b = contents[0];
switch (b)
{
case FALSE_VALUE: return FALSE;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1EncodableVector.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1EncodableVector.java
index 7dbd82d..6a885b7 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1EncodableVector.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1EncodableVector.java
@@ -52,6 +52,16 @@
this.elementCount = minCapacity;
}
+ public void addAll(ASN1Encodable[] others)
+ {
+ if (null == others)
+ {
+ throw new NullPointerException("'others' cannot be null");
+ }
+
+ doAddAll(others, "'others' elements cannot be null");
+ }
+
public void addAll(ASN1EncodableVector other)
{
if (null == other)
@@ -59,7 +69,12 @@
throw new NullPointerException("'other' cannot be null");
}
- int otherElementCount = other.size();
+ doAddAll(other.elements, "'other' elements cannot be null");
+ }
+
+ private void doAddAll(ASN1Encodable[] others, String nullMsg)
+ {
+ int otherElementCount = others.length;
if (otherElementCount < 1)
{
return;
@@ -75,10 +90,10 @@
int i = 0;
do
{
- ASN1Encodable otherElement = other.get(i);
+ ASN1Encodable otherElement = others[i];
if (null == otherElement)
{
- throw new NullPointerException("'other' elements cannot be null");
+ throw new NullPointerException(nullMsg);
}
this.elements[elementCount + i] = otherElement;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Enumerated.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Enumerated.java
index e67e174..6d96fb6 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Enumerated.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Enumerated.java
@@ -13,8 +13,13 @@
public class ASN1Enumerated
extends ASN1Primitive
{
- private final byte[] bytes;
- private final int start;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Enumerated.class, BERTags.ENUMERATED)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets(), false);
+ }
+ };
/**
* return an enumerated from the passed in object
@@ -35,7 +40,7 @@
{
try
{
- return (ASN1Enumerated)fromByteArray((byte[])obj);
+ return (ASN1Enumerated)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -49,29 +54,21 @@
/**
* return an Enumerated from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1Enumerated instance, or null.
*/
- public static ASN1Enumerated getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1Enumerated getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1Enumerated)
- {
- return getInstance(o);
- }
- else
- {
- return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1Enumerated)TYPE.getContextInstance(taggedObject, explicit);
}
+ private final byte[] contents;
+ private final int start;
+
/**
* Constructor from int.
*
@@ -84,7 +81,7 @@
throw new IllegalArgumentException("enumerated must be non-negative");
}
- this.bytes = BigInteger.valueOf(value).toByteArray();
+ this.contents = BigInteger.valueOf(value).toByteArray();
this.start = 0;
}
@@ -100,67 +97,78 @@
throw new IllegalArgumentException("enumerated must be non-negative");
}
- this.bytes = value.toByteArray();
+ this.contents = value.toByteArray();
this.start = 0;
}
/**
* Constructor from encoded BigInteger.
*
- * @param bytes the value of this enumerated as an encoded BigInteger (signed).
+ * @param contents the value of this enumerated as an encoded BigInteger (signed).
*/
- public ASN1Enumerated(byte[] bytes)
+ public ASN1Enumerated(byte[] contents)
{
- if (ASN1Integer.isMalformed(bytes))
+ this(contents, true);
+ }
+
+ ASN1Enumerated(byte[] contents, boolean clone)
+ {
+ if (ASN1Integer.isMalformed(contents))
{
throw new IllegalArgumentException("malformed enumerated");
}
- if (0 != (bytes[0] & 0x80))
+ if (0 != (contents[0] & 0x80))
{
throw new IllegalArgumentException("enumerated must be non-negative");
}
- this.bytes = Arrays.clone(bytes);
- this.start = ASN1Integer.signBytesToSkip(bytes);
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ this.start = ASN1Integer.signBytesToSkip(contents);
}
public BigInteger getValue()
{
- return new BigInteger(bytes);
+ return new BigInteger(contents);
+ }
+
+ public boolean hasValue(int x)
+ {
+ return (contents.length - start) <= 4
+ && ASN1Integer.intValue(contents, start, ASN1Integer.SIGN_EXT_SIGNED) == x;
}
public boolean hasValue(BigInteger x)
{
return null != x
// Fast check to avoid allocation
- && ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED) == x.intValue()
+ && ASN1Integer.intValue(contents, start, ASN1Integer.SIGN_EXT_SIGNED) == x.intValue()
&& getValue().equals(x);
}
public int intValueExact()
{
- int count = bytes.length - start;
+ int count = contents.length - start;
if (count > 4)
{
throw new ArithmeticException("ASN.1 Enumerated out of int range");
}
- return ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED);
+ return ASN1Integer.intValue(contents, start, ASN1Integer.SIGN_EXT_SIGNED);
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.ENUMERATED, bytes);
+ out.writeEncodingDL(withTag, BERTags.ENUMERATED, contents);
}
boolean asn1Equals(
@@ -173,39 +181,39 @@
ASN1Enumerated other = (ASN1Enumerated)o;
- return Arrays.areEqual(this.bytes, other.bytes);
+ return Arrays.areEqual(this.contents, other.contents);
}
public int hashCode()
{
- return Arrays.hashCode(bytes);
+ return Arrays.hashCode(contents);
}
- private static ASN1Enumerated[] cache = new ASN1Enumerated[12];
+ private static final ASN1Enumerated[] cache = new ASN1Enumerated[12];
- static ASN1Enumerated fromOctetString(byte[] enc)
+ static ASN1Enumerated createPrimitive(byte[] contents, boolean clone)
{
- if (enc.length > 1)
+ if (contents.length > 1)
{
- return new ASN1Enumerated(enc);
+ return new ASN1Enumerated(contents, clone);
}
- if (enc.length == 0)
+ if (contents.length == 0)
{
throw new IllegalArgumentException("ENUMERATED has zero length");
}
- int value = enc[0] & 0xff;
+ int value = contents[0] & 0xff;
if (value >= cache.length)
{
- return new ASN1Enumerated(enc);
+ return new ASN1Enumerated(contents, clone);
}
ASN1Enumerated possibleMatch = cache[value];
if (possibleMatch == null)
{
- possibleMatch = cache[value] = new ASN1Enumerated(enc);
+ possibleMatch = cache[value] = new ASN1Enumerated(contents, clone);
}
return possibleMatch;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1External.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1External.java
index dee1198..345858b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1External.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1External.java
@@ -3,6 +3,8 @@
import java.io.IOException;
+import com.android.org.bouncycastle.util.Objects;
+
/**
* Class representing the DER-type External
* @hide This class is not part of the Android public SDK API
@@ -10,101 +12,124 @@
public abstract class ASN1External
extends ASN1Primitive
{
- protected ASN1ObjectIdentifier directReference;
- protected ASN1Integer indirectReference;
- protected ASN1Primitive dataValueDescriptor;
- protected int encoding;
- protected ASN1Primitive externalContent;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1External.class, BERTags.EXTERNAL)
+ {
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ // TODO Ideally ASN1External would have no subclasses and just hold the sequence
+ return sequence.toASN1External();
+ }
+ };
- /**
- * Construct an EXTERNAL object, the input encoding vector must have exactly two elements on it.
- * <p>
- * Acceptable input formats are:
- * <ul>
- * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
- * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
- * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
- * </ul>
- *
- * @throws IllegalArgumentException if input size is wrong, or
- */
- public ASN1External(ASN1EncodableVector vector)
+ public static ASN1External getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1External)
+ {
+ return (ASN1External)obj;
+ }
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1External)
+ {
+ return (ASN1External)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1External)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct external from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ public static ASN1External getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1External)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ ASN1ObjectIdentifier directReference;
+ ASN1Integer indirectReference;
+ // TODO Actually use ASN1ObjectDescriptor for this
+ ASN1Primitive dataValueDescriptor;
+ int encoding;
+ ASN1Primitive externalContent;
+
+ ASN1External(ASN1Sequence sequence)
{
int offset = 0;
- ASN1Primitive enc = getObjFromVector(vector, offset);
- if (enc instanceof ASN1ObjectIdentifier)
+ ASN1Primitive asn1 = getObjFromSequence(sequence, offset);
+ if (asn1 instanceof ASN1ObjectIdentifier)
{
- directReference = (ASN1ObjectIdentifier)enc;
- offset++;
- enc = getObjFromVector(vector, offset);
+ directReference = (ASN1ObjectIdentifier)asn1;
+ asn1 = getObjFromSequence(sequence, ++offset);
}
- if (enc instanceof ASN1Integer)
+ if (asn1 instanceof ASN1Integer)
{
- indirectReference = (ASN1Integer) enc;
- offset++;
- enc = getObjFromVector(vector, offset);
+ indirectReference = (ASN1Integer)asn1;
+ asn1 = getObjFromSequence(sequence, ++offset);
}
- if (!(enc instanceof ASN1TaggedObject))
+ if (!(asn1 instanceof ASN1TaggedObject))
{
- dataValueDescriptor = (ASN1Primitive) enc;
- offset++;
- enc = getObjFromVector(vector, offset);
+ dataValueDescriptor = asn1;
+ asn1 = getObjFromSequence(sequence, ++offset);
}
- if (vector.size() != offset + 1)
+ if (sequence.size() != offset + 1)
{
- throw new IllegalArgumentException("input vector too large");
+ throw new IllegalArgumentException("input sequence too large");
}
- if (!(enc instanceof ASN1TaggedObject))
+ if (!(asn1 instanceof ASN1TaggedObject))
{
- throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
+ throw new IllegalArgumentException(
+ "No tagged object found in sequence. Structure doesn't seem to be of type External");
}
- ASN1TaggedObject obj = (ASN1TaggedObject)enc;
- setEncoding(obj.getTagNo());
- externalContent = obj.getObject();
+
+ ASN1TaggedObject obj = (ASN1TaggedObject)asn1;
+ this.encoding = checkEncoding(obj.getTagNo());
+ this.externalContent = getExternalContent(obj);
}
- private ASN1Primitive getObjFromVector(ASN1EncodableVector v, int index)
+ ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor,
+ DERTaggedObject externalData)
{
- if (v.size() <= index)
- {
- throw new IllegalArgumentException("too few objects in input vector");
- }
-
- return v.get(index).toASN1Primitive();
+ this.directReference = directReference;
+ this.indirectReference = indirectReference;
+ this.dataValueDescriptor = dataValueDescriptor;
+ this.encoding = checkEncoding(externalData.getTagNo());
+ this.externalContent = getExternalContent(externalData);
}
- /**
- * Creates a new instance of External
- * See X.690 for more informations about the meaning of these parameters
- * @param directReference The direct reference or <code>null</code> if not set.
- * @param indirectReference The indirect reference or <code>null</code> if not set.
- * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
- * @param externalData The external data in its encoded form.
- */
- public ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor,
+ int encoding, ASN1Primitive externalData)
{
- this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ this.directReference = directReference;
+ this.indirectReference = indirectReference;
+ this.dataValueDescriptor = dataValueDescriptor;
+ this.encoding = checkEncoding(encoding);
+ this.externalContent = checkExternalContent(encoding, externalData);
}
- /**
- * Creates a new instance of External.
- * See X.690 for more informations about the meaning of these parameters
- * @param directReference The direct reference or <code>null</code> if not set.
- * @param indirectReference The indirect reference or <code>null</code> if not set.
- * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
- * @param encoding The encoding to be used for the external data
- * @param externalData The external data
- */
- public ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ abstract ASN1Sequence buildSequence();
+
+ int encodedLength(boolean withTag) throws IOException
{
- setDirectReference(directReference);
- setIndirectReference(indirectReference);
- setDataValueDescriptor(dataValueDescriptor);
- setEncoding(encoding);
- setExternalContent(externalData.toASN1Primitive());
+ return buildSequence().encodedLength(withTag);
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.EXTERNAL);
+ buildSequence().encode(out, false);
}
ASN1Primitive toDERObject()
@@ -117,75 +142,38 @@
return new DLExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
}
- /* (non-Javadoc)
- * @see java.lang.Object#hashCode()
- */
public int hashCode()
{
- int ret = 0;
- if (directReference != null)
- {
- ret = directReference.hashCode();
- }
- if (indirectReference != null)
- {
- ret ^= indirectReference.hashCode();
- }
- if (dataValueDescriptor != null)
- {
- ret ^= dataValueDescriptor.hashCode();
- }
- ret ^= externalContent.hashCode();
- return ret;
+ return Objects.hashCode(this.directReference)
+ ^ Objects.hashCode(this.indirectReference)
+ ^ Objects.hashCode(this.dataValueDescriptor)
+ ^ this.encoding
+ ^ this.externalContent.hashCode();
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return true;
}
- int encodedLength()
- throws IOException
+ boolean asn1Equals(ASN1Primitive primitive)
{
- return this.getEncoded().length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#asn1Equals(org.bouncycastle.asn1.ASN1Primitive)
- */
- boolean asn1Equals(ASN1Primitive o)
- {
- if (!(o instanceof ASN1External))
- {
- return false;
- }
- if (this == o)
+ if (this == primitive)
{
return true;
}
- ASN1External other = (ASN1External)o;
- if (directReference != null)
+ if (!(primitive instanceof ASN1External))
{
- if (other.directReference == null || !other.directReference.equals(directReference))
- {
- return false;
- }
+ return false;
}
- if (indirectReference != null)
- {
- if (other.indirectReference == null || !other.indirectReference.equals(indirectReference))
- {
- return false;
- }
- }
- if (dataValueDescriptor != null)
- {
- if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor))
- {
- return false;
- }
- }
- return externalContent.equals(other.externalContent);
+
+ ASN1External that = (ASN1External)primitive;
+
+ return Objects.areEqual(this.directReference, that.directReference)
+ && Objects.areEqual(this.indirectReference, that.indirectReference)
+ && Objects.areEqual(this.dataValueDescriptor, that.dataValueDescriptor)
+ && this.encoding == that.encoding
+ && this.externalContent.equals(that.externalContent);
}
/**
@@ -219,7 +207,7 @@
{
return encoding;
}
-
+
/**
* Returns the content of this element
* @return The content
@@ -228,7 +216,7 @@
{
return externalContent;
}
-
+
/**
* Returns the indirect reference of this element
* @return The reference
@@ -237,27 +225,9 @@
{
return indirectReference;
}
-
- /**
- * Sets the data value descriptor
- * @param dataValueDescriptor The descriptor
- */
- private void setDataValueDescriptor(ASN1Primitive dataValueDescriptor)
- {
- this.dataValueDescriptor = dataValueDescriptor;
- }
/**
- * Sets the direct reference of the external element
- * @param directReferemce The reference
- */
- private void setDirectReference(ASN1ObjectIdentifier directReferemce)
- {
- this.directReference = directReferemce;
- }
-
- /**
- * Sets the encoding of the content. Valid values are
+ * Checks the encoding of the content. Valid values are
* <ul>
* <li><code>0</code> single-ASN1-type</li>
* <li><code>1</code> OCTET STRING</li>
@@ -265,30 +235,57 @@
* </ul>
* @param encoding The encoding
*/
- private void setEncoding(int encoding)
+ private static int checkEncoding(int encoding)
{
if (encoding < 0 || encoding > 2)
{
throw new IllegalArgumentException("invalid encoding value: " + encoding);
}
- this.encoding = encoding;
+
+ return encoding;
}
-
- /**
- * Sets the content of this element
- * @param externalContent The content
- */
- private void setExternalContent(ASN1Primitive externalContent)
+
+ private static ASN1Primitive checkExternalContent(int tagNo, ASN1Primitive externalContent)
{
- this.externalContent = externalContent;
+ switch (tagNo)
+ {
+ case 1:
+ return ASN1OctetString.TYPE.checkedCast(externalContent);
+ case 2:
+ return ASN1BitString.TYPE.checkedCast(externalContent);
+ default:
+ return externalContent;
+ }
}
-
- /**
- * Sets the indirect reference of this element
- * @param indirectReference The reference
- */
- private void setIndirectReference(ASN1Integer indirectReference)
+
+ private static ASN1Primitive getExternalContent(ASN1TaggedObject encoding)
{
- this.indirectReference = indirectReference;
+ int tagClass = encoding.getTagClass(), tagNo = encoding.getTagNo();
+ if (BERTags.CONTEXT_SPECIFIC != tagClass)
+ {
+ throw new IllegalArgumentException("invalid tag: " + ASN1Util.getTagText(tagClass, tagNo));
+ }
+
+ switch (tagNo)
+ {
+ case 0:
+ return encoding.getExplicitBaseObject().toASN1Primitive();
+ case 1:
+ return ASN1OctetString.getInstance(encoding, false);
+ case 2:
+ return ASN1BitString.getInstance(encoding, false);
+ default:
+ throw new IllegalArgumentException("invalid tag: " + ASN1Util.getTagText(tagClass, tagNo));
+ }
+ }
+
+ private static ASN1Primitive getObjFromSequence(ASN1Sequence sequence, int index)
+ {
+ if (sequence.size() <= index)
+ {
+ throw new IllegalArgumentException("too few objects in input sequence");
+ }
+
+ return sequence.getObjectAt(index).toASN1Primitive();
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ExternalParser.java
similarity index 81%
rename from repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java
rename to repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ExternalParser.java
index ff1d48c..7d1300e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ExternalParser.java
@@ -4,10 +4,10 @@
import java.io.IOException;
/**
- * Interface to parse ASN.1 ApplicationSpecific objects.
+ * Parser DER EXTERNAL tagged objects.
* @hide This class is not part of the Android public SDK API
*/
-public interface ASN1ApplicationSpecificParser
+public interface ASN1ExternalParser
extends ASN1Encodable, InMemoryRepresentable
{
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralString.java
new file mode 100644
index 0000000..61bcd1f
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralString.java
@@ -0,0 +1,153 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 GENERAL-STRING data type.
+ * <p>
+ * This is an 8-bit encoded ISO 646 (ASCII) character set
+ * with optional escapes to other character sets.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1GeneralString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1GeneralString.class, BERTags.GENERAL_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a GeneralString from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1GeneralString instance, or null.
+ */
+ public static ASN1GeneralString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1GeneralString)
+ {
+ return (ASN1GeneralString) obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1GeneralString)
+ {
+ return (ASN1GeneralString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1GeneralString)TYPE.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());
+ }
+
+ /**
+ * Return a GeneralString from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1GeneralString instance.
+ */
+ public static ASN1GeneralString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1GeneralString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1GeneralString(String string)
+ {
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1GeneralString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ /**
+ * Return a Java String representation of our contained String.
+ *
+ * @return a Java String representing our contents.
+ */
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ /**
+ * Return a byte array representation of our contained String.
+ *
+ * @return a byte array representing our contents.
+ */
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.GENERAL_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1GeneralString))
+ {
+ return false;
+ }
+
+ ASN1GeneralString that = (ASN1GeneralString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1GeneralString createPrimitive(byte[] contents)
+ {
+ return new DERGeneralString(contents, false);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralizedTime.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralizedTime.java
index 319c9bc..50b9795 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralizedTime.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralizedTime.java
@@ -48,7 +48,13 @@
public class ASN1GeneralizedTime
extends ASN1Primitive
{
- protected byte[] time;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1GeneralizedTime.class, BERTags.GENERALIZED_TIME)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
/**
* return a generalized time from the passed in object
@@ -64,12 +70,19 @@
{
return (ASN1GeneralizedTime)obj;
}
-
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1GeneralizedTime)
+ {
+ return (ASN1GeneralizedTime)primitive;
+ }
+ }
if (obj instanceof byte[])
{
try
{
- return (ASN1GeneralizedTime)fromByteArray((byte[])obj);
+ return (ASN1GeneralizedTime)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -83,29 +96,19 @@
/**
* return a Generalized Time object from a tagged object.
*
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
* @return an ASN1GeneralizedTime instance.
- * @throws IllegalArgumentException if the tagged object cannot
- * be converted.
+ * @throws IllegalArgumentException if the tagged object cannot be converted.
*/
- public static ASN1GeneralizedTime getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1GeneralizedTime getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1GeneralizedTime)
- {
- return getInstance(o);
- }
- else
- {
- return new ASN1GeneralizedTime(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1GeneralizedTime)TYPE.getContextInstance(taggedObject, explicit);
}
+ final byte[] contents;
+
/**
* The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z
* for local time, or Z+-HHMM on the end, for difference between local
@@ -118,7 +121,7 @@
public ASN1GeneralizedTime(
String time)
{
- this.time = Strings.toByteArray(time);
+ this.contents = Strings.toByteArray(time);
try
{
this.getDate();
@@ -143,7 +146,7 @@
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
/**
@@ -165,7 +168,7 @@
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
ASN1GeneralizedTime(
@@ -175,7 +178,7 @@
{
throw new IllegalArgumentException("GeneralizedTime string too short");
}
- this.time = bytes;
+ this.contents = bytes;
if (!(isDigit(0) && isDigit(1) && isDigit(2) && isDigit(3)))
{
@@ -190,7 +193,7 @@
*/
public String getTimeString()
{
- return Strings.fromByteArray(time);
+ return Strings.fromByteArray(contents);
}
/**
@@ -208,7 +211,7 @@
*/
public String getTime()
{
- String stime = Strings.fromByteArray(time);
+ String stime = Strings.fromByteArray(contents);
//
// standardise the format.
@@ -360,34 +363,26 @@
throws ParseException
{
SimpleDateFormat dateF;
- String stime = Strings.fromByteArray(time);
+ String stime = Strings.fromByteArray(contents);
String d = stime;
if (stime.endsWith("Z"))
{
if (hasFractionalSeconds())
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'", LocaleUtil.EN_Locale);
}
else if (hasSeconds())
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", LocaleUtil.EN_Locale);
}
else if (hasMinutes())
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmm'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHHmm'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHHmm'Z'", LocaleUtil.EN_Locale);
}
else
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHH'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHH'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHH'Z'", LocaleUtil.EN_Locale);
}
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
@@ -432,14 +427,14 @@
d = pruneFractionalSeconds(d);
}
- return DateUtil.epochAdjust(dateF.parse(d));
+ return dateF.parse(d);
}
protected boolean hasFractionalSeconds()
{
- for (int i = 0; i != time.length; i++)
+ for (int i = 0; i != contents.length; i++)
{
- if (time[i] == '.')
+ if (contents[i] == '.')
{
if (i == 14)
{
@@ -462,49 +457,46 @@
private boolean isDigit(int pos)
{
- return time.length > pos && time[pos] >= '0' && time[pos] <= '9';
+ return contents.length > pos && contents[pos] >= '0' && contents[pos] <= '9';
}
- boolean isConstructed()
+ final boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- int length = time.length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, time);
+ out.writeEncodingDL(withTag, BERTags.GENERALIZED_TIME, contents);
}
ASN1Primitive toDERObject()
{
- return new DERGeneralizedTime(time);
+ return new DERGeneralizedTime(contents);
}
- ASN1Primitive toDLObject()
- {
- return new DERGeneralizedTime(time);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive o)
{
if (!(o instanceof ASN1GeneralizedTime))
{
return false;
}
- return Arrays.areEqual(time, ((ASN1GeneralizedTime)o).time);
+ return Arrays.areEqual(contents, ((ASN1GeneralizedTime)o).contents);
}
public int hashCode()
{
- return Arrays.hashCode(time);
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1GeneralizedTime createPrimitive(byte[] contents)
+ {
+ return new ASN1GeneralizedTime(contents);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GraphicString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GraphicString.java
new file mode 100644
index 0000000..a768336
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GraphicString.java
@@ -0,0 +1,132 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1GraphicString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1GraphicString.class, BERTags.GRAPHIC_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a GraphicString from the passed in object.
+ *
+ * @param obj an ASN1GraphicString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1GraphicString instance, or null.
+ */
+ public static ASN1GraphicString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1GraphicString)
+ {
+ return (ASN1GraphicString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1GraphicString)
+ {
+ return (ASN1GraphicString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1GraphicString)TYPE.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());
+ }
+
+ /**
+ * Return a GraphicString from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly tagged,
+ * false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1GraphicString instance, or null.
+ */
+ public static ASN1GraphicString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1GraphicString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1GraphicString(byte[] contents, boolean clone)
+ {
+ if (null == contents)
+ {
+ throw new NullPointerException("'contents' cannot be null");
+ }
+
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.GRAPHIC_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1GraphicString))
+ {
+ return false;
+ }
+
+ ASN1GraphicString that = (ASN1GraphicString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ static ASN1GraphicString createPrimitive(byte[] contents)
+ {
+ return new DERGraphicString(contents, false);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1IA5String.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1IA5String.java
new file mode 100644
index 0000000..6dd9904
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1IA5String.java
@@ -0,0 +1,172 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 IA5String object - this is a ISO 646 (ASCII) string encoding code points 0 to 127.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1IA5String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1IA5String.class, BERTags.IA5_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return an IA5 string from the passed in object
+ *
+ * @param obj an ASN1IA5String or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a ASN1IA5String instance, or null.
+ */
+ public static ASN1IA5String getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1IA5String)
+ {
+ return (ASN1IA5String)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1IA5String)
+ {
+ return (ASN1IA5String)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1IA5String)TYPE.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());
+ }
+
+ /**
+ * Return an IA5 String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1IA5String instance, or null.
+ */
+ public static ASN1IA5String getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1IA5String)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1IA5String(String string, boolean validate)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+ if (validate && !isIA5String(string))
+ {
+ throw new IllegalArgumentException("'string' contains illegal characters");
+ }
+
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1IA5String(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.IA5_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1IA5String))
+ {
+ return false;
+ }
+
+ ASN1IA5String that = (ASN1IA5String)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ /**
+ * return true if the passed in String can be represented without
+ * loss as an IA5String, false otherwise.
+ *
+ * @param str the string to check.
+ * @return true if character set in IA5String set, false otherwise.
+ */
+ public static boolean isIA5String(String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ static ASN1IA5String createPrimitive(byte[] contents)
+ {
+ return new DERIA5String(contents, false);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1InputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1InputStream.java
index dbe0e1a..4cda186 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1InputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1InputStream.java
@@ -22,12 +22,10 @@
{
private final int limit;
private final boolean lazyEvaluate;
-
private final byte[][] tmpBuffers;
@android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- public ASN1InputStream(
- InputStream is)
+ public ASN1InputStream(InputStream is)
{
this(is, StreamUtil.findLimit(is));
}
@@ -39,8 +37,7 @@
* @param input array containing ASN.1 encoded data.
*/
@android.compat.annotation.UnsupportedAppUsage
- public ASN1InputStream(
- byte[] input)
+ public ASN1InputStream(byte[] input)
{
this(new ByteArrayInputStream(input), input.length);
}
@@ -52,22 +49,18 @@
* @param input array containing ASN.1 encoded data.
* @param lazyEvaluate true if parsing inside constructed objects can be delayed.
*/
- public ASN1InputStream(
- byte[] input,
- boolean lazyEvaluate)
+ public ASN1InputStream(byte[] input, boolean lazyEvaluate)
{
this(new ByteArrayInputStream(input), input.length, lazyEvaluate);
}
-
+
/**
* Create an ASN1InputStream where no DER object will be longer than limit.
*
* @param input stream containing ASN.1 encoded data.
* @param limit maximum size of a DER encoded object.
*/
- public ASN1InputStream(
- InputStream input,
- int limit)
+ public ASN1InputStream(InputStream input, int limit)
{
this(input, limit, false);
}
@@ -79,9 +72,7 @@
* @param input stream containing ASN.1 encoded data.
* @param lazyEvaluate true if parsing inside constructed objects can be delayed.
*/
- public ASN1InputStream(
- InputStream input,
- boolean lazyEvaluate)
+ public ASN1InputStream(InputStream input, boolean lazyEvaluate)
{
this(input, StreamUtil.findLimit(input), lazyEvaluate);
}
@@ -94,15 +85,17 @@
* @param limit maximum size of a DER encoded object.
* @param lazyEvaluate true if parsing inside constructed objects can be delayed.
*/
- public ASN1InputStream(
- InputStream input,
- int limit,
- boolean lazyEvaluate)
+ public ASN1InputStream(InputStream input, int limit, boolean lazyEvaluate)
+ {
+ this(input, limit, lazyEvaluate, new byte[11][]);
+ }
+
+ private ASN1InputStream(InputStream input, int limit, boolean lazyEvaluate, byte[][] tmpBuffers)
{
super(input);
this.limit = limit;
this.lazyEvaluate = lazyEvaluate;
- this.tmpBuffers = new byte[11][];
+ this.tmpBuffers = tmpBuffers;
}
int getLimit()
@@ -120,7 +113,7 @@
byte[] bytes)
throws IOException
{
- if (Streams.readFully(this, bytes) != bytes.length)
+ if (Streams.readFully(this, bytes, 0, bytes.length) != bytes.length)
{
throw new EOFException("EOF encountered in middle of object");
}
@@ -141,82 +134,57 @@
int length)
throws IOException
{
- boolean isConstructed = (tag & CONSTRUCTED) != 0;
+ // TODO[asn1] Special-case zero length first?
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length, limit);
- if ((tag & APPLICATION) != 0)
+ if (0 == (tag & FLAGS))
{
- return new DLApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
+ return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
}
- if ((tag & TAGGED) != 0)
+ int tagClass = tag & PRIVATE;
+ if (0 != tagClass)
{
- return new ASN1StreamParser(defIn).readTaggedObject(isConstructed, tagNo);
+ boolean isConstructed = (tag & CONSTRUCTED) != 0;
+ return readTaggedObjectDL(tagClass, tagNo, isConstructed, defIn);
}
- if (isConstructed)
+ switch (tagNo)
{
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagNo)
+ case BIT_STRING:
+ {
+ return buildConstructedBitString(readVector(defIn));
+ }
+ case OCTET_STRING:
+ {
+ //
+ // yes, people actually do this...
+ //
+ return buildConstructedOctetString(readVector(defIn));
+ }
+ case SEQUENCE:
+ {
+ if (defIn.getRemaining() < 1)
{
- case OCTET_STRING:
- //
- // yes, people actually do this...
- //
- ASN1EncodableVector v = readVector(defIn);
- ASN1OctetString[] strings = new ASN1OctetString[v.size()];
-
- for (int i = 0; i != strings.length; i++)
- {
- ASN1Encodable asn1Obj = v.get(i);
- if (asn1Obj instanceof ASN1OctetString)
- {
- strings[i] = (ASN1OctetString)asn1Obj;
- }
- else
- {
- throw new ASN1Exception("unknown object encountered in constructed OCTET STRING: " + asn1Obj.getClass());
- }
- }
-
- return new BEROctetString(strings);
- case SEQUENCE:
- if (lazyEvaluate)
- {
- return new LazyEncodedSequence(defIn.toByteArray());
- }
- else
- {
- return DLFactory.createSequence(readVector(defIn));
- }
- case SET:
- return DLFactory.createSet(readVector(defIn));
- case EXTERNAL:
- return new DLExternal(readVector(defIn));
- default:
- throw new IOException("unknown tag " + tagNo + " encountered");
+ return DLFactory.EMPTY_SEQUENCE;
+ }
+ else if (lazyEvaluate)
+ {
+ return new LazyEncodedSequence(defIn.toByteArray());
+ }
+ else
+ {
+ return DLFactory.createSequence(readVector(defIn));
}
}
-
- return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
- }
-
- ASN1EncodableVector readVector(DefiniteLengthInputStream dIn) throws IOException
- {
- if (dIn.getRemaining() < 1)
- {
- return new ASN1EncodableVector(0);
+ case SET:
+ return DLFactory.createSet(readVector(defIn));
+ case EXTERNAL:
+ return DLFactory.createSequence(readVector(defIn)).toASN1External();
+ default:
+ throw new IOException("unknown tag " + tagNo + " encountered");
}
-
- ASN1InputStream subStream = new ASN1InputStream(dIn);
- ASN1EncodableVector v = new ASN1EncodableVector();
- ASN1Primitive p;
- while ((p = subStream.readObject()) != null)
- {
- v.add(p);
- }
- return v;
}
@android.compat.annotation.UnsupportedAppUsage
@@ -234,55 +202,12 @@
return null;
}
- //
- // calculate tag number
- //
int tagNo = readTagNumber(this, tag);
-
- boolean isConstructed = (tag & CONSTRUCTED) != 0;
-
- //
- // calculate length
- //
int length = readLength();
- if (length < 0) // indefinite-length method
+ if (length >= 0)
{
- if (!isConstructed)
- {
- throw new IOException("indefinite-length primitive encoding encountered");
- }
-
- IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit);
- ASN1StreamParser sp = new ASN1StreamParser(indIn, limit);
-
- if ((tag & APPLICATION) != 0)
- {
- return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject();
- }
-
- if ((tag & TAGGED) != 0)
- {
- return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject();
- }
-
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagNo)
- {
- case OCTET_STRING:
- return new BEROctetStringParser(sp).getLoadedObject();
- case SEQUENCE:
- return new BERSequenceParser(sp).getLoadedObject();
- case SET:
- return new BERSetParser(sp).getLoadedObject();
- case EXTERNAL:
- return new DERExternalParser(sp).getLoadedObject();
- default:
- throw new IOException("unknown BER object encountered");
- }
- }
- else
- {
+ // definite-length
try
{
return buildObject(tag, tagNo, length);
@@ -292,6 +217,124 @@
throw new ASN1Exception("corrupted stream detected", e);
}
}
+
+ // indefinite-length
+
+ if (0 == (tag & CONSTRUCTED))
+ {
+ throw new IOException("indefinite-length primitive encoding encountered");
+ }
+
+ IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit);
+ ASN1StreamParser sp = new ASN1StreamParser(indIn, limit, tmpBuffers);
+
+ int tagClass = tag & PRIVATE;
+ if (0 != tagClass)
+ {
+ return sp.loadTaggedIL(tagClass, tagNo);
+ }
+
+ switch (tagNo)
+ {
+ case BIT_STRING:
+ return BERBitStringParser.parse(sp);
+ case OCTET_STRING:
+ return BEROctetStringParser.parse(sp);
+ case EXTERNAL:
+ // TODO[asn1] BERExternalParser
+ return DERExternalParser.parse(sp);
+ case SEQUENCE:
+ return BERSequenceParser.parse(sp);
+ case SET:
+ return BERSetParser.parse(sp);
+ default:
+ throw new IOException("unknown BER object encountered");
+ }
+ }
+
+ ASN1BitString buildConstructedBitString(ASN1EncodableVector contentsElements) throws IOException
+ {
+ ASN1BitString[] strings = new ASN1BitString[contentsElements.size()];
+
+ for (int i = 0; i != strings.length; i++)
+ {
+ ASN1Encodable asn1Obj = contentsElements.get(i);
+ if (asn1Obj instanceof ASN1BitString)
+ {
+ strings[i] = (ASN1BitString)asn1Obj;
+ }
+ else
+ {
+ throw new ASN1Exception(
+ "unknown object encountered in constructed BIT STRING: " + asn1Obj.getClass());
+ }
+ }
+
+ // TODO Probably ought to be DLBitString
+ return new BERBitString(strings);
+ }
+
+ ASN1OctetString buildConstructedOctetString(ASN1EncodableVector contentsElements) throws IOException
+ {
+ ASN1OctetString[] strings = new ASN1OctetString[contentsElements.size()];
+
+ for (int i = 0; i != strings.length; i++)
+ {
+ ASN1Encodable asn1Obj = contentsElements.get(i);
+ if (asn1Obj instanceof ASN1OctetString)
+ {
+ strings[i] = (ASN1OctetString)asn1Obj;
+ }
+ else
+ {
+ throw new ASN1Exception(
+ "unknown object encountered in constructed OCTET STRING: " + asn1Obj.getClass());
+ }
+ }
+
+ // TODO Probably ought to be DEROctetString (no DLOctetString available)
+ return new BEROctetString(strings);
+ }
+
+ ASN1Primitive readTaggedObjectDL(int tagClass, int tagNo, boolean constructed, DefiniteLengthInputStream defIn)
+ throws IOException
+ {
+ if (!constructed)
+ {
+ byte[] contentsOctets = defIn.toByteArray();
+ return ASN1TaggedObject.createPrimitive(tagClass, tagNo, contentsOctets);
+ }
+
+ ASN1EncodableVector contentsElements = readVector(defIn);
+ return ASN1TaggedObject.createConstructedDL(tagClass, tagNo, contentsElements);
+ }
+
+ ASN1EncodableVector readVector() throws IOException
+ {
+ ASN1Primitive p = readObject();
+ if (null == p)
+ {
+ return new ASN1EncodableVector(0);
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ do
+ {
+ v.add(p);
+ }
+ while ((p = readObject()) != null);
+ return v;
+ }
+
+ ASN1EncodableVector readVector(DefiniteLengthInputStream defIn) throws IOException
+ {
+ int remaining = defIn.getRemaining();
+ if (remaining < 1)
+ {
+ return new ASN1EncodableVector(0);
+ }
+
+ return new ASN1InputStream(defIn, remaining, lazyEvaluate, tmpBuffers).readVector();
}
static int readTagNumber(InputStream s, int tag)
@@ -304,32 +347,44 @@
//
if (tagNo == 0x1f)
{
- tagNo = 0;
-
int b = s.read();
+ if (b < 31)
+ {
+ if (b < 0)
+ {
+ throw new EOFException("EOF found inside tag value.");
+ }
+ throw new IOException("corrupted stream - high tag number < 31 found");
+ }
+
+ tagNo = b & 0x7f;
// X.690-0207 8.1.2.4.2
// "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
- if ((b & 0x7f) == 0) // Note: -1 will pass
+ if (0 == tagNo)
{
throw new IOException("corrupted stream - invalid high tag number found");
}
- while ((b >= 0) && ((b & 0x80) != 0))
+ while ((b & 0x80) != 0)
{
- tagNo |= (b & 0x7f);
- tagNo <<= 7;
- b = s.read();
- }
+ if ((tagNo >>> 24) != 0)
+ {
+ throw new IOException("Tag number more than 31 bits");
+ }
- if (b < 0)
- {
- throw new EOFException("EOF found inside tag value.");
+ tagNo <<= 7;
+
+ b = s.read();
+ if (b < 0)
+ {
+ throw new EOFException("EOF found inside tag value.");
+ }
+
+ tagNo |= (b & 0x7f);
}
-
- tagNo |= (b & 0x7f);
}
-
+
return tagNo;
}
@@ -337,48 +392,48 @@
throws IOException
{
int length = s.read();
+ if (0 == (length >>> 7))
+ {
+ // definite-length short form
+ return length;
+ }
+ if (0x80 == length)
+ {
+ // indefinite-length
+ return -1;
+ }
if (length < 0)
{
throw new EOFException("EOF found when length expected");
}
-
- if (length == 0x80)
+ if (0xFF == length)
{
- return -1; // indefinite-length encoding
+ throw new IOException("invalid long form definite-length 0xFF");
}
- if (length > 127)
+ int octetsCount = length & 0x7F, octetsPos = 0;
+
+ length = 0;
+ do
{
- int size = length & 0x7f;
-
- // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
- if (size > 4)
+ int octet = s.read();
+ if (octet < 0)
{
- throw new IOException("DER length more than 4 bytes: " + size);
+ throw new EOFException("EOF found reading length");
}
- length = 0;
- for (int i = 0; i < size; i++)
+ if ((length >>> 23) != 0)
{
- int next = s.read();
-
- if (next < 0)
- {
- throw new EOFException("EOF found reading length");
- }
-
- length = (length << 8) + next;
+ throw new IOException("long form definite-length more than 31 bits");
}
- if (length < 0)
- {
- throw new IOException("corrupted stream - negative length found");
- }
+ length = (length << 8) + octet;
+ }
+ while (++octetsPos < octetsCount);
- if (length >= limit && !isParsing) // after all we must have read at least 1 byte
- {
- throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
- }
+ if (length >= limit && !isParsing) // after all we must have read at least 1 byte
+ {
+ throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
}
return length;
@@ -462,50 +517,79 @@
byte[][] tmpBuffers)
throws IOException
{
- switch (tagNo)
+ /*
+ * TODO[asn1] Lookup the universal type object and get it to parse the stream directly (possibly with
+ * access to a single temporary buffer replacing tmpBuffers).
+ */
+ try
{
+ switch (tagNo)
+ {
case BIT_STRING:
- return ASN1BitString.fromInputStream(defIn.getRemaining(), defIn);
+ return ASN1BitString.createPrimitive(defIn.toByteArray());
case BMP_STRING:
- return new DERBMPString(getBMPCharBuffer(defIn));
+ return ASN1BMPString.createPrimitive(getBMPCharBuffer(defIn));
case BOOLEAN:
- return ASN1Boolean.fromOctetString(getBuffer(defIn, tmpBuffers));
+ return ASN1Boolean.createPrimitive(getBuffer(defIn, tmpBuffers));
case ENUMERATED:
- return ASN1Enumerated.fromOctetString(getBuffer(defIn, tmpBuffers));
- case GENERALIZED_TIME:
- return new ASN1GeneralizedTime(defIn.toByteArray());
+ // TODO Ideally only clone if we used a buffer
+ return ASN1Enumerated.createPrimitive(getBuffer(defIn, tmpBuffers), true);
case GENERAL_STRING:
- return new DERGeneralString(defIn.toByteArray());
- case IA5_STRING:
- return new DERIA5String(defIn.toByteArray());
- case INTEGER:
- return new ASN1Integer(defIn.toByteArray(), false);
- case NULL:
- return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?)
- case NUMERIC_STRING:
- return new DERNumericString(defIn.toByteArray());
- case OBJECT_IDENTIFIER:
- return ASN1ObjectIdentifier.fromOctetString(getBuffer(defIn, tmpBuffers));
- case OCTET_STRING:
- return new DEROctetString(defIn.toByteArray());
- case PRINTABLE_STRING:
- return new DERPrintableString(defIn.toByteArray());
- case T61_STRING:
- return new DERT61String(defIn.toByteArray());
- case UNIVERSAL_STRING:
- return new DERUniversalString(defIn.toByteArray());
- case UTC_TIME:
- return new ASN1UTCTime(defIn.toByteArray());
- case UTF8_STRING:
- return new DERUTF8String(defIn.toByteArray());
- case VISIBLE_STRING:
- return new DERVisibleString(defIn.toByteArray());
+ return ASN1GeneralString.createPrimitive(defIn.toByteArray());
+ case GENERALIZED_TIME:
+ return ASN1GeneralizedTime.createPrimitive(defIn.toByteArray());
case GRAPHIC_STRING:
- return new DERGraphicString(defIn.toByteArray());
+ return ASN1GraphicString.createPrimitive(defIn.toByteArray());
+ case IA5_STRING:
+ return ASN1IA5String.createPrimitive(defIn.toByteArray());
+ case INTEGER:
+ return ASN1Integer.createPrimitive(defIn.toByteArray());
+ case NULL:
+ return ASN1Null.createPrimitive(defIn.toByteArray());
+ case NUMERIC_STRING:
+ return ASN1NumericString.createPrimitive(defIn.toByteArray());
+ case OBJECT_DESCRIPTOR:
+ return ASN1ObjectDescriptor.createPrimitive(defIn.toByteArray());
+ case OBJECT_IDENTIFIER:
+ // TODO Ideally only clone if we used a buffer
+ return ASN1ObjectIdentifier.createPrimitive(getBuffer(defIn, tmpBuffers), true);
+ case OCTET_STRING:
+ return ASN1OctetString.createPrimitive(defIn.toByteArray());
+ case PRINTABLE_STRING:
+ return ASN1PrintableString.createPrimitive(defIn.toByteArray());
+ case RELATIVE_OID:
+ return ASN1RelativeOID.createPrimitive(defIn.toByteArray(), false);
+ case T61_STRING:
+ return ASN1T61String.createPrimitive(defIn.toByteArray());
+ case UNIVERSAL_STRING:
+ return ASN1UniversalString.createPrimitive(defIn.toByteArray());
+ case UTC_TIME:
+ return ASN1UTCTime.createPrimitive(defIn.toByteArray());
+ case UTF8_STRING:
+ return ASN1UTF8String.createPrimitive(defIn.toByteArray());
case VIDEOTEX_STRING:
- return new DERVideotexString(defIn.toByteArray());
+ return ASN1VideotexString.createPrimitive(defIn.toByteArray());
+ case VISIBLE_STRING:
+ return ASN1VisibleString.createPrimitive(defIn.toByteArray());
+ case TIME:
+ case DATE:
+ case TIME_OF_DAY:
+ case DATE_TIME:
+ case DURATION:
+ case OBJECT_IDENTIFIER_IRI:
+ case RELATIVE_OID_IRI:
+ throw new IOException("unsupported tag " + tagNo + " encountered");
default:
throw new IOException("unknown tag " + tagNo + " encountered");
+ }
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception(e.getMessage(), e);
+ }
+ catch (IllegalStateException e)
+ {
+ throw new ASN1Exception(e.getMessage(), e);
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Integer.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Integer.java
index 4e2d68e..22fc045 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Integer.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Integer.java
@@ -14,6 +14,14 @@
public class ASN1Integer
extends ASN1Primitive
{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Integer.class, BERTags.INTEGER)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
static final int SIGN_EXT_SIGNED = 0xFFFFFFFF;
static final int SIGN_EXT_UNSIGNED = 0xFF;
@@ -39,7 +47,7 @@
{
try
{
- return (ASN1Integer)fromByteArray((byte[])obj);
+ return (ASN1Integer)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -53,27 +61,16 @@
/**
* Return an Integer from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @return an ASN1Integer instance.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
*/
- public static ASN1Integer getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1Integer getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1Integer)
- {
- return getInstance(o);
- }
- else
- {
- return new ASN1Integer(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1Integer)TYPE.getContextInstance(taggedObject, explicit);
}
/**
@@ -153,6 +150,18 @@
return new BigInteger(bytes);
}
+ public boolean hasValue(int x)
+ {
+ return (bytes.length - start) <= 4
+ && intValue(bytes, start, SIGN_EXT_SIGNED) == x;
+ }
+
+ public boolean hasValue(long x)
+ {
+ return (bytes.length - start) <= 8
+ && longValue(bytes, start, SIGN_EXT_SIGNED) == x;
+ }
+
public boolean hasValue(BigInteger x)
{
return null != x
@@ -194,19 +203,19 @@
return longValue(bytes, start, SIGN_EXT_SIGNED);
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, bytes.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.INTEGER, bytes);
+ out.writeEncodingDL(withTag, BERTags.INTEGER, bytes);
}
public int hashCode()
@@ -231,6 +240,11 @@
return getValue().toString();
}
+ static ASN1Integer createPrimitive(byte[] contents)
+ {
+ return new ASN1Integer(contents, false);
+ }
+
static int intValue(byte[] bytes, int start, int signExt)
{
int length = bytes.length;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Null.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Null.java
index 6737fd5..6545545 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Null.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Null.java
@@ -1,7 +1,4 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
-/***************************************************************/
-/****** DO NOT EDIT THIS CLASS bc-java SOURCE FILE ******/
-/***************************************************************/
package com.android.org.bouncycastle.asn1;
import java.io.IOException;
@@ -13,10 +10,13 @@
public abstract class ASN1Null
extends ASN1Primitive
{
- ASN1Null()
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Null.class, BERTags.NULL)
{
-
- }
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
/**
* Return an instance of ASN.1 NULL from the passed in object.
@@ -44,21 +44,26 @@
{
try
{
- return ASN1Null.getInstance(ASN1Primitive.fromByteArray((byte[])o));
+ return (ASN1Null)TYPE.fromByteArray((byte[])o);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct NULL from byte[]: " + e.getMessage());
}
- catch (ClassCastException e)
- {
- throw new IllegalArgumentException("unknown object in getInstance(): " + o.getClass().getName());
- }
}
return null;
}
+ public static ASN1Null getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1Null)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ ASN1Null()
+ {
+ }
+
public int hashCode()
{
return -1;
@@ -75,10 +80,17 @@
return true;
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
return "NULL";
}
+
+ static ASN1Null createPrimitive(byte[] contents)
+ {
+ if (0 != contents.length)
+ {
+ throw new IllegalStateException("malformed NULL encoding encountered");
+ }
+ return DERNull.INSTANCE;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1NumericString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1NumericString.java
new file mode 100644
index 0000000..c384bb3
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1NumericString.java
@@ -0,0 +1,215 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
+ * ASN.1 NUMERIC-STRING object.
+ * <p>
+ * This is an ASCII string of characters {0,1,2,3,4,5,6,7,8,9} + space.
+ * <p>
+ * See X.680 section 37.2.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1NumericString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1NumericString.class, BERTags.NUMERIC_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a Numeric string from the passed in object
+ *
+ * @param obj an ASN1NumericString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1NumericString instance, or null
+ */
+ public static ASN1NumericString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1NumericString)
+ {
+ return (ASN1NumericString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1NumericString)
+ {
+ return (ASN1NumericString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1NumericString)TYPE.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());
+ }
+
+ /**
+ * Return an Numeric String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1NumericString instance, or null.
+ */
+ public static ASN1NumericString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1NumericString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ /**
+ * Constructor with optional validation.
+ *
+ * @param string the base string to wrap.
+ * @param validate whether or not to check the string.
+ * @throws IllegalArgumentException if validate is true and the string
+ * contains characters that should not be in a NumericString.
+ */
+ ASN1NumericString(String string, boolean validate)
+ {
+ if (validate && !isNumericString(string))
+ {
+ throw new IllegalArgumentException("string contains illegal characters");
+ }
+
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1NumericString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.NUMERIC_STRING, contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1NumericString))
+ {
+ return false;
+ }
+
+ ASN1NumericString that = (ASN1NumericString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ /**
+ * Return true if the string can be represented as a NumericString ('0'..'9', ' ')
+ *
+ * @param str string to validate.
+ * @return true if numeric, false otherwise.
+ */
+ public static boolean isNumericString(String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+
+ if (('0' <= ch && ch <= '9') || ch == ' ')
+ {
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ static boolean isNumericString(byte[] contents)
+ {
+ for (int i = 0; i < contents.length; ++i)
+ {
+ switch (contents[i])
+ {
+ case 0x20:
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ case 0x38:
+ case 0x39:
+ break;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ static ASN1NumericString createPrimitive(byte[] contents)
+ {
+ // TODO Validation - sort out exception types
+// if (!isNumericString(contents))
+
+ return new DERNumericString(contents, false);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Object.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Object.java
index d582aa8..eca3120 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Object.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Object.java
@@ -19,12 +19,12 @@
public void encodeTo(OutputStream output) throws IOException
{
- ASN1OutputStream.create(output).writeObject(this);
+ toASN1Primitive().encodeTo(output);
}
public void encodeTo(OutputStream output, String encoding) throws IOException
{
- ASN1OutputStream.create(output, encoding).writeObject(this);
+ toASN1Primitive().encodeTo(output, encoding);
}
/**
@@ -36,7 +36,7 @@
public byte[] getEncoded() throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- encodeTo(bOut);
+ toASN1Primitive().encodeTo(bOut);
return bOut.toByteArray();
}
@@ -50,7 +50,7 @@
public byte[] getEncoded(String encoding) throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- encodeTo(bOut, encoding);
+ toASN1Primitive().encodeTo(bOut, encoding);
return bOut.toByteArray();
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectDescriptor.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectDescriptor.java
new file mode 100644
index 0000000..2b02186
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectDescriptor.java
@@ -0,0 +1,145 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class ASN1ObjectDescriptor
+ extends ASN1Primitive
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1ObjectDescriptor.class, BERTags.OBJECT_DESCRIPTOR)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return new ASN1ObjectDescriptor(
+ (ASN1GraphicString)ASN1GraphicString.TYPE.fromImplicitPrimitive(octetString));
+ }
+
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return new ASN1ObjectDescriptor(
+ (ASN1GraphicString)ASN1GraphicString.TYPE.fromImplicitConstructed(sequence));
+ }
+ };
+
+ /**
+ * Return an ObjectDescriptor from the passed in object.
+ *
+ * @param obj an ASN1ObjectDescriptor or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1ObjectDescriptor instance, or null.
+ */
+ public static ASN1ObjectDescriptor getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1ObjectDescriptor)
+ {
+ return (ASN1ObjectDescriptor)obj;
+ }
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1ObjectDescriptor)
+ {
+ return (ASN1ObjectDescriptor)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1ObjectDescriptor)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct object descriptor from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an ObjectDescriptor from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly tagged,
+ * false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1ObjectDescriptor instance, or null.
+ */
+ public static ASN1ObjectDescriptor getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1ObjectDescriptor)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ private final ASN1GraphicString baseGraphicString;
+
+ public ASN1ObjectDescriptor(ASN1GraphicString baseGraphicString)
+ {
+ if (null == baseGraphicString)
+ {
+ throw new NullPointerException("'baseGraphicString' cannot be null");
+ }
+
+ this.baseGraphicString = baseGraphicString;
+ }
+
+ public ASN1GraphicString getBaseGraphicString()
+ {
+ return baseGraphicString;
+ }
+
+ boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength(boolean withTag)
+ {
+ return baseGraphicString.encodedLength(withTag);
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeIdentifier(withTag, BERTags.OBJECT_DESCRIPTOR);
+ baseGraphicString.encode(out, false);
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ ASN1GraphicString der = (ASN1GraphicString)baseGraphicString.toDERObject();
+
+ return der == baseGraphicString ? this : new ASN1ObjectDescriptor(der);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ ASN1GraphicString dl = (ASN1GraphicString)baseGraphicString.toDLObject();
+
+ return dl == baseGraphicString ? this : new ASN1ObjectDescriptor(dl);
+ }
+
+ boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1ObjectDescriptor))
+ {
+ return false;
+ }
+
+ ASN1ObjectDescriptor that = (ASN1ObjectDescriptor)other;
+
+ return this.baseGraphicString.asn1Equals(that.baseGraphicString);
+ }
+
+ public int hashCode()
+ {
+ return ~baseGraphicString.hashCode();
+ }
+
+ static ASN1ObjectDescriptor createPrimitive(byte[] contents)
+ {
+ return new ASN1ObjectDescriptor(ASN1GraphicString.createPrimitive(contents));
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
index 452a3a0..f6903dd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
@@ -16,9 +16,18 @@
public class ASN1ObjectIdentifier
extends ASN1Primitive
{
- private final String identifier;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1ObjectIdentifier.class, BERTags.OBJECT_IDENTIFIER)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets(), false);
+ }
+ };
- private byte[] body;
+ public static ASN1ObjectIdentifier fromContents(byte[] contents)
+ {
+ return createPrimitive(contents, true);
+ }
/**
* Return an OID from the passed in object
@@ -27,30 +36,25 @@
* @return an ASN1ObjectIdentifier instance, or null.
* @throws IllegalArgumentException if the object cannot be converted.
*/
- public static ASN1ObjectIdentifier getInstance(
- Object obj)
+ public static ASN1ObjectIdentifier getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1ObjectIdentifier)
{
return (ASN1ObjectIdentifier)obj;
}
-
- if (obj instanceof ASN1Encodable)
+ else if (obj instanceof ASN1Encodable)
{
ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
if (primitive instanceof ASN1ObjectIdentifier)
{
return (ASN1ObjectIdentifier)primitive;
}
}
-
- if (obj instanceof byte[])
+ else if (obj instanceof byte[])
{
- byte[] enc = (byte[])obj;
try
{
- return (ASN1ObjectIdentifier)fromByteArray(enc);
+ return (ASN1ObjectIdentifier)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
@@ -64,47 +68,60 @@
/**
* Return an OBJECT IDENTIFIER from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @return an ASN1ObjectIdentifier instance, or null.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
*/
- public static ASN1ObjectIdentifier getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1ObjectIdentifier getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
+ /*
+ * TODO[asn1] This block here is for backward compatibility, but should eventually be removed.
+ *
+ * - see https://github.com/bcgit/bc-java/issues/1015
+ */
+ if (!explicit && !taggedObject.isParsed() && BERTags.CONTEXT_SPECIFIC == taggedObject.getTagClass())
+ {
+ ASN1Primitive base = taggedObject.getBaseObject().toASN1Primitive();
+ if (!(base instanceof ASN1ObjectIdentifier))
+ {
+ return fromContents(ASN1OctetString.getInstance(base).getOctets());
+ }
+ }
- if (explicit || o instanceof ASN1ObjectIdentifier)
- {
- return getInstance(o);
- }
- else
- {
- return ASN1ObjectIdentifier.fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1ObjectIdentifier)TYPE.getContextInstance(taggedObject, explicit);
}
- private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f;
+ private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7F;
- ASN1ObjectIdentifier(
- byte[] bytes)
+ private static final ConcurrentMap<OidHandle, ASN1ObjectIdentifier> pool =
+ new ConcurrentHashMap<OidHandle, ASN1ObjectIdentifier>();
+
+ private final String identifier;
+ private byte[] contents;
+
+ ASN1ObjectIdentifier(byte[] contents, boolean clone)
{
- StringBuffer objId = new StringBuffer();
+ if (contents.length == 0)
+ {
+ throw new IllegalArgumentException("empty OBJECT IDENTIFIER with no sub-identifiers");
+ }
+
+ StringBuilder objId = new StringBuilder();
long value = 0;
BigInteger bigValue = null;
boolean first = true;
- for (int i = 0; i != bytes.length; i++)
+ for (int i = 0; i != contents.length; i++)
{
- int b = bytes[i] & 0xff;
+ int b = contents[i] & 0xff;
if (value <= LONG_LIMIT)
{
- value += (b & 0x7f);
- if ((b & 0x80) == 0) // end of number reached
+ value += b & 0x7F;
+ if ((b & 0x80) == 0)
{
if (first)
{
@@ -140,7 +157,7 @@
{
bigValue = BigInteger.valueOf(value);
}
- bigValue = bigValue.or(BigInteger.valueOf(b & 0x7f));
+ bigValue = bigValue.or(BigInteger.valueOf(b & 0x7F));
if ((b & 0x80) == 0)
{
if (first)
@@ -164,7 +181,7 @@
// Android-changed: Intern the identifier so there aren't hundreds of duplicates in practice.
this.identifier = objId.toString().intern();
- this.body = Arrays.clone(bytes);
+ this.contents = clone ? Arrays.clone(contents) : contents;
}
/**
@@ -196,7 +213,7 @@
*/
ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branchID)
{
- if (!isValidBranchID(branchID, 0))
+ if (!ASN1RelativeOID.isValidIdentifier(branchID, 0))
{
throw new IllegalArgumentException("string " + branchID + " not a valid OID branch");
}
@@ -237,44 +254,6 @@
return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId);
}
- private void writeField(
- ByteArrayOutputStream out,
- long fieldValue)
- {
- byte[] result = new byte[9];
- int pos = 8;
- result[pos] = (byte)((int)fieldValue & 0x7f);
- while (fieldValue >= (1L << 7))
- {
- fieldValue >>= 7;
- result[--pos] = (byte)((int)fieldValue & 0x7f | 0x80);
- }
- out.write(result, pos, 9 - pos);
- }
-
- private void writeField(
- ByteArrayOutputStream out,
- BigInteger fieldValue)
- {
- int byteCount = (fieldValue.bitLength() + 6) / 7;
- if (byteCount == 0)
- {
- out.write(0);
- }
- else
- {
- BigInteger tmpValue = fieldValue;
- byte[] tmp = new byte[byteCount];
- for (int i = byteCount - 1; i >= 0; i--)
- {
- tmp[i] = (byte)((tmpValue.intValue() & 0x7f) | 0x80);
- tmpValue = tmpValue.shiftRight(7);
- }
- tmp[byteCount - 1] &= 0x7f;
- out.write(tmp, 0, tmp.length);
- }
- }
-
private void doOutput(ByteArrayOutputStream aOut)
{
OIDTokenizer tok = new OIDTokenizer(identifier);
@@ -283,11 +262,11 @@
String secondToken = tok.nextToken();
if (secondToken.length() <= 18)
{
- writeField(aOut, first + Long.parseLong(secondToken));
+ ASN1RelativeOID.writeField(aOut, first + Long.parseLong(secondToken));
}
else
{
- writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
+ ASN1RelativeOID.writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
}
while (tok.hasMoreTokens())
@@ -295,45 +274,42 @@
String token = tok.nextToken();
if (token.length() <= 18)
{
- writeField(aOut, Long.parseLong(token));
+ ASN1RelativeOID.writeField(aOut, Long.parseLong(token));
}
else
{
- writeField(aOut, new BigInteger(token));
+ ASN1RelativeOID.writeField(aOut, new BigInteger(token));
}
}
}
- private synchronized byte[] getBody()
+ private synchronized byte[] getContents()
{
- if (body == null)
+ if (contents == null)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
doOutput(bOut);
- body = bOut.toByteArray();
+ contents = bOut.toByteArray();
}
- return body;
+ return contents;
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
- throws IOException
+ int encodedLength(boolean withTag)
{
- int length = getBody().length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContents().length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.OBJECT_IDENTIFIER, getBody());
+ out.writeEncodingDL(withTag, BERTags.OBJECT_IDENTIFIER, getContents());
}
public int hashCode()
@@ -362,45 +338,6 @@
return getId();
}
- private static boolean isValidBranchID(
- String branchID, int start)
- {
- int digitCount = 0;
-
- int pos = branchID.length();
- while (--pos >= start)
- {
- char ch = branchID.charAt(pos);
-
- if (ch == '.')
- {
- if (0 == digitCount
- || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
- {
- return false;
- }
-
- digitCount = 0;
- }
- else if ('0' <= ch && ch <= '9')
- {
- ++digitCount;
- }
- else
- {
- return false;
- }
- }
-
- if (0 == digitCount
- || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
- {
- return false;
- }
-
- return true;
- }
-
private static boolean isValidIdentifier(
String identifier)
{
@@ -415,7 +352,7 @@
return false;
}
- return isValidBranchID(identifier, 2);
+ return ASN1RelativeOID.isValidIdentifier(identifier, 2);
}
/**
@@ -430,30 +367,35 @@
*/
public ASN1ObjectIdentifier intern()
{
- final OidHandle hdl = new OidHandle(getBody());
+ final OidHandle hdl = new OidHandle(getContents());
ASN1ObjectIdentifier oid = pool.get(hdl);
if (oid == null)
{
- oid = pool.putIfAbsent(hdl, this);
- if (oid == null)
+ synchronized (pool)
{
- oid = this;
+ if (!pool.containsKey(hdl))
+ {
+ pool.put(hdl, this);
+ return this;
+ }
+ else
+ {
+ return pool.get(hdl);
+ }
}
}
return oid;
}
- private static final ConcurrentMap<OidHandle, ASN1ObjectIdentifier> pool = new ConcurrentHashMap<OidHandle, ASN1ObjectIdentifier>();
-
private static class OidHandle
{
private final int key;
- private final byte[] enc;
+ private final byte[] contents;
- OidHandle(byte[] enc)
+ OidHandle(byte[] contents)
{
- this.key = Arrays.hashCode(enc);
- this.enc = enc;
+ this.key = Arrays.hashCode(contents);
+ this.contents = contents;
}
public int hashCode()
@@ -465,20 +407,20 @@
{
if (o instanceof OidHandle)
{
- return Arrays.areEqual(enc, ((OidHandle)o).enc);
+ return Arrays.areEqual(contents, ((OidHandle)o).contents);
}
return false;
}
}
- static ASN1ObjectIdentifier fromOctetString(byte[] enc)
+ static ASN1ObjectIdentifier createPrimitive(byte[] contents, boolean clone)
{
- final OidHandle hdl = new OidHandle(enc);
+ final OidHandle hdl = new OidHandle(contents);
ASN1ObjectIdentifier oid = pool.get(hdl);
if (oid == null)
{
- return new ASN1ObjectIdentifier(enc);
+ return new ASN1ObjectIdentifier(contents, clone);
}
return oid;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OctetString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OctetString.java
index 30351c2..831b780 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OctetString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OctetString.java
@@ -102,7 +102,18 @@
extends ASN1Primitive
implements ASN1OctetStringParser
{
- byte[] string;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1OctetString.class, BERTags.OCTET_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return octetString;
+ }
+
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence.toASN1OctetString();
+ }
+ };
/**
* return an Octet String from a tagged object.
@@ -113,70 +124,9 @@
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
- public static ASN1OctetString getInstance(
- ASN1TaggedObject taggedObject,
- boolean explicit)
+ public static ASN1OctetString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- if (explicit)
- {
- if (!taggedObject.isExplicit())
- {
- throw new IllegalArgumentException("object implicit - explicit expected.");
- }
-
- return getInstance(taggedObject.getObject());
- }
-
- ASN1Primitive o = taggedObject.getObject();
-
- /*
- * constructed object which appears to be explicitly tagged and it's really implicit means
- * we have to add the surrounding octet string.
- */
- if (taggedObject.isExplicit())
- {
- ASN1OctetString singleSegment = getInstance(o);
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BEROctetString(new ASN1OctetString[]{ singleSegment });
- }
-
- // TODO Should really be similar to the BERTaggedObject case above:
-// return new DLOctetString(new ASN1OctetString[]{ singleSegment });
- return (ASN1OctetString)new BEROctetString(new ASN1OctetString[]{ singleSegment }).toDLObject();
- }
-
- if (o instanceof ASN1OctetString)
- {
- ASN1OctetString s = (ASN1OctetString)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return s;
- }
-
- return (ASN1OctetString)s.toDLObject();
- }
-
- /*
- * in this case the parser returns a sequence, convert it into an octet string.
- */
- if (o instanceof ASN1Sequence)
- {
- ASN1Sequence s = (ASN1Sequence)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return BEROctetString.fromSequence(s);
- }
-
- // TODO Should really be similar to the BERTaggedObject case above:
-// return DLOctetString.fromSequence(s);
- return (ASN1OctetString)BEROctetString.fromSequence(s).toDLObject();
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ return (ASN1OctetString)TYPE.getContextInstance(taggedObject, explicit);
}
/**
@@ -185,37 +135,40 @@
* @param obj the object we want converted.
* @exception IllegalArgumentException if the object cannot be converted.
*/
- public static ASN1OctetString getInstance(
- Object obj)
+ public static ASN1OctetString getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1OctetString)
{
return (ASN1OctetString)obj;
}
+// else if (obj instanceof ASN1OctetStringParser)
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1OctetString)
+ {
+ return (ASN1OctetString)primitive;
+ }
+ }
else if (obj instanceof byte[])
{
try
{
- return getInstance(fromByteArray((byte[])obj));
+ return (ASN1OctetString)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct OCTET STRING from byte[]: " + e.getMessage());
}
}
- else if (obj instanceof ASN1Encodable)
- {
- ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
- if (primitive instanceof ASN1OctetString)
- {
- return (ASN1OctetString)primitive;
- }
- }
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
+ static final byte[] EMPTY_OCTETS = new byte[0];
+
+ byte[] string;
+
/**
* Base constructor.
*
@@ -261,6 +214,11 @@
return string;
}
+ public int getOctetsLength()
+ {
+ return getOctets().length;
+ }
+
public int hashCode()
{
return Arrays.hashCode(this.getOctets());
@@ -294,10 +252,13 @@
return new DEROctetString(string);
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
return "#" + Strings.fromByteArray(Hex.encode(string));
}
+
+ static ASN1OctetString createPrimitive(byte[] contents)
+ {
+ return new DEROctetString(contents);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OutputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OutputStream.java
index 0c2c931..b84a84a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OutputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OutputStream.java
@@ -34,250 +34,33 @@
private OutputStream os;
- /**
- * @deprecated Use {@link ASN1OutputStream#create(OutputStream)} instead.
- */
- public ASN1OutputStream(OutputStream os)
+ ASN1OutputStream(OutputStream os)
{
this.os = os;
}
- final void writeLength(
- int length)
- throws IOException
+ public void close() throws IOException
{
- if (length > 127)
- {
- int size = 1;
- int val = length;
-
- while ((val >>>= 8) != 0)
- {
- size++;
- }
-
- write((byte)(size | 0x80));
-
- for (int i = (size - 1) * 8; i >= 0; i -= 8)
- {
- write((byte)(length >> i));
- }
- }
- else
- {
- write((byte)length);
- }
+ os.close();
}
- final void write(int b)
- throws IOException
+ public void flush() throws IOException
{
- os.write(b);
+ os.flush();
}
- final void write(byte[] bytes, int off, int len)
- throws IOException
+ public final void writeObject(ASN1Encodable encodable) throws IOException
{
- os.write(bytes, off, len);
- }
-
- final void writeElements(ASN1Encodable[] elements)
- throws IOException
- {
- int count = elements.length;
- for (int i = 0; i < count; ++i)
- {
- ASN1Primitive primitive = elements[i].toASN1Primitive();
-
- writePrimitive(primitive, true);
- }
- }
-
- final void writeElements(Enumeration elements)
- throws IOException
- {
- while (elements.hasMoreElements())
- {
- ASN1Primitive primitive = ((ASN1Encodable)elements.nextElement()).toASN1Primitive();
-
- writePrimitive(primitive, true);
- }
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte contents)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(1);
- write(contents);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte[] contents)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(contents.length);
- write(contents, 0, contents.length);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte[] contents,
- int contentsOff,
- int contentsLen)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(contentsLen);
- write(contents, contentsOff, contentsLen);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte headByte,
- byte[] tailBytes)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(1 + tailBytes.length);
- write(headByte);
- write(tailBytes, 0, tailBytes.length);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte headByte,
- byte[] body,
- int bodyOff,
- int bodyLen,
- byte tailByte)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(2 + bodyLen);
- write(headByte);
- write(body, bodyOff, bodyLen);
- write(tailByte);
- }
-
- final void writeEncoded(boolean withTag, int flags, int tagNo, byte[] contents)
- throws IOException
- {
- writeTag(withTag, flags, tagNo);
- writeLength(contents.length);
- write(contents, 0, contents.length);
- }
-
- final void writeEncodedIndef(boolean withTag, int flags, int tagNo, byte[] contents)
- throws IOException
- {
- writeTag(withTag, flags, tagNo);
- write(0x80);
- write(contents, 0, contents.length);
- write(0x00);
- write(0x00);
- }
-
- final void writeEncodedIndef(boolean withTag, int tag, ASN1Encodable[] elements)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- write(0x80);
- writeElements(elements);
- write(0x00);
- write(0x00);
- }
-
- final void writeEncodedIndef(boolean withTag, int tag, Enumeration elements)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- write(0x80);
- writeElements(elements);
- write(0x00);
- write(0x00);
- }
-
- final void writeTag(boolean withTag, int flags, int tagNo)
- throws IOException
- {
- if (!withTag)
- {
- return;
- }
-
- if (tagNo < 31)
- {
- write(flags | tagNo);
- }
- else
- {
- write(flags | 0x1f);
- if (tagNo < 128)
- {
- write(tagNo);
- }
- else
- {
- byte[] stack = new byte[5];
- int pos = stack.length;
-
- stack[--pos] = (byte)(tagNo & 0x7F);
-
- do
- {
- tagNo >>= 7;
- stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
- }
- while (tagNo > 127);
-
- write(stack, pos, stack.length - pos);
- }
- }
- }
-
- public void writeObject(ASN1Encodable obj) throws IOException
- {
- if (null == obj)
+ if (null == encodable)
{
throw new IOException("null object detected");
}
- writePrimitive(obj.toASN1Primitive(), true);
+ writePrimitive(encodable.toASN1Primitive(), true);
flushInternal();
}
- public void writeObject(ASN1Primitive primitive) throws IOException
+ public final void writeObject(ASN1Primitive primitive) throws IOException
{
if (null == primitive)
{
@@ -288,25 +71,7 @@
flushInternal();
}
- void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
- {
- primitive.encode(this, withTag);
- }
-
- public void close()
- throws IOException
- {
- os.close();
- }
-
- public void flush()
- throws IOException
- {
- os.flush();
- }
-
- void flushInternal()
- throws IOException
+ void flushInternal() throws IOException
{
// Placeholder to support future internal buffering
}
@@ -316,8 +81,192 @@
return new DEROutputStream(os);
}
- ASN1OutputStream getDLSubStream()
+ DLOutputStream getDLSubStream()
{
return new DLOutputStream(os);
}
+
+ final void writeDL(int length) throws IOException
+ {
+ if (length < 128)
+ {
+ write(length);
+ }
+ else
+ {
+ byte[] stack = new byte[5];
+ int pos = stack.length;
+
+ do
+ {
+ stack[--pos] = (byte)length;
+ length >>>= 8;
+ }
+ while (length != 0);
+
+ int count = stack.length - pos;
+ stack[--pos] = (byte)(0x80 | count);
+
+ write(stack, pos, count + 1);
+ }
+ }
+
+ final void write(int b) throws IOException
+ {
+ os.write(b);
+ }
+
+ final void write(byte[] bytes, int off, int len) throws IOException
+ {
+ os.write(bytes, off, len);
+ }
+
+ void writeElements(ASN1Encodable[] elements)
+ throws IOException
+ {
+ for (int i = 0, count = elements.length; i < count; ++i)
+ {
+ elements[i].toASN1Primitive().encode(this, true);
+ }
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte contents) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(1);
+ write(contents);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte[] contents) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(contents.length);
+ write(contents, 0, contents.length);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte[] contents, int contentsOff, int contentsLen)
+ throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(contentsLen);
+ write(contents, contentsOff, contentsLen);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte contentsPrefix, byte[] contents, int contentsOff,
+ int contentsLen) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(1 + contentsLen);
+ write(contentsPrefix);
+ write(contents, contentsOff, contentsLen);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte[] contents, int contentsOff, int contentsLen,
+ byte contentsSuffix) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(contentsLen + 1);
+ write(contents, contentsOff, contentsLen);
+ write(contentsSuffix);
+ }
+
+ final void writeEncodingDL(boolean withID, int flags, int tag, byte[] contents) throws IOException
+ {
+ writeIdentifier(withID, flags, tag);
+ writeDL(contents.length);
+ write(contents, 0, contents.length);
+ }
+
+ final void writeEncodingIL(boolean withID, int identifier, ASN1Encodable[] elements) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ write(0x80);
+ writeElements(elements);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeIdentifier(boolean withID, int identifier) throws IOException
+ {
+ if (withID)
+ {
+ write(identifier);
+ }
+ }
+
+ final void writeIdentifier(boolean withID, int flags, int tag) throws IOException
+ {
+ if (!withID)
+ {
+ // Don't write the identifier
+ }
+ else if (tag < 31)
+ {
+ write(flags | tag);
+ }
+ else
+ {
+ byte[] stack = new byte[6];
+ int pos = stack.length;
+
+ stack[--pos] = (byte)(tag & 0x7F);
+ while (tag > 127)
+ {
+ tag >>>= 7;
+ stack[--pos] = (byte)(tag & 0x7F | 0x80);
+ }
+
+ stack[--pos] = (byte)(flags | 0x1F);
+
+ write(stack, pos, stack.length - pos);
+ }
+ }
+
+ void writePrimitive(ASN1Primitive primitive, boolean withID) throws IOException
+ {
+ primitive.encode(this, withID);
+ }
+
+ void writePrimitives(ASN1Primitive[] primitives) throws IOException
+ {
+ for (int i = 0, count = primitives.length; i < count; ++i)
+ {
+ primitives[i].encode(this, true);
+ }
+ }
+
+ static int getLengthOfDL(int dl)
+ {
+ if (dl < 128)
+ {
+ return 1;
+ }
+
+ int length = 2;
+ while ((dl >>>= 8) != 0)
+ {
+ ++length;
+ }
+ return length;
+ }
+
+ static int getLengthOfEncodingDL(boolean withID, int contentsLength)
+ {
+ return (withID ? 1 : 0) + getLengthOfDL(contentsLength) + contentsLength;
+ }
+
+ static int getLengthOfIdentifier(int tag)
+ {
+ if (tag < 31)
+ {
+ return 1;
+ }
+
+ int length = 2;
+ while ((tag >>>= 7) != 0)
+ {
+ ++length;
+ }
+ return length;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Primitive.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Primitive.java
index c3b423b..e646dd0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Primitive.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Primitive.java
@@ -17,12 +17,16 @@
public void encodeTo(OutputStream output) throws IOException
{
- ASN1OutputStream.create(output).writeObject(this);
+ ASN1OutputStream asn1Out = ASN1OutputStream.create(output);
+ asn1Out.writePrimitive(this, true);
+ asn1Out.flushInternal();
}
public void encodeTo(OutputStream output, String encoding) throws IOException
{
- ASN1OutputStream.create(output, encoding).writeObject(this);
+ ASN1OutputStream asn1Out = ASN1OutputStream.create(output, encoding);
+ asn1Out.writePrimitive(this, true);
+ asn1Out.flushInternal();
}
/**
@@ -105,14 +109,9 @@
* Return true if this objected is a CONSTRUCTED one, false otherwise.
* @return true if CONSTRUCTED bit set on object's tag, false otherwise.
*/
- abstract boolean isConstructed();
+ abstract boolean encodeConstructed();
- /**
- * Return the length of the encoding this object will produce.
- * @return the length of the object's encoding.
- * @throws IOException if the encoding length cannot be calculated.
- */
- abstract int encodedLength() throws IOException;
+ abstract int encodedLength(boolean withTag) throws IOException;
abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1PrintableString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1PrintableString.java
new file mode 100644
index 0000000..a0de296
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1PrintableString.java
@@ -0,0 +1,231 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 PrintableString object.
+ * <p>
+ * X.680 section 37.4 defines PrintableString character codes as ASCII subset of following characters:
+ * </p>
+ * <ul>
+ * <li>Latin capital letters: 'A' .. 'Z'</li>
+ * <li>Latin small letters: 'a' .. 'z'</li>
+ * <li>Digits: '0'..'9'</li>
+ * <li>Space</li>
+ * <li>Apostrophe: '\''</li>
+ * <li>Left parenthesis: '('</li>
+ * <li>Right parenthesis: ')'</li>
+ * <li>Plus sign: '+'</li>
+ * <li>Comma: ','</li>
+ * <li>Hyphen-minus: '-'</li>
+ * <li>Full stop: '.'</li>
+ * <li>Solidus: '/'</li>
+ * <li>Colon: ':'</li>
+ * <li>Equals sign: '='</li>
+ * <li>Question mark: '?'</li>
+ * </ul>
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1PrintableString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1PrintableString.class, BERTags.PRINTABLE_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a printable string from the passed in object.
+ *
+ * @param obj an ASN1PrintableString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1PrintableString instance, or null.
+ */
+ public static ASN1PrintableString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1PrintableString)
+ {
+ return (ASN1PrintableString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1PrintableString)
+ {
+ return (ASN1PrintableString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1PrintableString)TYPE.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());
+ }
+
+ /**
+ * Return a Printable String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1PrintableString instance, or null.
+ */
+ public static ASN1PrintableString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1PrintableString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ /**
+ * Constructor with optional validation.
+ *
+ * @param string the base string to wrap.
+ * @param validate whether or not to check the string.
+ * @throws IllegalArgumentException if validate is true and the string
+ * contains characters that should not be in a PrintableString.
+ */
+ ASN1PrintableString(String string, boolean validate)
+ {
+ if (validate && !isPrintableString(string))
+ {
+ throw new IllegalArgumentException("string contains illegal characters");
+ }
+
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1PrintableString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.PRINTABLE_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1PrintableString))
+ {
+ return false;
+ }
+
+ ASN1PrintableString that = (ASN1PrintableString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ /**
+ * return true if the passed in String can be represented without
+ * loss as a PrintableString, false otherwise.
+ *
+ * @return true if in printable set, false otherwise.
+ */
+ public static boolean isPrintableString(
+ String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+
+ if ('a' <= ch && ch <= 'z')
+ {
+ continue;
+ }
+
+ if ('A' <= ch && ch <= 'Z')
+ {
+ continue;
+ }
+
+ if ('0' <= ch && ch <= '9')
+ {
+ continue;
+ }
+
+ switch (ch)
+ {
+ case ' ':
+ case '\'':
+ case '(':
+ case ')':
+ case '+':
+ case '-':
+ case '.':
+ case ':':
+ case '=':
+ case '?':
+ case '/':
+ case ',':
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ static ASN1PrintableString createPrimitive(byte[] contents)
+ {
+ return new DERPrintableString(contents, false);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1RelativeOID.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1RelativeOID.java
new file mode 100644
index 0000000..b6174bb
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1RelativeOID.java
@@ -0,0 +1,317 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1RelativeOID
+ extends ASN1Primitive
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1RelativeOID.class, BERTags.RELATIVE_OID)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets(), false);
+ }
+ };
+
+ public static ASN1RelativeOID fromContents(byte[] contents)
+ {
+ return createPrimitive(contents, true);
+ }
+
+ public static ASN1RelativeOID getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1RelativeOID)
+ {
+ return (ASN1RelativeOID)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1RelativeOID)
+ {
+ return (ASN1RelativeOID)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ byte[] enc = (byte[])obj;
+ try
+ {
+ return (ASN1RelativeOID)TYPE.fromByteArray(enc);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct relative OID from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ public static ASN1RelativeOID getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1RelativeOID)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7F;
+
+ private final String identifier;
+ private byte[] contents;
+
+ public ASN1RelativeOID(String identifier)
+ {
+ if (identifier == null)
+ {
+ throw new NullPointerException("'identifier' cannot be null");
+ }
+ if (!isValidIdentifier(identifier, 0))
+ {
+ throw new IllegalArgumentException("string " + identifier + " not a relative OID");
+ }
+
+ this.identifier = identifier;
+ }
+
+ ASN1RelativeOID(ASN1RelativeOID oid, String branchID)
+ {
+ if (!isValidIdentifier(branchID, 0))
+ {
+ throw new IllegalArgumentException("string " + branchID + " not a valid OID branch");
+ }
+
+ this.identifier = oid.getId() + "." + branchID;
+ }
+
+ private ASN1RelativeOID(byte[] contents, boolean clone)
+ {
+ StringBuffer objId = new StringBuffer();
+ long value = 0;
+ BigInteger bigValue = null;
+ boolean first = true;
+
+ for (int i = 0; i != contents.length; i++)
+ {
+ int b = contents[i] & 0xff;
+
+ if (value <= LONG_LIMIT)
+ {
+ value += b & 0x7F;
+ if ((b & 0x80) == 0)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ objId.append('.');
+ }
+
+ objId.append(value);
+ value = 0;
+ }
+ else
+ {
+ value <<= 7;
+ }
+ }
+ else
+ {
+ if (bigValue == null)
+ {
+ bigValue = BigInteger.valueOf(value);
+ }
+ bigValue = bigValue.or(BigInteger.valueOf(b & 0x7F));
+ if ((b & 0x80) == 0)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ objId.append('.');
+ }
+
+ objId.append(bigValue);
+ bigValue = null;
+ value = 0;
+ }
+ else
+ {
+ bigValue = bigValue.shiftLeft(7);
+ }
+ }
+ }
+
+ this.identifier = objId.toString();
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public ASN1RelativeOID branch(String branchID)
+ {
+ return new ASN1RelativeOID(this, branchID);
+ }
+
+ public String getId()
+ {
+ return identifier;
+ }
+
+ public int hashCode()
+ {
+ return identifier.hashCode();
+ }
+
+ public String toString()
+ {
+ return getId();
+ }
+
+ boolean asn1Equals(ASN1Primitive other)
+ {
+ if (this == other)
+ {
+ return true;
+ }
+ if (!(other instanceof ASN1RelativeOID))
+ {
+ return false;
+ }
+
+ ASN1RelativeOID that = (ASN1RelativeOID)other;
+
+ return this.identifier.equals(that.identifier);
+ }
+
+ int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContents().length);
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.RELATIVE_OID, getContents());
+ }
+
+ boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ private void doOutput(ByteArrayOutputStream aOut)
+ {
+ OIDTokenizer tok = new OIDTokenizer(identifier);
+ while (tok.hasMoreTokens())
+ {
+ String token = tok.nextToken();
+ if (token.length() <= 18)
+ {
+ writeField(aOut, Long.parseLong(token));
+ }
+ else
+ {
+ writeField(aOut, new BigInteger(token));
+ }
+ }
+ }
+
+ private synchronized byte[] getContents()
+ {
+ if (contents == null)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ doOutput(bOut);
+
+ contents = bOut.toByteArray();
+ }
+
+ return contents;
+ }
+
+ static ASN1RelativeOID createPrimitive(byte[] contents, boolean clone)
+ {
+ return new ASN1RelativeOID(contents, clone);
+ }
+
+ static boolean isValidIdentifier(String identifier, int from)
+ {
+ int digitCount = 0;
+
+ int pos = identifier.length();
+ while (--pos >= from)
+ {
+ char ch = identifier.charAt(pos);
+
+ if (ch == '.')
+ {
+ if (0 == digitCount
+ || (digitCount > 1 && identifier.charAt(pos + 1) == '0'))
+ {
+ return false;
+ }
+
+ digitCount = 0;
+ }
+ else if ('0' <= ch && ch <= '9')
+ {
+ ++digitCount;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (0 == digitCount
+ || (digitCount > 1 && identifier.charAt(pos + 1) == '0'))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ static void writeField(ByteArrayOutputStream out, long fieldValue)
+ {
+ byte[] result = new byte[9];
+ int pos = 8;
+ result[pos] = (byte)((int)fieldValue & 0x7F);
+ while (fieldValue >= (1L << 7))
+ {
+ fieldValue >>= 7;
+ result[--pos] = (byte)((int)fieldValue | 0x80);
+ }
+ out.write(result, pos, 9 - pos);
+ }
+
+ static void writeField(ByteArrayOutputStream out, BigInteger fieldValue)
+ {
+ int byteCount = (fieldValue.bitLength() + 6) / 7;
+ if (byteCount == 0)
+ {
+ out.write(0);
+ }
+ else
+ {
+ BigInteger tmpValue = fieldValue;
+ byte[] tmp = new byte[byteCount];
+ for (int i = byteCount - 1; i >= 0; i--)
+ {
+ tmp[i] = (byte)(tmpValue.intValue() | 0x80);
+ tmpValue = tmpValue.shiftRight(7);
+ }
+ tmp[byteCount - 1] &= 0x7F;
+ out.write(tmp, 0, tmp.length);
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Sequence.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Sequence.java
index 6984a50..8a747dd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Sequence.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Sequence.java
@@ -62,8 +62,13 @@
extends ASN1Primitive
implements com.android.org.bouncycastle.util.Iterable<ASN1Encodable>
{
- // NOTE: Only non-final to support LazyEncodedSequence
- ASN1Encodable[] elements;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Sequence.class, BERTags.SEQUENCE)
+ {
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence;
+ }
+ };
/**
* Return an ASN1Sequence from the given object.
@@ -72,37 +77,32 @@
* @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Sequence instance, or null.
*/
- public static ASN1Sequence getInstance(
- Object obj)
+ public static ASN1Sequence getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1Sequence)
{
return (ASN1Sequence)obj;
}
- else if (obj instanceof ASN1SequenceParser)
+// else if (obj instanceof ASN1SequenceParser)
+ else if (obj instanceof ASN1Encodable)
{
- return ASN1Sequence.getInstance(((ASN1SequenceParser)obj).toASN1Primitive());
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1Sequence)
+ {
+ return (ASN1Sequence)primitive;
+ }
}
else if (obj instanceof byte[])
{
try
{
- return ASN1Sequence.getInstance(fromByteArray((byte[])obj));
+ return (ASN1Sequence)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage());
}
}
- else if (obj instanceof ASN1Encodable)
- {
- ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
- if (primitive instanceof ASN1Sequence)
- {
- return (ASN1Sequence)primitive;
- }
- }
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
}
@@ -124,51 +124,14 @@
* be converted.
* @return an ASN1Sequence instance.
*/
- public static ASN1Sequence getInstance(
- ASN1TaggedObject taggedObject,
- boolean explicit)
+ public static ASN1Sequence getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- if (explicit)
- {
- if (!taggedObject.isExplicit())
- {
- throw new IllegalArgumentException("object implicit - explicit expected.");
- }
-
- return getInstance(taggedObject.getObject());
- }
-
- ASN1Primitive o = taggedObject.getObject();
-
- /*
- * constructed object which appears to be explicitly tagged when it should be implicit means
- * we have to add the surrounding sequence.
- */
- if (taggedObject.isExplicit())
- {
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BERSequence(o);
- }
-
- return new DLSequence(o);
- }
-
- if (o instanceof ASN1Sequence)
- {
- ASN1Sequence s = (ASN1Sequence)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return s;
- }
-
- return (ASN1Sequence)s.toDLObject();
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ return (ASN1Sequence)TYPE.getContextInstance(taggedObject, explicit);
}
+ // NOTE: Only non-final to support LazyEncodedSequence
+ ASN1Encodable[] elements;
+
/**
* Create an empty SEQUENCE
*/
@@ -342,6 +305,7 @@
ASN1Sequence that = (ASN1Sequence)other;
+ // NOTE: Call size() here (on both) to 'force' a LazyEncodedSequence
int count = this.size();
if (that.size() != count)
{
@@ -380,13 +344,19 @@
return new DLSequence(elements, false);
}
- boolean isConstructed()
+ abstract ASN1BitString toASN1BitString();
+
+ abstract ASN1External toASN1External();
+
+ abstract ASN1OctetString toASN1OctetString();
+
+ abstract ASN1Set toASN1Set();
+
+ boolean encodeConstructed()
{
return true;
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
// NOTE: Call size() here to 'force' a LazyEncodedSequence
@@ -415,4 +385,28 @@
{
return new Arrays.Iterator<ASN1Encodable>(elements);
}
+
+ ASN1BitString[] getConstructedBitStrings()
+ {
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ int count = size();
+ ASN1BitString[] bitStrings = new ASN1BitString[count];
+ for (int i = 0; i < count; ++i)
+ {
+ bitStrings[i] = ASN1BitString.getInstance(elements[i]);
+ }
+ return bitStrings;
+ }
+
+ ASN1OctetString[] getConstructedOctetStrings()
+ {
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ int count = size();
+ ASN1OctetString[] octetStrings = new ASN1OctetString[count];
+ for (int i = 0; i < count; ++i)
+ {
+ octetStrings[i] = ASN1OctetString.getInstance(elements[i]);
+ }
+ return octetStrings;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Set.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Set.java
index 564d151..0c112dc 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Set.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Set.java
@@ -100,8 +100,13 @@
extends ASN1Primitive
implements com.android.org.bouncycastle.util.Iterable<ASN1Encodable>
{
- protected final ASN1Encodable[] elements;
- protected final boolean isSorted;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Set.class, BERTags.SET)
+ {
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence.toASN1Set();
+ }
+ };
/**
* return an ASN1Set from the given object.
@@ -110,37 +115,32 @@
* @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Set instance, or null.
*/
- public static ASN1Set getInstance(
- Object obj)
+ public static ASN1Set getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1Set)
{
return (ASN1Set)obj;
}
- else if (obj instanceof ASN1SetParser)
+// else if (obj instanceof ASN1SetParser)
+ else if (obj instanceof ASN1Encodable)
{
- return ASN1Set.getInstance(((ASN1SetParser)obj).toASN1Primitive());
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1Set)
+ {
+ return (ASN1Set)primitive;
+ }
}
else if (obj instanceof byte[])
{
try
{
- return ASN1Set.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ return (ASN1Set)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct set from byte[]: " + e.getMessage());
}
}
- else if (obj instanceof ASN1Encodable)
- {
- ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
- if (primitive instanceof ASN1Set)
- {
- return (ASN1Set)primitive;
- }
- }
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
}
@@ -162,73 +162,19 @@
* be converted.
* @return an ASN1Set instance.
*/
- public static ASN1Set getInstance(
- ASN1TaggedObject taggedObject,
- boolean explicit)
+ public static ASN1Set getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- if (explicit)
- {
- if (!taggedObject.isExplicit())
- {
- throw new IllegalArgumentException("object implicit - explicit expected.");
- }
-
- return getInstance(taggedObject.getObject());
- }
-
- ASN1Primitive o = taggedObject.getObject();
-
- /*
- * constructed object which appears to be explicitly tagged and it's really implicit means
- * we have to add the surrounding set.
- */
- if (taggedObject.isExplicit())
- {
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BERSet(o);
- }
-
- return new DLSet(o);
- }
-
- if (o instanceof ASN1Set)
- {
- ASN1Set s = (ASN1Set)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return s;
- }
-
- return (ASN1Set)s.toDLObject();
- }
-
- /*
- * in this case the parser returns a sequence, convert it into a set.
- */
- if (o instanceof ASN1Sequence)
- {
- ASN1Sequence s = (ASN1Sequence)o;
-
- // NOTE: Will force() a LazyEncodedSequence
- ASN1Encodable[] elements = s.toArrayInternal();
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BERSet(false, elements);
- }
-
- return new DLSet(false, elements);
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ return (ASN1Set)TYPE.getContextInstance(taggedObject, explicit);
}
+ protected final ASN1Encodable[] elements;
+
+ protected ASN1Encodable[] sortedElements;
+
protected ASN1Set()
{
this.elements = ASN1EncodableVector.EMPTY_ELEMENTS;
- this.isSorted = true;
+ this.sortedElements = elements;
}
/**
@@ -243,7 +189,7 @@
}
this.elements = new ASN1Encodable[]{ element };
- this.isSorted = true;
+ this.sortedElements = elements;
}
/**
@@ -270,7 +216,7 @@
}
this.elements = tmp;
- this.isSorted = doSort || tmp.length < 2;
+ this.sortedElements = (doSort || tmp.length < 2) ? elements : null;
}
/**
@@ -292,13 +238,19 @@
}
this.elements = tmp;
- this.isSorted = doSort || tmp.length < 2;
+ this.sortedElements = (doSort || tmp.length < 2) ? elements : null;
}
ASN1Set(boolean isSorted, ASN1Encodable[] elements)
{
this.elements = elements;
- this.isSorted = isSorted || elements.length < 2;
+ this.sortedElements = (isSorted || elements.length < 2) ? elements : null;
+ }
+
+ ASN1Set(ASN1Encodable[] elements, ASN1Encodable[] sortedElements)
+ {
+ this.elements = elements;
+ this.sortedElements = sortedElements;
}
public Enumeration getObjects()
@@ -410,18 +362,13 @@
*/
ASN1Primitive toDERObject()
{
- ASN1Encodable[] tmp;
- if (isSorted)
+ if (sortedElements == null)
{
- tmp = elements;
- }
- else
- {
- tmp = (ASN1Encodable[])elements.clone();
- sort(tmp);
+ sortedElements = (ASN1Encodable[])elements.clone();
+ sort(sortedElements);
}
- return new DERSet(true, tmp);
+ return new DERSet(true, sortedElements);
}
/**
@@ -430,7 +377,7 @@
*/
ASN1Primitive toDLObject()
{
- return new DLSet(isSorted, elements);
+ return new DLSet(elements, sortedElements);
}
boolean asn1Equals(ASN1Primitive other)
@@ -465,13 +412,11 @@
return true;
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return true;
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
int count = size();
@@ -531,8 +476,8 @@
* primitive form accordingly. Failing to ignore the CONSTRUCTED bit could therefore lead to
* ordering inversions.
*/
- int a0 = a[0] & ~BERTags.CONSTRUCTED;
- int b0 = b[0] & ~BERTags.CONSTRUCTED;
+ int a0 = a[0] & (~BERTags.CONSTRUCTED & 0xff);
+ int b0 = b[0] & (~BERTags.CONSTRUCTED & 0xff);
if (a0 != b0)
{
return a0 < b0;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1StreamParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1StreamParser.java
index 2ae9ca7..21484a1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1StreamParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1StreamParser.java
@@ -12,214 +12,257 @@
public class ASN1StreamParser
{
private final InputStream _in;
- private final int _limit;
+ private final int _limit;
private final byte[][] tmpBuffers;
- public ASN1StreamParser(
- InputStream in)
+ public ASN1StreamParser(InputStream in)
{
this(in, StreamUtil.findLimit(in));
}
- public ASN1StreamParser(
- InputStream in,
- int limit)
- {
- this._in = in;
- this._limit = limit;
-
- this.tmpBuffers = new byte[11][];
- }
-
- public ASN1StreamParser(
- byte[] encoding)
+ public ASN1StreamParser(byte[] encoding)
{
this(new ByteArrayInputStream(encoding), encoding.length);
}
- ASN1Encodable readIndef(int tagValue) throws IOException
+ public ASN1StreamParser(InputStream in, int limit)
{
- // Note: INDEF => CONSTRUCTED
-
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagValue)
- {
- case BERTags.EXTERNAL:
- return new DERExternalParser(this);
- case BERTags.OCTET_STRING:
- return new BEROctetStringParser(this);
- case BERTags.SEQUENCE:
- return new BERSequenceParser(this);
- case BERTags.SET:
- return new BERSetParser(this);
- default:
- throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(tagValue));
- }
+ this(in, limit, new byte[11][]);
}
- ASN1Encodable readImplicit(boolean constructed, int tag) throws IOException
+ ASN1StreamParser(InputStream in, int limit, byte[][] tmpBuffers)
{
- if (_in instanceof IndefiniteLengthInputStream)
- {
- if (!constructed)
- {
- throw new IOException("indefinite-length primitive encoding encountered");
- }
-
- return readIndef(tag);
- }
-
- if (constructed)
- {
- switch (tag)
- {
- case BERTags.SET:
- return new DLSetParser(this);
- case BERTags.SEQUENCE:
- return new DLSequenceParser(this);
- case BERTags.OCTET_STRING:
- return new BEROctetStringParser(this);
- }
- }
- else
- {
- switch (tag)
- {
- case BERTags.SET:
- throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
- case BERTags.SEQUENCE:
- throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
- case BERTags.OCTET_STRING:
- return new DEROctetStringParser((DefiniteLengthInputStream)_in);
- }
- }
-
- throw new ASN1Exception("implicit tagging not implemented");
+ this._in = in;
+ this._limit = limit;
+ this.tmpBuffers = tmpBuffers;
}
- ASN1Primitive readTaggedObject(boolean constructed, int tag) throws IOException
+ public ASN1Encodable readObject() throws IOException
{
- if (!constructed)
- {
- // Note: !CONSTRUCTED => IMPLICIT
- DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
- return new DLTaggedObject(false, tag, new DEROctetString(defIn.toByteArray()));
- }
-
- ASN1EncodableVector v = readVector();
-
- if (_in instanceof IndefiniteLengthInputStream)
- {
- return v.size() == 1
- ? new BERTaggedObject(true, tag, v.get(0))
- : new BERTaggedObject(false, tag, BERFactory.createSequence(v));
- }
-
- return v.size() == 1
- ? new DLTaggedObject(true, tag, v.get(0))
- : new DLTaggedObject(false, tag, DLFactory.createSequence(v));
- }
-
- public ASN1Encodable readObject()
- throws IOException
- {
- int tag = _in.read();
- if (tag == -1)
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
{
return null;
}
+ return implParseObject(tagHdr);
+ }
+
+ ASN1Encodable implParseObject(int tagHdr) throws IOException
+ {
//
- // turn of looking for "00" while we resolve the tag
+ // turn off looking for "00" while we resolve the tag
//
set00Check(false);
//
// calculate tag number
//
- int tagNo = ASN1InputStream.readTagNumber(_in, tag);
-
- boolean isConstructed = (tag & BERTags.CONSTRUCTED) != 0;
+ int tagNo = ASN1InputStream.readTagNumber(_in, tagHdr);
//
// calculate length
//
int length = ASN1InputStream.readLength(_in, _limit,
- tagNo == BERTags.OCTET_STRING || tagNo == BERTags.SEQUENCE || tagNo == BERTags.SET || tagNo == BERTags.EXTERNAL);
+ tagNo == BERTags.BIT_STRING || tagNo == BERTags.OCTET_STRING || tagNo == BERTags.SEQUENCE
+ || tagNo == BERTags.SET || tagNo == BERTags.EXTERNAL);
if (length < 0) // indefinite-length method
{
- if (!isConstructed)
+ if (0 == (tagHdr & BERTags.CONSTRUCTED))
{
throw new IOException("indefinite-length primitive encoding encountered");
}
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit);
- ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit);
+ ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit, tmpBuffers);
- if ((tag & BERTags.APPLICATION) != 0)
+ int tagClass = tagHdr & BERTags.PRIVATE;
+ if (0 != tagClass)
{
- return new BERApplicationSpecificParser(tagNo, sp);
+ return new BERTaggedObjectParser(tagClass, tagNo, sp);
}
- if ((tag & BERTags.TAGGED) != 0)
- {
- return new BERTaggedObjectParser(true, tagNo, sp);
- }
-
- return sp.readIndef(tagNo);
+ return sp.parseImplicitConstructedIL(tagNo);
}
else
{
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length, _limit);
- if ((tag & BERTags.APPLICATION) != 0)
+ if (0 == (tagHdr & BERTags.FLAGS))
{
- return new DLApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
+ return parseImplicitPrimitive(tagNo, defIn);
}
- if ((tag & BERTags.TAGGED) != 0)
+ ASN1StreamParser sp = new ASN1StreamParser(defIn, defIn.getLimit(), tmpBuffers);
+
+ int tagClass = tagHdr & BERTags.PRIVATE;
+ if (0 != tagClass)
{
- return new BERTaggedObjectParser(isConstructed, tagNo, new ASN1StreamParser(defIn));
+ boolean isConstructed = (tagHdr & BERTags.CONSTRUCTED) != 0;
+
+ return new DLTaggedObjectParser(tagClass, tagNo, isConstructed, sp);
}
- if (isConstructed)
- {
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagNo)
- {
- case BERTags.OCTET_STRING:
- //
- // yes, people actually do this...
- //
- return new BEROctetStringParser(new ASN1StreamParser(defIn));
- case BERTags.SEQUENCE:
- return new DLSequenceParser(new ASN1StreamParser(defIn));
- case BERTags.SET:
- return new DLSetParser(new ASN1StreamParser(defIn));
- case BERTags.EXTERNAL:
- return new DERExternalParser(new ASN1StreamParser(defIn));
- default:
- throw new IOException("unknown tag " + tagNo + " encountered");
- }
- }
+ return sp.parseImplicitConstructedDL(tagNo);
+ }
+ }
- // Some primitive encodings can be handled by parsers too...
- switch (tagNo)
- {
- case BERTags.OCTET_STRING:
- return new DEROctetStringParser(defIn);
- }
+ ASN1Primitive loadTaggedDL(int tagClass, int tagNo, boolean constructed) throws IOException
+ {
+ if (!constructed)
+ {
+ byte[] contentsOctets = ((DefiniteLengthInputStream) _in).toByteArray();
+ return ASN1TaggedObject.createPrimitive(tagClass, tagNo, contentsOctets);
+ }
- try
+ ASN1EncodableVector contentsElements = readVector();
+ return ASN1TaggedObject.createConstructedDL(tagClass, tagNo, contentsElements);
+ }
+
+ ASN1Primitive loadTaggedIL(int tagClass, int tagNo) throws IOException
+ {
+ ASN1EncodableVector contentsElements = readVector();
+ return ASN1TaggedObject.createConstructedIL(tagClass, tagNo, contentsElements);
+ }
+
+ ASN1Encodable parseImplicitConstructedDL(int univTagNo) throws IOException
+ {
+ switch (univTagNo)
+ {
+ case BERTags.BIT_STRING:
+ // TODO[asn1] DLConstructedBitStringParser
+ return new BERBitStringParser(this);
+ case BERTags.EXTERNAL:
+ return new DERExternalParser(this);
+ case BERTags.OCTET_STRING:
+ // TODO[asn1] DLConstructedOctetStringParser
+ return new BEROctetStringParser(this);
+ case BERTags.SET:
+ return new DLSetParser(this);
+ case BERTags.SEQUENCE:
+ return new DLSequenceParser(this);
+ default:
+ // -DM toHexString
+ throw new ASN1Exception("unknown DL object encountered: 0x" + Integer.toHexString(univTagNo));
+ }
+ }
+
+ ASN1Encodable parseImplicitConstructedIL(int univTagNo) throws IOException
+ {
+ switch (univTagNo)
+ {
+ case BERTags.BIT_STRING:
+ return new BERBitStringParser(this);
+ case BERTags.OCTET_STRING:
+ return new BEROctetStringParser(this);
+ case BERTags.EXTERNAL:
+ // TODO[asn1] BERExternalParser
+ return new DERExternalParser(this);
+ case BERTags.SEQUENCE:
+ return new BERSequenceParser(this);
+ case BERTags.SET:
+ return new BERSetParser(this);
+ default:
+ throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(univTagNo));
+ }
+ }
+
+ ASN1Encodable parseImplicitPrimitive(int univTagNo) throws IOException
+ {
+ return parseImplicitPrimitive(univTagNo, (DefiniteLengthInputStream)_in);
+ }
+
+ ASN1Encodable parseImplicitPrimitive(int univTagNo, DefiniteLengthInputStream defIn) throws IOException
+ {
+ // Some primitive encodings can be handled by parsers too...
+ switch (univTagNo)
+ {
+ case BERTags.BIT_STRING:
+ return new DLBitStringParser(defIn);
+ case BERTags.EXTERNAL:
+ throw new ASN1Exception("externals must use constructed encoding (see X.690 8.18)");
+ case BERTags.OCTET_STRING:
+ return new DEROctetStringParser(defIn);
+ case BERTags.SET:
+ throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
+ case BERTags.SEQUENCE:
+ throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
+ }
+
+ try
+ {
+ return ASN1InputStream.createPrimitiveDERObject(univTagNo, defIn, tmpBuffers);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception("corrupted stream detected", e);
+ }
+ }
+
+ ASN1Encodable parseObject(int univTagNo) throws IOException
+ {
+ if (univTagNo < 0 || univTagNo > 30)
+ {
+ throw new IllegalArgumentException("invalid universal tag number: " + univTagNo);
+ }
+
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
+ {
+ return null;
+ }
+
+ if ((tagHdr & ~BERTags.CONSTRUCTED) != univTagNo)
+ {
+ throw new IOException("unexpected identifier encountered: " + tagHdr);
+ }
+
+ return implParseObject(tagHdr);
+ }
+
+ ASN1TaggedObjectParser parseTaggedObject() throws IOException
+ {
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
+ {
+ return null;
+ }
+
+ int tagClass = tagHdr & BERTags.PRIVATE;
+ if (0 == tagClass)
+ {
+ throw new ASN1Exception("no tagged object found");
+ }
+
+ return (ASN1TaggedObjectParser)implParseObject(tagHdr);
+ }
+
+ // TODO[asn1] Prefer 'loadVector'
+ ASN1EncodableVector readVector() throws IOException
+ {
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
+ {
+ return new ASN1EncodableVector(0);
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ do
+ {
+ ASN1Encodable obj = implParseObject(tagHdr);
+
+ if (obj instanceof InMemoryRepresentable)
{
- return ASN1InputStream.createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
+ v.add(((InMemoryRepresentable) obj).getLoadedObject());
}
- catch (IllegalArgumentException e)
+ else
{
- throw new ASN1Exception("corrupted stream detected", e);
+ v.add(obj.toASN1Primitive());
}
}
+ while ((tagHdr = _in.read()) >= 0);
+ return v;
}
private void set00Check(boolean enabled)
@@ -229,28 +272,4 @@
((IndefiniteLengthInputStream)_in).setEofOn00(enabled);
}
}
-
- ASN1EncodableVector readVector() throws IOException
- {
- ASN1Encodable obj = readObject();
- if (null == obj)
- {
- return new ASN1EncodableVector(0);
- }
-
- ASN1EncodableVector v = new ASN1EncodableVector();
- do
- {
- if (obj instanceof InMemoryRepresentable)
- {
- v.add(((InMemoryRepresentable)obj).getLoadedObject());
- }
- else
- {
- v.add(obj.toASN1Primitive());
- }
- }
- while ((obj = readObject()) != null);
- return v;
- }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1T61String.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1T61String.java
new file mode 100644
index 0000000..1dd062d
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1T61String.java
@@ -0,0 +1,147 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 T61String (also the teletex string), try not to use this if you don't need to. The standard support the encoding for
+ * this has been withdrawn.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1T61String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1T61String.class, BERTags.T61_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a T61 string from the passed in object.
+ *
+ * @param obj an ASN1T61String or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1T61String instance, or null
+ */
+ public static ASN1T61String getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1T61String)
+ {
+ return (ASN1T61String)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1T61String)
+ {
+ return (ASN1T61String)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1T61String)TYPE.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());
+ }
+
+ /**
+ * Return an T61 String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1T61String instance, or null
+ */
+ public static ASN1T61String getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1T61String)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1T61String(String string)
+ {
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1T61String(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ /**
+ * Decode the encoded string and return it, 8 bit encoding assumed.
+ * @return the decoded String
+ */
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.T61_STRING, contents);
+ }
+
+ /**
+ * Return the encoded string as a byte array.
+ * @return the actual bytes making up the encoded body of the T61 string.
+ */
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1T61String))
+ {
+ return false;
+ }
+
+ ASN1T61String that = (ASN1T61String)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1T61String createPrimitive(byte[] contents)
+ {
+ return new DERT61String(contents, false);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Tag.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Tag.java
new file mode 100644
index 0000000..c25f733
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Tag.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+final class ASN1Tag
+{
+ static ASN1Tag create(int tagClass, int tagNumber)
+ {
+ return new ASN1Tag(tagClass, tagNumber);
+ }
+
+ private final int tagClass;
+ private final int tagNumber;
+
+ private ASN1Tag(int tagClass, int tagNumber)
+ {
+ this.tagClass = tagClass;
+ this.tagNumber = tagNumber;
+ }
+
+ int getTagClass()
+ {
+ return tagClass;
+ }
+
+ int getTagNumber()
+ {
+ return tagNumber;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObject.java
index bbf6554..de23ed2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObject.java
@@ -3,6 +3,8 @@
import java.io.IOException;
+import com.android.org.bouncycastle.util.Arrays;
+
/**
* ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by
* a [n] where n is some number - these are assumed to follow the construction
@@ -13,34 +15,32 @@
extends ASN1Primitive
implements ASN1TaggedObjectParser
{
- final int tagNo;
- final boolean explicit;
- final ASN1Encodable obj;
+ private static final int DECLARED_EXPLICIT = 1;
+ private static final int DECLARED_IMPLICIT = 2;
+ // TODO It will probably be better to track parsing constructed vs primitive instead
+ private static final int PARSED_EXPLICIT = 3;
+ private static final int PARSED_IMPLICIT = 4;
- static public ASN1TaggedObject getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- if (explicit)
- {
- return getInstance(obj.getObject());
- }
-
- throw new IllegalArgumentException("implicitly tagged tagged object");
- }
-
- static public ASN1TaggedObject getInstance(
- Object obj)
+ public static ASN1TaggedObject getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1TaggedObject)
{
return (ASN1TaggedObject)obj;
}
+// else if (obj instanceof ASN1TaggedObjectParser)
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1TaggedObject)
+ {
+ return (ASN1TaggedObject)primitive;
+ }
+ }
else if (obj instanceof byte[])
{
try
{
- return ASN1TaggedObject.getInstance(fromByteArray((byte[])obj));
+ return checkedCast(fromByteArray((byte[])obj));
}
catch (IOException e)
{
@@ -51,6 +51,58 @@
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
}
+ public static ASN1TaggedObject getInstance(Object obj, int tagClass)
+ {
+ if (obj == null)
+ {
+ throw new NullPointerException("'obj' cannot be null");
+ }
+
+ ASN1TaggedObject taggedObject = getInstance(obj);
+ if (tagClass != taggedObject.getTagClass())
+ {
+ throw new IllegalArgumentException("unexpected tag in getInstance: " + ASN1Util.getTagText(taggedObject));
+ }
+
+ return taggedObject;
+ }
+
+ public static ASN1TaggedObject getInstance(Object obj, int tagClass, int tagNo)
+ {
+ if (obj == null)
+ {
+ throw new NullPointerException("'obj' cannot be null");
+ }
+
+ ASN1TaggedObject taggedObject = getInstance(obj);
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ throw new IllegalArgumentException("unexpected tag in getInstance: " + ASN1Util.getTagText(taggedObject));
+ }
+
+ return taggedObject;
+ }
+
+ public static ASN1TaggedObject getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
+ {
+ if (BERTags.CONTEXT_SPECIFIC != taggedObject.getTagClass())
+ {
+ throw new IllegalStateException("this method only valid for CONTEXT_SPECIFIC tags");
+ }
+
+ if (declaredExplicit)
+ {
+ return taggedObject.getExplicitBaseTagged();
+ }
+
+ throw new IllegalArgumentException("this method not valid for implicitly tagged tagged objects");
+ }
+
+ final int explicitness;
+ final int tagClass;
+ final int tagNo;
+ final ASN1Encodable obj;
+
/**
* Create a tagged object with the style given by the value of explicit.
* <p>
@@ -61,22 +113,34 @@
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public ASN1TaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
+ protected ASN1TaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
+ {
+ this(explicit, BERTags.CONTEXT_SPECIFIC, tagNo, obj);
+ }
+
+ protected ASN1TaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ this(explicit ? DECLARED_EXPLICIT : DECLARED_IMPLICIT, tagClass, tagNo, obj);
+ }
+
+ ASN1TaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
{
if (null == obj)
{
throw new NullPointerException("'obj' cannot be null");
}
+ if (tagClass == BERTags.UNIVERSAL || (tagClass & BERTags.PRIVATE) != tagClass)
+ {
+ throw new IllegalArgumentException("invalid tag class: " + tagClass);
+ }
+ this.explicitness = (obj instanceof ASN1Choice) ? DECLARED_EXPLICIT : explicitness;
+ this.tagClass = tagClass;
this.tagNo = tagNo;
- this.explicit = explicit || (obj instanceof ASN1Choice);
this.obj = obj;
}
- boolean asn1Equals(ASN1Primitive other)
+ final boolean asn1Equals(ASN1Primitive other)
{
if (!(other instanceof ASN1TaggedObject))
{
@@ -85,20 +149,58 @@
ASN1TaggedObject that = (ASN1TaggedObject)other;
- if (this.tagNo != that.tagNo || this.explicit != that.explicit)
+ if (this.tagNo != that.tagNo ||
+ this.tagClass != that.tagClass)
{
return false;
}
+ if (this.explicitness != that.explicitness)
+ {
+ /*
+ * TODO This seems incorrect for some cases of implicit tags e.g. if one is a
+ * declared-implicit SET and the other a parsed object.
+ */
+ if (this.isExplicit() != that.isExplicit())
+ {
+ return false;
+ }
+ }
+
ASN1Primitive p1 = this.obj.toASN1Primitive();
ASN1Primitive p2 = that.obj.toASN1Primitive();
- return p1 == p2 || p1.asn1Equals(p2);
+ if (p1 == p2)
+ {
+ return true;
+ }
+
+ if (!this.isExplicit())
+ {
+ try
+ {
+ byte[] d1 = this.getEncoded();
+ byte[] d2 = that.getEncoded();
+
+ return Arrays.areEqual(d1, d2);
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
+ }
+
+ return p1.asn1Equals(p2);
}
public int hashCode()
{
- return tagNo ^ (explicit ? 0x0F : 0xF0) ^ obj.toASN1Primitive().hashCode();
+ return (tagClass * 7919) ^ tagNo ^ (isExplicit() ? 0x0F : 0xF0) ^ obj.toASN1Primitive().hashCode();
+ }
+
+ public int getTagClass()
+ {
+ return tagClass;
}
/**
@@ -111,18 +213,24 @@
return tagNo;
}
- /**
- * return whether or not the object may be explicitly tagged.
- * <p>
- * Note: if the object has been read from an input stream, the only
- * time you can be sure if isExplicit is returning the true state of
- * affairs is if it returns false. An implicitly tagged object may appear
- * to be explicitly tagged, so you need to understand the context under
- * which the reading was done as well, see getObject below.
- */
- public boolean isExplicit()
+ public boolean hasContextTag()
{
- return explicit;
+ return this.tagClass == BERTags.CONTEXT_SPECIFIC;
+ }
+
+ public boolean hasContextTag(int tagNo)
+ {
+ return this.tagClass == BERTags.CONTEXT_SPECIFIC && this.tagNo == tagNo;
+ }
+
+ public boolean hasTag(int tagClass, int tagNo)
+ {
+ return this.tagClass == tagClass && this.tagNo == tagNo;
+ }
+
+ public boolean hasTagClass(int tagClass)
+ {
+ return this.tagClass == tagClass;
}
/**
@@ -138,52 +246,246 @@
}
/**
- * Return the object held in this tagged object as a parser assuming it has
- * the type of the passed in tag. If the object doesn't have a parser
- * associated with it, the base object is returned.
+ * return whether or not the object may be explicitly tagged.
+ * <p>
+ * Note: if the object has been read from an input stream, the only
+ * time you can be sure if isExplicit is returning the true state of
+ * affairs is if it returns false. An implicitly tagged object may appear
+ * to be explicitly tagged, so you need to understand the context under
+ * which the reading was done as well, see getObject below.
*/
- public ASN1Encodable getObjectParser(
- int tag,
- boolean isExplicit)
- throws IOException
+ public boolean isExplicit()
{
- switch (tag)
+ // TODO New methods like 'isKnownExplicit' etc. to distinguish uncertain cases?
+ switch (explicitness)
{
- case BERTags.SET:
- return ASN1Set.getInstance(this, isExplicit).parser();
- case BERTags.SEQUENCE:
- return ASN1Sequence.getInstance(this, isExplicit).parser();
+ case DECLARED_EXPLICIT:
+ case PARSED_EXPLICIT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ boolean isParsed()
+ {
+ switch (explicitness)
+ {
+ case PARSED_EXPLICIT:
+ case PARSED_IMPLICIT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Needed for open types, until we have better type-guided parsing support. Use sparingly for other
+ * purposes, and prefer {@link #getExplicitBaseTagged()}, {@link #getImplicitBaseTagged(int, int)} or
+ * {@link #getBaseUniversal(boolean, int)} where possible. Before using, check for matching tag
+ * {@link #getTagClass() class} and {@link #getTagNo() number}.
+ */
+ public ASN1Object getBaseObject()
+ {
+ return obj instanceof ASN1Object ? (ASN1Object)obj : obj.toASN1Primitive();
+ }
+
+ /**
+ * Needed for open types, until we have better type-guided parsing support. Use
+ * sparingly for other purposes, and prefer {@link #getExplicitBaseTagged()} or
+ * {@link #getBaseUniversal(boolean, int)} where possible. Before using, check
+ * for matching tag {@link #getTagClass() class} and {@link #getTagNo() number}.
+ */
+ public ASN1Object getExplicitBaseObject()
+ {
+ if (!isExplicit())
+ {
+ throw new IllegalStateException("object implicit - explicit expected.");
+ }
+
+ return obj instanceof ASN1Object ? (ASN1Object)obj : obj.toASN1Primitive();
+ }
+
+ public ASN1TaggedObject getExplicitBaseTagged()
+ {
+ if (!isExplicit())
+ {
+ throw new IllegalStateException("object implicit - explicit expected.");
+ }
+
+ return checkedCast(obj.toASN1Primitive());
+ }
+
+ public ASN1TaggedObject getImplicitBaseTagged(int baseTagClass, int baseTagNo)
+ {
+ if (baseTagClass == BERTags.UNIVERSAL || (baseTagClass & BERTags.PRIVATE) != baseTagClass)
+ {
+ throw new IllegalArgumentException("invalid base tag class: " + baseTagClass);
+ }
+
+ switch (explicitness)
+ {
+ case DECLARED_EXPLICIT:
+ throw new IllegalStateException("object explicit - implicit expected.");
+
+ case DECLARED_IMPLICIT:
+ {
+ ASN1TaggedObject declared = checkedCast(obj.toASN1Primitive());
+ return ASN1Util.checkTag(declared, baseTagClass, baseTagNo);
+ }
+
+ // Parsed; return a virtual tag (i.e. that couldn't have been present in the encoding)
+ default:
+ return replaceTag(baseTagClass, baseTagNo);
+ }
+ }
+
+ /**
+ * Note: tagged objects are generally context dependent. Before trying to
+ * extract a tagged object this way, make sure you have checked that both the
+ * {@link #getTagClass() tag class} and {@link #getTagNo() tag number} match
+ * what you are looking for.
+ *
+ * @param declaredExplicit Whether the tagged type for this object was declared
+ * EXPLICIT.
+ * @param tagNo The universal {@link BERTags tag number} of the
+ * expected base object.
+ */
+ public ASN1Primitive getBaseUniversal(boolean declaredExplicit, int tagNo)
+ {
+ ASN1UniversalType universalType = ASN1UniversalTypes.get(tagNo);
+ if (null == universalType)
+ {
+ throw new IllegalArgumentException("unsupported UNIVERSAL tag number: " + tagNo);
+ }
+
+ return getBaseUniversal(declaredExplicit, universalType);
+ }
+
+ ASN1Primitive getBaseUniversal(boolean declaredExplicit, ASN1UniversalType universalType)
+ {
+ if (declaredExplicit)
+ {
+ if (!isExplicit())
+ {
+ throw new IllegalStateException("object explicit - implicit expected.");
+ }
+
+ return universalType.checkedCast(obj.toASN1Primitive());
+ }
+
+ if (DECLARED_EXPLICIT == explicitness)
+ {
+ throw new IllegalStateException("object explicit - implicit expected.");
+ }
+
+ ASN1Primitive primitive = obj.toASN1Primitive();
+ switch (explicitness)
+ {
+ case PARSED_EXPLICIT:
+ return universalType.fromImplicitConstructed(rebuildConstructed(primitive));
+ case PARSED_IMPLICIT:
+ {
+ if (primitive instanceof ASN1Sequence)
+ {
+ return universalType.fromImplicitConstructed((ASN1Sequence)primitive);
+ }
+ return universalType.fromImplicitPrimitive((DEROctetString)primitive);
+ }
+ default:
+ return universalType.checkedCast(primitive);
+ }
+ }
+
+ public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ ASN1Primitive primitive = getBaseUniversal(declaredExplicit, baseTagNo);
+
+ switch (baseTagNo)
+ {
+ case BERTags.BIT_STRING:
+ return ((ASN1BitString)primitive).parser();
case BERTags.OCTET_STRING:
- return ASN1OctetString.getInstance(this, isExplicit).parser();
+ return ((ASN1OctetString)primitive).parser();
+ case BERTags.SEQUENCE:
+ return ((ASN1Sequence)primitive).parser();
+ case BERTags.SET:
+ return ((ASN1Set)primitive).parser();
}
- if (isExplicit)
- {
- return getObject();
- }
-
- throw new ASN1Exception("implicit tagging not implemented for tag: " + tag);
+ return primitive;
}
- public ASN1Primitive getLoadedObject()
+ public ASN1Encodable parseExplicitBaseObject() throws IOException
{
- return this.toASN1Primitive();
+ return getExplicitBaseObject();
}
+ public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException
+ {
+ return getExplicitBaseTagged();
+ }
+
+ public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException
+ {
+ return getImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public final ASN1Primitive getLoadedObject()
+ {
+ return this;
+ }
+
+ abstract ASN1Sequence rebuildConstructed(ASN1Primitive primitive);
+
+ abstract ASN1TaggedObject replaceTag(int tagClass, int tagNo);
+
ASN1Primitive toDERObject()
{
- return new DERTaggedObject(explicit, tagNo, obj);
+ return new DERTaggedObject(explicitness, tagClass, tagNo, obj);
}
ASN1Primitive toDLObject()
{
- return new DLTaggedObject(explicit, tagNo, obj);
+ return new DLTaggedObject(explicitness, tagClass, tagNo, obj);
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
- return "[" + tagNo + "]" + obj;
+ return ASN1Util.getTagText(tagClass, tagNo) + obj;
+ }
+
+ static ASN1Primitive createConstructedDL(int tagClass, int tagNo, ASN1EncodableVector contentsElements)
+ {
+ boolean maybeExplicit = (contentsElements.size() == 1);
+
+ return maybeExplicit
+ ? new DLTaggedObject(PARSED_EXPLICIT, tagClass, tagNo, contentsElements.get(0))
+ : new DLTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, DLFactory.createSequence(contentsElements));
+ }
+
+ static ASN1Primitive createConstructedIL(int tagClass, int tagNo, ASN1EncodableVector contentsElements)
+ {
+ boolean maybeExplicit = (contentsElements.size() == 1);
+
+ return maybeExplicit
+ ? new BERTaggedObject(PARSED_EXPLICIT, tagClass, tagNo, contentsElements.get(0))
+ : new BERTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, BERFactory.createSequence(contentsElements));
+ }
+
+ static ASN1Primitive createPrimitive(int tagClass, int tagNo, byte[] contentsOctets)
+ {
+ // Note: !CONSTRUCTED => IMPLICIT
+ return new DLTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, new DEROctetString(contentsOctets));
+ }
+
+ private static ASN1TaggedObject checkedCast(ASN1Primitive primitive)
+ {
+ if (primitive instanceof ASN1TaggedObject)
+ {
+ return (ASN1TaggedObject)primitive;
+ }
+
+ throw new IllegalStateException("unexpected object: " + primitive.getClass().getName());
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObjectParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObjectParser.java
index 77eeca2..1fe2595 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObjectParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObjectParser.java
@@ -11,19 +11,38 @@
extends ASN1Encodable, InMemoryRepresentable
{
/**
- * Return the tag number associated with the underlying tagged object.
- * @return the object's tag number.
+ * Return the tag class associated with this object.
+ *
+ * @return the tag class.
+ */
+ int getTagClass();
+
+ /**
+ * Return the tag number associated with this object.
+ *
+ * @return the tag number.
*/
int getTagNo();
+ boolean hasContextTag();
+
+ boolean hasContextTag(int tagNo);
+
+ boolean hasTag(int tagClass, int tagNo);
+
+ boolean hasTagClass(int tagClass);
+
+ ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException;
+
/**
- * Return a parser for the actual object tagged.
- *
- * @param tag the primitive tag value for the object tagged originally.
- * @param isExplicit true if the tagging was done explicitly.
- * @return a parser for the tagged object.
- * @throws IOException if a parser cannot be constructed.
+ * Needed for open types, until we have better type-guided parsing support. Use sparingly for other
+ * purposes, and prefer {@link #parseExplicitBaseTagged()} or {@link #parseBaseUniversal(boolean, int)}
+ * where possible. Before using, check for matching tag {@link #getTagClass() class} and
+ * {@link #getTagNo() number}.
*/
- ASN1Encodable getObjectParser(int tag, boolean isExplicit)
- throws IOException;
+ ASN1Encodable parseExplicitBaseObject() throws IOException;
+
+ ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException;
+
+ ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Type.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Type.java
new file mode 100644
index 0000000..9d45117
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Type.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+abstract class ASN1Type
+{
+ final Class javaClass;
+
+ ASN1Type(Class javaClass)
+ {
+ this.javaClass = javaClass;
+ }
+
+ final Class getJavaClass()
+ {
+ return javaClass;
+ }
+
+ public final boolean equals(Object that)
+ {
+ return this == that;
+ }
+
+ public final int hashCode()
+ {
+ return super.hashCode();
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTCTime.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTCTime.java
index e49ce01..d9b834d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTCTime.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTCTime.java
@@ -38,7 +38,13 @@
public class ASN1UTCTime
extends ASN1Primitive
{
- private byte[] time;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1UTCTime.class, BERTags.UTC_TIME)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
/**
* Return an UTC Time from the passed in object.
@@ -54,12 +60,19 @@
{
return (ASN1UTCTime)obj;
}
-
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1UTCTime)
+ {
+ return (ASN1UTCTime)primitive;
+ }
+ }
if (obj instanceof byte[])
{
try
{
- return (ASN1UTCTime)fromByteArray((byte[])obj);
+ return (ASN1UTCTime)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -73,29 +86,19 @@
/**
* Return an UTC Time from a tagged object.
*
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
* @return an ASN1UTCTime instance, or null.
*/
- public static ASN1UTCTime getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1UTCTime getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Object o = obj.getObject();
-
- if (explicit || o instanceof ASN1UTCTime)
- {
- return getInstance(o);
- }
- else
- {
- return new ASN1UTCTime(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1UTCTime)TYPE.getContextInstance(taggedObject, explicit);
}
+ final byte[] contents;
+
/**
* The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
* never encoded. When you're creating one of these objects from scratch, that's
@@ -109,7 +112,7 @@
public ASN1UTCTime(
String time)
{
- this.time = Strings.toByteArray(time);
+ this.contents = Strings.toByteArray(time);
try
{
this.getDate();
@@ -133,7 +136,7 @@
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
/**
@@ -155,17 +158,16 @@
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
- ASN1UTCTime(
- byte[] time)
+ ASN1UTCTime(byte[] contents)
{
- if (time.length < 2)
+ if (contents.length < 2)
{
throw new IllegalArgumentException("UTCTime string too short");
}
- this.time = time;
+ this.contents = contents;
if (!(isDigit(0) && isDigit(1)))
{
throw new IllegalArgumentException("illegal characters in UTCTime string");
@@ -186,7 +188,7 @@
// SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz");
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz", Locale.US);
- return DateUtil.epochAdjust(dateF.parse(getTime()));
+ return dateF.parse(getTime());
}
/**
@@ -204,8 +206,8 @@
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz", Locale.US);
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
-
- return DateUtil.epochAdjust(dateF.parse(getAdjustedTime()));
+
+ return dateF.parse(getAdjustedTime());
}
/**
@@ -226,7 +228,7 @@
*/
public String getTime()
{
- String stime = Strings.fromByteArray(time);
+ String stime = Strings.fromByteArray(contents);
//
// standardise the format.
@@ -287,24 +289,22 @@
private boolean isDigit(int pos)
{
- return time.length > pos && time[pos] >= '0' && time[pos] <= '9';
+ return contents.length > pos && contents[pos] >= '0' && contents[pos] <= '9';
}
- boolean isConstructed()
+ final boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- int length = time.length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.UTC_TIME, time);
+ out.writeEncodingDL(withTag, BERTags.UTC_TIME, contents);
}
boolean asn1Equals(
@@ -315,16 +315,21 @@
return false;
}
- return Arrays.areEqual(time, ((ASN1UTCTime)o).time);
+ return Arrays.areEqual(contents, ((ASN1UTCTime)o).contents);
}
public int hashCode()
{
- return Arrays.hashCode(time);
+ return Arrays.hashCode(contents);
}
public String toString()
{
- return Strings.fromByteArray(time);
+ return Strings.fromByteArray(contents);
+ }
+
+ static ASN1UTCTime createPrimitive(byte[] contents)
+ {
+ return new ASN1UTCTime(contents);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTF8String.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTF8String.java
new file mode 100644
index 0000000..e764f78
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTF8String.java
@@ -0,0 +1,133 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1UTF8String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1UTF8String.class, BERTags.UTF8_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a UTF8 string from the passed in object.
+ *
+ * @param obj an ASN1UTF8String or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1UTF8String instance, or null
+ */
+ public static ASN1UTF8String getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1UTF8String)
+ {
+ return (ASN1UTF8String)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1UTF8String)
+ {
+ return (ASN1UTF8String)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1UTF8String)TYPE.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());
+ }
+
+ /**
+ * Return an UTF8 String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return a DERUTF8String instance, or null
+ */
+ public static ASN1UTF8String getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1UTF8String)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1UTF8String(String string)
+ {
+ this(Strings.toUTF8ByteArray(string), false);
+ }
+
+ ASN1UTF8String(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromUTF8ByteArray(contents);
+ }
+
+ // TODO Not sure this is useful unless all ASN.1 types have a meaningful one
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1UTF8String))
+ {
+ return false;
+ }
+
+ ASN1UTF8String that = (ASN1UTF8String)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.UTF8_STRING, contents);
+ }
+
+ static ASN1UTF8String createPrimitive(byte[] contents)
+ {
+ return new DERUTF8String(contents, false);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UniversalString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UniversalString.java
new file mode 100644
index 0000000..2b65286
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UniversalString.java
@@ -0,0 +1,180 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * ASN.1 UniversalString object - encodes UNICODE (ISO 10646) characters using 32-bit format. In Java we
+ * have no way of representing this directly so we rely on byte arrays to carry these.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1UniversalString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1UniversalString.class, BERTags.UNIVERSAL_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ /**
+ * Return a Universal String from the passed in object.
+ *
+ * @param obj an ASN1UniversalString or an object that can be converted into
+ * one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1UniversalString instance, or null
+ */
+ public static ASN1UniversalString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1UniversalString)
+ {
+ return (ASN1UniversalString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1UniversalString)
+ {
+ return (ASN1UniversalString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1UniversalString)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return a Universal String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return a ASN1UniversalString instance, or null
+ */
+ public static ASN1UniversalString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1UniversalString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1UniversalString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ int dl = contents.length;
+ StringBuffer buf = new StringBuffer(3 + 2 * (ASN1OutputStream.getLengthOfDL(dl) + dl));
+ buf.append("#1C");
+ encodeHexDL(buf, dl);
+
+ for (int i = 0; i < dl; ++i)
+ {
+ encodeHexByte(buf, contents[i]);
+ }
+
+ return buf.toString();
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.UNIVERSAL_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1UniversalString))
+ {
+ return false;
+ }
+
+ ASN1UniversalString that = (ASN1UniversalString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1UniversalString createPrimitive(byte[] contents)
+ {
+ return new DERUniversalString(contents, false);
+ }
+
+ private static void encodeHexByte(StringBuffer buf, int i)
+ {
+ buf.append(table[(i >>> 4) & 0xF]);
+ buf.append(table[i & 0xF]);
+ }
+
+ private static void encodeHexDL(StringBuffer buf, int dl)
+ {
+ if (dl < 128)
+ {
+ encodeHexByte(buf, dl);
+ return;
+ }
+
+ byte[] stack = new byte[5];
+ int pos = 5;
+
+ do
+ {
+ stack[--pos] = (byte)dl;
+ dl >>>= 8;
+ }
+ while (dl != 0);
+
+ int count = stack.length - pos;
+ stack[--pos] = (byte)(0x80 | count);
+
+ do
+ {
+ encodeHexByte(buf, stack[pos++]);
+ }
+ while (pos < stack.length);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UniversalType.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UniversalType.java
new file mode 100644
index 0000000..6d0cfed
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UniversalType.java
@@ -0,0 +1,57 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+abstract class ASN1UniversalType
+ extends ASN1Type
+{
+ final ASN1Tag tag;
+
+ ASN1UniversalType(Class javaClass, int tagNumber)
+ {
+ super(javaClass);
+
+ this.tag = ASN1Tag.create(BERTags.UNIVERSAL, tagNumber);
+ }
+
+ final ASN1Primitive checkedCast(ASN1Primitive primitive)
+ {
+ if (javaClass.isInstance(primitive))
+ {
+ return primitive;
+ }
+
+ throw new IllegalStateException("unexpected object: " + primitive.getClass().getName());
+ }
+
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ throw new IllegalStateException("unexpected implicit primitive encoding");
+ }
+
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ throw new IllegalStateException("unexpected implicit constructed encoding");
+ }
+
+ final ASN1Primitive fromByteArray(byte[] bytes) throws IOException
+ {
+ return checkedCast(ASN1Primitive.fromByteArray(bytes));
+ }
+
+ final ASN1Primitive getContextInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
+ {
+ if (BERTags.CONTEXT_SPECIFIC != taggedObject.getTagClass())
+ {
+ throw new IllegalStateException("this method only valid for CONTEXT_SPECIFIC tags");
+ }
+
+ return checkedCast(taggedObject.getBaseUniversal(declaredExplicit, this));
+ }
+
+ final ASN1Tag getTag()
+ {
+ return tag;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UniversalTypes.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UniversalTypes.java
new file mode 100644
index 0000000..4f5deef
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UniversalTypes.java
@@ -0,0 +1,72 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+final class ASN1UniversalTypes
+{
+ private ASN1UniversalTypes()
+ {
+ }
+
+ static ASN1UniversalType get(int tagNumber)
+ {
+ switch (tagNumber)
+ {
+ case BERTags.BOOLEAN:
+ return ASN1Boolean.TYPE;
+ case BERTags.INTEGER:
+ return ASN1Integer.TYPE;
+ case BERTags.BIT_STRING:
+ return ASN1BitString.TYPE;
+ case BERTags.OCTET_STRING:
+ return ASN1OctetString.TYPE;
+ case BERTags.NULL:
+ return ASN1Null.TYPE;
+ case BERTags.OBJECT_IDENTIFIER:
+ return ASN1ObjectIdentifier.TYPE;
+ case BERTags.OBJECT_DESCRIPTOR: // [UNIVERSAL 7] IMPLICIT GraphicString
+ return ASN1ObjectDescriptor.TYPE;
+ case BERTags.EXTERNAL:
+ return ASN1External.TYPE;
+ case BERTags.ENUMERATED:
+ return ASN1Enumerated.TYPE;
+ case BERTags.UTF8_STRING: // [UNIVERSAL 12] IMPLICIT OCTET STRING (encode as if)
+ return ASN1UTF8String.TYPE;
+ case BERTags.RELATIVE_OID:
+ return ASN1RelativeOID.TYPE;
+ case BERTags.SEQUENCE:
+ return ASN1Sequence.TYPE;
+ case BERTags.SET:
+ return ASN1Set.TYPE;
+ case BERTags.NUMERIC_STRING: // [UNIVERSAL 18] IMPLICIT OCTET STRING (encode as if)
+ return ASN1NumericString.TYPE;
+ case BERTags.PRINTABLE_STRING: // [UNIVERSAL 19] IMPLICIT OCTET STRING (encode as if)
+ return ASN1PrintableString.TYPE;
+ case BERTags.T61_STRING: // [UNIVERSAL 20] IMPLICIT OCTET STRING (encode as if)
+ return ASN1T61String.TYPE;
+ case BERTags.VIDEOTEX_STRING: // [UNIVERSAL 21] IMPLICIT OCTET STRING (encode as if)
+ return ASN1VideotexString.TYPE;
+ case BERTags.IA5_STRING: // [UNIVERSAL 22] IMPLICIT OCTET STRING (encode as if)
+ return ASN1IA5String.TYPE;
+ case BERTags.UTC_TIME: // [UNIVERSAL 23] IMPLICIT VisibleString (restricted values)
+ return ASN1UTCTime.TYPE;
+ case BERTags.GENERALIZED_TIME: // [UNIVERSAL 24] IMPLICIT VisibleString (restricted values)
+ return ASN1GeneralizedTime.TYPE;
+ case BERTags.GRAPHIC_STRING: // [UNIVERSAL 25] IMPLICIT OCTET STRING (encode as if)
+ return ASN1GraphicString.TYPE;
+ case BERTags.VISIBLE_STRING: // [UNIVERSAL 26] IMPLICIT OCTET STRING (encode as if)
+ return ASN1VisibleString.TYPE;
+ case BERTags.GENERAL_STRING: // [UNIVERSAL 27] IMPLICIT OCTET STRING (encode as if)
+ return ASN1GeneralString.TYPE;
+ case BERTags.UNIVERSAL_STRING: // [UNIVERSAL 28] IMPLICIT OCTET STRING (encode as if)
+ return ASN1UniversalString.TYPE;
+ case BERTags.BMP_STRING: // [UNIVERSAL 30] IMPLICIT OCTET STRING (encode as if)
+ return ASN1BMPString.TYPE;
+
+ case BERTags.REAL:
+ case BERTags.EMBEDDED_PDV:
+ case BERTags.UNRESTRICTED_STRING:
+ default:
+ return null;
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Util.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Util.java
new file mode 100644
index 0000000..d79587c
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Util.java
@@ -0,0 +1,331 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1Util
+{
+ static ASN1TaggedObject checkTag(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ String expected = getTagText(tagClass, tagNo);
+ String found = getTagText(taggedObject);
+ throw new IllegalStateException("Expected " + expected + " tag but found " + found);
+ }
+ return taggedObject;
+ }
+
+ static ASN1TaggedObjectParser checkTag(ASN1TaggedObjectParser taggedObjectParser, int tagClass, int tagNo)
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ String expected = getTagText(tagClass, tagNo);
+ String found = getTagText(taggedObjectParser);
+ throw new IllegalStateException("Expected " + expected + " tag but found " + found);
+ }
+ return taggedObjectParser;
+ }
+
+
+ /*
+ * Tag text methods
+ */
+
+ static String getTagText(ASN1Tag tag)
+ {
+ return getTagText(tag.getTagClass(), tag.getTagNumber());
+ }
+
+ public static String getTagText(ASN1TaggedObject taggedObject)
+ {
+ return getTagText(taggedObject.getTagClass(), taggedObject.getTagNo());
+ }
+
+ public static String getTagText(ASN1TaggedObjectParser taggedObjectParser)
+ {
+ return getTagText(taggedObjectParser.getTagClass(), taggedObjectParser.getTagNo());
+ }
+
+ public static String getTagText(int tagClass, int tagNo)
+ {
+ switch (tagClass)
+ {
+ case BERTags.APPLICATION:
+ return "[APPLICATION " + tagNo + "]";
+ case BERTags.CONTEXT_SPECIFIC:
+ return "[CONTEXT " + tagNo + "]";
+ case BERTags.PRIVATE:
+ return "[PRIVATE " + tagNo + "]";
+ default:
+ return "[UNIVERSAL " + tagNo + "]";
+ }
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getExplicitBaseObject
+ */
+
+ public static ASN1Object getExplicitBaseObject(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getExplicitBaseObject();
+ }
+
+ public static ASN1Object getExplicitContextBaseObject(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return getExplicitBaseObject(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1Object tryGetExplicitBaseObject(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getExplicitBaseObject();
+ }
+
+ public static ASN1Object tryGetExplicitContextBaseObject(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return tryGetExplicitBaseObject(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getExplicitBaseTagged
+ */
+
+ public static ASN1TaggedObject getExplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObject getExplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return getExplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1TaggedObject tryGetExplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObject tryGetExplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return tryGetExplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getImplicitBaseTagged
+ */
+
+ public static ASN1TaggedObject getImplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObject getImplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ return getImplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObject tryGetImplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObject tryGetImplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ return tryGetImplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getBaseUniversal
+ */
+
+ public static ASN1Primitive getBaseUniversal(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Primitive getContextBaseUniversal(ASN1TaggedObject taggedObject, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ return getBaseUniversal(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Primitive tryGetBaseUniversal(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Primitive tryGetContextBaseUniversal(ASN1TaggedObject taggedObject, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ return tryGetBaseUniversal(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseExplicitBaseTagged
+ */
+
+ public static ASN1TaggedObjectParser parseExplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObjectParser parseExplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo) throws IOException
+ {
+ return parseExplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1TaggedObjectParser tryParseExplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObjectParser tryParseExplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo) throws IOException
+ {
+ return tryParseExplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseImplicitBaseTagged
+ */
+
+ public static ASN1TaggedObjectParser parseImplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObjectParser parseImplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ return parseImplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObjectParser tryParseImplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObjectParser tryParseImplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ return tryParseImplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseBaseUniversal
+ */
+
+ public static ASN1Encodable parseBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo, boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Encodable parseContextBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagNo,
+ boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ return parseBaseUniversal(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Encodable tryParseBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo, boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Encodable tryParseContextBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagNo,
+ boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ return tryParseBaseUniversal(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseExplicitBaseObject
+ */
+
+ public static ASN1Encodable parseExplicitBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseExplicitBaseObject();
+ }
+
+ public static ASN1Encodable parseExplicitContextBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagNo)
+ throws IOException
+ {
+ return parseExplicitBaseObject(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1Encodable tryParseExplicitBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseExplicitBaseObject();
+ }
+
+ public static ASN1Encodable tryParseExplicitContextBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagNo)
+ throws IOException
+ {
+ return tryParseExplicitBaseObject(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1VideotexString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1VideotexString.java
new file mode 100644
index 0000000..1c0d3df
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1VideotexString.java
@@ -0,0 +1,131 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1VideotexString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1VideotexString.class, BERTags.VIDEOTEX_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * return a Videotex String from the passed in object
+ *
+ * @param obj an ASN1VideotexString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1VideotexString instance, or null.
+ */
+ public static ASN1VideotexString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1VideotexString)
+ {
+ return (ASN1VideotexString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1VideotexString)
+ {
+ return (ASN1VideotexString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1VideotexString)TYPE.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());
+ }
+
+ /**
+ * return a Videotex String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1VideotexString instance, or null.
+ */
+ public static ASN1VideotexString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1VideotexString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ /**
+ * basic constructor - with bytes.
+ * @param string the byte encoding of the characters making up the string.
+ */
+ ASN1VideotexString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.VIDEOTEX_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1VideotexString))
+ {
+ return false;
+ }
+
+ ASN1VideotexString that = (ASN1VideotexString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ static ASN1VideotexString createPrimitive(byte[] contents)
+ {
+ return new DERVideotexString(contents, false);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1VisibleString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1VisibleString.java
new file mode 100644
index 0000000..7b49fc9
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1VisibleString.java
@@ -0,0 +1,143 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 VisibleString object encoding ISO 646 (ASCII) character code points 32 to 126.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1VisibleString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1VisibleString.class, BERTags.VISIBLE_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a Visible String from the passed in object.
+ *
+ * @param obj an ASN1VisibleString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1VisibleString instance, or null
+ */
+ public static ASN1VisibleString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1VisibleString)
+ {
+ return (ASN1VisibleString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1VisibleString)
+ {
+ return (ASN1VisibleString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1VisibleString)TYPE.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());
+ }
+
+ /**
+ * Return a Visible String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1VisibleString instance, or null
+ */
+ public static ASN1VisibleString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1VisibleString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1VisibleString(String string)
+ {
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1VisibleString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.VISIBLE_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1VisibleString))
+ {
+ return false;
+ }
+
+ ASN1VisibleString that = (ASN1VisibleString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1VisibleString createPrimitive(byte[] contents)
+ {
+ return new DERVisibleString(contents, false);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERApplicationSpecific.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERApplicationSpecific.java
deleted file mode 100644
index ae0d363..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERApplicationSpecific.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * An indefinite-length encoding version of an ASN.1 ApplicationSpecific object.
- * @hide This class is not part of the Android public SDK API
- */
-public class BERApplicationSpecific
- extends ASN1ApplicationSpecific
-{
- BERApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- super(isConstructed, tag, octets);
- }
-
- /**
- * Create an application specific object with a tagging of explicit/constructed.
- *
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public BERApplicationSpecific(
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- this(true, tag, object);
- }
-
- /**
- * Create an application specific object with the tagging style given by the value of constructed.
- *
- * @param constructed true if the object is constructed.
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public BERApplicationSpecific(
- boolean constructed,
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
- }
-
- private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
- throws IOException
- {
- byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.BER);
-
- if (explicit)
- {
- return data;
- }
- else
- {
- int lenBytes = getLengthOfHeader(data);
- byte[] tmp = new byte[data.length - lenBytes];
- System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
- return tmp;
- }
- }
-
- /**
- * Create an application specific object which is marked as constructed
- *
- * @param tagNo the tag number for this object.
- * @param vec the objects making up the application specific object.
- */
- public BERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
- {
- super(true, tagNo, getEncodedVector(vec));
- }
-
- private static byte[] getEncodedVector(ASN1EncodableVector vec)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != vec.size(); i++)
- {
- try
- {
- bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.BER));
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("malformed object: " + e, e);
- }
- }
- return bOut.toByteArray();
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncodedIndef(withTag, flags, tag, octets);
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERApplicationSpecificParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERApplicationSpecificParser.java
deleted file mode 100644
index 2474f18..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERApplicationSpecificParser.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-/**
- * A parser for indefinite-length ASN.1 ApplicationSpecific objects.
- * @hide This class is not part of the Android public SDK API
- */
-public class BERApplicationSpecificParser
- implements ASN1ApplicationSpecificParser
-{
- private final int tag;
- private final ASN1StreamParser parser;
-
- BERApplicationSpecificParser(int tag, ASN1StreamParser parser)
- {
- this.tag = tag;
- this.parser = parser;
- }
-
- /**
- * Return the object contained in this application specific object,
- * @return the contained object.
- * @throws IOException if the underlying stream cannot be read, or does not contain an ASN.1 encoding.
- */
- public ASN1Encodable readObject()
- throws IOException
- {
- return parser.readObject();
- }
-
- /**
- * Return an in-memory, encodable, representation of the application specific object.
- *
- * @return a BERApplicationSpecific.
- * @throws IOException if there is an issue loading the data.
- */
- public ASN1Primitive getLoadedObject()
- throws IOException
- {
- return new BERApplicationSpecific(tag, parser.readVector());
- }
-
- /**
- * Return a BERApplicationSpecific representing this parser and its contents.
- *
- * @return a BERApplicationSpecific
- */
- public ASN1Primitive toASN1Primitive()
- {
- try
- {
- return getLoadedObject();
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException(e.getMessage(), e);
- }
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERBitString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERBitString.java
new file mode 100644
index 0000000..e1e7a15
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERBitString.java
@@ -0,0 +1,192 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERBitString
+ extends ASN1BitString
+{
+ private static final int DEFAULT_SEGMENT_LIMIT = 1000;
+
+ private final int segmentLimit;
+ private final ASN1BitString[] elements;
+
+ /**
+ * Convert a vector of bit strings into a single bit string
+ */
+ static byte[] flattenBitStrings(ASN1BitString[] bitStrings)
+ {
+ int count = bitStrings.length;
+ switch (count)
+ {
+ case 0:
+ // No bits
+ return new byte[]{ 0 };
+ case 1:
+ return bitStrings[0].contents;
+ default:
+ {
+ int last = count - 1, totalLength = 0;
+ for (int i = 0; i < last; ++i)
+ {
+ byte[] elementContents = bitStrings[i].contents;
+ if (elementContents[0] != 0)
+ {
+ throw new IllegalArgumentException("only the last nested bitstring can have padding");
+ }
+
+ totalLength += elementContents.length - 1;
+ }
+
+ // Last one can have padding
+ byte[] lastElementContents = bitStrings[last].contents;
+ byte padBits = lastElementContents[0];
+ totalLength += lastElementContents.length;
+
+ byte[] contents = new byte[totalLength];
+ contents[0] = padBits;
+
+ int pos = 1;
+ for (int i = 0; i < count; ++i)
+ {
+ byte[] elementContents = bitStrings[i].contents;
+ int length = elementContents.length - 1;
+ System.arraycopy(elementContents, 1, contents, pos, length);
+ pos += length;
+ }
+
+// assert pos == totalLength;
+ return contents;
+ }
+ }
+ }
+
+ public BERBitString(byte[] data)
+ {
+ this(data, 0);
+ }
+
+ public BERBitString(byte data, int padBits)
+ {
+ super(data, padBits);
+ this.elements = null;
+ this.segmentLimit = DEFAULT_SEGMENT_LIMIT;
+ }
+
+ public BERBitString(byte[] data, int padBits)
+ {
+ this(data, padBits, DEFAULT_SEGMENT_LIMIT);
+ }
+
+ public BERBitString(byte[] data, int padBits, int segmentLimit)
+ {
+ super(data, padBits);
+ this.elements = null;
+ this.segmentLimit = segmentLimit;
+ }
+
+ public BERBitString(ASN1Encodable obj) throws IOException
+ {
+ this(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
+ }
+
+ public BERBitString(ASN1BitString[] elements)
+ {
+ this(elements, DEFAULT_SEGMENT_LIMIT);
+ }
+
+ public BERBitString(ASN1BitString[] elements, int segmentLimit)
+ {
+ super(flattenBitStrings(elements), false);
+ this.elements = elements;
+ this.segmentLimit = segmentLimit;
+ }
+
+ BERBitString(byte[] contents, boolean check)
+ {
+ super(contents, check);
+ this.elements = null;
+ this.segmentLimit = DEFAULT_SEGMENT_LIMIT;
+ }
+
+ boolean encodeConstructed()
+ {
+ return null != elements || contents.length > segmentLimit;
+ }
+
+ int encodedLength(boolean withTag)
+ throws IOException
+ {
+ if (!encodeConstructed())
+ {
+ return DLBitString.encodedLength(withTag, contents.length);
+ }
+
+ int totalLength = withTag ? 4 : 3;
+
+ if (null != elements)
+ {
+ for (int i = 0; i < elements.length; ++i)
+ {
+ totalLength += elements[i].encodedLength(true);
+ }
+ }
+ else if (contents.length < 2)
+ {
+ // No bits
+ }
+ else
+ {
+ int extraSegments = (contents.length - 2) / (segmentLimit - 1);
+ totalLength += extraSegments * DLBitString.encodedLength(true, segmentLimit);
+
+ int lastSegmentLength = contents.length - (extraSegments * (segmentLimit - 1));
+ totalLength += DLBitString.encodedLength(true, lastSegmentLength);
+ }
+
+ return totalLength;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ if (!encodeConstructed())
+ {
+ DLBitString.encode(out, withTag, contents, 0, contents.length);
+ return;
+ }
+
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.BIT_STRING);
+ out.write(0x80);
+
+ if (null != elements)
+ {
+ out.writePrimitives(elements);
+ }
+ else if (contents.length < 2)
+ {
+ // No bits
+ }
+ else
+ {
+ byte pad = contents[0];
+ int length = contents.length;
+ int remaining = length - 1;
+ int segmentLength = segmentLimit - 1;
+
+ while (remaining > segmentLength)
+ {
+ DLBitString.encode(out, true, (byte)0, contents, length - remaining, segmentLength);
+ remaining -= segmentLength;
+ }
+
+ DLBitString.encode(out, true, pad, contents, length - remaining, remaining);
+ }
+
+ out.write(0x00);
+ out.write(0x00);
+ }
+}
+
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERBitStringParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERBitStringParser.java
new file mode 100644
index 0000000..ed4f54d
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERBitStringParser.java
@@ -0,0 +1,68 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.org.bouncycastle.util.io.Streams;
+
+/**
+ * A parser for indefinite-length BIT STRINGs.
+ *
+ * @deprecated Check for 'ASN1BitStringParser' instead
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERBitStringParser
+ implements ASN1BitStringParser
+{
+ private ASN1StreamParser _parser;
+
+ private ConstructedBitStream _bitStream;
+
+ BERBitStringParser(
+ ASN1StreamParser parser)
+ {
+ _parser = parser;
+ }
+
+ public InputStream getOctetStream() throws IOException
+ {
+ return _bitStream = new ConstructedBitStream(_parser, true);
+ }
+
+ public InputStream getBitStream() throws IOException
+ {
+ return _bitStream = new ConstructedBitStream(_parser, false);
+ }
+
+ public int getPadBits()
+ {
+ return _bitStream.getPadBits();
+ }
+
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return parse(_parser);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
+ }
+ }
+
+ static BERBitString parse(ASN1StreamParser sp) throws IOException
+ {
+ ConstructedBitStream bitStream = new ConstructedBitStream(sp, false);
+ byte[] data = Streams.readAll(bitStream);
+ int padBits = bitStream.getPadBits();
+ return new BERBitString(data, padBits);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERConstructedOctetString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERConstructedOctetString.java
deleted file mode 100644
index 23ffd48..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERConstructedOctetString.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Vector;
-
-/**
- * @deprecated use BEROctetString
- * @hide This class is not part of the Android public SDK API
- */
-public class BERConstructedOctetString
- extends BEROctetString
-{
- private static final int MAX_LENGTH = 1000;
-
- /**
- * convert a vector of octet strings into a single byte string
- */
- static private byte[] toBytes(
- Vector octs)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != octs.size(); i++)
- {
- try
- {
- DEROctetString o = (DEROctetString)octs.elementAt(i);
-
- bOut.write(o.getOctets());
- }
- catch (ClassCastException e)
- {
- throw new IllegalArgumentException(octs.elementAt(i).getClass().getName() + " found in input should only contain DEROctetString");
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("exception converting octets " + e.toString());
- }
- }
-
- return bOut.toByteArray();
- }
-
- private Vector octs;
-
- /**
- * @param string the octets making up the octet string.
- */
- public BERConstructedOctetString(
- byte[] string)
- {
- super(string);
- }
-
- public BERConstructedOctetString(
- Vector octs)
- {
- super(toBytes(octs));
-
- this.octs = octs;
- }
-
- public BERConstructedOctetString(
- ASN1Primitive obj)
- {
- super(toByteArray(obj));
- }
-
- private static byte[] toByteArray(ASN1Primitive obj)
- {
- try
- {
- return obj.getEncoded();
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("Unable to encode object");
- }
- }
-
- public BERConstructedOctetString(
- ASN1Encodable obj)
- {
- this(obj.toASN1Primitive());
- }
-
- public byte[] getOctets()
- {
- return string;
- }
-
- /**
- * return the DER octets that make up this string.
- */
- public Enumeration getObjects()
- {
- if (octs == null)
- {
- return generateOcts().elements();
- }
-
- return octs.elements();
- }
-
- private Vector generateOcts()
- {
- Vector vec = new Vector();
- for (int i = 0; i < string.length; i += MAX_LENGTH)
- {
- int end;
-
- if (i + MAX_LENGTH > string.length)
- {
- end = string.length;
- }
- else
- {
- end = i + MAX_LENGTH;
- }
-
- byte[] nStr = new byte[end - i];
-
- System.arraycopy(string, i, nStr, 0, nStr.length);
-
- vec.addElement(new DEROctetString(nStr));
- }
-
- return vec;
- }
-
- public static BEROctetString fromSequence(ASN1Sequence seq)
- {
- Vector v = new Vector();
- Enumeration e = seq.getObjects();
-
- while (e.hasMoreElements())
- {
- v.addElement(e.nextElement());
- }
-
- return new BERConstructedOctetString(v);
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERGenerator.java
index af27f8a..d5e0b61 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERGenerator.java
@@ -8,7 +8,7 @@
* Base class for generators for indefinite-length structures.
* @hide This class is not part of the Android public SDK API
*/
-public class BERGenerator
+public abstract class BERGenerator
extends ASN1Generator
{
private boolean _tagged = false;
@@ -45,7 +45,7 @@
{
if (_tagged)
{
- int tagNum = _tagNo | BERTags.TAGGED;
+ int tagNum = _tagNo | BERTags.CONTEXT_SPECIFIC;
if (_isExplicit)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetString.java
index 04c1fad..63d88cd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetString.java
@@ -1,10 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
/**
* ASN.1 OctetStrings, with indefinite length rules, and <i>constructed form</i> support.
@@ -24,172 +21,148 @@
public class BEROctetString
extends ASN1OctetString
{
- private static final int DEFAULT_CHUNK_SIZE = 1000;
+ private static final int DEFAULT_SEGMENT_LIMIT = 1000;
- private final int chunkSize;
- private final ASN1OctetString[] octs;
+ private final int segmentLimit;
+ private final ASN1OctetString[] elements;
/**
* Convert a vector of octet strings into a single byte string
*/
- static private byte[] toBytes(
- ASN1OctetString[] octs)
+ static byte[] flattenOctetStrings(ASN1OctetString[] octetStrings)
{
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != octs.length; i++)
+ int count = octetStrings.length;
+ switch (count)
{
- try
+ case 0:
+ return EMPTY_OCTETS;
+ case 1:
+ return octetStrings[0].string;
+ default:
+ {
+ int totalOctets = 0;
+ for (int i = 0; i < count; ++i)
{
- bOut.write(octs[i].getOctets());
+ totalOctets += octetStrings[i].string.length;
}
- catch (IOException e)
+
+ byte[] string = new byte[totalOctets];
+ for (int i = 0, pos = 0; i < count; ++i)
{
- throw new IllegalArgumentException("exception converting octets " + e.toString());
+ byte[] octets = octetStrings[i].string;
+ System.arraycopy(octets, 0, string, pos, octets.length);
+ pos += octets.length;
}
+
+// assert pos == totalOctets;
+ return string;
}
-
- return bOut.toByteArray();
+ }
}
/**
* Create an OCTET-STRING object from a byte[]
* @param string the octets making up the octet string.
*/
- public BEROctetString(
- byte[] string)
+ public BEROctetString(byte[] string)
{
- this(string, DEFAULT_CHUNK_SIZE);
+ this(string, DEFAULT_SEGMENT_LIMIT);
}
/**
* Multiple {@link ASN1OctetString} data blocks are input,
* the result is <i>constructed form</i>.
*
- * @param octs an array of OCTET STRING to construct the BER OCTET STRING from.
+ * @param elements an array of OCTET STRING to construct the BER OCTET STRING from.
*/
- public BEROctetString(
- ASN1OctetString[] octs)
+ public BEROctetString(ASN1OctetString[] elements)
{
- this(octs, DEFAULT_CHUNK_SIZE);
+ this(elements, DEFAULT_SEGMENT_LIMIT);
}
/**
* Create an OCTET-STRING object from a byte[]
* @param string the octets making up the octet string.
- * @param chunkSize the number of octets stored in each DER encoded component OCTET STRING.
+ * @param segmentLimit the number of octets stored in each DER encoded component OCTET STRING.
*/
- public BEROctetString(
- byte[] string,
- int chunkSize)
+ public BEROctetString(byte[] string, int segmentLimit)
{
- this(string, null, chunkSize);
+ this(string, null, segmentLimit);
}
/**
* Multiple {@link ASN1OctetString} data blocks are input,
* the result is <i>constructed form</i>.
*
- * @param octs an array of OCTET STRING to construct the BER OCTET STRING from.
- * @param chunkSize the number of octets stored in each DER encoded component OCTET STRING.
+ * @param elements an array of OCTET STRING to construct the BER OCTET STRING from.
+ * @param segmentLimit the number of octets stored in each DER encoded component OCTET STRING.
*/
- public BEROctetString(
- ASN1OctetString[] octs,
- int chunkSize)
+ public BEROctetString(ASN1OctetString[] elements, int segmentLimit)
{
- this(toBytes(octs), octs, chunkSize);
+ this(flattenOctetStrings(elements), elements, segmentLimit);
}
- private BEROctetString(byte[] string, ASN1OctetString[] octs, int chunkSize)
+ private BEROctetString(byte[] string, ASN1OctetString[] elements, int segmentLimit)
{
super(string);
- this.octs = octs;
- this.chunkSize = chunkSize;
+ this.elements = elements;
+ this.segmentLimit = segmentLimit;
}
- /**
- * Return the OCTET STRINGs that make up this string.
- *
- * @return an Enumeration of the component OCTET STRINGs.
- */
- public Enumeration getObjects()
- {
- if (octs == null)
- {
- return new Enumeration()
- {
- int pos = 0;
-
- public boolean hasMoreElements()
- {
- return pos < string.length;
- }
-
- public Object nextElement()
- {
- if (pos < string.length)
- {
- int length = Math.min(string.length - pos, chunkSize);
- byte[] chunk = new byte[length];
- System.arraycopy(string, pos, chunk, 0, length);
- pos += length;
- return new DEROctetString(chunk);
- }
- throw new NoSuchElementException();
- }
- };
- }
-
- return new Enumeration()
- {
- int counter = 0;
-
- public boolean hasMoreElements()
- {
- return counter < octs.length;
- }
-
- public Object nextElement()
- {
- if (counter < octs.length)
- {
- return octs[counter++];
- }
- throw new NoSuchElementException();
- }
- };
- }
-
- boolean isConstructed()
+ boolean encodeConstructed()
{
return true;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
throws IOException
{
- int length = 0;
- for (Enumeration e = getObjects(); e.hasMoreElements();)
+ int totalLength = withTag ? 4 : 3;
+
+ if (null != elements)
{
- length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
+ for (int i = 0; i < elements.length; ++i)
+ {
+ totalLength += elements[i].encodedLength(true);
+ }
+ }
+ else
+ {
+ int fullSegments = string.length / segmentLimit;
+ totalLength += fullSegments * DEROctetString.encodedLength(true, segmentLimit);
+
+ int lastSegmentLength = string.length - (fullSegments * segmentLimit);
+ if (lastSegmentLength > 0)
+ {
+ totalLength += DEROctetString.encodedLength(true, lastSegmentLength);
+ }
}
- return 2 + length + 2;
+ return totalLength;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncodedIndef(withTag, BERTags.CONSTRUCTED | BERTags.OCTET_STRING, getObjects());
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
+ out.write(0x80);
- static BEROctetString fromSequence(ASN1Sequence seq)
- {
- int count = seq.size();
- ASN1OctetString[] v = new ASN1OctetString[count];
- for (int i = 0; i < count; ++i)
+ if (null != elements)
{
- v[i] = ASN1OctetString.getInstance(seq.getObjectAt(i));
+ out.writePrimitives(elements);
}
- return new BEROctetString(v);
+ else
+ {
+ int pos = 0;
+ while (pos < string.length)
+ {
+ int segmentLength = Math.min(string.length - pos, segmentLimit);
+ DEROctetString.encode(out, true, string, pos, segmentLength);
+ pos += segmentLength;
+ }
+ }
+
+ out.write(0x00);
+ out.write(0x00);
}
}
+
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringGenerator.java
index 6d21f9c..f7a9852 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringGenerator.java
@@ -98,23 +98,32 @@
public void write(byte[] b, int off, int len) throws IOException
{
- while (len > 0)
+ int bufLen = _buf.length;
+ int available = bufLen - _off;
+ if (len < available)
{
- int numToCopy = Math.min(len, _buf.length - _off);
- System.arraycopy(b, off, _buf, _off, numToCopy);
-
- _off += numToCopy;
- if (_off < _buf.length)
- {
- break;
- }
-
- DEROctetString.encode(_derOut, true, _buf, 0, _buf.length);
- _off = 0;
-
- off += numToCopy;
- len -= numToCopy;
+ System.arraycopy(b, off, _buf, _off, len);
+ _off += len;
+ return;
}
+
+ int count = 0;
+ if (_off > 0)
+ {
+ System.arraycopy(b, off, _buf, _off, available);
+ count += available;
+ DEROctetString.encode(_derOut, true, _buf, 0, bufLen);
+ }
+
+ int remaining;
+ while ((remaining = (len - count)) >= bufLen)
+ {
+ DEROctetString.encode(_derOut, true, b, off + count, bufLen);
+ count += bufLen;
+ }
+
+ System.arraycopy(b, off + count, _buf, 0, remaining);
+ this._off = remaining;
}
public void close()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringParser.java
index 674e488..4f2372e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringParser.java
@@ -8,6 +8,8 @@
/**
* A parser for indefinite-length OCTET STRINGs.
+ *
+ * @deprecated Check for 'ASN1OctetStringParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class BEROctetStringParser
@@ -40,7 +42,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new BEROctetString(Streams.readAll(getOctetStream()));
+ return parse(_parser);
}
/**
@@ -59,4 +61,9 @@
throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
}
}
+
+ static BEROctetString parse(ASN1StreamParser sp) throws IOException
+ {
+ return new BEROctetString(Streams.readAll(new ConstructedOctetStream(sp)));
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequence.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequence.java
index c4531d2..f0cf781 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequence.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequence.java
@@ -46,22 +46,42 @@
super(elements);
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int count = elements.length;
- int totalLength = 0;
+ int totalLength = withTag ? 4 : 3;
- for (int i = 0; i < count; ++i)
+ for (int i = 0, count = elements.length; i < count; ++i)
{
ASN1Primitive p = elements[i].toASN1Primitive();
- totalLength += p.encodedLength();
+ totalLength += p.encodedLength(true);
}
- return 2 + totalLength + 2;
+ return totalLength;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncodedIndef(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, elements);
+ out.writeEncodingIL(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE, elements);
+ }
+
+ ASN1BitString toASN1BitString()
+ {
+ return new BERBitString(getConstructedBitStrings());
+ }
+
+ ASN1External toASN1External()
+ {
+ // TODO There is currently no BERExternal class
+ return ((ASN1Sequence)toDLObject()).toASN1External();
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ return new BEROctetString(getConstructedOctetStrings());
+ }
+
+ ASN1Set toASN1Set()
+ {
+ return new BERSet(false, toArrayInternal());
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequenceParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequenceParser.java
index 4963546..48475b5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequenceParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequenceParser.java
@@ -5,6 +5,8 @@
/**
* Parser for indefinite-length SEQUENCEs.
+ *
+ * @deprecated Check for 'ASN1SequenceParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class BERSequenceParser
@@ -38,7 +40,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new BERSequence(_parser.readVector());
+ return parse(_parser);
}
/**
@@ -57,4 +59,9 @@
throw new IllegalStateException(e.getMessage());
}
}
+
+ static BERSequence parse(ASN1StreamParser sp) throws IOException
+ {
+ return new BERSequence(sp.readVector());
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSet.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSet.java
index 041bdd2..3f299ed 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSet.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSet.java
@@ -61,22 +61,21 @@
super(isSorted, elements);
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int count = elements.length;
- int totalLength = 0;
+ int totalLength = withTag ? 4 : 3;
- for (int i = 0; i < count; ++i)
+ for (int i = 0, count = elements.length; i < count; ++i)
{
ASN1Primitive p = elements[i].toASN1Primitive();
- totalLength += p.encodedLength();
+ totalLength += p.encodedLength(true);
}
- return 2 + totalLength + 2;
+ return totalLength;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncodedIndef(withTag, BERTags.SET | BERTags.CONSTRUCTED, elements);
+ out.writeEncodingIL(withTag, BERTags.CONSTRUCTED | BERTags.SET, elements);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSetParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSetParser.java
index 8362aa1..fa833cb 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSetParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSetParser.java
@@ -5,6 +5,8 @@
/**
* Parser for indefinite-length SETs.
+ *
+ * @deprecated Check for 'ASN1SetParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class BERSetParser
@@ -38,7 +40,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new BERSet(_parser.readVector());
+ return parse(_parser);
}
/**
@@ -57,4 +59,9 @@
throw new ASN1ParsingException(e.getMessage(), e);
}
}
-}
\ No newline at end of file
+
+ static BERSet parse(ASN1StreamParser sp) throws IOException
+ {
+ return new BERSet(sp.readVector());
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObject.java
index 0bdfc35..7cd4e83 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObject.java
@@ -2,7 +2,6 @@
package com.android.org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* BER TaggedObject - in ASN.1 notation this is any object preceded by
@@ -17,124 +16,96 @@
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public BERTaggedObject(
- int tagNo,
- ASN1Encodable obj)
+ public BERTaggedObject(int tagNo, ASN1Encodable obj)
{
super(true, tagNo, obj);
}
+ public BERTaggedObject(int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ super(true, tagClass, tagNo, obj);
+ }
+
/**
* @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public BERTaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
+ public BERTaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
{
super(explicit, tagNo, obj);
}
- /**
- * create an implicitly tagged object that contains a zero
- * length sequence.
- */
- public BERTaggedObject(
- int tagNo)
+ public BERTaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
{
- super(false, tagNo, new BERSequence());
+ super(explicit, tagClass, tagNo, obj);
}
- boolean isConstructed()
+ BERTaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
{
- return explicit || obj.toASN1Primitive().isConstructed();
+ super(explicitness, tagClass, tagNo, obj);
}
- int encodedLength()
- throws IOException
+ boolean encodeConstructed()
+ {
+ return isExplicit() || obj.toASN1Primitive().encodeConstructed();
+ }
+
+ int encodedLength(boolean withTag) throws IOException
{
ASN1Primitive primitive = obj.toASN1Primitive();
- int length = primitive.encodedLength();
+ boolean explicit = isExplicit();
+
+ int length = primitive.encodedLength(explicit);
if (explicit)
{
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ length += 3;
}
- else
- {
- // header length already in calculation
- length = length - 1;
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ length += withTag ? ASN1OutputStream.getLengthOfIdentifier(tagNo) : 0;
+
+ return length;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeTag(withTag, BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
- out.write(0x80);
+// assert out.getClass().isAssignableFrom(ASN1OutputStream.class);
- if (!explicit)
+ ASN1Primitive primitive = obj.toASN1Primitive();
+ boolean explicit = isExplicit();
+
+ if (withTag)
{
- Enumeration e;
- if (obj instanceof ASN1OctetString)
+ int flags = tagClass;
+ if (explicit || primitive.encodeConstructed())
{
- if (obj instanceof BEROctetString)
- {
- e = ((BEROctetString)obj).getObjects();
- }
- else
- {
- ASN1OctetString octs = (ASN1OctetString)obj;
- BEROctetString berO = new BEROctetString(octs.getOctets());
- e = berO.getObjects();
- }
- }
- else if (obj instanceof ASN1Sequence)
- {
- e = ((ASN1Sequence)obj).getObjects();
- }
- else if (obj instanceof ASN1Set)
- {
- e = ((ASN1Set)obj).getObjects();
- }
- else
- {
- throw new ASN1Exception("not implemented: " + obj.getClass().getName());
+ flags |= BERTags.CONSTRUCTED;
}
- out.writeElements(e);
+ out.writeIdentifier(true, flags, tagNo);
+ }
+
+ if (explicit)
+ {
+ out.write(0x80);
+ primitive.encode(out, true);
+ out.write(0x00);
+ out.write(0x00);
}
else
{
- out.writePrimitive(obj.toASN1Primitive(), true);
+ primitive.encode(out, false);
}
+ }
- out.write(0x00);
- out.write(0x00);
+ ASN1Sequence rebuildConstructed(ASN1Primitive primitive)
+ {
+ return new BERSequence(primitive);
+ }
-// ASN1Primitive primitive = obj.toASN1Primitive();
-//
-// int flags = BERTags.TAGGED;
-// if (explicit || primitive.isConstructed())
-// {
-// flags |= BERTags.CONSTRUCTED;
-// }
-//
-// out.writeTag(withTag, flags, tagNo);
-//
-// if (explicit)
-// {
-// out.write(0x80);
-// out.writePrimitive(obj.toASN1Primitive(), true);
-// out.write(0x00);
-// out.write(0x00);
-// }
-// else
-// {
-// out.writePrimitive(obj.toASN1Primitive(), false);
-// }
+ ASN1TaggedObject replaceTag(int tagClass, int tagNo)
+ {
+ return new BERTaggedObject(explicitness, tagClass, tagNo, obj);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObjectParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObjectParser.java
index efc2691..7cd2a14 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObjectParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObjectParser.java
@@ -5,68 +5,49 @@
/**
* Parser for indefinite-length tagged objects.
- * @hide This class is not part of the Android public SDK API
*/
-public class BERTaggedObjectParser
+class BERTaggedObjectParser
implements ASN1TaggedObjectParser
{
- private boolean _constructed;
- private int _tagNumber;
- private ASN1StreamParser _parser;
+ final int _tagClass;
+ final int _tagNo;
+ final ASN1StreamParser _parser;
- BERTaggedObjectParser(
- boolean constructed,
- int tagNumber,
- ASN1StreamParser parser)
+ BERTaggedObjectParser(int tagClass, int tagNo, ASN1StreamParser parser)
{
- _constructed = constructed;
- _tagNumber = tagNumber;
+ _tagClass = tagClass;
+ _tagNo = tagNo;
_parser = parser;
}
- /**
- * Return true if this tagged object is marked as constructed.
- *
- * @return true if constructed, false otherwise.
- */
- public boolean isConstructed()
+ public int getTagClass()
{
- return _constructed;
+ return _tagClass;
}
- /**
- * Return the tag number associated with this object.
- *
- * @return the tag number.
- */
public int getTagNo()
{
- return _tagNumber;
+ return _tagNo;
}
- /**
- * Return an object parser for the contents of this tagged object.
- *
- * @param tag the actual tag number of the object (needed if implicit).
- * @param isExplicit true if the contained object was explicitly tagged, false if implicit.
- * @return an ASN.1 encodable object parser.
- * @throws IOException if there is an issue building the object parser from the stream.
- */
- public ASN1Encodable getObjectParser(
- int tag,
- boolean isExplicit)
- throws IOException
+ public boolean hasContextTag()
{
- if (isExplicit)
- {
- if (!_constructed)
- {
- throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
- }
- return _parser.readObject();
- }
+ return this._tagClass == BERTags.CONTEXT_SPECIFIC;
+ }
- return _parser.readImplicit(_constructed, tag);
+ public boolean hasContextTag(int tagNo)
+ {
+ return this._tagClass == BERTags.CONTEXT_SPECIFIC && this._tagNo == tagNo;
+ }
+
+ public boolean hasTag(int tagClass, int tagNo)
+ {
+ return this._tagClass == tagClass && this._tagNo == tagNo;
+ }
+
+ public boolean hasTagClass(int tagClass)
+ {
+ return this._tagClass == tagClass;
}
/**
@@ -78,7 +59,32 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return _parser.readTaggedObject(_constructed, _tagNumber);
+ return _parser.loadTaggedIL(_tagClass, _tagNo);
+ }
+
+ public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ if (declaredExplicit)
+ {
+ return _parser.parseObject(baseTagNo);
+ }
+
+ return _parser.parseImplicitConstructedIL(baseTagNo);
+ }
+
+ public ASN1Encodable parseExplicitBaseObject() throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException
+ {
+ return _parser.parseTaggedObject();
+ }
+
+ public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException
+ {
+ return new BERTaggedObjectParser(baseTagClass, baseTagNo, _parser);
}
/**
@@ -90,7 +96,7 @@
{
try
{
- return this.getLoadedObject();
+ return getLoadedObject();
}
catch (IOException e)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTags.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTags.java
index a8a9644..8531e69 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTags.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTags.java
@@ -6,20 +6,26 @@
*/
public interface BERTags
{
+ // 0x00: Reserved for use by the encoding rules
public static final int BOOLEAN = 0x01;
public static final int INTEGER = 0x02;
public static final int BIT_STRING = 0x03;
public static final int OCTET_STRING = 0x04;
public static final int NULL = 0x05;
public static final int OBJECT_IDENTIFIER = 0x06;
+ public static final int OBJECT_DESCRIPTOR = 0x07;
public static final int EXTERNAL = 0x08;
+ public static final int REAL = 0x09;
public static final int ENUMERATED = 0x0a; // decimal 10
+ public static final int EMBEDDED_PDV = 0x0b; // decimal 11
+ public static final int UTF8_STRING = 0x0c; // decimal 12
+ public static final int RELATIVE_OID = 0x0d; // decimal 13
+ public static final int TIME = 0x0e;
+ // 0x0f: Reserved for future editions of this Recommendation | International Standard
public static final int SEQUENCE = 0x10; // decimal 16
public static final int SEQUENCE_OF = 0x10; // for completeness - used to model a SEQUENCE of the same type.
public static final int SET = 0x11; // decimal 17
public static final int SET_OF = 0x11; // for completeness - used to model a SET of the same type.
-
-
public static final int NUMERIC_STRING = 0x12; // decimal 18
public static final int PRINTABLE_STRING = 0x13; // decimal 19
public static final int T61_STRING = 0x14; // decimal 20
@@ -31,10 +37,23 @@
public static final int VISIBLE_STRING = 0x1a; // decimal 26
public static final int GENERAL_STRING = 0x1b; // decimal 27
public static final int UNIVERSAL_STRING = 0x1c; // decimal 28
+ public static final int UNRESTRICTED_STRING = 0x1d; // decimal 29
public static final int BMP_STRING = 0x1e; // decimal 30
- public static final int UTF8_STRING = 0x0c; // decimal 12
-
+ public static final int DATE = 0x1f;
+ public static final int TIME_OF_DAY = 0x20;
+ public static final int DATE_TIME = 0x21;
+ public static final int DURATION = 0x22;
+ public static final int OBJECT_IDENTIFIER_IRI = 0x23;
+ public static final int RELATIVE_OID_IRI = 0x24;
+ // 0x25..: Reserved for addenda to this Recommendation | International Standard
+
public static final int CONSTRUCTED = 0x20; // decimal 32
+
+ public static final int UNIVERSAL = 0x00; // decimal 32
public static final int APPLICATION = 0x40; // decimal 64
- public static final int TAGGED = 0x80; // decimal 128
+ public static final int TAGGED = 0x80; // decimal 128 - maybe should deprecate this.
+ public static final int CONTEXT_SPECIFIC = 0x80; // decimal 128
+ public static final int PRIVATE = 0xC0; // decimal 192
+
+ public static final int FLAGS = 0xE0;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ConstructedBitStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ConstructedBitStream.java
new file mode 100644
index 0000000..ea06af1
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ConstructedBitStream.java
@@ -0,0 +1,146 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class ConstructedBitStream
+ extends InputStream
+{
+ private final ASN1StreamParser _parser;
+ private final boolean _octetAligned;
+
+ private boolean _first = true;
+ private int _padBits = 0;
+
+ private ASN1BitStringParser _currentParser;
+ private InputStream _currentStream;
+
+ ConstructedBitStream(ASN1StreamParser parser, boolean octetAligned)
+ {
+ _parser = parser;
+ _octetAligned = octetAligned;
+ }
+
+ int getPadBits()
+ {
+ return _padBits;
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException
+ {
+ if (_currentStream == null)
+ {
+ if (!_first)
+ {
+ return -1;
+ }
+
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ return -1;
+ }
+
+ _first = false;
+ _currentStream = _currentParser.getBitStream();
+
+ }
+
+ int totalRead = 0;
+
+ for (;;)
+ {
+ int numRead = _currentStream.read(b, off + totalRead, len - totalRead);
+
+ if (numRead >= 0)
+ {
+ totalRead += numRead;
+
+ if (totalRead == len)
+ {
+ return totalRead;
+ }
+ }
+ else
+ {
+ _padBits = _currentParser.getPadBits();
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ _currentStream = null;
+ return totalRead < 1 ? -1 : totalRead;
+ }
+
+ _currentStream = _currentParser.getBitStream();
+ }
+ }
+ }
+
+ public int read()
+ throws IOException
+ {
+ if (_currentStream == null)
+ {
+ if (!_first)
+ {
+ return -1;
+ }
+
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ return -1;
+ }
+
+ _first = false;
+ _currentStream = _currentParser.getBitStream();
+ }
+
+ for (;;)
+ {
+ int b = _currentStream.read();
+
+ if (b >= 0)
+ {
+ return b;
+ }
+
+ _padBits = _currentParser.getPadBits();
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ _currentStream = null;
+ return -1;
+ }
+
+ _currentStream = _currentParser.getBitStream();
+ }
+ }
+
+ private ASN1BitStringParser getNextParser() throws IOException
+ {
+ ASN1Encodable asn1Obj = _parser.readObject();
+ if (asn1Obj == null)
+ {
+ if (_octetAligned && _padBits != 0)
+ {
+ throw new IOException("expected octet-aligned bitstring, but found padBits: " + _padBits);
+ }
+
+ return null;
+ }
+
+ if (asn1Obj instanceof ASN1BitStringParser)
+ {
+ if (_padBits != 0)
+ {
+ throw new IOException("only the last nested bitstring can have padding");
+ }
+
+ return (ASN1BitStringParser)asn1Obj;
+ }
+
+ throw new IOException("unknown object encountered: " + asn1Obj.getClass());
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERApplicationSpecific.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERApplicationSpecific.java
deleted file mode 100644
index b77373d..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERApplicationSpecific.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * A DER encoding version of an application specific object.
- * @hide This class is not part of the Android public SDK API
- */
-public class DERApplicationSpecific
- extends ASN1ApplicationSpecific
-{
- DERApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- super(isConstructed, tag, octets);
- }
-
- /**
- * Create an application specific object from the passed in data. This will assume
- * the data does not represent a constructed object.
- *
- * @param tag the tag number for this object.
- * @param octets the encoding of the object's body.
- */
- public DERApplicationSpecific(
- int tag,
- byte[] octets)
- {
- this(false, tag, octets);
- }
-
- /**
- * Create an application specific object with a tagging of explicit/constructed.
- *
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DERApplicationSpecific(
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- this(true, tag, object);
- }
-
- /**
- * Create an application specific object with the tagging style given by the value of constructed.
- *
- * @param constructed true if the object is constructed.
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DERApplicationSpecific(
- boolean constructed,
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
- }
-
- private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
- throws IOException
- {
- byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.DER);
-
- if (explicit)
- {
- return data;
- }
- else
- {
- int lenBytes = getLengthOfHeader(data);
- byte[] tmp = new byte[data.length - lenBytes];
- System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
- return tmp;
- }
- }
-
- /**
- * Create an application specific object which is marked as constructed
- *
- * @param tagNo the tag number for this object.
- * @param vec the objects making up the application specific object.
- */
- public DERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
- {
- super(true, tagNo, getEncodedVector(vec));
- }
-
- private static byte[] getEncodedVector(ASN1EncodableVector vec)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != vec.size(); i++)
- {
- try
- {
- bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DER));
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("malformed object: " + e, e);
- }
- }
- return bOut.toByteArray();
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncoded(withTag, flags, tag, octets);
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBMPString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBMPString.java
index 3803c2b..b5cc119 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBMPString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBMPString.java
@@ -1,10 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-
/**
* DER BMPString object encodes BMP (<i>Basic Multilingual Plane</i>) subset
* (aka UCS-2) of UNICODE (ISO 10646) characters in codepoints 0 to 65535.
@@ -15,203 +11,28 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERBMPString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1BMPString
{
- private final char[] string;
-
- /**
- * Return a BMP String from the given object.
- *
- * @param obj the object we want converted.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERBMPString instance, or null.
- */
- public static DERBMPString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERBMPString)
- {
- return (DERBMPString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERBMPString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a BMP String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERBMPString instance.
- */
- public static DERBMPString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERBMPString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERBMPString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - byte encoded string.
- * @param string the encoded BMP STRING to wrap.
- */
- DERBMPString(
- byte[] string)
- {
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
-
- int byteLen = string.length;
- if (0 != (byteLen & 1))
- {
- throw new IllegalArgumentException("malformed BMPString encoding encountered");
- }
-
- int charLen = byteLen / 2;
- char[] cs = new char[charLen];
-
- for (int i = 0; i != charLen; i++)
- {
- cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
- }
-
- this.string = cs;
- }
-
- DERBMPString(char[] string)
- {
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
-
- this.string = string;
- }
-
/**
* Basic constructor
* @param string a String to wrap as a BMP STRING.
*/
- public DERBMPString(
- String string)
+ public DERBMPString(String string)
{
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
-
- this.string = string.toCharArray();
+ super(string);
}
- public String getString()
+ /**
+ * Basic constructor - byte encoded string.
+ * @param contents the encoded BMP STRING to wrap.
+ */
+ DERBMPString(byte[] contents)
{
- return new String(string);
+ super(contents);
}
- public String toString()
+ DERBMPString(char[] string)
{
- return getString();
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- protected boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERBMPString))
- {
- return false;
- }
-
- DERBMPString s = (DERBMPString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length * 2) + (string.length * 2);
- }
-
- void encode(
- ASN1OutputStream out, boolean withTag)
- throws IOException
- {
- int count = string.length;
- if (withTag)
- {
- out.write(BERTags.BMP_STRING);
- }
- out.writeLength(count * 2);
-
- byte[] buf = new byte[8];
-
- int i = 0, limit = count & -4;
- while (i < limit)
- {
- char c0 = string[i], c1 = string[i + 1], c2 = string[i + 2], c3 = string[i + 3];
- i += 4;
-
- buf[0] = (byte)(c0 >> 8);
- buf[1] = (byte)c0;
- buf[2] = (byte)(c1 >> 8);
- buf[3] = (byte)c1;
- buf[4] = (byte)(c2 >> 8);
- buf[5] = (byte)c2;
- buf[6] = (byte)(c3 >> 8);
- buf[7] = (byte)c3;
-
- out.write(buf, 0, 8);
- }
- if (i < count)
- {
- int bufPos = 0;
- do
- {
- char c0 = string[i];
- i += 1;
-
- buf[bufPos++] = (byte)(c0 >> 8);
- buf[bufPos++] = (byte)c0;
- }
- while (i < count);
-
- out.write(buf, 0, bufPos);
- }
+ super(string);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBitString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBitString.java
index fbfb67c..185e62c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBitString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBitString.java
@@ -10,124 +10,70 @@
public class DERBitString
extends ASN1BitString
{
- /**
- * return a Bit String from the passed in object
- *
- * @param obj a DERBitString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERBitString instance, or null.
- */
- public static DERBitString getInstance(
- Object obj)
+ public static DERBitString convert(ASN1BitString bitString)
{
- if (obj == null || obj instanceof DERBitString)
- {
- return (DERBitString)obj;
- }
- if (obj instanceof DLBitString)
- {
- return new DERBitString(((DLBitString)obj).data, ((DLBitString)obj).padBits);
- }
- if (obj instanceof byte[])
- {
- try
- {
- return (DERBitString)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());
- }
-
- /**
- * return a Bit String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERBitString instance, or null.
- */
- public static DERBitString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERBitString)
- {
- return getInstance(o);
- }
- else
- {
- return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- protected DERBitString(byte data, int padBits)
- {
- super(data, padBits);
- }
-
- /**
- * @param data the octets making up the bit string.
- * @param padBits the number of extra bits at the end of the string.
- */
- public DERBitString(
- byte[] data,
- int padBits)
- {
- super(data, padBits);
+ return (DERBitString)bitString.toDERObject();
}
@android.compat.annotation.UnsupportedAppUsage
- public DERBitString(
- byte[] data)
+ public DERBitString(byte[] data)
{
this(data, 0);
}
- public DERBitString(
- int value)
+ public DERBitString(byte data, int padBits)
{
+ super(data, padBits);
+ }
+
+ public DERBitString(byte[] data, int padBits)
+ {
+ super(data, padBits);
+ }
+
+ public DERBitString(int value)
+ {
+ // TODO[asn1] Unify in single allocation of 'contents'
super(getBytes(value), getPadBits(value));
}
- public DERBitString(
- ASN1Encodable obj)
- throws IOException
+ public DERBitString(ASN1Encodable obj) throws IOException
{
+ // TODO[asn1] Unify in single allocation of 'contents'
super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
}
- boolean isConstructed()
+ DERBitString(byte[] contents, boolean check)
+ {
+ super(contents, check);
+ }
+
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- int len = data.length;
- if (0 == len
- || 0 == padBits
- || (data[len - 1] == (byte)(data[len - 1] & (0xFF << padBits))))
+ int padBits = contents[0] & 0xFF;
+ int length = contents.length;
+ int last = length - 1;
+
+ byte lastOctet = contents[last];
+ byte lastOctetDER = (byte)(contents[last] & (0xFF << padBits));
+
+ if (lastOctet == lastOctetDER)
{
- out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, contents);
}
else
{
- byte der = (byte)(data[len - 1] & (0xFF << padBits));
- out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data, 0, len - 1, der);
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, contents, 0, last, lastOctetDER);
}
}
@@ -141,21 +87,8 @@
return this;
}
- static DERBitString fromOctetString(byte[] bytes)
+ static DERBitString fromOctetString(ASN1OctetString octetString)
{
- if (bytes.length < 1)
- {
- throw new IllegalArgumentException("truncated BIT STRING detected");
- }
-
- int padBits = bytes[0];
- byte[] data = new byte[bytes.length - 1];
-
- if (data.length != 0)
- {
- System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
- }
-
- return new DERBitString(data, padBits);
+ return new DERBitString(octetString.getOctets(), true);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEREncodableVector.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEREncodableVector.java
deleted file mode 100644
index c216ef2..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEREncodableVector.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-/**
- * a general class for building up a vector of DER encodable objects -
- * this will eventually be superseded by ASN1EncodableVector so you should
- * use that class in preference.
- * @hide This class is not part of the Android public SDK API
- */
-public class DEREncodableVector
- extends ASN1EncodableVector
-{
- /**
- * @deprecated use ASN1EncodableVector instead.
- */
- @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- public DEREncodableVector()
- {
-
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEREnumerated.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEREnumerated.java
deleted file mode 100644
index 5d3ce32..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEREnumerated.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-import java.math.BigInteger;
-
-/**
- * @deprecated Use ASN1Enumerated instead of this.
- * @hide This class is not part of the Android public SDK API
- */
-public class DEREnumerated
- extends ASN1Enumerated
-{
- /**
- * @param bytes the value of this enumerated as an encoded BigInteger (signed).
- * @deprecated use ASN1Enumerated
- */
- DEREnumerated(byte[] bytes)
- {
- super(bytes);
- }
-
- /**
- * @param value the value of this enumerated.
- * @deprecated use ASN1Enumerated
- */
- public DEREnumerated(BigInteger value)
- {
- super(value);
- }
-
- /**
- * @param value the value of this enumerated.
- * @deprecated use ASN1Enumerated
- */
- public DEREnumerated(int value)
- {
- super(value);
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternal.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternal.java
index 018b892..f0e60ce 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternal.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternal.java
@@ -1,9 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
/**
* Class representing the DER-type External
* @hide This class is not part of the Android public SDK API
@@ -21,11 +18,30 @@
* <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
* </ul>
*
- * @throws IllegalArgumentException if input size is wrong, or
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ *
+ * @deprecated Use {@link DERExternal#DERExternal(DERSequence)} instead.
*/
public DERExternal(ASN1EncodableVector vector)
{
- super(vector);
+ this(DERFactory.createSequence(vector));
+ }
+
+ /**
+ * Construct a DER EXTERNAL object, the input sequence must have exactly two elements on it.
+ * <p>
+ * Acceptable input formats are:
+ * <ul>
+ * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
+ * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
+ * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
+ * </ul>
+ *
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ */
+ public DERExternal(DERSequence sequence)
+ {
+ super(sequence);
}
/**
@@ -36,9 +52,10 @@
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param externalData The external data in its encoded form.
*/
- public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
{
- this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ super(directReference, indirectReference, dataValueDescriptor, externalData);
}
/**
@@ -50,11 +67,33 @@
* @param encoding The encoding to be used for the external data
* @param externalData The external data
*/
- public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
{
super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
}
+ ASN1Sequence buildSequence()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+ if (directReference != null)
+ {
+ v.add(directReference);
+ }
+ if (indirectReference != null)
+ {
+ v.add(indirectReference);
+ }
+ if (dataValueDescriptor != null)
+ {
+ v.add(dataValueDescriptor.toDERObject());
+ }
+
+ v.add(new DERTaggedObject(0 == encoding, encoding, externalContent));
+
+ return new DERSequence(v);
+ }
+
ASN1Primitive toDERObject()
{
return this;
@@ -64,34 +103,4 @@
{
return this;
}
-
- int encodedLength()
- throws IOException
- {
- return this.getEncoded().length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- if (directReference != null)
- {
- baos.write(directReference.getEncoded(ASN1Encoding.DER));
- }
- if (indirectReference != null)
- {
- baos.write(indirectReference.getEncoded(ASN1Encoding.DER));
- }
- if (dataValueDescriptor != null)
- {
- baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DER));
- }
- DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
- baos.write(obj.getEncoded(ASN1Encoding.DER));
-
- out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
- }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternalParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternalParser.java
index ede2658..9358566 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternalParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternalParser.java
@@ -8,7 +8,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERExternalParser
- implements ASN1Encodable, InMemoryRepresentable
+ implements ASN1ExternalParser
{
private ASN1StreamParser _parser;
@@ -37,14 +37,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- try
- {
- return new DLExternal(_parser.readVector());
- }
- catch (IllegalArgumentException e)
- {
- throw new ASN1Exception(e.getMessage(), e);
- }
+ return parse(_parser);
}
/**
@@ -67,4 +60,16 @@
throw new ASN1ParsingException("unable to get DER object", ioe);
}
}
+
+ static DLExternal parse(ASN1StreamParser sp) throws IOException
+ {
+ try
+ {
+ return new DLExternal(new DLSequence(sp.readVector()));
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception(e.getMessage(), e);
+ }
+ }
}
\ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERFactory.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERFactory.java
index 0c4f774..3195ae3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERFactory.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERFactory.java
@@ -3,10 +3,10 @@
class DERFactory
{
- static final ASN1Sequence EMPTY_SEQUENCE = new DERSequence();
- static final ASN1Set EMPTY_SET = new DERSet();
+ static final DERSequence EMPTY_SEQUENCE = new DERSequence();
+ static final DERSet EMPTY_SET = new DERSet();
- static ASN1Sequence createSequence(ASN1EncodableVector v)
+ static DERSequence createSequence(ASN1EncodableVector v)
{
if (v.size() < 1)
{
@@ -16,7 +16,7 @@
return new DERSequence(v);
}
- static ASN1Set createSet(ASN1EncodableVector v)
+ static DERSet createSet(ASN1EncodableVector v)
{
if (v.size() < 1)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralString.java
index 6781839..c1e3338 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralString.java
@@ -1,11 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.Strings;
-
/**
* ASN.1 GENERAL-STRING data type.
* <p>
@@ -15,136 +10,20 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERGeneralString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1GeneralString
{
- private final byte[] string;
-
- /**
- * Return a GeneralString from the given object.
- *
- * @param obj the object we want converted.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERBMPString instance, or null.
- */
- public static DERGeneralString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERGeneralString)
- {
- return (DERGeneralString) obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERGeneralString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: "
- + obj.getClass().getName());
- }
-
- /**
- * Return a GeneralString from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERGeneralString instance.
- */
- public static DERGeneralString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERGeneralString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERGeneralString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- DERGeneralString(byte[] string)
- {
- this.string = string;
- }
-
/**
* Construct a GeneralString from the passed in String.
*
* @param string the string to be contained in this object.
*/
- public DERGeneralString(String string)
+ public DERGeneralString(String string)
{
- this.string = Strings.toByteArray(string);
+ super(string);
}
- /**
- * Return a Java String representation of our contained String.
- *
- * @return a Java String representing our contents.
- */
- public String getString()
+ DERGeneralString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- /**
- * Return a byte array representation of our contained String.
- *
- * @return a byte array representing our contents.
- */
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.GENERAL_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(ASN1Primitive o)
- {
- if (!(o instanceof DERGeneralString))
- {
- return false;
- }
- DERGeneralString s = (DERGeneralString)o;
-
- return Arrays.areEqual(string, s.string);
+ super(contents, clone);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralizedTime.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralizedTime.java
index b8f3969..fe4a3ad 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralizedTime.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralizedTime.java
@@ -44,39 +44,39 @@
private byte[] getDERTime()
{
- if (time[time.length - 1] == 'Z')
+ if (contents[contents.length - 1] == 'Z')
{
if (!hasMinutes())
{
- byte[] derTime = new byte[time.length + 4];
+ byte[] derTime = new byte[contents.length + 4];
- System.arraycopy(time, 0, derTime, 0, time.length - 1);
- System.arraycopy(Strings.toByteArray("0000Z"), 0, derTime, time.length - 1, 5);
+ System.arraycopy(contents, 0, derTime, 0, contents.length - 1);
+ System.arraycopy(Strings.toByteArray("0000Z"), 0, derTime, contents.length - 1, 5);
return derTime;
}
else if (!hasSeconds())
{
- byte[] derTime = new byte[time.length + 2];
+ byte[] derTime = new byte[contents.length + 2];
- System.arraycopy(time, 0, derTime, 0, time.length - 1);
- System.arraycopy(Strings.toByteArray("00Z"), 0, derTime, time.length - 1, 3);
+ System.arraycopy(contents, 0, derTime, 0, contents.length - 1);
+ System.arraycopy(Strings.toByteArray("00Z"), 0, derTime, contents.length - 1, 3);
return derTime;
}
else if (hasFractionalSeconds())
{
- int ind = time.length - 2;
- while (ind > 0 && time[ind] == '0')
+ int ind = contents.length - 2;
+ while (ind > 0 && contents[ind] == '0')
{
ind--;
}
- if (time[ind] == '.')
+ if (contents[ind] == '.')
{
byte[] derTime = new byte[ind + 1];
- System.arraycopy(time, 0, derTime, 0, ind);
+ System.arraycopy(contents, 0, derTime, 0, ind);
derTime[ind] = (byte)'Z';
return derTime;
@@ -85,7 +85,7 @@
{
byte[] derTime = new byte[ind + 2];
- System.arraycopy(time, 0, derTime, 0, ind + 1);
+ System.arraycopy(contents, 0, derTime, 0, ind + 1);
derTime[ind + 1] = (byte)'Z';
return derTime;
@@ -93,25 +93,23 @@
}
else
{
- return time;
+ return contents;
}
}
else
{
- return time; // TODO: is there a better way?
+ return contents; // TODO: is there a better way?
}
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- int length = getDERTime().length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getDERTime().length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, getDERTime());
+ out.writeEncodingDL(withTag, BERTags.GENERALIZED_TIME, getDERTime());
}
ASN1Primitive toDERObject()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGraphicString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGraphicString.java
index 1000928..b130aaa 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGraphicString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGraphicString.java
@@ -1,126 +1,19 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.Strings;
-
/**
* @hide This class is not part of the Android public SDK API
*/
public class DERGraphicString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1GraphicString
{
- private final byte[] string;
-
- /**
- * return a Graphic String from the passed in object
- *
- * @param obj a DERGraphicString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERGraphicString instance, or null.
- */
- public static DERGraphicString getInstance(
- Object obj)
+ public DERGraphicString(byte[] octets)
{
- if (obj == null || obj instanceof DERGraphicString)
- {
- return (DERGraphicString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERGraphicString)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());
+ this(octets, true);
}
- /**
- * return a Graphic String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERGraphicString instance, or null.
- */
- public static DERGraphicString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ DERGraphicString(byte[] contents, boolean clone)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERGraphicString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERGraphicString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * basic constructor - with bytes.
- * @param string the byte encoding of the characters making up the string.
- */
- public DERGraphicString(
- byte[] string)
- {
- this.string = Arrays.clone(string);
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.GRAPHIC_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERGraphicString))
- {
- return false;
- }
-
- DERGraphicString s = (DERGraphicString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- public String getString()
- {
- return Strings.fromByteArray(string);
+ super(contents, clone);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERIA5String.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERIA5String.java
index b4364e3..cdf85f4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERIA5String.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERIA5String.java
@@ -1,11 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.Strings;
-
/**
* DER IA5String object - this is a ISO 646 (ASCII) string encoding code points 0 to 127.
* <p>
@@ -14,83 +9,13 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERIA5String
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1IA5String
{
- private final byte[] string;
-
- /**
- * Return an IA5 string from the passed in object
- *
- * @param obj a DERIA5String or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERIA5String instance, or null.
- */
- public static DERIA5String getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERIA5String)
- {
- return (DERIA5String)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERIA5String)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return an IA5 String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERIA5String instance, or null.
- */
- public static DERIA5String getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERIA5String)
- {
- return getInstance(o);
- }
- else
- {
- return new DERIA5String(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - with bytes.
- * @param string the byte encoding of the characters making up the string.
- */
- DERIA5String(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor - without validation.
* @param string the base string to use..
*/
- public DERIA5String(
- String string)
+ public DERIA5String(String string)
{
this(string, false);
}
@@ -103,90 +28,13 @@
* @throws IllegalArgumentException if validate is true and the string
* contains characters that should not be in an IA5String.
*/
- public DERIA5String(
- String string,
- boolean validate)
+ public DERIA5String(String string, boolean validate)
{
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
- if (validate && !isIA5String(string))
- {
- throw new IllegalArgumentException("'string' contains illegal characters");
- }
-
- this.string = Strings.toByteArray(string);
+ super(string, validate);
}
- public String getString()
+ DERIA5String(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.IA5_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERIA5String))
- {
- return false;
- }
-
- DERIA5String s = (DERIA5String)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- /**
- * return true if the passed in String can be represented without
- * loss as an IA5String, false otherwise.
- *
- * @param str the string to check.
- * @return true if character set in IA5String set, false otherwise.
- */
- public static boolean isIA5String(
- String str)
- {
- for (int i = str.length() - 1; i >= 0; i--)
- {
- char ch = str.charAt(i);
-
- if (ch > 0x007f)
- {
- return false;
- }
- }
-
- return true;
+ super(contents, clone);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERInteger.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERInteger.java
deleted file mode 100644
index 75e8aea..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERInteger.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-import java.math.BigInteger;
-
-/**
- * @deprecated Use ASN1Integer instead of this,
- * @hide This class is not part of the Android public SDK API
- */
-public class DERInteger
- extends ASN1Integer
-{
- /**
- * Constructor from a byte array containing a signed representation of the number.
- *
- * @param bytes a byte array containing the signed number.A copy is made of the byte array.
- */
- public DERInteger(byte[] bytes)
- {
- super(bytes, true);
- }
-
- @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- public DERInteger(BigInteger value)
- {
- super(value);
- }
-
- @android.compat.annotation.UnsupportedAppUsage
- public DERInteger(long value)
- {
- super(value);
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNull.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNull.java
index b4de8ae..83720a8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNull.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNull.java
@@ -21,18 +21,18 @@
{
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 2;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, 0);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.NULL, zeroBytes);
+ out.writeEncodingDL(withTag, BERTags.NULL, zeroBytes);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNumericString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNumericString.java
index 1ff789c..f888c58 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNumericString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNumericString.java
@@ -1,11 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.Strings;
-
/**
* DER NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
* ASN.1 NUMERIC-STRING object.
@@ -18,81 +13,12 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERNumericString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1NumericString
{
- private final byte[] string;
-
- /**
- * Return a Numeric string from the passed in object
- *
- * @param obj a DERNumericString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERNumericString instance, or null
- */
- public static DERNumericString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERNumericString)
- {
- return (DERNumericString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERNumericString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return an Numeric String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERNumericString instance, or null.
- */
- public static DERNumericString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERNumericString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERNumericString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - with bytes.
- */
- DERNumericString(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor - without validation..
*/
- public DERNumericString(
- String string)
+ public DERNumericString(String string)
{
this(string, false);
}
@@ -105,92 +31,13 @@
* @throws IllegalArgumentException if validate is true and the string
* contains characters that should not be in a NumericString.
*/
- public DERNumericString(
- String string,
- boolean validate)
+ public DERNumericString(String string, boolean validate)
{
- if (validate && !isNumericString(string))
- {
- throw new IllegalArgumentException("string contains illegal characters");
- }
-
- this.string = Strings.toByteArray(string);
+ super(string, validate);
}
- public String getString()
+ DERNumericString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.NUMERIC_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERNumericString))
- {
- return false;
- }
-
- DERNumericString s = (DERNumericString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- /**
- * Return true if the string can be represented as a NumericString ('0'..'9', ' ')
- *
- * @param str string to validate.
- * @return true if numeric, fale otherwise.
- */
- public static boolean isNumericString(
- String str)
- {
- for (int i = str.length() - 1; i >= 0; i--)
- {
- char ch = str.charAt(i);
-
- if (ch > 0x007f)
- {
- return false;
- }
-
- if (('0' <= ch && ch <= '9') || ch == ' ')
- {
- continue;
- }
-
- return false;
- }
-
- return true;
+ super(contents, clone);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERObjectIdentifier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERObjectIdentifier.java
deleted file mode 100644
index 05c8380..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERObjectIdentifier.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-/**
- *
- * @deprecated Use ASN1ObjectIdentifier instead of this,
- * @hide This class is not part of the Android public SDK API
- */
-public class DERObjectIdentifier
- extends ASN1ObjectIdentifier
-{
- @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- public DERObjectIdentifier(String identifier)
- {
- super(identifier);
- }
-
- DERObjectIdentifier(byte[] bytes)
- {
- super(bytes);
- }
-
- DERObjectIdentifier(ASN1ObjectIdentifier oid, String branch)
- {
- super(oid, branch);
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetString.java
index 52cbfa4..b69d63e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetString.java
@@ -34,19 +34,19 @@
super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER));
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, string.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.OCTET_STRING, string);
+ out.writeEncodingDL(withTag, BERTags.OCTET_STRING, string);
}
ASN1Primitive toDERObject()
@@ -59,8 +59,13 @@
return this;
}
- static void encode(ASN1OutputStream derOut, boolean withTag, byte[] buf, int off, int len) throws IOException
+ static void encode(ASN1OutputStream out, boolean withTag, byte[] buf, int off, int len) throws IOException
{
- derOut.writeEncoded(withTag, BERTags.OCTET_STRING, buf, off, len);
+ out.writeEncodingDL(withTag, BERTags.OCTET_STRING, buf, off, len);
+ }
+
+ static int encodedLength(boolean withTag, int contentsLength)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contentsLength);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetStringParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetStringParser.java
index 8ea3ef4..8c4636a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetStringParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetStringParser.java
@@ -6,6 +6,8 @@
/**
* Parser for DER encoded OCTET STRINGS
+ *
+ * @deprecated Check for 'ASN1OctetStringParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class DEROctetStringParser
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROutputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROutputStream.java
index 2cae73b..cfb2d70 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROutputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROutputStream.java
@@ -19,18 +19,32 @@
super(os);
}
- void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
- {
- primitive.toDERObject().encode(this, withTag);
- }
-
DEROutputStream getDERSubStream()
{
return this;
}
- ASN1OutputStream getDLSubStream()
+ void writeElements(ASN1Encodable[] elements)
+ throws IOException
{
- return this;
+ for (int i = 0, count = elements.length; i < count; ++i)
+ {
+ elements[i].toASN1Primitive().toDERObject().encode(this, true);
+ }
+ }
+
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
+ {
+ primitive.toDERObject().encode(this, withTag);
+ }
+
+ void writePrimitives(ASN1Primitive[] primitives)
+ throws IOException
+ {
+ int count = primitives.length;
+ for (int i = 0; i < count; ++i)
+ {
+ primitives[i].toDERObject().encode(this, true);
+ }
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERPrintableString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERPrintableString.java
index f32ecff..6e3b558 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERPrintableString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERPrintableString.java
@@ -1,11 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.Strings;
-
/**
* DER PrintableString object.
* <p>
@@ -34,76 +29,8 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERPrintableString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1PrintableString
{
- private final byte[] string;
-
- /**
- * Return a printable string from the passed in object.
- *
- * @param obj a DERPrintableString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERPrintableString instance, or null.
- */
- public static DERPrintableString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERPrintableString)
- {
- return (DERPrintableString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERPrintableString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a Printable String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERPrintableString instance, or null.
- */
- public static DERPrintableString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERPrintableString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERPrintableString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - byte encoded string.
- */
- DERPrintableString(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor - this does not validate the string
*/
@@ -125,115 +52,11 @@
String string,
boolean validate)
{
- if (validate && !isPrintableString(string))
- {
- throw new IllegalArgumentException("string contains illegal characters");
- }
-
- this.string = Strings.toByteArray(string);
+ super(string, validate);
}
- public String getString()
+ DERPrintableString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.PRINTABLE_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERPrintableString))
- {
- return false;
- }
-
- DERPrintableString s = (DERPrintableString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- /**
- * return true if the passed in String can be represented without
- * loss as a PrintableString, false otherwise.
- *
- * @return true if in printable set, false otherwise.
- */
- public static boolean isPrintableString(
- String str)
- {
- for (int i = str.length() - 1; i >= 0; i--)
- {
- char ch = str.charAt(i);
-
- if (ch > 0x007f)
- {
- return false;
- }
-
- if ('a' <= ch && ch <= 'z')
- {
- continue;
- }
-
- if ('A' <= ch && ch <= 'Z')
- {
- continue;
- }
-
- if ('0' <= ch && ch <= '9')
- {
- continue;
- }
-
- switch (ch)
- {
- case ' ':
- case '\'':
- case '(':
- case ')':
- case '+':
- case '-':
- case '.':
- case ':':
- case '=':
- case '?':
- case '/':
- case ',':
- continue;
- }
-
- return false;
- }
-
- return true;
+ super(contents, clone);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequence.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequence.java
index 9e8b6e5..85dafab 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequence.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequence.java
@@ -18,7 +18,7 @@
return (DERSequence)seq.toDERObject();
}
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* Create an empty sequence
@@ -61,9 +61,9 @@
super(elements, clone);
}
- private int getBodyLength() throws IOException
+ private int getContentsLength() throws IOException
{
- if (bodyLength < 0)
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -71,20 +71,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/*
@@ -97,17 +95,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE);
DEROutputStream derOut = out.getDERSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -124,11 +119,11 @@
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
derObjects[i] = derObject;
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
@@ -137,6 +132,27 @@
}
}
+ ASN1BitString toASN1BitString()
+ {
+ return new DERBitString(BERBitString.flattenBitStrings(getConstructedBitStrings()), false);
+ }
+
+ ASN1External toASN1External()
+ {
+ return new DERExternal(this);
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ return new DEROctetString(BEROctetString.flattenOctetStrings(getConstructedOctetStrings()));
+ }
+
+ ASN1Set toASN1Set()
+ {
+ // NOTE: DLSet is intentional, we don't want sorting
+ return new DLSet(false, toArrayInternal());
+ }
+
ASN1Primitive toDERObject()
{
return this;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequenceParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequenceParser.java
deleted file mode 100644
index 918db1f..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequenceParser.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-/**
- * @deprecated Use DLSequenceParser instead
- * @hide This class is not part of the Android public SDK API
- */
-public class DERSequenceParser
- implements ASN1SequenceParser
-{
- private ASN1StreamParser _parser;
-
- DERSequenceParser(ASN1StreamParser parser)
- {
- this._parser = parser;
- }
-
- /**
- * Return the next object in the SEQUENCE.
- *
- * @return next object in SEQUENCE.
- * @throws IOException if there is an issue loading the object.
- */
- public ASN1Encodable readObject()
- throws IOException
- {
- return _parser.readObject();
- }
-
- /**
- * Return an in memory, encodable, representation of the SEQUENCE.
- *
- * @return a DERSequence.
- * @throws IOException if there is an issue loading the data.
- */
- public ASN1Primitive getLoadedObject()
- throws IOException
- {
- return new DLSequence(_parser.readVector());
- }
-
- /**
- * Return a DERSequence representing this parser and its contents.
- *
- * @return a DERSequence.
- */
- public ASN1Primitive toASN1Primitive()
- {
- try
- {
- return getLoadedObject();
- }
- catch (IOException e)
- {
- throw new IllegalStateException(e.getMessage());
- }
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSet.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSet.java
index bacdb68..79e5c58 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSet.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSet.java
@@ -22,7 +22,7 @@
return (DERSet)set.toDERObject();
}
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* create an empty set
@@ -64,9 +64,9 @@
super(checkSorted(isSorted), elements);
}
- private int getBodyLength() throws IOException
+ private int getContentsLength() throws IOException
{
- if (bodyLength < 0)
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -74,20 +74,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/*
@@ -100,17 +98,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SET);
DEROutputStream derOut = out.getDERSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -127,11 +122,11 @@
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
derObjects[i] = derObject;
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
@@ -142,7 +137,7 @@
ASN1Primitive toDERObject()
{
- return isSorted ? this : super.toDERObject();
+ return (sortedElements != null) ? this : super.toDERObject();
}
ASN1Primitive toDLObject()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSetParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSetParser.java
deleted file mode 100644
index 31b1577..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSetParser.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-/**
- * @deprecated Use DLSetParser instead
- * @hide This class is not part of the Android public SDK API
- */
-public class DERSetParser
- implements ASN1SetParser
-{
- private ASN1StreamParser _parser;
-
- DERSetParser(ASN1StreamParser parser)
- {
- this._parser = parser;
- }
-
- /**
- * Return the next object in the SET.
- *
- * @return next object in SET.
- * @throws IOException if there is an issue loading the object.
- */
- public ASN1Encodable readObject()
- throws IOException
- {
- return _parser.readObject();
- }
-
- /**
- * Return an in memory, encodable, representation of the SET.
- *
- * @return a DERSet.
- * @throws IOException if there is an issue loading the data.
- */
- public ASN1Primitive getLoadedObject()
- throws IOException
- {
- return new DLSet(_parser.readVector());
- }
-
- /**
- * Return a DERSet representing this parser and its contents.
- *
- * @return a DERSet
- */
- public ASN1Primitive toASN1Primitive()
- {
- try
- {
- return getLoadedObject();
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException(e.getMessage(), e);
- }
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERT61String.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERT61String.java
index a0a7b3c..2f73b48 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERT61String.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERT61String.java
@@ -1,76 +1,22 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.Strings;
-
/**
* DER T61String (also the teletex string), try not to use this if you don't need to. The standard support the encoding for
* this has been withdrawn.
* @hide This class is not part of the Android public SDK API
*/
public class DERT61String
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1T61String
{
- private byte[] string;
-
/**
- * Return a T61 string from the passed in object.
+ * Basic constructor - with string 8 bit assumed.
*
- * @param obj a DERT61String or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERT61String instance, or null
+ * @param string the string to be wrapped.
*/
- public static DERT61String getInstance(
- Object obj)
+ public DERT61String(String string)
{
- if (obj == null || obj instanceof DERT61String)
- {
- return (DERT61String)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERT61String)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return an T61 String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERT61String instance, or null
- */
- public static DERT61String getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERT61String)
- {
- return getInstance(o);
- }
- else
- {
- return new DERT61String(ASN1OctetString.getInstance(o).getOctets());
- }
+ super(string);
}
/**
@@ -78,74 +24,13 @@
*
* @param string the byte encoding of the string to be wrapped.
*/
- public DERT61String(
- byte[] string)
+ public DERT61String(byte[] string)
{
- this.string = Arrays.clone(string);
+ this(string, true);
}
- /**
- * Basic constructor - with string 8 bit assumed.
- *
- * @param string the string to be wrapped.
- */
- public DERT61String(
- String string)
+ DERT61String(byte[] contents, boolean clone)
{
- this.string = Strings.toByteArray(string);
- }
-
- /**
- * Decode the encoded string and return it, 8 bit encoding assumed.
- * @return the decoded String
- */
- public String getString()
- {
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.T61_STRING, string);
- }
-
- /**
- * Return the encoded string as a byte array.
- * @return the actual bytes making up the encoded body of the T61 string.
- */
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERT61String))
- {
- return false;
- }
-
- return Arrays.areEqual(string, ((DERT61String)o).string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
+ super(contents, clone);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTaggedObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTaggedObject.java
index 2aaf86a..5570a48 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTaggedObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTaggedObject.java
@@ -12,68 +12,94 @@
public class DERTaggedObject
extends ASN1TaggedObject
{
- /**
- * @param explicit true if an explicitly tagged object.
- * @param tagNo the tag number for this object.
- * @param obj the tagged object.
- */
- public DERTaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
- {
- super(explicit, tagNo, obj);
- }
-
public DERTaggedObject(int tagNo, ASN1Encodable encodable)
{
super(true, tagNo, encodable);
}
- boolean isConstructed()
+ public DERTaggedObject(int tagClass, int tagNo, ASN1Encodable obj)
{
- return explicit || obj.toASN1Primitive().toDERObject().isConstructed();
+ super(true, tagClass, tagNo, obj);
}
- int encodedLength()
- throws IOException
+ /**
+ * @param explicit true if an explicitly tagged object.
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public DERTaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
+ {
+ super(explicit, tagNo, obj);
+ }
+
+ public DERTaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ super(explicit, tagClass, tagNo, obj);
+ }
+
+ DERTaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ super(explicitness, tagClass, tagNo, obj);
+ }
+
+ boolean encodeConstructed()
+ {
+ return isExplicit() || obj.toASN1Primitive().toDERObject().encodeConstructed();
+ }
+
+ int encodedLength(boolean withTag) throws IOException
{
ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
- int length = primitive.encodedLength();
+ boolean explicit = isExplicit();
+
+ int length = primitive.encodedLength(explicit);
if (explicit)
{
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ length += ASN1OutputStream.getLengthOfDL(length);
}
- else
- {
- // header length already in calculation
- length = length - 1;
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ length += withTag ? ASN1OutputStream.getLengthOfIdentifier(tagNo) : 0;
+
+ return length;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
+// assert out.getClass().isAssignableFrom(DEROutputStream.class);
+
ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
+ boolean explicit = isExplicit();
- int flags = BERTags.TAGGED;
- if (explicit || primitive.isConstructed())
+ if (withTag)
{
- flags |= BERTags.CONSTRUCTED;
- }
+ int flags = tagClass;
+ if (explicit || primitive.encodeConstructed())
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
- out.writeTag(withTag, flags, tagNo);
+ out.writeIdentifier(true, flags, tagNo);
+ }
if (explicit)
{
- out.writeLength(primitive.encodedLength());
+ out.writeDL(primitive.encodedLength(true));
}
primitive.encode(out.getDERSubStream(), explicit);
}
+ ASN1Sequence rebuildConstructed(ASN1Primitive primitive)
+ {
+ return new DERSequence(primitive);
+ }
+
+ ASN1TaggedObject replaceTag(int tagClass, int tagNo)
+ {
+ return new DERTaggedObject(explicitness, tagClass, tagNo, obj);
+ }
+
ASN1Primitive toDERObject()
{
return this;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTags.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTags.java
deleted file mode 100644
index eddc5f1..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTags.java
+++ /dev/null
@@ -1,11 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-/**
- * @deprecated use BERTags
- * @hide This class is not part of the Android public SDK API
- */
-public interface DERTags
- extends BERTags
-{
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUTF8String.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUTF8String.java
index 8136d45..b2444c2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUTF8String.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUTF8String.java
@@ -1,88 +1,13 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.Strings;
-
/**
* DER UTF8String object.
* @hide This class is not part of the Android public SDK API
*/
public class DERUTF8String
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1UTF8String
{
- private final byte[] string;
-
- /**
- * Return an UTF8 string from the passed in object.
- *
- * @param obj a DERUTF8String or an object that can be converted into one.
- * @exception IllegalArgumentException
- * if the object cannot be converted.
- * @return a DERUTF8String instance, or null
- */
- public static DERUTF8String getInstance(Object obj)
- {
- if (obj == null || obj instanceof DERUTF8String)
- {
- return (DERUTF8String)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERUTF8String)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: "
- + obj.getClass().getName());
- }
-
- /**
- * Return an UTF8 String from a tagged object.
- *
- * @param obj
- * the tagged object holding the object we want
- * @param explicit
- * true if the object is meant to be explicitly tagged false
- * otherwise.
- * @exception IllegalArgumentException
- * if the tagged object cannot be converted.
- * @return a DERUTF8String instance, or null
- */
- public static DERUTF8String getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERUTF8String)
- {
- return getInstance(o);
- }
- else
- {
- return new DERUTF8String(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /*
- * Basic constructor - byte encoded string.
- */
- DERUTF8String(byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor
*
@@ -90,49 +15,11 @@
*/
public DERUTF8String(String string)
{
- this.string = Strings.toUTF8ByteArray(string);
+ super(string);
}
- public String getString()
+ DERUTF8String(byte[] contents, boolean clone)
{
- return Strings.fromUTF8ByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(ASN1Primitive o)
- {
- if (!(o instanceof DERUTF8String))
- {
- return false;
- }
-
- DERUTF8String s = (DERUTF8String)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- throws IOException
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.UTF8_STRING, string);
+ super(contents, clone);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUniversalString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUniversalString.java
index 0aaef1e..56c5c9b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUniversalString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUniversalString.java
@@ -1,150 +1,26 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-
/**
* DER UniversalString object - encodes UNICODE (ISO 10646) characters using 32-bit format. In Java we
* have no way of representing this directly so we rely on byte arrays to carry these.
* @hide This class is not part of the Android public SDK API
*/
public class DERUniversalString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1UniversalString
{
- private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- private final byte[] string;
-
- /**
- * Return a Universal String from the passed in object.
- *
- * @param obj a DERUniversalString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERUniversalString instance, or null
- */
- public static DERUniversalString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERUniversalString)
- {
- return (DERUniversalString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERUniversalString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a Universal String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERUniversalString instance, or null
- */
- public static DERUniversalString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERUniversalString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERUniversalString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
/**
* Basic constructor - byte encoded string.
*
* @param string the byte encoding of the string to be carried in the UniversalString object,
*/
- public DERUniversalString(
- byte[] string)
+ public DERUniversalString(byte[] string)
{
- this.string = Arrays.clone(string);
+ this(string, true);
}
- public String getString()
+ DERUniversalString(byte[] contents, boolean clone)
{
- StringBuffer buf = new StringBuffer("#");
-
- byte[] string;
- try
- {
- string = getEncoded();
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("internal error encoding UniversalString");
- }
-
- for (int i = 0; i != string.length; i++)
- {
- buf.append(table[(string[i] >>> 4) & 0xf]);
- buf.append(table[string[i] & 0xf]);
- }
-
- return buf.toString();
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.UNIVERSAL_STRING, string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERUniversalString))
- {
- return false;
- }
-
- return Arrays.areEqual(string, ((DERUniversalString)o).string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
+ super(contents, clone);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVideotexString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVideotexString.java
index 505072f..e1340d3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVideotexString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVideotexString.java
@@ -1,126 +1,19 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.Strings;
-
/**
* @hide This class is not part of the Android public SDK API
*/
public class DERVideotexString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1VideotexString
{
- private final byte[] string;
-
- /**
- * return a Videotex String from the passed in object
- *
- * @param obj a DERVideotexString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERVideotexString instance, or null.
- */
- public static DERVideotexString getInstance(
- Object obj)
+ public DERVideotexString(byte[] octets)
{
- if (obj == null || obj instanceof DERVideotexString)
- {
- return (DERVideotexString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERVideotexString)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());
+ this(octets, true);
}
- /**
- * return a Videotex String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERVideotexString instance, or null.
- */
- public static DERVideotexString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ DERVideotexString(byte[] contents, boolean clone)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERVideotexString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERVideotexString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * basic constructor - with bytes.
- * @param string the byte encoding of the characters making up the string.
- */
- public DERVideotexString(
- byte[] string)
- {
- this.string = Arrays.clone(string);
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.VIDEOTEX_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERVideotexString))
- {
- return false;
- }
-
- DERVideotexString s = (DERVideotexString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- public String getString()
- {
- return Strings.fromByteArray(string);
+ super(contents, clone);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVisibleString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVisibleString.java
index dbfb118..6478807 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVisibleString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVisibleString.java
@@ -1,11 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.Strings;
-
/**
* DER VisibleString object encoding ISO 646 (ASCII) character code points 32 to 126.
* <p>
@@ -14,130 +9,20 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERVisibleString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1VisibleString
{
- private final byte[] string;
-
- /**
- * Return a Visible String from the passed in object.
- *
- * @param obj a DERVisibleString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERVisibleString instance, or null
- */
- public static DERVisibleString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERVisibleString)
- {
- return (DERVisibleString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERVisibleString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a Visible String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERVisibleString instance, or null
- */
- public static DERVisibleString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERVisibleString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERVisibleString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /*
- * Basic constructor - byte encoded string.
- */
- DERVisibleString(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor
*
* @param string the string to be carried in the VisibleString object,
*/
- public DERVisibleString(
- String string)
+ public DERVisibleString(String string)
{
- this.string = Strings.toByteArray(string);
+ super(string);
}
- public String getString()
+ DERVisibleString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.VISIBLE_STRING, this.string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERVisibleString))
- {
- return false;
- }
-
- return Arrays.areEqual(string, ((DERVisibleString)o).string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
+ super(contents, clone);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLApplicationSpecific.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLApplicationSpecific.java
deleted file mode 100644
index 53bf2d7..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLApplicationSpecific.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * A DER encoding version of an application specific object.
- * @hide This class is not part of the Android public SDK API
- */
-public class DLApplicationSpecific
- extends ASN1ApplicationSpecific
-{
- DLApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- super(isConstructed, tag, octets);
- }
-
- /**
- * Create an application specific object from the passed in data. This will assume
- * the data does not represent a constructed object.
- *
- * @param tag the tag number for this object.
- * @param octets the encoding of the object's body.
- */
- public DLApplicationSpecific(
- int tag,
- byte[] octets)
- {
- this(false, tag, octets);
- }
-
- /**
- * Create an application specific object with a tagging of explicit/constructed.
- *
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DLApplicationSpecific(
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- this(true, tag, object);
- }
-
- /**
- * Create an application specific object with the tagging style given by the value of constructed.
- *
- * @param constructed true if the object is constructed.
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DLApplicationSpecific(
- boolean constructed,
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
- }
-
- private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
- throws IOException
- {
- byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.DL);
-
- if (explicit)
- {
- return data;
- }
- else
- {
- int lenBytes = getLengthOfHeader(data);
- byte[] tmp = new byte[data.length - lenBytes];
- System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
- return tmp;
- }
- }
-
- /**
- * Create an application specific object which is marked as constructed
- *
- * @param tagNo the tag number for this object.
- * @param vec the objects making up the application specific object.
- */
- public DLApplicationSpecific(int tagNo, ASN1EncodableVector vec)
- {
- super(true, tagNo, getEncodedVector(vec));
- }
-
- private static byte[] getEncodedVector(ASN1EncodableVector vec)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != vec.size(); i++)
- {
- try
- {
- bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DL));
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("malformed object: " + e, e);
- }
- }
- return bOut.toByteArray();
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncoded(withTag, flags, tag, octets);
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitString.java
index 7ee84e4..b076d4a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitString.java
@@ -10,113 +10,51 @@
public class DLBitString
extends ASN1BitString
{
- /**
- * return a Bit String that can be definite-length encoded from the passed in object.
- *
- * @param obj a DL or DER BitString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return an ASN1BitString instance, or null.
- */
- public static ASN1BitString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DLBitString)
- {
- return (DLBitString)obj;
- }
- if (obj instanceof DERBitString)
- {
- return (DERBitString)obj;
- }
- if (obj instanceof byte[])
- {
- try
- {
- return (ASN1BitString)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());
- }
-
- /**
- * return a Bit String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return an ASN1BitString instance, or null.
- */
- public static ASN1BitString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DLBitString)
- {
- return getInstance(o);
- }
- else
- {
- return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- protected DLBitString(byte data, int padBits)
- {
- super(data, padBits);
- }
-
- /**
- * @param data the octets making up the bit string.
- * @param padBits the number of extra bits at the end of the string.
- */
- public DLBitString(
- byte[] data,
- int padBits)
- {
- super(data, padBits);
- }
-
- public DLBitString(
- byte[] data)
+ public DLBitString(byte[] data)
{
this(data, 0);
}
- public DLBitString(
- int value)
+ public DLBitString(byte data, int padBits)
{
+ super(data, padBits);
+ }
+
+ public DLBitString(byte[] data, int padBits)
+ {
+ super(data, padBits);
+ }
+
+ public DLBitString(int value)
+ {
+ // TODO[asn1] Unify in single allocation of 'contents'
super(getBytes(value), getPadBits(value));
}
- public DLBitString(
- ASN1Encodable obj)
- throws IOException
+ public DLBitString(ASN1Encodable obj) throws IOException
{
+ // TODO[asn1] Unify in single allocation of 'contents'
super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
}
- boolean isConstructed()
+ DLBitString(byte[] contents, boolean check)
+ {
+ super(contents, check);
+ }
+
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, contents);
}
ASN1Primitive toDLObject()
@@ -124,21 +62,19 @@
return this;
}
- static DLBitString fromOctetString(byte[] bytes)
+ static int encodedLength(boolean withTag, int contentsLength)
{
- if (bytes.length < 1)
- {
- throw new IllegalArgumentException("truncated BIT STRING detected");
- }
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contentsLength);
+ }
- int padBits = bytes[0];
- byte[] data = new byte[bytes.length - 1];
+ static void encode(ASN1OutputStream out, boolean withTag, byte[] buf, int off, int len) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, buf, off, len);
+ }
- if (data.length != 0)
- {
- System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
- }
-
- return new DLBitString(data, padBits);
+ static void encode(ASN1OutputStream out, boolean withTag, byte pad, byte[] buf, int off, int len)
+ throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, pad, buf, off, len);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitStringParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitStringParser.java
new file mode 100644
index 0000000..ec98b36
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitStringParser.java
@@ -0,0 +1,85 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Parser for a DL encoded BIT STRING.
+ *
+ * @deprecated Check for 'ASN1BitStringParser' instead
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLBitStringParser
+ implements ASN1BitStringParser
+{
+ private final DefiniteLengthInputStream stream;
+ private int padBits = 0;
+
+ DLBitStringParser(
+ DefiniteLengthInputStream stream)
+ {
+ this.stream = stream;
+ }
+
+ public InputStream getBitStream() throws IOException
+ {
+ return getBitStream(false);
+ }
+
+ public InputStream getOctetStream() throws IOException
+ {
+ return getBitStream(true);
+ }
+
+ public int getPadBits()
+ {
+ return padBits;
+ }
+
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return ASN1BitString.createPrimitive(stream.toByteArray());
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
+ }
+ }
+
+ private InputStream getBitStream(boolean octetAligned) throws IOException
+ {
+ int length = stream.getRemaining();
+ if (length < 1)
+ {
+ throw new IllegalStateException("content octets cannot be empty");
+ }
+
+ padBits = stream.read();
+ if (padBits > 0)
+ {
+ if (length < 2)
+ {
+ throw new IllegalStateException("zero length data with non-zero pad bits");
+ }
+ if (padBits > 7)
+ {
+ throw new IllegalStateException("pad bits cannot be greater than 7 or less than 0");
+ }
+ if (octetAligned)
+ {
+ throw new IOException("expected octet-aligned bitstring, but found padBits: " + padBits);
+ }
+ }
+
+ return stream;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLExternal.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLExternal.java
index 0945a86..47d4aba 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLExternal.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLExternal.java
@@ -1,9 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
/**
* Class representing the Definite-Length-type External
* @hide This class is not part of the Android public SDK API
@@ -21,11 +18,30 @@
* <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
* </ul>
*
- * @throws IllegalArgumentException if input size is wrong, or
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ *
+ * @deprecated Use {@link DLExternal#DLExternal(DLSequence)} instead.
*/
public DLExternal(ASN1EncodableVector vector)
{
- super(vector);
+ this(DLFactory.createSequence(vector));
+ }
+
+ /**
+ * Construct a Definite-Length EXTERNAL object, the input sequence must have exactly two elements on it.
+ * <p>
+ * Acceptable input formats are:
+ * <ul>
+ * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
+ * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
+ * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
+ * </ul>
+ *
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ */
+ public DLExternal(DLSequence sequence)
+ {
+ super(sequence);
}
/**
@@ -36,9 +52,10 @@
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param externalData The external data in its encoded form.
*/
- public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
{
- this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ super(directReference, indirectReference, dataValueDescriptor, externalData);
}
/**
@@ -50,43 +67,35 @@
* @param encoding The encoding to be used for the external data
* @param externalData The external data
*/
- public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
{
super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
}
+ ASN1Sequence buildSequence()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+ if (directReference != null)
+ {
+ v.add(directReference);
+ }
+ if (indirectReference != null)
+ {
+ v.add(indirectReference);
+ }
+ if (dataValueDescriptor != null)
+ {
+ v.add(dataValueDescriptor.toDLObject());
+ }
+
+ v.add(new DLTaggedObject(0 == encoding, encoding, externalContent));
+
+ return new DLSequence(v);
+ }
+
ASN1Primitive toDLObject()
{
return this;
}
-
- int encodedLength()
- throws IOException
- {
- return this.getEncoded().length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- if (directReference != null)
- {
- baos.write(directReference.getEncoded(ASN1Encoding.DL));
- }
- if (indirectReference != null)
- {
- baos.write(indirectReference.getEncoded(ASN1Encoding.DL));
- }
- if (dataValueDescriptor != null)
- {
- baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DL));
- }
- ASN1TaggedObject obj = new DLTaggedObject(true, encoding, externalContent);
- baos.write(obj.getEncoded(ASN1Encoding.DL));
-
- out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
- }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLFactory.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLFactory.java
index ad993d1..738fcb2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLFactory.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLFactory.java
@@ -3,10 +3,10 @@
class DLFactory
{
- static final ASN1Sequence EMPTY_SEQUENCE = new DLSequence();
- static final ASN1Set EMPTY_SET = new DLSet();
+ static final DLSequence EMPTY_SEQUENCE = new DLSequence();
+ static final DLSet EMPTY_SET = new DLSet();
- static ASN1Sequence createSequence(ASN1EncodableVector v)
+ static DLSequence createSequence(ASN1EncodableVector v)
{
if (v.size() < 1)
{
@@ -16,7 +16,7 @@
return new DLSequence(v);
}
- static ASN1Set createSet(ASN1EncodableVector v)
+ static DLSet createSet(ASN1EncodableVector v)
{
if (v.size() < 1)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLOutputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLOutputStream.java
index 1ab6e15..993882a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLOutputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLOutputStream.java
@@ -15,13 +15,32 @@
super(os);
}
+ DLOutputStream getDLSubStream()
+ {
+ return this;
+ }
+
+ void writeElements(ASN1Encodable[] elements)
+ throws IOException
+ {
+ for (int i = 0, count = elements.length; i < count; ++i)
+ {
+ elements[i].toASN1Primitive().toDLObject().encode(this, true);
+ }
+ }
+
void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
{
primitive.toDLObject().encode(this, withTag);
}
- ASN1OutputStream getDLSubStream()
+ void writePrimitives(ASN1Primitive[] primitives)
+ throws IOException
{
- return this;
+ int count = primitives.length;
+ for (int i = 0; i < count; ++i)
+ {
+ primitives[i].toDLObject().encode(this, true);
+ }
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequence.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequence.java
index 1255e33..278bd15 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequence.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequence.java
@@ -10,7 +10,7 @@
public class DLSequence
extends ASN1Sequence
{
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* Create an empty sequence
@@ -51,9 +51,9 @@
super(elements, clone);
}
- private int getBodyLength() throws IOException
+ private int getContentsLength() throws IOException
{
- if (bodyLength < 0)
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -61,20 +61,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/**
@@ -87,17 +85,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE);
ASN1OutputStream dlOut = out.getDLSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -113,11 +108,11 @@
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
dlObjects[i] = dlObject;
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
@@ -126,8 +121,29 @@
}
}
+ ASN1BitString toASN1BitString()
+ {
+ return new DLBitString(BERBitString.flattenBitStrings(getConstructedBitStrings()), false);
+ }
+
+ ASN1External toASN1External()
+ {
+ return new DLExternal(this);
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ // NOTE: There is no DLOctetString
+ return new DEROctetString(BEROctetString.flattenOctetStrings(getConstructedOctetStrings()));
+ }
+
+ ASN1Set toASN1Set()
+ {
+ return new DLSet(false, toArrayInternal());
+ }
+
ASN1Primitive toDLObject()
{
return this;
}
-}
\ No newline at end of file
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequenceParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequenceParser.java
index e5c17f6..8933837 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequenceParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequenceParser.java
@@ -6,7 +6,7 @@
/**
* Parser class for DL SEQUENCEs.
*
- * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ * @deprecated Check for 'ASN1SequenceParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class DLSequenceParser
@@ -40,7 +40,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new DLSequence(_parser.readVector());
+ return DLFactory.createSequence(_parser.readVector());
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSet.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSet.java
index 85b71a8..85932d4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSet.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSet.java
@@ -55,7 +55,7 @@
public class DLSet
extends ASN1Set
{
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* create an empty set
@@ -93,9 +93,14 @@
super(isSorted, elements);
}
- private int getBodyLength() throws IOException
+ DLSet(ASN1Encodable[] elements, ASN1Encodable[] sortedElements)
{
- if (bodyLength < 0)
+ super(elements, sortedElements);
+ }
+
+ private int getContentsLength() throws IOException
+ {
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -103,20 +108,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/**
@@ -129,17 +132,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SET);
ASN1OutputStream dlOut = out.getDLSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -155,11 +155,11 @@
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
dlObjects[i] = dlObject;
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSetParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSetParser.java
index 6d2ef11..9d6cd8e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSetParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSetParser.java
@@ -6,7 +6,7 @@
/**
* Parser class for DL SETs.
*
- * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ * @deprecated Check for 'ASN1SetParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class DLSetParser
@@ -40,7 +40,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new DLSet(_parser.readVector());
+ return DLFactory.createSet(_parser.readVector());
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObject.java
index e9f7479..acbcb2c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObject.java
@@ -12,60 +12,92 @@
public class DLTaggedObject
extends ASN1TaggedObject
{
+ public DLTaggedObject(int tagNo, ASN1Encodable encodable)
+ {
+ super(true, tagNo, encodable);
+ }
+
+ public DLTaggedObject(int tagClass, int tagNo, ASN1Encodable encodable)
+ {
+ super(true, tagClass, tagNo, encodable);
+ }
+
/**
* @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public DLTaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
+ public DLTaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
{
super(explicit, tagNo, obj);
}
- boolean isConstructed()
+ public DLTaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
{
- return explicit || obj.toASN1Primitive().toDLObject().isConstructed();
+ super(explicit, tagClass, tagNo, obj);
}
- int encodedLength()
- throws IOException
+ DLTaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
{
- int length = obj.toASN1Primitive().toDLObject().encodedLength();
+ super(explicitness, tagClass, tagNo, obj);
+ }
+
+ boolean encodeConstructed()
+ {
+ return isExplicit() || obj.toASN1Primitive().toDLObject().encodeConstructed();
+ }
+
+ int encodedLength(boolean withTag) throws IOException
+ {
+ ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
+ boolean explicit = isExplicit();
+
+ int length = primitive.encodedLength(explicit);
if (explicit)
{
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ length += ASN1OutputStream.getLengthOfDL(length);
}
- else
- {
- // header length already in calculation
- length = length - 1;
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ length += withTag ? ASN1OutputStream.getLengthOfIdentifier(tagNo) : 0;
+
+ return length;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
+// assert out.getClass().isAssignableFrom(DLOutputStream.class);
+
ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
+ boolean explicit = isExplicit();
- int flags = BERTags.TAGGED;
- if (explicit || primitive.isConstructed())
+ if (withTag)
{
- flags |= BERTags.CONSTRUCTED;
- }
+ int flags = tagClass;
+ if (explicit || primitive.encodeConstructed())
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
- out.writeTag(withTag, flags, tagNo);
+ out.writeIdentifier(true, flags, tagNo);
+ }
if (explicit)
{
- out.writeLength(primitive.encodedLength());
+ out.writeDL(primitive.encodedLength(true));
}
- out.getDLSubStream().writePrimitive(primitive, explicit);
+ primitive.encode(out.getDLSubStream(), explicit);
+ }
+
+ ASN1Sequence rebuildConstructed(ASN1Primitive primitive)
+ {
+ return new DLSequence(primitive);
+ }
+
+ ASN1TaggedObject replaceTag(int tagClass, int tagNo)
+ {
+ return new DLTaggedObject(explicitness, tagClass, tagNo, obj);
}
ASN1Primitive toDLObject()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObjectParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObjectParser.java
new file mode 100644
index 0000000..e1b68e0
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObjectParser.java
@@ -0,0 +1,74 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser for definite-length tagged objects.
+ */
+class DLTaggedObjectParser
+ extends BERTaggedObjectParser
+{
+ private final boolean _constructed;
+
+ DLTaggedObjectParser(int tagClass, int tagNo, boolean constructed, ASN1StreamParser parser)
+ {
+ super(tagClass, tagNo, parser);
+
+ _constructed = constructed;
+ }
+
+ /**
+ * Return an in-memory, encodable, representation of the tagged object.
+ *
+ * @return an ASN1TaggedObject.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return _parser.loadTaggedDL(_tagClass, _tagNo, _constructed);
+ }
+
+ public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ if (declaredExplicit)
+ {
+ if (!_constructed)
+ {
+ throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
+ }
+
+ return _parser.parseObject(baseTagNo);
+ }
+
+ return _constructed
+ ? _parser.parseImplicitConstructedDL(baseTagNo)
+ : _parser.parseImplicitPrimitive(baseTagNo);
+ }
+
+ public ASN1Encodable parseExplicitBaseObject() throws IOException
+ {
+ if (!_constructed)
+ {
+ throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
+ }
+
+ return _parser.readObject();
+ }
+
+ public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException
+ {
+ if (!_constructed)
+ {
+ throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
+ }
+
+ return _parser.parseTaggedObject();
+ }
+
+ public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException
+ {
+ return new DLTaggedObjectParser(baseTagClass, baseTagNo, _constructed, _parser);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DefiniteLengthInputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DefiniteLengthInputStream.java
index 5ab6e11..3d95d72 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DefiniteLengthInputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DefiniteLengthInputStream.java
@@ -26,18 +26,18 @@
{
super(in, limit);
- if (length < 0)
+ if (length <= 0)
{
- throw new IllegalArgumentException("negative lengths not allowed");
+ if (length < 0)
+ {
+ throw new IllegalArgumentException("negative lengths not allowed");
+ }
+
+ setParentEofDetect(true);
}
this._originalLength = length;
this._remaining = length;
-
- if (length == 0)
- {
- setParentEofDetect(true);
- }
}
int getRemaining()
@@ -112,7 +112,7 @@
throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
}
- if ((_remaining -= Streams.readFully(_in, buf)) != 0)
+ if ((_remaining -= Streams.readFully(_in, buf, 0, buf.length)) != 0)
{
throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
}
@@ -135,7 +135,7 @@
}
byte[] bytes = new byte[_remaining];
- if ((_remaining -= Streams.readFully(_in, bytes)) != 0)
+ if ((_remaining -= Streams.readFully(_in, bytes, 0, bytes.length)) != 0)
{
throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyConstructionEnumeration.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyConstructionEnumeration.java
index ebda1a7..a196822 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyConstructionEnumeration.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyConstructionEnumeration.java
@@ -41,7 +41,7 @@
}
catch (IOException e)
{
- throw new ASN1ParsingException("malformed DER construction: " + e, e);
+ throw new ASN1ParsingException("malformed ASN.1: " + e, e);
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyEncodedSequence.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyEncodedSequence.java
index 8ec6478..86ec78d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyEncodedSequence.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyEncodedSequence.java
@@ -18,18 +18,24 @@
// NOTE: Initially, the actual 'elements' will be empty
super();
+ if (null == encoded)
+ {
+ throw new NullPointerException("'encoded' cannot be null");
+ }
+
this.encoded = encoded;
}
- public synchronized ASN1Encodable getObjectAt(int index)
+ public ASN1Encodable getObjectAt(int index)
{
force();
return super.getObjectAt(index);
}
- public synchronized Enumeration getObjects()
+ public Enumeration getObjects()
{
+ byte[] encoded = getContents();
if (null != encoded)
{
return new LazyConstructionEnumeration(encoded);
@@ -38,28 +44,28 @@
return super.getObjects();
}
- public synchronized int hashCode()
+ public int hashCode()
{
force();
return super.hashCode();
}
- public synchronized Iterator<ASN1Encodable> iterator()
+ public Iterator<ASN1Encodable> iterator()
{
force();
return super.iterator();
}
- public synchronized int size()
+ public int size()
{
force();
return super.size();
}
- public synchronized ASN1Encodable[] toArray()
+ public ASN1Encodable[] toArray()
{
force();
@@ -73,27 +79,48 @@
return super.toArrayInternal();
}
- synchronized int encodedLength()
+ int encodedLength(boolean withTag)
throws IOException
{
+ byte[] encoded = getContents();
if (null != encoded)
{
- return 1 + StreamUtil.calculateBodyLength(encoded.length) + encoded.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, encoded.length);
}
- return super.toDLObject().encodedLength();
+ return super.toDLObject().encodedLength(withTag);
}
- synchronized void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
+ byte[] encoded = getContents();
if (null != encoded)
{
- out.writeEncoded(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded);
+ out.writeEncodingDL(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE, encoded);
+ return;
}
- else
- {
- super.toDLObject().encode(out, withTag);
- }
+
+ super.toDLObject().encode(out, withTag);
+ }
+
+ ASN1BitString toASN1BitString()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1BitString();
+ }
+
+ ASN1External toASN1External()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1External();
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1OctetString();
+ }
+
+ ASN1Set toASN1Set()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1Set();
}
synchronized ASN1Primitive toDERObject()
@@ -110,20 +137,28 @@
return super.toDLObject();
}
- private void force()
+ private synchronized void force()
{
if (null != encoded)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
-
- Enumeration en = new LazyConstructionEnumeration(encoded);
- while (en.hasMoreElements())
+ ASN1InputStream aIn = new ASN1InputStream(encoded, true);
+ try
{
- v.add((ASN1Primitive)en.nextElement());
- }
+ ASN1EncodableVector v = aIn.readVector();
+ aIn.close();
- this.elements = v.takeElements();
- this.encoded = null;
+ this.elements = v.takeElements();
+ this.encoded = null;
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("malformed ASN.1: " + e, e);
+ }
}
}
+
+ private synchronized byte[] getContents()
+ {
+ return encoded;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DateUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LocaleUtil.java
similarity index 77%
rename from repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DateUtil.java
rename to repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LocaleUtil.java
index 0c322a1..9d04f66 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DateUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LocaleUtil.java
@@ -8,13 +8,18 @@
import java.util.Locale;
import java.util.Map;
-class DateUtil
-{
- private static Long ZERO = longValueOf(0);
+import com.android.org.bouncycastle.util.Longs;
+/**
+ * ASN.1 uses an EN locale for its internal formatting. This class finds the nearest equivalent in the
+ * current JVM to ensure date formats are always respected.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class LocaleUtil
+{
private static final Map localeCache = new HashMap();
- static Locale EN_Locale = forEN();
+ public static Locale EN_Locale = forEN();
private static Locale forEN()
{
@@ -53,19 +58,12 @@
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
long v = dateF.parse("19700101000000GMT+00:00").getTime();
- if (v == 0)
- {
- adj = ZERO;
- }
- else
- {
- adj = longValueOf(v);
- }
+ adj = longValueOf(v);
localeCache.put(locale, adj);
}
- if (adj != ZERO)
+ if (adj.longValue() != 0L)
{
return new Date(date.getTime() - adj.longValue());
}
@@ -76,6 +74,6 @@
private static Long longValueOf(long v)
{
- return Long.valueOf(v);
+ return Longs.valueOf(v);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
index 74005e9..ff17380 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
@@ -4,75 +4,103 @@
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
/**
- * Object Identifiers belonging to iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle (1.3.6.1.4.1.22554)
+ * Object Identifiers belonging to iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle (1.3.6.1.4.1.22554)
* @hide This class is not part of the Android public SDK API
*/
public interface BCObjectIdentifiers
{
/**
- * iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle
- *<p>
- * 1.3.6.1.4.1.22554
+ * iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle
+ * <p>
+ * 1.3.6.1.4.1.22554
*/
- public static final ASN1ObjectIdentifier bc = new ASN1ObjectIdentifier("1.3.6.1.4.1.22554");
+ ASN1ObjectIdentifier bc = new ASN1ObjectIdentifier("1.3.6.1.4.1.22554");
/**
* pbe(1) algorithms
* <p>
* 1.3.6.1.4.1.22554.1
*/
- public static final ASN1ObjectIdentifier bc_pbe = bc.branch("1");
+ ASN1ObjectIdentifier bc_pbe = bc.branch("1");
/**
* SHA-1(1)
* <p>
* 1.3.6.1.4.1.22554.1.1
*/
- public static final ASN1ObjectIdentifier bc_pbe_sha1 = bc_pbe.branch("1");
+ ASN1ObjectIdentifier bc_pbe_sha1 = bc_pbe.branch("1");
- /** SHA-2.SHA-256; 1.3.6.1.4.1.22554.1.2.1 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256 = bc_pbe.branch("2.1");
- /** SHA-2.SHA-384; 1.3.6.1.4.1.22554.1.2.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha384 = bc_pbe.branch("2.2");
- /** SHA-2.SHA-512; 1.3.6.1.4.1.22554.1.2.3 */
- public static final ASN1ObjectIdentifier bc_pbe_sha512 = bc_pbe.branch("2.3");
- /** SHA-2.SHA-224; 1.3.6.1.4.1.22554.1.2.4 */
- public static final ASN1ObjectIdentifier bc_pbe_sha224 = bc_pbe.branch("2.4");
+ /**
+ * SHA-2.SHA-256; 1.3.6.1.4.1.22554.1.2.1
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256 = bc_pbe.branch("2.1");
+ /**
+ * SHA-2.SHA-384; 1.3.6.1.4.1.22554.1.2.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha384 = bc_pbe.branch("2.2");
+ /**
+ * SHA-2.SHA-512; 1.3.6.1.4.1.22554.1.2.3
+ */
+ ASN1ObjectIdentifier bc_pbe_sha512 = bc_pbe.branch("2.3");
+ /**
+ * SHA-2.SHA-224; 1.3.6.1.4.1.22554.1.2.4
+ */
+ ASN1ObjectIdentifier bc_pbe_sha224 = bc_pbe.branch("2.4");
/**
* PKCS-5(1)|PKCS-12(2)
*/
- /** SHA-1.PKCS5; 1.3.6.1.4.1.22554.1.1.1 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs5 = bc_pbe_sha1.branch("1");
- /** SHA-1.PKCS12; 1.3.6.1.4.1.22554.1.1.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12 = bc_pbe_sha1.branch("2");
+ /**
+ * SHA-1.PKCS5; 1.3.6.1.4.1.22554.1.1.1
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs5 = bc_pbe_sha1.branch("1");
+ /**
+ * SHA-1.PKCS12; 1.3.6.1.4.1.22554.1.1.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12 = bc_pbe_sha1.branch("2");
- /** SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.1 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs5 = bc_pbe_sha256.branch("1");
- /** SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12 = bc_pbe_sha256.branch("2");
+ /**
+ * SHA-256.PKCS5; 1.3.6.1.4.1.22554.1.2.1.1
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs5 = bc_pbe_sha256.branch("1");
+ /**
+ * SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12 = bc_pbe_sha256.branch("2");
/**
* AES(1) . (CBC-128(2)|CBC-192(22)|CBC-256(42))
*/
- /** 1.3.6.1.4.1.22554.1.1.2.1.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = bc_pbe_sha1_pkcs12.branch("1.2");
- /** 1.3.6.1.4.1.22554.1.1.2.1.22 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = bc_pbe_sha1_pkcs12.branch("1.22");
- /** 1.3.6.1.4.1.22554.1.1.2.1.42 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = bc_pbe_sha1_pkcs12.branch("1.42");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.1.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = bc_pbe_sha1_pkcs12.branch("1.2");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.1.22
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = bc_pbe_sha1_pkcs12.branch("1.22");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.1.42
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = bc_pbe_sha1_pkcs12.branch("1.42");
- /** 1.3.6.1.4.1.22554.1.1.2.2.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = bc_pbe_sha256_pkcs12.branch("1.2");
- /** 1.3.6.1.4.1.22554.1.1.2.2.22 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = bc_pbe_sha256_pkcs12.branch("1.22");
- /** 1.3.6.1.4.1.22554.1.1.2.2.42 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = bc_pbe_sha256_pkcs12.branch("1.42");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.2.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = bc_pbe_sha256_pkcs12.branch("1.2");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.2.22
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = bc_pbe_sha256_pkcs12.branch("1.22");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.2.42
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = bc_pbe_sha256_pkcs12.branch("1.42");
/**
* signature(2) algorithms
*/
- public static final ASN1ObjectIdentifier bc_sig = bc.branch("2");
+ ASN1ObjectIdentifier bc_sig = bc.branch("2");
// BEGIN Android-removed: Unsupported algorithms
/*
@@ -83,101 +111,329 @@
public static final ASN1ObjectIdentifier sphincs256_with_BLAKE512 = sphincs256.branch("1");
public static final ASN1ObjectIdentifier sphincs256_with_SHA512 = sphincs256.branch("2");
public static final ASN1ObjectIdentifier sphincs256_with_SHA3_512 = sphincs256.branch("3");
+ ASN1ObjectIdentifier sphincs256 = bc_sig.branch("1");
+ ASN1ObjectIdentifier sphincs256_with_BLAKE512 = sphincs256.branch("1");
+ ASN1ObjectIdentifier sphincs256_with_SHA512 = sphincs256.branch("2");
+ ASN1ObjectIdentifier sphincs256_with_SHA3_512 = sphincs256.branch("3");
+ */
/**
* XMSS
*/
- public static final ASN1ObjectIdentifier xmss = bc_sig.branch("2");
- public static final ASN1ObjectIdentifier xmss_SHA256ph = xmss.branch("1");
- public static final ASN1ObjectIdentifier xmss_SHA512ph = xmss.branch("2");
- public static final ASN1ObjectIdentifier xmss_SHAKE128ph = xmss.branch("3");
- public static final ASN1ObjectIdentifier xmss_SHAKE256ph = xmss.branch("4");
- public static final ASN1ObjectIdentifier xmss_SHA256 = xmss.branch("5");
- public static final ASN1ObjectIdentifier xmss_SHA512 = xmss.branch("6");
- public static final ASN1ObjectIdentifier xmss_SHAKE128 = xmss.branch("7");
- public static final ASN1ObjectIdentifier xmss_SHAKE256 = xmss.branch("8");
+ ASN1ObjectIdentifier xmss = bc_sig.branch("2");
+ ASN1ObjectIdentifier xmss_SHA256ph = xmss.branch("1");
+ ASN1ObjectIdentifier xmss_SHA512ph = xmss.branch("2");
+ ASN1ObjectIdentifier xmss_SHAKE128_512ph = xmss.branch("3");
+ ASN1ObjectIdentifier xmss_SHAKE256_1024ph = xmss.branch("4");
+ ASN1ObjectIdentifier xmss_SHA256 = xmss.branch("5");
+ ASN1ObjectIdentifier xmss_SHA512 = xmss.branch("6");
+ ASN1ObjectIdentifier xmss_SHAKE128 = xmss.branch("7");
+ ASN1ObjectIdentifier xmss_SHAKE256 = xmss.branch("8");
+ ASN1ObjectIdentifier xmss_SHAKE128ph = xmss.branch("9");
+ ASN1ObjectIdentifier xmss_SHAKE256ph = xmss.branch("10");
/**
* XMSS^MT
*/
- public static final ASN1ObjectIdentifier xmss_mt = bc_sig.branch("3");
- public static final ASN1ObjectIdentifier xmss_mt_SHA256ph = xmss_mt.branch("1");
- public static final ASN1ObjectIdentifier xmss_mt_SHA512ph = xmss_mt.branch("2");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE128ph = xmss_mt.branch("3");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE256ph = xmss_mt.branch("4");
- public static final ASN1ObjectIdentifier xmss_mt_SHA256 = xmss_mt.branch("5");
- public static final ASN1ObjectIdentifier xmss_mt_SHA512 = xmss_mt.branch("6");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE128 = xmss_mt.branch("7");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE256 = xmss_mt.branch("8");
-
- // old OIDs.
- /**
- * @deprecated use xmss_SHA256ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHA256 = xmss_SHA256ph;
- /**
- * @deprecated use xmss_SHA512ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHA512 = xmss_SHA512ph;
- /**
- * @deprecated use xmss_SHAKE128ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHAKE128 = xmss_SHAKE128ph;
- /**
- * @deprecated use xmss_SHAKE256ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHAKE256 = xmss_SHAKE256ph;
-
- /**
- * @deprecated use xmss_mt_SHA256ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHA256 = xmss_mt_SHA256ph;
- /**
- * @deprecated use xmss_mt_SHA512ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHA512 = xmss_mt_SHA512ph;
- /**
- * @deprecated use xmss_mt_SHAKE128ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE128 = xmss_mt_SHAKE128;
- /**
- * @deprecated use xmss_mt_SHAKE256ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE256 = xmss_mt_SHAKE256;
+ ASN1ObjectIdentifier xmss_mt = bc_sig.branch("3");
+ ASN1ObjectIdentifier xmss_mt_SHA256ph = xmss_mt.branch("1");
+ ASN1ObjectIdentifier xmss_mt_SHA512ph = xmss_mt.branch("2");
+ ASN1ObjectIdentifier xmss_mt_SHAKE128_512ph = xmss_mt.branch("3");
+ ASN1ObjectIdentifier xmss_mt_SHAKE256_1024ph = xmss_mt.branch("4");
+ ASN1ObjectIdentifier xmss_mt_SHA256 = xmss_mt.branch("5");
+ ASN1ObjectIdentifier xmss_mt_SHA512 = xmss_mt.branch("6");
+ ASN1ObjectIdentifier xmss_mt_SHAKE128 = xmss_mt.branch("7");
+ ASN1ObjectIdentifier xmss_mt_SHAKE256 = xmss_mt.branch("8");
+ ASN1ObjectIdentifier xmss_mt_SHAKE128ph = xmss_mt.branch("9");
+ ASN1ObjectIdentifier xmss_mt_SHAKE256ph = xmss_mt.branch("10");
/**
* qTESLA
*/
- public static final ASN1ObjectIdentifier qTESLA = bc_sig.branch("4");
+ ASN1ObjectIdentifier qTESLA = bc_sig.branch("4");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_I = qTESLA.branch("1");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_size = qTESLA.branch("2");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_speed = qTESLA.branch("3");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_I = qTESLA.branch("4");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_III = qTESLA.branch("5");
+ ASN1ObjectIdentifier qTESLA_Rnd1_I = qTESLA.branch("1");
+ ASN1ObjectIdentifier qTESLA_Rnd1_III_size = qTESLA.branch("2");
+ ASN1ObjectIdentifier qTESLA_Rnd1_III_speed = qTESLA.branch("3");
+ ASN1ObjectIdentifier qTESLA_Rnd1_p_I = qTESLA.branch("4");
+ ASN1ObjectIdentifier qTESLA_Rnd1_p_III = qTESLA.branch("5");
- public static final ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("11");
- public static final ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("12");
+ ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("11");
+ ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("12");
+
+ /**
+ * SPHINCS+
+ */
+ ASN1ObjectIdentifier sphincsPlus = bc_sig.branch("5");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128s_r3 = sphincsPlus.branch("1");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128f_r3 = sphincsPlus.branch("2");
+ ASN1ObjectIdentifier sphincsPlus_shake_128s_r3 = sphincsPlus.branch("3");
+ ASN1ObjectIdentifier sphincsPlus_shake_128f_r3 = sphincsPlus.branch("4");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128s_r3 = sphincsPlus.branch("5");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128f_r3 = sphincsPlus.branch("6");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_192s_r3 = sphincsPlus.branch("7");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192f_r3 = sphincsPlus.branch("8");
+ ASN1ObjectIdentifier sphincsPlus_shake_192s_r3 = sphincsPlus.branch("9");
+ ASN1ObjectIdentifier sphincsPlus_shake_192f_r3 = sphincsPlus.branch("10");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192s_r3 = sphincsPlus.branch("11");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192f_r3 = sphincsPlus.branch("12");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_256s_r3 = sphincsPlus.branch("13");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256f_r3 = sphincsPlus.branch("14");
+ ASN1ObjectIdentifier sphincsPlus_shake_256s_r3 = sphincsPlus.branch("15");
+ ASN1ObjectIdentifier sphincsPlus_shake_256f_r3 = sphincsPlus.branch("16");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256s_r3 = sphincsPlus.branch("17");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256f_r3 = sphincsPlus.branch("18");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_128s_r3_simple = sphincsPlus.branch("19");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128f_r3_simple = sphincsPlus.branch("20");
+ ASN1ObjectIdentifier sphincsPlus_shake_128s_r3_simple = sphincsPlus.branch("21");
+ ASN1ObjectIdentifier sphincsPlus_shake_128f_r3_simple = sphincsPlus.branch("22");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128s_r3_simple = sphincsPlus.branch("23");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128f_r3_simple = sphincsPlus.branch("24");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_192s_r3_simple = sphincsPlus.branch("25");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192f_r3_simple = sphincsPlus.branch("26");
+ ASN1ObjectIdentifier sphincsPlus_shake_192s_r3_simple = sphincsPlus.branch("27");
+ ASN1ObjectIdentifier sphincsPlus_shake_192f_r3_simple = sphincsPlus.branch("28");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192s_r3_simple = sphincsPlus.branch("29");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192f_r3_simple = sphincsPlus.branch("30");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_256s_r3_simple = sphincsPlus.branch("31");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256f_r3_simple = sphincsPlus.branch("32");
+ ASN1ObjectIdentifier sphincsPlus_shake_256s_r3_simple = sphincsPlus.branch("33");
+ ASN1ObjectIdentifier sphincsPlus_shake_256f_r3_simple = sphincsPlus.branch("34");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256s_r3_simple = sphincsPlus.branch("35");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256f_r3_simple = sphincsPlus.branch("36");
+
+
+ ASN1ObjectIdentifier sphincsPlus_interop = new ASN1ObjectIdentifier("1.3.9999.6");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_128f = new ASN1ObjectIdentifier("1.3.9999.6.4.13");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128s = new ASN1ObjectIdentifier("1.3.9999.6.4.16");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192f = new ASN1ObjectIdentifier("1.3.9999.6.5.10");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192s = new ASN1ObjectIdentifier("1.3.9999.6.5.12");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256f = new ASN1ObjectIdentifier("1.3.9999.6.6.10");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256s = new ASN1ObjectIdentifier("1.3.9999.6.6.12");
+
+ ASN1ObjectIdentifier sphincsPlus_shake_128f = new ASN1ObjectIdentifier("1.3.9999.6.7.13");
+ ASN1ObjectIdentifier sphincsPlus_shake_128s = new ASN1ObjectIdentifier("1.3.9999.6.7.16");
+ ASN1ObjectIdentifier sphincsPlus_shake_192f = new ASN1ObjectIdentifier("1.3.9999.6.8.10");
+ ASN1ObjectIdentifier sphincsPlus_shake_192s = new ASN1ObjectIdentifier("1.3.9999.6.8.12");
+ ASN1ObjectIdentifier sphincsPlus_shake_256f = new ASN1ObjectIdentifier("1.3.9999.6.9.10");
+ ASN1ObjectIdentifier sphincsPlus_shake_256s = new ASN1ObjectIdentifier("1.3.9999.6.9.12");
+
+ /**
+ * Picnic
+ */
+ ASN1ObjectIdentifier picnic = bc_sig.branch("6");
+
+ ASN1ObjectIdentifier picnic_key = picnic.branch("1");
+
+ ASN1ObjectIdentifier picnicl1fs = picnic_key.branch("1");
+ ASN1ObjectIdentifier picnicl1ur = picnic_key.branch("2");
+ ASN1ObjectIdentifier picnicl3fs = picnic_key.branch("3");
+ ASN1ObjectIdentifier picnicl3ur = picnic_key.branch("4");
+ ASN1ObjectIdentifier picnicl5fs = picnic_key.branch("5");
+ ASN1ObjectIdentifier picnicl5ur = picnic_key.branch("6");
+ ASN1ObjectIdentifier picnic3l1 = picnic_key.branch("7");
+ ASN1ObjectIdentifier picnic3l3 = picnic_key.branch("8");
+ ASN1ObjectIdentifier picnic3l5 = picnic_key.branch("9");
+ ASN1ObjectIdentifier picnicl1full = picnic_key.branch("10");
+ ASN1ObjectIdentifier picnicl3full = picnic_key.branch("11");
+ ASN1ObjectIdentifier picnicl5full = picnic_key.branch("12");
+
+ ASN1ObjectIdentifier picnic_signature = picnic.branch("2");
+ ASN1ObjectIdentifier picnic_with_sha512 = picnic_signature.branch("1");
+ ASN1ObjectIdentifier picnic_with_shake256 = picnic_signature.branch("2");
+ ASN1ObjectIdentifier picnic_with_sha3_512 = picnic_signature.branch("3");
+
+
+ /*
+ * Falcon
+ */
+ ASN1ObjectIdentifier falcon = bc_sig.branch("7");
+
+ ASN1ObjectIdentifier falcon_512 = new ASN1ObjectIdentifier("1.3.9999.3.6"); // falcon.branch("1");
+ ASN1ObjectIdentifier falcon_1024 = new ASN1ObjectIdentifier("1.3.9999.3.9"); // falcon.branch("2");
+
+ /*
+ * Dilithium
+ */
+ ASN1ObjectIdentifier dilithium = bc_sig.branch("8");
+
+ // OpenSSL OIDs
+ ASN1ObjectIdentifier dilithium2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.4.4"); // dilithium.branch("1");
+ ASN1ObjectIdentifier dilithium3 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.6.5"); // dilithium.branch("2");
+ ASN1ObjectIdentifier dilithium5 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.8.7"); // dilithium.branch("3");
+ ASN1ObjectIdentifier dilithium2_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.4.4"); // dilithium.branch("4");
+ ASN1ObjectIdentifier dilithium3_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.6.5"); // dilithium.branch("5");
+ ASN1ObjectIdentifier dilithium5_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.8.7"); // dilithium.branch("6");
+
+ /*
+ * Rainbow
+ */
+ ASN1ObjectIdentifier rainbow = bc_sig.branch("9");
+
+ ASN1ObjectIdentifier rainbow_III_classic = rainbow.branch("1");
+ ASN1ObjectIdentifier rainbow_III_circumzenithal = rainbow.branch("2");
+ ASN1ObjectIdentifier rainbow_III_compressed = rainbow.branch("3");
+ ASN1ObjectIdentifier rainbow_V_classic = rainbow.branch("4");
+ ASN1ObjectIdentifier rainbow_V_circumzenithal = rainbow.branch("5");
+ ASN1ObjectIdentifier rainbow_V_compressed = rainbow.branch("6");
/**
* key_exchange(3) algorithms
- *
- public static final ASN1ObjectIdentifier bc_exch = bc.branch("3");
+ */
+ ASN1ObjectIdentifier bc_exch = bc.branch("3");
/**
* NewHope
- *
- public static final ASN1ObjectIdentifier newHope = bc_exch.branch("1");
- */
- // END Android-removed: Unsupported algorithms
+ */
+ ASN1ObjectIdentifier newHope = bc_exch.branch("1");
/**
- * X.509 extension(4) values
+ * X.509 extension/certificate types
* <p>
* 1.3.6.1.4.1.22554.4
*/
- public static final ASN1ObjectIdentifier bc_ext = bc.branch("4");
+ ASN1ObjectIdentifier bc_ext = bc.branch("4");
- public static final ASN1ObjectIdentifier linkedCertificate = bc_ext.branch("1");
+ ASN1ObjectIdentifier linkedCertificate = bc_ext.branch("1");
+ ASN1ObjectIdentifier external_value = bc_ext.branch("2");
+
+ /**
+ * KEM(5) algorithms
+ */
+ ASN1ObjectIdentifier bc_kem = bc.branch("5");
+
+ /**
+ * Classic McEliece
+ */
+ ASN1ObjectIdentifier pqc_kem_mceliece = bc_kem.branch("1");
+
+ ASN1ObjectIdentifier mceliece348864_r3 = pqc_kem_mceliece.branch("1");
+ ASN1ObjectIdentifier mceliece348864f_r3 = pqc_kem_mceliece.branch("2");
+ ASN1ObjectIdentifier mceliece460896_r3 = pqc_kem_mceliece.branch("3");
+ ASN1ObjectIdentifier mceliece460896f_r3 = pqc_kem_mceliece.branch("4");
+ ASN1ObjectIdentifier mceliece6688128_r3 = pqc_kem_mceliece.branch("5");
+ ASN1ObjectIdentifier mceliece6688128f_r3 = pqc_kem_mceliece.branch("6");
+ ASN1ObjectIdentifier mceliece6960119_r3 = pqc_kem_mceliece.branch("7");
+ ASN1ObjectIdentifier mceliece6960119f_r3 = pqc_kem_mceliece.branch("8");
+ ASN1ObjectIdentifier mceliece8192128_r3 = pqc_kem_mceliece.branch("9");
+ ASN1ObjectIdentifier mceliece8192128f_r3 = pqc_kem_mceliece.branch("10");
+
+
+ /**
+ * Frodo
+ */
+ ASN1ObjectIdentifier pqc_kem_frodo = bc_kem.branch("2");
+
+ ASN1ObjectIdentifier frodokem640aes = pqc_kem_frodo.branch("1");
+ ASN1ObjectIdentifier frodokem640shake = pqc_kem_frodo.branch("2");
+ ASN1ObjectIdentifier frodokem976aes = pqc_kem_frodo.branch("3");
+ ASN1ObjectIdentifier frodokem976shake = pqc_kem_frodo.branch("4");
+ ASN1ObjectIdentifier frodokem1344aes = pqc_kem_frodo.branch("5");
+ ASN1ObjectIdentifier frodokem1344shake = pqc_kem_frodo.branch("6");
+
+ /**
+ * SABER
+ */
+ ASN1ObjectIdentifier pqc_kem_saber = bc_kem.branch("3");
+
+ ASN1ObjectIdentifier lightsaberkem128r3 = pqc_kem_saber.branch("1");
+ ASN1ObjectIdentifier saberkem128r3 = pqc_kem_saber.branch("2");
+ ASN1ObjectIdentifier firesaberkem128r3 = pqc_kem_saber.branch("3");
+ ASN1ObjectIdentifier lightsaberkem192r3 = pqc_kem_saber.branch("4");
+ ASN1ObjectIdentifier saberkem192r3 = pqc_kem_saber.branch("5");
+ ASN1ObjectIdentifier firesaberkem192r3 = pqc_kem_saber.branch("6");
+ ASN1ObjectIdentifier lightsaberkem256r3 = pqc_kem_saber.branch("7");
+ ASN1ObjectIdentifier saberkem256r3 = pqc_kem_saber.branch("8");
+ ASN1ObjectIdentifier firesaberkem256r3 = pqc_kem_saber.branch("9");
+ ASN1ObjectIdentifier ulightsaberkemr3 = pqc_kem_saber.branch("10");
+ ASN1ObjectIdentifier usaberkemr3 = pqc_kem_saber.branch("11");
+ ASN1ObjectIdentifier ufiresaberkemr3 = pqc_kem_saber.branch("12");
+ ASN1ObjectIdentifier lightsaberkem90sr3 = pqc_kem_saber.branch("13");
+ ASN1ObjectIdentifier saberkem90sr3 = pqc_kem_saber.branch("14");
+ ASN1ObjectIdentifier firesaberkem90sr3 = pqc_kem_saber.branch("15");
+ ASN1ObjectIdentifier ulightsaberkem90sr3 = pqc_kem_saber.branch("16");
+ ASN1ObjectIdentifier usaberkem90sr3 = pqc_kem_saber.branch("17");
+ ASN1ObjectIdentifier ufiresaberkem90sr3 = pqc_kem_saber.branch("18");
+
+ /**
+ * SIKE
+ */
+ ASN1ObjectIdentifier pqc_kem_sike = bc_kem.branch("4");
+
+ ASN1ObjectIdentifier sikep434 = pqc_kem_sike.branch("1");
+ ASN1ObjectIdentifier sikep503 = pqc_kem_sike.branch("2");
+ ASN1ObjectIdentifier sikep610 = pqc_kem_sike.branch("3");
+ ASN1ObjectIdentifier sikep751 = pqc_kem_sike.branch("4");
+ ASN1ObjectIdentifier sikep434_compressed = pqc_kem_sike.branch("5");
+ ASN1ObjectIdentifier sikep503_compressed = pqc_kem_sike.branch("6");
+ ASN1ObjectIdentifier sikep610_compressed = pqc_kem_sike.branch("7");
+ ASN1ObjectIdentifier sikep751_compressed = pqc_kem_sike.branch("8");
+
+ /**
+ * NTRU
+ */
+ ASN1ObjectIdentifier pqc_kem_ntru = bc_kem.branch("5");
+
+ ASN1ObjectIdentifier ntruhps2048509 = pqc_kem_ntru.branch("1");
+ ASN1ObjectIdentifier ntruhps2048677 = pqc_kem_ntru.branch("2");
+ ASN1ObjectIdentifier ntruhps4096821 = pqc_kem_ntru.branch("3");
+ ASN1ObjectIdentifier ntruhrss701 = pqc_kem_ntru.branch("4");
+
+ /**
+ * Kyber
+ */
+ ASN1ObjectIdentifier pqc_kem_kyber = bc_kem.branch("6");
+
+ ASN1ObjectIdentifier kyber512 = pqc_kem_kyber.branch("1");
+ ASN1ObjectIdentifier kyber768 = pqc_kem_kyber.branch("2");
+ ASN1ObjectIdentifier kyber1024 = pqc_kem_kyber.branch("3");
+ ASN1ObjectIdentifier kyber512_aes = pqc_kem_kyber.branch("4");
+ ASN1ObjectIdentifier kyber768_aes = pqc_kem_kyber.branch("5");
+ ASN1ObjectIdentifier kyber1024_aes = pqc_kem_kyber.branch("6");
+
+ /**
+ * NTRUPrime
+ */
+ ASN1ObjectIdentifier pqc_kem_ntruprime = bc_kem.branch("7");
+
+ ASN1ObjectIdentifier pqc_kem_ntrulprime = pqc_kem_ntruprime.branch("1");
+ ASN1ObjectIdentifier ntrulpr653 = pqc_kem_ntrulprime.branch("1");
+ ASN1ObjectIdentifier ntrulpr761 = pqc_kem_ntrulprime.branch("2");
+ ASN1ObjectIdentifier ntrulpr857 = pqc_kem_ntrulprime.branch("3");
+ ASN1ObjectIdentifier ntrulpr953 = pqc_kem_ntrulprime.branch("4");
+ ASN1ObjectIdentifier ntrulpr1013 = pqc_kem_ntrulprime.branch("5");
+ ASN1ObjectIdentifier ntrulpr1277 = pqc_kem_ntrulprime.branch("6");
+
+ ASN1ObjectIdentifier pqc_kem_sntruprime = pqc_kem_ntruprime.branch("2");
+ ASN1ObjectIdentifier sntrup653 = pqc_kem_sntruprime.branch("1");
+ ASN1ObjectIdentifier sntrup761 = pqc_kem_sntruprime.branch("2");
+ ASN1ObjectIdentifier sntrup857 = pqc_kem_sntruprime.branch("3");
+ ASN1ObjectIdentifier sntrup953 = pqc_kem_sntruprime.branch("4");
+ ASN1ObjectIdentifier sntrup1013 = pqc_kem_sntruprime.branch("5");
+ ASN1ObjectIdentifier sntrup1277 = pqc_kem_sntruprime.branch("6");
+
+ /**
+ * BIKE
+ **/
+ ASN1ObjectIdentifier pqc_kem_bike = bc_kem.branch("8");
+
+ ASN1ObjectIdentifier bike128 = pqc_kem_bike.branch("1");
+ ASN1ObjectIdentifier bike192 = pqc_kem_bike.branch("2");
+ ASN1ObjectIdentifier bike256 = pqc_kem_bike.branch("3");
+
+ /**
+ * HQC
+ **/
+ ASN1ObjectIdentifier pqc_kem_hqc = bc_kem.branch("9");
+
+ ASN1ObjectIdentifier hqc128 = pqc_kem_hqc.branch("1");
+ ASN1ObjectIdentifier hqc192 = pqc_kem_hqc.branch("2");
+ ASN1ObjectIdentifier hqc256 = pqc_kem_hqc.branch("3");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/ExternalValue.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/ExternalValue.java
new file mode 100644
index 0000000..dd6ea4d
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/ExternalValue.java
@@ -0,0 +1,119 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.bc;
+
+import com.android.org.bouncycastle.asn1.ASN1BitString;
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DERBitString;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.org.bouncycastle.asn1.x509.GeneralNames;
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * Based on External Keys And Signatures For Use In Internet PKI
+ * draft-ounsworth-pq-external-pubkeys-00
+ * <pre>
+ * ExternalValue ::= SEQUENCE {
+ * location GeneralNames, # MUST refer to a DER encoded SubjectPublicKeyInfo/Signature (may be Base64)
+ * hashAlg AlgorithmIdentifier,
+ * hashVal OCTET STRING }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExternalValue
+ extends ASN1Object
+{
+ private final GeneralNames location;
+ private final AlgorithmIdentifier hashAlg;
+ private final byte[] hashValue;
+
+ public ExternalValue(GeneralName location, AlgorithmIdentifier hashAlg, byte[] hashVal)
+ {
+ this.location = new GeneralNames(location);
+ this.hashAlg = hashAlg;
+ this.hashValue = Arrays.clone(hashVal);
+ }
+
+ private ExternalValue(ASN1Sequence seq)
+ {
+ if (seq.size() == 3)
+ {
+ location = GeneralNames.getInstance(seq.getObjectAt(0));
+ hashAlg = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ if (seq.getObjectAt(2) instanceof ASN1BitString) // legacy implementation on 2021 draft
+ {
+ hashValue = ASN1BitString.getInstance(seq.getObjectAt(2)).getOctets();
+ }
+ else
+ {
+ hashValue = ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets();
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown sequence");
+ }
+ }
+
+ public static ExternalValue getInstance(Object o)
+ {
+ if (o instanceof ExternalValue)
+ {
+ return (ExternalValue)o;
+ }
+ else if (o != null)
+ {
+ return new ExternalValue(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public GeneralName getLocation()
+ {
+ return location.getNames()[0];
+ }
+
+ public GeneralName[] getLocations()
+ {
+ return location.getNames();
+ }
+
+ public AlgorithmIdentifier getHashAlg()
+ {
+ return hashAlg;
+ }
+
+ public byte[] getHashValue()
+ {
+ return Arrays.clone(hashValue);
+ }
+
+ /**
+ * Get the hash value as a BIT STRING.
+ *
+ * @return the hash value as a BIT STRING
+ * @deprecated use getHash(), the internal encoding is now an OCTET STRING
+ */
+ public ASN1BitString getHashVal()
+ {
+ return new DERBitString(hashValue);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(location);
+ v.add(hashAlg);
+ v.add(new DEROctetString(hashValue));
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/LinkedCertificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/LinkedCertificate.java
new file mode 100644
index 0000000..a3e4469
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/LinkedCertificate.java
@@ -0,0 +1,128 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.bc;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.org.bouncycastle.asn1.x500.X500Name;
+import com.android.org.bouncycastle.asn1.x509.DigestInfo;
+import com.android.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.org.bouncycastle.asn1.x509.GeneralNames;
+
+/**
+ * Extension to tie an alternate certificate to the containing certificate.
+ * <pre>
+ * LinkedCertificate := SEQUENCE {
+ * digest DigestInfo, -- digest of PQC certificate
+ * certLocation GeneralName, -- location of PQC certificate
+ * certIssuer [0] Name OPTIONAL, -- issuer of PQC cert (if different from current certificate)
+ * cACerts [1] GeneralNames OPTIONAL, -- CA certificates for PQC cert (one of more locations)
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class LinkedCertificate
+ extends ASN1Object
+{
+ private final DigestInfo digest;
+ private final GeneralName certLocation;
+
+ private X500Name certIssuer;
+ private GeneralNames cACerts;
+
+ public LinkedCertificate(DigestInfo digest, GeneralName certLocation)
+ {
+ this(digest, certLocation, null, null);
+ }
+
+ public LinkedCertificate(DigestInfo digest, GeneralName certLocation, X500Name certIssuer, GeneralNames cACerts)
+ {
+ this.digest = digest;
+ this.certLocation = certLocation;
+ this.certIssuer = certIssuer;
+ this.cACerts = cACerts;
+ }
+
+ private LinkedCertificate(ASN1Sequence seq)
+ {
+ this.digest = DigestInfo.getInstance(seq.getObjectAt(0));
+ this.certLocation = GeneralName.getInstance(seq.getObjectAt(1));
+
+ if (seq.size() > 2)
+ {
+ for (int i = 2; i != seq.size(); i++)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(i));
+
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ certIssuer = X500Name.getInstance(tagged, false);
+ break;
+ case 1:
+ cACerts = GeneralNames.getInstance(tagged, false);
+ break;
+ default:
+ throw new IllegalArgumentException("unknown tag in tagged field");
+ }
+ }
+ }
+ }
+
+ public static LinkedCertificate getInstance(Object o)
+ {
+ if (o instanceof LinkedCertificate)
+ {
+ return (LinkedCertificate)o;
+ }
+ else if (o != null)
+ {
+ return new LinkedCertificate(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public DigestInfo getDigest()
+ {
+ return digest;
+ }
+
+ public GeneralName getCertLocation()
+ {
+ return certLocation;
+ }
+
+ public X500Name getCertIssuer()
+ {
+ return certIssuer;
+ }
+
+ public GeneralNames getCACerts()
+ {
+ return cACerts;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(digest);
+ v.add(certLocation);
+
+ if (certIssuer != null)
+ {
+ v.add(new DERTaggedObject(false, 0, certIssuer));
+ }
+ if (cACerts != null)
+ {
+ v.add(new DERTaggedObject(false, 1, cACerts));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/ContentInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/ContentInfo.java
index cbde2d3..fe02988 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/ContentInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/ContentInfo.java
@@ -130,3 +130,4 @@
return new BERSequence(v);
}
}
+
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
deleted file mode 100644
index a437f4e..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1.eac;
-
-import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-
-/**
- * German Federal Office for Information Security
- * (Bundesamt für Sicherheit in der Informationstechnik)
- * <a href="https://www.bsi.bund.de/">https://www.bsi.bund.de/</a>
- * <p>
- * <a href="https://www.bsi.bund.de/EN/Publications/TechnicalGuidelines/TR03110/BSITR03110.html">BSI TR-03110</a>
- * Technical Guideline Advanced Security Mechanisms for Machine Readable Travel Documents
- * <p>
- * <a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03110/TR-03110_v2.1_P3pdf.pdf">
- * Technical Guideline TR-03110-3</a>
- * Advanced Security Mechanisms for Machine Readable Travel Documents;
- * Part 3: Common Specifications.
- * @hide This class is not part of the Android public SDK API
- */
-public interface EACObjectIdentifiers
-{
- /**
- * <pre>
- * bsi-de OBJECT IDENTIFIER ::= {
- * itu-t(0) identified-organization(4) etsi(0)
- * reserved(127) etsi-identified-organization(0) 7
- * }
- * </pre>
- * OID: 0.4.0.127.0.7
- */
- static final ASN1ObjectIdentifier bsi_de = new ASN1ObjectIdentifier("0.4.0.127.0.7");
-
- /**
- * <pre>
- * id-PK OBJECT IDENTIFIER ::= {
- * bsi-de protocols(2) smartcard(2) 1
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.2.2.1
- */
- static final ASN1ObjectIdentifier id_PK = bsi_de.branch("2.2.1");
-
- /** OID: 0.4.0.127.0.7.2.2.1.1 */
- static final ASN1ObjectIdentifier id_PK_DH = id_PK.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.1.2 */
- static final ASN1ObjectIdentifier id_PK_ECDH = id_PK.branch("2");
-
- /**
- * <pre>
- * id-CA OBJECT IDENTIFIER ::= {
- * bsi-de protocols(2) smartcard(2) 3
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.2.2.3
- */
- static final ASN1ObjectIdentifier id_CA = bsi_de.branch("2.2.3");
- /** OID: 0.4.0.127.0.7.2.2.3.1 */
- static final ASN1ObjectIdentifier id_CA_DH = id_CA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.3.1.1 */
- static final ASN1ObjectIdentifier id_CA_DH_3DES_CBC_CBC = id_CA_DH.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.3.2 */
- static final ASN1ObjectIdentifier id_CA_ECDH = id_CA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.3.2.1 */
- static final ASN1ObjectIdentifier id_CA_ECDH_3DES_CBC_CBC = id_CA_ECDH.branch("1");
-
- /**
- * <pre>
- * id-TA OBJECT IDENTIFIER ::= {
- * bsi-de protocols(2) smartcard(2) 2
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.2.2.2
- */
- static final ASN1ObjectIdentifier id_TA = bsi_de.branch("2.2.2");
-
- /** OID: 0.4.0.127.0.7.2.2.2.1 */
- static final ASN1ObjectIdentifier id_TA_RSA = id_TA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.2.1.1 */
- static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_1 = id_TA_RSA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.2.1.2 */
- static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_256 = id_TA_RSA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.2.1.3 */
- static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_1 = id_TA_RSA.branch("3");
- /** OID: 0.4.0.127.0.7.2.2.2.1.4 */
- static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_256 = id_TA_RSA.branch("4");
- /** OID: 0.4.0.127.0.7.2.2.2.1.5 */
- static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_512 = id_TA_RSA.branch("5");
- /** OID: 0.4.0.127.0.7.2.2.2.1.6 */
- static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_512 = id_TA_RSA.branch("6");
- /** OID: 0.4.0.127.0.7.2.2.2.2 */
- static final ASN1ObjectIdentifier id_TA_ECDSA = id_TA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.2.2.1 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_1 = id_TA_ECDSA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.2.2.2 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_224 = id_TA_ECDSA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.2.2.3 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_256 = id_TA_ECDSA.branch("3");
- /** OID: 0.4.0.127.0.7.2.2.2.2.4 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_384 = id_TA_ECDSA.branch("4");
- /** OID: 0.4.0.127.0.7.2.2.2.2.5 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_512 = id_TA_ECDSA.branch("5");
-
- /**
- * <pre>
- * id-EAC-ePassport OBJECT IDENTIFIER ::= {
- * bsi-de applications(3) mrtd(1) roles(2) 1
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.3.1.2.1
- */
- static final ASN1ObjectIdentifier id_EAC_ePassport = bsi_de.branch("3.1.2.1");
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java
index 3d1a30c..0c10eb4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java
@@ -8,6 +8,8 @@
*/
public interface GMObjectIdentifiers
{
+ //1.2.156.10197: Chinese Cryptography Standardization Technology Committee (CCSTC)
+ //1.2.156.11235: China Broadband Wireless IP Standard Group
ASN1ObjectIdentifier sm_scheme = new ASN1ObjectIdentifier("1.2.156.10197.1");
ASN1ObjectIdentifier sm6_ecb = sm_scheme.branch("101.1");
@@ -50,7 +52,20 @@
ASN1ObjectIdentifier sm2exchange = sm_scheme.branch("301.2");
ASN1ObjectIdentifier sm2encrypt = sm_scheme.branch("301.3");
- ASN1ObjectIdentifier wapip192v1 = sm_scheme.branch("301.101");
+ /**
+ * <Information security technology — Cryptographic application identifier criterion specification>
+ * <url>http://c.gb688.cn/bzgk/gb/showGb?type=online&hcno=252CF0F72A7BE339A56DEA7D774E8994</url>,
+ * Page 21 only cover from 301.1 to 301.3
+ * */
+ ASN1ObjectIdentifier wapip192v1 = sm_scheme.branch("301.101");
+ /**
+ * <WAPI certificate management—Part 5: Example of certificate format (draft)>
+ * <url>http://www.chinabwips.org.cn/zqyjgs1.htm</url> and
+ * <url>http://www.chinabwips.org.cn/doc/101.pdf</url>,
+ * Page 9 and page 10 states the OID of ECDSA-192 algorithm based on SHA-256 is 1.2.156.11235.1.1.1
+ * */
+ ASN1ObjectIdentifier wapi192v1 = new ASN1ObjectIdentifier("1.2.156.11235.1.1.1");
+ ASN1ObjectIdentifier wapi192v1_parameters = new ASN1ObjectIdentifier("1.2.156.11235.1.1.2.1");
ASN1ObjectIdentifier sm2encrypt_recommendedParameters = sm2encrypt.branch("1");
ASN1ObjectIdentifier sm2encrypt_specifiedParameters = sm2encrypt.branch("2");
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java
new file mode 100644
index 0000000..3bef6c0
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.isara;
+
+import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface IsaraObjectIdentifiers
+{
+ /*
+ id-alg-xmss OBJECT IDENTIFIER ::= { itu-t(0)
+ identified-organization(4) etsi(0) reserved(127)
+ etsi-identified-organization(0) isara(15) algorithms(1)
+ asymmetric(1) xmss(13) 0 }
+ */
+ static ASN1ObjectIdentifier id_alg_xmss = new ASN1ObjectIdentifier("0.4.0.127.0.15.1.1.13.0");
+
+ /*
+ id-alg-xmssmt OBJECT IDENTIFIER ::= { itu-t(0)
+ identified-organization(4) etsi(0) reserved(127)
+ etsi-identified-organization(0) isara(15) algorithms(1)
+ asymmetric(1) xmssmt(14) 0 }
+ */
+ static ASN1ObjectIdentifier id_alg_xmssmt = new ASN1ObjectIdentifier("0.4.0.127.0.15.1.1.14.0");
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
index bbf5cd7..8366925 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
@@ -128,7 +128,7 @@
ASN1ObjectIdentifier cryptlib_algorithm_blowfish_OFB = cryptlib_algorithm.branch("1.4");
//
- // Blake2b
+ // Blake2b/Blake2s
//
ASN1ObjectIdentifier blake2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.1722.12.2");
@@ -142,6 +142,10 @@
ASN1ObjectIdentifier id_blake2s224 = blake2.branch("2.7");
ASN1ObjectIdentifier id_blake2s256 = blake2.branch("2.8");
+ ASN1ObjectIdentifier blake3 = blake2.branch("3");
+
+ ASN1ObjectIdentifier blake3_256 = blake3.branch("8");
+
//
// Scrypt
ASN1ObjectIdentifier id_scrypt = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.4.11");
@@ -152,4 +156,15 @@
// iso(1) identified-organization(3) dod(6) internet(1) private(4)
// enterprise(1) OpenCA(18227) Algorithms(2) id-alg-composite(1) }
ASN1ObjectIdentifier id_alg_composite = new ASN1ObjectIdentifier("1.3.6.1.4.1.18227.2.1");
+
+ // -- To be replaced by IANA
+ //
+ //id-composite-key OBJECT IDENTIFIER ::= {
+ //
+ // joint-iso-itu-t(2) country(16) us(840) organization(1) entrust(114027)
+ //
+ // Algorithm(80) Composite(4) CompositeKey(1)
+ ASN1ObjectIdentifier id_composite_key = new ASN1ObjectIdentifier("2.16.840.1.114027.80.4.1");
+
+ ASN1ObjectIdentifier id_oracle_pkcs12_trusted_key_usage = new ASN1ObjectIdentifier("2.16.840.1.113894.746875.1.1");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/NetscapeCertType.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/NetscapeCertType.java
index f8c20bf..53de37c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/NetscapeCertType.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/NetscapeCertType.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.misc;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.DERBitString;
/**
@@ -44,13 +45,18 @@
}
public NetscapeCertType(
- DERBitString usage)
+ ASN1BitString usage)
{
super(usage.getBytes(), usage.getPadBits());
}
+ public boolean hasUsages(int usages)
+ {
+ return (intValue() & usages) == usages;
+ }
+
public String toString()
{
- return "NetscapeCertType: 0x" + Integer.toHexString(data[0] & 0xff);
+ return "NetscapeCertType: 0x" + Integer.toHexString(intValue());
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java
index b3a4bfe..b0e4f3d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.misc;
+import com.android.org.bouncycastle.asn1.ASN1IA5String;
import com.android.org.bouncycastle.asn1.DERIA5String;
/**
@@ -10,7 +11,7 @@
extends DERIA5String
{
public NetscapeRevocationURL(
- DERIA5String str)
+ ASN1IA5String str)
{
super(str.getString());
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/VerisignCzagExtension.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/VerisignCzagExtension.java
index c67c7ae..d0e5f7b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/VerisignCzagExtension.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/VerisignCzagExtension.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.misc;
+import com.android.org.bouncycastle.asn1.ASN1IA5String;
import com.android.org.bouncycastle.asn1.DERIA5String;
/**
@@ -10,7 +11,7 @@
extends DERIA5String
{
public VerisignCzagExtension(
- DERIA5String str)
+ ASN1IA5String str)
{
super(str.getString());
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java
new file mode 100644
index 0000000..9b2926a
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java
@@ -0,0 +1,116 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.nist;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * KMACwithSHAKE128-params ::= SEQUENCE {
+ * kMACOutputLength INTEGER DEFAULT 256, -- Output length in bits
+ * customizationString OCTET STRING DEFAULT ''H
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KMACwithSHAKE128_params
+ extends ASN1Object
+{
+ private static final byte[] EMPTY_STRING = new byte[0];
+ private static final int DEF_LENGTH = 256;
+
+ private final int outputLength;
+ private final byte[] customizationString;
+
+ public KMACwithSHAKE128_params(int outputLength)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = EMPTY_STRING;
+ }
+
+ public KMACwithSHAKE128_params(int outputLength, byte[] customizationString)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = Arrays.clone(customizationString);
+ }
+
+ public static KMACwithSHAKE128_params getInstance(Object o)
+ {
+ if (o instanceof KMACwithSHAKE128_params)
+ {
+ return (KMACwithSHAKE128_params)o;
+ }
+ else if (o != null)
+ {
+ return new KMACwithSHAKE128_params(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ private KMACwithSHAKE128_params(ASN1Sequence seq)
+ {
+ if (seq.size() > 2)
+ {
+ throw new IllegalArgumentException("sequence size greater than 2");
+ }
+
+ if (seq.size() == 2)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+ }
+ else if (seq.size() == 1)
+ {
+ if (seq.getObjectAt(0) instanceof ASN1Integer)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = EMPTY_STRING;
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
+ }
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = EMPTY_STRING;
+ }
+ }
+
+ public int getOutputLength()
+ {
+ return outputLength;
+ }
+
+ public byte[] getCustomizationString()
+ {
+ return Arrays.clone(customizationString);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (outputLength != DEF_LENGTH)
+ {
+ v.add(new ASN1Integer(outputLength));
+ }
+
+ if (customizationString.length != 0)
+ {
+ v.add(new DEROctetString(getCustomizationString()));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java
new file mode 100644
index 0000000..2ad37f7
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java
@@ -0,0 +1,116 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.nist;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * KMACwithSHAKE256-params ::= SEQUENCE {
+ * kMACOutputLength INTEGER DEFAULT 512, -- Output length in bits
+ * customizationString OCTET STRING DEFAULT ''H
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KMACwithSHAKE256_params
+ extends ASN1Object
+{
+ private static final byte[] EMPTY_STRING = new byte[0];
+ private static final int DEF_LENGTH = 512;
+
+ private final int outputLength;
+ private final byte[] customizationString;
+
+ public KMACwithSHAKE256_params(int outputLength)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = EMPTY_STRING;
+ }
+
+ public KMACwithSHAKE256_params(int outputLength, byte[] customizationString)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = Arrays.clone(customizationString);
+ }
+
+ public static KMACwithSHAKE256_params getInstance(Object o)
+ {
+ if (o instanceof KMACwithSHAKE256_params)
+ {
+ return (KMACwithSHAKE256_params)o;
+ }
+ else if (o != null)
+ {
+ return new KMACwithSHAKE256_params(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ private KMACwithSHAKE256_params(ASN1Sequence seq)
+ {
+ if (seq.size() > 2)
+ {
+ throw new IllegalArgumentException("sequence size greater than 2");
+ }
+
+ if (seq.size() == 2)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+ }
+ else if (seq.size() == 1)
+ {
+ if (seq.getObjectAt(0) instanceof ASN1Integer)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = EMPTY_STRING;
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
+ }
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = EMPTY_STRING;
+ }
+ }
+
+ public int getOutputLength()
+ {
+ return outputLength;
+ }
+
+ public byte[] getCustomizationString()
+ {
+ return Arrays.clone(customizationString);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (outputLength != DEF_LENGTH)
+ {
+ v.add(new ASN1Integer(outputLength));
+ }
+
+ if (customizationString.length != 0)
+ {
+ v.add(new DEROctetString(getCustomizationString()));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTNamedCurves.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTNamedCurves.java
index 3e3e981..c75948b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTNamedCurves.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTNamedCurves.java
@@ -8,6 +8,7 @@
import com.android.org.bouncycastle.asn1.sec.SECNamedCurves;
import com.android.org.bouncycastle.asn1.sec.SECObjectIdentifiers;
import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.org.bouncycastle.asn1.x9.X9ECParametersHolder;
import com.android.org.bouncycastle.util.Strings;
/**
@@ -44,17 +45,16 @@
defineCurve("P-192", SECObjectIdentifiers.secp192r1);
}
- public static X9ECParameters getByName(
- String name)
+ public static X9ECParameters getByName(String name)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name));
+ ASN1ObjectIdentifier oid = getOID(name);
+ return null != oid ? SECNamedCurves.getByOID(oid) : null;
+ }
- if (oid != null)
- {
- return getByOID(oid);
- }
-
- return null;
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ ASN1ObjectIdentifier oid = getOID(name);
+ return null != oid ? SECNamedCurves.getByOIDLazy(oid) : null;
}
/**
@@ -63,10 +63,14 @@
*
* @param oid an object identifier representing a named curve, if present.
*/
- public static X9ECParameters getByOID(
- ASN1ObjectIdentifier oid)
+ public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- return SECNamedCurves.getByOID(oid);
+ return names.containsKey(oid) ? SECNamedCurves.getByOID(oid) : null;
+ }
+
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return names.containsKey(oid) ? SECNamedCurves.getByOIDLazy(oid) : null;
}
/**
@@ -75,8 +79,7 @@
*
* @return the object identifier associated with name, if present.
*/
- public static ASN1ObjectIdentifier getOID(
- String name)
+ public static ASN1ObjectIdentifier getOID(String name)
{
return (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name));
}
@@ -84,8 +87,7 @@
/**
* return the named curve name represented by the given object identifier.
*/
- public static String getName(
- ASN1ObjectIdentifier oid)
+ public static String getName(ASN1ObjectIdentifier oid)
{
return (String)names.get(oid);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
index 3a1609e..128d5ef 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
@@ -60,69 +60,137 @@
/** 2.16.840.1.101.3.4.2.19 */
static final ASN1ObjectIdentifier id_KmacWithSHAKE128 = hashAlgs.branch("19");
/** 2.16.840.1.101.3.4.2.20 */
- static final ASN1ObjectIdentifier id_KmacWithSHAKE256 = hashAlgs.branch("20");
+ static final ASN1ObjectIdentifier id_KmacWithSHAKE256 = hashAlgs.branch("20");
- /** 2.16.840.1.101.3.4.1 */
- static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1");
-
- /** 2.16.840.1.101.3.4.1.1 */
- static final ASN1ObjectIdentifier id_aes128_ECB = aes.branch("1");
- /** 2.16.840.1.101.3.4.1.2 */
- static final ASN1ObjectIdentifier id_aes128_CBC = aes.branch("2");
- /** 2.16.840.1.101.3.4.1.3 */
- static final ASN1ObjectIdentifier id_aes128_OFB = aes.branch("3");
- /** 2.16.840.1.101.3.4.1.4 */
- static final ASN1ObjectIdentifier id_aes128_CFB = aes.branch("4");
- /** 2.16.840.1.101.3.4.1.5 */
- static final ASN1ObjectIdentifier id_aes128_wrap = aes.branch("5");
- /** 2.16.840.1.101.3.4.1.6 */
- static final ASN1ObjectIdentifier id_aes128_GCM = aes.branch("6");
- /** 2.16.840.1.101.3.4.1.7 */
- static final ASN1ObjectIdentifier id_aes128_CCM = aes.branch("7");
- /** 2.16.840.1.101.3.4.1.28 */
- static final ASN1ObjectIdentifier id_aes128_wrap_pad = aes.branch("8");
+ /**
+ * 2.16.840.1.101.3.4.1
+ */
+ static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1");
- /** 2.16.840.1.101.3.4.1.21 */
- static final ASN1ObjectIdentifier id_aes192_ECB = aes.branch("21");
- /** 2.16.840.1.101.3.4.1.22 */
- static final ASN1ObjectIdentifier id_aes192_CBC = aes.branch("22");
- /** 2.16.840.1.101.3.4.1.23 */
- static final ASN1ObjectIdentifier id_aes192_OFB = aes.branch("23");
- /** 2.16.840.1.101.3.4.1.24 */
- static final ASN1ObjectIdentifier id_aes192_CFB = aes.branch("24");
- /** 2.16.840.1.101.3.4.1.25 */
- static final ASN1ObjectIdentifier id_aes192_wrap = aes.branch("25");
- /** 2.16.840.1.101.3.4.1.26 */
- static final ASN1ObjectIdentifier id_aes192_GCM = aes.branch("26");
- /** 2.16.840.1.101.3.4.1.27 */
- static final ASN1ObjectIdentifier id_aes192_CCM = aes.branch("27");
- /** 2.16.840.1.101.3.4.1.28 */
- static final ASN1ObjectIdentifier id_aes192_wrap_pad = aes.branch("28");
+ /**
+ * 2.16.840.1.101.3.4.1.1
+ */
+ static final ASN1ObjectIdentifier id_aes128_ECB = aes.branch("1");
+ /**
+ * 2.16.840.1.101.3.4.1.2
+ */
+ static final ASN1ObjectIdentifier id_aes128_CBC = aes.branch("2");
+ /**
+ * 2.16.840.1.101.3.4.1.3
+ */
+ static final ASN1ObjectIdentifier id_aes128_OFB = aes.branch("3");
+ /**
+ * 2.16.840.1.101.3.4.1.4
+ */
+ static final ASN1ObjectIdentifier id_aes128_CFB = aes.branch("4");
+ /**
+ * 2.16.840.1.101.3.4.1.5
+ */
+ static final ASN1ObjectIdentifier id_aes128_wrap = aes.branch("5");
+ /**
+ * 2.16.840.1.101.3.4.1.6
+ */
+ static final ASN1ObjectIdentifier id_aes128_GCM = aes.branch("6");
+ /**
+ * 2.16.840.1.101.3.4.1.7
+ */
+ static final ASN1ObjectIdentifier id_aes128_CCM = aes.branch("7");
+ /**
+ * 2.16.840.1.101.3.4.1.8
+ */
+ static final ASN1ObjectIdentifier id_aes128_wrap_pad = aes.branch("8");
+ /**
+ * 2.16.840.1.101.3.4.1.9
+ */
+ static final ASN1ObjectIdentifier id_aes128_GMAC = aes.branch("9");
- /** 2.16.840.1.101.3.4.1.41 */
- static final ASN1ObjectIdentifier id_aes256_ECB = aes.branch("41");
- /** 2.16.840.1.101.3.4.1.42 */
- static final ASN1ObjectIdentifier id_aes256_CBC = aes.branch("42");
- /** 2.16.840.1.101.3.4.1.43 */
- static final ASN1ObjectIdentifier id_aes256_OFB = aes.branch("43");
- /** 2.16.840.1.101.3.4.1.44 */
- static final ASN1ObjectIdentifier id_aes256_CFB = aes.branch("44");
- /** 2.16.840.1.101.3.4.1.45 */
- static final ASN1ObjectIdentifier id_aes256_wrap = aes.branch("45");
- /** 2.16.840.1.101.3.4.1.46 */
- static final ASN1ObjectIdentifier id_aes256_GCM = aes.branch("46");
- /** 2.16.840.1.101.3.4.1.47 */
- static final ASN1ObjectIdentifier id_aes256_CCM = aes.branch("47");
- /** 2.16.840.1.101.3.4.1.48 */
- static final ASN1ObjectIdentifier id_aes256_wrap_pad = aes.branch("48");
+
+ /**
+ * 2.16.840.1.101.3.4.1.21
+ */
+ static final ASN1ObjectIdentifier id_aes192_ECB = aes.branch("21");
+ /**
+ * 2.16.840.1.101.3.4.1.22
+ */
+ static final ASN1ObjectIdentifier id_aes192_CBC = aes.branch("22");
+ /**
+ * 2.16.840.1.101.3.4.1.23
+ */
+ static final ASN1ObjectIdentifier id_aes192_OFB = aes.branch("23");
+ /**
+ * 2.16.840.1.101.3.4.1.24
+ */
+ static final ASN1ObjectIdentifier id_aes192_CFB = aes.branch("24");
+ /**
+ * 2.16.840.1.101.3.4.1.25
+ */
+ static final ASN1ObjectIdentifier id_aes192_wrap = aes.branch("25");
+ /**
+ * 2.16.840.1.101.3.4.1.26
+ */
+ static final ASN1ObjectIdentifier id_aes192_GCM = aes.branch("26");
+ /**
+ * 2.16.840.1.101.3.4.1.27
+ */
+ static final ASN1ObjectIdentifier id_aes192_CCM = aes.branch("27");
+ /**
+ * 2.16.840.1.101.3.4.1.28
+ */
+ static final ASN1ObjectIdentifier id_aes192_wrap_pad = aes.branch("28");
+
+ /**
+ * 2.16.840.1.101.3.4.1.29
+ */
+ static final ASN1ObjectIdentifier id_aes192_GMAC = aes.branch("29");
+
+
+ /**
+ * 2.16.840.1.101.3.4.1.41
+ */
+ static final ASN1ObjectIdentifier id_aes256_ECB = aes.branch("41");
+ /**
+ * 2.16.840.1.101.3.4.1.42
+ */
+ static final ASN1ObjectIdentifier id_aes256_CBC = aes.branch("42");
+ /**
+ * 2.16.840.1.101.3.4.1.43
+ */
+ static final ASN1ObjectIdentifier id_aes256_OFB = aes.branch("43");
+ /**
+ * 2.16.840.1.101.3.4.1.44
+ */
+ static final ASN1ObjectIdentifier id_aes256_CFB = aes.branch("44");
+ /**
+ * 2.16.840.1.101.3.4.1.45
+ */
+ static final ASN1ObjectIdentifier id_aes256_wrap = aes.branch("45");
+ /**
+ * 2.16.840.1.101.3.4.1.46
+ */
+ static final ASN1ObjectIdentifier id_aes256_GCM = aes.branch("46");
+ /**
+ * 2.16.840.1.101.3.4.1.47
+ */
+ static final ASN1ObjectIdentifier id_aes256_CCM = aes.branch("47");
+ /**
+ * 2.16.840.1.101.3.4.1.48
+ */
+ static final ASN1ObjectIdentifier id_aes256_wrap_pad = aes.branch("48");
+ /**
+ * 2.16.840.1.101.3.4.1.49
+ */
+ static final ASN1ObjectIdentifier id_aes256_GMAC = aes.branch("49");
+
//
// signatures
//
- /** 2.16.840.1.101.3.4.3 */
- static final ASN1ObjectIdentifier sigAlgs = nistAlgorithm.branch("3");
+ /**
+ * 2.16.840.1.101.3.4.3
+ */
+ static final ASN1ObjectIdentifier sigAlgs = nistAlgorithm.branch("3");
- static final ASN1ObjectIdentifier id_dsa_with_sha2 = sigAlgs;
+ static final ASN1ObjectIdentifier id_dsa_with_sha2 = sigAlgs;
/** 2.16.840.1.101.3.4.3.1 */
static final ASN1ObjectIdentifier dsa_with_sha224 = sigAlgs.branch("1");
@@ -152,12 +220,12 @@
static final ASN1ObjectIdentifier id_ecdsa_with_sha3_512 = sigAlgs.branch("12");
// RSA PKCS #1 v1.5 Signature with SHA-3 family.
- /** 2.16.840.1.101.3.4.3.9 */
+ /** 2.16.840.1.101.3.4.3.13 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_224 = sigAlgs.branch("13");
- /** 2.16.840.1.101.3.4.3.10 */
+ /** 2.16.840.1.101.3.4.3.14 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_256 = sigAlgs.branch("14");
- /** 2.16.840.1.101.3.4.3.11 */
+ /** 2.16.840.1.101.3.4.3.15 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_384 = sigAlgs.branch("15");
- /** 2.16.840.1.101.3.4.3.12 */
+ /** 2.16.840.1.101.3.4.3.16 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_512 = sigAlgs.branch("16");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java
new file mode 100644
index 0000000..aefc353
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java
@@ -0,0 +1,124 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERBitString;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * BasicOCSPResponse ::= SEQUENCE {
+ * tbsResponseData ResponseData,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BasicOCSPResponse
+ extends ASN1Object
+{
+ private ResponseData tbsResponseData;
+ private AlgorithmIdentifier signatureAlgorithm;
+ private DERBitString signature;
+ private ASN1Sequence certs;
+
+ public BasicOCSPResponse(
+ ResponseData tbsResponseData,
+ AlgorithmIdentifier signatureAlgorithm,
+ DERBitString signature,
+ ASN1Sequence certs)
+ {
+ this.tbsResponseData = tbsResponseData;
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.signature = signature;
+ this.certs = certs;
+ }
+
+ private BasicOCSPResponse(
+ ASN1Sequence seq)
+ {
+ this.tbsResponseData = ResponseData.getInstance(seq.getObjectAt(0));
+ this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ this.signature = (DERBitString)seq.getObjectAt(2);
+
+ if (seq.size() > 3)
+ {
+ this.certs = ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(3), true);
+ }
+ }
+
+ public static BasicOCSPResponse getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static BasicOCSPResponse getInstance(
+ Object obj)
+ {
+ if (obj instanceof BasicOCSPResponse)
+ {
+ return (BasicOCSPResponse)obj;
+ }
+ else if (obj != null)
+ {
+ return new BasicOCSPResponse(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ResponseData getTbsResponseData()
+ {
+ return tbsResponseData;
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return signatureAlgorithm;
+ }
+
+ public DERBitString getSignature()
+ {
+ return signature;
+ }
+
+ public ASN1Sequence getCerts()
+ {
+ return certs;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * BasicOCSPResponse ::= SEQUENCE {
+ * tbsResponseData ResponseData,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(tbsResponseData);
+ v.add(signatureAlgorithm);
+ v.add(signature);
+ if (certs != null)
+ {
+ v.add(new DERTaggedObject(true, 0, certs));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/CertID.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/CertID.java
new file mode 100644
index 0000000..5fc6d06
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/CertID.java
@@ -0,0 +1,109 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertID
+ extends ASN1Object
+{
+ AlgorithmIdentifier hashAlgorithm;
+ ASN1OctetString issuerNameHash;
+ ASN1OctetString issuerKeyHash;
+ ASN1Integer serialNumber;
+
+ public CertID(
+ AlgorithmIdentifier hashAlgorithm,
+ ASN1OctetString issuerNameHash,
+ ASN1OctetString issuerKeyHash,
+ ASN1Integer serialNumber)
+ {
+ this.hashAlgorithm = hashAlgorithm;
+ this.issuerNameHash = issuerNameHash;
+ this.issuerKeyHash = issuerKeyHash;
+ this.serialNumber = serialNumber;
+ }
+
+ private CertID(
+ ASN1Sequence seq)
+ {
+ hashAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0));
+ issuerNameHash = (ASN1OctetString)seq.getObjectAt(1);
+ issuerKeyHash = (ASN1OctetString)seq.getObjectAt(2);
+ serialNumber = (ASN1Integer)seq.getObjectAt(3);
+ }
+
+ public static CertID getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static CertID getInstance(
+ Object obj)
+ {
+ if (obj instanceof CertID)
+ {
+ return (CertID)obj;
+ }
+ else if (obj != null)
+ {
+ return new CertID(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public AlgorithmIdentifier getHashAlgorithm()
+ {
+ return hashAlgorithm;
+ }
+
+ public ASN1OctetString getIssuerNameHash()
+ {
+ return issuerNameHash;
+ }
+
+ public ASN1OctetString getIssuerKeyHash()
+ {
+ return issuerKeyHash;
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * CertID ::= SEQUENCE {
+ * hashAlgorithm AlgorithmIdentifier,
+ * issuerNameHash OCTET STRING, -- Hash of Issuer's DN
+ * issuerKeyHash OCTET STRING, -- Hash of Issuers public key
+ * serialNumber CertificateSerialNumber }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(hashAlgorithm);
+ v.add(issuerNameHash);
+ v.add(issuerKeyHash);
+ v.add(serialNumber);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/CertStatus.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/CertStatus.java
new file mode 100644
index 0000000..4a76cb4
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/CertStatus.java
@@ -0,0 +1,117 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1Choice;
+import com.android.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.org.bouncycastle.asn1.ASN1Null;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.ASN1Util;
+import com.android.org.bouncycastle.asn1.DERNull;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertStatus
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private int tagNo;
+ private ASN1Encodable value;
+
+ /**
+ * create a CertStatus object with a tag of zero.
+ */
+ public CertStatus()
+ {
+ tagNo = 0;
+ value = DERNull.INSTANCE;
+ }
+
+ public CertStatus(
+ RevokedInfo info)
+ {
+ tagNo = 1;
+ value = info;
+ }
+
+ public CertStatus(
+ int tagNo,
+ ASN1Encodable value)
+ {
+ this.tagNo = tagNo;
+ this.value = value;
+ }
+
+ private CertStatus(
+ ASN1TaggedObject choice)
+ {
+ int tagNo = choice.getTagNo();
+
+ switch (tagNo)
+ {
+ case 0:
+ value = ASN1Null.getInstance(choice, false);
+ break;
+ case 1:
+ value = RevokedInfo.getInstance(choice, false);
+ break;
+ case 2:
+ // UnknownInfo ::= NULL
+ value = ASN1Null.getInstance(choice, false);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown tag encountered: " + ASN1Util.getTagText(choice));
+ }
+
+ this.tagNo = tagNo;
+ }
+
+ public static CertStatus getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof CertStatus)
+ {
+ return (CertStatus)obj;
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ return new CertStatus((ASN1TaggedObject)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
+ }
+
+ public static CertStatus getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getExplicitBaseTagged()); // must be explicitly tagged
+ }
+
+ public int getTagNo()
+ {
+ return tagNo;
+ }
+
+ public ASN1Encodable getStatus()
+ {
+ return value;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * CertStatus ::= CHOICE {
+ * good [0] IMPLICIT NULL,
+ * revoked [1] IMPLICIT RevokedInfo,
+ * unknown [2] IMPLICIT UnknownInfo }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new DERTaggedObject(false, tagNo, value);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/CrlID.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/CrlID.java
new file mode 100644
index 0000000..becc59f
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/CrlID.java
@@ -0,0 +1,125 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import java.util.Enumeration;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.org.bouncycastle.asn1.ASN1IA5String;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERIA5String;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CrlID
+ extends ASN1Object
+{
+ private ASN1IA5String crlUrl;
+ private ASN1Integer crlNum;
+ private ASN1GeneralizedTime crlTime;
+
+ private CrlID(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)e.nextElement();
+
+ switch (o.getTagNo())
+ {
+ case 0:
+ crlUrl = ASN1IA5String.getInstance(o, true);
+ break;
+ case 1:
+ crlNum = ASN1Integer.getInstance(o, true);
+ break;
+ case 2:
+ crlTime = ASN1GeneralizedTime.getInstance(o, true);
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "unknown tag number: " + o.getTagNo());
+ }
+ }
+ }
+
+ public static CrlID getInstance(
+ Object obj)
+ {
+ if (obj instanceof CrlID)
+ {
+ return (CrlID)obj;
+ }
+ else if (obj != null)
+ {
+ return new CrlID(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * @deprecated Use {@link #getCrlUrlIA5()} instead.
+ */
+ public DERIA5String getCrlUrl()
+ {
+ return null == crlUrl || crlUrl instanceof DERIA5String
+ ? (DERIA5String)crlUrl
+ : new DERIA5String(crlUrl.getString(), false);
+ }
+
+ public ASN1IA5String getCrlUrlIA5()
+ {
+ return crlUrl;
+ }
+
+ public ASN1Integer getCrlNum()
+ {
+ return crlNum;
+ }
+
+ public ASN1GeneralizedTime getCrlTime()
+ {
+ return crlTime;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * CrlID ::= SEQUENCE {
+ * crlUrl [0] EXPLICIT IA5String OPTIONAL,
+ * crlNum [1] EXPLICIT INTEGER OPTIONAL,
+ * crlTime [2] EXPLICIT GeneralizedTime OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ if (crlUrl != null)
+ {
+ v.add(new DERTaggedObject(true, 0, crlUrl));
+ }
+
+ if (crlNum != null)
+ {
+ v.add(new DERTaggedObject(true, 1, crlNum));
+ }
+
+ if (crlTime != null)
+ {
+ v.add(new DERTaggedObject(true, 2, crlTime));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java
new file mode 100644
index 0000000..ff065f5
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * OIDs for <a href="https://tools.ietf.org/html/rfc2560">RFC 2560</a> and <a href="https://tools.ietf.org/html/rfc6960">RFC 6960</a>
+ * Online Certificate Status Protocol - OCSP.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface OCSPObjectIdentifiers
+{
+ /** OID: 1.3.6.1.5.5.7.48.1 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1");
+ /** OID: 1.3.6.1.5.5.7.48.1.1 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_basic = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.1");
+
+ /** OID: 1.3.6.1.5.5.7.48.1.2 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_nonce = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.2");
+ /** OID: 1.3.6.1.5.5.7.48.1.3 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_crl = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.3");
+
+ /** OID: 1.3.6.1.5.5.7.48.1.4 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_response = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.4");
+ /** OID: 1.3.6.1.5.5.7.48.1.5 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_nocheck = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.5");
+ /** OID: 1.3.6.1.5.5.7.48.1.6 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_archive_cutoff = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.6");
+ /** OID: 1.3.6.1.5.5.7.48.1.7 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_service_locator = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.7");
+
+
+ static final ASN1ObjectIdentifier id_pkix_ocsp_pref_sig_algs = id_pkix_ocsp.branch("8");
+
+ static final ASN1ObjectIdentifier id_pkix_ocsp_extended_revoke = id_pkix_ocsp.branch("9");
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPRequest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPRequest.java
new file mode 100644
index 0000000..bd2ddd0
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPRequest.java
@@ -0,0 +1,94 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OCSPRequest
+ extends ASN1Object
+{
+ TBSRequest tbsRequest;
+ Signature optionalSignature;
+
+ public OCSPRequest(
+ TBSRequest tbsRequest,
+ Signature optionalSignature)
+ {
+ this.tbsRequest = tbsRequest;
+ this.optionalSignature = optionalSignature;
+ }
+
+ private OCSPRequest(
+ ASN1Sequence seq)
+ {
+ tbsRequest = TBSRequest.getInstance(seq.getObjectAt(0));
+
+ if (seq.size() == 2)
+ {
+ optionalSignature = Signature.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(1), true);
+ }
+ }
+
+ public static OCSPRequest getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static OCSPRequest getInstance(
+ Object obj)
+ {
+ if (obj instanceof OCSPRequest)
+ {
+ return (OCSPRequest)obj;
+ }
+ else if (obj != null)
+ {
+ return new OCSPRequest(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public TBSRequest getTbsRequest()
+ {
+ return tbsRequest;
+ }
+
+ public Signature getOptionalSignature()
+ {
+ return optionalSignature;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * OCSPRequest ::= SEQUENCE {
+ * tbsRequest TBSRequest,
+ * optionalSignature [0] EXPLICIT Signature OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(tbsRequest);
+
+ if (optionalSignature != null)
+ {
+ v.add(new DERTaggedObject(true, 0, optionalSignature));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPResponse.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPResponse.java
new file mode 100644
index 0000000..7bcf2f4
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPResponse.java
@@ -0,0 +1,103 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * OCSPResponse ::= SEQUENCE {
+ * responseStatus OCSPResponseStatus,
+ * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
+ * </pre>
+ * @see OCSPResponseStatus
+ * @see ResponseBytes
+ * @hide This class is not part of the Android public SDK API
+ */
+
+public class OCSPResponse
+ extends ASN1Object
+{
+ OCSPResponseStatus responseStatus;
+ ResponseBytes responseBytes;
+
+ public OCSPResponse(
+ OCSPResponseStatus responseStatus,
+ ResponseBytes responseBytes)
+ {
+ this.responseStatus = responseStatus;
+ this.responseBytes = responseBytes;
+ }
+
+ private OCSPResponse(
+ ASN1Sequence seq)
+ {
+ responseStatus = OCSPResponseStatus.getInstance(seq.getObjectAt(0));
+
+ if (seq.size() == 2)
+ {
+ responseBytes = ResponseBytes.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(1), true);
+ }
+ }
+
+ public static OCSPResponse getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static OCSPResponse getInstance(
+ Object obj)
+ {
+ if (obj instanceof OCSPResponse)
+ {
+ return (OCSPResponse)obj;
+ }
+ else if (obj != null)
+ {
+ return new OCSPResponse(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public OCSPResponseStatus getResponseStatus()
+ {
+ return responseStatus;
+ }
+
+ public ResponseBytes getResponseBytes()
+ {
+ return responseBytes;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * OCSPResponse ::= SEQUENCE {
+ * responseStatus OCSPResponseStatus,
+ * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(responseStatus);
+
+ if (responseBytes != null)
+ {
+ v.add(new DERTaggedObject(true, 0, responseBytes));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java
new file mode 100644
index 0000000..dcdd7f8
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java
@@ -0,0 +1,97 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import java.math.BigInteger;
+
+import com.android.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <p>
+ * The OCSPResponseStatus enumeration.
+ * <pre>
+ * OCSPResponseStatus ::= ENUMERATED {
+ * successful (0), --Response has valid confirmations
+ * malformedRequest (1), --Illegal confirmation request
+ * internalError (2), --Internal error in issuer
+ * tryLater (3), --Try again later
+ * --(4) is not used
+ * sigRequired (5), --Must sign the request
+ * unauthorized (6) --Request unauthorized
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OCSPResponseStatus
+ extends ASN1Object
+{
+ public static final int SUCCESSFUL = 0;
+ public static final int MALFORMED_REQUEST = 1;
+ public static final int INTERNAL_ERROR = 2;
+ public static final int TRY_LATER = 3;
+ public static final int SIG_REQUIRED = 5;
+ public static final int UNAUTHORIZED = 6;
+
+ private ASN1Enumerated value;
+
+ /**
+ * RFC 2560, RFC 6960
+ * <p>
+ * The OCSPResponseStatus enumeration.
+ * <pre>
+ * OCSPResponseStatus ::= ENUMERATED {
+ * successful (0), --Response has valid confirmations
+ * malformedRequest (1), --Illegal confirmation request
+ * internalError (2), --Internal error in issuer
+ * tryLater (3), --Try again later
+ * --(4) is not used
+ * sigRequired (5), --Must sign the request
+ * unauthorized (6) --Request unauthorized
+ * }
+ * </pre>
+ */
+ public OCSPResponseStatus(
+ int value)
+ {
+ this(new ASN1Enumerated(value));
+ }
+
+ private OCSPResponseStatus(
+ ASN1Enumerated value)
+ {
+ this.value = value;
+ }
+
+ public static OCSPResponseStatus getInstance(
+ Object obj)
+ {
+ if (obj instanceof OCSPResponseStatus)
+ {
+ return (OCSPResponseStatus)obj;
+ }
+ else if (obj != null)
+ {
+ return new OCSPResponseStatus(ASN1Enumerated.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public int getIntValue()
+ {
+ return value.intValueExact();
+ }
+
+ public BigInteger getValue()
+ {
+ return value.getValue();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return value;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/Request.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/Request.java
new file mode 100644
index 0000000..4883c02
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/Request.java
@@ -0,0 +1,95 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.org.bouncycastle.asn1.x509.Extensions;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Request
+ extends ASN1Object
+{
+ CertID reqCert;
+ Extensions singleRequestExtensions;
+
+ public Request(
+ CertID reqCert,
+ Extensions singleRequestExtensions)
+ {
+ this.reqCert = reqCert;
+ this.singleRequestExtensions = singleRequestExtensions;
+ }
+
+ private Request(
+ ASN1Sequence seq)
+ {
+ reqCert = CertID.getInstance(seq.getObjectAt(0));
+
+ if (seq.size() == 2)
+ {
+ singleRequestExtensions = Extensions.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(1), true);
+ }
+ }
+
+ public static Request getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static Request getInstance(
+ Object obj)
+ {
+ if (obj instanceof Request)
+ {
+ return (Request)obj;
+ }
+ else if (obj != null)
+ {
+ return new Request(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public CertID getReqCert()
+ {
+ return reqCert;
+ }
+
+ public Extensions getSingleRequestExtensions()
+ {
+ return singleRequestExtensions;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * Request ::= SEQUENCE {
+ * reqCert CertID,
+ * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(reqCert);
+
+ if (singleRequestExtensions != null)
+ {
+ v.add(new DERTaggedObject(true, 0, singleRequestExtensions));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/ResponderID.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/ResponderID.java
new file mode 100644
index 0000000..6724903
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/ResponderID.java
@@ -0,0 +1,113 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1Choice;
+import com.android.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ResponderID
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private ASN1Encodable value;
+
+ public ResponderID(
+ ASN1OctetString value)
+ {
+ this.value = value;
+ }
+
+ public ResponderID(
+ X500Name value)
+ {
+ this.value = value;
+ }
+
+ public static ResponderID getInstance(
+ Object obj)
+ {
+ if (obj instanceof ResponderID)
+ {
+ return (ResponderID)obj;
+ }
+ else if (obj instanceof DEROctetString)
+ {
+ return new ResponderID((DEROctetString)obj);
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)obj;
+
+ if (o.getTagNo() == 1)
+ {
+ return new ResponderID(X500Name.getInstance(o, true));
+ }
+ else
+ {
+ return new ResponderID(ASN1OctetString.getInstance(o, true));
+ }
+ }
+
+ return new ResponderID(X500Name.getInstance(obj));
+ }
+
+ public static ResponderID getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
+ return getInstance(obj.getExplicitBaseObject());
+ }
+
+ public byte[] getKeyHash()
+ {
+ if (this.value instanceof ASN1OctetString)
+ {
+ ASN1OctetString octetString = (ASN1OctetString)this.value;
+ return octetString.getOctets();
+ }
+
+ return null;
+ }
+
+ public X500Name getName()
+ {
+ if (this.value instanceof ASN1OctetString)
+ {
+ return null;
+ }
+
+ return X500Name.getInstance(value);
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * ResponderID ::= CHOICE {
+ * byName [1] Name,
+ * byKey [2] KeyHash }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (value instanceof ASN1OctetString)
+ {
+ return new DERTaggedObject(true, 2, value);
+ }
+
+ return new DERTaggedObject(true, 1, value);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/ResponseBytes.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/ResponseBytes.java
new file mode 100644
index 0000000..0ae80a4
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/ResponseBytes.java
@@ -0,0 +1,92 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * ResponseBytes ::= SEQUENCE {
+ * responseType OBJECT IDENTIFIER,
+ * response OCTET STRING }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ResponseBytes
+ extends ASN1Object
+{
+ ASN1ObjectIdentifier responseType;
+ ASN1OctetString response;
+
+ public ResponseBytes(
+ ASN1ObjectIdentifier responseType,
+ ASN1OctetString response)
+ {
+ this.responseType = responseType;
+ this.response = response;
+ }
+
+ private ResponseBytes(
+ ASN1Sequence seq)
+ {
+ responseType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
+ response = (ASN1OctetString)seq.getObjectAt(1);
+ }
+
+ public static ResponseBytes getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static ResponseBytes getInstance(
+ Object obj)
+ {
+ if (obj instanceof ResponseBytes)
+ {
+ return (ResponseBytes)obj;
+ }
+ else if (obj != null)
+ {
+ return new ResponseBytes(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1ObjectIdentifier getResponseType()
+ {
+ return responseType;
+ }
+
+ public ASN1OctetString getResponse()
+ {
+ return response;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * ResponseBytes ::= SEQUENCE {
+ * responseType OBJECT IDENTIFIER,
+ * response OCTET STRING }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(responseType);
+ v.add(response);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/ResponseData.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/ResponseData.java
new file mode 100644
index 0000000..b3964c9
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/ResponseData.java
@@ -0,0 +1,194 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.org.bouncycastle.asn1.x509.Extensions;
+import com.android.org.bouncycastle.asn1.x509.X509Extensions;
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * ResponseData ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * responderID ResponderID,
+ * producedAt GeneralizedTime,
+ * responses SEQUENCE OF SingleResponse,
+ * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ResponseData
+ extends ASN1Object
+{
+ private static final ASN1Integer V1 = new ASN1Integer(0);
+
+ private boolean versionPresent;
+
+ private ASN1Integer version;
+ private ResponderID responderID;
+ private ASN1GeneralizedTime producedAt;
+ private ASN1Sequence responses;
+ private Extensions responseExtensions;
+
+ public ResponseData(
+ ASN1Integer version,
+ ResponderID responderID,
+ ASN1GeneralizedTime producedAt,
+ ASN1Sequence responses,
+ Extensions responseExtensions)
+ {
+ this.version = version;
+ this.responderID = responderID;
+ this.producedAt = producedAt;
+ this.responses = responses;
+ this.responseExtensions = responseExtensions;
+ }
+
+ /**
+ * @deprecated use method taking Extensions
+ * @param responderID
+ * @param producedAt
+ * @param responses
+ * @param responseExtensions
+ */
+ public ResponseData(
+ ResponderID responderID,
+ ASN1GeneralizedTime producedAt,
+ ASN1Sequence responses,
+ X509Extensions responseExtensions)
+ {
+ this(V1, responderID, ASN1GeneralizedTime.getInstance(producedAt), responses, Extensions.getInstance(responseExtensions));
+ }
+
+ public ResponseData(
+ ResponderID responderID,
+ ASN1GeneralizedTime producedAt,
+ ASN1Sequence responses,
+ Extensions responseExtensions)
+ {
+ this(V1, responderID, producedAt, responses, responseExtensions);
+ }
+
+ private ResponseData(
+ ASN1Sequence seq)
+ {
+ int index = 0;
+
+ if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0);
+
+ if (o.getTagNo() == 0)
+ {
+ this.versionPresent = true;
+ this.version = ASN1Integer.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(0), true);
+ index++;
+ }
+ else
+ {
+ this.version = V1;
+ }
+ }
+ else
+ {
+ this.version = V1;
+ }
+
+ this.responderID = ResponderID.getInstance(seq.getObjectAt(index++));
+ this.producedAt = ASN1GeneralizedTime.getInstance(seq.getObjectAt(index++));
+ this.responses = (ASN1Sequence)seq.getObjectAt(index++);
+
+ if (seq.size() > index)
+ {
+ this.responseExtensions = Extensions.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(index), true);
+ }
+ }
+
+ public static ResponseData getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static ResponseData getInstance(
+ Object obj)
+ {
+ if (obj instanceof ResponseData)
+ {
+ return (ResponseData)obj;
+ }
+ else if (obj != null)
+ {
+ return new ResponseData(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public ResponderID getResponderID()
+ {
+ return responderID;
+ }
+
+ public ASN1GeneralizedTime getProducedAt()
+ {
+ return producedAt;
+ }
+
+ public ASN1Sequence getResponses()
+ {
+ return responses;
+ }
+
+ public Extensions getResponseExtensions()
+ {
+ return responseExtensions;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * ResponseData ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * responderID ResponderID,
+ * producedAt GeneralizedTime,
+ * responses SEQUENCE OF SingleResponse,
+ * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
+
+ if (versionPresent || !version.equals(V1))
+ {
+ v.add(new DERTaggedObject(true, 0, version));
+ }
+
+ v.add(responderID);
+ v.add(producedAt);
+ v.add(responses);
+ if (responseExtensions != null)
+ {
+ v.add(new DERTaggedObject(true, 1, responseExtensions));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/RevokedInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/RevokedInfo.java
new file mode 100644
index 0000000..81c832b
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/RevokedInfo.java
@@ -0,0 +1,101 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.org.bouncycastle.asn1.x509.CRLReason;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RevokedInfo
+ extends ASN1Object
+{
+ private ASN1GeneralizedTime revocationTime;
+ private CRLReason revocationReason;
+
+ public RevokedInfo(ASN1GeneralizedTime revocationTime)
+ {
+ this(revocationTime, null);
+ }
+
+ public RevokedInfo(
+ ASN1GeneralizedTime revocationTime,
+ CRLReason revocationReason)
+ {
+ this.revocationTime = revocationTime;
+ this.revocationReason = revocationReason;
+ }
+
+ private RevokedInfo(
+ ASN1Sequence seq)
+ {
+ this.revocationTime = ASN1GeneralizedTime.getInstance(seq.getObjectAt(0));
+
+ if (seq.size() > 1)
+ {
+ this.revocationReason = CRLReason.getInstance(ASN1Enumerated.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(1), true));
+ }
+ }
+
+ public static RevokedInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static RevokedInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof RevokedInfo)
+ {
+ return (RevokedInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new RevokedInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1GeneralizedTime getRevocationTime()
+ {
+ return revocationTime;
+ }
+
+ public CRLReason getRevocationReason()
+ {
+ return revocationReason;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * RevokedInfo ::= SEQUENCE {
+ * revocationTime GeneralizedTime,
+ * revocationReason [0] EXPLICIT CRLReason OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(revocationTime);
+ if (revocationReason != null)
+ {
+ v.add(new DERTaggedObject(true, 0, revocationReason));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/Signature.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/Signature.java
new file mode 100644
index 0000000..40fe942
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/Signature.java
@@ -0,0 +1,115 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERBitString;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Signature
+ extends ASN1Object
+{
+ AlgorithmIdentifier signatureAlgorithm;
+ DERBitString signature;
+ ASN1Sequence certs;
+
+ public Signature(
+ AlgorithmIdentifier signatureAlgorithm,
+ DERBitString signature)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.signature = signature;
+ }
+
+ public Signature(
+ AlgorithmIdentifier signatureAlgorithm,
+ DERBitString signature,
+ ASN1Sequence certs)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.signature = signature;
+ this.certs = certs;
+ }
+
+ private Signature(
+ ASN1Sequence seq)
+ {
+ signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0));
+ signature = (DERBitString)seq.getObjectAt(1);
+
+ if (seq.size() == 3)
+ {
+ certs = ASN1Sequence.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(2), true);
+ }
+ }
+
+ public static Signature getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static Signature getInstance(
+ Object obj)
+ {
+ if (obj instanceof Signature)
+ {
+ return (Signature)obj;
+ }
+ else if (obj != null)
+ {
+ return new Signature(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return signatureAlgorithm;
+ }
+
+ public DERBitString getSignature()
+ {
+ return signature;
+ }
+
+ public ASN1Sequence getCerts()
+ {
+ return certs;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * Signature ::= SEQUENCE {
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(signatureAlgorithm);
+ v.add(signature);
+
+ if (certs != null)
+ {
+ v.add(new DERTaggedObject(true, 0, certs));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/SingleResponse.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/SingleResponse.java
new file mode 100644
index 0000000..85e8802
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/SingleResponse.java
@@ -0,0 +1,166 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.org.bouncycastle.asn1.x509.Extensions;
+import com.android.org.bouncycastle.asn1.x509.X509Extensions;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SingleResponse
+ extends ASN1Object
+{
+ private CertID certID;
+ private CertStatus certStatus;
+ private ASN1GeneralizedTime thisUpdate;
+ private ASN1GeneralizedTime nextUpdate;
+ private Extensions singleExtensions;
+
+ /**
+ * @deprecated use method taking ASN1GeneralizedTime and Extensions
+ * @param certID
+ * @param certStatus
+ * @param thisUpdate
+ * @param nextUpdate
+ * @param singleExtensions
+ */
+ public SingleResponse(
+ CertID certID,
+ CertStatus certStatus,
+ ASN1GeneralizedTime thisUpdate,
+ ASN1GeneralizedTime nextUpdate,
+ X509Extensions singleExtensions)
+ {
+ this(certID, certStatus, thisUpdate, nextUpdate, Extensions.getInstance(singleExtensions));
+ }
+
+ public SingleResponse(
+ CertID certID,
+ CertStatus certStatus,
+ ASN1GeneralizedTime thisUpdate,
+ ASN1GeneralizedTime nextUpdate,
+ Extensions singleExtensions)
+ {
+ this.certID = certID;
+ this.certStatus = certStatus;
+ this.thisUpdate = thisUpdate;
+ this.nextUpdate = nextUpdate;
+ this.singleExtensions = singleExtensions;
+ }
+
+ private SingleResponse(
+ ASN1Sequence seq)
+ {
+ this.certID = CertID.getInstance(seq.getObjectAt(0));
+ this.certStatus = CertStatus.getInstance(seq.getObjectAt(1));
+ this.thisUpdate = ASN1GeneralizedTime.getInstance(seq.getObjectAt(2));
+
+ if (seq.size() > 4)
+ {
+ this.nextUpdate = ASN1GeneralizedTime.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(3), true);
+ this.singleExtensions = Extensions.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(4), true);
+ }
+ else if (seq.size() > 3)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(3);
+
+ if (o.getTagNo() == 0)
+ {
+ this.nextUpdate = ASN1GeneralizedTime.getInstance(o, true);
+ }
+ else
+ {
+ this.singleExtensions = Extensions.getInstance(o, true);
+ }
+ }
+ }
+
+ public static SingleResponse getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static SingleResponse getInstance(
+ Object obj)
+ {
+ if (obj instanceof SingleResponse)
+ {
+ return (SingleResponse)obj;
+ }
+ else if (obj != null)
+ {
+ return new SingleResponse(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public CertID getCertID()
+ {
+ return certID;
+ }
+
+ public CertStatus getCertStatus()
+ {
+ return certStatus;
+ }
+
+ public ASN1GeneralizedTime getThisUpdate()
+ {
+ return thisUpdate;
+ }
+
+ public ASN1GeneralizedTime getNextUpdate()
+ {
+ return nextUpdate;
+ }
+
+ public Extensions getSingleExtensions()
+ {
+ return singleExtensions;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * SingleResponse ::= SEQUENCE {
+ * certID CertID,
+ * certStatus CertStatus,
+ * thisUpdate GeneralizedTime,
+ * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
+ * singleExtensions [1] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
+
+ v.add(certID);
+ v.add(certStatus);
+ v.add(thisUpdate);
+
+ if (nextUpdate != null)
+ {
+ v.add(new DERTaggedObject(true, 0, nextUpdate));
+ }
+
+ if (singleExtensions != null)
+ {
+ v.add(new DERTaggedObject(true, 1, singleExtensions));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/TBSRequest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/TBSRequest.java
new file mode 100644
index 0000000..839158f
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/TBSRequest.java
@@ -0,0 +1,176 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.ocsp;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.org.bouncycastle.asn1.x509.Extensions;
+import com.android.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.org.bouncycastle.asn1.x509.X509Extensions;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TBSRequest
+ extends ASN1Object
+{
+ private static final ASN1Integer V1 = new ASN1Integer(0);
+
+ ASN1Integer version;
+ GeneralName requestorName;
+ ASN1Sequence requestList;
+ Extensions requestExtensions;
+
+ boolean versionSet;
+
+ /**
+ * @deprecated use method taking Extensions
+ * @param requestorName
+ * @param requestList
+ * @param requestExtensions
+ */
+ public TBSRequest(
+ GeneralName requestorName,
+ ASN1Sequence requestList,
+ X509Extensions requestExtensions)
+ {
+ this.version = V1;
+ this.requestorName = requestorName;
+ this.requestList = requestList;
+ this.requestExtensions = Extensions.getInstance(requestExtensions);
+ }
+
+ public TBSRequest(
+ GeneralName requestorName,
+ ASN1Sequence requestList,
+ Extensions requestExtensions)
+ {
+ this.version = V1;
+ this.requestorName = requestorName;
+ this.requestList = requestList;
+ this.requestExtensions = requestExtensions;
+ }
+
+ private TBSRequest(
+ ASN1Sequence seq)
+ {
+ int index = 0;
+
+ if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0);
+
+ if (o.getTagNo() == 0)
+ {
+ versionSet = true;
+ version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true);
+ index++;
+ }
+ else
+ {
+ version = V1;
+ }
+ }
+ else
+ {
+ version = V1;
+ }
+
+ if (seq.getObjectAt(index) instanceof ASN1TaggedObject)
+ {
+ requestorName = GeneralName.getInstance((ASN1TaggedObject)seq.getObjectAt(index++), true);
+ }
+
+ requestList = (ASN1Sequence)seq.getObjectAt(index++);
+
+ if (seq.size() == (index + 1))
+ {
+ requestExtensions = Extensions.getInstance((ASN1TaggedObject)seq.getObjectAt(index), true);
+ }
+ }
+
+ public static TBSRequest getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static TBSRequest getInstance(
+ Object obj)
+ {
+ if (obj instanceof TBSRequest)
+ {
+ return (TBSRequest)obj;
+ }
+ else if (obj != null)
+ {
+ return new TBSRequest(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public GeneralName getRequestorName()
+ {
+ return requestorName;
+ }
+
+ public ASN1Sequence getRequestList()
+ {
+ return requestList;
+ }
+
+ public Extensions getRequestExtensions()
+ {
+ return requestExtensions;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * TBSRequest ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * requestorName [1] EXPLICIT GeneralName OPTIONAL,
+ * requestList SEQUENCE OF Request,
+ * requestExtensions [2] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ //
+ // if default don't include - unless explicitly provided. Not strictly correct
+ // but required for some requests
+ //
+ if (!version.equals(V1) || versionSet)
+ {
+ v.add(new DERTaggedObject(true, 0, version));
+ }
+
+ if (requestorName != null)
+ {
+ v.add(new DERTaggedObject(true, 1, requestorName));
+ }
+
+ v.add(requestList);
+
+ if (requestExtensions != null)
+ {
+ v.add(new DERTaggedObject(true, 2, requestExtensions));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CRLBag.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CRLBag.java
index 441dfd1..5d97e80 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CRLBag.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CRLBag.java
@@ -24,8 +24,8 @@
private CRLBag(
ASN1Sequence seq)
{
- this.crlId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
- this.crlValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject();
+ this.crlId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ this.crlValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
}
public static CRLBag getInstance(Object o)
@@ -69,7 +69,7 @@
*
* x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}
* -- DER-encoded X.509 CRL stored in OCTET STRING
- *
+ *
* CRLTypes BAG-TYPE ::= {
* x509CRL,
* ... -- For future extensions
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertBag.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertBag.java
index 76fe51a..0501b4a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertBag.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertBag.java
@@ -24,7 +24,7 @@
ASN1Sequence seq)
{
this.certId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
- this.certValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject();
+ this.certValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
}
public static CertBag getInstance(Object o)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequest.java
index b5e9091..4feb3da 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequest.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.pkcs;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
@@ -25,7 +26,7 @@
{
protected CertificationRequestInfo reqInfo = null;
protected AlgorithmIdentifier sigAlgId = null;
- protected DERBitString sigBits = null;
+ protected ASN1BitString sigBits = null;
public static CertificationRequest getInstance(Object o)
{
@@ -49,7 +50,7 @@
public CertificationRequest(
CertificationRequestInfo requestInfo,
AlgorithmIdentifier algorithm,
- DERBitString signature)
+ ASN1BitString signature)
{
this.reqInfo = requestInfo;
this.sigAlgId = algorithm;
@@ -77,7 +78,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sigBits;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
index fc3e97c..a58828c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
@@ -99,10 +99,7 @@
this(X500Name.getInstance(subject.toASN1Primitive()), pkInfo, attributes);
}
- /**
- * @deprecated use getInstance().
- */
- public CertificationRequestInfo(
+ private CertificationRequestInfo(
ASN1Sequence seq)
{
version = (ASN1Integer)seq.getObjectAt(0);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/ContentInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/ContentInfo.java
index 2611ac7..41219ce 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/ContentInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/ContentInfo.java
@@ -50,7 +50,7 @@
if (e.hasMoreElements())
{
- content = ((ASN1TaggedObject)e.nextElement()).getObject();
+ content = ((ASN1TaggedObject)e.nextElement()).getExplicitBaseObject();
}
isBer = seq instanceof BERSequence;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedData.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedData.java
index 87d7d06..4510a4f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedData.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedData.java
@@ -57,9 +57,8 @@
private EncryptedData(
ASN1Sequence seq)
{
- int version = ((ASN1Integer)seq.getObjectAt(0)).intValueExact();
-
- if (version != 0)
+ ASN1Integer version = (ASN1Integer)seq.getObjectAt(0);
+ if (!version.hasValue(0))
{
throw new IllegalArgumentException("sequence not version 0");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
index 1a72358..3b01891 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
@@ -11,6 +11,7 @@
import com.android.org.bouncycastle.asn1.DEROctetString;
import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.org.bouncycastle.util.Arrays;
/**
* @hide This class is not part of the Android public SDK API
@@ -35,7 +36,7 @@
byte[] encoding)
{
this.algId = algId;
- this.data = new DEROctetString(encoding);
+ this.data = new DEROctetString(Arrays.clone(encoding));
}
public static EncryptedPrivateKeyInfo getInstance(
@@ -60,7 +61,7 @@
public byte[] getEncryptedData()
{
- return data.getOctets();
+ return Arrays.clone(data.getOctets());
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBKDF2Params.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
index 082284e..d974470 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
@@ -185,7 +185,7 @@
*/
public byte[] getSalt()
{
- return octStr.getOctets();
+ return Arrays.clone(octStr.getOctets());
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBMAC1Params.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBMAC1Params.java
new file mode 100644
index 0000000..842fc5e
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBMAC1Params.java
@@ -0,0 +1,90 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.pkcs;
+
+import java.util.Enumeration;
+
+import com.android.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+
+/**
+ * From https://datatracker.ietf.org/doc/html/rfc8018
+ *
+ * <pre>
+ * PBMAC1-params ::= SEQUENCE {
+ * keyDerivationFunc AlgorithmIdentifier {{PBMAC1-KDFs}},
+ * messageAuthScheme AlgorithmIdentifier {{PBMAC1-MACs}} }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PBMAC1Params
+ extends ASN1Object
+ implements PKCSObjectIdentifiers
+{
+ private AlgorithmIdentifier func;
+ private AlgorithmIdentifier scheme;
+
+ public static PBMAC1Params getInstance(
+ Object obj)
+ {
+ if (obj instanceof PBMAC1Params)
+ {
+ return (PBMAC1Params)obj;
+ }
+ if (obj != null)
+ {
+ return new PBMAC1Params(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public PBMAC1Params(AlgorithmIdentifier keyDevFunc, AlgorithmIdentifier encScheme)
+ {
+ this.func = keyDevFunc;
+ this.scheme = encScheme;
+ }
+
+ private PBMAC1Params(
+ ASN1Sequence obj)
+ {
+ Enumeration e = obj.getObjects();
+ ASN1Sequence funcSeq = ASN1Sequence.getInstance(((ASN1Encodable)e.nextElement()).toASN1Primitive());
+
+ if (funcSeq.getObjectAt(0).equals(id_PBKDF2))
+ {
+ func = new AlgorithmIdentifier(id_PBKDF2, PBKDF2Params.getInstance(funcSeq.getObjectAt(1)));
+ }
+ else
+ {
+ func = AlgorithmIdentifier.getInstance(funcSeq);
+ }
+
+ scheme = AlgorithmIdentifier.getInstance(e.nextElement());
+ }
+
+ public AlgorithmIdentifier getKeyDerivationFunc()
+ {
+ return func;
+ }
+
+ public AlgorithmIdentifier getMessageAuthScheme()
+ {
+ return scheme;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(func);
+ v.add(scheme);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
index 1e68d87..b243bc8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
@@ -79,10 +79,12 @@
ASN1ObjectIdentifier pbeWithSHA1AndDES_CBC = pkcs_5.branch("10");
/** PKCS#5: 1.2.840.113549.1.5.11 */
ASN1ObjectIdentifier pbeWithSHA1AndRC2_CBC = pkcs_5.branch("11");
- /** PKCS#5: 1.2.840.113549.1.5.13 */
- ASN1ObjectIdentifier id_PBES2 = pkcs_5.branch("13");
/** PKCS#5: 1.2.840.113549.1.5.12 */
ASN1ObjectIdentifier id_PBKDF2 = pkcs_5.branch("12");
+ /** PKCS#5: 1.2.840.113549.1.5.13 */
+ ASN1ObjectIdentifier id_PBES2 = pkcs_5.branch("13");
+ /** PKCS#5: 1.2.840.113549.1.5.14 */
+ ASN1ObjectIdentifier id_PBMAC1 = pkcs_5.branch("14");
//
// encryptionAlgorithm OBJECT IDENTIFIER ::= {
@@ -138,6 +140,10 @@
ASN1ObjectIdentifier id_hmacWithSHA384 = digestAlgorithm.branch("10").intern();
/** 1.2.840.113549.2.11 */
ASN1ObjectIdentifier id_hmacWithSHA512 = digestAlgorithm.branch("11").intern();
+ /** 1.2.840.113549.2.12 */
+ ASN1ObjectIdentifier id_hmacWithSHA512_224 = digestAlgorithm.branch("12").intern();
+ /** 1.2.840.113549.2.13 */
+ ASN1ObjectIdentifier id_hmacWithSHA512_256 = digestAlgorithm.branch("13").intern();
//
// pkcs-7 OBJECT IDENTIFIER ::= {
@@ -192,6 +198,8 @@
ASN1ObjectIdentifier pkcs_9_at_smimeCapabilities = pkcs_9.branch("15").intern();
/** PKCS#9: 1.2.840.113549.1.9.16 */
ASN1ObjectIdentifier id_smime = pkcs_9.branch("16").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.46 */
+ ASN1ObjectIdentifier pkcs_9_at_binarySigningTime = pkcs_9.branch("16.2.46").intern();
/** PKCS#9: 1.2.840.113549.1.9.20 */
ASN1ObjectIdentifier pkcs_9_at_friendlyName = pkcs_9.branch("20").intern();
@@ -250,8 +258,20 @@
/** S/MIME: Algorithm Identifiers ; 1.2.840.113549.1.9.16.3 */
ASN1ObjectIdentifier id_alg = id_smime.branch("3");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.5 */
+ ASN1ObjectIdentifier id_alg_ESDH = id_alg.branch("5");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.6 */
+ ASN1ObjectIdentifier id_alg_CMS3DESwrap = id_alg.branch("6");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.7 */
+ ASN1ObjectIdentifier id_alg_CMSRC2wrap = id_alg.branch("7");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.8 */
+ ASN1ObjectIdentifier id_alg_zlibCompress = id_alg.branch("8");
/** PKCS#9: 1.2.840.113549.1.9.16.3.9 */
- ASN1ObjectIdentifier id_alg_PWRI_KEK = id_alg.branch("9");
+ ASN1ObjectIdentifier id_alg_PWRI_KEK = id_alg.branch("9");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.10 */
+ ASN1ObjectIdentifier id_alg_SSDH = id_alg.branch("10");
+
/**
* <pre>
* -- RSA-KEM Key Transport Algorithm RFC 5990
@@ -469,14 +489,5 @@
* @deprecated use pbeWithSHAAnd40BitRC2_CBC
*/
ASN1ObjectIdentifier pbewithSHAAnd40BitRC2_CBC = pkcs_12PbeIds.branch("6");
-
- /** PKCS#9: 1.2.840.113549.1.9.16.3.6 */
- ASN1ObjectIdentifier id_alg_CMS3DESwrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.6");
- /** PKCS#9: 1.2.840.113549.1.9.16.3.7 */
- ASN1ObjectIdentifier id_alg_CMSRC2wrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.7");
- /** PKCS#9: 1.2.840.113549.1.9.16.3.5 */
- ASN1ObjectIdentifier id_alg_ESDH = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.5");
- /** PKCS#9: 1.2.840.113549.1.9.16.3.10 */
- ASN1ObjectIdentifier id_alg_SSDH = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.10");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Pfx.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Pfx.java
index 01241cc..7a6217b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Pfx.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Pfx.java
@@ -23,7 +23,7 @@
ASN1Sequence seq)
{
ASN1Integer version = ASN1Integer.getInstance(seq.getObjectAt(0));
- if (version.intValueExact() != 3)
+ if (!version.hasValue(3))
{
throw new IllegalArgumentException("wrong version for PFX PDU");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
index c368321..1cb91be 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
@@ -166,7 +166,7 @@
throw new IllegalArgumentException("'publicKey' requires version v2(1) or later");
}
- this.publicKey = DERBitString.getInstance(tagged, false);
+ this.publicKey = ASN1BitString.getInstance(tagged, false);
break;
}
default:
@@ -197,6 +197,11 @@
return new DEROctetString(privateKey.getOctets());
}
+ public int getPrivateKeyLength()
+ {
+ return privateKey.getOctetsLength();
+ }
+
public ASN1Encodable parsePrivateKey()
throws IOException
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
index 2bdfbab..eedb57b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
@@ -62,11 +62,7 @@
this.pSourceAlgorithm = pSourceAlgorithm;
}
- /**
- * @deprecated use getInstance()
- * @param seq
- */
- public RSAESOAEPparams(
+ private RSAESOAEPparams(
ASN1Sequence seq)
{
hashAlgorithm = DEFAULT_HASH_ALGORITHM;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SafeBag.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SafeBag.java
index b093f6c..b07ab2f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SafeBag.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SafeBag.java
@@ -61,7 +61,7 @@
ASN1Sequence seq)
{
this.bagId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
- this.bagValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject();
+ this.bagValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getExplicitBaseObject();
if (seq.size() == 3)
{
this.bagAttributes = (ASN1Set)seq.getObjectAt(2);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKey.java
index 07f0439..4ae47d8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKey.java
@@ -4,6 +4,7 @@
import java.math.BigInteger;
import java.util.Enumeration;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Integer;
@@ -12,7 +13,7 @@
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.org.bouncycastle.asn1.DERBitString;
+import com.android.org.bouncycastle.asn1.BERTags;
import com.android.org.bouncycastle.asn1.DEROctetString;
import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.asn1.DERTaggedObject;
@@ -93,7 +94,7 @@
*/
public ECPrivateKey(
BigInteger key,
- DERBitString publicKey,
+ ASN1BitString publicKey,
ASN1Encodable parameters)
{
this(key.bitLength(), key, publicKey, parameters);
@@ -110,7 +111,7 @@
public ECPrivateKey(
int orderBitLength,
BigInteger key,
- DERBitString publicKey,
+ ASN1BitString publicKey,
ASN1Encodable parameters)
{
byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key);
@@ -139,18 +140,27 @@
return new BigInteger(1, octs.getOctets());
}
-
- public DERBitString getPublicKey()
+
+ public ASN1BitString getPublicKey()
{
- return (DERBitString)getObjectInTag(1);
+ return (ASN1BitString)getObjectInTag(1, BERTags.BIT_STRING);
}
+ /**
+ * @deprecated Use {@link #getParametersObject()} instead and getInstance
+ * methods or similar to get the object at the desired type.
+ */
public ASN1Primitive getParameters()
{
- return getObjectInTag(0);
+ return getParametersObject().toASN1Primitive();
}
- private ASN1Primitive getObjectInTag(int tagNo)
+ public ASN1Object getParametersObject()
+ {
+ return getObjectInTag(0, -1);
+ }
+
+ private ASN1Object getObjectInTag(int tagNo, int baseTagNo)
{
Enumeration e = seq.getObjects();
@@ -161,9 +171,11 @@
if (obj instanceof ASN1TaggedObject)
{
ASN1TaggedObject tag = (ASN1TaggedObject)obj;
- if (tag.getTagNo() == tagNo)
+ if (tag.hasContextTag(tagNo))
{
- return tag.getObject().toASN1Primitive();
+ return baseTagNo < 0
+ ? tag.getExplicitBaseObject().toASN1Primitive()
+ : tag.getBaseUniversal(true, baseTagNo);
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
index dbef9bd..fe0e278 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
@@ -4,6 +4,7 @@
import java.math.BigInteger;
import java.util.Enumeration;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Integer;
@@ -12,7 +13,6 @@
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DEROctetString;
import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.asn1.DERTaggedObject;
@@ -56,7 +56,7 @@
public ECPrivateKeyStructure(
BigInteger key,
- DERBitString publicKey,
+ ASN1BitString publicKey,
ASN1Encodable parameters)
{
byte[] bytes = BigIntegers.asUnsignedByteArray(key);
@@ -86,9 +86,9 @@
return new BigInteger(1, octs.getOctets());
}
- public DERBitString getPublicKey()
+ public ASN1BitString getPublicKey()
{
- return (DERBitString)getObjectInTag(1);
+ return (ASN1BitString)getObjectInTag(1);
}
public ASN1Primitive getParameters()
@@ -109,7 +109,7 @@
ASN1TaggedObject tag = (ASN1TaggedObject)obj;
if (tag.getTagNo() == tagNo)
{
- return (ASN1Primitive)((ASN1Encodable)tag.getObject()).toASN1Primitive();
+ return (ASN1Primitive)((ASN1Encodable)tag.getExplicitBaseObject()).toASN1Primitive();
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/SECNamedCurves.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/SECNamedCurves.java
index 2c67e25..7d1c56e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/SECNamedCurves.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/SECNamedCurves.java
@@ -50,22 +50,27 @@
*/
static X9ECParametersHolder secp112r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = (2^128 - 3) / 76439
BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
BigInteger a = fromHex("DB7C2ABF62E35E668076BEAD2088");
BigInteger b = fromHex("659EF8BA043916EEDE8911702B22");
- byte[] S = Hex.decodeStrict("00F50B028E4D696E676875615175290472783FB1");
BigInteger n = fromHex("DB7C2ABF62E35E7628DFAC6561C5");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("00F50B028E4D696E676875615175290472783FB1");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -74,22 +79,27 @@
*/
static X9ECParametersHolder secp112r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = (2^128 - 3) / 76439
BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
BigInteger a = fromHex("6127C24C05F38A0AAAF65C0EF02C");
BigInteger b = fromHex("51DEF1815DB5ED74FCC34C85D709");
- byte[] S = Hex.decodeStrict("002757A1114D696E6768756151755316C05E0BD4");
BigInteger n = fromHex("36DF0AAFD8B8D7597CA10520D04B");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("002757A1114D696E6768756151755316C05E0BD4");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -98,22 +108,27 @@
*/
static X9ECParametersHolder secp128r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^128 - 2^97 - 1
BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("E87579C11079F43DD824993C2CEE5ED3");
- byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
BigInteger n = fromHex("FFFFFFFE0000000075A30D1B9038A115");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -122,22 +137,27 @@
*/
static X9ECParametersHolder secp128r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^128 - 2^97 - 1
BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("D6031998D1B3BBFEBF59CC9BBFF9AEE1");
BigInteger b = fromHex("5EEEFCA380D02919DC2C6558BB6D8A5D");
- byte[] S = Hex.decodeStrict("004D696E67687561517512D8F03431FCE63B88F4");
BigInteger n = fromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("004D696E67687561517512D8F03431FCE63B88F4");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -146,13 +166,12 @@
*/
static X9ECParametersHolder secp160k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(7);
- byte[] S = null;
BigInteger n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3");
BigInteger h = BigInteger.valueOf(1);
@@ -170,12 +189,18 @@
new BigInteger("96341f1138933bc2f503fd44", 16),
176));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -184,22 +209,27 @@
*/
static X9ECParametersHolder secp160r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^160 - 2^31 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC");
BigInteger b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45");
- byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
BigInteger n = fromHex("0100000000000000000001F4C8F927AED3CA752257");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -208,22 +238,27 @@
*/
static X9ECParametersHolder secp160r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70");
BigInteger b = fromHex("B4E134D3FB59EB8BAB57274904664D5AF50388BA");
- byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
BigInteger n = fromHex("0100000000000000000000351EE786A818F3A1A16B");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -232,13 +267,12 @@
*/
static X9ECParametersHolder secp192k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(3);
- byte[] S = null;
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D");
BigInteger h = BigInteger.valueOf(1);
@@ -256,12 +290,18 @@
new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
208));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -270,22 +310,27 @@
*/
static X9ECParametersHolder secp192r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^192 - 2^64 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1");
- byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -294,13 +339,12 @@
*/
static X9ECParametersHolder secp224k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(5);
- byte[] S = null;
BigInteger n = fromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
BigInteger h = BigInteger.valueOf(1);
@@ -318,12 +362,18 @@
new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
240));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -332,22 +382,27 @@
*/
static X9ECParametersHolder secp224r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^224 - 2^96 + 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE");
BigInteger b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4");
- byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -356,13 +411,12 @@
*/
static X9ECParametersHolder secp256k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(7);
- byte[] S = null;
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
BigInteger h = BigInteger.valueOf(1);
@@ -380,12 +434,18 @@
new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
272));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -394,22 +454,27 @@
*/
static X9ECParametersHolder secp256r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1
BigInteger p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B");
- byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -418,23 +483,28 @@
*/
static X9ECParametersHolder secp384r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^384 - 2^128 - 2^96 + 2^32 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC");
BigInteger b = fromHex("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF");
- byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -443,23 +513,28 @@
*/
static X9ECParametersHolder secp521r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^521 - 1
BigInteger p = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00");
- byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
+ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -468,23 +543,28 @@
*/
static X9ECParametersHolder sect113r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 113;
int k = 9;
BigInteger a = fromHex("003088250CA6E7C7FE649CE85820F7");
BigInteger b = fromHex("00E8BEE4D3E2260744188BE0E9C723");
- byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
BigInteger n = fromHex("0100000000000000D9CCEC8A39E56F");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -493,23 +573,28 @@
*/
static X9ECParametersHolder sect113r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 113;
int k = 9;
BigInteger a = fromHex("00689918DBEC7E5A0DD6DFC0AA55C7");
BigInteger b = fromHex("0095E9A9EC9B297BD4BF36E059184F");
- byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
BigInteger n = fromHex("010000000000000108789B2496AF93");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -518,7 +603,7 @@
*/
static X9ECParametersHolder sect131r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 131;
int k1 = 2;
@@ -527,16 +612,21 @@
BigInteger a = fromHex("07A11B09A76B562144418FF3FF8C2570B8");
BigInteger b = fromHex("0217C05610884B63B9C6C7291678F9D341");
- byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
BigInteger n = fromHex("0400000000000000023123953A9464B54D");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -545,7 +635,7 @@
*/
static X9ECParametersHolder sect131r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 131;
int k1 = 2;
@@ -554,16 +644,21 @@
BigInteger a = fromHex("03E5A88919D7CAFCBF415F07C2176573B2");
BigInteger b = fromHex("04B8266A46C55657AC734CE38F018F2192");
- byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
BigInteger n = fromHex("0400000000000000016954A233049BA98F");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -572,7 +667,7 @@
*/
static X9ECParametersHolder sect163k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 163;
int k1 = 3;
@@ -581,16 +676,21 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("04000000000000000000020108A2E0CC0D99F8A5EF");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -599,7 +699,7 @@
*/
static X9ECParametersHolder sect163r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 163;
int k1 = 3;
@@ -608,16 +708,21 @@
BigInteger a = fromHex("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2");
BigInteger b = fromHex("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9");
- byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -626,7 +731,7 @@
*/
static X9ECParametersHolder sect163r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 163;
int k1 = 3;
@@ -635,16 +740,21 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("020A601907B8C953CA1481EB10512F78744A3205FD");
- byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
BigInteger n = fromHex("040000000000000000000292FE77E70C12A4234C33");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -653,23 +763,28 @@
*/
static X9ECParametersHolder sect193r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 193;
int k = 15;
BigInteger a = fromHex("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01");
BigInteger b = fromHex("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814");
- byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
BigInteger n = fromHex("01000000000000000000000000C7F34A778F443ACC920EBA49");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -678,23 +793,28 @@
*/
static X9ECParametersHolder sect193r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 193;
int k = 15;
BigInteger a = fromHex("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B");
BigInteger b = fromHex("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE");
- byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
BigInteger n = fromHex("010000000000000000000000015AAB561B005413CCD4EE99D5");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -703,23 +823,28 @@
*/
static X9ECParametersHolder sect233k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 233;
int k = 74;
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -728,23 +853,28 @@
*/
static X9ECParametersHolder sect233r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 233;
int k = 74;
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD");
- byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
BigInteger n = fromHex("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -753,23 +883,28 @@
*/
static X9ECParametersHolder sect239k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 239;
int k = 158;
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -778,7 +913,7 @@
*/
static X9ECParametersHolder sect283k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 283;
int k1 = 5;
@@ -787,17 +922,22 @@
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
+ "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -806,7 +946,7 @@
*/
static X9ECParametersHolder sect283r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 283;
int k1 = 5;
@@ -815,17 +955,22 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5");
- byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
+ "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -834,24 +979,29 @@
*/
static X9ECParametersHolder sect409k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 409;
int k = 87;
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
+ "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -860,24 +1010,29 @@
*/
static X9ECParametersHolder sect409r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 409;
int k = 87;
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F");
- byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
BigInteger n = fromHex("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
+ "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -886,7 +1041,7 @@
*/
static X9ECParametersHolder sect571k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 571;
int k1 = 2;
@@ -895,17 +1050,22 @@
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
+ "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -914,7 +1074,7 @@
*/
static X9ECParametersHolder sect571r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 571;
int k1 = 2;
@@ -923,17 +1083,22 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A");
- byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
+ "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -987,26 +1152,35 @@
defineCurve("sect571r1", SECObjectIdentifiers.sect571r1, sect571r1);
}
- public static X9ECParameters getByName(
- String name)
+ public static X9ECParameters getByName(String name)
{
ASN1ObjectIdentifier oid = getOID(name);
return oid == null ? null : getByOID(oid);
}
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOIDLazy(oid);
+ }
+
/**
* return the X9ECParameters object for the named curve represented by
* the passed in object identifier. Null if the curve isn't present.
*
* @param oid an object identifier representing a named curve, if present.
*/
- public static X9ECParameters getByOID(
- ASN1ObjectIdentifier oid)
+ public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid);
+ X9ECParametersHolder holder = getByOIDLazy(oid);
return holder == null ? null : holder.getParameters();
}
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return (X9ECParametersHolder)curves.get(oid);
+ }
+
/**
* return the object identifier signified by the passed in name. Null
* if there is no object identifier associated with name.
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/util/ASN1Dump.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/util/ASN1Dump.java
index 91fd01f..9ddf89a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/util/ASN1Dump.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/util/ASN1Dump.java
@@ -1,43 +1,42 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.util;
-import java.io.IOException;
-import java.util.Enumeration;
-
-import com.android.org.bouncycastle.asn1.ASN1ApplicationSpecific;
+import com.android.org.bouncycastle.asn1.ASN1BMPString;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Boolean;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Enumerated;
import com.android.org.bouncycastle.asn1.ASN1External;
import com.android.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.org.bouncycastle.asn1.ASN1GraphicString;
+import com.android.org.bouncycastle.asn1.ASN1IA5String;
import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Null;
+import com.android.org.bouncycastle.asn1.ASN1NumericString;
+import com.android.org.bouncycastle.asn1.ASN1ObjectDescriptor;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1PrintableString;
+import com.android.org.bouncycastle.asn1.ASN1RelativeOID;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1Set;
+import com.android.org.bouncycastle.asn1.ASN1T61String;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.org.bouncycastle.asn1.ASN1UTCTime;
-import com.android.org.bouncycastle.asn1.BERApplicationSpecific;
+import com.android.org.bouncycastle.asn1.ASN1UTF8String;
+import com.android.org.bouncycastle.asn1.ASN1Util;
+import com.android.org.bouncycastle.asn1.ASN1VideotexString;
+import com.android.org.bouncycastle.asn1.ASN1VisibleString;
import com.android.org.bouncycastle.asn1.BEROctetString;
import com.android.org.bouncycastle.asn1.BERSequence;
import com.android.org.bouncycastle.asn1.BERSet;
import com.android.org.bouncycastle.asn1.BERTaggedObject;
-import com.android.org.bouncycastle.asn1.BERTags;
-import com.android.org.bouncycastle.asn1.DERApplicationSpecific;
-import com.android.org.bouncycastle.asn1.DERBMPString;
import com.android.org.bouncycastle.asn1.DERBitString;
-import com.android.org.bouncycastle.asn1.DERGraphicString;
-import com.android.org.bouncycastle.asn1.DERIA5String;
-import com.android.org.bouncycastle.asn1.DERNull;
-import com.android.org.bouncycastle.asn1.DERPrintableString;
import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.asn1.DERSet;
-import com.android.org.bouncycastle.asn1.DERT61String;
-import com.android.org.bouncycastle.asn1.DERUTF8String;
-import com.android.org.bouncycastle.asn1.DERVideotexString;
-import com.android.org.bouncycastle.asn1.DERVisibleString;
-import com.android.org.bouncycastle.asn1.DLApplicationSpecific;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.org.bouncycastle.asn1.DLBitString;
import com.android.org.bouncycastle.util.Strings;
import com.android.org.bouncycastle.util.encoders.Hex;
@@ -62,11 +61,14 @@
StringBuffer buf)
{
String nl = Strings.lineSeparator();
- if (obj instanceof ASN1Sequence)
+ if (obj instanceof ASN1Null)
{
- Enumeration e = ((ASN1Sequence)obj).getObjects();
- String tab = indent + TAB;
-
+ buf.append(indent);
+ buf.append("NULL");
+ buf.append(nl);
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
buf.append(indent);
if (obj instanceof BERSequence)
{
@@ -80,64 +82,19 @@
{
buf.append("Sequence");
}
-
buf.append(nl);
- while (e.hasMoreElements())
+ ASN1Sequence sequence = (ASN1Sequence)obj;
+ String elementsIndent = indent + TAB;
+
+ for (int i = 0, count = sequence.size(); i < count; ++i)
{
- Object o = e.nextElement();
-
- if (o == null || o.equals(DERNull.INSTANCE))
- {
- 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);
- }
+ _dumpAsString(elementsIndent, verbose, sequence.getObjectAt(i).toASN1Primitive(), buf);
}
}
- else if (obj instanceof ASN1TaggedObject)
- {
- String tab = indent + TAB;
-
- buf.append(indent);
- if (obj instanceof BERTaggedObject)
- {
- buf.append("BER Tagged [");
- }
- else
- {
- buf.append("Tagged [");
- }
-
- ASN1TaggedObject o = (ASN1TaggedObject)obj;
-
- buf.append(Integer.toString(o.getTagNo()));
- buf.append(']');
-
- if (!o.isExplicit())
- {
- buf.append(" IMPLICIT ");
- }
-
- buf.append(nl);
-
- _dumpAsString(tab, verbose, o.getObject(), buf);
- }
else if (obj instanceof ASN1Set)
{
- Enumeration e = ((ASN1Set)obj).getObjects();
- String tab = indent + TAB;
-
buf.append(indent);
-
if (obj instanceof BERSet)
{
buf.append("BER Set");
@@ -152,26 +109,45 @@
}
buf.append(nl);
- while (e.hasMoreElements())
- {
- Object o = e.nextElement();
+ ASN1Set set = (ASN1Set)obj;
+ String elementsIndent = indent + TAB;
- 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);
- }
+ for (int i = 0, count = set.size(); i < count; ++i)
+ {
+ _dumpAsString(elementsIndent, verbose, set.getObjectAt(i).toASN1Primitive(), buf);
}
}
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ buf.append(indent);
+ if (obj instanceof BERTaggedObject)
+ {
+ buf.append("BER Tagged ");
+ }
+ else if (obj instanceof DERTaggedObject)
+ {
+ buf.append("DER Tagged ");
+ }
+ else
+ {
+ buf.append("Tagged ");
+ }
+
+ ASN1TaggedObject o = (ASN1TaggedObject)obj;
+
+ buf.append(ASN1Util.getTagText(o));
+
+ if (!o.isExplicit())
+ {
+ buf.append(" IMPLICIT ");
+ }
+
+ buf.append(nl);
+
+ String baseIndent = indent + TAB;
+
+ _dumpAsString(baseIndent, verbose, o.getBaseObject().toASN1Primitive(), buf);
+ }
else if (obj instanceof ASN1OctetString)
{
ASN1OctetString oct = (ASN1OctetString)obj;
@@ -197,6 +173,10 @@
{
buf.append(indent + "ObjectIdentifier(" + ((ASN1ObjectIdentifier)obj).getId() + ")" + nl);
}
+ else if (obj instanceof ASN1RelativeOID)
+ {
+ buf.append(indent + "RelativeOID(" + ((ASN1RelativeOID)obj).getId() + ")" + nl);
+ }
else if (obj instanceof ASN1Boolean)
{
buf.append(indent + "Boolean(" + ((ASN1Boolean)obj).isTrue() + ")" + nl);
@@ -205,50 +185,70 @@
{
buf.append(indent + "Integer(" + ((ASN1Integer)obj).getValue() + ")" + nl);
}
- else if (obj instanceof DERBitString)
+ else if (obj instanceof ASN1BitString)
{
- DERBitString bt = (DERBitString)obj;
- buf.append(indent + "DER Bit String" + "[" + bt.getBytes().length + ", " + bt.getPadBits() + "] ");
+ ASN1BitString bitString = (ASN1BitString)obj;
+
+ byte[] bytes = bitString.getBytes();
+ int padBits = bitString.getPadBits();
+
+ if (bitString instanceof DERBitString)
+ {
+ buf.append(indent + "DER Bit String" + "[" + bytes.length + ", " + padBits + "] ");
+ }
+ else if (bitString instanceof DLBitString)
+ {
+ buf.append(indent + "DL Bit String" + "[" + bytes.length + ", " + padBits + "] ");
+ }
+ else
+ {
+ buf.append(indent + "BER Bit String" + "[" + bytes.length + ", " + padBits + "] ");
+ }
+
if (verbose)
{
- buf.append(dumpBinaryDataAsString(indent, bt.getBytes()));
+ buf.append(dumpBinaryDataAsString(indent, bytes));
}
else
{
buf.append(nl);
}
}
- else if (obj instanceof DERIA5String)
+ else if (obj instanceof ASN1IA5String)
{
- buf.append(indent + "IA5String(" + ((DERIA5String)obj).getString() + ") " + nl);
+ buf.append(indent + "IA5String(" + ((ASN1IA5String)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERUTF8String)
+ else if (obj instanceof ASN1UTF8String)
{
- buf.append(indent + "UTF8String(" + ((DERUTF8String)obj).getString() + ") " + nl);
+ buf.append(indent + "UTF8String(" + ((ASN1UTF8String)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERPrintableString)
+ else if (obj instanceof ASN1NumericString)
{
- buf.append(indent + "PrintableString(" + ((DERPrintableString)obj).getString() + ") " + nl);
+ buf.append(indent + "NumericString(" + ((ASN1NumericString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERVisibleString)
+ else if (obj instanceof ASN1PrintableString)
{
- buf.append(indent + "VisibleString(" + ((DERVisibleString)obj).getString() + ") " + nl);
+ buf.append(indent + "PrintableString(" + ((ASN1PrintableString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERBMPString)
+ else if (obj instanceof ASN1VisibleString)
{
- buf.append(indent + "BMPString(" + ((DERBMPString)obj).getString() + ") " + nl);
+ buf.append(indent + "VisibleString(" + ((ASN1VisibleString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERT61String)
+ else if (obj instanceof ASN1BMPString)
{
- buf.append(indent + "T61String(" + ((DERT61String)obj).getString() + ") " + nl);
+ buf.append(indent + "BMPString(" + ((ASN1BMPString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERGraphicString)
+ else if (obj instanceof ASN1T61String)
{
- buf.append(indent + "GraphicString(" + ((DERGraphicString)obj).getString() + ") " + nl);
+ buf.append(indent + "T61String(" + ((ASN1T61String)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERVideotexString)
+ else if (obj instanceof ASN1GraphicString)
{
- buf.append(indent + "VideotexString(" + ((DERVideotexString)obj).getString() + ") " + nl);
+ buf.append(indent + "GraphicString(" + ((ASN1GraphicString)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof ASN1VideotexString)
+ {
+ buf.append(indent + "VideotexString(" + ((ASN1VideotexString)obj).getString() + ") " + nl);
}
else if (obj instanceof ASN1UTCTime)
{
@@ -258,23 +258,16 @@
{
buf.append(indent + "GeneralizedTime(" + ((ASN1GeneralizedTime)obj).getTime() + ") " + nl);
}
- else if (obj instanceof BERApplicationSpecific)
- {
- buf.append(outputApplicationSpecific("BER", indent, verbose, obj, nl));
- }
- else if (obj instanceof DERApplicationSpecific)
- {
- buf.append(outputApplicationSpecific("DER", indent, verbose, obj, nl));
- }
- else if (obj instanceof DLApplicationSpecific)
- {
- buf.append(outputApplicationSpecific("", indent, verbose, obj, nl));
- }
else if (obj instanceof ASN1Enumerated)
{
ASN1Enumerated en = (ASN1Enumerated) obj;
buf.append(indent + "DER Enumerated(" + en.getValue() + ")" + nl);
}
+ else if (obj instanceof ASN1ObjectDescriptor)
+ {
+ ASN1ObjectDescriptor od = (ASN1ObjectDescriptor)obj;
+ buf.append(indent + "ObjectDescriptor(" + od.getBaseGraphicString().getString() + ") " + nl);
+ }
else if (obj instanceof ASN1External)
{
ASN1External ext = (ASN1External) obj;
@@ -300,32 +293,6 @@
buf.append(indent + obj.toString() + nl);
}
}
-
- private static String outputApplicationSpecific(String type, String indent, boolean verbose, ASN1Primitive obj, String nl)
- {
- ASN1ApplicationSpecific app = ASN1ApplicationSpecific.getInstance(obj);
- StringBuffer buf = new StringBuffer();
-
- if (app.isConstructed())
- {
- try
- {
- ASN1Sequence s = ASN1Sequence.getInstance(app.getObject(BERTags.SEQUENCE));
- buf.append(indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "]" + nl);
- for (Enumeration e = s.getObjects(); e.hasMoreElements();)
- {
- _dumpAsString(indent + TAB, verbose, (ASN1Primitive)e.nextElement(), buf);
- }
- }
- catch (IOException e)
- {
- buf.append(e);
- }
- return buf.toString();
- }
-
- return indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "] (" + Strings.fromByteArray(Hex.encode(app.getContents())) + ")" + nl;
- }
/**
* dump out a DER object as a formatted string, in non-verbose mode.
@@ -350,21 +317,22 @@
Object obj,
boolean verbose)
{
- StringBuffer buf = new StringBuffer();
-
+ ASN1Primitive primitive;
if (obj instanceof ASN1Primitive)
{
- _dumpAsString("", verbose, (ASN1Primitive)obj, buf);
+ primitive = (ASN1Primitive)obj;
}
else if (obj instanceof ASN1Encodable)
{
- _dumpAsString("", verbose, ((ASN1Encodable)obj).toASN1Primitive(), buf);
+ primitive = ((ASN1Encodable)obj).toASN1Primitive();
}
else
{
return "unknown object type " + obj.toString();
}
+ StringBuffer buf = new StringBuffer();
+ _dumpAsString("", verbose, primitive, buf);
return buf.toString();
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/DirectoryString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/DirectoryString.java
index 568a09b..91b09dc 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/DirectoryString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/DirectoryString.java
@@ -1,17 +1,18 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x500;
+import com.android.org.bouncycastle.asn1.ASN1BMPString;
import com.android.org.bouncycastle.asn1.ASN1Choice;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1PrintableString;
import com.android.org.bouncycastle.asn1.ASN1String;
+import com.android.org.bouncycastle.asn1.ASN1T61String;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.org.bouncycastle.asn1.DERBMPString;
-import com.android.org.bouncycastle.asn1.DERPrintableString;
-import com.android.org.bouncycastle.asn1.DERT61String;
+import com.android.org.bouncycastle.asn1.ASN1UTF8String;
+import com.android.org.bouncycastle.asn1.ASN1UniversalString;
import com.android.org.bouncycastle.asn1.DERUTF8String;
-import com.android.org.bouncycastle.asn1.DERUniversalString;
/**
* The DirectoryString CHOICE object.
@@ -30,29 +31,29 @@
return (DirectoryString)o;
}
- if (o instanceof DERT61String)
+ if (o instanceof ASN1T61String)
{
- return new DirectoryString((DERT61String)o);
+ return new DirectoryString((ASN1T61String)o);
}
- if (o instanceof DERPrintableString)
+ if (o instanceof ASN1PrintableString)
{
- return new DirectoryString((DERPrintableString)o);
+ return new DirectoryString((ASN1PrintableString)o);
}
- if (o instanceof DERUniversalString)
+ if (o instanceof ASN1UniversalString)
{
- return new DirectoryString((DERUniversalString)o);
+ return new DirectoryString((ASN1UniversalString)o);
}
- if (o instanceof DERUTF8String)
+ if (o instanceof ASN1UTF8String)
{
- return new DirectoryString((DERUTF8String)o);
+ return new DirectoryString((ASN1UTF8String)o);
}
- if (o instanceof DERBMPString)
+ if (o instanceof ASN1BMPString)
{
- return new DirectoryString((DERBMPString)o);
+ return new DirectoryString((ASN1BMPString)o);
}
throw new IllegalArgumentException("illegal object in getInstance: " + o.getClass().getName());
@@ -65,35 +66,35 @@
throw new IllegalArgumentException("choice item must be explicitly tagged");
}
- return getInstance(o.getObject());
+ return getInstance(o.getExplicitBaseObject());
}
private DirectoryString(
- DERT61String string)
+ ASN1T61String string)
{
this.string = string;
}
private DirectoryString(
- DERPrintableString string)
+ ASN1PrintableString string)
{
this.string = string;
}
private DirectoryString(
- DERUniversalString string)
+ ASN1UniversalString string)
{
this.string = string;
}
private DirectoryString(
- DERUTF8String string)
+ ASN1UTF8String string)
{
this.string = string;
}
private DirectoryString(
- DERBMPString string)
+ ASN1BMPString string)
{
this.string = string;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/RDN.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/RDN.java
index 853c9ed..676b80c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/RDN.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/RDN.java
@@ -2,12 +2,11 @@
package com.android.org.bouncycastle.asn1.x500;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
-import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Set;
-import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.org.bouncycastle.asn1.DERSet;
/**
@@ -21,6 +20,7 @@
private RDN(ASN1Set values)
{
+ // TODO Require minimum size of 1?
this.values = values;
}
@@ -38,6 +38,11 @@
return null;
}
+ public static RDN getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
+ {
+ return new RDN(ASN1Set.getInstance(taggedObject, declaredExplicit));
+ }
+
/**
* Create a single valued RDN.
*
@@ -46,12 +51,7 @@
*/
public RDN(ASN1ObjectIdentifier oid, ASN1Encodable value)
{
- ASN1EncodableVector v = new ASN1EncodableVector(2);
-
- v.add(oid);
- v.add(value);
-
- this.values = new DERSet(new DERSequence(v));
+ this(new AttributeTypeAndValue(oid, value));
}
public RDN(AttributeTypeAndValue attrTAndV)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/X500Name.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/X500Name.java
index 3f54005..067a461 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/X500Name.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/X500Name.java
@@ -1,8 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x500;
-import java.util.Enumeration;
-
import com.android.org.bouncycastle.asn1.ASN1Choice;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Object;
@@ -113,18 +111,18 @@
X500NameStyle style,
ASN1Sequence seq)
{
+ int count = seq.size();
+
this.style = style;
- this.rdns = new RDN[seq.size()];
+ this.rdns = new RDN[count];
boolean inPlace = true;
-
- int index = 0;
- for (Enumeration e = seq.getObjects(); e.hasMoreElements();)
+ for (int index = 0; index < count; ++index)
{
- Object element = e.nextElement();
+ ASN1Encodable element = seq.getObjectAt(index);
RDN rdn = RDN.getInstance(element);
inPlace &= (rdn == element);
- rdns[index++] = rdn;
+ rdns[index] = rdn;
}
if (inPlace)
@@ -231,6 +229,11 @@
return res;
}
+ public int size()
+ {
+ return rdns.length;
+ }
+
public ASN1Primitive toASN1Primitive()
{
return rdnSeq;
@@ -267,14 +270,14 @@
ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive();
- if (this.toASN1Primitive().equals(derO))
+ if (toASN1Primitive().equals(derO))
{
return true;
}
try
{
- return style.areEqual(this, new X500Name(ASN1Sequence.getInstance(((ASN1Encodable)obj).toASN1Primitive())));
+ return style.areEqual(this, getInstance(obj));
}
catch (Exception e)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
index 083bff9..1f730da 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
@@ -133,19 +133,22 @@
public boolean areEqual(X500Name name1, X500Name name2)
{
- RDN[] rdns1 = name1.getRDNs();
- RDN[] rdns2 = name2.getRDNs();
-
- if (rdns1.length != rdns2.length)
+ if (name1.size() != name2.size())
{
return false;
}
+ RDN[] rdns1 = name1.getRDNs();
+ RDN[] rdns2 = name2.getRDNs();
+
boolean reverse = false;
- if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null)
+ AttributeTypeAndValue first1 = rdns1[0].getFirst();
+ AttributeTypeAndValue first2 = rdns2[0].getFirst();
+
+ if (first1 != null && first2 != null)
{
- reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType()); // guess forward
+ reverse = !first1.getType().equals(first2.getType()); // guess forward
}
for (int i = 0; i != rdns1.length; i++)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStrictStyle.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStrictStyle.java
index be5c761..899d699 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStrictStyle.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStrictStyle.java
@@ -17,14 +17,14 @@
public boolean areEqual(X500Name name1, X500Name name2)
{
- RDN[] rdns1 = name1.getRDNs();
- RDN[] rdns2 = name2.getRDNs();
-
- if (rdns1.length != rdns2.length)
+ if (name1.size() != name2.size())
{
return false;
}
+ RDN[] rdns1 = name1.getRDNs();
+ RDN[] rdns2 = name2.getRDNs();
+
for (int i = 0; i != rdns1.length; i++)
{
if (!rdnAreEqual(rdns1[i], rdns2[i]))
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStyle.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStyle.java
index a55bc29..953a410 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStyle.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStyle.java
@@ -293,9 +293,9 @@
defaultLookUp = copyHashTable(DefaultLookUp);
}
- protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid,
- String value) {
- if (oid.equals(EmailAddress) || oid.equals(DC))
+ protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, String value)
+ {
+ if (oid.equals(EmailAddress) || oid.equals(DC))
{
return new DERIA5String(value);
}
@@ -303,18 +303,18 @@
{
return new ASN1GeneralizedTime(value);
}
- else if (oid.equals(C) || oid.equals(SN) || oid.equals(DN_QUALIFIER)
+ else if (oid.equals(C) || oid.equals(SERIALNUMBER) || oid.equals(DN_QUALIFIER)
|| oid.equals(TELEPHONE_NUMBER))
{
return new DERPrintableString(value);
}
-
- return super.encodeStringValue(oid, value);
+
+ return super.encodeStringValue(oid, value);
}
public String oidToDisplayName(ASN1ObjectIdentifier oid)
{
- return (String)DefaultSymbols.get(oid);
+ return (String)defaultSymbols.get(oid);
}
public String[] oidToAttrNames(ASN1ObjectIdentifier oid)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/IETFUtils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/IETFUtils.java
index 38a82a8..817753d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/IETFUtils.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/IETFUtils.java
@@ -11,7 +11,7 @@
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1String;
-import com.android.org.bouncycastle.asn1.DERUniversalString;
+import com.android.org.bouncycastle.asn1.ASN1UniversalString;
import com.android.org.bouncycastle.asn1.x500.AttributeTypeAndValue;
import com.android.org.bouncycastle.asn1.x500.RDN;
import com.android.org.bouncycastle.asn1.x500.X500NameBuilder;
@@ -26,12 +26,15 @@
{
private static String unescape(String elt)
{
- if (elt.length() == 0 || (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0))
+ if (elt.length() == 0)
+ {
+ return elt;
+ }
+ if (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0)
{
return elt.trim();
}
- char[] elts = elt.toCharArray();
boolean escaped = false;
boolean quoted = false;
StringBuffer buf = new StringBuffer(elt.length());
@@ -39,9 +42,9 @@
// if it's an escaped hash string and not an actual encoding in string form
// we need to leave it escaped.
- if (elts[0] == '\\')
+ if (elt.charAt(0) == '\\')
{
- if (elts[1] == '#')
+ if (elt.charAt(1) == '#')
{
start = 2;
buf.append("\\#");
@@ -52,9 +55,9 @@
int lastEscaped = 0;
char hex1 = 0;
- for (int i = start; i != elts.length; i++)
+ for (int i = start; i != elt.length(); i++)
{
- char c = elts[i];
+ char c = elt.charAt(i);
if (c != ' ')
{
@@ -70,8 +73,8 @@
else
{
buf.append(c);
+ escaped = false;
}
- escaped = false;
}
else if (c == '\\' && !(escaped || quoted))
{
@@ -132,81 +135,93 @@
public static RDN[] rDNsFromString(String name, X500NameStyle x500Style)
{
- X500NameTokenizer nTok = new X500NameTokenizer(name);
+ X500NameTokenizer tokenizer = new X500NameTokenizer(name);
X500NameBuilder builder = new X500NameBuilder(x500Style);
- while (nTok.hasMoreTokens())
+ addRDNs(x500Style, builder, tokenizer);
+
+ // TODO There's an unnecessary clone of the RDNs array happening here
+ return builder.build().getRDNs();
+ }
+
+ private static void addRDNs(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer)
+ {
+ String token;
+ while ((token = tokenizer.nextToken()) != null)
{
- String token = nTok.nextToken();
-
- if (token.indexOf('+') > 0)
+ if (token.indexOf('+') >= 0)
{
- X500NameTokenizer pTok = new X500NameTokenizer(token, '+');
- X500NameTokenizer vTok = new X500NameTokenizer(pTok.nextToken(), '=');
-
- String attr = vTok.nextToken();
-
- if (!vTok.hasMoreTokens())
- {
- throw new IllegalArgumentException("badly formatted directory string");
- }
-
- String value = vTok.nextToken();
- ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim());
-
- if (pTok.hasMoreTokens())
- {
- Vector oids = new Vector();
- Vector values = new Vector();
-
- oids.addElement(oid);
- values.addElement(unescape(value));
-
- while (pTok.hasMoreTokens())
- {
- vTok = new X500NameTokenizer(pTok.nextToken(), '=');
-
- attr = vTok.nextToken();
-
- if (!vTok.hasMoreTokens())
- {
- throw new IllegalArgumentException("badly formatted directory string");
- }
-
- value = vTok.nextToken();
- oid = x500Style.attrNameToOID(attr.trim());
-
-
- oids.addElement(oid);
- values.addElement(unescape(value));
- }
-
- builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values));
- }
- else
- {
- builder.addRDN(oid, unescape(value));
- }
+ addMultiValuedRDN(style, builder, new X500NameTokenizer(token, '+'));
}
else
{
- X500NameTokenizer vTok = new X500NameTokenizer(token, '=');
-
- String attr = vTok.nextToken();
-
- if (!vTok.hasMoreTokens())
- {
- throw new IllegalArgumentException("badly formatted directory string");
- }
-
- String value = vTok.nextToken();
- ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim());
-
- builder.addRDN(oid, unescape(value));
+ addRDN(style, builder, token);
}
}
+ }
- return builder.build().getRDNs();
+ private static void addMultiValuedRDN(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer)
+ {
+ String token = tokenizer.nextToken();
+ if (token == null)
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
+
+ if (!tokenizer.hasMoreTokens())
+ {
+ addRDN(style, builder, token);
+ return;
+ }
+
+ Vector oids = new Vector();
+ Vector values = new Vector();
+
+ do
+ {
+ collectAttributeTypeAndValue(style, oids, values, token);
+ token = tokenizer.nextToken();
+ }
+ while (token != null);
+
+ builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values));
+ }
+
+ private static void addRDN(X500NameStyle style, X500NameBuilder builder, String token)
+ {
+ X500NameTokenizer tokenizer = new X500NameTokenizer(token, '=');
+
+ String typeToken = nextToken(tokenizer, true);
+ String valueToken = nextToken(tokenizer, false);
+
+ ASN1ObjectIdentifier oid = style.attrNameToOID(typeToken.trim());
+ String value = unescape(valueToken);
+
+ builder.addRDN(oid, value);
+ }
+
+ private static void collectAttributeTypeAndValue(X500NameStyle style, Vector oids, Vector values, String token)
+ {
+ X500NameTokenizer tokenizer = new X500NameTokenizer(token, '=');
+
+ String typeToken = nextToken(tokenizer, true);
+ String valueToken = nextToken(tokenizer, false);
+
+ ASN1ObjectIdentifier oid = style.attrNameToOID(typeToken.trim());
+ String value = unescape(valueToken);
+
+ oids.addElement(oid);
+ values.addElement(value);
+ }
+
+ private static String nextToken(X500NameTokenizer tokenizer, boolean expectMoreTokens)
+ {
+ String token = tokenizer.nextToken();
+ if (token == null || tokenizer.hasMoreTokens() != expectMoreTokens)
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
+ return token;
}
private static String[] toValueArray(Vector values)
@@ -358,7 +373,7 @@
{
StringBuffer vBuf = new StringBuffer();
- if (value instanceof ASN1String && !(value instanceof DERUniversalString))
+ if (value instanceof ASN1String && !(value instanceof ASN1UniversalString))
{
String v = ((ASN1String)value).getString();
if (v.length() > 0 && v.charAt(0) == '#')
@@ -373,6 +388,7 @@
try
{
vBuf.append('#');
+ // -DM Hex.toHexString
vBuf.append(Hex.toHexString(value.toASN1Primitive().getEncoded(ASN1Encoding.DER)));
}
catch (IOException e)
@@ -427,7 +443,7 @@
int endBuf = vBuf.length() - 1;
- while (endBuf >= 0 && vBuf.charAt(endBuf) == ' ')
+ while (endBuf >= start && vBuf.charAt(endBuf) == ' ')
{
vBuf.insert(endBuf, '\\');
endBuf--;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/RFC4519Style.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/RFC4519Style.java
index 0499180..21381cd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/RFC4519Style.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/RFC4519Style.java
@@ -15,7 +15,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class RFC4519Style
- extends AbstractX500NameStyle
+ extends AbstractX500NameStyle
{
public static final ASN1ObjectIdentifier businessCategory = new ASN1ObjectIdentifier("2.5.4.15").intern();
public static final ASN1ObjectIdentifier c = new ASN1ObjectIdentifier("2.5.4.6").intern();
@@ -179,9 +179,9 @@
defaultLookUp = copyHashTable(DefaultLookUp);
}
- protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid,
- String value) {
- if (oid.equals(dc))
+ protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, String value)
+ {
+ if (oid.equals(dc))
{
return new DERIA5String(value);
}
@@ -191,12 +191,12 @@
return new DERPrintableString(value);
}
- return super.encodeStringValue(oid, value);
+ return super.encodeStringValue(oid, value);
}
public String oidToDisplayName(ASN1ObjectIdentifier oid)
{
- return (String)DefaultSymbols.get(oid);
+ return (String)defaultSymbols.get(oid);
}
public String[] oidToAttrNames(ASN1ObjectIdentifier oid)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java
index 3f08dad..27ae360 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java
@@ -10,83 +10,78 @@
*/
public class X500NameTokenizer
{
- private String value;
- private int index;
- private char separator;
- private StringBuffer buf = new StringBuffer();
+ private final String value;
+ private final char separator;
- public X500NameTokenizer(
- String oid)
+ private int index;
+
+ public X500NameTokenizer(String oid)
{
this(oid, ',');
}
-
- public X500NameTokenizer(
- String oid,
- char separator)
+
+ public X500NameTokenizer(String oid, char separator)
{
+ if (oid == null)
+ {
+ throw new NullPointerException();
+ }
+ if (separator == '"' || separator == '\\')
+ {
+ throw new IllegalArgumentException("reserved separator character");
+ }
+
this.value = oid;
- this.index = -1;
this.separator = separator;
+ this.index = oid.length() < 1 ? 0 : -1;
}
public boolean hasMoreTokens()
{
- return (index != value.length());
+ return index < value.length();
}
public String nextToken()
{
- if (index == value.length())
+ if (index >= value.length())
{
return null;
}
- int end = index + 1;
boolean quoted = false;
boolean escaped = false;
- buf.setLength(0);
-
- while (end != value.length())
+ int beginIndex = index + 1;
+ while (++index < value.length())
{
- char c = value.charAt(end);
+ char c = value.charAt(index);
- if (c == '"')
+ if (escaped)
{
- if (!escaped)
- {
- quoted = !quoted;
- }
- buf.append(c);
escaped = false;
}
- else
+ else if (c == '"')
{
- if (escaped || quoted)
- {
- buf.append(c);
- escaped = false;
- }
- else if (c == '\\')
- {
- buf.append(c);
- escaped = true;
- }
- else if (c == separator)
- {
- break;
- }
- else
- {
- buf.append(c);
- }
+ quoted = !quoted;
}
- end++;
+ else if (quoted)
+ {
+ }
+ else if (c == '\\')
+ {
+ escaped = true;
+ }
+ else if (c == separator)
+ {
+ return value.substring(beginIndex, index);
+ }
}
- index = end;
+ if (escaped || quoted)
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
- return buf.toString();
+ return value.substring(beginIndex, index);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AltSignatureAlgorithm.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AltSignatureAlgorithm.java
new file mode 100644
index 0000000..6f46b48
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AltSignatureAlgorithm.java
@@ -0,0 +1,96 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.x509;
+
+import com.android.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+
+/**
+ * X.509 Section 9.8.3.
+ * <br/>
+ * This extension may be used as a public-key certificate extension, a CRL extension or an AVL extension. It shall contain
+ * the algorithm identifier for the alternative digital signature algorithm used by the signer when creating an alternative
+ * digital signature and by the relying party when validating the alternative digital signature.
+ * <pre>
+ * altSignatureAlgorithm EXTENSION ::= {
+ * SYNTAX AltSignatureAlgorithm
+ * IDENTIFIED BY id-ce-altSignatureAlgorithm }
+ *
+ * AltSignatureAlgorithm ::= AlgorithmIdentifier{{SupportedAlgorithms}}
+ * </pre>
+ * When the altSignatureAlgorithm extension is included in a particular value that is an instance of a data type that
+ * supports extensions, the altSignatureValue extension shall also be included.
+ * <br/>
+ * NOTE 1 – By having a separate altSignatureAlgorithm extension, instead of having it combined with the
+ * altSignatureValue extension, the alternative digital signature algorithm is protected by the alternative signature.
+ * This extension may be flagged either as critical or as non-critical.
+ * <br/>
+ * NOTE 2 – It is recommended that it be flagged as non-critical. Flagging it as critical would require all relying parties to understand
+ * the extension and the alternative public-key algorithms
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AltSignatureAlgorithm
+ extends ASN1Object
+{
+ private final AlgorithmIdentifier algorithm;
+
+ public static AltSignatureAlgorithm getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(AlgorithmIdentifier.getInstance(obj, explicit));
+ }
+
+ public static AltSignatureAlgorithm getInstance(
+ Object obj)
+ {
+ if (obj instanceof AltSignatureAlgorithm)
+ {
+ return (AltSignatureAlgorithm)obj;
+ }
+ else if (obj != null)
+ {
+ return new AltSignatureAlgorithm(AlgorithmIdentifier.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static AltSignatureAlgorithm fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.altSignatureAlgorithm));
+ }
+
+ public AltSignatureAlgorithm(AlgorithmIdentifier algorithm)
+ {
+ this.algorithm = algorithm;
+ }
+
+ public AltSignatureAlgorithm(ASN1ObjectIdentifier algorithm)
+ {
+ this(algorithm, null);
+ }
+
+ public AltSignatureAlgorithm(ASN1ObjectIdentifier algorithm, ASN1Encodable parameters)
+ {
+ this.algorithm = new AlgorithmIdentifier(algorithm, parameters);
+ }
+
+ /**
+ * Return the algorithm identifier representing the alternate signature algorithm
+ * used to generate the alternate signature algorithm value extension.
+ *
+ * @return alternate signature algorithm identifier.
+ */
+ public AlgorithmIdentifier getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return algorithm.toASN1Primitive();
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AltSignatureValue.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AltSignatureValue.java
new file mode 100644
index 0000000..46c307c
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AltSignatureValue.java
@@ -0,0 +1,96 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.x509;
+
+import com.android.org.bouncycastle.asn1.ASN1BitString;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERBitString;
+
+/**
+ * X.509 Section 9.8.4.
+ * <br/>
+ * This extension may be used as a public-key certificate extension, a CRL extension or an AVL extension.
+ * This alternative signature shall be created by the issuer using its alternative private key, and it shall be verified using the
+ * alternative public key of the issuer.
+ * <pre>
+ * altSignatureValue EXTENSION ::= {
+ * SYNTAX AltSignatureValue
+ * IDENTIFIED BY id-ce-altSignatureValue }
+ *
+ * AltSignatureValue ::= BIT STRING
+ * </pre>
+ * This extension can only be created by a signer holding a multiple cryptographic algorithms public-key certificate. When
+ * creating the alternative digital signature on an issued public-key certificate or CRL, the signer shall use its alternative
+ * private key.
+ * <br/>
+ * The procedures for creating and validating alternative digital signatures are specified in:
+ * <ul>
+ * <li>clause 7.2.2 for public-key certificates;</li>
+ * <li>clause 7.10.3 for CRLs: and</li>
+ * <li>clause 11.4 for AVLs.</li>
+ * </ul>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AltSignatureValue
+ extends ASN1Object
+{
+ private final ASN1BitString signature;
+
+ public static AltSignatureValue getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1BitString.getInstance(obj, explicit));
+ }
+
+ public static AltSignatureValue getInstance(
+ Object obj)
+ {
+ if (obj instanceof AltSignatureValue)
+ {
+ return (AltSignatureValue)obj;
+ }
+ else if (obj != null)
+ {
+ return new AltSignatureValue(ASN1BitString.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static AltSignatureValue fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.altSignatureValue));
+ }
+
+ private AltSignatureValue(ASN1BitString signature)
+ {
+ this.signature = signature;
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param signature a signature value, based on the enclosing certificate.
+ */
+ public AltSignatureValue(byte[] signature)
+ {
+ this.signature = new DERBitString(signature);
+ }
+
+ /**
+ * Return the alternate signature to verify the certificate.
+ *
+ * @return certificate's alternate signature.
+ */
+ public ASN1BitString getSignature()
+ {
+ return signature;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return signature;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttCertIssuer.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttCertIssuer.java
index 7d343dd..acad7a4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttCertIssuer.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttCertIssuer.java
@@ -50,7 +50,7 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ return getInstance(obj.getExplicitBaseObject()); // must be explicitly tagged
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificate.java
index b5658e6..5ee2cd1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificate.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificate.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
@@ -16,7 +17,7 @@
{
AttributeCertificateInfo acinfo;
AlgorithmIdentifier signatureAlgorithm;
- DERBitString signatureValue;
+ ASN1BitString signatureValue;
/**
* @param obj
@@ -39,28 +40,23 @@
public AttributeCertificate(
AttributeCertificateInfo acinfo,
AlgorithmIdentifier signatureAlgorithm,
- DERBitString signatureValue)
+ ASN1BitString signatureValue)
{
this.acinfo = acinfo;
this.signatureAlgorithm = signatureAlgorithm;
this.signatureValue = signatureValue;
}
- /**
- * @deprecated use getInstance() method.
- */
- public AttributeCertificate(
- ASN1Sequence seq)
+ private AttributeCertificate(ASN1Sequence seq)
{
if (seq.size() != 3)
{
- throw new IllegalArgumentException("Bad sequence size: "
- + seq.size());
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
}
this.acinfo = AttributeCertificateInfo.getInstance(seq.getObjectAt(0));
this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- this.signatureValue = DERBitString.getInstance(seq.getObjectAt(2));
+ this.signatureValue = ASN1BitString.getInstance(seq.getObjectAt(2));
}
public AttributeCertificateInfo getAcinfo()
@@ -73,7 +69,7 @@
return signatureAlgorithm;
}
- public DERBitString getSignatureValue()
+ public ASN1BitString getSignatureValue()
{
return signatureValue;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
index f8ee260..e7263d9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Integer;
@@ -8,7 +9,6 @@
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DERSequence;
/**
@@ -21,10 +21,10 @@
private Holder holder;
private AttCertIssuer issuer;
private AlgorithmIdentifier signature;
- private ASN1Integer serialNumber;
+ private ASN1Integer serialNumber;
private AttCertValidityPeriod attrCertValidityPeriod;
private ASN1Sequence attributes;
- private DERBitString issuerUniqueID;
+ private ASN1BitString issuerUniqueID;
private Extensions extensions;
public static AttributeCertificateInfo getInstance(
@@ -80,9 +80,9 @@
{
ASN1Encodable obj = seq.getObjectAt(i);
- if (obj instanceof DERBitString)
+ if (obj instanceof ASN1BitString)
{
- this.issuerUniqueID = DERBitString.getInstance(seq.getObjectAt(i));
+ this.issuerUniqueID = ASN1BitString.getInstance(seq.getObjectAt(i));
}
else if (obj instanceof ASN1Sequence || obj instanceof Extensions)
{
@@ -126,7 +126,7 @@
return attributes;
}
- public DERBitString getIssuerUniqueID()
+ public ASN1BitString getIssuerUniqueID()
{
return issuerUniqueID;
}
@@ -158,7 +158,7 @@
{
ASN1EncodableVector v = new ASN1EncodableVector(9);
- if (version.intValueExact() != 0)
+ if (!version.hasValue(0))
{
v.add(version);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
index c4e2cf3..f4f45b5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
@@ -18,6 +18,7 @@
// Android-changed: Use Android digests
// import org.bouncycastle.crypto.digests.SHA1Digest;
import com.android.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.org.bouncycastle.util.Arrays;
import com.android.org.bouncycastle.util.encoders.Hex;
/**
@@ -175,7 +176,7 @@
GeneralNames name,
BigInteger serialNumber)
{
- this.keyidentifier = (keyIdentifier != null) ? new DEROctetString(keyIdentifier) : null;
+ this.keyidentifier = (keyIdentifier != null) ? new DEROctetString(Arrays.clone(keyIdentifier)) : null;
this.certissuer = name;
this.certserno = (serialNumber != null) ? new ASN1Integer(serialNumber) : null;
}
@@ -232,6 +233,7 @@
public String toString()
{
+ // -DM Hex.toHexString
String keyID = (keyidentifier != null) ? Hex.toHexString(keyidentifier.getOctets()) : "null";
return "AuthorityKeyIdentifier: KeyID(" + keyID + ")";
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/BasicConstraints.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/BasicConstraints.java
index c0b8ef8..0975cda 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/BasicConstraints.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/BasicConstraints.java
@@ -126,6 +126,11 @@
return null;
}
+ public ASN1Integer getPathLenConstraintInteger()
+ {
+ return pathLenConstraint;
+ }
+
/**
* Produce an object suitable for an ASN1OutputStream.
* <pre>
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLNumber.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLNumber.java
index c02cec2..433013c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLNumber.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLNumber.java
@@ -6,6 +6,7 @@
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.util.BigIntegers;
/**
* The CRLNumber object.
@@ -22,6 +23,10 @@
public CRLNumber(
BigInteger number)
{
+ if (BigIntegers.ZERO.compareTo(number) > 0)
+ {
+ throw new IllegalArgumentException("Invalid CRL number : not in (0..MAX)");
+ }
this.number = number;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLReason.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLReason.java
index 545c535..f370dfd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLReason.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLReason.java
@@ -53,7 +53,7 @@
/**
* @deprecated use lower case version
*/
- public static final int CESSATION_OF_OPERATION = 5;
+ public static final int CESSATION_OF_OPERATION = 5;
/**
* @deprecated use lower case version
*/
@@ -76,7 +76,7 @@
public static final int cACompromise = 2;
public static final int affiliationChanged = 3;
public static final int superseded = 4;
- public static final int cessationOfOperation = 5;
+ public static final int cessationOfOperation = 5;
public static final int certificateHold = 6;
// 7 -> unknown
public static final int removeFromCRL = 8;
@@ -84,11 +84,11 @@
public static final int aACompromise = 10;
private static final String[] reasonString =
- {
- "unspecified", "keyCompromise", "cACompromise", "affiliationChanged",
- "superseded", "cessationOfOperation", "certificateHold", "unknown",
- "removeFromCRL", "privilegeWithdrawn", "aACompromise"
- };
+ {
+ "unspecified", "keyCompromise", "cACompromise", "affiliationChanged",
+ "superseded", "cessationOfOperation", "certificateHold", "unknown",
+ "removeFromCRL", "privilegeWithdrawn", "aACompromise"
+ };
private static final Hashtable table = new Hashtable();
@@ -111,6 +111,10 @@
private CRLReason(
int reason)
{
+ if (reason < 0)
+ {
+ throw new IllegalArgumentException("Invalid CRL reason : not in (0..MAX)");
+ }
value = new ASN1Enumerated(reason);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Certificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Certificate.java
index c5ce691..19f2fda 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Certificate.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Certificate.java
@@ -1,12 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.x500.X500Name;
/**
@@ -26,7 +26,7 @@
ASN1Sequence seq;
TBSCertificate tbsCert;
AlgorithmIdentifier sigAlgId;
- DERBitString sig;
+ ASN1BitString sig;
public static Certificate getInstance(
ASN1TaggedObject obj,
@@ -64,7 +64,7 @@
tbsCert = TBSCertificate.getInstance(seq.getObjectAt(0));
sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- sig = DERBitString.getInstance(seq.getObjectAt(2));
+ sig = ASN1BitString.getInstance(seq.getObjectAt(2));
}
else
{
@@ -122,7 +122,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sig;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CertificateList.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CertificateList.java
index cc8a9db..546fb69 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CertificateList.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CertificateList.java
@@ -4,6 +4,7 @@
import java.util.Enumeration;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
@@ -32,7 +33,7 @@
{
TBSCertList tbsCertList;
AlgorithmIdentifier sigAlgId;
- DERBitString sig;
+ ASN1BitString sig;
boolean isHashCodeSet = false;
int hashCodeValue;
@@ -58,18 +59,14 @@
return null;
}
- /**
- * @deprecated use getInstance() method.
- * @param seq
- */
- public CertificateList(
+ private CertificateList(
ASN1Sequence seq)
{
if (seq.size() == 3)
{
tbsCertList = TBSCertList.getInstance(seq.getObjectAt(0));
sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- sig = DERBitString.getInstance(seq.getObjectAt(2));
+ sig = ASN1BitString.getInstance(seq.getObjectAt(2));
}
else
{
@@ -97,7 +94,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sig;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java
new file mode 100644
index 0000000..8f87d68
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java
@@ -0,0 +1,276 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.x509;
+
+import java.util.Enumeration;
+
+import com.android.org.bouncycastle.asn1.ASN1BitString;
+import com.android.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * <pre>
+ * DeltaCertificateDescriptor ::= SEQUENCE {
+ * serialNumber CertificateSerialNumber,
+ * signature [0] IMPLICIT AlgorithmIdentifier
+ * {SIGNATURE_ALGORITHM, {...}} OPTIONAL,
+ * issuer [1] IMPLICIT Name OPTIONAL,
+ * validity [2] IMPLICIT Validity OPTIONAL,
+ * subject [3] IMPLICIT Name OPTIONAL,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * extensions [4] IMPLICIT Extensions{CertExtensions}
+ * OPTIONAL,
+ * signatureValue BIT STRING
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DeltaCertificateDescriptor
+ extends ASN1Object
+{
+ private final ASN1Integer serialNumber;
+
+ private AlgorithmIdentifier signature;
+ private X500Name issuer;
+ private ASN1Sequence validity;
+ private X500Name subject;
+ private SubjectPublicKeyInfo subjectPublicKeyInfo;
+ private Extensions extensions;
+
+ private final ASN1BitString signatureValue;
+
+ public static DeltaCertificateDescriptor getInstance(
+ Object obj)
+ {
+ if (obj instanceof DeltaCertificateDescriptor)
+ {
+ return (DeltaCertificateDescriptor)obj;
+ }
+ else if (obj != null)
+ {
+ return new DeltaCertificateDescriptor(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieve a DeltaCertificateDescriptor for a passed in Extensions object, if present.
+ *
+ * @param extensions the extensions object to be examined.
+ * @return the DeltaCertificateDescriptor, null if the extension is not present.
+ */
+ public static DeltaCertificateDescriptor fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.deltaCertificateDescriptor));
+ }
+
+ private DeltaCertificateDescriptor(ASN1Sequence seq)
+ {
+ this.serialNumber = ASN1Integer.getInstance(seq.getObjectAt(0));
+
+ int idx = 1;
+ ASN1Encodable next = seq.getObjectAt(idx);
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ signature = AlgorithmIdentifier.getInstance(tagged, false);
+ break;
+ case 1:
+ issuer = X500Name.getInstance(tagged, true); // issuer
+ break;
+ case 2:
+ validity = ASN1Sequence.getInstance(tagged, false);
+ break;
+ case 3:
+ subject = X500Name.getInstance(tagged, true); // subject
+ break;
+ }
+ next = seq.getObjectAt(idx++);
+ }
+
+ subjectPublicKeyInfo = subjectPublicKeyInfo.getInstance(next);
+
+ next = seq.getObjectAt(idx);
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 4:
+ extensions = Extensions.getInstance(tagged, false);
+ break;
+ }
+ next = seq.getObjectAt(idx++);
+ }
+
+ signatureValue = ASN1BitString.getInstance(next);
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ public AlgorithmIdentifier getSignature()
+ {
+ return signature;
+ }
+
+ public X500Name getIssuer()
+ {
+ return issuer;
+ }
+
+ public ASN1Sequence getValidity()
+ {
+ return validity;
+ }
+
+ public X500Name getSubject()
+ {
+ return subject;
+ }
+
+ public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
+ {
+ return subjectPublicKeyInfo;
+ }
+
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+
+ public ASN1BitString getSignatureValue()
+ {
+ return signatureValue;
+ }
+
+ public DeltaCertificateDescriptor trimTo(TBSCertificate baseTbsCertificate, Extensions tbsExtensions)
+ {
+ AlgorithmIdentifier signature = baseTbsCertificate.signature;
+ X500Name issuer = baseTbsCertificate.issuer;
+ ASN1Sequence validity = new DERSequence(new ASN1Encodable[]
+ {
+ baseTbsCertificate.startDate, baseTbsCertificate.endDate
+ });
+ X500Name subject = baseTbsCertificate.subject;
+ ASN1Sequence s = ASN1Sequence.getInstance(toASN1Primitive());
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ Enumeration en = s.getObjects();
+ v.add((ASN1Encodable)en.nextElement());
+
+ ASN1Encodable next = (ASN1Encodable)en.nextElement();
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ AlgorithmIdentifier sig = AlgorithmIdentifier.getInstance(tagged, false);
+ if (!sig.equals(signature))
+ {
+ v.add(next);
+ }
+ break;
+ case 1:
+ X500Name iss = X500Name.getInstance(tagged, true); // issuer
+ if (!iss.equals(issuer))
+ {
+ v.add(next);
+ }
+ break;
+ case 2:
+ ASN1Sequence val = ASN1Sequence.getInstance(tagged, false);
+ if (!val.equals(validity))
+ {
+ v.add(next);
+ }
+ break;
+ case 3:
+ X500Name sub = X500Name.getInstance(tagged, true); // subject
+ if (!sub.equals(subject))
+ {
+ v.add(next);
+ }
+ break;
+ }
+ next = (ASN1Encodable)en.nextElement();
+ }
+
+ v.add(next);
+
+ next = (ASN1Encodable)en.nextElement();
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 4:
+ Extensions deltaExts = Extensions.getInstance(tagged, false);
+ ExtensionsGenerator deltaExtGen = new ExtensionsGenerator();
+ for (Enumeration extEn = deltaExts.oids(); extEn.hasMoreElements(); )
+ {
+ Extension deltaExt = deltaExts.getExtension((ASN1ObjectIdentifier)extEn.nextElement());
+ Extension primaryExt = tbsExtensions.getExtension(deltaExt.getExtnId());
+
+ if (primaryExt != null)
+ {
+ if (!deltaExt.equals(primaryExt))
+ {
+ deltaExtGen.addExtension(deltaExt);
+ }
+ }
+ }
+
+ DeltaCertificateDescriptor trimmedDeltaCertDesc;
+ if (!deltaExtGen.isEmpty())
+ {
+ v.add(new DERTaggedObject(false, 4, deltaExtGen.generate()));
+ }
+ }
+ next = (ASN1Encodable)en.nextElement();
+ }
+
+ v.add(next);
+
+ return new DeltaCertificateDescriptor(new DERSequence(v));
+ }
+
+ private void addOptional(ASN1EncodableVector v, int tag, boolean explicit, ASN1Object obj)
+ {
+ if (obj != null)
+ {
+ v.add(new DERTaggedObject(explicit, tag, obj));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(7);
+
+ v.add(serialNumber);
+ addOptional(v, 0, false, signature);
+ addOptional(v, 1, true, issuer); // CHOICE
+ addOptional(v, 2, false, validity);
+ addOptional(v, 3, true, subject); // CHOICE
+ v.add(subjectPublicKeyInfo);
+ addOptional(v, 4, false, extensions);
+ v.add(signatureValue);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DistributionPoint.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DistributionPoint.java
index f37199e..86dd71a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DistributionPoint.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DistributionPoint.java
@@ -1,12 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.asn1.DERTaggedObject;
import com.android.org.bouncycastle.util.Strings;
@@ -61,10 +61,11 @@
switch (t.getTagNo())
{
case 0:
+ // CHOICE so explicit
distributionPoint = DistributionPointName.getInstance(t, true);
break;
case 1:
- reasons = new ReasonFlags(DERBitString.getInstance(t, false));
+ reasons = new ReasonFlags(ASN1BitString.getInstance(t, false));
break;
case 2:
cRLIssuer = GeneralNames.getInstance(t, false);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extension.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extension.java
index 3ae3404..45adc5c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extension.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extension.java
@@ -13,6 +13,7 @@
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.DEROctetString;
import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.util.Arrays;
/**
* an object for the elements in the X.509 V3 extension block.
@@ -181,6 +182,26 @@
*/
public static final ASN1ObjectIdentifier expiredCertsOnCRL = new ASN1ObjectIdentifier("2.5.29.60").intern();
+ /**
+ * the subject’s alternative public key information
+ */
+ public static final ASN1ObjectIdentifier subjectAltPublicKeyInfo = new ASN1ObjectIdentifier("2.5.29.72").intern();
+
+ /**
+ * the algorithm identifier for the alternative digital signature algorithm.
+ */
+ public static final ASN1ObjectIdentifier altSignatureAlgorithm = new ASN1ObjectIdentifier("2.5.29.73").intern();
+
+ /**
+ * alternative signature shall be created by the issuer using its alternative private key.
+ */
+ public static final ASN1ObjectIdentifier altSignatureValue = new ASN1ObjectIdentifier("2.5.29.74").intern();
+
+ /**
+ * delta certificate extension - prototype value will change!
+ */
+ public static final ASN1ObjectIdentifier deltaCertificateDescriptor = new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.1");
+
private ASN1ObjectIdentifier extnId;
private boolean critical;
private ASN1OctetString value;
@@ -212,7 +233,7 @@
boolean critical,
byte[] value)
{
- this(extnId, critical, new DEROctetString(value));
+ this(extnId, critical, new DEROctetString(Arrays.clone(value)));
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extensions.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extensions.java
index c721c9c..4166c83 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extensions.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extensions.java
@@ -13,6 +13,7 @@
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.util.Properties;
/**
* <pre>
@@ -72,6 +73,11 @@
private Extensions(
ASN1Sequence seq)
{
+ if (seq.size() == 0)
+ {
+ throw new IllegalArgumentException("empty extension sequence found");
+ }
+
Enumeration e = seq.getObjects();
while (e.hasMoreElements())
@@ -80,7 +86,10 @@
if (extensions.containsKey(ext.getExtnId()))
{
- throw new IllegalArgumentException("repeated extension found: " + ext.getExtnId());
+ if (!Properties.isOverrideSet("com.android.org.bouncycastle.x509.ignore_repeated_extensions"))
+ {
+ throw new IllegalArgumentException("repeated extension found: " + ext.getExtnId());
+ }
}
extensions.put(ext.getExtnId(), ext);
@@ -108,6 +117,11 @@
public Extensions(
Extension[] extensions)
{
+ if (extensions == null || extensions.length == 0)
+ {
+ throw new IllegalArgumentException("extension array cannot be null or empty");
+ }
+
for (int i = 0; i != extensions.length; i++)
{
Extension ext = extensions[i];
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtensionsGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
index 2720ba2..31bde19 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
@@ -2,13 +2,22 @@
package com.android.org.bouncycastle.asn1.x509;
import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Set;
import java.util.Vector;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.org.bouncycastle.asn1.ASN1ParsingException;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.util.Arrays;
/**
* Generator for X.509 extensions
@@ -18,6 +27,18 @@
{
private Hashtable extensions = new Hashtable();
private Vector extOrdering = new Vector();
+ private static final Set dupsAllowed;
+
+
+ static
+ {
+ Set dups = new HashSet();
+ dups.add(Extension.subjectAlternativeName);
+ dups.add(Extension.issuerAlternativeName);
+ dups.add(Extension.subjectDirectoryAttributes);
+ dups.add(Extension.certificateIssuer);
+ dupsAllowed = Collections.unmodifiableSet(dups);
+ }
/**
* Reset the generator
@@ -32,14 +53,14 @@
* Add an extension with the given oid and the passed in value to be included
* in the OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
- * @param critical true if critical, false otherwise.
- * @param value the ASN.1 object to be included in the extension.
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the ASN.1 object to be included in the extension.
*/
public void addExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- ASN1Encodable value)
+ boolean critical,
+ ASN1Encodable value)
throws IOException
{
this.addExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER));
@@ -49,22 +70,52 @@
* Add an extension with the given oid and the passed in byte array to be wrapped in the
* OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
+ * @param oid OID for the extension.
* @param critical true if critical, false otherwise.
- * @param value the byte array to be wrapped.
+ * @param value the byte array to be wrapped.
*/
public void addExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- byte[] value)
+ boolean critical,
+ byte[] value)
{
if (extensions.containsKey(oid))
{
- throw new IllegalArgumentException("extension " + oid + " already added");
- }
+ if (dupsAllowed.contains(oid))
+ {
+ Extension existingExtension = (Extension)extensions.get(oid);
+ ASN1Sequence seq1 = ASN1Sequence.getInstance(DEROctetString.getInstance(existingExtension.getExtnValue()).getOctets());
+ ASN1Sequence seq2 = ASN1Sequence.getInstance(value);
- extOrdering.addElement(oid);
- extensions.put(oid, new Extension(oid, critical, new DEROctetString(value)));
+ ASN1EncodableVector items = new ASN1EncodableVector(seq1.size() + seq2.size());
+ for (Enumeration en = seq1.getObjects(); en.hasMoreElements();)
+ {
+ items.add((ASN1Encodable)en.nextElement());
+ }
+ for (Enumeration en = seq2.getObjects(); en.hasMoreElements();)
+ {
+ items.add((ASN1Encodable)en.nextElement());
+ }
+
+ try
+ {
+ extensions.put(oid, new Extension(oid, critical, new DERSequence(items).getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException(e.getMessage(), e);
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("extension " + oid + " already added");
+ }
+ }
+ else
+ {
+ extOrdering.addElement(oid);
+ extensions.put(oid, new Extension(oid, critical, new DEROctetString(Arrays.clone(value))));
+ }
}
/**
@@ -88,14 +139,14 @@
* Replace an extension with the given oid and the passed in value to be included
* in the OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
- * @param critical true if critical, false otherwise.
- * @param value the ASN.1 object to be included in the extension.
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the ASN.1 object to be included in the extension.
*/
public void replaceExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- ASN1Encodable value)
+ boolean critical,
+ ASN1Encodable value)
throws IOException
{
this.replaceExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER));
@@ -105,14 +156,14 @@
* Replace an extension with the given oid and the passed in byte array to be wrapped in the
* OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
+ * @param oid OID for the extension.
* @param critical true if critical, false otherwise.
- * @param value the byte array to be wrapped.
+ * @param value the byte array to be wrapped.
*/
public void replaceExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- byte[] value)
+ boolean critical,
+ byte[] value)
{
this.replaceExtension(new Extension(oid, critical, value));
}
@@ -158,7 +209,7 @@
*/
public boolean hasExtension(ASN1ObjectIdentifier oid)
{
- return extensions.containsKey(oid);
+ return extensions.containsKey(oid);
}
/**
@@ -169,7 +220,7 @@
*/
public Extension getExtension(ASN1ObjectIdentifier oid)
{
- return (Extension)extensions.get(oid);
+ return (Extension)extensions.get(oid);
}
/**
@@ -185,7 +236,7 @@
/**
* Generate an Extensions object based on the current state of the generator.
*
- * @return an X09Extensions object.
+ * @return an X09Extensions object.
*/
public Extensions generate()
{
@@ -198,4 +249,15 @@
return new Extensions(exts);
}
+
+ public void addExtension(Extensions extensions)
+ {
+ ASN1ObjectIdentifier[] oids = extensions.getExtensionOIDs();
+ for (int i = 0; i != oids.length; i++)
+ {
+ ASN1ObjectIdentifier ident = oids[i];
+ Extension ext = extensions.getExtension(ident);
+ addExtension(ASN1ObjectIdentifier.getInstance(ident), ext.isCritical(), ext.getExtnValue().getOctets());
+ }
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralName.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralName.java
index 982782b..f0dbfa2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralName.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralName.java
@@ -6,6 +6,7 @@
import com.android.org.bouncycastle.asn1.ASN1Choice;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.org.bouncycastle.asn1.ASN1IA5String;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
@@ -196,7 +197,7 @@
case dNSName:
case rfc822Name:
case uniformResourceIdentifier:
- return new GeneralName(tag, DERIA5String.getInstance(tagObj, false));
+ return new GeneralName(tag, ASN1IA5String.getInstance(tagObj, false));
case directoryName:
return new GeneralName(tag, X500Name.getInstance(tagObj, true));
@@ -229,6 +230,11 @@
ASN1TaggedObject tagObj,
boolean explicit)
{
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
return GeneralName.getInstance(ASN1TaggedObject.getInstance(tagObj, true));
}
@@ -253,7 +259,7 @@
case rfc822Name:
case dNSName:
case uniformResourceIdentifier:
- buf.append(DERIA5String.getInstance(obj).getString());
+ buf.append(ASN1IA5String.getInstance(obj).getString());
break;
case directoryName:
buf.append(X500Name.getInstance(obj).toString());
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralSubtree.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralSubtree.java
index 6830ad5..d67a44b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralSubtree.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralSubtree.java
@@ -205,7 +205,7 @@
v.add(base);
- if (minimum != null && !minimum.hasValue(ZERO))
+ if (minimum != null && !minimum.hasValue(0))
{
v.add(new DERTaggedObject(false, 0, minimum));
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Holder.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Holder.java
index 16b280a..f31c025 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Holder.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Holder.java
@@ -89,7 +89,7 @@
default:
throw new IllegalArgumentException("unknown tag in Holder");
}
- version = 0;
+ version = V1_CERTIFICATE_HOLDER;
}
/**
@@ -125,7 +125,7 @@
throw new IllegalArgumentException("unknown tag in Holder");
}
}
- version = 1;
+ version = V2_CERTIFICATE_HOLDER;
}
public Holder(IssuerSerial baseCertificateID)
@@ -211,7 +211,7 @@
public ASN1Primitive toASN1Primitive()
{
- if (version == 1)
+ if (version == V2_CERTIFICATE_HOLDER)
{
ASN1EncodableVector v = new ASN1EncodableVector(3);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuerSerial.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuerSerial.java
index b92639d..fdd59c2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuerSerial.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuerSerial.java
@@ -3,13 +3,13 @@
import java.math.BigInteger;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.asn1.x500.X500Name;
@@ -19,9 +19,9 @@
public class IssuerSerial
extends ASN1Object
{
- GeneralNames issuer;
- ASN1Integer serial;
- DERBitString issuerUID;
+ GeneralNames issuer;
+ ASN1Integer serial;
+ ASN1BitString issuerUID;
public static IssuerSerial getInstance(
Object obj)
@@ -59,7 +59,7 @@
if (seq.size() == 3)
{
- issuerUID = DERBitString.getInstance(seq.getObjectAt(2));
+ issuerUID = ASN1BitString.getInstance(seq.getObjectAt(2));
}
}
@@ -95,7 +95,7 @@
return serial;
}
- public DERBitString getIssuerUID()
+ public ASN1BitString getIssuerUID()
{
return issuerUID;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
index 62fafaf..6a89df0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Boolean;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Object;
@@ -154,7 +155,7 @@
switch (o.getTagNo())
{
case 0:
- // CHOICE so explicit
+ // CHOICE so explicit
distributionPoint = DistributionPointName.getInstance(o, true);
break;
case 1:
@@ -164,7 +165,7 @@
onlyContainsCACerts = ASN1Boolean.getInstance(o, false).isTrue();
break;
case 3:
- onlySomeReasons = new ReasonFlags(ReasonFlags.getInstance(o, false));
+ onlySomeReasons = new ReasonFlags(ASN1BitString.getInstance(o, false));
break;
case 4:
indirectCRL = ASN1Boolean.getInstance(o, false).isTrue();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyPurposeId.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyPurposeId.java
index 8f464a1..6f6206b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyPurposeId.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyPurposeId.java
@@ -109,6 +109,30 @@
*/
public static final KeyPurposeId id_kp_capwapWTP = new KeyPurposeId(id_kp.branch("19"));
+
+ /**
+ * id-kp-cmcCA OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) kp(3) 27 }
+ */
+ public static final KeyPurposeId id_kp_cmcCA = new KeyPurposeId(id_kp.branch("27"));
+
+ /**
+ * id-kp-cmcRA OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) kp(3) 28 }
+ */
+ public static final KeyPurposeId id_kp_cmcRA = new KeyPurposeId(id_kp.branch("28"));
+
+ /**
+ * id-kp-cmKGA OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) kp(3) 32 }
+ */
+ public static final KeyPurposeId id_kp_cmKGA = new KeyPurposeId(id_kp.branch("32"));
+
+
+
//
// microsoft key purpose ids
//
@@ -142,15 +166,6 @@
this.id = id;
}
- /**
- * @param id string representation of an OID.
- * @deprecated use getInstance and an OID or one of the constants above.
- */
- public KeyPurposeId(String id)
- {
- this(new ASN1ObjectIdentifier(id));
- }
-
public static KeyPurposeId getInstance(Object o)
{
if (o instanceof KeyPurposeId)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyUsage.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyUsage.java
index 12d2d07..b3d7a6f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyUsage.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyUsage.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.DERBitString;
@@ -36,7 +37,7 @@
public static final int encipherOnly = (1 << 0);
public static final int decipherOnly = (1 << 15);
- private DERBitString bitString;
+ private ASN1BitString bitString;
public static KeyUsage getInstance(Object obj) // needs to be DERBitString for other VMs
{
@@ -46,7 +47,7 @@
}
else if (obj != null)
{
- return new KeyUsage(DERBitString.getInstance(obj));
+ return new KeyUsage(ASN1BitString.getInstance(obj));
}
return null;
@@ -71,7 +72,7 @@
}
private KeyUsage(
- DERBitString bitString)
+ ASN1BitString bitString)
{
this.bitString = bitString;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ObjectDigestInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
index a5478ca..6b41325 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Enumerated;
import com.android.org.bouncycastle.asn1.ASN1Object;
@@ -56,7 +57,7 @@
AlgorithmIdentifier digestAlgorithm;
- DERBitString objectDigest;
+ ASN1BitString objectDigest;
public static ObjectDigestInfo getInstance(
Object obj)
@@ -131,7 +132,7 @@
digestAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1 + offset));
- objectDigest = DERBitString.getInstance(seq.getObjectAt(2 + offset));
+ objectDigest = ASN1BitString.getInstance(seq.getObjectAt(2 + offset));
}
public ASN1Enumerated getDigestedObjectType()
@@ -149,7 +150,7 @@
return digestAlgorithm;
}
- public DERBitString getObjectDigest()
+ public ASN1BitString getObjectDigest()
{
return objectDigest;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/OtherName.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/OtherName.java
index 0a91d49..9693ad9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/OtherName.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/OtherName.java
@@ -69,7 +69,7 @@
private OtherName(ASN1Sequence seq)
{
this.typeID = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
- this.value = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject(); // explicitly tagged
+ this.value = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
}
public ASN1ObjectIdentifier getTypeID()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
index ed2ded2..b7c29cf 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
@@ -10,9 +10,9 @@
import java.util.Map;
import java.util.Set;
+import com.android.org.bouncycastle.asn1.ASN1IA5String;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.org.bouncycastle.asn1.DERIA5String;
import com.android.org.bouncycastle.asn1.x500.RDN;
import com.android.org.bouncycastle.asn1.x500.X500Name;
import com.android.org.bouncycastle.asn1.x500.style.IETFUtils;
@@ -1826,22 +1826,22 @@
private static String extractHostFromURL(String url)
{
// see RFC 1738
- // remove ':' after protocol, e.g. http:
+ // remove ':' after protocol, e.g. https:
String sub = url.substring(url.indexOf(':') + 1);
- // extract host from Common Internet Scheme Syntax, e.g. http://
+ // extract host from Common Internet Scheme Syntax, e.g. https://
if (sub.indexOf("//") != -1)
{
sub = sub.substring(sub.indexOf("//") + 2);
}
- // first remove port, e.g. http://test.com:21
+ // first remove port, e.g. https://test.com:21
if (sub.lastIndexOf(':') != -1)
{
sub = sub.substring(0, sub.lastIndexOf(':'));
}
- // remove user and password, e.g. http://john:[email protected]
+ // remove user and password, e.g. https://john:[email protected]
sub = sub.substring(sub.indexOf(':') + 1);
sub = sub.substring(sub.indexOf('@') + 1);
- // remove local parts, e.g. http://test.com/bla
+ // remove local parts, e.g. https://test.com/bla
if (sub.indexOf('/') != -1)
{
sub = sub.substring(0, sub.indexOf('/'));
@@ -1851,7 +1851,7 @@
private String extractNameAsString(GeneralName name)
{
- return DERIA5String.getInstance(name.getName()).getString();
+ return ASN1IA5String.getInstance(name.getName()).getString();
}
/**
@@ -2080,6 +2080,7 @@
temp.append(":");
try
{
+ // -DM Hex.toHexString
temp.append(Hex.toHexString(name.getValue().toASN1Primitive().getEncoded()));
}
catch (IOException e)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
index 933cc5f..de3ff86 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
@@ -116,4 +116,9 @@
return new DERSequence(dev);
}
+
+ public String toString()
+ {
+ return "PolicyQualifierInfo[" + policyQualifierId + ", " + qualifier + "]";
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ReasonFlags.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ReasonFlags.java
index 79d22f6..ad7b1ef 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ReasonFlags.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ReasonFlags.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.DERBitString;
/**
@@ -80,7 +81,7 @@
}
public ReasonFlags(
- DERBitString reasons)
+ ASN1BitString reasons)
{
super(reasons.getBytes(), reasons.getPadBits());
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectAltPublicKeyInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectAltPublicKeyInfo.java
new file mode 100644
index 0000000..d473897
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectAltPublicKeyInfo.java
@@ -0,0 +1,110 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1.x509;
+
+import com.android.org.bouncycastle.asn1.ASN1BitString;
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * X.509 Section 9.8.2.
+ * <br/>
+ * This public-key certificate extension, when present, shall contain the subject’s alternative public key information
+ * <pre>
+ * subjectAltPublicKeyInfo EXTENSION ::= {
+ * SYNTAX SubjectAltPublicKeyInfo
+ * IDENTIFIED BY id-ce-subjectAltPublicKeyInfo }
+ *
+ * SubjectAltPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier{{SupportedAlgorithms}},
+ * subjectAltPublicKey BIT STRING }
+ * </pre>
+ * The SubjectAltPublicKeyInfo data type has the following components:
+ * <ul>
+ * <li>the algorithm subcomponent, which shall hold the algorithm that this public key is an instance of</li>
+ * <li>the subjectAltPublicKey subcomponent, which shall hold the alternative public key</li>
+ * </ul>
+ * This extension may be flagged as critical or as non-critical.
+ * <br/>
+ * NOTE – It is recommended that it be flagged as non-critical. Flagging it as critical would require relying parties to understand this
+ * extension and the alternative public-key algorithm.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SubjectAltPublicKeyInfo
+ extends ASN1Object
+{
+ private AlgorithmIdentifier algorithm;
+ private ASN1BitString subjectAltPublicKey;
+
+ public static SubjectAltPublicKeyInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static SubjectAltPublicKeyInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof SubjectAltPublicKeyInfo)
+ {
+ return (SubjectAltPublicKeyInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new SubjectAltPublicKeyInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static SubjectAltPublicKeyInfo fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.subjectAltPublicKeyInfo));
+ }
+
+ private SubjectAltPublicKeyInfo(ASN1Sequence s)
+ {
+ if (s.size() != 2)
+ {
+ throw new IllegalArgumentException("extension should contain only 2 elements");
+ }
+ algorithm = AlgorithmIdentifier.getInstance(s.getObjectAt(0));
+ subjectAltPublicKey = ASN1BitString.getInstance(s.getObjectAt(1));
+ }
+
+ public SubjectAltPublicKeyInfo(AlgorithmIdentifier algorithm, ASN1BitString subjectAltPublicKey)
+ {
+ this.algorithm = algorithm;
+ this.subjectAltPublicKey = subjectAltPublicKey;
+ }
+
+ public SubjectAltPublicKeyInfo(SubjectPublicKeyInfo subjectPublicKeyInfo)
+ {
+ this.algorithm = subjectPublicKeyInfo.getAlgorithm();
+ this.subjectAltPublicKey = subjectPublicKeyInfo.getPublicKeyData();
+ }
+
+ public AlgorithmIdentifier getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public ASN1BitString getSubjectAltPublicKey()
+ {
+ return subjectAltPublicKey;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(algorithm);
+ v.add(subjectAltPublicKey);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
index 66f0369..99aad0b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
@@ -4,6 +4,7 @@
import java.io.IOException;
import java.util.Enumeration;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Object;
@@ -24,7 +25,7 @@
extends ASN1Object
{
private AlgorithmIdentifier algId;
- private DERBitString keyData;
+ private ASN1BitString keyData;
public static SubjectPublicKeyInfo getInstance(
ASN1TaggedObject obj,
@@ -51,6 +52,14 @@
public SubjectPublicKeyInfo(
AlgorithmIdentifier algId,
+ ASN1BitString publicKey)
+ {
+ this.keyData = publicKey;
+ this.algId = algId;
+ }
+
+ public SubjectPublicKeyInfo(
+ AlgorithmIdentifier algId,
ASN1Encodable publicKey)
throws IOException
{
@@ -78,10 +87,10 @@
+ seq.size());
}
- Enumeration e = seq.getObjects();
+ Enumeration e = seq.getObjects();
this.algId = AlgorithmIdentifier.getInstance(e.nextElement());
- this.keyData = DERBitString.getInstance(e.nextElement());
+ this.keyData = ASN1BitString.getInstance(e.nextElement());
}
public AlgorithmIdentifier getAlgorithm()
@@ -132,7 +141,7 @@
*
* @return the public key as the raw bit string...
*/
- public DERBitString getPublicKeyData()
+ public ASN1BitString getPublicKeyData()
{
return keyData;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertList.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertList.java
index c25f87a..dd701a5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertList.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertList.java
@@ -107,7 +107,7 @@
}
}
- private class RevokedCertificatesEnumeration
+ private static class RevokedCertificatesEnumeration
implements Enumeration
{
private final Enumeration en;
@@ -128,7 +128,7 @@
}
}
- private class EmptyEnumeration
+ private static class EmptyEnumeration
implements Enumeration
{
public boolean hasMoreElements()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificate.java
index efce6aa..5545c0c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificate.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificate.java
@@ -1,19 +1,16 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
-import java.math.BigInteger;
-
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.asn1.DERTaggedObject;
import com.android.org.bouncycastle.asn1.x500.X500Name;
-import com.android.org.bouncycastle.util.BigIntegers;
import com.android.org.bouncycastle.util.Properties;
/**
@@ -49,8 +46,8 @@
Time startDate, endDate;
X500Name subject;
SubjectPublicKeyInfo subjectPublicKeyInfo;
- DERBitString issuerUniqueId;
- DERBitString subjectUniqueId;
+ ASN1BitString issuerUniqueId;
+ ASN1BitString subjectUniqueId;
Extensions extensions;
public static TBSCertificate getInstance(
@@ -98,15 +95,15 @@
boolean isV1 = false;
boolean isV2 = false;
- if (version.hasValue(BigInteger.valueOf(0)))
+ if (version.hasValue(0))
{
isV1 = true;
}
- else if (version.hasValue(BigInteger.valueOf(1)))
+ else if (version.hasValue(1))
{
isV2 = true;
}
- else if (!version.hasValue(BigInteger.valueOf(2)))
+ else if (!version.hasValue(2))
{
throw new IllegalArgumentException("version number not recognised");
}
@@ -144,10 +141,10 @@
switch (extra.getTagNo())
{
case 1:
- issuerUniqueId = DERBitString.getInstance(extra, false);
+ issuerUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 2:
- subjectUniqueId = DERBitString.getInstance(extra, false);
+ subjectUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 3:
if (isV2)
@@ -208,12 +205,12 @@
return subjectPublicKeyInfo;
}
- public DERBitString getIssuerUniqueId()
+ public ASN1BitString getIssuerUniqueId()
{
return issuerUniqueId;
}
- public DERBitString getSubjectUniqueId()
+ public ASN1BitString getSubjectUniqueId()
{
return subjectUniqueId;
}
@@ -240,7 +237,7 @@
ASN1EncodableVector v = new ASN1EncodableVector();
// DEFAULT Zero
- if (!version.hasValue(BigIntegers.ZERO))
+ if (!version.hasValue(0))
{
v.add(new DERTaggedObject(true, 0, version));
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificateStructure.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
index fc5aa92..9fef389 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
@@ -1,12 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.x500.X500Name;
@@ -45,8 +45,8 @@
Time startDate, endDate;
X500Name subject;
SubjectPublicKeyInfo subjectPublicKeyInfo;
- DERBitString issuerUniqueId;
- DERBitString subjectUniqueId;
+ ASN1BitString issuerUniqueId;
+ ASN1BitString subjectUniqueId;
X509Extensions extensions;
public static TBSCertificateStructure getInstance(
@@ -118,10 +118,10 @@
switch (extra.getTagNo())
{
case 1:
- issuerUniqueId = DERBitString.getInstance(extra, false);
+ issuerUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 2:
- subjectUniqueId = DERBitString.getInstance(extra, false);
+ subjectUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 3:
extensions = X509Extensions.getInstance(extra);
@@ -174,12 +174,12 @@
return subjectPublicKeyInfo;
}
- public DERBitString getIssuerUniqueId()
+ public ASN1BitString getIssuerUniqueId()
{
return issuerUniqueId;
}
- public DERBitString getSubjectUniqueId()
+ public ASN1BitString getSubjectUniqueId()
{
return subjectUniqueId;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Time.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Time.java
index 2b3a122..c556273 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Time.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Time.java
@@ -17,6 +17,7 @@
import com.android.org.bouncycastle.asn1.ASN1UTCTime;
import com.android.org.bouncycastle.asn1.DERGeneralizedTime;
import com.android.org.bouncycastle.asn1.DERUTCTime;
+import com.android.org.bouncycastle.asn1.LocaleUtil;
/**
* @hide This class is not part of the Android public SDK API
@@ -31,7 +32,12 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
+ return getInstance(obj.getExplicitBaseObject());
}
public Time(
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V2Form.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V2Form.java
index cab4fb4..1f7af22 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V2Form.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V2Form.java
@@ -71,10 +71,7 @@
this.objectDigestInfo = objectDigestInfo;
}
- /**
- * @deprecated use getInstance().
- */
- public V2Form(
+ private V2Form(
ASN1Sequence seq)
{
if (seq.size() > 3)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
index 1c7d69a..576c06f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
@@ -3,6 +3,8 @@
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1UTCTime;
import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DERSequence;
@@ -165,21 +167,34 @@
}
}
- @android.compat.annotation.UnsupportedAppUsage
- public TBSCertificate generateTBSCertificate()
+ public ASN1Sequence generatePreTBSCertificate()
{
- if ((serialNumber == null) || (signature == null)
+ if (signature != null)
+ {
+ throw new IllegalStateException("signature field should not be set in PreTBSCertificate");
+ }
+ if ((serialNumber == null)
|| (issuer == null) || (startDate == null) || (endDate == null)
|| (subject == null && !altNamePresentAndCritical) || (subjectPublicKeyInfo == null))
{
throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator");
}
+ return generateTBSStructure();
+ }
+
+ private ASN1Sequence generateTBSStructure()
+ {
ASN1EncodableVector v = new ASN1EncodableVector(10);
v.add(version);
v.add(serialNumber);
- v.add(signature);
+
+ if (signature != null)
+ {
+ v.add(signature);
+ }
+
v.add(issuer);
//
@@ -219,6 +234,19 @@
v.add(new DERTaggedObject(true, 3, extensions));
}
- return TBSCertificate.getInstance(new DERSequence(v));
+ return new DERSequence(v);
+ }
+
+ @android.compat.annotation.UnsupportedAppUsage
+ public TBSCertificate generateTBSCertificate()
+ {
+ if ((serialNumber == null) || (signature == null)
+ || (issuer == null) || (startDate == null) || (endDate == null)
+ || (subject == null && !altNamePresentAndCritical) || (subjectPublicKeyInfo == null))
+ {
+ throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator");
+ }
+
+ return TBSCertificate.getInstance(generateTBSStructure());
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509CertificateStructure.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509CertificateStructure.java
index 658d6cc..04b559b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509CertificateStructure.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509CertificateStructure.java
@@ -1,12 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.x500.X500Name;
@@ -29,7 +29,7 @@
ASN1Sequence seq;
TBSCertificateStructure tbsCert;
AlgorithmIdentifier sigAlgId;
- DERBitString sig;
+ ASN1BitString sig;
public static X509CertificateStructure getInstance(
ASN1TaggedObject obj,
@@ -66,7 +66,7 @@
tbsCert = TBSCertificateStructure.getInstance(seq.getObjectAt(0));
sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- sig = DERBitString.getInstance(seq.getObjectAt(2));
+ sig = ASN1BitString.getInstance(seq.getObjectAt(2));
}
else
{
@@ -119,7 +119,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sig;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
index 3a0d261..a67b1c9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
@@ -9,6 +9,7 @@
import com.android.org.bouncycastle.asn1.DERIA5String;
import com.android.org.bouncycastle.asn1.DERPrintableString;
import com.android.org.bouncycastle.asn1.DERUTF8String;
+import com.android.org.bouncycastle.asn1.x500.style.BCStyle;
/**
* The default converter for X509 DN entries when going from their
@@ -47,16 +48,16 @@
{
value = value.substring(1);
}
- if (oid.equals(X509Name.EmailAddress) || oid.equals(X509Name.DC))
+ if (oid.equals(BCStyle.EmailAddress) || oid.equals(BCStyle.DC))
{
return new DERIA5String(value);
}
- else if (oid.equals(X509Name.DATE_OF_BIRTH)) // accept time string as well as # (for compatibility)
+ else if (oid.equals(BCStyle.DATE_OF_BIRTH)) // accept time string as well as # (for compatibility)
{
return new DERGeneralizedTime(value);
}
- else if (oid.equals(X509Name.C) || oid.equals(X509Name.SN) || oid.equals(X509Name.DN_QUALIFIER)
- || oid.equals(X509Name.TELEPHONE_NUMBER))
+ else if (oid.equals(BCStyle.C) || oid.equals(BCStyle.SERIALNUMBER) || oid.equals(BCStyle.DN_QUALIFIER)
+ || oid.equals(BCStyle.TELEPHONE_NUMBER))
{
return new DERPrintableString(value);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Extensions.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Extensions.java
index f93dc33..a45feee 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Extensions.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Extensions.java
@@ -13,10 +13,11 @@
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.BERTags;
import com.android.org.bouncycastle.asn1.DERSequence;
/**
- * @deprecated use {@link Extensions}
+ * @deprecated use {@link Extension} and {@link Extensions}
* @hide This class is not part of the Android public SDK API
*/
public class X509Extensions
@@ -238,7 +239,9 @@
if (obj instanceof ASN1TaggedObject)
{
- return getInstance(((ASN1TaggedObject)obj).getObject());
+ ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC);
+
+ return getInstance(taggedObject.getBaseObject().toASN1Primitive());
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Name.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Name.java
index 58fd9b7..fdc2dc4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Name.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Name.java
@@ -16,9 +16,9 @@
import com.android.org.bouncycastle.asn1.ASN1Set;
import com.android.org.bouncycastle.asn1.ASN1String;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.org.bouncycastle.asn1.ASN1UniversalString;
import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.asn1.DERSet;
-import com.android.org.bouncycastle.asn1.DERUniversalString;
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.x500.X500Name;
import com.android.org.bouncycastle.util.Strings;
@@ -429,7 +429,7 @@
ordering.addElement(ASN1ObjectIdentifier.getInstance(s.getObjectAt(0)));
ASN1Encodable value = s.getObjectAt(1);
- if (value instanceof ASN1String && !(value instanceof DERUniversalString))
+ if (value instanceof ASN1String && !(value instanceof ASN1UniversalString))
{
String v = ((ASN1String)value).getString();
if (v.length() > 0 && v.charAt(0) == '#')
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509NameEntryConverter.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
index 2d48ac0..99ff23e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
@@ -5,7 +5,7 @@
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.DERPrintableString;
+import com.android.org.bouncycastle.asn1.ASN1PrintableString;
import com.android.org.bouncycastle.util.encoders.Hex;
/**
@@ -73,7 +73,7 @@
protected boolean canBePrintable(
String str)
{
- return DERPrintableString.isPrintableString(str);
+ return ASN1PrintableString.isPrintableString(str);
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
index 45c4582..74ce730 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
@@ -111,4 +111,11 @@
static final ASN1ObjectIdentifier ocspAccessMethod = id_ad_ocsp;
/** OID for crl uri in AuthorityInformationAccess extension */
static final ASN1ObjectIdentifier crlAccessMethod = id_ad_caIssuers;
+
+
+ /**
+ * id-PasswordBasedMac OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) nt(113533) nsn(7) algorithms(66) 13 }
+ */
+ static final ASN1ObjectIdentifier id_PasswordBasedMac = new ASN1ObjectIdentifier("1.2.840.113533.7.66.13");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHValidationParms.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHValidationParms.java
index 01bdf6e..8e72e3f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHValidationParms.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHValidationParms.java
@@ -1,13 +1,13 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x9;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DERSequence;
/**
@@ -16,7 +16,7 @@
*/
public class DHValidationParms extends ASN1Object
{
- private DERBitString seed;
+ private ASN1BitString seed;
private ASN1Integer pgenCounter;
public static DHValidationParms getInstance(ASN1TaggedObject obj, boolean explicit)
@@ -38,7 +38,7 @@
return null;
}
- public DHValidationParms(DERBitString seed, ASN1Integer pgenCounter)
+ public DHValidationParms(ASN1BitString seed, ASN1Integer pgenCounter)
{
if (seed == null)
{
@@ -60,11 +60,11 @@
throw new IllegalArgumentException("Bad sequence size: " + seq.size());
}
- this.seed = DERBitString.getInstance(seq.getObjectAt(0));
+ this.seed = ASN1BitString.getInstance(seq.getObjectAt(0));
this.pgenCounter = ASN1Integer.getInstance(seq.getObjectAt(1));
}
- public DERBitString getSeed()
+ public ASN1BitString getSeed()
{
return this.seed;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ECNamedCurveTable.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
index 19018b1..5f351aa 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
@@ -71,6 +71,47 @@
return ecP;
}
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ X9ECParametersHolder holder = X962NamedCurves.getByNameLazy(name);
+
+ if (null == holder)
+ {
+ holder = SECNamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = NISTNamedCurves.getByNameLazy(name);
+ }
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ if (null == holder)
+ {
+ holder = TeleTrusTNamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = ANSSINamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = ECGOST3410NamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = GMNamedCurves.getByNameLazy(name);
+ }
+ */
+ // END Android-removed: Unsupported curves
+
+ return holder;
+ }
+
/**
* return the object identifier signified by the passed in name. Null
* if there is no object identifier associated with name.
@@ -224,6 +265,44 @@
return ecP;
}
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ X9ECParametersHolder holder = X962NamedCurves.getByOIDLazy(oid);
+
+ if (null == holder)
+ {
+ holder = SECNamedCurves.getByOIDLazy(oid);
+ }
+
+ // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ if (null == holder)
+ {
+ holder = TeleTrusTNamedCurves.getByOIDLazy(oid);
+ }
+
+ if (null == holder)
+ {
+ holder = ANSSINamedCurves.getByOIDLazy(oid);
+ }
+
+ if (null == holder)
+ {
+ holder = ECGOST3410NamedCurves.getByOIDLazy(oid);
+ }
+
+ if (null == holder)
+ {
+ holder = GMNamedCurves.getByOIDLazy(oid);
+ }
+ */
+ // END Android-removed: Unsupported curves
+
+ return holder;
+ }
+
/**
* return an enumeration of the names of the available curves.
*
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ValidationParams.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ValidationParams.java
index deac4bc..0a03fce 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ValidationParams.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ValidationParams.java
@@ -3,6 +3,7 @@
import java.math.BigInteger;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1Object;
@@ -25,7 +26,7 @@
public class ValidationParams
extends ASN1Object
{
- private DERBitString seed;
+ private ASN1BitString seed;
private ASN1Integer pgenCounter;
public static ValidationParams getInstance(ASN1TaggedObject obj, boolean explicit)
@@ -80,7 +81,7 @@
throw new IllegalArgumentException("Bad sequence size: " + seq.size());
}
- this.seed = DERBitString.getInstance(seq.getObjectAt(0));
+ this.seed = ASN1BitString.getInstance(seq.getObjectAt(0));
this.pgenCounter = ASN1Integer.getInstance(seq.getObjectAt(1));
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962NamedCurves.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962NamedCurves.java
index 70e96e2..d461d24 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962NamedCurves.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962NamedCurves.java
@@ -37,141 +37,183 @@
static X9ECParametersHolder prime192v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("ffffffffffffffffffffffff99def836146bc9b1b4d22831");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
fromHex("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("3045AE6FC8422f64ED579528D38120EAE12196D5");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("3045AE6FC8422f64ED579528D38120EAE12196D5"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime192v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
fromHex("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("31a92ee2029fd10d901b113e990710f0d21ac6b6");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("31a92ee2029fd10d901b113e990710f0d21ac6b6"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime192v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("ffffffffffffffffffffffff7a62d031c83f4294f640ec13");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
fromHex("22123dc2395a05caa7423daeccc94760a7d462256bd56916"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("c469684435deb378c4b65ca9591e2a5763059a2e");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"027d29778100c65a1da1783716588dce2b8b4aee8e228f1896");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c469684435deb378c4b65ca9591e2a5763059a2e"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime239v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
fromHex("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("e43bb460f0b80cc0c0b075798e948060f8321b7d");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e43bb460f0b80cc0c0b075798e948060f8321b7d"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime239v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
fromHex("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("e8b4011604095303ca3b8099982be09fcb9ae616");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e8b4011604095303ca3b8099982be09fcb9ae616"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime239v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
fromHex("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("7d7374168ffe3471b60a857686a19475d3bfa2ff");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("7d7374168ffe3471b60a857686a19475d3bfa2ff"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime256v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"),
fromHex("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc"),
fromHex("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("c49d360886e704936a6678e1139d26b7819f7e90");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c49d360886e704936a6678e1139d26b7819f7e90"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -180,337 +222,433 @@
*/
static X9ECParametersHolder c2pnb163v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0400000000000000000001E60FC8821CC74DAEAFC1");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
fromHex("072546B5435234A422E0789675F432C89435DE5242"),
fromHex("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("D2C0FB15760860DEF1EEF4D696E6768756151754");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0307AF69989546103D79329FCC3D74880F33BBE803CB");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("D2C0FB15760860DEF1EEF4D696E6768756151754"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb163v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
fromHex("0108B39E77C4B108BED981ED0E890E117C511CF072"),
fromHex("0667ACEB38AF4E488C407433FFAE4F1C811638DF20"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"030024266E4EB5106D0A964D92C4860E2671DB9B6CC5");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb163v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
fromHex("07A526C63D3E25A256A007699F5447E32AE456B50E"),
fromHex("03F7061798EB99E238FD6F1BF95B48FEEB4854252B"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb176w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("010092537397ECA4F6145799D62B0A19CE06FE26AD");
BigInteger h = BigInteger.valueOf(0xFF6E);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
176,
1, 2, 43,
fromHex("E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B"),
fromHex("5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"038D16C2866798B600F9F08BB4A8E860F3298CE04A5798");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb191v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("40000000000000000000000004A20E90C39067C893BBB9A5");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
191,
9,
fromHex("2866537B676752636A68F56554E12640276B649EF7526267"),
fromHex("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("4E13CA542744D696E67687561517552F279A8C84");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("4E13CA542744D696E67687561517552F279A8C84"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb191v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("20000000000000000000000050508CB89F652824E06B8173");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
191,
9,
fromHex("401028774D7777C7B7666D1366EA432071274F89FF01E718"),
fromHex("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb191v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("155555555555555555555555610C0B196812BFB6288A3EA3");
BigInteger h = BigInteger.valueOf(6);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
191,
9,
fromHex("6C01074756099122221056911C77D77E77A777E7E7E77FCB"),
fromHex("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"03375D4CE24FDE434489DE8746E71786015009E66E38A926DD");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb208w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D");
BigInteger h = BigInteger.valueOf(0xFE48);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
208,
1, 2, 83,
BigInteger.valueOf(0),
fromHex("C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb239v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
239,
36,
fromHex("32010857077C5431123A46B808906756F543423E8D27877578125778AC76"),
fromHex("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb239v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D");
BigInteger h = BigInteger.valueOf(6);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
239,
36,
fromHex("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F"),
fromHex("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb239v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF");
BigInteger h = BigInteger.valueOf(10);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
239,
36,
fromHex("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F"),
fromHex("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb272w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521");
BigInteger h = BigInteger.valueOf(0xFF06);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
272,
1, 3, 56,
fromHex("91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20"),
fromHex("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb304w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D");
BigInteger h = BigInteger.valueOf(0xFE2E);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
304,
1, 2, 11,
fromHex("FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681"),
fromHex("BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb359v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B");
BigInteger h = BigInteger.valueOf(0x4C);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
359,
68,
fromHex("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557"),
fromHex("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb368w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967");
BigInteger h = BigInteger.valueOf(0xFF70);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
368,
1, 2, 85,
fromHex("E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D"),
fromHex("FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb431r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91");
BigInteger h = BigInteger.valueOf(0x2760);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
431,
120,
fromHex("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F"),
fromHex("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -553,17 +691,16 @@
defineCurve("c2tnb431r1", X9ObjectIdentifiers.c2tnb431r1, c2tnb431r1);
}
- public static X9ECParameters getByName(
- String name)
+ public static X9ECParameters getByName(String name)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name));
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOID(oid);
+ }
- if (oid != null)
- {
- return getByOID(oid);
- }
-
- return null;
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOIDLazy(oid);
}
/**
@@ -572,17 +709,15 @@
*
* @param oid an object identifier representing a named curve, if present.
*/
- public static X9ECParameters getByOID(
- ASN1ObjectIdentifier oid)
+ public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid);
+ X9ECParametersHolder holder = getByOIDLazy(oid);
+ return holder == null ? null : holder.getParameters();
+ }
- if (holder != null)
- {
- return holder.getParameters();
- }
-
- return null;
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return (X9ECParametersHolder)curves.get(oid);
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962Parameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962Parameters.java
index fac3bdd..579c562 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962Parameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962Parameters.java
@@ -50,7 +50,12 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
+ return getInstance(obj.getExplicitBaseObject());
}
public X962Parameters(
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParameters.java
index d2a48d1..9fe2d7d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParameters.java
@@ -38,7 +38,7 @@
ASN1Sequence seq)
{
if (!(seq.getObjectAt(0) instanceof ASN1Integer)
- || !((ASN1Integer)seq.getObjectAt(0)).hasValue(ONE))
+ || !((ASN1Integer)seq.getObjectAt(0)).hasValue(1))
{
throw new IllegalArgumentException("bad version in X9ECParameters");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParametersHolder.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
index ddc5700..2582d93 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
@@ -1,14 +1,27 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x9;
+import com.android.org.bouncycastle.math.ec.ECCurve;
+
/**
* A holding class that allows for X9ECParameters to be lazily constructed.
* @hide This class is not part of the Android public SDK API
*/
public abstract class X9ECParametersHolder
{
+ private ECCurve curve;
private X9ECParameters params;
+ public synchronized ECCurve getCurve()
+ {
+ if (curve == null)
+ {
+ curve = createCurve();
+ }
+
+ return curve;
+ }
+
public synchronized X9ECParameters getParameters()
{
if (params == null)
@@ -19,5 +32,10 @@
return params;
}
+ protected ECCurve createCurve()
+ {
+ return createParameters().getCurve();
+ }
+
protected abstract X9ECParameters createParameters();
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9FieldElement.java
index 53f51e6..1e0c609 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9FieldElement.java
@@ -1,10 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x9;
-import java.math.BigInteger;
-
import com.android.org.bouncycastle.asn1.ASN1Object;
-import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.DEROctetString;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
@@ -25,22 +22,6 @@
this.f = f;
}
- /**
- * @deprecated Will be removed
- */
- public X9FieldElement(BigInteger p, ASN1OctetString s)
- {
- this(new ECFieldElement.Fp(p, new BigInteger(1, s.getOctets())));
- }
-
- /**
- * @deprecated Will be removed
- */
- public X9FieldElement(int m, int k1, int k2, int k3, ASN1OctetString s)
- {
- this(new ECFieldElement.F2m(m, k1, k2, k3, new BigInteger(1, s.getOctets())));
- }
-
public ECFieldElement getValue()
{
return f;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/AlphabetMapper.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/AlphabetMapper.java
new file mode 100644
index 0000000..038ee71
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/AlphabetMapper.java
@@ -0,0 +1,34 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+/**
+ * Base interface for mapping from an alphabet to a set of indexes
+ * suitable for use with FPE.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface AlphabetMapper
+{
+ /**
+ * Return the number of characters in the alphabet.
+ *
+ * @return the radix for the alphabet.
+ */
+ int getRadix();
+
+ /**
+ * Return the passed in char[] as a byte array of indexes (indexes
+ * can be more than 1 byte)
+ *
+ * @param input characters to be mapped.
+ * @return an index array.
+ */
+ byte[] convertToIndexes(char[] input);
+
+ /**
+ * Return a char[] for this alphabet based on the indexes passed.
+ *
+ * @param input input array of indexes.
+ * @return an array of char corresponding to the index values.
+ */
+ char[] convertToChars(byte[] input);
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/BlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/BlockCipher.java
index eaf9803..1789d21 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/BlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/BlockCipher.java
@@ -38,16 +38,16 @@
* Process one block of input from the array in and write it to
* the out array.
*
- * @param in the array containing the input data.
+ * @param input the array containing the input data.
* @param inOff offset into the in array the data starts at.
- * @param out the array the output data will be copied into.
+ * @param output the array the output data will be copied into.
* @param outOff the offset into the out array the output will start at.
- * @exception DataLengthException if there isn't enough data in in, or
+ * @exception DataLengthException if there isn't enough data in input , or
* space in out.
* @exception IllegalStateException if the cipher isn't initialised.
* @return the number of bytes processed and produced.
*/
- public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
+ public int processBlock(byte[] input, int inOff, byte[] output, int outOff)
throws DataLengthException, IllegalStateException;
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/BufferedBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/BufferedBlockCipher.java
index f3cfea8..0cde747 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/BufferedBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/BufferedBlockCipher.java
@@ -16,8 +16,9 @@
protected byte[] buf;
protected int bufOff;
- protected boolean forEncryption;
- protected BlockCipher cipher;
+ protected boolean forEncryption;
+ protected BlockCipher cipher;
+ protected MultiBlockCipher mbCipher;
protected boolean partialBlockOkay;
protected boolean pgpCFB;
@@ -25,7 +26,7 @@
/**
* constructor for subclasses
*/
- protected BufferedBlockCipher()
+ BufferedBlockCipher()
{
}
@@ -33,13 +34,24 @@
* Create a buffered block cipher without padding.
*
* @param cipher the underlying block cipher this buffering object wraps.
+ * @deprecated use the constructor on DefaultBufferedBlockCipher.
*/
public BufferedBlockCipher(
BlockCipher cipher)
{
this.cipher = cipher;
- buf = new byte[cipher.getBlockSize()];
+ if (cipher instanceof MultiBlockCipher)
+ {
+ this.mbCipher = (MultiBlockCipher)cipher;
+ buf = new byte[mbCipher.getMultiBlockSize()];
+ }
+ else
+ {
+ this.mbCipher = null;
+ buf = new byte[cipher.getBlockSize()];
+ }
+
bufOff = 0;
//
@@ -145,6 +157,11 @@
public int getOutputSize(
int length)
{
+ if (pgpCFB && forEncryption)
+ {
+ return length + bufOff + (cipher.getBlockSize() + 2);
+ }
+
// Note: Can assume partialBlockOkay is true for purposes of this calculation
return length + bufOff;
}
@@ -227,12 +244,29 @@
len -= gapLen;
inOff += gapLen;
- while (len > buf.length)
+ if (mbCipher != null)
{
- resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen);
+ int blockCount = len / mbCipher.getMultiBlockSize();
- len -= blockSize;
- inOff += blockSize;
+ if (blockCount > 0)
+ {
+ resultLen += mbCipher.processBlocks(in, inOff, blockCount, out, outOff + resultLen);
+
+ int processed = blockCount * mbCipher.getMultiBlockSize();
+
+ len -= processed;
+ inOff += processed;
+ }
+ }
+ else
+ {
+ while (len > buf.length)
+ {
+ resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen);
+
+ len -= blockSize;
+ inOff += blockSize;
+ }
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CipherKeyGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CipherKeyGenerator.java
index a7212c9..eae4741 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CipherKeyGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CipherKeyGenerator.java
@@ -3,6 +3,8 @@
import java.security.SecureRandom;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+
/**
* The base class for symmetric, or secret, cipher key generators.
* @hide This class is not part of the Android public SDK API
@@ -22,6 +24,8 @@
{
this.random = param.getRandom();
this.strength = (param.getStrength() + 7) / 8;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("SymKeyGen", param.getStrength()));
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServiceConstraintsException.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServiceConstraintsException.java
new file mode 100644
index 0000000..33f9e09
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServiceConstraintsException.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CryptoServiceConstraintsException
+ extends RuntimeException
+{
+ public CryptoServiceConstraintsException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServiceProperties.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServiceProperties.java
new file mode 100644
index 0000000..d80043a
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServiceProperties.java
@@ -0,0 +1,16 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CryptoServiceProperties
+{
+ int bitsOfSecurity();
+
+ String getServiceName();
+
+ CryptoServicePurpose getPurpose();
+
+ Object getParams();
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicePurpose.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicePurpose.java
new file mode 100644
index 0000000..76b81ea
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicePurpose.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public enum CryptoServicePurpose
+{
+ AGREEMENT,
+ ENCRYPTION,
+ DECRYPTION,
+ KEYGEN,
+ SIGNING, // for signatures (and digests)
+ VERIFYING,
+ AUTHENTICATION, // for MACs (and digests)
+ VERIFICATION,
+ PRF,
+ ANY
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesConstraints.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesConstraints.java
new file mode 100644
index 0000000..6c90e31
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesConstraints.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CryptoServicesConstraints
+{
+ void check(CryptoServiceProperties service);
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesPermission.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesPermission.java
index c393a4d..3a977ef 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesPermission.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesPermission.java
@@ -27,6 +27,11 @@
*/
public static final String DEFAULT_RANDOM = "defaultRandomConfig";
+ /**
+ * Enable the setting of the constraints.
+ */
+ public static final String CONSTRAINTS = "constraints";
+
private final Set<String> actions = new HashSet<String>();
public CryptoServicesPermission(String name)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesRegistrar.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesRegistrar.java
index 920e33c..81c47d3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesRegistrar.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesRegistrar.java
@@ -9,12 +9,16 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Logger;
import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
import com.android.org.bouncycastle.crypto.params.DHParameters;
import com.android.org.bouncycastle.crypto.params.DHValidationParameters;
import com.android.org.bouncycastle.crypto.params.DSAParameters;
import com.android.org.bouncycastle.crypto.params.DSAValidationParameters;
+import com.android.org.bouncycastle.util.Properties;
+import com.android.org.bouncycastle.util.Strings;
import com.android.org.bouncycastle.util.encoders.Hex;
/**
@@ -23,15 +27,28 @@
*/
public final class CryptoServicesRegistrar
{
+ private static final Logger LOG = Logger.getLogger(CryptoServicesRegistrar.class.getName());
+
private static final Permission CanSetDefaultProperty = new CryptoServicesPermission(CryptoServicesPermission.GLOBAL_CONFIG);
private static final Permission CanSetThreadProperty = new CryptoServicesPermission(CryptoServicesPermission.THREAD_LOCAL_CONFIG);
private static final Permission CanSetDefaultRandom = new CryptoServicesPermission(CryptoServicesPermission.DEFAULT_RANDOM);
+ private static final Permission CanSetConstraints = new CryptoServicesPermission(CryptoServicesPermission.CONSTRAINTS);
private static final ThreadLocal<Map<String, Object[]>> threadProperties = new ThreadLocal<Map<String, Object[]>>();
private static final Map<String, Object[]> globalProperties = Collections.synchronizedMap(new HashMap<String, Object[]>());
+ private static final SecureRandomProvider defaultRandomProviderImpl = new ThreadLocalSecureRandomProvider();
- private static final Object cacheLock = new Object();
- private static SecureRandom defaultSecureRandom;
+ private static final CryptoServicesConstraints noConstraintsImpl = new CryptoServicesConstraints()
+ {
+ public void check(CryptoServiceProperties service)
+ {
+ // anything goes.
+ }
+ };
+
+ private static final AtomicReference<SecureRandomProvider> defaultSecureRandomProvider = new AtomicReference<SecureRandomProvider>();
+ private static final boolean preconfiguredConstraints;
+ private static final AtomicReference<CryptoServicesConstraints> servicesConstraints = new AtomicReference<CryptoServicesConstraints>();
static
{
@@ -45,56 +62,59 @@
DSAParameters def768Params = new DSAParameters(
new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5" +
- "d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a" +
- "22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45" +
- "ee3688c11a8c56ab127a3daf", 16),
+ "d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a" +
+ "22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45" +
+ "ee3688c11a8c56ab127a3daf", 16),
new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16),
new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7" +
- "a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d366844577" +
- "1f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a" +
- "7064f316933a346d3f529252", 16),
+ "a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d366844577" +
+ "1f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a" +
+ "7064f316933a346d3f529252", 16),
new DSAValidationParameters(Hex.decodeStrict("77d0f8c4dad15eb8c4f2f8d6726cefd96d5bb399"), 263));
DSAParameters def1024Params = new DSAParameters(
new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80" +
- "b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b" +
- "801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c6" +
- "1bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675" +
- "f3ae2b61d72aeff22203199dd14801c7", 16),
+ "b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b" +
+ "801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c6" +
+ "1bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675" +
+ "f3ae2b61d72aeff22203199dd14801c7", 16),
new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16),
new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b" +
- "3d0782675159578ebad4594fe67107108180b449167123e84c281613" +
- "b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f" +
- "0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06" +
- "928b665e807b552564014c3bfecf492a", 16),
+ "3d0782675159578ebad4594fe67107108180b449167123e84c281613" +
+ "b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f" +
+ "0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06" +
+ "928b665e807b552564014c3bfecf492a", 16),
new DSAValidationParameters(Hex.decodeStrict("8d5155894229d5e689ee01e6018a237e2cae64cd"), 92));
DSAParameters def2048Params = new DSAParameters(
new BigInteger("95475cf5d93e596c3fcd1d902add02f427f5f3c7210313bb45fb4d5b" +
- "b2e5fe1cbd678cd4bbdd84c9836be1f31c0777725aeb6c2fc38b85f4" +
- "8076fa76bcd8146cc89a6fb2f706dd719898c2083dc8d896f84062e2" +
- "c9c94d137b054a8d8096adb8d51952398eeca852a0af12df83e475aa" +
- "65d4ec0c38a9560d5661186ff98b9fc9eb60eee8b030376b236bc73b" +
- "e3acdbd74fd61c1d2475fa3077b8f080467881ff7e1ca56fee066d79" +
- "506ade51edbb5443a563927dbc4ba520086746175c8885925ebc64c6" +
- "147906773496990cb714ec667304e261faee33b3cbdf008e0c3fa906" +
- "50d97d3909c9275bf4ac86ffcb3d03e6dfc8ada5934242dd6d3bcca2" +
- "a406cb0b", 16),
+ "b2e5fe1cbd678cd4bbdd84c9836be1f31c0777725aeb6c2fc38b85f4" +
+ "8076fa76bcd8146cc89a6fb2f706dd719898c2083dc8d896f84062e2" +
+ "c9c94d137b054a8d8096adb8d51952398eeca852a0af12df83e475aa" +
+ "65d4ec0c38a9560d5661186ff98b9fc9eb60eee8b030376b236bc73b" +
+ "e3acdbd74fd61c1d2475fa3077b8f080467881ff7e1ca56fee066d79" +
+ "506ade51edbb5443a563927dbc4ba520086746175c8885925ebc64c6" +
+ "147906773496990cb714ec667304e261faee33b3cbdf008e0c3fa906" +
+ "50d97d3909c9275bf4ac86ffcb3d03e6dfc8ada5934242dd6d3bcca2" +
+ "a406cb0b", 16),
new BigInteger("f8183668ba5fc5bb06b5981e6d8b795d30b8978d43ca0ec572e37e09939a9773", 16),
new BigInteger("42debb9da5b3d88cc956e08787ec3f3a09bba5f48b889a74aaf53174" +
- "aa0fbe7e3c5b8fcd7a53bef563b0e98560328960a9517f4014d3325f" +
- "c7962bf1e049370d76d1314a76137e792f3f0db859d095e4a5b93202" +
- "4f079ecf2ef09c797452b0770e1350782ed57ddf794979dcef23cb96" +
- "f183061965c4ebc93c9c71c56b925955a75f94cccf1449ac43d586d0" +
- "beee43251b0b2287349d68de0d144403f13e802f4146d882e057af19" +
- "b6f6275c6676c8fa0e3ca2713a3257fd1b27d0639f695e347d8d1cf9" +
- "ac819a26ca9b04cb0eb9b7b035988d15bbac65212a55239cfc7e58fa" +
- "e38d7250ab9991ffbc97134025fe8ce04c4399ad96569be91a546f49" +
- "78693c7a", 16),
+ "aa0fbe7e3c5b8fcd7a53bef563b0e98560328960a9517f4014d3325f" +
+ "c7962bf1e049370d76d1314a76137e792f3f0db859d095e4a5b93202" +
+ "4f079ecf2ef09c797452b0770e1350782ed57ddf794979dcef23cb96" +
+ "f183061965c4ebc93c9c71c56b925955a75f94cccf1449ac43d586d0" +
+ "beee43251b0b2287349d68de0d144403f13e802f4146d882e057af19" +
+ "b6f6275c6676c8fa0e3ca2713a3257fd1b27d0639f695e347d8d1cf9" +
+ "ac819a26ca9b04cb0eb9b7b035988d15bbac65212a55239cfc7e58fa" +
+ "e38d7250ab9991ffbc97134025fe8ce04c4399ad96569be91a546f49" +
+ "78693c7a", 16),
new DSAValidationParameters(Hex.decodeStrict("b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536"), 497));
localSetGlobalProperty(Property.DSA_DEFAULT_PARAMS, def512Params, def768Params, def1024Params, def2048Params);
localSetGlobalProperty(Property.DH_DEFAULT_PARAMS, toDH(def512Params), toDH(def768Params), toDH(def1024Params), toDH(def2048Params));
+
+ servicesConstraints.set(getDefaultConstraints());
+ preconfiguredConstraints = (servicesConstraints.get() != noConstraintsImpl);
}
private CryptoServicesRegistrar()
@@ -109,25 +129,9 @@
*/
public static SecureRandom getSecureRandom()
{
- synchronized (cacheLock)
- {
- if (null != defaultSecureRandom)
- {
- return defaultSecureRandom;
- }
- }
+ defaultSecureRandomProvider.compareAndSet(null, defaultRandomProviderImpl);
- SecureRandom tmp = new SecureRandom();
-
- synchronized (cacheLock)
- {
- if (null == defaultSecureRandom)
- {
- defaultSecureRandom = tmp;
- }
-
- return defaultSecureRandom;
- }
+ return defaultSecureRandomProvider.get().get();
}
/**
@@ -146,13 +150,83 @@
*
* @param secureRandom the SecureRandom to use as the default.
*/
- public static void setSecureRandom(SecureRandom secureRandom)
+ public static void setSecureRandom(final SecureRandom secureRandom)
{
checkPermission(CanSetDefaultRandom);
- synchronized (cacheLock)
+ if (secureRandom == null)
{
- defaultSecureRandom = secureRandom;
+ defaultSecureRandomProvider.set(defaultRandomProviderImpl);
+ }
+ else
+ {
+ defaultSecureRandomProvider.set(new SecureRandomProvider()
+ {
+ public SecureRandom get()
+ {
+ return secureRandom;
+ }
+ });
+ }
+ }
+
+ /**
+ * Set a default secure random provider to be used where none is otherwise provided.
+ *
+ * @param secureRandomProvider a provider SecureRandom to use when a default SecureRandom is requested.
+ */
+ public static void setSecureRandomProvider(SecureRandomProvider secureRandomProvider)
+ {
+ checkPermission(CanSetDefaultRandom);
+
+ defaultSecureRandomProvider.set(secureRandomProvider);
+ }
+
+ /**
+ * Return the current algorithm/services constraints.
+ *
+ * @return the algorithm/services constraints.
+ */
+ public static CryptoServicesConstraints getServicesConstraints()
+ {
+ return servicesConstraints.get();
+ }
+
+ /**
+ * Check a service to make sure it meets the current constraints.
+ *
+ * @param cryptoService the service to be checked.
+ * @throws CryptoServiceConstraintsException if the service violates the current constraints.
+ */
+ public static void checkConstraints(CryptoServiceProperties cryptoService)
+ {
+ servicesConstraints.get().check(cryptoService);
+ }
+
+ /**
+ * Set the current algorithm constraints.
+ */
+ public static void setServicesConstraints(CryptoServicesConstraints constraints)
+ {
+ checkPermission(CanSetConstraints);
+
+ CryptoServicesConstraints newConstraints = (constraints == null) ? noConstraintsImpl : constraints;
+
+ if (preconfiguredConstraints)
+ {
+ if (Properties.isOverrideSet("com.android.org.bouncycastle.constraints.allow_override"))
+ {
+ servicesConstraints.set(newConstraints);
+ }
+ else
+ {
+ LOG.warning("attempt to override pre-configured constraints ignored");
+ }
+ }
+ else
+ {
+ // TODO: should this only be allowed once?
+ servicesConstraints.set(newConstraints);
}
}
@@ -161,7 +235,7 @@
* configuration first and then on the global configuration in no local configuration exists.
*
* @param property the property to look up.
- * @param <T> the type to be returned
+ * @param <T> the type to be returned
* @return null if the property is not set, the default value otherwise,
*/
public static <T> T getProperty(Property property)
@@ -197,7 +271,7 @@
* DSA_DEFAULT_PARAMS.
*
* @param property the name of the property to look up.
- * @param <T> the base type of the array to be returned.
+ * @param <T> the base type of the array to be returned.
* @return null if the property is not set, an array of the current values otherwise.
*/
public static <T> T[] getSizedProperty(Property property)
@@ -217,8 +291,8 @@
* DSA_DEFAULT_PARAMS.
*
* @param property the name of the property to look up.
- * @param size the size (in bits) of the defining value in the property type.
- * @param <T> the type of the value to be returned.
+ * @param size the size (in bits) of the defining value in the property type.
+ * @param <T> the type of the value to be returned.
* @return the current value for the size, null if there is no value set,
*/
public static <T> T getSizedProperty(Property property, int size)
@@ -263,9 +337,9 @@
* one value can be passed in for a sized property. If more than one value is provided the
* first value in the argument list becomes the default value.
*
- * @param property the name of the property to set.
+ * @param property the name of the property to set.
* @param propertyValue the values to assign to the property.
- * @param <T> the base type of the property value.
+ * @param <T> the base type of the property value.
*/
public static <T> void setThreadProperty(Property property, T... propertyValue)
{
@@ -284,9 +358,9 @@
* one value can be passed in for a sized property. If more than one value is provided the
* first value in the argument list becomes the default value.
*
- * @param property the name of the property to set.
+ * @param property the name of the property to set.
* @param propertyValue the values to assign to the property.
- * @param <T> the base type of the property value.
+ * @param <T> the base type of the property value.
*/
public static <T> void setGlobalProperty(Property property, T... propertyValue)
{
@@ -325,7 +399,7 @@
* Clear the global value for the passed in property.
*
* @param property the property to be cleared.
- * @param <T> the base type of the property value
+ * @param <T> the base type of the property value
* @return an array of T if a value was previously set, null otherwise.
*/
public static <T> T[] clearGlobalProperty(Property property)
@@ -342,7 +416,7 @@
* Clear the thread local value for the passed in property.
*
* @param property the property to be cleared.
- * @param <T> the base type of the property value
+ * @param <T> the base type of the property value
* @return an array of T if a value was previously set, null otherwise.
*/
public static <T> T[] clearThreadProperty(Property property)
@@ -417,6 +491,13 @@
return m;
}
+ private static CryptoServicesConstraints getDefaultConstraints()
+ {
+ // TODO: return one based on system/security properties if set.
+
+ return noConstraintsImpl;
+ }
+
/**
* Available properties that can be set.
* @hide This class is not part of the Android public SDK API
@@ -430,11 +511,11 @@
/**
* The default parameters for a particular size of Diffie-Hellman key.This is a sized property.
*/
- public static final Property DH_DEFAULT_PARAMS= new Property("dhDefaultParams", DHParameters.class);
+ public static final Property DH_DEFAULT_PARAMS = new Property("dhDefaultParams", DHParameters.class);
/**
* The default parameters for a particular size of DSA key. This is a sized property.
*/
- public static final Property DSA_DEFAULT_PARAMS= new Property("dsaDefaultParams", DSAParameters.class);
+ public static final Property DSA_DEFAULT_PARAMS = new Property("dsaDefaultParams", DSAParameters.class);
private final String name;
private final Class type;
@@ -444,4 +525,20 @@
this.type = type;
}
}
+
+ private static class ThreadLocalSecureRandomProvider
+ implements SecureRandomProvider
+ {
+ final ThreadLocal<SecureRandom> defaultRandoms = new ThreadLocal<SecureRandom>();
+
+ public SecureRandom get()
+ {
+ if (defaultRandoms.get() == null)
+ {
+ defaultRandoms.set(new SecureRandom());
+ }
+
+ return defaultRandoms.get();
+ }
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java
new file mode 100644
index 0000000..2107405
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java
@@ -0,0 +1,358 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+
+/**
+ * A wrapper class that allows block ciphers to be used to process data in
+ * a piecemeal fashion. The BufferedBlockCipher outputs a block only when the
+ * buffer is full and more data is being added, or on a doFinal.
+ * <p>
+ * Note: in the case where the underlying cipher is either a CFB cipher or an
+ * OFB one the last block may not be a multiple of the block size. Use this class
+ * for construction rather than BufferedBlockCipher as BufferedBlockCipher will eventually
+ * turn into an interface.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultBufferedBlockCipher
+ extends BufferedBlockCipher
+{
+ protected byte[] buf;
+ protected int bufOff;
+
+ protected boolean forEncryption;
+ protected BlockCipher cipher;
+ protected MultiBlockCipher mbCipher;
+
+ protected boolean partialBlockOkay;
+ protected boolean pgpCFB;
+
+ /**
+ * constructor for subclasses
+ */
+ protected DefaultBufferedBlockCipher()
+ {
+ }
+
+ /**
+ * Create a buffered block cipher without padding.
+ *
+ * @param cipher the underlying block cipher this buffering object wraps.
+ */
+ public DefaultBufferedBlockCipher(
+ BlockCipher cipher)
+ {
+ this.cipher = cipher;
+
+ if (cipher instanceof MultiBlockCipher)
+ {
+ this.mbCipher = (MultiBlockCipher)cipher;
+ buf = new byte[mbCipher.getMultiBlockSize()];
+ }
+ else
+ {
+ this.mbCipher = null;
+ buf = new byte[cipher.getBlockSize()];
+ }
+
+ bufOff = 0;
+
+ //
+ // check if we can handle partial blocks on doFinal.
+ //
+ String name = cipher.getAlgorithmName();
+ int idx = name.indexOf('/') + 1;
+
+ pgpCFB = (idx > 0 && name.startsWith("PGP", idx));
+
+ if (pgpCFB || cipher instanceof StreamCipher)
+ {
+ partialBlockOkay = true;
+ }
+ else
+ {
+ partialBlockOkay = (idx > 0 && (name.startsWith("OpenPGP", idx)));
+ }
+ }
+
+ /**
+ * return the cipher this object wraps.
+ *
+ * @return the cipher this object wraps.
+ */
+ public BlockCipher getUnderlyingCipher()
+ {
+ return cipher;
+ }
+
+ /**
+ * initialise the cipher.
+ *
+ * @param forEncryption if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param params the key and other data required by the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters params)
+ throws IllegalArgumentException
+ {
+ this.forEncryption = forEncryption;
+
+ reset();
+
+ cipher.init(forEncryption, params);
+ }
+
+ /**
+ * return the blocksize for the underlying cipher.
+ *
+ * @return the blocksize for the underlying cipher.
+ */
+ public int getBlockSize()
+ {
+ return cipher.getBlockSize();
+ }
+
+ /**
+ * return the size of the output buffer required for an update
+ * an input of len bytes.
+ *
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to update
+ * with len bytes of input.
+ */
+ public int getUpdateOutputSize(
+ int len)
+ {
+ int total = len + bufOff;
+ int leftOver;
+
+ if (pgpCFB)
+ {
+ if (forEncryption)
+ {
+ leftOver = total % buf.length - (cipher.getBlockSize() + 2);
+ }
+ else
+ {
+ leftOver = total % buf.length;
+ }
+ }
+ else
+ {
+ leftOver = total % buf.length;
+ }
+
+ return total - leftOver;
+ }
+
+ /**
+ * return the size of the output buffer required for an update plus a
+ * doFinal with an input of 'length' bytes.
+ *
+ * @param length the length of the input.
+ * @return the space required to accommodate a call to update and doFinal
+ * with 'length' bytes of input.
+ */
+ public int getOutputSize(
+ int length)
+ {
+ if (pgpCFB && forEncryption)
+ {
+ return length + bufOff + (cipher.getBlockSize() + 2);
+ }
+
+ // Note: Can assume partialBlockOkay is true for purposes of this calculation
+ return length + bufOff;
+ }
+
+ /**
+ * process a single byte, producing an output block if necessary.
+ *
+ * @param in the input byte.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processByte(
+ byte in,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ int resultLen = 0;
+
+ buf[bufOff++] = in;
+
+ if (bufOff == buf.length)
+ {
+ resultLen = cipher.processBlock(buf, 0, out, outOff);
+ bufOff = 0;
+ }
+
+ return resultLen;
+ }
+
+ /**
+ * process an array of bytes, producing output if necessary.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset at which the input data starts.
+ * @param len the number of bytes to be copied out of the input array.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processBytes(
+ byte[] in,
+ int inOff,
+ int len,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Can't have a negative input length!");
+ }
+
+ int blockSize = getBlockSize();
+ int length = getUpdateOutputSize(len);
+
+ if (length > 0)
+ {
+ if ((outOff + length) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ }
+
+ int resultLen = 0;
+ int gapLen = buf.length - bufOff;
+
+ if (len > gapLen)
+ {
+ System.arraycopy(in, inOff, buf, bufOff, gapLen);
+
+ resultLen += cipher.processBlock(buf, 0, out, outOff);
+
+ bufOff = 0;
+ len -= gapLen;
+ inOff += gapLen;
+
+ if (mbCipher != null)
+ {
+ int blockCount = len / mbCipher.getMultiBlockSize();
+
+ if (blockCount > 0)
+ {
+ resultLen += mbCipher.processBlocks(in, inOff, blockCount, out, outOff + resultLen);
+
+ int processed = blockCount * mbCipher.getMultiBlockSize();
+
+ len -= processed;
+ inOff += processed;
+ }
+ }
+ else
+ {
+ while (len > buf.length)
+ {
+ resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen);
+
+ len -= blockSize;
+ inOff += blockSize;
+ }
+ }
+ }
+
+ System.arraycopy(in, inOff, buf, bufOff, len);
+
+ bufOff += len;
+
+ if (bufOff == buf.length)
+ {
+ resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen);
+ bufOff = 0;
+ }
+
+ return resultLen;
+ }
+
+ /**
+ * Process the last block in the buffer.
+ *
+ * @param out the array the block currently being held is copied into.
+ * @param outOff the offset at which the copying starts.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there is insufficient space in out for
+ * the output, or the input is not block size aligned and should be.
+ * @exception IllegalStateException if the underlying cipher is not
+ * initialised.
+ * @exception InvalidCipherTextException if padding is expected and not found.
+ * @exception DataLengthException if the input is not block size
+ * aligned.
+ */
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException, InvalidCipherTextException
+ {
+ try
+ {
+ int resultLen = 0;
+
+ if (outOff + bufOff > out.length)
+ {
+ throw new OutputLengthException("output buffer too short for doFinal()");
+ }
+
+ if (bufOff != 0)
+ {
+ if (!partialBlockOkay)
+ {
+ throw new DataLengthException("data not block size aligned");
+ }
+
+ cipher.processBlock(buf, 0, buf, 0);
+ resultLen = bufOff;
+ bufOff = 0;
+ System.arraycopy(buf, 0, out, outOff, resultLen);
+ }
+
+ return resultLen;
+ }
+ finally
+ {
+ reset();
+ }
+ }
+
+ /**
+ * Reset the buffer and cipher. After resetting the object is in the same
+ * state as it was after the last init (if there was one).
+ */
+ public void reset()
+ {
+ //
+ // clean the buffer.
+ //
+ for (int i = 0; i < buf.length; i++)
+ {
+ buf[i] = 0;
+ }
+
+ bufOff = 0;
+
+ //
+ // reset the underlying cipher.
+ //
+ cipher.reset();
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/DefaultMultiBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/DefaultMultiBlockCipher.java
new file mode 100644
index 0000000..bf1de96
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/DefaultMultiBlockCipher.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class DefaultMultiBlockCipher
+ implements MultiBlockCipher
+{
+ protected DefaultMultiBlockCipher()
+ {
+ }
+
+ public int getMultiBlockSize()
+ {
+ return this.getBlockSize();
+ }
+
+ public int processBlocks(byte[] in, int inOff, int blockCount, byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+
+ // TODO check if the underlying cipher supports the multiblock interface and call it directly?
+
+ int resultLen = 0;
+ int blockSize = this.getMultiBlockSize();
+
+ for (int i = 0; i != blockCount; i++)
+ {
+ resultLen += this.processBlock(in, inOff, out, outOff + resultLen);
+
+ inOff += blockSize;
+ }
+
+ return resultLen;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/EncapsulatedSecretExtractor.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/EncapsulatedSecretExtractor.java
new file mode 100644
index 0000000..215dc09
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/EncapsulatedSecretExtractor.java
@@ -0,0 +1,22 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface EncapsulatedSecretExtractor
+{
+ /**
+ * Extract the secret based on the recipient private key.
+ *
+ * @param encapsulation the encapsulated secret.
+ */
+ byte[] extractSecret(byte[] encapsulation);
+
+ /**
+ * Return the length in bytes of the encapsulation.
+ *
+ * @return length in bytes of an encapsulation for this parameter set.
+ */
+ int getEncapsulationLength();
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/EncapsulatedSecretGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/EncapsulatedSecretGenerator.java
new file mode 100644
index 0000000..d94b70b
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/EncapsulatedSecretGenerator.java
@@ -0,0 +1,17 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+import com.android.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface EncapsulatedSecretGenerator
+{
+ /**
+ * Generate secret/encapsulation based on the recipient public key.
+ *
+ * @return An SecretWithEncapsulation derived from the recipient public key.
+ */
+ SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey);
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/MultiBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/MultiBlockCipher.java
new file mode 100644
index 0000000..128bc4b
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/MultiBlockCipher.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+/**
+ * Base interface for a cipher engine capable of processing multiple blocks at a time.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface MultiBlockCipher
+ extends BlockCipher
+{
+ /**
+ * Return the multi-block size for this cipher (in bytes).
+ *
+ * @return the multi-block size for this cipher in bytes.
+ */
+ int getMultiBlockSize();
+
+ /**
+ * Process blockCount blocks from input in offset inOff and place the output in
+ * out from offset outOff.
+ *
+ * @param in input data array.
+ * @param inOff start of input data in in.
+ * @param blockCount number of blocks to be processed.
+ * @param out output data array.
+ * @param outOff start position for output data.
+ * @return number of bytes written to out.
+ * @throws DataLengthException
+ * @throws IllegalStateException
+ */
+ int processBlocks(byte[] in, int inOff, int blockCount, byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException;
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/SavableDigest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/SavableDigest.java
new file mode 100644
index 0000000..1d03a68
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/SavableDigest.java
@@ -0,0 +1,15 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+import com.android.org.bouncycastle.crypto.digests.EncodableDigest;
+import com.android.org.bouncycastle.util.Memoable;
+
+/**
+ * Extended digest which provides the ability to store state and
+ * provide an encoding.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface SavableDigest
+ extends ExtendedDigest, EncodableDigest, Memoable
+{
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/SecretWithEncapsulation.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/SecretWithEncapsulation.java
new file mode 100644
index 0000000..78debf9
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/SecretWithEncapsulation.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+import javax.security.auth.Destroyable;
+
+/**
+ * Interface describing secret with encapsulation details.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface SecretWithEncapsulation
+ extends Destroyable
+{
+ /**
+ * Return the secret associated with the encapsulation.
+ *
+ * @return the secret the encapsulation is for.
+ */
+ byte[] getSecret();
+
+ /**
+ * Return the data that carries the secret in its encapsulated form.
+ *
+ * @return the encapsulation of the secret.
+ */
+ byte[] getEncapsulation();
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/SecureRandomProvider.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/SecureRandomProvider.java
new file mode 100644
index 0000000..b837cc2
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/SecureRandomProvider.java
@@ -0,0 +1,17 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+import java.security.SecureRandom;
+
+/**
+ * Source provider for SecureRandom implementations.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface SecureRandomProvider
+{
+ /**
+ * Return a SecureRandom instance.
+ * @return a SecureRandom
+ */
+ SecureRandom get();
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/StreamBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/StreamBlockCipher.java
index 513ca36..7835b6b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/StreamBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/StreamBlockCipher.java
@@ -7,7 +7,8 @@
* @hide This class is not part of the Android public SDK API
*/
public abstract class StreamBlockCipher
- implements BlockCipher, StreamCipher
+ extends DefaultMultiBlockCipher
+ implements StreamCipher
{
private final BlockCipher cipher;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/agreement/DHBasicAgreement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
index 87d4b77..fe57b37 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
@@ -5,6 +5,7 @@
import com.android.org.bouncycastle.crypto.BasicAgreement;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import com.android.org.bouncycastle.crypto.params.DHParameters;
import com.android.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
@@ -49,6 +50,8 @@
this.key = (DHPrivateKeyParameters)kParam;
this.dhParams = key.getParameters();
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("DHB", key));
}
public int getFieldSize()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
index 824dc4b..fcba1aa 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
@@ -5,6 +5,7 @@
import com.android.org.bouncycastle.crypto.BasicAgreement;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
import com.android.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import com.android.org.bouncycastle.crypto.params.ECPublicKeyParameters;
@@ -36,6 +37,8 @@
CipherParameters key)
{
this.key = (ECPrivateKeyParameters)key;
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("ECDH", this.key));
}
public int getFieldSize()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/agreement/Utils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/agreement/Utils.java
new file mode 100644
index 0000000..329b7db
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/agreement/Utils.java
@@ -0,0 +1,41 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.agreement;
+
+import com.android.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import com.android.org.bouncycastle.crypto.params.DHKeyParameters;
+import com.android.org.bouncycastle.crypto.params.ECKeyParameters;
+// Android-removed: unsupported algorithms
+// import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
+// import org.bouncycastle.crypto.params.X448PrivateKeyParameters;
+
+class Utils
+{
+ static CryptoServiceProperties getDefaultProperties(String algorithm, ECKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getCurve()), k, CryptoServicePurpose.AGREEMENT);
+ }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, DHKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getP()), k, CryptoServicePurpose.AGREEMENT);
+ }
+
+ // BEGIN Android-removed: unsupported algorithms
+ /*
+ static CryptoServiceProperties getDefaultProperties(String algorithm, X448PrivateKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, 224, k, CryptoServicePurpose.AGREEMENT);
+ }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, X25519PrivateKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, 128, k, CryptoServicePurpose.AGREEMENT);
+ }
+ */
+ // END Android-removed: unsupported algorithms
+}
+
+
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/constraints/ConstraintUtils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/constraints/ConstraintUtils.java
new file mode 100644
index 0000000..24eb1c2
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/constraints/ConstraintUtils.java
@@ -0,0 +1,51 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.constraints;
+
+import java.math.BigInteger;
+
+import com.android.org.bouncycastle.math.ec.ECCurve;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ConstraintUtils
+{
+ /**
+ * Return the bits of security for the passed in RSA modulus or DH/DSA group value.
+ *
+ * @param p a modulus or group value
+ * @return the security strength in bits.
+ */
+ public static int bitsOfSecurityFor(BigInteger p)
+ {
+ return bitsOfSecurityForFF(p.bitLength());
+ }
+
+ /**
+ * Return the bits of security for the passed in Elliptic Curve.
+ *
+ * @param curve the ECCurve of interest.
+ * @return the security strength in bits.
+ */
+ public static int bitsOfSecurityFor(ECCurve curve)
+ {
+ int sBits = (curve.getFieldSize() + 1) / 2;
+
+ return (sBits > 256) ? 256 : sBits;
+ }
+
+ public static int bitsOfSecurityForFF(int strength)
+ {
+ if (strength >= 2048)
+ {
+ return (strength >= 3072) ?
+ ((strength >= 7680) ?
+ ((strength >= 15360) ? 256
+ : 192)
+ : 128)
+ : 112;
+ }
+
+ return (strength >= 1024) ? 80 : 20; // TODO: possibly a bit harsh...
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/constraints/DefaultServiceProperties.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/constraints/DefaultServiceProperties.java
new file mode 100644
index 0000000..21fe865
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/constraints/DefaultServiceProperties.java
@@ -0,0 +1,59 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.constraints;
+
+import com.android.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultServiceProperties
+ implements CryptoServiceProperties
+{
+ private final String algorithm;
+ private final int bitsOfSecurity;
+ private final Object params;
+ private final CryptoServicePurpose purpose;
+
+ public DefaultServiceProperties(String algorithm, int bitsOfSecurity)
+ {
+ this(algorithm, bitsOfSecurity, null, CryptoServicePurpose.ANY);
+ }
+
+ public DefaultServiceProperties(String algorithm, int bitsOfSecurity, Object params)
+ {
+ this(algorithm, bitsOfSecurity, params, CryptoServicePurpose.ANY);
+ }
+
+ public DefaultServiceProperties(String algorithm, int bitsOfSecurity, Object params, CryptoServicePurpose purpose)
+ {
+ this.algorithm = algorithm;
+ this.bitsOfSecurity = bitsOfSecurity;
+ this.params = params;
+ if (params instanceof CryptoServicePurpose)
+ {
+ throw new IllegalArgumentException("params should not be CryptoServicePurpose");
+ }
+ this.purpose = purpose;
+ }
+
+ public int bitsOfSecurity()
+ {
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return algorithm;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return purpose;
+ }
+
+ public Object getParams()
+ {
+ return params;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/AsconDigest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/AsconDigest.java
new file mode 100644
index 0000000..7e4f2b8
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/AsconDigest.java
@@ -0,0 +1,222 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.ExtendedDigest;
+import com.android.org.bouncycastle.crypto.OutputLengthException;
+
+/* ASCON v1.2 Digest, https://ascon.iaik.tugraz.at/ .
+ * <p>
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf
+ * <p>
+ * ASCON v1.2 Digest with reference to C Reference Impl from: https://github.com/ascon/ascon-c .
+ */
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AsconDigest
+ implements ExtendedDigest
+{
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public enum AsconParameters
+ {
+ AsconHash,
+ AsconHashA,
+ }
+
+ AsconParameters asconParameters;
+
+ public AsconDigest(AsconParameters parameters)
+ {
+ this.asconParameters = parameters;
+ switch (parameters)
+ {
+ case AsconHash:
+ ASCON_PB_ROUNDS = 12;
+ algorithmName = "Ascon-Hash";
+ break;
+ case AsconHashA:
+ ASCON_PB_ROUNDS = 8;
+ algorithmName = "Ascon-HashA";
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid parameter settings for Ascon Hash");
+ }
+ reset();
+ }
+
+ private final String algorithmName;
+ private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ private long x0;
+ private long x1;
+ private long x2;
+ private long x3;
+ private long x4;
+ private final int CRYPTO_BYTES = 32;
+ private final int ASCON_PB_ROUNDS;
+
+ private long ROR(long x, int n)
+ {
+ return x >>> n | x << (64 - n);
+ }
+
+ private void ROUND(long C)
+ {
+ long t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
+ long t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
+ long t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
+ long t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
+ long t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
+ x0 = t0 ^ ROR(t0, 19) ^ ROR(t0, 28);
+ x1 = t1 ^ ROR(t1, 39) ^ ROR(t1, 61);
+ x2 = ~(t2 ^ ROR(t2, 1) ^ ROR(t2, 6));
+ x3 = t3 ^ ROR(t3, 10) ^ ROR(t3, 17);
+ x4 = t4 ^ ROR(t4, 7) ^ ROR(t4, 41);
+ }
+
+ private void P(int nr)
+ {
+ if (nr == 12)
+ {
+ ROUND(0xf0L);
+ ROUND(0xe1L);
+ ROUND(0xd2L);
+ ROUND(0xc3L);
+ }
+ if (nr >= 8)
+ {
+ ROUND(0xb4L);
+ ROUND(0xa5L);
+ }
+ ROUND(0x96L);
+ ROUND(0x87L);
+ ROUND(0x78L);
+ ROUND(0x69L);
+ ROUND(0x5aL);
+ ROUND(0x4bL);
+ }
+
+ private long PAD(int i)
+ {
+ return 0x80L << (56 - (i << 3));
+ }
+
+ private long LOADBYTES(final byte[] bytes, int inOff, int n)
+ {
+ long x = 0;
+ for (int i = 0; i < n; ++i)
+ {
+ x |= (bytes[i + inOff] & 0xFFL) << ((7 - i) << 3);
+ }
+ return x;
+ }
+
+ private void STOREBYTES(byte[] bytes, int inOff, long w, int n)
+ {
+ for (int i = 0; i < n; ++i)
+ {
+ bytes[i + inOff] = (byte)(w >>> ((7 - i) << 3));
+ }
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return algorithmName;
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return CRYPTO_BYTES;
+ }
+
+ @Override
+ public int getByteLength()
+ {
+ return 8;
+ }
+
+ @Override
+ public void update(byte in)
+ {
+ buffer.write(in);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+ }
+
+ @Override
+ public int doFinal(byte[] output, int outOff)
+ {
+ if (CRYPTO_BYTES + outOff > output.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ byte[] input = buffer.toByteArray();
+ int len = buffer.size();
+ int inOff = 0;
+ /* absorb full plaintext blocks */
+ int ASCON_HASH_RATE = 8;
+ while (len >= ASCON_HASH_RATE)
+ {
+ x0 ^= LOADBYTES(input, inOff, 8);
+ P(ASCON_PB_ROUNDS);
+ inOff += ASCON_HASH_RATE;
+ len -= ASCON_HASH_RATE;
+ }
+ /* absorb final plaintext block */
+ x0 ^= LOADBYTES(input, inOff, len);
+ x0 ^= PAD(len);
+ int ASCON_PA_ROUNDS = 12;
+ P(ASCON_PA_ROUNDS);
+ /* squeeze full output blocks */
+ len = CRYPTO_BYTES;
+ while (len > ASCON_HASH_RATE)
+ {
+ STOREBYTES(output, outOff, x0, 8);
+ P(ASCON_PB_ROUNDS);
+ outOff += ASCON_HASH_RATE;
+ len -= ASCON_HASH_RATE;
+ }
+ /* squeeze final output block */
+ STOREBYTES(output, outOff, x0, len);
+ reset();
+ return CRYPTO_BYTES;
+ }
+
+ @Override
+ public void reset()
+ {
+ buffer.reset();
+ /* initialize */
+ switch (asconParameters)
+ {
+ case AsconHashA:
+ x0 = 92044056785660070L;
+ x1 = 8326807761760157607L;
+ x2 = 3371194088139667532L;
+ x3 = -2956994353054992515L;
+ x4 = -6828509670848688761L;
+ break;
+ case AsconHash:
+ x0 = -1255492011513352131L;
+ x1 = -8380609354527731710L;
+ x2 = -5437372128236807582L;
+ x3 = 4834782570098516968L;
+ x4 = 3787428097924915520L;
+ break;
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/GeneralDigest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/GeneralDigest.java
index c075dce..9a1b9bf 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/GeneralDigest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/GeneralDigest.java
@@ -1,4 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: maintain old behaviour
package com.android.org.bouncycastle.crypto.digests;
import com.android.org.bouncycastle.crypto.ExtendedDigest;
@@ -160,3 +161,4 @@
protected abstract void processBlock();
}
+// END Android-changed: maintain old behaviour
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/Haraka256Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/Haraka256Digest.java
new file mode 100644
index 0000000..61fa962
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/Haraka256Digest.java
@@ -0,0 +1,156 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.digests;
+
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Bytes;
+
+/**
+ * Haraka-256 v2, https://eprint.iacr.org/2016/098.pdf
+ * <p>
+ * Haraka256-256 with reference to Python Reference Impl from: https://github.com/kste/haraka
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Haraka256Digest
+ extends HarakaBase
+{
+ private void mix256(byte[][] s1, byte[][] s2)
+ {
+ System.arraycopy(s1[0], 0, s2[0], 0, 4);
+ System.arraycopy(s1[1], 0, s2[0], 4, 4);
+ System.arraycopy(s1[0], 4, s2[0], 8, 4);
+ System.arraycopy(s1[1], 4, s2[0], 12, 4);
+
+ System.arraycopy(s1[0], 8, s2[1], 0, 4);
+ System.arraycopy(s1[1], 8, s2[1], 4, 4);
+ System.arraycopy(s1[0], 12, s2[1], 8, 4);
+ System.arraycopy(s1[1], 12, s2[1], 12, 4);
+ }
+
+ private int haraka256256(byte[] msg, byte[] out, int outOff)
+ {
+ byte[][] s1 = new byte[2][16];
+ byte[][] s2 = new byte[2][16];
+
+ System.arraycopy(msg, 0, s1[0], 0, 16);
+ System.arraycopy(msg, 16, s1[1], 0, 16);
+
+ s1[0] = aesEnc(s1[0], RC[0]);
+ s1[1] = aesEnc(s1[1], RC[1]);
+ s1[0] = aesEnc(s1[0], RC[2]);
+ s1[1] = aesEnc(s1[1], RC[3]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[4]);
+ s1[1] = aesEnc(s2[1], RC[5]);
+ s1[0] = aesEnc(s1[0], RC[6]);
+ s1[1] = aesEnc(s1[1], RC[7]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[8]);
+ s1[1] = aesEnc(s2[1], RC[9]);
+ s1[0] = aesEnc(s1[0], RC[10]);
+ s1[1] = aesEnc(s1[1], RC[11]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[12]);
+ s1[1] = aesEnc(s2[1], RC[13]);
+ s1[0] = aesEnc(s1[0], RC[14]);
+ s1[1] = aesEnc(s1[1], RC[15]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[16]);
+ s1[1] = aesEnc(s2[1], RC[17]);
+ s1[0] = aesEnc(s1[0], RC[18]);
+ s1[1] = aesEnc(s1[1], RC[19]);
+ mix256(s1, s2);
+
+ Bytes.xor(16, s2[0], 0, msg, 0, out, outOff);
+ Bytes.xor(16, s2[1], 0, msg, 16, out, outOff + 16);
+
+ return DIGEST_SIZE;
+ }
+
+ private final byte[] buffer;
+ private int off;
+
+ private final CryptoServicePurpose purpose;
+
+
+ public Haraka256Digest()
+ {
+ this(CryptoServicePurpose.ANY);
+ }
+
+ public Haraka256Digest(CryptoServicePurpose purpose)
+ {
+ this.purpose = purpose;
+
+ this.buffer = new byte[32];
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties(this, getDigestSize()*4, purpose));
+ }
+
+ public Haraka256Digest(Haraka256Digest digest)
+ {
+ this.purpose = digest.purpose;
+
+ this.buffer = Arrays.clone(digest.buffer);
+ this.off = digest.off;
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties(this, getDigestSize()*4, purpose));
+ }
+
+ public String getAlgorithmName()
+ {
+ return "Haraka-256";
+ }
+
+ public void update(byte in)
+ {
+ if (off > 32 - 1)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 32 bytes");
+ }
+
+ buffer[off++] = in;
+ }
+
+ public void update(byte[] in, int inOff, int len)
+ {
+ if (off > 32 - len)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 32 bytes");
+ }
+
+ System.arraycopy(in, inOff, buffer, off, len);
+ off += len;
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ {
+ if (off != 32)
+ {
+ throw new IllegalStateException("input must be exactly 32 bytes");
+ }
+
+ if (out.length - outOff < 32)
+ {
+ throw new IllegalArgumentException("output too short to receive digest");
+ }
+
+ int rv = haraka256256(buffer, out, outOff);
+
+ reset();
+
+ return rv;
+ }
+
+ public void reset()
+ {
+ off = 0;
+ Arrays.clear(buffer);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/Haraka512Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/Haraka512Digest.java
new file mode 100644
index 0000000..5035ed3
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/Haraka512Digest.java
@@ -0,0 +1,191 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.digests;
+
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Bytes;
+
+/**
+ * Haraka-512 v2, https://eprint.iacr.org/2016/098.pdf
+ * <p>
+ * Haraka512-256 with reference to Python Reference Impl from: https://github.com/kste/haraka
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Haraka512Digest
+ extends HarakaBase
+{
+ private final byte[] buffer;
+ private int off;
+
+ private final CryptoServicePurpose purpose;
+
+
+ public Haraka512Digest()
+ {
+ this(CryptoServicePurpose.ANY);
+ }
+ public Haraka512Digest(CryptoServicePurpose purpose)
+ {
+ this.purpose = purpose;
+
+ this.buffer = new byte[64];
+ }
+
+ public Haraka512Digest(Haraka512Digest digest)
+ {
+ this.purpose = digest.purpose;
+
+ this.buffer = Arrays.clone(digest.buffer);
+ this.off = digest.off;
+ }
+
+ private void mix512(byte[][] s1, byte[][] s2)
+ {
+ System.arraycopy(s1[0], 12, s2[0], 0, 4);
+ System.arraycopy(s1[2], 12, s2[0], 4, 4);
+ System.arraycopy(s1[1], 12, s2[0], 8, 4);
+ System.arraycopy(s1[3], 12, s2[0], 12, 4);
+
+ System.arraycopy(s1[2], 0, s2[1], 0, 4);
+ System.arraycopy(s1[0], 0, s2[1], 4, 4);
+ System.arraycopy(s1[3], 0, s2[1], 8, 4);
+ System.arraycopy(s1[1], 0, s2[1], 12, 4);
+
+ System.arraycopy(s1[2], 4, s2[2], 0, 4);
+ System.arraycopy(s1[0], 4, s2[2], 4, 4);
+ System.arraycopy(s1[3], 4, s2[2], 8, 4);
+ System.arraycopy(s1[1], 4, s2[2], 12, 4);
+
+ System.arraycopy(s1[0], 8, s2[3], 0, 4);
+ System.arraycopy(s1[2], 8, s2[3], 4, 4);
+ System.arraycopy(s1[1], 8, s2[3], 8, 4);
+ System.arraycopy(s1[3], 8, s2[3], 12, 4);
+ }
+
+ private int haraka512256(byte[] msg, byte[] out, int outOff)
+ {
+ byte[][] s1 = new byte[4][16];
+ byte[][] s2 = new byte[4][16];
+
+ //-- Unrolled version of above.
+
+ System.arraycopy(msg, 0, s1[0], 0, 16);
+ System.arraycopy(msg, 16, s1[1], 0, 16);
+ System.arraycopy(msg, 32, s1[2], 0, 16);
+ System.arraycopy(msg, 48, s1[3], 0, 16);
+
+ s1[0] = aesEnc(s1[0], RC[0]);
+ s1[1] = aesEnc(s1[1], RC[1]);
+ s1[2] = aesEnc(s1[2], RC[2]);
+ s1[3] = aesEnc(s1[3], RC[3]);
+ s1[0] = aesEnc(s1[0], RC[4]);
+ s1[1] = aesEnc(s1[1], RC[5]);
+ s1[2] = aesEnc(s1[2], RC[6]);
+ s1[3] = aesEnc(s1[3], RC[7]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[8]);
+ s1[1] = aesEnc(s2[1], RC[9]);
+ s1[2] = aesEnc(s2[2], RC[10]);
+ s1[3] = aesEnc(s2[3], RC[11]);
+ s1[0] = aesEnc(s1[0], RC[12]);
+ s1[1] = aesEnc(s1[1], RC[13]);
+ s1[2] = aesEnc(s1[2], RC[14]);
+ s1[3] = aesEnc(s1[3], RC[15]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[16]);
+ s1[1] = aesEnc(s2[1], RC[17]);
+ s1[2] = aesEnc(s2[2], RC[18]);
+ s1[3] = aesEnc(s2[3], RC[19]);
+ s1[0] = aesEnc(s1[0], RC[20]);
+ s1[1] = aesEnc(s1[1], RC[21]);
+ s1[2] = aesEnc(s1[2], RC[22]);
+ s1[3] = aesEnc(s1[3], RC[23]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[24]);
+ s1[1] = aesEnc(s2[1], RC[25]);
+ s1[2] = aesEnc(s2[2], RC[26]);
+ s1[3] = aesEnc(s2[3], RC[27]);
+ s1[0] = aesEnc(s1[0], RC[28]);
+ s1[1] = aesEnc(s1[1], RC[29]);
+ s1[2] = aesEnc(s1[2], RC[30]);
+ s1[3] = aesEnc(s1[3], RC[31]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[32]);
+ s1[1] = aesEnc(s2[1], RC[33]);
+ s1[2] = aesEnc(s2[2], RC[34]);
+ s1[3] = aesEnc(s2[3], RC[35]);
+ s1[0] = aesEnc(s1[0], RC[36]);
+ s1[1] = aesEnc(s1[1], RC[37]);
+ s1[2] = aesEnc(s1[2], RC[38]);
+ s1[3] = aesEnc(s1[3], RC[39]);
+ mix512(s1, s2);
+
+ Bytes.xor(16, s2[0], 0, msg, 0, s1[0], 0);
+ Bytes.xor(16, s2[1], 0, msg, 16, s1[1], 0);
+ Bytes.xor(16, s2[2], 0, msg, 32, s1[2], 0);
+ Bytes.xor(16, s2[3], 0, msg, 48, s1[3], 0);
+
+ System.arraycopy(s1[0], 8, out, outOff, 8);
+ System.arraycopy(s1[1], 8, out, outOff + 8, 8);
+ System.arraycopy(s1[2], 0, out, outOff + 16, 8);
+ System.arraycopy(s1[3], 0, out, outOff + 24, 8);
+
+ return DIGEST_SIZE;
+ }
+
+ public String getAlgorithmName()
+ {
+ return "Haraka-512";
+ }
+
+ public void update(byte in)
+ {
+ if (off > 64 - 1)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 64 bytes");
+ }
+
+ buffer[off++] = in;
+ }
+
+ public void update(byte[] in, int inOff, int len)
+ {
+ if (off > 64 - len)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 64 bytes");
+ }
+
+ System.arraycopy(in, inOff, buffer, off, len);
+ off += len;
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ {
+ if (off != 64)
+ {
+ throw new IllegalStateException("input must be exactly 64 bytes");
+ }
+
+ if (out.length - outOff < 32)
+ {
+ throw new IllegalArgumentException("output too short to receive digest");
+ }
+
+ int rv = haraka512256(buffer, out, outOff);
+
+ reset();
+
+ return rv;
+ }
+
+ public void reset()
+ {
+ off = 0;
+ Arrays.clear(buffer);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/HarakaBase.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/HarakaBase.java
new file mode 100644
index 0000000..cd7f508
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/HarakaBase.java
@@ -0,0 +1,149 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.digests;
+
+import com.android.org.bouncycastle.crypto.Digest;
+import com.android.org.bouncycastle.util.Bytes;
+
+/**
+ * Base class for Haraka v2, https://eprint.iacr.org/2016/098.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class HarakaBase
+ implements Digest
+{
+ protected static final int DIGEST_SIZE = 32;
+
+ // Haraka round constants
+ static final byte[][] RC = new byte[][]
+ {
+ new byte[]{ (byte)0x9D, (byte)0x7B, (byte)0x81, (byte)0x75, (byte)0xF0, (byte)0xFE, (byte)0xC5, (byte)0xB2, (byte)0x0A, (byte)0xC0, (byte)0x20, (byte)0xE6, (byte)0x4C, (byte)0x70, (byte)0x84, (byte)0x06 },
+ new byte[]{ (byte)0x17, (byte)0xF7, (byte)0x08, (byte)0x2F, (byte)0xA4, (byte)0x6B, (byte)0x0F, (byte)0x64, (byte)0x6B, (byte)0xA0, (byte)0xF3, (byte)0x88, (byte)0xE1, (byte)0xB4, (byte)0x66, (byte)0x8B },
+ new byte[]{ (byte)0x14, (byte)0x91, (byte)0x02, (byte)0x9F, (byte)0x60, (byte)0x9D, (byte)0x02, (byte)0xCF, (byte)0x98, (byte)0x84, (byte)0xF2, (byte)0x53, (byte)0x2D, (byte)0xDE, (byte)0x02, (byte)0x34 },
+ new byte[]{ (byte)0x79, (byte)0x4F, (byte)0x5B, (byte)0xFD, (byte)0xAF, (byte)0xBC, (byte)0xF3, (byte)0xBB, (byte)0x08, (byte)0x4F, (byte)0x7B, (byte)0x2E, (byte)0xE6, (byte)0xEA, (byte)0xD6, (byte)0x0E },
+ new byte[]{ (byte)0x44, (byte)0x70, (byte)0x39, (byte)0xBE, (byte)0x1C, (byte)0xCD, (byte)0xEE, (byte)0x79, (byte)0x8B, (byte)0x44, (byte)0x72, (byte)0x48, (byte)0xCB, (byte)0xB0, (byte)0xCF, (byte)0xCB },
+ new byte[]{ (byte)0x7B, (byte)0x05, (byte)0x8A, (byte)0x2B, (byte)0xED, (byte)0x35, (byte)0x53, (byte)0x8D, (byte)0xB7, (byte)0x32, (byte)0x90, (byte)0x6E, (byte)0xEE, (byte)0xCD, (byte)0xEA, (byte)0x7E },
+ new byte[]{ (byte)0x1B, (byte)0xEF, (byte)0x4F, (byte)0xDA, (byte)0x61, (byte)0x27, (byte)0x41, (byte)0xE2, (byte)0xD0, (byte)0x7C, (byte)0x2E, (byte)0x5E, (byte)0x43, (byte)0x8F, (byte)0xC2, (byte)0x67 },
+ new byte[]{ (byte)0x3B, (byte)0x0B, (byte)0xC7, (byte)0x1F, (byte)0xE2, (byte)0xFD, (byte)0x5F, (byte)0x67, (byte)0x07, (byte)0xCC, (byte)0xCA, (byte)0xAF, (byte)0xB0, (byte)0xD9, (byte)0x24, (byte)0x29 },
+ new byte[]{ (byte)0xEE, (byte)0x65, (byte)0xD4, (byte)0xB9, (byte)0xCA, (byte)0x8F, (byte)0xDB, (byte)0xEC, (byte)0xE9, (byte)0x7F, (byte)0x86, (byte)0xE6, (byte)0xF1, (byte)0x63, (byte)0x4D, (byte)0xAB },
+ new byte[]{ (byte)0x33, (byte)0x7E, (byte)0x03, (byte)0xAD, (byte)0x4F, (byte)0x40, (byte)0x2A, (byte)0x5B, (byte)0x64, (byte)0xCD, (byte)0xB7, (byte)0xD4, (byte)0x84, (byte)0xBF, (byte)0x30, (byte)0x1C },
+ new byte[]{ (byte)0x00, (byte)0x98, (byte)0xF6, (byte)0x8D, (byte)0x2E, (byte)0x8B, (byte)0x02, (byte)0x69, (byte)0xBF, (byte)0x23, (byte)0x17, (byte)0x94, (byte)0xB9, (byte)0x0B, (byte)0xCC, (byte)0xB2 },
+ new byte[]{ (byte)0x8A, (byte)0x2D, (byte)0x9D, (byte)0x5C, (byte)0xC8, (byte)0x9E, (byte)0xAA, (byte)0x4A, (byte)0x72, (byte)0x55, (byte)0x6F, (byte)0xDE, (byte)0xA6, (byte)0x78, (byte)0x04, (byte)0xFA },
+ new byte[]{ (byte)0xD4, (byte)0x9F, (byte)0x12, (byte)0x29, (byte)0x2E, (byte)0x4F, (byte)0xFA, (byte)0x0E, (byte)0x12, (byte)0x2A, (byte)0x77, (byte)0x6B, (byte)0x2B, (byte)0x9F, (byte)0xB4, (byte)0xDF },
+ new byte[]{ (byte)0xEE, (byte)0x12, (byte)0x6A, (byte)0xBB, (byte)0xAE, (byte)0x11, (byte)0xD6, (byte)0x32, (byte)0x36, (byte)0xA2, (byte)0x49, (byte)0xF4, (byte)0x44, (byte)0x03, (byte)0xA1, (byte)0x1E },
+ new byte[]{ (byte)0xA6, (byte)0xEC, (byte)0xA8, (byte)0x9C, (byte)0xC9, (byte)0x00, (byte)0x96, (byte)0x5F, (byte)0x84, (byte)0x00, (byte)0x05, (byte)0x4B, (byte)0x88, (byte)0x49, (byte)0x04, (byte)0xAF },
+ new byte[]{ (byte)0xEC, (byte)0x93, (byte)0xE5, (byte)0x27, (byte)0xE3, (byte)0xC7, (byte)0xA2, (byte)0x78, (byte)0x4F, (byte)0x9C, (byte)0x19, (byte)0x9D, (byte)0xD8, (byte)0x5E, (byte)0x02, (byte)0x21 },
+ new byte[]{ (byte)0x73, (byte)0x01, (byte)0xD4, (byte)0x82, (byte)0xCD, (byte)0x2E, (byte)0x28, (byte)0xB9, (byte)0xB7, (byte)0xC9, (byte)0x59, (byte)0xA7, (byte)0xF8, (byte)0xAA, (byte)0x3A, (byte)0xBF },
+ new byte[]{ (byte)0x6B, (byte)0x7D, (byte)0x30, (byte)0x10, (byte)0xD9, (byte)0xEF, (byte)0xF2, (byte)0x37, (byte)0x17, (byte)0xB0, (byte)0x86, (byte)0x61, (byte)0x0D, (byte)0x70, (byte)0x60, (byte)0x62 },
+ new byte[]{ (byte)0xC6, (byte)0x9A, (byte)0xFC, (byte)0xF6, (byte)0x53, (byte)0x91, (byte)0xC2, (byte)0x81, (byte)0x43, (byte)0x04, (byte)0x30, (byte)0x21, (byte)0xC2, (byte)0x45, (byte)0xCA, (byte)0x5A },
+ new byte[]{ (byte)0x3A, (byte)0x94, (byte)0xD1, (byte)0x36, (byte)0xE8, (byte)0x92, (byte)0xAF, (byte)0x2C, (byte)0xBB, (byte)0x68, (byte)0x6B, (byte)0x22, (byte)0x3C, (byte)0x97, (byte)0x23, (byte)0x92 },
+ new byte[]{ (byte)0xB4, (byte)0x71, (byte)0x10, (byte)0xE5, (byte)0x58, (byte)0xB9, (byte)0xBA, (byte)0x6C, (byte)0xEB, (byte)0x86, (byte)0x58, (byte)0x22, (byte)0x38, (byte)0x92, (byte)0xBF, (byte)0xD3 },
+ new byte[]{ (byte)0x8D, (byte)0x12, (byte)0xE1, (byte)0x24, (byte)0xDD, (byte)0xFD, (byte)0x3D, (byte)0x93, (byte)0x77, (byte)0xC6, (byte)0xF0, (byte)0xAE, (byte)0xE5, (byte)0x3C, (byte)0x86, (byte)0xDB },
+ new byte[]{ (byte)0xB1, (byte)0x12, (byte)0x22, (byte)0xCB, (byte)0xE3, (byte)0x8D, (byte)0xE4, (byte)0x83, (byte)0x9C, (byte)0xA0, (byte)0xEB, (byte)0xFF, (byte)0x68, (byte)0x62, (byte)0x60, (byte)0xBB },
+ new byte[]{ (byte)0x7D, (byte)0xF7, (byte)0x2B, (byte)0xC7, (byte)0x4E, (byte)0x1A, (byte)0xB9, (byte)0x2D, (byte)0x9C, (byte)0xD1, (byte)0xE4, (byte)0xE2, (byte)0xDC, (byte)0xD3, (byte)0x4B, (byte)0x73 },
+ new byte[]{ (byte)0x4E, (byte)0x92, (byte)0xB3, (byte)0x2C, (byte)0xC4, (byte)0x15, (byte)0x14, (byte)0x4B, (byte)0x43, (byte)0x1B, (byte)0x30, (byte)0x61, (byte)0xC3, (byte)0x47, (byte)0xBB, (byte)0x43 },
+ new byte[]{ (byte)0x99, (byte)0x68, (byte)0xEB, (byte)0x16, (byte)0xDD, (byte)0x31, (byte)0xB2, (byte)0x03, (byte)0xF6, (byte)0xEF, (byte)0x07, (byte)0xE7, (byte)0xA8, (byte)0x75, (byte)0xA7, (byte)0xDB },
+ new byte[]{ (byte)0x2C, (byte)0x47, (byte)0xCA, (byte)0x7E, (byte)0x02, (byte)0x23, (byte)0x5E, (byte)0x8E, (byte)0x77, (byte)0x59, (byte)0x75, (byte)0x3C, (byte)0x4B, (byte)0x61, (byte)0xF3, (byte)0x6D },
+ new byte[]{ (byte)0xF9, (byte)0x17, (byte)0x86, (byte)0xB8, (byte)0xB9, (byte)0xE5, (byte)0x1B, (byte)0x6D, (byte)0x77, (byte)0x7D, (byte)0xDE, (byte)0xD6, (byte)0x17, (byte)0x5A, (byte)0xA7, (byte)0xCD },
+ new byte[]{ (byte)0x5D, (byte)0xEE, (byte)0x46, (byte)0xA9, (byte)0x9D, (byte)0x06, (byte)0x6C, (byte)0x9D, (byte)0xAA, (byte)0xE9, (byte)0xA8, (byte)0x6B, (byte)0xF0, (byte)0x43, (byte)0x6B, (byte)0xEC },
+ new byte[]{ (byte)0xC1, (byte)0x27, (byte)0xF3, (byte)0x3B, (byte)0x59, (byte)0x11, (byte)0x53, (byte)0xA2, (byte)0x2B, (byte)0x33, (byte)0x57, (byte)0xF9, (byte)0x50, (byte)0x69, (byte)0x1E, (byte)0xCB },
+ new byte[]{ (byte)0xD9, (byte)0xD0, (byte)0x0E, (byte)0x60, (byte)0x53, (byte)0x03, (byte)0xED, (byte)0xE4, (byte)0x9C, (byte)0x61, (byte)0xDA, (byte)0x00, (byte)0x75, (byte)0x0C, (byte)0xEE, (byte)0x2C },
+ new byte[]{ (byte)0x50, (byte)0xA3, (byte)0xA4, (byte)0x63, (byte)0xBC, (byte)0xBA, (byte)0xBB, (byte)0x80, (byte)0xAB, (byte)0x0C, (byte)0xE9, (byte)0x96, (byte)0xA1, (byte)0xA5, (byte)0xB1, (byte)0xF0 },
+ new byte[]{ (byte)0x39, (byte)0xCA, (byte)0x8D, (byte)0x93, (byte)0x30, (byte)0xDE, (byte)0x0D, (byte)0xAB, (byte)0x88, (byte)0x29, (byte)0x96, (byte)0x5E, (byte)0x02, (byte)0xB1, (byte)0x3D, (byte)0xAE },
+ new byte[]{ (byte)0x42, (byte)0xB4, (byte)0x75, (byte)0x2E, (byte)0xA8, (byte)0xF3, (byte)0x14, (byte)0x88, (byte)0x0B, (byte)0xA4, (byte)0x54, (byte)0xD5, (byte)0x38, (byte)0x8F, (byte)0xBB, (byte)0x17 },
+ new byte[]{ (byte)0xF6, (byte)0x16, (byte)0x0A, (byte)0x36, (byte)0x79, (byte)0xB7, (byte)0xB6, (byte)0xAE, (byte)0xD7, (byte)0x7F, (byte)0x42, (byte)0x5F, (byte)0x5B, (byte)0x8A, (byte)0xBB, (byte)0x34 },
+ new byte[]{ (byte)0xDE, (byte)0xAF, (byte)0xBA, (byte)0xFF, (byte)0x18, (byte)0x59, (byte)0xCE, (byte)0x43, (byte)0x38, (byte)0x54, (byte)0xE5, (byte)0xCB, (byte)0x41, (byte)0x52, (byte)0xF6, (byte)0x26 },
+ new byte[]{ (byte)0x78, (byte)0xC9, (byte)0x9E, (byte)0x83, (byte)0xF7, (byte)0x9C, (byte)0xCA, (byte)0xA2, (byte)0x6A, (byte)0x02, (byte)0xF3, (byte)0xB9, (byte)0x54, (byte)0x9A, (byte)0xE9, (byte)0x4C },
+ new byte[]{ (byte)0x35, (byte)0x12, (byte)0x90, (byte)0x22, (byte)0x28, (byte)0x6E, (byte)0xC0, (byte)0x40, (byte)0xBE, (byte)0xF7, (byte)0xDF, (byte)0x1B, (byte)0x1A, (byte)0xA5, (byte)0x51, (byte)0xAE },
+ new byte[]{ (byte)0xCF, (byte)0x59, (byte)0xA6, (byte)0x48, (byte)0x0F, (byte)0xBC, (byte)0x73, (byte)0xC1, (byte)0x2B, (byte)0xD2, (byte)0x7E, (byte)0xBA, (byte)0x3C, (byte)0x61, (byte)0xC1, (byte)0xA0 },
+ new byte[]{ (byte)0xA1, (byte)0x9D, (byte)0xC5, (byte)0xE9, (byte)0xFD, (byte)0xBD, (byte)0xD6, (byte)0x4A, (byte)0x88, (byte)0x82, (byte)0x28, (byte)0x02, (byte)0x03, (byte)0xCC, (byte)0x6A, (byte)0x75 },
+ };
+
+ private static final byte[][] S = new byte[][]{
+ { (byte)0x63, (byte)0x7C, (byte)0x77, (byte)0x7B, (byte)0xF2, (byte)0x6B, (byte)0x6F, (byte)0xC5, (byte)0x30, (byte)0x01, (byte)0x67, (byte)0x2B, (byte)0xFE, (byte)0xD7, (byte)0xAB, (byte)0x76 },
+ { (byte)0xCA, (byte)0x82, (byte)0xC9, (byte)0x7D, (byte)0xFA, (byte)0x59, (byte)0x47, (byte)0xF0, (byte)0xAD, (byte)0xD4, (byte)0xA2, (byte)0xAF, (byte)0x9C, (byte)0xA4, (byte)0x72, (byte)0xC0 },
+ { (byte)0xB7, (byte)0xFD, (byte)0x93, (byte)0x26, (byte)0x36, (byte)0x3F, (byte)0xF7, (byte)0xCC, (byte)0x34, (byte)0xA5, (byte)0xE5, (byte)0xF1, (byte)0x71, (byte)0xD8, (byte)0x31, (byte)0x15 },
+ { (byte)0x04, (byte)0xC7, (byte)0x23, (byte)0xC3, (byte)0x18, (byte)0x96, (byte)0x05, (byte)0x9A, (byte)0x07, (byte)0x12, (byte)0x80, (byte)0xE2, (byte)0xEB, (byte)0x27, (byte)0xB2, (byte)0x75 },
+ { (byte)0x09, (byte)0x83, (byte)0x2C, (byte)0x1A, (byte)0x1B, (byte)0x6E, (byte)0x5A, (byte)0xA0, (byte)0x52, (byte)0x3B, (byte)0xD6, (byte)0xB3, (byte)0x29, (byte)0xE3, (byte)0x2F, (byte)0x84 },
+ { (byte)0x53, (byte)0xD1, (byte)0x00, (byte)0xED, (byte)0x20, (byte)0xFC, (byte)0xB1, (byte)0x5B, (byte)0x6A, (byte)0xCB, (byte)0xBE, (byte)0x39, (byte)0x4A, (byte)0x4C, (byte)0x58, (byte)0xCF },
+ { (byte)0xD0, (byte)0xEF, (byte)0xAA, (byte)0xFB, (byte)0x43, (byte)0x4D, (byte)0x33, (byte)0x85, (byte)0x45, (byte)0xF9, (byte)0x02, (byte)0x7F, (byte)0x50, (byte)0x3C, (byte)0x9F, (byte)0xA8 },
+ { (byte)0x51, (byte)0xA3, (byte)0x40, (byte)0x8F, (byte)0x92, (byte)0x9D, (byte)0x38, (byte)0xF5, (byte)0xBC, (byte)0xB6, (byte)0xDA, (byte)0x21, (byte)0x10, (byte)0xFF, (byte)0xF3, (byte)0xD2 },
+ { (byte)0xCD, (byte)0x0C, (byte)0x13, (byte)0xEC, (byte)0x5F, (byte)0x97, (byte)0x44, (byte)0x17, (byte)0xC4, (byte)0xA7, (byte)0x7E, (byte)0x3D, (byte)0x64, (byte)0x5D, (byte)0x19, (byte)0x73 },
+ { (byte)0x60, (byte)0x81, (byte)0x4F, (byte)0xDC, (byte)0x22, (byte)0x2A, (byte)0x90, (byte)0x88, (byte)0x46, (byte)0xEE, (byte)0xB8, (byte)0x14, (byte)0xDE, (byte)0x5E, (byte)0x0B, (byte)0xDB },
+ { (byte)0xE0, (byte)0x32, (byte)0x3A, (byte)0x0A, (byte)0x49, (byte)0x06, (byte)0x24, (byte)0x5C, (byte)0xC2, (byte)0xD3, (byte)0xAC, (byte)0x62, (byte)0x91, (byte)0x95, (byte)0xE4, (byte)0x79 },
+ { (byte)0xE7, (byte)0xC8, (byte)0x37, (byte)0x6D, (byte)0x8D, (byte)0xD5, (byte)0x4E, (byte)0xA9, (byte)0x6C, (byte)0x56, (byte)0xF4, (byte)0xEA, (byte)0x65, (byte)0x7A, (byte)0xAE, (byte)0x08 },
+ { (byte)0xBA, (byte)0x78, (byte)0x25, (byte)0x2E, (byte)0x1C, (byte)0xA6, (byte)0xB4, (byte)0xC6, (byte)0xE8, (byte)0xDD, (byte)0x74, (byte)0x1F, (byte)0x4B, (byte)0xBD, (byte)0x8B, (byte)0x8A },
+ { (byte)0x70, (byte)0x3E, (byte)0xB5, (byte)0x66, (byte)0x48, (byte)0x03, (byte)0xF6, (byte)0x0E, (byte)0x61, (byte)0x35, (byte)0x57, (byte)0xB9, (byte)0x86, (byte)0xC1, (byte)0x1D, (byte)0x9E },
+ { (byte)0xE1, (byte)0xF8, (byte)0x98, (byte)0x11, (byte)0x69, (byte)0xD9, (byte)0x8E, (byte)0x94, (byte)0x9B, (byte)0x1E, (byte)0x87, (byte)0xE9, (byte)0xCE, (byte)0x55, (byte)0x28, (byte)0xDF },
+ { (byte)0x8C, (byte)0xA1, (byte)0x89, (byte)0x0D, (byte)0xBF, (byte)0xE6, (byte)0x42, (byte)0x68, (byte)0x41, (byte)0x99, (byte)0x2D, (byte)0x0F, (byte)0xB0, (byte)0x54, (byte)0xBB, (byte)0x16 },
+ };
+
+ static byte sBox(byte x)
+ {
+ return S[(((x & 0xFF) >>> 4))][x & 0xF];
+ }
+
+ static byte[] subBytes(byte[] s)
+ {
+ byte[] out = new byte[s.length];
+ out[0] = sBox(s[0]);
+ out[1] = sBox(s[1]);
+ out[2] = sBox(s[2]);
+ out[3] = sBox(s[3]);
+ out[4] = sBox(s[4]);
+ out[5] = sBox(s[5]);
+ out[6] = sBox(s[6]);
+ out[7] = sBox(s[7]);
+ out[8] = sBox(s[8]);
+ out[9] = sBox(s[9]);
+ out[10] = sBox(s[10]);
+ out[11] = sBox(s[11]);
+ out[12] = sBox(s[12]);
+ out[13] = sBox(s[13]);
+ out[14] = sBox(s[14]);
+ out[15] = sBox(s[15]);
+ return out;
+ }
+
+ static byte[] shiftRows(byte[] s)
+ {
+ return new byte[]{
+ s[0], s[5], s[10], s[15],
+ s[4], s[9], s[14], s[3],
+ s[8], s[13], s[2], s[7],
+ s[12], s[1], s[6], s[11]
+ };
+ }
+
+ static byte[] aesEnc(byte[] s, byte[] rk)
+ {
+ s = subBytes(s);
+ s = shiftRows(s);
+ s = mixColumns(s);
+ Bytes.xorTo(16, rk, s);
+ return s;
+ }
+
+ static byte mulX(byte p)
+ {
+ return (byte)(((p & 0x7F) << 1) ^ (((p & 0x80) >> 7) * 0x1B));
+ }
+
+ private static byte[] mixColumns(byte[] s)
+ {
+ byte[] out = new byte[s.length];
+ int j = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ out[j++] = (byte)(mulX(s[4 * i]) ^ mulX(s[4 * i + 1]) ^ s[4 * i + 1] ^ s[4 * i + 2] ^ s[4 * i + 3]);
+ out[j++] = (byte)(s[4 * i] ^ mulX(s[4 * i + 1]) ^ mulX(s[4 * i + 2]) ^ s[4 * i + 2] ^ s[4 * i + 3]);
+ out[j++] = (byte)(s[4 * i] ^ s[4 * i + 1] ^ mulX(s[4 * i + 2]) ^ mulX(s[4 * i + 3]) ^ s[4 * i + 3]);
+ out[j++] = (byte)(mulX(s[4 * i]) ^ s[4 * i] ^ s[4 * i + 1] ^ s[4 * i + 2] ^ mulX(s[4 * i + 3]));
+ }
+ return out;
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_SIZE;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/ISAPDigest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/ISAPDigest.java
new file mode 100644
index 0000000..26bf5f2
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/ISAPDigest.java
@@ -0,0 +1,148 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.Digest;
+import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.util.Pack;
+
+/**
+ * ISAP Hash v2, https://isap.iaik.tugraz.at/
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/isap-spec-final.pdf
+ * <p>
+ * ISAP Hash v2 with reference to C Reference Impl from: https://github.com/isap-lwc/isap-code-package
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+
+public class ISAPDigest
+ implements Digest
+{
+ private long x0, x1, x2, x3, x4;
+ private long t0, t1, t2, t3, t4;
+ private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+
+ private void ROUND(long C)
+ {
+ t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
+ t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
+ t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
+ t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
+ t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
+ x0 = t0 ^ ROTR(t0, 19) ^ ROTR(t0, 28);
+ x1 = t1 ^ ROTR(t1, 39) ^ ROTR(t1, 61);
+ x2 = ~(t2 ^ ROTR(t2, 1) ^ ROTR(t2, 6));
+ x3 = t3 ^ ROTR(t3, 10) ^ ROTR(t3, 17);
+ x4 = t4 ^ ROTR(t4, 7) ^ ROTR(t4, 41);
+ }
+
+ private void P12()
+ {
+ ROUND(0xf0);
+ ROUND(0xe1);
+ ROUND(0xd2);
+ ROUND(0xc3);
+ ROUND(0xb4);
+ ROUND(0xa5);
+ ROUND(0x96);
+ ROUND(0x87);
+ ROUND(0x78);
+ ROUND(0x69);
+ ROUND(0x5a);
+ ROUND(0x4b);
+ }
+
+ private long ROTR(long x, long n)
+ {
+ return (x >>> n) | (x << (64 - n));
+ }
+
+ protected long U64BIG(long x)
+ {
+ return ((ROTR(x, 8) & (0xFF000000FF000000L)) | (ROTR(x, 24) & (0x00FF000000FF0000L)) |
+ (ROTR(x, 40) & (0x0000FF000000FF00L)) | (ROTR(x, 56) & (0x000000FF000000FFL)));
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return "ISAP Hash";
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return 32;
+ }
+
+ @Override
+ public void update(byte input)
+ {
+ buffer.write(input);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+ }
+
+ @Override
+ public int doFinal(byte[] out, int outOff)
+ {
+ if (32 + outOff > out.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ t0 = t1 = t2 = t3 = t4 = 0;
+ /* init state */
+ x0 = -1255492011513352131L;
+ x1 = -8380609354527731710L;
+ x2 = -5437372128236807582L;
+ x3 = 4834782570098516968L;
+ x4 = 3787428097924915520L;
+ /* absorb */
+ byte[] input = buffer.toByteArray();
+ int len = input.length;
+ long[] in64 = new long[len >> 3];
+ Pack.littleEndianToLong(input, 0, in64, 0, in64.length);
+ int idx = 0;
+ while (len >= 8)
+ {
+ x0 ^= U64BIG(in64[idx++]);
+ P12();
+ len -= 8;
+ }
+ /* absorb final input block */
+ x0 ^= 0x80L << ((7 - len) << 3);
+ while (len > 0)
+ {
+ x0 ^= (input[(idx << 3) + --len] & 0xFFL) << ((7 - len) << 3);
+ }
+ P12();
+ // squeeze
+ long[] out64 = new long[4];
+ for (idx = 0; idx < 3; ++idx)
+ {
+ out64[idx] = U64BIG(x0);
+ P12();
+ }
+ /* squeeze final output block */
+ out64[idx] = U64BIG(x0);
+ Pack.longToLittleEndian(out64, out, outOff);
+ buffer.reset();
+ return 32;
+ }
+
+ @Override
+ public void reset()
+ {
+ buffer.reset();
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/LongDigest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/LongDigest.java
index 2c9aa03..ed94702 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/LongDigest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/LongDigest.java
@@ -1,6 +1,8 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.digests;
+import com.android.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
import com.android.org.bouncycastle.crypto.ExtendedDigest;
import com.android.org.bouncycastle.util.Memoable;
import com.android.org.bouncycastle.util.Pack;
@@ -14,6 +16,8 @@
{
private static final int BYTE_LENGTH = 128;
+ protected final CryptoServicePurpose purpose;
+
private byte[] xBuf = new byte[8];
private int xBufOff;
@@ -30,6 +34,16 @@
*/
protected LongDigest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Constructor for variable length word
+ */
+ protected LongDigest(CryptoServicePurpose purpose)
+ {
+ this.purpose = purpose;
+
xBufOff = 0;
reset();
@@ -42,6 +56,8 @@
*/
protected LongDigest(LongDigest t)
{
+ this.purpose = t.purpose;
+
copyIn(t);
}
@@ -149,7 +165,7 @@
//
// process whole words.
//
- while (len > xBuf.length)
+ while (len >= xBuf.length)
{
processWord(in, inOff);
@@ -408,4 +424,5 @@
0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L
};
+ protected abstract CryptoServiceProperties cryptoServiceProperties();
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD4Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD4Digest.java
index 19d2fe7..8e30270 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD4Digest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD4Digest.java
@@ -1,4 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: maintain old behaviour
package com.android.org.bouncycastle.crypto.digests;
@@ -291,3 +292,4 @@
copyIn(d);
}
}
+// END Android-changed: maintain old behaviour
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD5Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD5Digest.java
index ab7b875..a764061 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD5Digest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD5Digest.java
@@ -1,4 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: maintain old behaviour
package com.android.org.bouncycastle.crypto.digests;
@@ -361,3 +362,4 @@
return state;
}
}
+// END Android-changed: maintain old behaviour
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java
new file mode 100644
index 0000000..77c46db
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java
@@ -0,0 +1,221 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.Digest;
+import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Bytes;
+
+/**
+ * Photon-Beetle, https://www.isical.ac.in/~lightweight/beetle/
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/photon-beetle-spec-final.pdf
+ * <p>
+ * Photon-Beetle with reference to C Reference Impl from: https://github.com/PHOTON-Beetle/Software
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PhotonBeetleDigest
+ implements Digest
+{
+ private byte[] state;
+ private byte[][] state_2d;
+ private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ private final int INITIAL_RATE_INBYTES = 16;
+ private int RATE_INBYTES = 4;
+ private int SQUEEZE_RATE_INBYTES = 16;
+ private int STATE_INBYTES = 32;
+ private int TAG_INBYTES = 32;
+ private int LAST_THREE_BITS_OFFSET = 5;
+ private int ROUND = 12;
+ private int D = 8;
+ private int Dq = 3;
+ private int Dr = 7;
+ private int DSquare = 64;
+ private int S = 4;
+ private int S_1 = 3;
+ private byte[][] RC = {//[D][12]
+ {1, 3, 7, 14, 13, 11, 6, 12, 9, 2, 5, 10},
+ {0, 2, 6, 15, 12, 10, 7, 13, 8, 3, 4, 11},
+ {2, 0, 4, 13, 14, 8, 5, 15, 10, 1, 6, 9},
+ {6, 4, 0, 9, 10, 12, 1, 11, 14, 5, 2, 13},
+ {14, 12, 8, 1, 2, 4, 9, 3, 6, 13, 10, 5},
+ {15, 13, 9, 0, 3, 5, 8, 2, 7, 12, 11, 4},
+ {13, 15, 11, 2, 1, 7, 10, 0, 5, 14, 9, 6},
+ {9, 11, 15, 6, 5, 3, 14, 4, 1, 10, 13, 2}
+ };
+ private byte[][] MixColMatrix = { //[D][D]
+ {2, 4, 2, 11, 2, 8, 5, 6},
+ {12, 9, 8, 13, 7, 7, 5, 2},
+ {4, 4, 13, 13, 9, 4, 13, 9},
+ {1, 6, 5, 1, 12, 13, 15, 14},
+ {15, 12, 9, 13, 14, 5, 14, 13},
+ {9, 14, 5, 15, 4, 12, 9, 6},
+ {12, 2, 2, 10, 3, 1, 1, 14},
+ {15, 1, 13, 10, 5, 10, 2, 3}
+ };
+
+ private byte[] sbox = {12, 5, 6, 11, 9, 0, 10, 13, 3, 14, 15, 8, 4, 7, 1, 2};
+
+ public PhotonBeetleDigest()
+ {
+ state = new byte[STATE_INBYTES];
+ state_2d = new byte[D][D];
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return "Photon-Beetle Hash";
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return TAG_INBYTES;
+ }
+
+ @Override
+ public void update(byte input)
+ {
+ buffer.write(input);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+ }
+
+ @Override
+ public int doFinal(byte[] output, int outOff)
+ {
+ if (32 + outOff > output.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ byte[] input = buffer.toByteArray();
+ int inlen = input.length;
+ if (inlen == 0)
+ {
+ state[STATE_INBYTES - 1] ^= 1 << LAST_THREE_BITS_OFFSET;
+ }
+ else if (inlen <= INITIAL_RATE_INBYTES)
+ {
+ System.arraycopy(input, 0, state, 0, inlen);
+ if (inlen < INITIAL_RATE_INBYTES)
+ {
+ state[inlen] ^= 0x01; // ozs
+ }
+ state[STATE_INBYTES - 1] ^= (inlen < INITIAL_RATE_INBYTES ? (byte)1 : (byte)2) << LAST_THREE_BITS_OFFSET;
+ }
+ else
+ {
+ System.arraycopy(input, 0, state, 0, INITIAL_RATE_INBYTES);
+ inlen -= INITIAL_RATE_INBYTES;
+ int Dlen_inblocks = (inlen + RATE_INBYTES - 1) / RATE_INBYTES;
+ int i, LastDBlocklen;
+ for (i = 0; i < Dlen_inblocks - 1; i++)
+ {
+ PHOTON_Permutation();
+ Bytes.xorTo(RATE_INBYTES, input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, state, 0);
+ }
+ PHOTON_Permutation();
+ LastDBlocklen = inlen - i * RATE_INBYTES;
+ Bytes.xorTo(LastDBlocklen, input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, state, 0);
+ if (LastDBlocklen < RATE_INBYTES)
+ {
+ state[LastDBlocklen] ^= 0x01; // ozs
+ }
+ state[STATE_INBYTES - 1] ^= (inlen % RATE_INBYTES == 0 ? (byte)1 : (byte)2) << LAST_THREE_BITS_OFFSET;
+ }
+ PHOTON_Permutation();
+ System.arraycopy(state, 0, output, outOff, SQUEEZE_RATE_INBYTES);
+ PHOTON_Permutation();
+ System.arraycopy(state, 0, output, outOff + SQUEEZE_RATE_INBYTES, TAG_INBYTES - SQUEEZE_RATE_INBYTES);
+ return TAG_INBYTES;
+ }
+
+ @Override
+ public void reset()
+ {
+ buffer.reset();
+ Arrays.fill(state, (byte)0);
+ }
+
+ void PHOTON_Permutation()
+ {
+ int i, j, k, l;
+ for (i = 0; i < DSquare; i++)
+ {
+ state_2d[i >>> Dq][i & Dr] = (byte)(((state[i >> 1] & 0xFF) >>> (4 * (i & 1))) & 0xf);
+ }
+ for (int round = 0; round < ROUND; round++)
+ {
+ //AddKey
+ for (i = 0; i < D; i++)
+ {
+ state_2d[i][0] ^= RC[i][round];
+ }
+ //SubCell
+ for (i = 0; i < D; i++)
+ {
+ for (j = 0; j < D; j++)
+ {
+ state_2d[i][j] = sbox[state_2d[i][j]];
+ }
+ }
+ //ShiftRow
+ for (i = 1; i < D; i++)
+ {
+ System.arraycopy(state_2d[i], 0, state, 0, D);
+ System.arraycopy(state, i, state_2d[i], 0, D - i);
+ System.arraycopy(state, 0, state_2d[i], D - i, i);
+ }
+ //MixColumn
+ for (j = 0; j < D; j++)
+ {
+ for (i = 0; i < D; i++)
+ {
+ byte sum = 0;
+ for (k = 0; k < D; k++)
+ {
+ int x = MixColMatrix[i][k], ret = 0, b = state_2d[k][j];
+ for (l = 0; l < S; l++)
+ {
+ if (((b >>> l) & 1) != 0)
+ {
+ ret ^= x;
+ }
+ if (((x >>> S_1) & 1) != 0)
+ {
+ x <<= 1;
+ x ^= 0x3;
+ }
+ else
+ {
+ x <<= 1;
+ }
+ }
+ sum ^= ret & 15;
+ }
+ state[i] = sum;
+ }
+ for (i = 0; i < D; i++)
+ {
+ state_2d[i][j] = state[i];
+ }
+ }
+ }
+ for (i = 0; i < DSquare; i += 2)
+ {
+ state[i >>> 1] = (byte)(((state_2d[i >>> Dq][i & Dr] & 0xf)) | ((state_2d[i >>> Dq][(i + 1) & Dr] & 0xf) << 4));
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA1Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA1Digest.java
index ebc5bfe..fcb56ad 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA1Digest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA1Digest.java
@@ -1,4 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: maintain old behaviour
package com.android.org.bouncycastle.crypto.digests;
import com.android.org.bouncycastle.util.Memoable;
@@ -350,6 +351,4 @@
}
}
-
-
-
+// END Android-changed: maintain old behaviour
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA224Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA224Digest.java
index b17a503..0f60f69 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA224Digest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA224Digest.java
@@ -1,4 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: maintain old behaviour
package com.android.org.bouncycastle.crypto.digests;
@@ -360,4 +361,4 @@
return state;
}
}
-
+// END Android-changed: maintain old behaviour
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA256Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA256Digest.java
index 25eda9d..16d0dce 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA256Digest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA256Digest.java
@@ -1,7 +1,13 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: adapt to old version of GeneralDigest
package com.android.org.bouncycastle.crypto.digests;
+import com.android.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.org.bouncycastle.crypto.Digest;
+import com.android.org.bouncycastle.crypto.SavableDigest;
import com.android.org.bouncycastle.util.Memoable;
import com.android.org.bouncycastle.util.Pack;
@@ -20,20 +26,60 @@
*/
public class SHA256Digest
extends GeneralDigest
- implements EncodableDigest
+ implements SavableDigest
{
private static final int DIGEST_LENGTH = 32;
+ protected final CryptoServicePurpose purpose;
private int H1, H2, H3, H4, H5, H6, H7, H8;
private int[] X = new int[64];
private int xOff;
+ public static SavableDigest newInstance()
+ {
+ return new SHA256Digest();
+ }
+
+ public static SavableDigest newInstance(CryptoServicePurpose purpose)
+ {
+ return new SHA256Digest(purpose);
+ }
+
+ public static SavableDigest newInstance(Digest digest)
+ {
+ if (digest instanceof SHA256Digest)
+ {
+ return new SHA256Digest((SHA256Digest) digest);
+ }
+
+ throw new IllegalArgumentException("receiver digest not available for input type " + (digest != null ? digest.getClass().getName() : "null"));
+ }
+
+ public static SavableDigest newInstance(byte[] encoded)
+ {
+ return new SHA256Digest(encoded);
+ }
+
/**
* Standard constructor
*/
public SHA256Digest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Standard constructor, with purpose
+ */
+ public SHA256Digest(CryptoServicePurpose purpose)
+ {
+ super();
+
+ this.purpose = purpose;
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
+
reset();
}
@@ -45,6 +91,8 @@
{
super(t);
+ this.purpose = CryptoServicePurpose.ANY;
+
copyIn(t);
}
@@ -74,6 +122,8 @@
{
super(encodedState);
+ this.purpose = CryptoServicePurpose.ANY;
+
H1 = Pack.bigEndianToInt(encodedState, 16);
H2 = Pack.bigEndianToInt(encodedState, 20);
H3 = Pack.bigEndianToInt(encodedState, 24);
@@ -105,13 +155,7 @@
byte[] in,
int inOff)
{
- // Note: Inlined for performance
-// X[xOff] = Pack.bigEndianToInt(in, inOff);
- int n = in[inOff] << 24;
- n |= (in[++inOff] & 0xff) << 16;
- n |= (in[++inOff] & 0xff) << 8;
- n |= (in[++inOff] & 0xff);
- X[xOff] = n;
+ X[xOff] = Pack.bigEndianToInt(in, inOff);
if (++xOff == 16)
{
@@ -131,9 +175,7 @@
X[15] = (int)(bitLength & 0xffffffff);
}
- public int doFinal(
- byte[] out,
- int outOff)
+ public int doFinal(byte[] out, int outOff)
{
finish();
@@ -201,7 +243,7 @@
int g = H7;
int h = H8;
- int t = 0;
+ int t = 0;
for(int i = 0; i < 8; i ++)
{
// t = 8 * i
@@ -334,7 +376,7 @@
public byte[] getEncodedState()
{
- byte[] state = new byte[52 + xOff * 4];
+ byte[] state = new byte[52 + xOff * 4 + 1];
super.populateState(state);
@@ -353,7 +395,14 @@
Pack.intToBigEndian(X[i], state, 52 + (i * 4));
}
+ state[state.length - 1] = (byte)purpose.ordinal();
+
return state;
}
-}
+ protected CryptoServiceProperties cryptoServiceProperties()
+ {
+ return Utils.getDefaultProperties(this, 256, purpose);
+ }
+}
+// END Android-changed: adapt to old version of GeneralDigest
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA384Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA384Digest.java
index 8ff6764..ca25f05 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA384Digest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA384Digest.java
@@ -1,6 +1,9 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.digests;
+import com.android.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.util.Memoable;
import com.android.org.bouncycastle.util.Pack;
@@ -27,6 +30,19 @@
*/
public SHA384Digest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Standard constructor, with purpose
+ */
+ public SHA384Digest(CryptoServicePurpose purpose)
+ {
+ super(purpose);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
+
+ reset();
}
/**
@@ -36,6 +52,8 @@
public SHA384Digest(SHA384Digest t)
{
super(t);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
/**
@@ -45,7 +63,11 @@
*/
public SHA384Digest(byte[] encodedState)
{
+ super(CryptoServicePurpose.values()[encodedState[encodedState.length - 1]]);
+
restoreState(encodedState);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
public String getAlgorithmName()
@@ -111,8 +133,16 @@
public byte[] getEncodedState()
{
- byte[] encoded = new byte[getEncodedStateSize()];
+ byte[] encoded = new byte[getEncodedStateSize() + 1];
super.populateState(encoded);
+
+ encoded[encoded.length - 1] = (byte)purpose.ordinal();
+
return encoded;
}
+
+ protected CryptoServiceProperties cryptoServiceProperties()
+ {
+ return Utils.getDefaultProperties(this, 256, purpose);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA512Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA512Digest.java
index 882b671..bb89ed7 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA512Digest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA512Digest.java
@@ -1,6 +1,9 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.digests;
+import com.android.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.util.Memoable;
import com.android.org.bouncycastle.util.Pack;
@@ -27,6 +30,19 @@
*/
public SHA512Digest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Standard constructor, with purpose
+ */
+ public SHA512Digest(CryptoServicePurpose purpose)
+ {
+ super(purpose);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
+
+ reset();
}
/**
@@ -36,6 +52,8 @@
public SHA512Digest(SHA512Digest t)
{
super(t);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
/**
@@ -45,7 +63,11 @@
*/
public SHA512Digest(byte[] encodedState)
{
+ super(CryptoServicePurpose.values()[encodedState[encodedState.length - 1]]);
+
restoreState(encodedState);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
public String getAlgorithmName()
@@ -113,9 +135,17 @@
public byte[] getEncodedState()
{
- byte[] encoded = new byte[getEncodedStateSize()];
+ byte[] encoded = new byte[getEncodedStateSize() + 1];
super.populateState(encoded);
+
+ encoded[encoded.length - 1] = (byte)purpose.ordinal();
+
return encoded;
}
+
+ protected CryptoServiceProperties cryptoServiceProperties()
+ {
+ return Utils.getDefaultProperties(this, 256, purpose);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/Utils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/Utils.java
new file mode 100644
index 0000000..c6bd5bb
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/Utils.java
@@ -0,0 +1,98 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.digests;
+
+import com.android.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.Digest;
+
+class Utils
+{
+ static CryptoServiceProperties getDefaultProperties(Digest digest, CryptoServicePurpose purpose)
+ {
+ return new DefaultProperties(digest.getDigestSize() * 4, digest.getAlgorithmName(), purpose);
+ }
+
+ static CryptoServiceProperties getDefaultProperties(Digest digest, int prfBitsOfSecurity, CryptoServicePurpose purpose)
+ {
+ return new DefaultPropertiesWithPRF(digest.getDigestSize() * 4, prfBitsOfSecurity, digest.getAlgorithmName(), purpose);
+ }
+
+ // Service Definitions
+ private static class DefaultPropertiesWithPRF
+ implements CryptoServiceProperties
+ {
+ private final int bitsOfSecurity;
+ private final int prfBitsOfSecurity;
+ private final String algorithmName;
+ private final CryptoServicePurpose purpose;
+
+ public DefaultPropertiesWithPRF(int bitsOfSecurity, int prfBitsOfSecurity, String algorithmName, CryptoServicePurpose purpose)
+ {
+ this.bitsOfSecurity = bitsOfSecurity;
+ this.prfBitsOfSecurity = prfBitsOfSecurity;
+ this.algorithmName = algorithmName;
+ this.purpose = purpose;
+ }
+
+ public int bitsOfSecurity()
+ {
+ if (purpose == CryptoServicePurpose.PRF)
+ {
+ return prfBitsOfSecurity;
+ }
+
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return algorithmName;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return purpose;
+ }
+
+ public Object getParams()
+ {
+ return null;
+ }
+ }
+
+ // Service Definitions
+ private static class DefaultProperties
+ implements CryptoServiceProperties
+ {
+ private final int bitsOfSecurity;
+ private final String algorithmName;
+ private final CryptoServicePurpose purpose;
+
+ public DefaultProperties(int bitsOfSecurity, String algorithmName, CryptoServicePurpose purpose)
+ {
+ this.bitsOfSecurity = bitsOfSecurity;
+ this.algorithmName = algorithmName;
+ this.purpose = purpose;
+ }
+
+ public int bitsOfSecurity()
+ {
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return algorithmName;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return purpose;
+ }
+
+ public Object getParams()
+ {
+ return null;
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/XofUtils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/XofUtils.java
index 13a053d..f5ba10f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/XofUtils.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/XofUtils.java
@@ -1,6 +1,8 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.digests;
+import com.android.org.bouncycastle.util.Arrays;
+
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -8,24 +10,24 @@
{
public static byte[] leftEncode(long strLen)
{
- byte n = 1;
+ byte n = 1;
long v = strLen;
- while ((v >>= 8) != 0)
+ while ((v >>= 8) != 0)
{
- n++;
- }
+ n++;
+ }
byte[] b = new byte[n + 1];
- b[0] = n;
+ b[0] = n;
- for (int i = 1; i <= n; i++)
- {
- b[i] = (byte)(strLen >> (8 * (n - i)));
- }
+ for (int i = 1; i <= n; i++)
+ {
+ b[i] = (byte)(strLen >> (8 * (n - i)));
+ }
- return b;
+ return b;
}
public static byte[] rightEncode(long strLen)
@@ -49,4 +51,18 @@
return b;
}
+
+ static byte[] encode(byte X)
+ {
+ return Arrays.concatenate(XofUtils.leftEncode(8), new byte[] { X });
+ }
+
+ static byte[] encode(byte[] in, int inOff, int len)
+ {
+ if (in.length == len)
+ {
+ return Arrays.concatenate(XofUtils.leftEncode(len * 8), in);
+ }
+ return Arrays.concatenate(XofUtils.leftEncode(len * 8), Arrays.copyOfRange(in, inOff, inOff + len));
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/XoodyakDigest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/XoodyakDigest.java
new file mode 100644
index 0000000..3fa6856
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/XoodyakDigest.java
@@ -0,0 +1,208 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.Digest;
+import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Pack;
+
+/**
+ * Xoodyak v1, https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/xoodyak-spec-final.pdf
+ * <p>
+ * Xoodyak with reference to C Reference Impl from: https://github.com/XKCP/XKCP
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+
+public class XoodyakDigest
+ implements Digest
+{
+ private byte[] state;
+ private int phase;
+ private MODE mode;
+ private int Rabsorb;
+ private final int f_bPrime = 48;
+ private final int Rhash = 16;
+ private final int PhaseDown = 1;
+ private final int PhaseUp = 2;
+ private final int NLANES = 12;
+ private final int NROWS = 3;
+ private final int NCOLUMS = 4;
+ private final int MAXROUNDS = 12;
+ private final int TAGLEN = 16;
+ private final int[] RC = {0x00000058, 0x00000038, 0x000003C0, 0x000000D0, 0x00000120, 0x00000014, 0x00000060,
+ 0x0000002C, 0x00000380, 0x000000F0, 0x000001A0, 0x00000012};
+ private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+
+ enum MODE
+ {
+ ModeHash,
+ ModeKeyed
+ }
+
+ public XoodyakDigest()
+ {
+ state = new byte[48];
+ reset();
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return "Xoodyak Hash";
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return 32;
+ }
+
+ @Override
+ public void update(byte input)
+ {
+ buffer.write(input);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+
+ }
+
+ @Override
+ public int doFinal(byte[] output, int outOff)
+ {
+ if (32 + outOff > output.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ byte[] input = buffer.toByteArray();
+ int inOff = 0;
+ int len = buffer.size();
+ int Cd = 0x03;
+ int splitLen;
+ do
+ {
+ if (phase != PhaseUp)
+ {
+ Up(null, 0, 0, 0);
+ }
+ splitLen = Math.min(len, Rabsorb);
+ Down(input, inOff, splitLen, Cd);
+ Cd = 0;
+ inOff += splitLen;
+ len -= splitLen;
+ }
+ while (len != 0);
+ Up(output, outOff, TAGLEN, 0x40);
+ Down(null, 0, 0, 0);
+ Up(output, outOff + TAGLEN, TAGLEN, 0);
+ return 32;
+ }
+
+ @Override
+ public void reset()
+ {
+ Arrays.fill(state, (byte)0);
+ phase = PhaseUp;
+ mode = MODE.ModeHash;
+ Rabsorb = Rhash;
+ buffer.reset();
+ }
+
+ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
+ {
+ if (mode != MODE.ModeHash)
+ {
+ state[f_bPrime - 1] ^= Cu;
+ }
+ int[] a = new int[NLANES];
+ Pack.littleEndianToInt(state, 0, a, 0, a.length);
+ int x, y;
+ int[] b = new int[NLANES];
+ int[] p = new int[NCOLUMS];
+ int[] e = new int[NCOLUMS];
+ for (int i = 0; i < MAXROUNDS; ++i)
+ {
+ /* Theta: Column Parity Mixer */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ p[x] = a[index(x, 0)] ^ a[index(x, 1)] ^ a[index(x, 2)];
+ }
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ y = p[(x + 3) & 3];
+ e[x] = ROTL32(y, 5) ^ ROTL32(y, 14);
+ }
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ for (y = 0; y < NROWS; ++y)
+ {
+ a[index(x, y)] ^= e[x];
+ }
+ }
+ /* Rho-west: plane shift */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ b[index(x, 0)] = a[index(x, 0)];
+ b[index(x, 1)] = a[index(x + 3, 1)];
+ b[index(x, 2)] = ROTL32(a[index(x, 2)], 11);
+ }
+ /* Iota: round ant */
+ b[0] ^= RC[i];
+ /* Chi: non linear layer */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ for (y = 0; y < NROWS; ++y)
+ {
+ a[index(x, y)] = b[index(x, y)] ^ (~b[index(x, y + 1)] & b[index(x, y + 2)]);
+ }
+ }
+ /* Rho-east: plane shift */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ b[index(x, 0)] = a[index(x, 0)];
+ b[index(x, 1)] = ROTL32(a[index(x, 1)], 1);
+ b[index(x, 2)] = ROTL32(a[index(x + 2, 2)], 8);
+ }
+ System.arraycopy(b, 0, a, 0, NLANES);
+ }
+ Pack.intToLittleEndian(a, 0, a.length, state, 0);
+ phase = PhaseUp;
+ if (Yi != null)
+ {
+ System.arraycopy(state, 0, Yi, YiOff, YiLen);
+ }
+ }
+
+ void Down(byte[] Xi, int XiOff, int XiLen, int Cd)
+ {
+ for (int i = 0; i < XiLen; i++)
+ {
+ state[i] ^= Xi[XiOff++];
+ }
+ state[XiLen] ^= 0x01;
+ state[f_bPrime - 1] ^= (mode == MODE.ModeHash) ? (Cd & 0x01) : Cd;
+ phase = PhaseDown;
+ }
+
+ private int index(int x, int y)
+ {
+ return (((y % NROWS) * NCOLUMS) + ((x) % NCOLUMS));
+ }
+
+ private int ROTL32(int a, int offset)
+ {
+ return (a << (offset & 31)) ^ (a >>> ((32 - (offset)) & 31));
+ }
+
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/ec/CustomNamedCurves.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/ec/CustomNamedCurves.java
index aeb8590..d1c8033 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/ec/CustomNamedCurves.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/ec/CustomNamedCurves.java
@@ -87,10 +87,15 @@
*
static X9ECParametersHolder curve25519 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new Curve25519());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new Curve25519());
+ ECCurve curve = getCurve();
/*
* NOTE: Curve25519 was specified in Montgomery form. Rewriting in Weierstrass form
@@ -113,10 +118,15 @@
*
static X9ECParametersHolder secp128r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP128R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
- ECCurve curve = configureCurve(new SecP128R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -128,9 +138,8 @@
*
static X9ECParametersHolder secp160k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
@@ -144,7 +153,13 @@
new BigInteger("9162fbe73984472a0a9d0590", 16),
new BigInteger("96341f1138933bc2f503fd44", 16),
176));
- ECCurve curve = configureCurveGLV(new SecP160K1Curve(), glv);
+ return configureCurveGLV(new SecP160K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -156,10 +171,15 @@
*
static X9ECParametersHolder secp160r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP160R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
- ECCurve curve = configureCurve(new SecP160R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -171,10 +191,15 @@
*
static X9ECParametersHolder secp160r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP160R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
- ECCurve curve = configureCurve(new SecP160R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -188,9 +213,8 @@
*/
static X9ECParametersHolder secp192k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
@@ -204,7 +228,13 @@
new BigInteger("71169be7330b3038edb025f1d0f9", 16),
new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
208));
- ECCurve curve = configureCurveGLV(new SecP192K1Curve(), glv);
+ return configureCurveGLV(new SecP192K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -216,10 +246,15 @@
*/
static X9ECParametersHolder secp192r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP192R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
- ECCurve curve = configureCurve(new SecP192R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -231,9 +266,8 @@
*/
static X9ECParametersHolder secp224k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
@@ -247,7 +281,13 @@
new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
240));
- ECCurve curve = configureCurveGLV(new SecP224K1Curve(), glv);
+ return configureCurveGLV(new SecP224K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -259,10 +299,15 @@
*/
static X9ECParametersHolder secp224r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP224R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
- ECCurve curve = configureCurve(new SecP224R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -274,9 +319,8 @@
*/
static X9ECParametersHolder secp256k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
@@ -290,7 +334,13 @@
new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
272));
- ECCurve curve = configureCurveGLV(new SecP256K1Curve(), glv);
+ return configureCurveGLV(new SecP256K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -302,10 +352,15 @@
*/
static X9ECParametersHolder secp256r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP256R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
- ECCurve curve = configureCurve(new SecP256R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -317,10 +372,15 @@
*/
static X9ECParametersHolder secp384r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP384R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
- ECCurve curve = configureCurve(new SecP384R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
@@ -333,10 +393,15 @@
*/
static X9ECParametersHolder secp521r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP521R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
- ECCurve curve = configureCurve(new SecP521R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
+ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
@@ -351,10 +416,15 @@
*
static X9ECParametersHolder sect113r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT113R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
- ECCurve curve = configureCurve(new SecT113R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -366,10 +436,15 @@
*
static X9ECParametersHolder sect113r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT113R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
- ECCurve curve = configureCurve(new SecT113R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -381,10 +456,15 @@
*
static X9ECParametersHolder sect131r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT131R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
- ECCurve curve = configureCurve(new SecT131R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -396,10 +476,15 @@
*
static X9ECParametersHolder sect131r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT131R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
- ECCurve curve = configureCurve(new SecT131R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -411,10 +496,15 @@
*
static X9ECParametersHolder sect163k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT163K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT163K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -426,10 +516,15 @@
*
static X9ECParametersHolder sect163r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT163R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
- ECCurve curve = configureCurve(new SecT163R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -441,10 +536,15 @@
*
static X9ECParametersHolder sect163r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT163R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
- ECCurve curve = configureCurve(new SecT163R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -456,10 +556,15 @@
*
static X9ECParametersHolder sect193r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT193R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
- ECCurve curve = configureCurve(new SecT193R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -471,10 +576,15 @@
*
static X9ECParametersHolder sect193r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT193R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
- ECCurve curve = configureCurve(new SecT193R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -486,10 +596,15 @@
*
static X9ECParametersHolder sect233k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT233K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT233K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -501,10 +616,15 @@
*
static X9ECParametersHolder sect233r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT233R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
- ECCurve curve = configureCurve(new SecT233R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -516,10 +636,15 @@
*
static X9ECParametersHolder sect239k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT239K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT239K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -531,10 +656,15 @@
*
static X9ECParametersHolder sect283k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT283K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT283K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
+ "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
@@ -547,10 +677,15 @@
*
static X9ECParametersHolder sect283r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT283R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
- ECCurve curve = configureCurve(new SecT283R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
+ "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
@@ -563,10 +698,15 @@
*
static X9ECParametersHolder sect409k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT409K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT409K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
+ "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
@@ -579,10 +719,15 @@
*
static X9ECParametersHolder sect409r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT409R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
- ECCurve curve = configureCurve(new SecT409R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
+ "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
@@ -595,10 +740,15 @@
*
static X9ECParametersHolder sect571k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT571K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT571K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
+ "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
@@ -611,10 +761,15 @@
*
static X9ECParametersHolder sect571r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT571R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
- ECCurve curve = configureCurve(new SecT571R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
+ "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
@@ -627,10 +782,15 @@
*
static X9ECParametersHolder sm2p256v1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SM2P256V1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SM2P256V1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0432C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -640,6 +800,7 @@
// END Android-removed: Unsupported curves
+
static final Hashtable nameToCurve = new Hashtable();
static final Hashtable nameToOID = new Hashtable();
static final Hashtable oidToCurve = new Hashtable();
@@ -746,10 +907,15 @@
public static X9ECParameters getByName(String name)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)nameToCurve.get(Strings.toLowerCase(name));
+ X9ECParametersHolder holder = getByNameLazy(name);
return holder == null ? null : holder.getParameters();
}
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ return (X9ECParametersHolder)nameToCurve.get(Strings.toLowerCase(name));
+ }
+
/**
* return the X9ECParameters object for the named curve represented by the passed in object
* identifier. Null if the curve isn't present.
@@ -759,10 +925,15 @@
*/
public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)oidToCurve.get(oid);
+ X9ECParametersHolder holder = getByOIDLazy(oid);
return holder == null ? null : holder.getParameters();
}
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return (X9ECParametersHolder)oidToCurve.get(oid);
+ }
+
/**
* return the object identifier signified by the passed in name. Null if there is no object
* identifier associated with name.
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/OAEPEncoding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/OAEPEncoding.java
index c085844..43c7616 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/OAEPEncoding.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/OAEPEncoding.java
@@ -14,6 +14,7 @@
// import org.bouncycastle.crypto.util.DigestFactory;
import com.android.org.bouncycastle.crypto.digests.AndroidDigestFactory;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Pack;
/**
* Optimal Asymmetric Encryption Padding (OAEP) - see PKCS 1 V 2.
@@ -227,7 +228,9 @@
// on encryption, we need to make sure our decrypted block comes back
// the same size.
//
- boolean wrongData = (block.length < (2 * defHash.length) + 1);
+
+ // i.e. wrong when block.length < (2 * defHash.length) + 1
+ int wrongMask = (block.length - ((2 * defHash.length) + 1)) >> 31;
if (data.length <= block.length)
{
@@ -236,7 +239,7 @@
else
{
System.arraycopy(data, 0, block, 0, block.length);
- wrongData = true;
+ wrongMask |= 1;
}
//
@@ -264,39 +267,38 @@
// check the hash of the encoding params.
// long check to try to avoid this been a source of a timing attack.
//
- boolean defHashWrong = false;
-
for (int i = 0; i != defHash.length; i++)
{
- if (defHash[i] != block[defHash.length + i])
- {
- defHashWrong = true;
- }
+ wrongMask |= defHash[i] ^ block[defHash.length + i];
}
//
// find the data block
//
- int start = block.length;
+ int start = -1;
for (int index = 2 * defHash.length; index != block.length; index++)
{
- if (block[index] != 0 & start == block.length)
- {
- start = index;
- }
+ int octet = block[index] & 0xFF;
+
+ // i.e. mask will be 0xFFFFFFFF if octet is non-zero and start is (still) negative, else 0.
+ int shouldSetMask = (-octet & start) >> 31;
+
+ start += index & shouldSetMask;
}
- boolean dataStartWrong = (start > (block.length - 1) | block[start] != 1);
+ wrongMask |= start >> 31;
+ ++start;
+ wrongMask |= block[start] ^ 1;
- start++;
-
- if (defHashWrong | wrongData | dataStartWrong)
+ if (wrongMask != 0)
{
Arrays.fill(block, (byte)0);
throw new InvalidCipherTextException("data wrong");
}
+ ++start;
+
//
// extract the data block
//
@@ -309,19 +311,6 @@
}
/**
- * int to octet string.
- */
- private void ItoOSP(
- int i,
- byte[] sp)
- {
- sp[0] = (byte)(i >>> 24);
- sp[1] = (byte)(i >>> 16);
- sp[2] = (byte)(i >>> 8);
- sp[3] = (byte)(i >>> 0);
- }
-
- /**
* mask generator function, as described in PKCS1v2.
*/
private byte[] maskGeneratorFunction1(
@@ -339,7 +328,7 @@
while (counter < (length / hashBuf.length))
{
- ItoOSP(counter, C);
+ Pack.intToBigEndian(counter, C, 0);
mgf1Hash.update(Z, zOff, zLen);
mgf1Hash.update(C, 0, C.length);
@@ -352,7 +341,7 @@
if ((counter * hashBuf.length) < length)
{
- ItoOSP(counter, C);
+ Pack.intToBigEndian(counter, C, 0);
mgf1Hash.update(Z, zOff, zLen);
mgf1Hash.update(C, 0, C.length);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/PKCS1Encoding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
index 7f8b1ba..9627bd8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
@@ -235,52 +235,86 @@
}
/**
- * Checks if the argument is a correctly PKCS#1.5 encoded Plaintext
- * for encryption.
- *
- * @param encoded The Plaintext.
- * @param pLen Expected length of the plaintext.
- * @return Either 0, if the encoding is correct, or -1, if it is incorrect.
+ * Check the argument is a valid encoding with type 1. Returns the plaintext length if valid, or -1 if invalid.
*/
- private static int checkPkcs1Encoding(byte[] encoded, int pLen)
+ private static int checkPkcs1Encoding1(byte[] buf)
{
- int correct = 0;
- /*
- * Check if the first two bytes are 0 2
- */
- correct |= (encoded[0] ^ 2);
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
- /*
- * Now the padding check, check for no 0 byte in the padding
- */
- int plen = encoded.length - (
- pLen /* Length of the PMS */
- + 1 /* Final 0-byte before PMS */
- );
+ // The first byte should be 0x01
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x01);
- for (int i = 1; i < plen; i++)
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
{
- int tmp = encoded[i];
- tmp |= tmp >> 1;
- tmp |= tmp >> 2;
- tmp |= tmp >> 4;
- correct |= (tmp & 1) - 1;
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ int is0xFFMask = ((padByte ^ 0xFF) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ badPadSign |= ~(foundZeroMask | is0xFFMask);
}
- /*
- * Make sure the padding ends with a 0 byte.
- */
- correct |= encoded[encoded.length - (pLen + 1)];
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
- /*
- * Return 0 or 1, depending on the result.
- */
- correct |= correct >> 1;
- correct |= correct >> 2;
- correct |= correct >> 4;
- return ~((correct & 1) - 1);
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
}
+ /**
+ * Check the argument is a valid encoding with type 2. Returns the plaintext length if valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding2(byte[] buf)
+ {
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
+
+ // The first byte should be 0x02
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x02);
+
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
+ {
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ }
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
+ }
+
+ /**
+ * Check the argument is a valid encoding with type 2 of a plaintext with the given length. Returns 0 if
+ * valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding2(byte[] buf, int plaintextLength)
+ {
+ // The first byte should be 0x02
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x02);
+
+ int lastPadPos = buf.length - 1 - plaintextLength;
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ // All pad bytes before the last one should be non-zero
+ for (int i = 1; i < lastPadPos; ++i)
+ {
+ badPadSign |= (buf[i] & 0xFF) - 1;
+ }
+
+ // Last pad byte should be zero
+ badPadSign |= -(buf[lastPadPos] & 0xFF);
+
+ return badPadSign >> 31;
+ }
/**
* Decode PKCS#1.5 encoding, and return a random value if the padding is not correct.
@@ -300,36 +334,43 @@
throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
}
- byte[] block = engine.processBlock(in, inOff, inLen);
- byte[] random;
- if (this.fallback == null)
+ int plaintextLength = this.pLen;
+
+ byte[] random = fallback;
+ if (fallback == null)
{
- random = new byte[this.pLen];
+ random = new byte[plaintextLength];
this.random.nextBytes(random);
}
- else
+
+ int badPadMask = 0;
+ int strictBlockSize = engine.getOutputBlockSize();
+ byte[] block = engine.processBlock(in, inOff, inLen);
+
+ byte[] data = block;
+ if (block.length != strictBlockSize)
{
- random = fallback;
+ if (useStrictLength || block.length < strictBlockSize)
+ {
+ data = blockBuffer;
+ }
}
- byte[] data = (useStrictLength & (block.length != engine.getOutputBlockSize())) ? blockBuffer : block;
+ badPadMask |= checkPkcs1Encoding2(data, plaintextLength);
- /*
- * Check the padding.
- */
- int correct = PKCS1Encoding.checkPkcs1Encoding(data, this.pLen);
-
- /*
- * Now, to a constant time constant memory copy of the decrypted value
- * or the random value, depending on the validity of the padding.
- */
- byte[] result = new byte[this.pLen];
- for (int i = 0; i < this.pLen; i++)
+ /*
+ * Now, to a constant time constant memory copy of the decrypted value
+ * or the random value, depending on the validity of the padding.
+ */
+ int dataOff = data.length - plaintextLength;
+ byte[] result = new byte[plaintextLength];
+ for (int i = 0; i < plaintextLength; ++i)
{
- result[i] = (byte)((data[i + (data.length - pLen)] & (~correct)) | (random[i] & correct));
+ result[i] = (byte)((data[dataOff + i] & ~badPadMask) | (random[i] & badPadMask));
}
- Arrays.fill(data, (byte)0);
+ Arrays.fill(block, (byte)0);
+ Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0);
return result;
}
@@ -337,95 +378,50 @@
/**
* @throws InvalidCipherTextException if the decrypted block is not in PKCS1 format.
*/
- private byte[] decodeBlock(
- byte[] in,
- int inOff,
- int inLen)
+ private byte[] decodeBlock(byte[] in, int inOff, int inLen)
throws InvalidCipherTextException
{
/*
* If the length of the expected plaintext is known, we use a constant-time decryption.
* If the decryption fails, we return a random value.
*/
- if (this.pLen != -1)
+ if (forPrivateKey && this.pLen != -1)
{
return this.decodeBlockOrRandom(in, inOff, inLen);
}
+ int strictBlockSize = engine.getOutputBlockSize();
byte[] block = engine.processBlock(in, inOff, inLen);
- boolean incorrectLength = (useStrictLength & (block.length != engine.getOutputBlockSize()));
- byte[] data;
- if (block.length < getOutputBlockSize())
+ boolean incorrectLength = useStrictLength & (block.length != strictBlockSize);
+
+ byte[] data = block;
+ if (block.length < strictBlockSize)
{
data = blockBuffer;
}
- else
+
+ int plaintextLength = forPrivateKey ? checkPkcs1Encoding2(data) : checkPkcs1Encoding1(data);
+
+ try
{
- data = block;
- }
-
- byte type = data[0];
-
- boolean badType;
- if (forPrivateKey)
- {
- badType = (type != 2);
- }
- else
- {
- badType = (type != 1);
- }
-
- //
- // find and extract the message block.
- //
- int start = findStart(type, data);
-
- start++; // data should start at the next byte
-
- if (badType | start < HEADER_LENGTH)
- {
- Arrays.fill(data, (byte)0);
- throw new InvalidCipherTextException("block incorrect");
- }
-
- // if we get this far, it's likely to be a genuine encoding error
- if (incorrectLength)
- {
- Arrays.fill(data, (byte)0);
- throw new InvalidCipherTextException("block incorrect size");
- }
-
- byte[] result = new byte[data.length - start];
-
- System.arraycopy(data, start, result, 0, result.length);
-
- return result;
- }
-
- private int findStart(byte type, byte[] block)
- throws InvalidCipherTextException
- {
- int start = -1;
- boolean padErr = false;
-
- for (int i = 1; i != block.length; i++)
- {
- byte pad = block[i];
-
- if (pad == 0 & start < 0)
+ if (plaintextLength < 0)
{
- start = i;
+ throw new InvalidCipherTextException("block incorrect");
}
- padErr |= (type == 1 & start < 0 & pad != (byte)0xff);
- }
+ if (incorrectLength)
+ {
+ throw new InvalidCipherTextException("block incorrect size");
+ }
- if (padErr)
+ byte[] result = new byte[plaintextLength];
+ System.arraycopy(data, data.length - plaintextLength, result, 0, plaintextLength);
+ return result;
+ }
+ finally
{
- return -1;
+ Arrays.fill(block, (byte)0);
+ Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0);
}
-
- return start;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESEngine.java
index 8c9e2dd..fcd0fe0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESEngine.java
@@ -1,10 +1,13 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.engines;
-import com.android.org.bouncycastle.crypto.BlockCipher;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.DefaultMultiBlockCipher;
+import com.android.org.bouncycastle.crypto.MultiBlockCipher;
import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.KeyParameter;
import com.android.org.bouncycastle.util.Arrays;
import com.android.org.bouncycastle.util.Pack;
@@ -15,7 +18,7 @@
* For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
- * <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
+ * <a href="https://fp.gladman.plus.com/cryptography_technology/rijndael/">https://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
*
* There are three levels of tradeoff of speed vs memory
* Because java has no preprocessor, they are written as three separate classes from which to choose
@@ -34,7 +37,7 @@
*
*/
public class AESEngine
- implements BlockCipher
+ extends DefaultMultiBlockCipher
{
// The S box
private static final byte[] S = {
@@ -414,7 +417,6 @@
private int ROUNDS;
private int[][] WorkingKey = null;
- private int C0, C1, C2, C3;
private boolean forEncryption;
private byte[] s;
@@ -422,10 +424,22 @@
private static final int BLOCK_SIZE = 16;
/**
+ * Return an AESEngine.
+ *
+ * @return an AES ECB mode cipher.
+ */
+ public static MultiBlockCipher newInstance()
+ {
+ return new AESEngine();
+ }
+
+ /**
* default constructor - 128 bit block size.
+ * @deprecated use AESEngine.newInstance()
*/
public AESEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 256));
}
/**
@@ -452,6 +466,9 @@
{
s = Arrays.clone(Si);
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, Utils.getPurpose(forEncryption)));
+
return;
}
@@ -468,38 +485,30 @@
return BLOCK_SIZE;
}
- public int processBlock(
- byte[] in,
- int inOff,
- byte[] out,
- int outOff)
+ public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
{
if (WorkingKey == null)
{
throw new IllegalStateException("AES engine not initialised");
}
- if ((inOff + (32 / 2)) > in.length)
+ if (inOff > (in.length - BLOCK_SIZE))
{
throw new DataLengthException("input buffer too short");
}
- if ((outOff + (32 / 2)) > out.length)
+ if (outOff > (out.length - BLOCK_SIZE))
{
throw new OutputLengthException("output buffer too short");
}
if (forEncryption)
{
- unpackBlock(in, inOff);
- encryptBlock(WorkingKey);
- packBlock(out, outOff);
+ encryptBlock(in, inOff, out, outOff, WorkingKey);
}
else
{
- unpackBlock(in, inOff);
- decryptBlock(WorkingKey);
- packBlock(out, outOff);
+ decryptBlock(in, inOff, out, outOff, WorkingKey);
}
return BLOCK_SIZE;
@@ -509,68 +518,18 @@
{
}
- private void unpackBlock(
- byte[] bytes,
- int off)
+ private void encryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- int index = off;
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- C0 = (bytes[index++] & 0xff);
- C0 |= (bytes[index++] & 0xff) << 8;
- C0 |= (bytes[index++] & 0xff) << 16;
- C0 |= bytes[index++] << 24;
+ int t0 = C0 ^ KW[0][0];
+ int t1 = C1 ^ KW[0][1];
+ int t2 = C2 ^ KW[0][2];
- C1 = (bytes[index++] & 0xff);
- C1 |= (bytes[index++] & 0xff) << 8;
- C1 |= (bytes[index++] & 0xff) << 16;
- C1 |= bytes[index++] << 24;
-
- C2 = (bytes[index++] & 0xff);
- C2 |= (bytes[index++] & 0xff) << 8;
- C2 |= (bytes[index++] & 0xff) << 16;
- C2 |= bytes[index++] << 24;
-
- C3 = (bytes[index++] & 0xff);
- C3 |= (bytes[index++] & 0xff) << 8;
- C3 |= (bytes[index++] & 0xff) << 16;
- C3 |= bytes[index++] << 24;
- }
-
- private void packBlock(
- byte[] bytes,
- int off)
- {
- int index = off;
-
- bytes[index++] = (byte)C0;
- bytes[index++] = (byte)(C0 >> 8);
- bytes[index++] = (byte)(C0 >> 16);
- bytes[index++] = (byte)(C0 >> 24);
-
- bytes[index++] = (byte)C1;
- bytes[index++] = (byte)(C1 >> 8);
- bytes[index++] = (byte)(C1 >> 16);
- bytes[index++] = (byte)(C1 >> 24);
-
- bytes[index++] = (byte)C2;
- bytes[index++] = (byte)(C2 >> 8);
- bytes[index++] = (byte)(C2 >> 16);
- bytes[index++] = (byte)(C2 >> 24);
-
- bytes[index++] = (byte)C3;
- bytes[index++] = (byte)(C3 >> 8);
- bytes[index++] = (byte)(C3 >> 16);
- bytes[index++] = (byte)(C3 >> 24);
- }
-
-
- private void encryptBlock(int[][] KW)
- {
- int t0 = this.C0 ^ KW[0][0];
- int t1 = this.C1 ^ KW[0][1];
- int t2 = this.C2 ^ KW[0][2];
-
- int r = 1, r0, r1, r2, r3 = this.C3 ^ KW[0][3];
+ int r = 1, r0, r1, r2, r3 = C3 ^ KW[0][3];
while (r < ROUNDS - 1)
{
r0 = T0[t0&255] ^ shift(T0[(t1>>8)&255], 24) ^ shift(T0[(t2>>16)&255], 16) ^ shift(T0[(r3>>24)&255], 8) ^ KW[r][0];
@@ -590,19 +549,29 @@
// the final round's table is a simple function of S so we don't use a whole other four tables for it
- this.C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[r][0];
- this.C1 = (s[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[r][1];
- this.C2 = (s[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2];
- this.C3 = (s[r3&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3];
+ C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[r][0];
+ C1 = (s[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[r][1];
+ C2 = (s[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2];
+ C3 = (s[r3&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
}
- private void decryptBlock(int[][] KW)
+ private void decryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- int t0 = this.C0 ^ KW[ROUNDS][0];
- int t1 = this.C1 ^ KW[ROUNDS][1];
- int t2 = this.C2 ^ KW[ROUNDS][2];
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- int r = ROUNDS - 1, r0, r1, r2, r3 = this.C3 ^ KW[ROUNDS][3];
+ int t0 = C0 ^ KW[ROUNDS][0];
+ int t1 = C1 ^ KW[ROUNDS][1];
+ int t2 = C2 ^ KW[ROUNDS][2];
+
+ int r = ROUNDS - 1, r0, r1, r2, r3 = C3 ^ KW[ROUNDS][3];
while (r > 1)
{
r0 = Tinv0[t0&255] ^ shift(Tinv0[(r3>>8)&255], 24) ^ shift(Tinv0[(t2>>16)&255], 16) ^ shift(Tinv0[(t1>>24)&255], 8) ^ KW[r][0];
@@ -622,9 +591,23 @@
// the final round's table is a simple function of Si so we don't use a whole other four tables for it
- this.C0 = (Si[r0&255]&255) ^ ((s[(r3>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0];
- this.C1 = (s[r1&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (s[(r2>>24)&255]<<24) ^ KW[0][1];
- this.C2 = (s[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[0][2];
- this.C3 = (Si[r3&255]&255) ^ ((s[(r2>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[0][3];
+ C0 = (Si[r0&255]&255) ^ ((s[(r3>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0];
+ C1 = (s[r1&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (s[(r2>>24)&255]<<24) ^ KW[0][1];
+ C2 = (s[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[0][2];
+ C3 = (Si[r3&255]&255) ^ ((s[(r2>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[0][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
+ }
+
+ private int bitsOfSecurity()
+ {
+ if (WorkingKey == null)
+ {
+ return 256;
+ }
+ return (WorkingKey.length - 7) << 5;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESFastEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESFastEngine.java
index 95ccb38..d222a67 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESFastEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESFastEngine.java
@@ -3,8 +3,10 @@
import com.android.org.bouncycastle.crypto.BlockCipher;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.DataLengthException;
import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.KeyParameter;
import com.android.org.bouncycastle.util.Pack;
@@ -14,7 +16,7 @@
* For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
- * <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
+ * <a href="https://fp.gladman.plus.com/cryptography_technology/rijndael/">https://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
*
* There are three levels of tradeoff of speed vs memory
* Because java has no preprocessor, they are written as three separate classes from which to choose
@@ -743,7 +745,6 @@
private int ROUNDS;
private int[][] WorkingKey = null;
- private int C0, C1, C2, C3;
private boolean forEncryption;
private static final int BLOCK_SIZE = 16;
@@ -753,6 +754,7 @@
*/
public AESFastEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 256));
}
/**
@@ -771,6 +773,7 @@
{
WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption);
this.forEncryption = forEncryption;
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, Utils.getPurpose(forEncryption)));
return;
}
@@ -787,40 +790,32 @@
return BLOCK_SIZE;
}
- public int processBlock(
- byte[] in,
- int inOff,
- byte[] out,
- int outOff)
+ public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
{
if (WorkingKey == null)
{
throw new IllegalStateException("AES engine not initialised");
}
- if ((inOff + (32 / 2)) > in.length)
+ if (inOff > (in.length - BLOCK_SIZE))
{
throw new DataLengthException("input buffer too short");
}
- if ((outOff + (32 / 2)) > out.length)
+ if (outOff > (out.length - BLOCK_SIZE))
{
throw new OutputLengthException("output buffer too short");
}
- unpackBlock(in, inOff);
-
if (forEncryption)
{
- encryptBlock(WorkingKey);
+ encryptBlock(in, inOff, out, outOff, WorkingKey);
}
else
{
- decryptBlock(WorkingKey);
+ decryptBlock(in, inOff, out, outOff, WorkingKey);
}
- packBlock(out, outOff);
-
return BLOCK_SIZE;
}
@@ -828,27 +823,16 @@
{
}
- private void unpackBlock(byte[] bytes, int off)
+ private void encryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- this.C0 = Pack.littleEndianToInt(bytes, off);
- this.C1 = Pack.littleEndianToInt(bytes, off + 4);
- this.C2 = Pack.littleEndianToInt(bytes, off + 8);
- this.C3 = Pack.littleEndianToInt(bytes, off + 12);
- }
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- private void packBlock(byte[] bytes, int off)
- {
- Pack.intToLittleEndian(this.C0, bytes, off);
- Pack.intToLittleEndian(this.C1, bytes, off + 4);
- Pack.intToLittleEndian(this.C2, bytes, off + 8);
- Pack.intToLittleEndian(this.C3, bytes, off + 12);
- }
-
- private void encryptBlock(int[][] KW)
- {
- int t0 = this.C0 ^ KW[0][0];
- int t1 = this.C1 ^ KW[0][1];
- int t2 = this.C2 ^ KW[0][2];
+ int t0 = C0 ^ KW[0][0];
+ int t1 = C1 ^ KW[0][1];
+ int t2 = C2 ^ KW[0][2];
/*
* Fast engine has precomputed rotr(T0, 8/16/24) tables T1/T2/T3.
@@ -857,7 +841,7 @@
* avoids additional array range checks on 3 more arrays (which on HotSpot are more
* expensive than the offset additions).
*/
- int r = 1, r0, r1, r2, r3 = this.C3 ^ KW[0][3];
+ int r = 1, r0, r1, r2, r3 = C3 ^ KW[0][3];
int i0, i1, i2, i3;
while (r < ROUNDS - 1)
@@ -915,28 +899,38 @@
i0 = r0; i1 = r1 >>> 8; i2 = r2 >>> 16; i3 = r3 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][0];
+ C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][0];
i0 = r1; i1 = r2 >>> 8; i2 = r3 >>> 16; i3 = r0 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][1];
+ C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][1];
i0 = r2; i1 = r3 >>> 8; i2 = r0 >>> 16; i3 = r1 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][2];
+ C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][2];
i0 = r3; i1 = r0 >>> 8; i2 = r1 >>> 16; i3 = r2 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][3];
+ C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
}
- private void decryptBlock(int[][] KW)
+ private void decryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- int t0 = this.C0 ^ KW[ROUNDS][0];
- int t1 = this.C1 ^ KW[ROUNDS][1];
- int t2 = this.C2 ^ KW[ROUNDS][2];
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- int r = ROUNDS - 1, r0, r1, r2, r3 = this.C3 ^ KW[ROUNDS][3];
+ int t0 = C0 ^ KW[ROUNDS][0];
+ int t1 = C1 ^ KW[ROUNDS][1];
+ int t2 = C2 ^ KW[ROUNDS][2];
+
+ int r = ROUNDS - 1, r0, r1, r2, r3 = C3 ^ KW[ROUNDS][3];
int i0, i1, i2, i3;
while (r > 1)
@@ -994,18 +988,33 @@
i0 = r0; i1 = r3 >>> 8; i2 = r2 >>> 16; i3 = r1 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][0];
+ C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][0];
i0 = r1; i1 = r0 >>> 8; i2 = r3 >>> 16; i3 = r2 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][1];
+ C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][1];
i0 = r2; i1 = r1 >>> 8; i2 = r0 >>> 16; i3 = r3 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][2];
+ C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][2];
i0 = r3; i1 = r2 >>> 8; i2 = r1 >>> 16; i3 = r0 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][3];
+ C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
+ }
+
+ // Service Definitions
+ private int bitsOfSecurity()
+ {
+ if (WorkingKey == null)
+ {
+ return 256;
+ }
+ return (WorkingKey.length - 7) << 5;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESWrapEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESWrapEngine.java
index 00690c1..e0caf1e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESWrapEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESWrapEngine.java
@@ -16,16 +16,16 @@
*/
public AESWrapEngine()
{
- super(new AESEngine());
+ super(AESEngine.newInstance());
}
/**
- * Create an AESWrapEngine where the underlying cipher is set to decrypt for wrapping, encrypt for unwrapping.
+ * Create an AESWrapEngine where the underlying cipher is (optionally) set to decrypt for wrapping, encrypt for unwrapping.
*
* @param useReverseDirection true if underlying cipher should be used in decryption mode, false otherwise.
*/
public AESWrapEngine(boolean useReverseDirection)
{
- super(new AESEngine(), useReverseDirection);
+ super(AESEngine.newInstance(), useReverseDirection);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AsconEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AsconEngine.java
new file mode 100644
index 0000000..f088224
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AsconEngine.java
@@ -0,0 +1,743 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.engines;
+
+import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import com.android.org.bouncycastle.crypto.modes.AEADCipher;
+import com.android.org.bouncycastle.crypto.params.AEADParameters;
+import com.android.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Longs;
+import com.android.org.bouncycastle.util.Pack;
+
+/**
+ * ASCON AEAD v1.2, https://ascon.iaik.tugraz.at/
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf
+ * <p>
+ * ASCON AEAD v1.2 with reference to C Reference Impl from: https://github.com/ascon/ascon-c
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AsconEngine
+ implements AEADCipher
+{
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public enum AsconParameters
+ {
+ ascon80pq,
+ ascon128a,
+ ascon128
+ }
+
+ private enum State
+ {
+ Uninitialized,
+ EncInit,
+ EncAad,
+ EncData,
+ EncFinal,
+ DecInit,
+ DecAad,
+ DecData,
+ DecFinal,
+ }
+
+ private final AsconParameters asconParameters;
+ private State m_state = State.Uninitialized;
+ private byte[] mac;
+ private byte[] initialAssociatedText;
+ private final String algorithmName;
+ private final int CRYPTO_KEYBYTES;
+ private final int CRYPTO_ABYTES;
+ private final int ASCON_AEAD_RATE;
+ private final int nr;
+ private long K0;
+ private long K1;
+ private long K2;
+ private long N0;
+ private long N1;
+ private final long ASCON_IV;
+ private long x0;
+ private long x1;
+ private long x2;
+ private long x3;
+ private long x4;
+ private final int m_bufferSizeDecrypt;
+ private final byte[] m_buf;
+ private int m_bufPos = 0;
+
+ public AsconEngine(AsconParameters asconParameters)
+ {
+ this.asconParameters = asconParameters;
+ switch (asconParameters)
+ {
+ case ascon80pq:
+ CRYPTO_KEYBYTES = 20;
+ CRYPTO_ABYTES = 16;
+ ASCON_AEAD_RATE = 8;
+ ASCON_IV = 0xa0400c0600000000L;
+ algorithmName = "Ascon-80pq AEAD";
+ break;
+ case ascon128a:
+ CRYPTO_KEYBYTES = 16;
+ CRYPTO_ABYTES = 16;
+ ASCON_AEAD_RATE = 16;
+ ASCON_IV = 0x80800c0800000000L;
+ algorithmName = "Ascon-128a AEAD";
+ break;
+ case ascon128:
+ CRYPTO_KEYBYTES = 16;
+ CRYPTO_ABYTES = 16;
+ ASCON_AEAD_RATE = 8;
+ ASCON_IV = 0x80400c0600000000L;
+ algorithmName = "Ascon-128 AEAD";
+ break;
+ default:
+ throw new IllegalArgumentException("invalid parameter setting for ASCON AEAD");
+ }
+ nr = (ASCON_AEAD_RATE == 8) ? 6 : 8;
+ m_bufferSizeDecrypt = ASCON_AEAD_RATE + CRYPTO_ABYTES;
+ m_buf = new byte[m_bufferSizeDecrypt];
+ }
+
+ private long PAD(int i)
+ {
+ return 0x80L << (56 - (i << 3));
+ }
+
+ private void ROUND(long C)
+ {
+ long t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
+ long t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
+ long t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
+ long t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
+ long t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
+ x0 = t0 ^ Longs.rotateRight(t0, 19) ^ Longs.rotateRight(t0, 28);
+ x1 = t1 ^ Longs.rotateRight(t1, 39) ^ Longs.rotateRight(t1, 61);
+ x2 = ~(t2 ^ Longs.rotateRight(t2, 1) ^ Longs.rotateRight(t2, 6));
+ x3 = t3 ^ Longs.rotateRight(t3, 10) ^ Longs.rotateRight(t3, 17);
+ x4 = t4 ^ Longs.rotateRight(t4, 7) ^ Longs.rotateRight(t4, 41);
+ }
+
+ private void P(int nr)
+ {
+ if (nr >= 8)
+ {
+ if (nr == 12)
+ {
+ ROUND(0xf0L);
+ ROUND(0xe1L);
+ ROUND(0xd2L);
+ ROUND(0xc3L);
+ }
+ ROUND(0xb4L);
+ ROUND(0xa5L);
+ }
+ ROUND(0x96L);
+ ROUND(0x87L);
+ ROUND(0x78L);
+ ROUND(0x69L);
+ ROUND(0x5aL);
+ ROUND(0x4bL);
+ }
+
+ private void ascon_aeadinit()
+ {
+ /* initialize */
+ x0 = ASCON_IV;
+ if (CRYPTO_KEYBYTES == 20)
+ {
+ x0 ^= K0;
+ }
+ x1 = K1;
+ x2 = K2;
+ x3 = N0;
+ x4 = N1;
+ P(12);
+ if (CRYPTO_KEYBYTES == 20)
+ {
+ x2 ^= K0;
+ }
+ x3 ^= K1;
+ x4 ^= K2;
+ }
+
+ private void checkAAD()
+ {
+ switch (m_state)
+ {
+ case DecInit:
+ m_state = State.DecAad;
+ break;
+ case EncInit:
+ m_state = State.EncAad;
+ break;
+ case DecAad:
+ case EncAad:
+ break;
+ case EncFinal:
+ throw new IllegalStateException(getAlgorithmName() + " cannot be reused for encryption");
+ default:
+ throw new IllegalStateException(getAlgorithmName() + " needs to be initialized");
+ }
+ }
+
+ private boolean checkData()
+ {
+ switch (m_state)
+ {
+ case DecInit:
+ case DecAad:
+ finishAAD(State.DecData);
+ return false;
+ case EncInit:
+ case EncAad:
+ finishAAD(State.EncData);
+ return true;
+ case DecData:
+ return false;
+ case EncData:
+ return true;
+ case EncFinal:
+ throw new IllegalStateException(getAlgorithmName() + " cannot be reused for encryption");
+ default:
+ throw new IllegalStateException(getAlgorithmName() + " needs to be initialized");
+ }
+ }
+
+ private void processBufferAAD(byte[] buffer, int inOff)
+ {
+ x0 ^= Pack.bigEndianToLong(buffer, inOff);
+ if (ASCON_AEAD_RATE == 16)
+ {
+ x1 ^= Pack.bigEndianToLong(buffer, 8 + inOff);
+ }
+ P(nr);
+ }
+
+ private void finishAAD(State nextState)
+ {
+ // State indicates whether we ever received AAD
+ switch (m_state)
+ {
+ case DecAad:
+ case EncAad:
+ m_buf[m_bufPos] = (byte)0x80;
+ if (m_bufPos >= 8) // ASCON_AEAD_RATE == 16 is implied
+ {
+ x0 ^= Pack.bigEndianToLong(m_buf, 0);
+ x1 ^= Pack.bigEndianToLong(m_buf, 8) & (-1L << (56 - ((m_bufPos - 8) << 3)));
+ }
+ else
+ {
+ x0 ^= Pack.bigEndianToLong(m_buf, 0) & (-1L << (56 - (m_bufPos << 3)));
+ }
+ P(nr);
+ break;
+ default:
+ break;
+ }
+ // domain separation
+ x4 ^= 1L;
+ m_bufPos = 0;
+ m_state = nextState;
+ }
+
+ private void processBufferDecrypt(byte[] buffer, int bufOff, byte[] output, int outOff)
+ {
+ if (outOff + ASCON_AEAD_RATE > output.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ long t0 = Pack.bigEndianToLong(buffer, bufOff);
+ Pack.longToBigEndian(x0 ^ t0, output, outOff);
+ x0 = t0;
+
+ if (ASCON_AEAD_RATE == 16)
+ {
+ long t1 = Pack.bigEndianToLong(buffer, bufOff + 8);
+ Pack.longToBigEndian(x1 ^ t1, output, outOff + 8);
+ x1 = t1;
+ }
+ P(nr);
+ }
+
+ private void processBufferEncrypt(byte[] buffer, int bufOff, byte[] output, int outOff)
+ {
+ if (outOff + ASCON_AEAD_RATE > output.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ x0 ^= Pack.bigEndianToLong(buffer, bufOff);
+ Pack.longToBigEndian(x0, output, outOff);
+
+ if (ASCON_AEAD_RATE == 16)
+ {
+ x1 ^= Pack.bigEndianToLong(buffer, bufOff + 8);
+ Pack.longToBigEndian(x1, output, outOff + 8);
+ }
+
+ P(nr);
+ }
+
+ private void processFinalDecrypt(byte[] input, int inOff, int inLen, byte[] output, int outOff)
+ {
+ if (inLen >= 8) // ASCON_AEAD_RATE == 16 is implied
+ {
+ long c0 = Pack.bigEndianToLong(input, inOff);
+ x0 ^= c0;
+ Pack.longToBigEndian(x0, output, outOff);
+ x0 = c0;
+ inOff += 8;
+ outOff += 8;
+ inLen -= 8;
+ x1 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ long c1 = Pack.littleEndianToLong_High(input, inOff, inLen);
+ x1 ^= c1;
+ Pack.longToLittleEndian_High(x1, output, outOff, inLen);
+ x1 &= -1L >>> (inLen << 3);
+ x1 ^= c1;
+ }
+ }
+ else
+ {
+ x0 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ long c0 = Pack.littleEndianToLong_High(input, inOff, inLen);
+ x0 ^= c0;
+ Pack.longToLittleEndian_High(x0, output, outOff, inLen);
+ x0 &= -1L >>> (inLen << 3);
+ x0 ^= c0;
+ }
+ }
+
+ finishData(State.DecFinal);
+ }
+
+ private void processFinalEncrypt(byte[] input, int inOff, int inLen, byte[] output, int outOff)
+ {
+ if (inLen >= 8) // ASCON_AEAD_RATE == 16 is implied
+ {
+ x0 ^= Pack.bigEndianToLong(input, inOff);
+ Pack.longToBigEndian(x0, output, outOff);
+ inOff += 8;
+ outOff += 8;
+ inLen -= 8;
+ x1 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ x1 ^= Pack.littleEndianToLong_High(input, inOff, inLen);
+ Pack.longToLittleEndian_High(x1, output, outOff, inLen);
+ }
+ }
+ else
+ {
+ x0 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ x0 ^= Pack.littleEndianToLong_High(input, inOff, inLen);
+ Pack.longToLittleEndian_High(x0, output, outOff, inLen);
+ }
+ }
+ finishData(State.EncFinal);
+ }
+
+ private void finishData(State nextState)
+ {
+ switch (asconParameters)
+ {
+ case ascon128:
+ x1 ^= K1;
+ x2 ^= K2;
+ break;
+ case ascon128a:
+ x2 ^= K1;
+ x3 ^= K2;
+ break;
+ case ascon80pq:
+ x1 ^= (K0 << 32 | K1 >> 32);
+ x2 ^= (K1 << 32 | K2 >> 32);
+ x3 ^= K2 << 32;
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ P(12);
+ x3 ^= K1;
+ x4 ^= K2;
+
+ m_state = nextState;
+ }
+
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException
+ {
+ KeyParameter key;
+ byte[] npub;
+ if (params instanceof AEADParameters)
+ {
+ AEADParameters aeadParameters = (AEADParameters)params;
+ key = aeadParameters.getKey();
+ npub = aeadParameters.getNonce();
+ initialAssociatedText = aeadParameters.getAssociatedText();
+
+ int macSizeBits = aeadParameters.getMacSize();
+ if (macSizeBits != CRYPTO_ABYTES * 8)
+ {
+ throw new IllegalArgumentException("Invalid value for MAC size: " + macSizeBits);
+ }
+ }
+ else if (params instanceof ParametersWithIV)
+ {
+ ParametersWithIV withIV = (ParametersWithIV)params;
+ key = (KeyParameter)withIV.getParameters();
+ npub = withIV.getIV();
+ initialAssociatedText = null;
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid parameters passed to Ascon");
+ }
+
+ if (key == null)
+ {
+ throw new IllegalArgumentException("Ascon Init parameters must include a key");
+ }
+ if (npub == null || npub.length != CRYPTO_ABYTES)
+ {
+ throw new IllegalArgumentException(asconParameters + " requires exactly " + CRYPTO_ABYTES + " bytes of IV");
+ }
+
+ byte[] k = key.getKey();
+ if (k.length != CRYPTO_KEYBYTES)
+ {
+ throw new IllegalArgumentException(asconParameters + " key must be " + CRYPTO_KEYBYTES + " bytes long");
+ }
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(
+ this.getAlgorithmName(), 128, params, Utils.getPurpose(forEncryption)));
+ N0 = Pack.bigEndianToLong(npub, 0);
+ N1 = Pack.bigEndianToLong(npub, 8);
+ if (CRYPTO_KEYBYTES == 16)
+ {
+ K1 = Pack.bigEndianToLong(k, 0);
+ K2 = Pack.bigEndianToLong(k, 8);
+ }
+ else if (CRYPTO_KEYBYTES == 20)
+ {
+ K0 = Pack.bigEndianToInt(k, 0);
+ K1 = Pack.bigEndianToLong(k, 4);
+ K2 = Pack.bigEndianToLong(k, 12);
+ }
+ else
+ {
+ throw new IllegalStateException();
+ }
+
+ m_state = forEncryption ? State.EncInit : State.DecInit;
+
+ reset(true);
+ }
+
+ public String getAlgorithmName()
+ {
+ return algorithmName;
+ }
+
+ public String getAlgorithmVersion()
+ {
+ return "v1.2";
+ }
+
+ public void processAADByte(byte in)
+ {
+ checkAAD();
+ m_buf[m_bufPos] = in;
+ if (++m_bufPos == ASCON_AEAD_RATE)
+ {
+ processBufferAAD(m_buf, 0);
+ }
+ }
+
+ public void processAADBytes(byte[] inBytes, int inOff, int len)
+ {
+ if ((inOff + len) > inBytes.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ // Don't enter AAD state until we actually get input
+ if (len <= 0)
+ {
+ return;
+ }
+ checkAAD();
+ if (m_bufPos > 0)
+ {
+ int available = ASCON_AEAD_RATE - m_bufPos;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return;
+ }
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, available);
+ inOff += available;
+ len -= available;
+ processBufferAAD(m_buf, 0);
+ //m_bufPos = 0;
+ }
+ while (len >= ASCON_AEAD_RATE)
+ {
+ processBufferAAD(inBytes, inOff);
+ inOff += ASCON_AEAD_RATE;
+ len -= ASCON_AEAD_RATE;
+ }
+ System.arraycopy(inBytes, inOff, m_buf, 0, len);
+ m_bufPos = len;
+ }
+
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ return processBytes(new byte[]{in}, 0, 1, out, outOff);
+ }
+
+ public int processBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff)
+ throws DataLengthException
+ {
+ if ((inOff + len) > inBytes.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ boolean forEncryption = checkData();
+ int resultLength = 0;
+
+ if (forEncryption)
+ {
+ if (m_bufPos > 0)
+ {
+ int available = ASCON_AEAD_RATE - m_bufPos;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return 0;
+ }
+
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, available);
+ inOff += available;
+ len -= available;
+
+ processBufferEncrypt(m_buf, 0, outBytes, outOff);
+ resultLength = ASCON_AEAD_RATE;
+ //m_bufPos = 0;
+ }
+
+ while (len >= ASCON_AEAD_RATE)
+ {
+ processBufferEncrypt(inBytes, inOff, outBytes, outOff + resultLength);
+ inOff += ASCON_AEAD_RATE;
+ len -= ASCON_AEAD_RATE;
+ resultLength += ASCON_AEAD_RATE;
+ }
+ }
+ else
+ {
+ int available = m_bufferSizeDecrypt - m_bufPos;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return 0;
+ }
+
+ // NOTE: Need 'while' here because ASCON_AEAD_RATE < CRYPTO_ABYTES in some parameter sets
+ while (m_bufPos >= ASCON_AEAD_RATE)
+ {
+ processBufferDecrypt(m_buf, 0, outBytes, outOff + resultLength);
+ m_bufPos -= ASCON_AEAD_RATE;
+ System.arraycopy(m_buf, ASCON_AEAD_RATE, m_buf, 0, m_bufPos);
+ resultLength += ASCON_AEAD_RATE;
+
+ available += ASCON_AEAD_RATE;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return resultLength;
+ }
+ }
+
+ available = ASCON_AEAD_RATE - m_bufPos;
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, available);
+ inOff += available;
+ len -= available;
+ processBufferDecrypt(m_buf, 0, outBytes, outOff + resultLength);
+ resultLength += ASCON_AEAD_RATE;
+ //m_bufPos = 0;
+
+ while (len >= m_bufferSizeDecrypt)
+ {
+ processBufferDecrypt(inBytes, inOff, outBytes, outOff + resultLength);
+ inOff += ASCON_AEAD_RATE;
+ len -= ASCON_AEAD_RATE;
+ resultLength += ASCON_AEAD_RATE;
+ }
+ }
+
+ System.arraycopy(inBytes, inOff, m_buf, 0, len);
+ m_bufPos = len;
+
+ return resultLength;
+ }
+
+ public int doFinal(byte[] outBytes, int outOff)
+ throws IllegalStateException, InvalidCipherTextException, DataLengthException
+ {
+ boolean forEncryption = checkData();
+ int resultLength;
+ if (forEncryption)
+ {
+ resultLength = m_bufPos + CRYPTO_ABYTES;
+ if (outOff + resultLength > outBytes.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ processFinalEncrypt(m_buf, 0, m_bufPos, outBytes, outOff);
+ mac = new byte[CRYPTO_ABYTES];
+ Pack.longToBigEndian(x3, mac, 0);
+ Pack.longToBigEndian(x4, mac, 8);
+ System.arraycopy(mac, 0, outBytes, outOff + m_bufPos, CRYPTO_ABYTES);
+ reset(false);
+ }
+ else
+ {
+ if (m_bufPos < CRYPTO_ABYTES)
+ {
+ throw new InvalidCipherTextException("data too short");
+ }
+ m_bufPos -= CRYPTO_ABYTES;
+ resultLength = m_bufPos;
+ if (outOff + resultLength > outBytes.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ processFinalDecrypt(m_buf, 0, m_bufPos, outBytes, outOff);
+ x3 ^= Pack.bigEndianToLong(m_buf, m_bufPos);
+ x4 ^= Pack.bigEndianToLong(m_buf, m_bufPos + 8);
+ if ((x3 | x4) != 0L)
+ {
+ throw new InvalidCipherTextException("mac check in " + getAlgorithmName() + " failed");
+ }
+ reset(true);
+ }
+ return resultLength;
+ }
+
+ public byte[] getMac()
+ {
+ return mac;
+ }
+
+ public int getUpdateOutputSize(int len)
+ {
+ int total = Math.max(0, len);
+ switch (m_state)
+ {
+ case DecInit:
+ case DecAad:
+ total = Math.max(0, total - CRYPTO_ABYTES);
+ break;
+ case DecData:
+ case DecFinal:
+ total = Math.max(0, total + m_bufPos - CRYPTO_ABYTES);
+ break;
+ case EncData:
+ case EncFinal:
+ total += m_bufPos;
+ break;
+ default:
+ break;
+ }
+ return total - total % ASCON_AEAD_RATE;
+ }
+
+ public int getOutputSize(int len)
+ {
+ int total = Math.max(0, len);
+
+ switch (m_state)
+ {
+ case DecInit:
+ case DecAad:
+ return Math.max(0, total - CRYPTO_ABYTES);
+ case DecData:
+ case DecFinal:
+ return Math.max(0, total + m_bufPos - CRYPTO_ABYTES);
+ case EncData:
+ case EncFinal:
+ return total + m_bufPos + CRYPTO_ABYTES;
+ default:
+ return total + CRYPTO_ABYTES;
+ }
+ }
+
+ public void reset()
+ {
+ reset(true);
+ }
+
+ private void reset(boolean clearMac)
+ {
+ if (clearMac)
+ {
+ mac = null;
+ }
+ Arrays.clear(m_buf);
+ m_bufPos = 0;
+
+ switch (m_state)
+ {
+ case DecInit:
+ case EncInit:
+ break;
+ case DecAad:
+ case DecData:
+ case DecFinal:
+ m_state = State.DecInit;
+ break;
+ case EncAad:
+ case EncData:
+ case EncFinal:
+ m_state = State.EncFinal;
+ return;
+ default:
+ throw new IllegalStateException(getAlgorithmName() + " needs to be initialized");
+ }
+ ascon_aeadinit();
+ if (initialAssociatedText != null)
+ {
+ processAADBytes(initialAssociatedText, 0, initialAssociatedText.length);
+ }
+ }
+
+ public int getKeyBytesSize()
+ {
+ return CRYPTO_KEYBYTES;
+ }
+
+ public int getIVBytesSize()
+ {
+ return CRYPTO_ABYTES;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/BlowfishEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/BlowfishEngine.java
index 2979a61..ab6f8d6 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/BlowfishEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/BlowfishEngine.java
@@ -3,8 +3,11 @@
import com.android.org.bouncycastle.crypto.BlockCipher;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.DataLengthException;
import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.KeyParameter;
/**
@@ -317,6 +320,7 @@
S2 = new int[SBOX_SK];
S3 = new int[SBOX_SK];
P = new int[P_SZ];
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity()));
}
/**
@@ -337,6 +341,7 @@
this.workingKey = ((KeyParameter)params).getKey();
setKey(this.workingKey);
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, getPurpose()));
return;
}
@@ -433,6 +438,11 @@
private void setKey(byte[] key)
{
+ if (key.length < 4 || key.length > 56)
+ {
+ throw new IllegalArgumentException("key length must be in range 32 to 448 bits");
+ }
+
/*
* - comments are from _Applied Crypto_, Schneier, p338
* please be careful comparing the two, AC numbers the
@@ -577,4 +587,22 @@
b[offset + 1] = (byte)(in >> 16);
b[offset] = (byte)(in >> 24);
}
+
+ private int bitsOfSecurity()
+ {
+ if (workingKey == null)
+ {
+ return 256;
+ }
+ return (workingKey.length > 32) ? 256 : workingKey.length * 8;
+ }
+
+ private CryptoServicePurpose getPurpose()
+ {
+ if (workingKey == null)
+ {
+ return CryptoServicePurpose.ANY;
+ }
+ return encrypting ? CryptoServicePurpose.ENCRYPTION : CryptoServicePurpose.DECRYPTION;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESBase.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESBase.java
new file mode 100644
index 0000000..8ec449c
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESBase.java
@@ -0,0 +1,408 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.engines;
+
+import com.android.org.bouncycastle.util.Pack;
+
+/**
+ * a class that provides a basic DES engine.
+ */
+class DESBase
+{
+ protected static final int BLOCK_SIZE = 8;
+
+ /**
+ * standard constructor.
+ */
+ public DESBase()
+ {
+ }
+
+ /**
+ * what follows is mainly taken from "Applied Cryptography", by
+ * Bruce Schneier, however it also bears great resemblance to Richard
+ * Outerbridge's D3DES...
+ */
+
+// private static final short[] Df_Key =
+// {
+// 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+// 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+// 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
+// };
+
+ private static final short[] bytebit =
+ {
+ 0200, 0100, 040, 020, 010, 04, 02, 01
+ };
+
+ private static final int[] bigbyte =
+ {
+ 0x800000, 0x400000, 0x200000, 0x100000,
+ 0x80000, 0x40000, 0x20000, 0x10000,
+ 0x8000, 0x4000, 0x2000, 0x1000,
+ 0x800, 0x400, 0x200, 0x100,
+ 0x80, 0x40, 0x20, 0x10,
+ 0x8, 0x4, 0x2, 0x1
+ };
+
+ /*
+ * Use the key schedule specified in the Standard (ANSI X3.92-1981).
+ */
+
+ private static final byte[] pc1 =
+ {
+ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
+ 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
+ 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
+ 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
+ };
+
+ private static final byte[] totrot =
+ {
+ 1, 2, 4, 6, 8, 10, 12, 14,
+ 15, 17, 19, 21, 23, 25, 27, 28
+ };
+
+ private static final byte[] pc2 =
+ {
+ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
+ 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
+ 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
+ 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
+ };
+
+ private static final int[] SP1 = {
+ 0x01010400, 0x00000000, 0x00010000, 0x01010404,
+ 0x01010004, 0x00010404, 0x00000004, 0x00010000,
+ 0x00000400, 0x01010400, 0x01010404, 0x00000400,
+ 0x01000404, 0x01010004, 0x01000000, 0x00000004,
+ 0x00000404, 0x01000400, 0x01000400, 0x00010400,
+ 0x00010400, 0x01010000, 0x01010000, 0x01000404,
+ 0x00010004, 0x01000004, 0x01000004, 0x00010004,
+ 0x00000000, 0x00000404, 0x00010404, 0x01000000,
+ 0x00010000, 0x01010404, 0x00000004, 0x01010000,
+ 0x01010400, 0x01000000, 0x01000000, 0x00000400,
+ 0x01010004, 0x00010000, 0x00010400, 0x01000004,
+ 0x00000400, 0x00000004, 0x01000404, 0x00010404,
+ 0x01010404, 0x00010004, 0x01010000, 0x01000404,
+ 0x01000004, 0x00000404, 0x00010404, 0x01010400,
+ 0x00000404, 0x01000400, 0x01000400, 0x00000000,
+ 0x00010004, 0x00010400, 0x00000000, 0x01010004
+ };
+
+ private static final int[] SP2 = {
+ 0x80108020, 0x80008000, 0x00008000, 0x00108020,
+ 0x00100000, 0x00000020, 0x80100020, 0x80008020,
+ 0x80000020, 0x80108020, 0x80108000, 0x80000000,
+ 0x80008000, 0x00100000, 0x00000020, 0x80100020,
+ 0x00108000, 0x00100020, 0x80008020, 0x00000000,
+ 0x80000000, 0x00008000, 0x00108020, 0x80100000,
+ 0x00100020, 0x80000020, 0x00000000, 0x00108000,
+ 0x00008020, 0x80108000, 0x80100000, 0x00008020,
+ 0x00000000, 0x00108020, 0x80100020, 0x00100000,
+ 0x80008020, 0x80100000, 0x80108000, 0x00008000,
+ 0x80100000, 0x80008000, 0x00000020, 0x80108020,
+ 0x00108020, 0x00000020, 0x00008000, 0x80000000,
+ 0x00008020, 0x80108000, 0x00100000, 0x80000020,
+ 0x00100020, 0x80008020, 0x80000020, 0x00100020,
+ 0x00108000, 0x00000000, 0x80008000, 0x00008020,
+ 0x80000000, 0x80100020, 0x80108020, 0x00108000
+ };
+
+ private static final int[] SP3 = {
+ 0x00000208, 0x08020200, 0x00000000, 0x08020008,
+ 0x08000200, 0x00000000, 0x00020208, 0x08000200,
+ 0x00020008, 0x08000008, 0x08000008, 0x00020000,
+ 0x08020208, 0x00020008, 0x08020000, 0x00000208,
+ 0x08000000, 0x00000008, 0x08020200, 0x00000200,
+ 0x00020200, 0x08020000, 0x08020008, 0x00020208,
+ 0x08000208, 0x00020200, 0x00020000, 0x08000208,
+ 0x00000008, 0x08020208, 0x00000200, 0x08000000,
+ 0x08020200, 0x08000000, 0x00020008, 0x00000208,
+ 0x00020000, 0x08020200, 0x08000200, 0x00000000,
+ 0x00000200, 0x00020008, 0x08020208, 0x08000200,
+ 0x08000008, 0x00000200, 0x00000000, 0x08020008,
+ 0x08000208, 0x00020000, 0x08000000, 0x08020208,
+ 0x00000008, 0x00020208, 0x00020200, 0x08000008,
+ 0x08020000, 0x08000208, 0x00000208, 0x08020000,
+ 0x00020208, 0x00000008, 0x08020008, 0x00020200
+ };
+
+ private static final int[] SP4 = {
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802080, 0x00800081, 0x00800001, 0x00002001,
+ 0x00000000, 0x00802000, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00800080, 0x00800001,
+ 0x00000001, 0x00002000, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002001, 0x00002080,
+ 0x00800081, 0x00000001, 0x00002080, 0x00800080,
+ 0x00002000, 0x00802080, 0x00802081, 0x00000081,
+ 0x00800080, 0x00800001, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00000000, 0x00802000,
+ 0x00002080, 0x00800080, 0x00800081, 0x00000001,
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802081, 0x00000081, 0x00000001, 0x00002000,
+ 0x00800001, 0x00002001, 0x00802080, 0x00800081,
+ 0x00002001, 0x00002080, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002000, 0x00802080
+ };
+
+ private static final int[] SP5 = {
+ 0x00000100, 0x02080100, 0x02080000, 0x42000100,
+ 0x00080000, 0x00000100, 0x40000000, 0x02080000,
+ 0x40080100, 0x00080000, 0x02000100, 0x40080100,
+ 0x42000100, 0x42080000, 0x00080100, 0x40000000,
+ 0x02000000, 0x40080000, 0x40080000, 0x00000000,
+ 0x40000100, 0x42080100, 0x42080100, 0x02000100,
+ 0x42080000, 0x40000100, 0x00000000, 0x42000000,
+ 0x02080100, 0x02000000, 0x42000000, 0x00080100,
+ 0x00080000, 0x42000100, 0x00000100, 0x02000000,
+ 0x40000000, 0x02080000, 0x42000100, 0x40080100,
+ 0x02000100, 0x40000000, 0x42080000, 0x02080100,
+ 0x40080100, 0x00000100, 0x02000000, 0x42080000,
+ 0x42080100, 0x00080100, 0x42000000, 0x42080100,
+ 0x02080000, 0x00000000, 0x40080000, 0x42000000,
+ 0x00080100, 0x02000100, 0x40000100, 0x00080000,
+ 0x00000000, 0x40080000, 0x02080100, 0x40000100
+ };
+
+ private static final int[] SP6 = {
+ 0x20000010, 0x20400000, 0x00004000, 0x20404010,
+ 0x20400000, 0x00000010, 0x20404010, 0x00400000,
+ 0x20004000, 0x00404010, 0x00400000, 0x20000010,
+ 0x00400010, 0x20004000, 0x20000000, 0x00004010,
+ 0x00000000, 0x00400010, 0x20004010, 0x00004000,
+ 0x00404000, 0x20004010, 0x00000010, 0x20400010,
+ 0x20400010, 0x00000000, 0x00404010, 0x20404000,
+ 0x00004010, 0x00404000, 0x20404000, 0x20000000,
+ 0x20004000, 0x00000010, 0x20400010, 0x00404000,
+ 0x20404010, 0x00400000, 0x00004010, 0x20000010,
+ 0x00400000, 0x20004000, 0x20000000, 0x00004010,
+ 0x20000010, 0x20404010, 0x00404000, 0x20400000,
+ 0x00404010, 0x20404000, 0x00000000, 0x20400010,
+ 0x00000010, 0x00004000, 0x20400000, 0x00404010,
+ 0x00004000, 0x00400010, 0x20004010, 0x00000000,
+ 0x20404000, 0x20000000, 0x00400010, 0x20004010
+ };
+
+ private static final int[] SP7 = {
+ 0x00200000, 0x04200002, 0x04000802, 0x00000000,
+ 0x00000800, 0x04000802, 0x00200802, 0x04200800,
+ 0x04200802, 0x00200000, 0x00000000, 0x04000002,
+ 0x00000002, 0x04000000, 0x04200002, 0x00000802,
+ 0x04000800, 0x00200802, 0x00200002, 0x04000800,
+ 0x04000002, 0x04200000, 0x04200800, 0x00200002,
+ 0x04200000, 0x00000800, 0x00000802, 0x04200802,
+ 0x00200800, 0x00000002, 0x04000000, 0x00200800,
+ 0x04000000, 0x00200800, 0x00200000, 0x04000802,
+ 0x04000802, 0x04200002, 0x04200002, 0x00000002,
+ 0x00200002, 0x04000000, 0x04000800, 0x00200000,
+ 0x04200800, 0x00000802, 0x00200802, 0x04200800,
+ 0x00000802, 0x04000002, 0x04200802, 0x04200000,
+ 0x00200800, 0x00000000, 0x00000002, 0x04200802,
+ 0x00000000, 0x00200802, 0x04200000, 0x00000800,
+ 0x04000002, 0x04000800, 0x00000800, 0x00200002
+ };
+
+ private static final int[] SP8 = {
+ 0x10001040, 0x00001000, 0x00040000, 0x10041040,
+ 0x10000000, 0x10001040, 0x00000040, 0x10000000,
+ 0x00040040, 0x10040000, 0x10041040, 0x00041000,
+ 0x10041000, 0x00041040, 0x00001000, 0x00000040,
+ 0x10040000, 0x10000040, 0x10001000, 0x00001040,
+ 0x00041000, 0x00040040, 0x10040040, 0x10041000,
+ 0x00001040, 0x00000000, 0x00000000, 0x10040040,
+ 0x10000040, 0x10001000, 0x00041040, 0x00040000,
+ 0x00041040, 0x00040000, 0x10041000, 0x00001000,
+ 0x00000040, 0x10040040, 0x00001000, 0x00041040,
+ 0x10001000, 0x00000040, 0x10000040, 0x10040000,
+ 0x10040040, 0x10000000, 0x00040000, 0x10001040,
+ 0x00000000, 0x10041040, 0x00040040, 0x10000040,
+ 0x10040000, 0x10001000, 0x10001040, 0x00000000,
+ 0x10041040, 0x00041000, 0x00041000, 0x00001040,
+ 0x00001040, 0x00040040, 0x10000000, 0x10041000
+ };
+
+ /**
+ * generate an integer based working key based on our secret key
+ * and what we processing we are planning to do.
+ *
+ * Acknowledgements for this routine go to James Gillogly & Phil Karn.
+ * (whoever, and wherever they are!).
+ */
+ protected int[] generateWorkingKey(
+ boolean encrypting,
+ byte[] key)
+ {
+ int[] newKey = new int[32];
+ boolean[] pc1m = new boolean[56],
+ pcr = new boolean[56];
+
+ for (int j = 0; j < 56; j++)
+ {
+ int l = pc1[j];
+
+ pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0);
+ }
+
+ for (int i = 0; i < 16; i++)
+ {
+ int l, m, n;
+
+ if (encrypting)
+ {
+ m = i << 1;
+ }
+ else
+ {
+ m = (15 - i) << 1;
+ }
+
+ n = m + 1;
+ newKey[m] = newKey[n] = 0;
+
+ for (int j = 0; j < 28; j++)
+ {
+ l = j + totrot[i];
+ if (l < 28)
+ {
+ pcr[j] = pc1m[l];
+ }
+ else
+ {
+ pcr[j] = pc1m[l - 28];
+ }
+ }
+
+ for (int j = 28; j < 56; j++)
+ {
+ l = j + totrot[i];
+ if (l < 56)
+ {
+ pcr[j] = pc1m[l];
+ }
+ else
+ {
+ pcr[j] = pc1m[l - 28];
+ }
+ }
+
+ for (int j = 0; j < 24; j++)
+ {
+ if (pcr[pc2[j]])
+ {
+ newKey[m] |= bigbyte[j];
+ }
+
+ if (pcr[pc2[j + 24]])
+ {
+ newKey[n] |= bigbyte[j];
+ }
+ }
+ }
+
+ //
+ // store the processed key
+ //
+ for (int i = 0; i != 32; i += 2)
+ {
+ int i1, i2;
+
+ i1 = newKey[i];
+ i2 = newKey[i + 1];
+
+ newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10)
+ | ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6);
+
+ newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16)
+ | ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f);
+ }
+
+ return newKey;
+ }
+
+ /**
+ * the DES engine.
+ */
+ protected void desFunc(
+ int[] wKey,
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ int work, right, left;
+
+ left = Pack.bigEndianToInt(in, inOff);
+ right = Pack.bigEndianToInt(in, inOff + 4);
+
+ work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
+ right ^= work;
+ left ^= (work << 4);
+ work = ((left >>> 16) ^ right) & 0x0000ffff;
+ right ^= work;
+ left ^= (work << 16);
+ work = ((right >>> 2) ^ left) & 0x33333333;
+ left ^= work;
+ right ^= (work << 2);
+ work = ((right >>> 8) ^ left) & 0x00ff00ff;
+ left ^= work;
+ right ^= (work << 8);
+ right = (right << 1) | (right >>> 31);
+ work = (left ^ right) & 0xaaaaaaaa;
+ left ^= work;
+ right ^= work;
+ left = (left << 1) | (left >>> 31);
+
+ for (int round = 0; round < 8; round++)
+ {
+ int fval;
+
+ work = (right << 28) | (right >>> 4);
+ work ^= wKey[round * 4 + 0];
+ fval = SP7[ work & 0x3f];
+ fval |= SP5[(work >>> 8) & 0x3f];
+ fval |= SP3[(work >>> 16) & 0x3f];
+ fval |= SP1[(work >>> 24) & 0x3f];
+ work = right ^ wKey[round * 4 + 1];
+ fval |= SP8[ work & 0x3f];
+ fval |= SP6[(work >>> 8) & 0x3f];
+ fval |= SP4[(work >>> 16) & 0x3f];
+ fval |= SP2[(work >>> 24) & 0x3f];
+ left ^= fval;
+ work = (left << 28) | (left >>> 4);
+ work ^= wKey[round * 4 + 2];
+ fval = SP7[ work & 0x3f];
+ fval |= SP5[(work >>> 8) & 0x3f];
+ fval |= SP3[(work >>> 16) & 0x3f];
+ fval |= SP1[(work >>> 24) & 0x3f];
+ work = left ^ wKey[round * 4 + 3];
+ fval |= SP8[ work & 0x3f];
+ fval |= SP6[(work >>> 8) & 0x3f];
+ fval |= SP4[(work >>> 16) & 0x3f];
+ fval |= SP2[(work >>> 24) & 0x3f];
+ right ^= fval;
+ }
+
+ right = (right << 31) | (right >>> 1);
+ work = (left ^ right) & 0xaaaaaaaa;
+ left ^= work;
+ right ^= work;
+ left = (left << 31) | (left >>> 1);
+ work = ((left >>> 8) ^ right) & 0x00ff00ff;
+ right ^= work;
+ left ^= (work << 8);
+ work = ((left >>> 2) ^ right) & 0x33333333;
+ right ^= work;
+ left ^= (work << 2);
+ work = ((right >>> 16) ^ left) & 0x0000ffff;
+ left ^= work;
+ right ^= (work << 16);
+ work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
+ left ^= work;
+ right ^= (work << 4);
+
+ Pack.intToBigEndian(right, out, outOff);
+ Pack.intToBigEndian(left, out, outOff + 4);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESEngine.java
index 7d11710..5581827 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESEngine.java
@@ -3,8 +3,10 @@
import com.android.org.bouncycastle.crypto.BlockCipher;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.DataLengthException;
import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.KeyParameter;
import com.android.org.bouncycastle.util.Pack;
@@ -13,10 +15,12 @@
* @hide This class is not part of the Android public SDK API
*/
public class DESEngine
+ extends DESBase
implements BlockCipher
{
protected static final int BLOCK_SIZE = 8;
+ private boolean forEncryption;
private int[] workingKey = null;
/**
@@ -24,6 +28,7 @@
*/
public DESEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 56));
}
/**
@@ -40,14 +45,17 @@
{
if (params instanceof KeyParameter)
{
- if (((KeyParameter)params).getKey().length > 8)
+ if (((KeyParameter)params).getKeyLength() > 8)
{
throw new IllegalArgumentException("DES key too long - should be 8 bytes");
}
-
+
+ forEncryption = encrypting;
workingKey = generateWorkingKey(encrypting,
((KeyParameter)params).getKey());
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 56, params, Utils.getPurpose(forEncryption)));
+
return;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeEngine.java
index 885d0f8..3392fd1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeEngine.java
@@ -1,9 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.engines;
+import com.android.org.bouncycastle.crypto.BlockCipher;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.DataLengthException;
import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.KeyParameter;
/**
@@ -11,34 +14,36 @@
* @hide This class is not part of the Android public SDK API
*/
public class DESedeEngine
- extends DESEngine
+ extends DESBase
+ implements BlockCipher
{
- protected static final int BLOCK_SIZE = 8;
+ protected static final int BLOCK_SIZE = 8;
- private int[] workingKey1 = null;
- private int[] workingKey2 = null;
- private int[] workingKey3 = null;
+ private int[] workingKey1 = null;
+ private int[] workingKey2 = null;
+ private int[] workingKey3 = null;
- private boolean forEncryption;
+ private boolean forEncryption;
/**
* standard constructor.
*/
public DESedeEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity()));
}
/**
* initialise a DESede cipher.
*
* @param encrypting whether or not we are for encryption.
- * @param params the parameters required to set up the cipher.
- * @exception IllegalArgumentException if the params argument is
- * inappropriate.
+ * @param params the parameters required to set up the cipher.
+ * @throws IllegalArgumentException if the params argument is
+ * inappropriate.
*/
public void init(
- boolean encrypting,
- CipherParameters params)
+ boolean encrypting,
+ CipherParameters params)
{
if (!(params instanceof KeyParameter))
{
@@ -72,6 +77,8 @@
{
workingKey3 = workingKey1;
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, Utils.getPurpose(forEncryption)));
}
public String getAlgorithmName()
@@ -126,4 +133,14 @@
public void reset()
{
}
+
+ // Service Definitions
+ private int bitsOfSecurity()
+ {
+ if (workingKey1 != null && workingKey1 == workingKey3)
+ {
+ return 80;
+ }
+ return 112;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeWrapEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
index d1c05ce..dde38f9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
@@ -184,8 +184,8 @@
System.arraycopy(this.iv, 0, TEMP2, 0, this.iv.length);
System.arraycopy(TEMP1, 0, TEMP2, this.iv.length, TEMP1.length);
- // Reverse the order of the octets in TEMP2 and call the result TEMP3.
- byte[] TEMP3 = reverse(TEMP2);
+ // Reverse the order of the octets in TEMP2.
+ Arrays.reverseInPlace(TEMP2);
// Encrypt TEMP3 in CBC mode using the KEK and an initialization vector
// of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired
@@ -194,12 +194,12 @@
this.engine.init(true, param2);
- for (int currentBytePos = 0; currentBytePos != TEMP3.length; currentBytePos += blockSize)
+ for (int currentBytePos = 0; currentBytePos != TEMP2.length; currentBytePos += blockSize)
{
- engine.processBlock(TEMP3, currentBytePos, TEMP3, currentBytePos);
+ engine.processBlock(TEMP2, currentBytePos, TEMP2, currentBytePos);
}
- return TEMP3;
+ return TEMP2;
}
/**
@@ -252,15 +252,15 @@
this.engine.init(false, param2);
- byte TEMP3[] = new byte[inLen];
+ byte TEMP2[] = new byte[inLen];
for (int currentBytePos = 0; currentBytePos != inLen; currentBytePos += blockSize)
{
- engine.processBlock(in, inOff + currentBytePos, TEMP3, currentBytePos);
+ engine.processBlock(in, inOff + currentBytePos, TEMP2, currentBytePos);
}
- // Reverse the order of the octets in TEMP3 and call the result TEMP2.
- byte[] TEMP2 = reverse(TEMP3);
+ // Reverse the order of the octets in TEMP2.
+ Arrays.reverseInPlace(TEMP2);
// Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets.
this.iv = new byte[8];
@@ -343,14 +343,4 @@
{
return Arrays.constantTimeAreEqual(calculateCMSKeyChecksum(key), checksum);
}
-
- private static byte[] reverse(byte[] bs)
- {
- byte[] result = new byte[bs.length];
- for (int i = 0; i < bs.length; i++)
- {
- result[i] = bs[bs.length - (i + 1)];
- }
- return result;
- }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RC2Engine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RC2Engine.java
index 05c3d1e..6bf05fa 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RC2Engine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RC2Engine.java
@@ -1,10 +1,8 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.engines;
-import com.android.org.bouncycastle.crypto.BlockCipher;
-import com.android.org.bouncycastle.crypto.CipherParameters;
-import com.android.org.bouncycastle.crypto.DataLengthException;
-import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.crypto.*;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.KeyParameter;
import com.android.org.bouncycastle.crypto.params.RC2Parameters;
@@ -124,17 +122,18 @@
CipherParameters params)
{
this.encrypting = encrypting;
-
+ byte[] key;
if (params instanceof RC2Parameters)
{
RC2Parameters param = (RC2Parameters)params;
workingKey = generateWorkingKey(param.getKey(),
param.getEffectiveKeyBits());
+ key = param.getKey();
}
else if (params instanceof KeyParameter)
{
- byte[] key = ((KeyParameter)params).getKey();
+ key = ((KeyParameter)params).getKey();
workingKey = generateWorkingKey(key, key.length * 8);
}
@@ -143,6 +142,7 @@
throw new IllegalArgumentException("invalid parameter passed to RC2 init - " + params.getClass().getName());
}
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), key.length * 8, params, Utils.getPurpose(encrypting)));
}
public void reset()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RC4Engine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RC4Engine.java
index 2a8b108..989810c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RC4Engine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RC4Engine.java
@@ -2,15 +2,18 @@
package com.android.org.bouncycastle.crypto.engines;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.DataLengthException;
import com.android.org.bouncycastle.crypto.OutputLengthException;
import com.android.org.bouncycastle.crypto.StreamCipher;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.KeyParameter;
/**
* @hide This class is not part of the Android public SDK API
*/
-public class RC4Engine implements StreamCipher
+public class RC4Engine
+ implements StreamCipher
{
private final static int STATE_LENGTH = 256;
@@ -23,6 +26,12 @@
private int x = 0;
private int y = 0;
private byte[] workingKey = null;
+ private boolean forEncryption;
+
+ public RC4Engine()
+ {
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 20));
+ }
/**
* initialise a RC4 cipher.
@@ -34,8 +43,7 @@
*/
public void init(
boolean forEncryption,
- CipherParameters params
- )
+ CipherParameters params)
{
if (params instanceof KeyParameter)
{
@@ -44,9 +52,12 @@
* symmetrical, so the 'forEncryption' is
* irrelevant.
*/
- workingKey = ((KeyParameter)params).getKey();
+ this.workingKey = ((KeyParameter)params).getKey();
+ this.forEncryption = forEncryption;
setKey(workingKey);
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 20, params, Utils.getPurpose(forEncryption)));
+
return;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
index f1f9684..986aef4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
@@ -22,14 +22,15 @@
public class RFC3394WrapEngine
implements Wrapper
{
- private BlockCipher engine;
- private boolean wrapCipherMode;
- private KeyParameter param;
- private boolean forWrapping;
+ private static final byte[] DEFAULT_IV = { (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6,
+ (byte)0xa6, (byte)0xa6 };
- private byte[] iv = {
- (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6,
- (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6 };
+ private final BlockCipher engine;
+ private final boolean wrapCipherMode;
+ private final byte[] iv = new byte[8];
+
+ private KeyParameter param = null;
+ private boolean forWrapping = true;
/**
* Create a RFC 3394 WrapEngine specifying the encrypt for wrapping, decrypt for unwrapping.
@@ -50,7 +51,7 @@
public RFC3394WrapEngine(BlockCipher engine, boolean useReverseDirection)
{
this.engine = engine;
- this.wrapCipherMode = (useReverseDirection) ? false : true;
+ this.wrapCipherMode = !useReverseDirection;
}
public void init(
@@ -67,15 +68,24 @@
if (param instanceof KeyParameter)
{
this.param = (KeyParameter)param;
+ System.arraycopy(DEFAULT_IV, 0, iv, 0, 8);
}
else if (param instanceof ParametersWithIV)
{
- this.iv = ((ParametersWithIV)param).getIV();
- this.param = (KeyParameter)((ParametersWithIV) param).getParameters();
- if (this.iv.length != 8)
+ ParametersWithIV withIV = (ParametersWithIV)param;
+
+ byte[] iv = withIV.getIV();
+ if (iv.length != 8)
{
throw new IllegalArgumentException("IV not equal to 8");
}
+
+ this.param = (KeyParameter)withIV.getParameters();
+ System.arraycopy(iv, 0, this.iv, 0, 8);
+ }
+ else
+ {
+ // TODO Throw an exception for bad parameters?
}
}
@@ -93,6 +103,10 @@
{
throw new IllegalStateException("not set for wrapping");
}
+ if (inLen < 8)
+ {
+ throw new DataLengthException("wrap data must be at least 8 bytes");
+ }
int n = inLen / 8;
@@ -101,34 +115,41 @@
throw new DataLengthException("wrap data must be a multiple of 8 bytes");
}
- byte[] block = new byte[inLen + iv.length];
- byte[] buf = new byte[8 + iv.length];
+ engine.init(wrapCipherMode, param);
+ byte[] block = new byte[inLen + iv.length];
System.arraycopy(iv, 0, block, 0, iv.length);
System.arraycopy(in, inOff, block, iv.length, inLen);
- engine.init(wrapCipherMode, param);
-
- for (int j = 0; j != 6; j++)
+ if (n == 1)
{
- for (int i = 1; i <= n; i++)
+ engine.processBlock(block, 0, block, 0);
+ }
+ else
+ {
+ byte[] buf = new byte[8 + iv.length];
+
+ for (int j = 0; j != 6; j++)
{
- System.arraycopy(block, 0, buf, 0, iv.length);
- System.arraycopy(block, 8 * i, buf, iv.length, 8);
- engine.processBlock(buf, 0, buf, 0);
-
- int t = n * j + i;
- for (int k = 1; t != 0; k++)
+ for (int i = 1; i <= n; i++)
{
- byte v = (byte)t;
+ System.arraycopy(block, 0, buf, 0, iv.length);
+ System.arraycopy(block, 8 * i, buf, iv.length, 8);
+ engine.processBlock(buf, 0, buf, 0);
- buf[iv.length - k] ^= v;
+ int t = n * j + i;
+ for (int k = 1; t != 0; k++)
+ {
+ byte v = (byte)t;
- t >>>= 8;
+ buf[iv.length - k] ^= v;
+
+ t >>>= 8;
+ }
+
+ System.arraycopy(buf, 0, block, 0, 8);
+ System.arraycopy(buf, 8, block, 8 * i, 8);
}
-
- System.arraycopy(buf, 0, block, 0, 8);
- System.arraycopy(buf, 8, block, 8 * i, 8);
}
}
@@ -145,6 +166,10 @@
{
throw new IllegalStateException("not set for unwrapping");
}
+ if (inLen < 16)
+ {
+ throw new InvalidCipherTextException("unwrap data too short");
+ }
int n = inLen / 8;
@@ -153,43 +178,89 @@
throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes");
}
- byte[] block = new byte[inLen - iv.length];
- byte[] a = new byte[iv.length];
- byte[] buf = new byte[8 + iv.length];
-
- System.arraycopy(in, inOff, a, 0, iv.length);
- System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length);
-
engine.init(!wrapCipherMode, param);
+ byte[] block = new byte[inLen - iv.length];
+ byte[] a = new byte[iv.length];
+ byte[] buf = new byte[8 + iv.length];
+
n = n - 1;
- for (int j = 5; j >= 0; j--)
+ if (n == 1)
{
- for (int i = n; i >= 1; i--)
+ engine.processBlock(in, inOff, buf, 0);
+ System.arraycopy(buf, 0, a, 0, iv.length);
+ System.arraycopy(buf, iv.length, block, 0, 8);
+ }
+ else
+ {
+ System.arraycopy(in, inOff, a, 0, iv.length);
+ System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length);
+
+ for (int j = 5; j >= 0; j--)
{
- System.arraycopy(a, 0, buf, 0, iv.length);
- System.arraycopy(block, 8 * (i - 1), buf, iv.length, 8);
-
- int t = n * j + i;
- for (int k = 1; t != 0; k++)
+ for (int i = n; i >= 1; i--)
{
- byte v = (byte)t;
-
- buf[iv.length - k] ^= v;
-
- t >>>= 8;
+ System.arraycopy(a, 0, buf, 0, iv.length);
+ System.arraycopy(block, 8 * (i - 1), buf, iv.length, 8);
+
+ int t = n * j + i;
+ for (int k = 1; t != 0; k++)
+ {
+ byte v = (byte)t;
+
+ buf[iv.length - k] ^= v;
+
+ t >>>= 8;
+ }
+
+ engine.processBlock(buf, 0, buf, 0);
+ System.arraycopy(buf, 0, a, 0, 8);
+ System.arraycopy(buf, 8, block, 8 * (i - 1), 8);
}
-
- engine.processBlock(buf, 0, buf, 0);
- System.arraycopy(buf, 0, a, 0, 8);
- System.arraycopy(buf, 8, block, 8 * (i - 1), 8);
}
}
- if (!Arrays.constantTimeAreEqual(a, iv))
+ if (n != 1)
{
- throw new InvalidCipherTextException("checksum failed");
+ if (!Arrays.constantTimeAreEqual(a, iv))
+ {
+ throw new InvalidCipherTextException("checksum failed");
+ }
+ }
+ else
+ {
+ // TODO: old (incorrect) backwards compatible unwrap - will be removed.
+ if (!Arrays.constantTimeAreEqual(a, iv))
+ {
+ System.arraycopy(in, inOff, a, 0, iv.length);
+ System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length);
+
+ for (int j = 5; j >= 0; j--)
+ {
+ System.arraycopy(a, 0, buf, 0, iv.length);
+ System.arraycopy(block, 0, buf, iv.length, 8);
+
+ int t = n * j + 1;
+ for (int k = 1; t != 0; k++)
+ {
+ byte v = (byte)t;
+
+ buf[iv.length - k] ^= v;
+
+ t >>>= 8;
+ }
+
+ engine.processBlock(buf, 0, buf, 0);
+ System.arraycopy(buf, 0, a, 0, 8);
+ System.arraycopy(buf, 8, block, 0, 8);
+ }
+
+ if (!Arrays.constantTimeAreEqual(a, iv))
+ {
+ throw new InvalidCipherTextException("checksum failed");
+ }
+ }
}
return block;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSABlindedEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSABlindedEngine.java
index 2ff1b4f..4db17e9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSABlindedEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSABlindedEngine.java
@@ -112,39 +112,31 @@
}
BigInteger input = core.convertInput(in, inOff, inLen);
+ BigInteger result = processInput(input);
+ return core.convertOutput(result);
+ }
- BigInteger result;
+ private BigInteger processInput(BigInteger input)
+ {
if (key instanceof RSAPrivateCrtKeyParameters)
{
- RSAPrivateCrtKeyParameters k = (RSAPrivateCrtKeyParameters)key;
+ RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)key;
- BigInteger e = k.getPublicExponent();
+ BigInteger e = crtKey.getPublicExponent();
if (e != null) // can't do blinding without a public exponent
{
- BigInteger m = k.getModulus();
+ BigInteger m = crtKey.getModulus();
+
BigInteger r = BigIntegers.createRandomInRange(ONE, m.subtract(ONE), random);
+ BigInteger blind = r.modPow(e, m);
+ BigInteger unblind = BigIntegers.modOddInverse(m, r);
- BigInteger blindedInput = r.modPow(e, m).multiply(input).mod(m);
+ BigInteger blindedInput = blind.multiply(input).mod(m);
BigInteger blindedResult = core.processBlock(blindedInput);
-
- BigInteger rInv = BigIntegers.modOddInverse(m, r);
- result = blindedResult.multiply(rInv).mod(m);
- // defence against Arjen Lenstra’s CRT attack
- if (!input.equals(result.modPow(e, m)))
- {
- throw new IllegalStateException("RSA engine faulty decryption/signing detected");
- }
- }
- else
- {
- result = core.processBlock(input);
+ return unblind.multiply(blindedResult).mod(m);
}
}
- else
- {
- result = core.processBlock(input);
- }
- return core.convertOutput(result);
+ return core.processBlock(input);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSACoreEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSACoreEngine.java
index 66ae3b7..7820551 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSACoreEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSACoreEngine.java
@@ -4,7 +4,11 @@
import java.math.BigInteger;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.ParametersWithRandom;
import com.android.org.bouncycastle.crypto.params.RSAKeyParameters;
import com.android.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
@@ -16,21 +20,21 @@
class RSACoreEngine
{
private RSAKeyParameters key;
- private boolean forEncryption;
+ private boolean forEncryption;
/**
* initialise the RSA engine.
*
* @param forEncryption true if we are encrypting, false otherwise.
- * @param param the necessary RSA key parameters.
+ * @param param the necessary RSA key parameters.
*/
public void init(
- boolean forEncryption,
+ boolean forEncryption,
CipherParameters param)
{
if (param instanceof ParametersWithRandom)
{
- ParametersWithRandom rParam = (ParametersWithRandom)param;
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
key = (RSAKeyParameters)rParam.getParameters();
}
@@ -40,6 +44,8 @@
}
this.forEncryption = forEncryption;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("RSA", ConstraintUtils.bitsOfSecurityFor(key.getModulus()), key, getPurpose(key.isPrivate(), forEncryption)));
}
/**
@@ -51,7 +57,7 @@
*/
public int getInputBlockSize()
{
- int bitSize = key.getModulus().bitLength();
+ int bitSize = key.getModulus().bitLength();
if (forEncryption)
{
@@ -72,7 +78,7 @@
*/
public int getOutputBlockSize()
{
- int bitSize = key.getModulus().bitLength();
+ int bitSize = key.getModulus().bitLength();
if (forEncryption)
{
@@ -85,9 +91,9 @@
}
public BigInteger convertInput(
- byte[] in,
- int inOff,
- int inLen)
+ byte[] in,
+ int inOff,
+ int inLen)
{
if (inLen > (getInputBlockSize() + 1))
{
@@ -98,7 +104,7 @@
throw new DataLengthException("input too large for RSA cipher.");
}
- byte[] block;
+ byte[] block;
if (inOff != 0 || inLen != in.length)
{
@@ -123,13 +129,13 @@
public byte[] convertOutput(
BigInteger result)
{
- byte[] output = result.toByteArray();
+ byte[] output = result.toByteArray();
if (forEncryption)
{
if (output[0] == 0 && output.length > getOutputBlockSize()) // have ended up with an extra zero byte, copy down.
{
- byte[] tmp = new byte[output.length - 1];
+ byte[] tmp = new byte[output.length - 1];
System.arraycopy(output, 1, tmp, 0, tmp.length);
@@ -138,7 +144,7 @@
if (output.length < getOutputBlockSize()) // have ended up with less bytes than normal, lengthen
{
- byte[] tmp = new byte[getOutputBlockSize()];
+ byte[] tmp = new byte[getOutputBlockSize()];
System.arraycopy(output, 0, tmp, tmp.length - output.length, output.length);
@@ -149,7 +155,7 @@
}
else
{
- byte[] rv;
+ byte[] rv;
if (output[0] == 0) // have ended up with an extra zero byte, copy down.
{
rv = new byte[output.length - 1];
@@ -180,35 +186,64 @@
//
RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)key;
- BigInteger p = crtKey.getP();
- BigInteger q = crtKey.getQ();
- BigInteger dP = crtKey.getDP();
- BigInteger dQ = crtKey.getDQ();
- BigInteger qInv = crtKey.getQInv();
+ BigInteger e = crtKey.getPublicExponent();
+ if (e != null) // can't apply fault-attack countermeasure without public exponent
+ {
+ BigInteger p = crtKey.getP();
+ BigInteger q = crtKey.getQ();
+ BigInteger dP = crtKey.getDP();
+ BigInteger dQ = crtKey.getDQ();
+ BigInteger qInv = crtKey.getQInv();
- BigInteger mP, mQ, h, m;
+ BigInteger mP, mQ, h, m;
- // mP = ((input mod p) ^ dP)) mod p
- mP = (input.remainder(p)).modPow(dP, p);
+ // mP = ((input mod p) ^ dP)) mod p
+ mP = (input.remainder(p)).modPow(dP, p);
- // mQ = ((input mod q) ^ dQ)) mod q
- mQ = (input.remainder(q)).modPow(dQ, q);
+ // mQ = ((input mod q) ^ dQ)) mod q
+ mQ = (input.remainder(q)).modPow(dQ, q);
- // h = qInv * (mP - mQ) mod p
- h = mP.subtract(mQ);
- h = h.multiply(qInv);
- h = h.mod(p); // mod (in Java) returns the positive residual
+ // h = qInv * (mP - mQ) mod p
+ h = mP.subtract(mQ);
+ h = h.multiply(qInv);
+ h = h.mod(p); // mod (in Java) returns the positive residual
- // m = h * q + mQ
- m = h.multiply(q);
- m = m.add(mQ);
+ // m = h * q + mQ
+ m = h.multiply(q).add(mQ);
- return m;
+ // defence against Arjen Lenstra’s CRT attack
+ BigInteger check = m.modPow(e, crtKey.getModulus());
+ if (!check.equals(input))
+ {
+ throw new IllegalStateException("RSA engine faulty decryption/signing detected");
+ }
+
+ return m;
+ }
}
- else
+
+ return input.modPow(key.getExponent(), key.getModulus());
+ }
+
+ private CryptoServicePurpose getPurpose(boolean isPrivate, boolean forEncryption)
+ {
+ boolean isSigning = isPrivate && forEncryption;
+ boolean isEncryption = !isPrivate && forEncryption;
+ boolean isVerifying = !isPrivate && !forEncryption;
+
+ if (isSigning)
{
- return input.modPow(
- key.getExponent(), key.getModulus());
+ return CryptoServicePurpose.SIGNING;
}
+ if (isEncryption)
+ {
+ return CryptoServicePurpose.ENCRYPTION;
+ }
+ if (isVerifying)
+ {
+ return CryptoServicePurpose.VERIFYING;
+ }
+
+ return CryptoServicePurpose.DECRYPTION;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/TwofishEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/TwofishEngine.java
index ef52518..32186fd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/TwofishEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/TwofishEngine.java
@@ -3,9 +3,13 @@
import com.android.org.bouncycastle.crypto.BlockCipher;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.DataLengthException;
import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.org.bouncycastle.util.Integers;
+import com.android.org.bouncycastle.util.Pack;
/**
* A class that provides Twofish encryption operations.
@@ -226,6 +230,8 @@
public TwofishEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 256));
+
// calculate the MDS matrix
int[] m1 = new int[2];
int[] mX = new int[2];
@@ -274,7 +280,21 @@
{
this.encrypting = encrypting;
this.workingKey = ((KeyParameter)params).getKey();
- this.k64Cnt = (this.workingKey.length / 8); // pre-padded ?
+
+ int keyBits = this.workingKey.length * 8;
+ switch (keyBits)
+ {
+ case 128:
+ case 192:
+ case 256:
+ break;
+ default:
+ throw new IllegalArgumentException("Key length not 128/192/256 bits.");
+ }
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), keyBits, params, Utils.getPurpose(encrypting)));
+
+ this.k64Cnt = this.workingKey.length / 8;
setKey(this.workingKey);
return;
@@ -346,28 +366,16 @@
int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4
gSubKeys = new int[TOTAL_SUBKEYS];
- if (k64Cnt < 1)
- {
- throw new IllegalArgumentException("Key size less than 64 bits");
- }
-
- if (k64Cnt > 4)
- {
- throw new IllegalArgumentException("Key size larger than 256 bits");
- }
-
/*
- * k64Cnt is the number of 8 byte blocks (64 chunks)
- * that are in the input key. The input key is a
- * maximum of 32 bytes (256 bits), so the range
- * for k64Cnt is 1..4
+ * k64Cnt is the number of 8 byte blocks (64 chunks) that are in the input key.
+ * The input key is 16, 24 or 32 bytes, so the range for k64Cnt is 2..4
*/
for (int i=0; i<k64Cnt ; i++)
{
int p = i* 8;
- k32e[i] = BytesTo32Bits(key, p);
- k32o[i] = BytesTo32Bits(key, p+4);
+ k32e[i] = Pack.littleEndianToInt(key, p);
+ k32o[i] = Pack.littleEndianToInt(key, p + 4);
sBoxKeys[k64Cnt-1-i] = RS_MDS_Encode(k32e[i], k32o[i]);
}
@@ -378,7 +386,7 @@
q = i*SK_STEP;
A = F32(q, k32e);
B = F32(q+SK_BUMP, k32o);
- B = B << 8 | B >>> 24;
+ B = Integers.rotateLeft(B, 8);
A += B;
gSubKeys[i*2] = A;
A += B;
@@ -450,10 +458,10 @@
byte[] dst,
int dstIndex)
{
- int x0 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[INPUT_WHITEN];
- int x1 = BytesTo32Bits(src, srcIndex + 4) ^ gSubKeys[INPUT_WHITEN + 1];
- int x2 = BytesTo32Bits(src, srcIndex + 8) ^ gSubKeys[INPUT_WHITEN + 2];
- int x3 = BytesTo32Bits(src, srcIndex + 12) ^ gSubKeys[INPUT_WHITEN + 3];
+ int x0 = Pack.littleEndianToInt(src, srcIndex) ^ gSubKeys[INPUT_WHITEN];
+ int x1 = Pack.littleEndianToInt(src, srcIndex + 4) ^ gSubKeys[INPUT_WHITEN + 1];
+ int x2 = Pack.littleEndianToInt(src, srcIndex + 8) ^ gSubKeys[INPUT_WHITEN + 2];
+ int x3 = Pack.littleEndianToInt(src, srcIndex + 12) ^ gSubKeys[INPUT_WHITEN + 3];
int k = ROUND_SUBKEYS;
int t0, t1;
@@ -462,20 +470,20 @@
t0 = Fe32_0(x0);
t1 = Fe32_3(x1);
x2 ^= t0 + t1 + gSubKeys[k++];
- x2 = x2 >>>1 | x2 << 31;
- x3 = (x3 << 1 | x3 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
+ x2 = Integers.rotateRight(x2, 1);
+ x3 = Integers.rotateLeft(x3, 1) ^ (t0 + 2*t1 + gSubKeys[k++]);
t0 = Fe32_0(x2);
t1 = Fe32_3(x3);
x0 ^= t0 + t1 + gSubKeys[k++];
- x0 = x0 >>>1 | x0 << 31;
- x1 = (x1 << 1 | x1 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
+ x0 = Integers.rotateRight(x0, 1);
+ x1 = Integers.rotateLeft(x1, 1) ^ (t0 + 2*t1 + gSubKeys[k++]);
}
- Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex);
- Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4);
- Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8);
- Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12);
+ Pack.intToLittleEndian(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex);
+ Pack.intToLittleEndian(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4);
+ Pack.intToLittleEndian(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8);
+ Pack.intToLittleEndian(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12);
}
/**
@@ -489,10 +497,10 @@
byte[] dst,
int dstIndex)
{
- int x2 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN];
- int x3 = BytesTo32Bits(src, srcIndex+4) ^ gSubKeys[OUTPUT_WHITEN + 1];
- int x0 = BytesTo32Bits(src, srcIndex+8) ^ gSubKeys[OUTPUT_WHITEN + 2];
- int x1 = BytesTo32Bits(src, srcIndex+12) ^ gSubKeys[OUTPUT_WHITEN + 3];
+ int x2 = Pack.littleEndianToInt(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN];
+ int x3 = Pack.littleEndianToInt(src, srcIndex + 4) ^ gSubKeys[OUTPUT_WHITEN + 1];
+ int x0 = Pack.littleEndianToInt(src, srcIndex + 8) ^ gSubKeys[OUTPUT_WHITEN + 2];
+ int x1 = Pack.littleEndianToInt(src, srcIndex + 12) ^ gSubKeys[OUTPUT_WHITEN + 3];
int k = ROUND_SUBKEYS + 2 * ROUNDS -1 ;
int t0, t1;
@@ -501,20 +509,20 @@
t0 = Fe32_0(x2);
t1 = Fe32_3(x3);
x1 ^= t0 + 2*t1 + gSubKeys[k--];
- x0 = (x0 << 1 | x0 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
- x1 = x1 >>>1 | x1 << 31;
+ x0 = Integers.rotateLeft(x0, 1) ^ (t0 + t1 + gSubKeys[k--]);
+ x1 = Integers.rotateRight(x1, 1);
t0 = Fe32_0(x0);
t1 = Fe32_3(x1);
x3 ^= t0 + 2*t1 + gSubKeys[k--];
- x2 = (x2 << 1 | x2 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
- x3 = x3 >>>1 | x3 << 31;
+ x2 = Integers.rotateLeft(x2, 1) ^ (t0 + t1 + gSubKeys[k--]);
+ x3 = Integers.rotateRight(x3, 1);
}
- Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex);
- Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4);
- Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8);
- Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12);
+ Pack.intToLittleEndian(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex);
+ Pack.intToLittleEndian(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4);
+ Pack.intToLittleEndian(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8);
+ Pack.intToLittleEndian(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12);
}
/*
@@ -663,20 +671,4 @@
gSBox[ 0x200 + 2*((x >>> 8) & 0xff) ] ^
gSBox[ 0x201 + 2*((x >>> 16) & 0xff) ];
}
-
- private int BytesTo32Bits(byte[] b, int p)
- {
- return ((b[p] & 0xff)) |
- ((b[p+1] & 0xff) << 8) |
- ((b[p+2] & 0xff) << 16) |
- ((b[p+3] & 0xff) << 24);
- }
-
- private void Bits32ToBytes(int in, byte[] b, int offset)
- {
- b[offset] = (byte)in;
- b[offset + 1] = (byte)(in >> 8);
- b[offset + 2] = (byte)(in >> 16);
- b[offset + 3] = (byte)(in >> 24);
- }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Utils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Utils.java
new file mode 100644
index 0000000..4c563f1
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Utils.java
@@ -0,0 +1,12 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.engines;
+
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+
+class Utils
+{
+ static CryptoServicePurpose getPurpose(boolean forEncryption)
+ {
+ return forEncryption ? CryptoServicePurpose.ENCRYPTION : CryptoServicePurpose.DECRYPTION;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Zuc128CoreEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Zuc128CoreEngine.java
new file mode 100644
index 0000000..b408995
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Zuc128CoreEngine.java
@@ -0,0 +1,577 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.engines;
+
+import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.crypto.StreamCipher;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import com.android.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.org.bouncycastle.util.Memoable;
+
+/**
+ * Zuc128Engine implementation.
+ * Based on https://www.gsma.com/aboutus/wp-content/uploads/2014/12/eea3eia3zucv16.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Zuc128CoreEngine
+ implements StreamCipher, Memoable
+{
+ /* the s-boxes */
+ private static final byte[] S0 = new byte[]{
+ (byte)0x3e, (byte)0x72, (byte)0x5b, (byte)0x47, (byte)0xca, (byte)0xe0, (byte)0x00, (byte)0x33, (byte)0x04, (byte)0xd1, (byte)0x54, (byte)0x98, (byte)0x09, (byte)0xb9, (byte)0x6d, (byte)0xcb,
+ (byte)0x7b, (byte)0x1b, (byte)0xf9, (byte)0x32, (byte)0xaf, (byte)0x9d, (byte)0x6a, (byte)0xa5, (byte)0xb8, (byte)0x2d, (byte)0xfc, (byte)0x1d, (byte)0x08, (byte)0x53, (byte)0x03, (byte)0x90,
+ (byte)0x4d, (byte)0x4e, (byte)0x84, (byte)0x99, (byte)0xe4, (byte)0xce, (byte)0xd9, (byte)0x91, (byte)0xdd, (byte)0xb6, (byte)0x85, (byte)0x48, (byte)0x8b, (byte)0x29, (byte)0x6e, (byte)0xac,
+ (byte)0xcd, (byte)0xc1, (byte)0xf8, (byte)0x1e, (byte)0x73, (byte)0x43, (byte)0x69, (byte)0xc6, (byte)0xb5, (byte)0xbd, (byte)0xfd, (byte)0x39, (byte)0x63, (byte)0x20, (byte)0xd4, (byte)0x38,
+ (byte)0x76, (byte)0x7d, (byte)0xb2, (byte)0xa7, (byte)0xcf, (byte)0xed, (byte)0x57, (byte)0xc5, (byte)0xf3, (byte)0x2c, (byte)0xbb, (byte)0x14, (byte)0x21, (byte)0x06, (byte)0x55, (byte)0x9b,
+ (byte)0xe3, (byte)0xef, (byte)0x5e, (byte)0x31, (byte)0x4f, (byte)0x7f, (byte)0x5a, (byte)0xa4, (byte)0x0d, (byte)0x82, (byte)0x51, (byte)0x49, (byte)0x5f, (byte)0xba, (byte)0x58, (byte)0x1c,
+ (byte)0x4a, (byte)0x16, (byte)0xd5, (byte)0x17, (byte)0xa8, (byte)0x92, (byte)0x24, (byte)0x1f, (byte)0x8c, (byte)0xff, (byte)0xd8, (byte)0xae, (byte)0x2e, (byte)0x01, (byte)0xd3, (byte)0xad,
+ (byte)0x3b, (byte)0x4b, (byte)0xda, (byte)0x46, (byte)0xeb, (byte)0xc9, (byte)0xde, (byte)0x9a, (byte)0x8f, (byte)0x87, (byte)0xd7, (byte)0x3a, (byte)0x80, (byte)0x6f, (byte)0x2f, (byte)0xc8,
+ (byte)0xb1, (byte)0xb4, (byte)0x37, (byte)0xf7, (byte)0x0a, (byte)0x22, (byte)0x13, (byte)0x28, (byte)0x7c, (byte)0xcc, (byte)0x3c, (byte)0x89, (byte)0xc7, (byte)0xc3, (byte)0x96, (byte)0x56,
+ (byte)0x07, (byte)0xbf, (byte)0x7e, (byte)0xf0, (byte)0x0b, (byte)0x2b, (byte)0x97, (byte)0x52, (byte)0x35, (byte)0x41, (byte)0x79, (byte)0x61, (byte)0xa6, (byte)0x4c, (byte)0x10, (byte)0xfe,
+ (byte)0xbc, (byte)0x26, (byte)0x95, (byte)0x88, (byte)0x8a, (byte)0xb0, (byte)0xa3, (byte)0xfb, (byte)0xc0, (byte)0x18, (byte)0x94, (byte)0xf2, (byte)0xe1, (byte)0xe5, (byte)0xe9, (byte)0x5d,
+ (byte)0xd0, (byte)0xdc, (byte)0x11, (byte)0x66, (byte)0x64, (byte)0x5c, (byte)0xec, (byte)0x59, (byte)0x42, (byte)0x75, (byte)0x12, (byte)0xf5, (byte)0x74, (byte)0x9c, (byte)0xaa, (byte)0x23,
+ (byte)0x0e, (byte)0x86, (byte)0xab, (byte)0xbe, (byte)0x2a, (byte)0x02, (byte)0xe7, (byte)0x67, (byte)0xe6, (byte)0x44, (byte)0xa2, (byte)0x6c, (byte)0xc2, (byte)0x93, (byte)0x9f, (byte)0xf1,
+ (byte)0xf6, (byte)0xfa, (byte)0x36, (byte)0xd2, (byte)0x50, (byte)0x68, (byte)0x9e, (byte)0x62, (byte)0x71, (byte)0x15, (byte)0x3d, (byte)0xd6, (byte)0x40, (byte)0xc4, (byte)0xe2, (byte)0x0f,
+ (byte)0x8e, (byte)0x83, (byte)0x77, (byte)0x6b, (byte)0x25, (byte)0x05, (byte)0x3f, (byte)0x0c, (byte)0x30, (byte)0xea, (byte)0x70, (byte)0xb7, (byte)0xa1, (byte)0xe8, (byte)0xa9, (byte)0x65,
+ (byte)0x8d, (byte)0x27, (byte)0x1a, (byte)0xdb, (byte)0x81, (byte)0xb3, (byte)0xa0, (byte)0xf4, (byte)0x45, (byte)0x7a, (byte)0x19, (byte)0xdf, (byte)0xee, (byte)0x78, (byte)0x34, (byte)0x60
+ };
+
+ private static final byte[] S1 = new byte[]{
+ (byte)0x55, (byte)0xc2, (byte)0x63, (byte)0x71, (byte)0x3b, (byte)0xc8, (byte)0x47, (byte)0x86, (byte)0x9f, (byte)0x3c, (byte)0xda, (byte)0x5b, (byte)0x29, (byte)0xaa, (byte)0xfd, (byte)0x77,
+ (byte)0x8c, (byte)0xc5, (byte)0x94, (byte)0x0c, (byte)0xa6, (byte)0x1a, (byte)0x13, (byte)0x00, (byte)0xe3, (byte)0xa8, (byte)0x16, (byte)0x72, (byte)0x40, (byte)0xf9, (byte)0xf8, (byte)0x42,
+ (byte)0x44, (byte)0x26, (byte)0x68, (byte)0x96, (byte)0x81, (byte)0xd9, (byte)0x45, (byte)0x3e, (byte)0x10, (byte)0x76, (byte)0xc6, (byte)0xa7, (byte)0x8b, (byte)0x39, (byte)0x43, (byte)0xe1,
+ (byte)0x3a, (byte)0xb5, (byte)0x56, (byte)0x2a, (byte)0xc0, (byte)0x6d, (byte)0xb3, (byte)0x05, (byte)0x22, (byte)0x66, (byte)0xbf, (byte)0xdc, (byte)0x0b, (byte)0xfa, (byte)0x62, (byte)0x48,
+ (byte)0xdd, (byte)0x20, (byte)0x11, (byte)0x06, (byte)0x36, (byte)0xc9, (byte)0xc1, (byte)0xcf, (byte)0xf6, (byte)0x27, (byte)0x52, (byte)0xbb, (byte)0x69, (byte)0xf5, (byte)0xd4, (byte)0x87,
+ (byte)0x7f, (byte)0x84, (byte)0x4c, (byte)0xd2, (byte)0x9c, (byte)0x57, (byte)0xa4, (byte)0xbc, (byte)0x4f, (byte)0x9a, (byte)0xdf, (byte)0xfe, (byte)0xd6, (byte)0x8d, (byte)0x7a, (byte)0xeb,
+ (byte)0x2b, (byte)0x53, (byte)0xd8, (byte)0x5c, (byte)0xa1, (byte)0x14, (byte)0x17, (byte)0xfb, (byte)0x23, (byte)0xd5, (byte)0x7d, (byte)0x30, (byte)0x67, (byte)0x73, (byte)0x08, (byte)0x09,
+ (byte)0xee, (byte)0xb7, (byte)0x70, (byte)0x3f, (byte)0x61, (byte)0xb2, (byte)0x19, (byte)0x8e, (byte)0x4e, (byte)0xe5, (byte)0x4b, (byte)0x93, (byte)0x8f, (byte)0x5d, (byte)0xdb, (byte)0xa9,
+ (byte)0xad, (byte)0xf1, (byte)0xae, (byte)0x2e, (byte)0xcb, (byte)0x0d, (byte)0xfc, (byte)0xf4, (byte)0x2d, (byte)0x46, (byte)0x6e, (byte)0x1d, (byte)0x97, (byte)0xe8, (byte)0xd1, (byte)0xe9,
+ (byte)0x4d, (byte)0x37, (byte)0xa5, (byte)0x75, (byte)0x5e, (byte)0x83, (byte)0x9e, (byte)0xab, (byte)0x82, (byte)0x9d, (byte)0xb9, (byte)0x1c, (byte)0xe0, (byte)0xcd, (byte)0x49, (byte)0x89,
+ (byte)0x01, (byte)0xb6, (byte)0xbd, (byte)0x58, (byte)0x24, (byte)0xa2, (byte)0x5f, (byte)0x38, (byte)0x78, (byte)0x99, (byte)0x15, (byte)0x90, (byte)0x50, (byte)0xb8, (byte)0x95, (byte)0xe4,
+ (byte)0xd0, (byte)0x91, (byte)0xc7, (byte)0xce, (byte)0xed, (byte)0x0f, (byte)0xb4, (byte)0x6f, (byte)0xa0, (byte)0xcc, (byte)0xf0, (byte)0x02, (byte)0x4a, (byte)0x79, (byte)0xc3, (byte)0xde,
+ (byte)0xa3, (byte)0xef, (byte)0xea, (byte)0x51, (byte)0xe6, (byte)0x6b, (byte)0x18, (byte)0xec, (byte)0x1b, (byte)0x2c, (byte)0x80, (byte)0xf7, (byte)0x74, (byte)0xe7, (byte)0xff, (byte)0x21,
+ (byte)0x5a, (byte)0x6a, (byte)0x54, (byte)0x1e, (byte)0x41, (byte)0x31, (byte)0x92, (byte)0x35, (byte)0xc4, (byte)0x33, (byte)0x07, (byte)0x0a, (byte)0xba, (byte)0x7e, (byte)0x0e, (byte)0x34,
+ (byte)0x88, (byte)0xb1, (byte)0x98, (byte)0x7c, (byte)0xf3, (byte)0x3d, (byte)0x60, (byte)0x6c, (byte)0x7b, (byte)0xca, (byte)0xd3, (byte)0x1f, (byte)0x32, (byte)0x65, (byte)0x04, (byte)0x28,
+ (byte)0x64, (byte)0xbe, (byte)0x85, (byte)0x9b, (byte)0x2f, (byte)0x59, (byte)0x8a, (byte)0xd7, (byte)0xb0, (byte)0x25, (byte)0xac, (byte)0xaf, (byte)0x12, (byte)0x03, (byte)0xe2, (byte)0xf2
+ };
+
+ /* the constants D */
+ private static final short[] EK_d = new short[]{
+ 0x44D7, 0x26BC, 0x626B, 0x135E, 0x5789, 0x35E2, 0x7135, 0x09AF,
+ 0x4D78, 0x2F13, 0x6BC4, 0x1AF1, 0x5E26, 0x3C4D, 0x789A, 0x47AC
+ };
+
+ /**
+ * State.
+ */
+ private final int[] LFSR = new int[16];
+ private final int[] F = new int[2];
+ private final int[] BRC = new int[4];
+
+ /**
+ * index of next byte in keyStream.
+ */
+ private int theIndex;
+
+ /**
+ * Advanced stream.
+ */
+ private final byte[] keyStream = new byte[4]; // Integer.BYTES
+
+ /**
+ * The iterations.
+ */
+ private int theIterations;
+
+ /**
+ * Reset state.
+ */
+ private Zuc128CoreEngine theResetState;
+
+ /**
+ * Constructor.
+ */
+ protected Zuc128CoreEngine()
+ {
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param pSource the source engine
+ */
+ protected Zuc128CoreEngine(final Zuc128CoreEngine pSource)
+ {
+ reset(pSource);
+ }
+
+ /**
+ * initialise a Snow3G cipher.
+ *
+ * @param forEncryption whether or not we are for encryption.
+ * @param params the parameters required to set up the cipher.
+ * @throws IllegalArgumentException if the params argument is inappropriate.
+ */
+ public void init(final boolean forEncryption,
+ final CipherParameters params)
+ {
+ /*
+ * encryption and decryption is completely symmetrical.
+ */
+
+ /* Determine parameters */
+ CipherParameters myParams = params;
+ byte[] newKey = null;
+ byte[] newIV = null;
+ if ((myParams instanceof ParametersWithIV))
+ {
+ final ParametersWithIV ivParams = (ParametersWithIV)myParams;
+ newIV = ivParams.getIV();
+ myParams = ivParams.getParameters();
+ }
+ if (myParams instanceof KeyParameter)
+ {
+ final KeyParameter keyParam = (KeyParameter)myParams;
+ newKey = keyParam.getKey();
+ }
+
+ /* Initialise engine and mark as initialised */
+ theIndex = 0;
+ theIterations = 0;
+ setKeyAndIV(newKey, newIV);
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), newKey.length * 8,
+ params, forEncryption ? CryptoServicePurpose.ENCRYPTION : CryptoServicePurpose.DECRYPTION));
+
+ /* Save reset state */
+ theResetState = (Zuc128CoreEngine)copy();
+ }
+
+ /**
+ * Obtain Max iterations.
+ *
+ * @return the maximum iterations
+ */
+ protected int getMaxIterations()
+ {
+ return 2047;
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc-128";
+ }
+
+ /**
+ * Process bytes.
+ *
+ * @param in the input buffer
+ * @param inOff the starting offset in the input buffer
+ * @param len the length of data in the input buffer
+ * @param out the output buffer
+ * @param outOff the starting offset in the output buffer
+ * @return the number of bytes returned in the output buffer
+ */
+ public int processBytes(final byte[] in,
+ final int inOff,
+ final int len,
+ final byte[] out,
+ final int outOff)
+ {
+ /* Check for errors */
+ if (theResetState == null)
+ {
+ throw new IllegalStateException(getAlgorithmName() + " not initialised");
+ }
+ if ((inOff + len) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ if ((outOff + len) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ /* Loop through the input bytes */
+ for (int i = 0; i < len; i++)
+ {
+ out[i + outOff] = returnByte(in[i + inOff]);
+ }
+ return len;
+ }
+
+ /**
+ * Reset the engine.
+ */
+ public void reset()
+ {
+ if (theResetState != null)
+ {
+ reset(theResetState);
+ }
+ }
+
+ /**
+ * Process single byte.
+ *
+ * @param in the input byte
+ * @return the output byte
+ */
+ public byte returnByte(final byte in)
+ {
+ /* Make the keyStream if required */
+ if (theIndex == 0)
+ {
+ makeKeyStream();
+ }
+
+ /* Map the next byte and adjust index */
+ final byte out = (byte)(keyStream[theIndex] ^ in);
+ theIndex = (theIndex + 1) % 4; // Integer.BYTES
+
+ /* Return the mapped character */
+ return out;
+ }
+
+ /**
+ * Encode a 32-bit value into a buffer (little-endian).
+ *
+ * @param val the value to encode
+ * @param buf the output buffer
+ * @param off the output offset
+ */
+ public static void encode32be(int val, byte[] buf, int off)
+ {
+ buf[off] = (byte)(val >> 24);
+ buf[off + 1] = (byte)(val >> 16);
+ buf[off + 2] = (byte)(val >> 8);
+ buf[off + 3] = (byte)val;
+ }
+
+ /* ����������������������- */
+
+ /**
+ * Modular add c = a + b mod (2^31 � 1).
+ *
+ * @param a value A
+ * @param b value B
+ * @return the result
+ */
+ private int AddM(final int a, final int b)
+ {
+ final int c = a + b;
+ return (c & 0x7FFFFFFF) + (c >>> 31);
+ }
+
+ /**
+ * Multiply by power of two.
+ *
+ * @param x input value
+ * @param k the power of two
+ * @return the result
+ */
+ private static int MulByPow2(final int x, final int k)
+ {
+ return ((((x) << k) | ((x) >>> (31 - k))) & 0x7FFFFFFF);
+ }
+
+ /**
+ * LFSR with initialisation mode.
+ *
+ * @param u
+ */
+ private void LFSRWithInitialisationMode(final int u)
+ {
+ int f = LFSR[0];
+ int v = MulByPow2(LFSR[0], 8);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[4], 20);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[10], 21);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[13], 17);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[15], 15);
+ f = AddM(f, v);
+ f = AddM(f, u);
+
+ /* update the state */
+ LFSR[0] = LFSR[1];
+ LFSR[1] = LFSR[2];
+ LFSR[2] = LFSR[3];
+ LFSR[3] = LFSR[4];
+ LFSR[4] = LFSR[5];
+ LFSR[5] = LFSR[6];
+ LFSR[6] = LFSR[7];
+ LFSR[7] = LFSR[8];
+ LFSR[8] = LFSR[9];
+ LFSR[9] = LFSR[10];
+ LFSR[10] = LFSR[11];
+ LFSR[11] = LFSR[12];
+ LFSR[12] = LFSR[13];
+ LFSR[13] = LFSR[14];
+ LFSR[14] = LFSR[15];
+ LFSR[15] = f;
+ }
+
+ /**
+ * LFSR with work mode.
+ */
+ private void LFSRWithWorkMode()
+ {
+ int f, v;
+ f = LFSR[0];
+ v = MulByPow2(LFSR[0], 8);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[4], 20);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[10], 21);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[13], 17);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[15], 15);
+ f = AddM(f, v);
+
+ /* update the state */
+ LFSR[0] = LFSR[1];
+ LFSR[1] = LFSR[2];
+ LFSR[2] = LFSR[3];
+ LFSR[3] = LFSR[4];
+ LFSR[4] = LFSR[5];
+ LFSR[5] = LFSR[6];
+ LFSR[6] = LFSR[7];
+ LFSR[7] = LFSR[8];
+ LFSR[8] = LFSR[9];
+ LFSR[9] = LFSR[10];
+ LFSR[10] = LFSR[11];
+ LFSR[11] = LFSR[12];
+ LFSR[12] = LFSR[13];
+ LFSR[13] = LFSR[14];
+ LFSR[14] = LFSR[15];
+ LFSR[15] = f;
+ }
+
+ /**
+ * BitReorganization.
+ */
+ private void BitReorganization()
+ {
+ BRC[0] = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
+ BRC[1] = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
+ BRC[2] = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
+ BRC[3] = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >>> 15);
+ }
+
+ /**
+ * Rotate integer.
+ *
+ * @param a the integer
+ * @param k the shift
+ * @return the result
+ */
+ static int ROT(int a, int k)
+ {
+ return (((a) << k) | ((a) >>> (32 - k)));
+ }
+
+ /**
+ * L1.
+ *
+ * @param X the input integer.
+ * @return the result
+ */
+ private static int L1(final int X)
+ {
+ return (X ^ ROT(X, 2) ^ ROT(X, 10) ^ ROT(X, 18) ^ ROT(X, 24));
+ }
+
+ /**
+ * L2.
+ *
+ * @param X the input integer.
+ * @return the result
+ */
+ private static int L2(final int X)
+ {
+ return (X ^ ROT(X, 8) ^ ROT(X, 14) ^ ROT(X, 22) ^ ROT(X, 30));
+ }
+
+ /**
+ * Build a 32-bit integer from constituent parts.
+ *
+ * @param a part A
+ * @param b part B
+ * @param c part C
+ * @param d part D
+ * @return the built integer
+ */
+ private static int MAKEU32(final byte a,
+ final byte b,
+ final byte c,
+ final byte d)
+ {
+ return (((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF)));
+ }
+
+ /**
+ * F.
+ */
+ int F()
+ {
+ int W, W1, W2, u, v;
+ W = (BRC[0] ^ F[0]) + F[1];
+ W1 = F[0] + BRC[1];
+ W2 = F[1] ^ BRC[2];
+ u = L1((W1 << 16) | (W2 >>> 16));
+ v = L2((W2 << 16) | (W1 >>> 16));
+ F[0] = MAKEU32(S0[u >>> 24], S1[(u >>> 16) & 0xFF],
+ S0[(u >>> 8) & 0xFF], S1[u & 0xFF]);
+ F[1] = MAKEU32(S0[v >>> 24], S1[(v >>> 16) & 0xFF],
+ S0[(v >>> 8) & 0xFF], S1[v & 0xFF]);
+ return W;
+ }
+
+ /**
+ * Build a 31-bit integer from constituent parts.
+ *
+ * @param a part A
+ * @param b part B
+ * @param c part C
+ * @return the built integer
+ */
+ private static int MAKEU31(final byte a,
+ final short b,
+ final byte c)
+ {
+ return (((a & 0xFF) << 23) | ((b & 0xFFFF) << 8) | (c & 0xFF));
+ }
+
+ /**
+ * Process key and IV into LFSR.
+ *
+ * @param pLFSR the LFSR
+ * @param k the key
+ * @param iv the iv
+ */
+ protected void setKeyAndIV(final int[] pLFSR,
+ final byte[] k,
+ final byte[] iv)
+ {
+ /* Check lengths */
+ if (k == null || k.length != 16)
+ {
+ throw new IllegalArgumentException("A key of 16 bytes is needed");
+ }
+ if (iv == null || iv.length != 16)
+ {
+ throw new IllegalArgumentException("An IV of 16 bytes is needed");
+ }
+
+ /* expand key */
+ LFSR[0] = MAKEU31(k[0], EK_d[0], iv[0]);
+ LFSR[1] = MAKEU31(k[1], EK_d[1], iv[1]);
+ LFSR[2] = MAKEU31(k[2], EK_d[2], iv[2]);
+ LFSR[3] = MAKEU31(k[3], EK_d[3], iv[3]);
+ LFSR[4] = MAKEU31(k[4], EK_d[4], iv[4]);
+ LFSR[5] = MAKEU31(k[5], EK_d[5], iv[5]);
+ LFSR[6] = MAKEU31(k[6], EK_d[6], iv[6]);
+ LFSR[7] = MAKEU31(k[7], EK_d[7], iv[7]);
+ LFSR[8] = MAKEU31(k[8], EK_d[8], iv[8]);
+ LFSR[9] = MAKEU31(k[9], EK_d[9], iv[9]);
+ LFSR[10] = MAKEU31(k[10], EK_d[10], iv[10]);
+ LFSR[11] = MAKEU31(k[11], EK_d[11], iv[11]);
+ LFSR[12] = MAKEU31(k[12], EK_d[12], iv[12]);
+ LFSR[13] = MAKEU31(k[13], EK_d[13], iv[13]);
+ LFSR[14] = MAKEU31(k[14], EK_d[14], iv[14]);
+ LFSR[15] = MAKEU31(k[15], EK_d[15], iv[15]);
+ }
+
+ /**
+ * Process key and IV.
+ *
+ * @param k the key
+ * @param iv the IV
+ */
+ private void setKeyAndIV(final byte[] k,
+ final byte[] iv)
+ {
+ /* Initialise LFSR */
+ setKeyAndIV(LFSR, k, iv);
+
+ /* set F_R1 and F_R2 to zero */
+ F[0] = 0;
+ F[1] = 0;
+ int nCount = 32;
+ while (nCount > 0)
+ {
+ BitReorganization();
+ final int w = F();
+ LFSRWithInitialisationMode(w >>> 1);
+ nCount--;
+ }
+ BitReorganization();
+ F(); /* discard the output of F */
+ LFSRWithWorkMode();
+ }
+
+ /**
+ * Create the next byte keyStream.
+ */
+ private void makeKeyStream()
+ {
+ encode32be(makeKeyStreamWord(), keyStream, 0);
+ }
+
+ /**
+ * Create the next keyStream word.
+ *
+ * @return the next word
+ */
+ protected int makeKeyStreamWord()
+ {
+ if (theIterations++ >= getMaxIterations())
+ {
+ throw new IllegalStateException("Too much data processed by singleKey/IV");
+ }
+ BitReorganization();
+ final int result = F() ^ BRC[3];
+ LFSRWithWorkMode();
+ return result;
+ }
+
+ /**
+ * Create a copy of the engine.
+ *
+ * @return the copy
+ */
+ public Memoable copy()
+ {
+ return new Zuc128CoreEngine(this);
+ }
+
+ /**
+ * Reset from saved engine state.
+ *
+ * @param pState the state to restore
+ */
+ public void reset(final Memoable pState)
+ {
+ final Zuc128CoreEngine e = (Zuc128CoreEngine)pState;
+ System.arraycopy(e.LFSR, 0, LFSR, 0, LFSR.length);
+ System.arraycopy(e.F, 0, F, 0, F.length);
+ System.arraycopy(e.BRC, 0, BRC, 0, BRC.length);
+ System.arraycopy(e.keyStream, 0, keyStream, 0, keyStream.length);
+ theIndex = e.theIndex;
+ theIterations = e.theIterations;
+ theResetState = e;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Zuc256CoreEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Zuc256CoreEngine.java
new file mode 100644
index 0000000..6c21db9
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Zuc256CoreEngine.java
@@ -0,0 +1,183 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.engines;
+
+import com.android.org.bouncycastle.util.Memoable;
+
+/**
+ * Zuc256 implementation.
+ * Based on https://www.is.cas.cn/ztzl2016/zouchongzhi/201801/W020180126529970733243.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Zuc256CoreEngine
+ extends Zuc128CoreEngine
+{
+ /* the constants D */
+ private static final byte[] EK_d = new byte[]{
+ 0x22, 0x2f, 0x24, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100010, 0b0101111, 0b0100100, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /* the constants D for 32 bit Mac*/
+ private static final byte[] EK_d32 = new byte[]{
+ 0x22, 0x2f, 0x25, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100010, 0b0101111, 0b0100101, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /* the constants D for 64 bit Mac */
+ private static final byte[] EK_d64 = new byte[]{
+ 0x23, 0x2f, 0x24, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100011, 0b0101111, 0b0100100, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /* the constants D for 128 bit Mac */
+ private static final byte[] EK_d128 = new byte[]{
+ 0x23, 0x2f, 0x25, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100011, 0b0101111, 0b0100101, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /**
+ * The selected D constants.
+ */
+ private byte[] theD;
+
+ /**
+ * Constructor for streamCipher.
+ */
+ protected Zuc256CoreEngine()
+ {
+ theD = EK_d;
+ }
+
+ /**
+ * Constructor for Mac.
+ *
+ * @param pLength the Mac length
+ */
+ protected Zuc256CoreEngine(final int pLength)
+ {
+ switch (pLength)
+ {
+ case 32:
+ theD = EK_d32;
+ break;
+ case 64:
+ theD = EK_d64;
+ break;
+ case 128:
+ theD = EK_d128;
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported length: " + pLength);
+ }
+ }
+
+ /**
+ * Constructor for Memoable.
+ *
+ * @param pSource the source engine
+ */
+ protected Zuc256CoreEngine(final Zuc256CoreEngine pSource)
+ {
+ super(pSource);
+ }
+
+ /**
+ * Obtain Max iterations.
+ *
+ * @return the maximum iterations
+ */
+ protected int getMaxIterations()
+ {
+ return 625;
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc-256";
+ }
+
+ /**
+ * Build a 31-bit integer from constituent parts.
+ *
+ * @param a part A
+ * @param b part B
+ * @param c part C
+ * @param d part D
+ * @return the built integer
+ */
+ private static int MAKEU31(byte a, byte b, byte c, byte d)
+ {
+ return (((a & 0xFF) << 23) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | (d & 0xFF));
+ }
+
+ /**
+ * Process key and IV into LFSR.
+ *
+ * @param pLFSR the LFSR
+ * @param k the key
+ * @param iv the iv
+ */
+ protected void setKeyAndIV(final int[] pLFSR,
+ final byte[] k,
+ final byte[] iv)
+ {
+ /* Check lengths */
+ if (k == null || k.length != 32)
+ {
+ throw new IllegalArgumentException("A key of 32 bytes is needed");
+ }
+ if (iv == null || iv.length != 25)
+ {
+ throw new IllegalArgumentException("An IV of 25 bytes is needed");
+ }
+
+ /* expand key and IV */
+ pLFSR[0] = MAKEU31(k[0], theD[0], k[21], k[16]);
+ pLFSR[1] = MAKEU31(k[1], theD[1], k[22], k[17]);
+ pLFSR[2] = MAKEU31(k[2], theD[2], k[23], k[18]);
+ pLFSR[3] = MAKEU31(k[3], theD[3], k[24], k[19]);
+ pLFSR[4] = MAKEU31(k[4], theD[4], k[25], k[20]);
+ pLFSR[5] = MAKEU31(iv[0], (byte)(theD[5] | (iv[17] & 0x3F)), k[5], k[26]);
+ pLFSR[6] = MAKEU31(iv[1], (byte)(theD[6] | (iv[18] & 0x3F)), k[6], k[27]);
+ pLFSR[7] = MAKEU31(iv[10], (byte)(theD[7] | (iv[19] & 0x3F)), k[7], iv[2]);
+ pLFSR[8] = MAKEU31(k[8], (byte)(theD[8] | (iv[20] & 0x3F)), iv[3], iv[11]);
+ pLFSR[9] = MAKEU31(k[9], (byte)(theD[9] | (iv[21] & 0x3F)), iv[12], iv[4]);
+ pLFSR[10] = MAKEU31(iv[5], (byte)(theD[10] | (iv[22] & 0x3F)), k[10], k[28]);
+ pLFSR[11] = MAKEU31(k[11], (byte)(theD[11] | (iv[23] & 0x3F)), iv[6], iv[13]);
+ pLFSR[12] = MAKEU31(k[12], (byte)(theD[12] | (iv[24] & 0x3F)), iv[7], iv[14]);
+ pLFSR[13] = MAKEU31(k[13], theD[13], iv[15], iv[8]);
+ pLFSR[14] = MAKEU31(k[14], (byte)(theD[14] | ((k[31] >>> 4) & 0xF)), iv[16], iv[9]);
+ pLFSR[15] = MAKEU31(k[15], (byte)(theD[15] | (k[31] & 0xF)), k[30], k[29]);
+ }
+
+ /**
+ * Create a copy of the engine.
+ *
+ * @return the copy
+ */
+ public Memoable copy()
+ {
+ return new Zuc256CoreEngine(this);
+ }
+
+ /**
+ * Reset from saved engine state.
+ *
+ * @param pState the state to restore
+ */
+ public void reset(final Memoable pState)
+ {
+ final Zuc256CoreEngine e = (Zuc256CoreEngine)pState;
+ super.reset(pState);
+ theD = e.theD;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Zuc256Engine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Zuc256Engine.java
new file mode 100644
index 0000000..0b70c60
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/Zuc256Engine.java
@@ -0,0 +1,51 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.engines;
+
+import com.android.org.bouncycastle.util.Memoable;
+
+/**
+ * Zuc256 implementation.
+ * Based on https://www.is.cas.cn/ztzl2016/zouchongzhi/201801/W020180126529970733243.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Zuc256Engine
+ extends Zuc256CoreEngine
+{
+ /**
+ * Constructor for streamCipher.
+ */
+ public Zuc256Engine()
+ {
+ super();
+ }
+
+ /**
+ * Constructor for Mac.
+ *
+ * @param pLength the Mac length
+ */
+ public Zuc256Engine(final int pLength)
+ {
+ super(pLength);
+ }
+
+ /**
+ * Constructor for Memoable.
+ *
+ * @param pSource the source engine
+ */
+ private Zuc256Engine(final Zuc256Engine pSource)
+ {
+ super(pSource);
+ }
+
+ /**
+ * Create a copy of the engine.
+ *
+ * @return the copy
+ */
+ public Memoable copy()
+ {
+ return new Zuc256Engine(this);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DESKeyGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DESKeyGenerator.java
index def7dd0..3f593c3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DESKeyGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DESKeyGenerator.java
@@ -2,7 +2,10 @@
package com.android.org.bouncycastle.crypto.generators;
import com.android.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.DESParameters;
/**
@@ -33,6 +36,8 @@
+ (DESParameters.DES_KEY_LENGTH * 8)
+ " bits long.");
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DESKeyGen", 56, null, CryptoServicePurpose.KEYGEN));
}
public byte[] generateKey()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
index a797969..e380848 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
@@ -1,7 +1,10 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.generators;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.DESedeParameters;
/**
@@ -43,6 +46,8 @@
+ (2 * 8 * DESedeParameters.DES_KEY_LENGTH)
+ " bits long.");
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DESedeKeyGen", 112, null, CryptoServicePurpose.KEYGEN));
}
public byte[] generateKey()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java
index 05d32d7..f47d753 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java
@@ -1,16 +1,20 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.generators;
+import java.math.BigInteger;
+
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.DHKeyGenerationParameters;
import com.android.org.bouncycastle.crypto.params.DHParameters;
import com.android.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
import com.android.org.bouncycastle.crypto.params.DHPublicKeyParameters;
-import java.math.BigInteger;
-
/**
* a basic Diffie-Hellman key pair generator.
*
@@ -27,6 +31,8 @@
KeyGenerationParameters param)
{
this.param = (DHKeyGenerationParameters)param;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DHBasicKeyGen", ConstraintUtils.bitsOfSecurityFor(this.param.getParameters().getP()), this.param.getParameters(), CryptoServicePurpose.KEYGEN));
}
public AsymmetricCipherKeyPair generateKeyPair()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java
index ec8945d..b749f39 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java
@@ -6,7 +6,11 @@
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.DSAKeyGenerationParameters;
import com.android.org.bouncycastle.crypto.params.DSAParameters;
import com.android.org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
@@ -32,6 +36,8 @@
KeyGenerationParameters param)
{
this.param = (DSAKeyGenerationParameters)param;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DSAKeyGen", ConstraintUtils.bitsOfSecurityFor(this.param.getParameters().getP()), this.param.getParameters(), CryptoServicePurpose.KEYGEN));
}
public AsymmetricCipherKeyPair generateKeyPair()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
index 6779b85..ac1daaa 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
@@ -6,7 +6,11 @@
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
import com.android.org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import com.android.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
@@ -24,9 +28,20 @@
public class ECKeyPairGenerator
implements AsymmetricCipherKeyPairGenerator, ECConstants
{
+ private final String name;
ECDomainParameters params;
SecureRandom random;
+ public ECKeyPairGenerator()
+ {
+ this("ECKeyGen");
+ }
+
+ protected ECKeyPairGenerator(String name)
+ {
+ this.name = name;
+ }
+
public void init(
KeyGenerationParameters param)
{
@@ -34,6 +49,8 @@
this.random = ecP.getRandom();
this.params = ecP.getDomainParameters();
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(name, ConstraintUtils.bitsOfSecurityFor(this.params.getCurve()), ecP.getDomainParameters(), CryptoServicePurpose.KEYGEN));
}
/**
@@ -51,7 +68,7 @@
{
d = BigIntegers.createRandomBigInteger(nBitLength, random);
- if (d.compareTo(ONE) < 0 || (d.compareTo(n) >= 0))
+ if (isOutOfRangeD(d, n))
{
continue;
}
@@ -71,6 +88,11 @@
new ECPrivateKeyParameters(d, params));
}
+ protected boolean isOutOfRangeD(BigInteger d, BigInteger n)
+ {
+ return d.compareTo(ONE) < 0 || (d.compareTo(n) >= 0);
+ }
+
protected ECMultiplier createBasePointMultiplier()
{
return new FixedPointCombMultiplier();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
index 116aa7d..bfbc415 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
@@ -13,8 +13,9 @@
/**
* Generator for PBE derived keys and ivs as usd by OpenSSL.
* <p>
- * The scheme is a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an
- * iteration count of 1.
+ * Originally this scheme was a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an
+ * iteration count of 1. The default digest was changed to SHA-256 with OpenSSL 1.1.0. This
+ * implementation still defaults to MD5, but the digest can now be set.
* <p>
* @hide This class is not part of the Android public SDK API
*/
@@ -26,7 +27,7 @@
private Digest digest = AndroidDigestFactory.getMD5();
/**
- * Construct a OpenSSL Parameters generator.
+ * Construct a OpenSSL Parameters generator.
*/
public OpenSSLPBEParametersGenerator()
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
index fa7aea2..2a41500 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
@@ -5,7 +5,11 @@
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
import com.android.org.bouncycastle.crypto.params.RSAKeyParameters;
import com.android.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
@@ -27,6 +31,8 @@
public void init(KeyGenerationParameters param)
{
this.param = (RSAKeyGenerationParameters)param;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("RSAKeyGen", ConstraintUtils.bitsOfSecurityForFF(param.getStrength()), null, CryptoServicePurpose.KEYGEN));
}
public AsymmetricCipherKeyPair generateKeyPair()
@@ -93,12 +99,12 @@
continue;
}
- /*
+ /*
* Require a minimum weight of the NAF representation, since low-weight composites may
- * be weak against a version of the number-field-sieve for factoring.
- *
- * See "The number field sieve for integers of low weight", Oliver Schirokauer.
- */
+ * be weak against a version of the number-field-sieve for factoring.
+ *
+ * See "The number field sieve for integers of low weight", Oliver Schirokauer.
+ */
if (WNafUtil.getNafWeight(n) < minWeight)
{
p = chooseRandomPrime(pbitlength, e, squaredBound);
@@ -144,8 +150,8 @@
qInv = BigIntegers.modOddInverse(p, q);
result = new AsymmetricCipherKeyPair(
- new RSAKeyParameters(false, n, e),
- new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv));
+ new RSAKeyParameters(false, n, e, true),
+ new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv, true));
}
return result;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/SM2KeyPairGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/SM2KeyPairGenerator.java
new file mode 100644
index 0000000..d38240f
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/SM2KeyPairGenerator.java
@@ -0,0 +1,40 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.generators;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.org.bouncycastle.crypto.params.ECKeyGenerationParameters;
+import com.android.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import com.android.org.bouncycastle.math.ec.ECConstants;
+import com.android.org.bouncycastle.math.ec.ECMultiplier;
+import com.android.org.bouncycastle.math.ec.ECPoint;
+import com.android.org.bouncycastle.math.ec.FixedPointCombMultiplier;
+import com.android.org.bouncycastle.math.ec.WNafUtil;
+import com.android.org.bouncycastle.util.BigIntegers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SM2KeyPairGenerator
+ extends ECKeyPairGenerator
+{
+ public SM2KeyPairGenerator()
+ {
+ super("SM2KeyGen");
+ }
+
+ protected boolean isOutOfRangeD(BigInteger d, BigInteger n)
+ {
+ return d.compareTo(ONE) < 0 || (d.compareTo(n.subtract(BigIntegers.ONE)) >= 0);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java
index 8569ea0..0e95b03 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java
@@ -94,7 +94,7 @@
throw new IllegalArgumentException("MAC size must be multiple of 8");
}
- this.cipher = new CBCBlockCipher(cipher);
+ this.cipher = CBCBlockCipher.newInstance(cipher);
this.padding = padding;
this.macSize = macSizeInBits / 8;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/HMac.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/HMac.java
index a77a0e8..00a23c3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/HMac.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/HMac.java
@@ -218,15 +218,15 @@
*/
public void reset()
{
- /*
- * reset the underlying digest.
- */
- digest.reset();
-
- /*
- * reinitialize the digest.
- */
- digest.update(inputPad, 0, inputPad.length);
+ if (ipadState != null)
+ {
+ ((Memoable)digest).reset(ipadState);
+ }
+ else
+ {
+ digest.reset();
+ digest.update(inputPad, 0, inputPad.length);
+ }
}
private static void xorPad(byte[] pad, int len, byte n)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/Zuc128Mac.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/Zuc128Mac.java
new file mode 100644
index 0000000..4a886c7
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/Zuc128Mac.java
@@ -0,0 +1,247 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.macs;
+
+import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.Mac;
+import com.android.org.bouncycastle.crypto.engines.Zuc128CoreEngine;
+
+/**
+ * Zuc128 Mac implementation.
+ * Based on https://www.qtc.jp/3GPP/Specs/eea3eia3specificationv16.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Zuc128Mac
+ implements Mac
+{
+ /**
+ * The Maximum Bit Mask.
+ */
+ private static final int TOPBIT = 0x80;
+
+ /**
+ * The Zuc128 Engine.
+ */
+ private final InternalZuc128Engine theEngine;
+
+ /**
+ * The calculated Mac in words.
+ */
+ private int theMac;
+
+ /**
+ * The active keyStream.
+ */
+ private final int[] theKeyStream;
+
+ /**
+ * The initialised state.
+ */
+ private Zuc128CoreEngine theState;
+
+ /**
+ * The current word index.
+ */
+ private int theWordIndex;
+
+ /**
+ * The current byte index.
+ */
+ private int theByteIndex;
+
+ /**
+ * Constructor.
+ */
+ public Zuc128Mac()
+ {
+ theEngine = new InternalZuc128Engine();
+ theKeyStream = new int[2];
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc128Mac";
+ }
+
+ /**
+ * Obtain Mac Size.
+ *
+ * @return the size in Bytes
+ */
+ public int getMacSize()
+ {
+ return 4; // Integer.Bytes
+ }
+
+ /**
+ * Initialise the Mac.
+ *
+ * @param pParams the parameters
+ */
+ public void init(final CipherParameters pParams)
+ {
+ /* Initialise the engine */
+ theEngine.init(true, pParams);
+ theState = (Zuc128CoreEngine)theEngine.copy();
+ initKeyStream();
+ }
+
+ /**
+ * Initialise the keyStream.
+ */
+ private void initKeyStream()
+ {
+ /* Initialise the Mac */
+ theMac = 0;
+
+ /* Initialise the KeyStream */
+ for (int i = 0; i < theKeyStream.length - 1; i++)
+ {
+ theKeyStream[i] = theEngine.createKeyStreamWord();
+ }
+ theWordIndex = theKeyStream.length - 1;
+ theByteIndex = 3; //Integer.BYTES - 1;
+ }
+
+ /**
+ * Update the mac with a single byte.
+ *
+ * @param in the byte to update with
+ */
+ public void update(final byte in)
+ {
+ /* shift for next byte */
+ shift4NextByte();
+
+ /* Loop through the bits */
+ final int bitBase = theByteIndex * 8; //Byte.SIZE;
+ for (int bitMask = TOPBIT, bitNo = 0; bitMask > 0; bitMask >>= 1, bitNo++)
+ {
+ /* If the bit is set */
+ if ((in & bitMask) != 0)
+ {
+ /* update theMac */
+ updateMac(bitBase + bitNo);
+ }
+ }
+ }
+
+ /**
+ * Shift for next byte.
+ */
+ private void shift4NextByte()
+ {
+ /* Adjust the byte index */
+ theByteIndex = (theByteIndex + 1) % 4; //Integer.BYTES;
+
+ /* Adjust keyStream if required */
+ if (theByteIndex == 0)
+ {
+ theKeyStream[theWordIndex] = theEngine.createKeyStreamWord();
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ }
+ }
+
+ /**
+ * Update the Mac.
+ *
+ * @param bitNo the bit number
+ */
+ private void updateMac(final int bitNo)
+ {
+ /* Update the Mac */
+ theMac ^= getKeyStreamWord(bitNo);
+ }
+
+ /**
+ * Obtain the keyStreamWord.
+ *
+ * @param bitNo the bitNumber
+ * @return the word
+ */
+ private int getKeyStreamWord(final int bitNo)
+ {
+ /* Access the first word and return it if this is bit 0 */
+ final int myFirst = theKeyStream[theWordIndex];
+ if (bitNo == 0)
+ {
+ return myFirst;
+ }
+
+ /* Access the second word */
+ final int mySecond = theKeyStream[(theWordIndex + 1) % theKeyStream.length];
+ return (myFirst << bitNo) | (mySecond >>> (32 - bitNo)); // Integer.SIZE - bitNo
+ }
+
+ /**
+ * Update the mac.
+ *
+ * @param in the input buffer
+ * @param inOff the starting offset in the input buffer
+ * @param len the length of data to process
+ */
+ public void update(final byte[] in, final int inOff, final int len)
+ {
+ for (int byteNo = 0; byteNo < len; byteNo++)
+ {
+ update(in[inOff + byteNo]);
+ }
+ }
+
+ /**
+ * Obtain the final word.
+ *
+ * @return the final word
+ */
+ private int getFinalWord()
+ {
+ if (theByteIndex != 0)
+ {
+ return theEngine.createKeyStreamWord();
+ }
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ return theKeyStream[theWordIndex];
+ }
+
+ /**
+ * Finalize the mac.
+ *
+ * @param out the output buffer
+ * @param outOff the starting offset in the input buffer
+ * @return the size of the mac
+ */
+ public int doFinal(final byte[] out, final int outOff)
+ {
+ /* Finish the Mac and output it */
+ shift4NextByte();
+ theMac ^= getKeyStreamWord(theByteIndex * 8); //Byte.SIZE
+ theMac ^= getFinalWord();
+ Zuc128CoreEngine.encode32be(theMac, out, outOff);
+
+ /* Reset the Mac */
+ reset();
+ return getMacSize();
+ }
+
+ public void reset()
+ {
+ if (theState != null)
+ {
+ theEngine.reset(theState);
+ }
+ initKeyStream();
+ }
+
+ private static class InternalZuc128Engine
+ extends Zuc128CoreEngine
+ {
+ int createKeyStreamWord()
+ {
+ return super.makeKeyStreamWord();
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/Zuc256Mac.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/Zuc256Mac.java
new file mode 100644
index 0000000..c162db9
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/macs/Zuc256Mac.java
@@ -0,0 +1,276 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.macs;
+
+import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.Mac;
+import com.android.org.bouncycastle.crypto.engines.Zuc256CoreEngine;
+
+/**
+ * Zuc256 Mac implementation.
+ * Based on https://www.is.cas.cn/ztzl2016/zouchongzhi/201801/W020180126529970733243.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Zuc256Mac
+ implements Mac
+{
+ /**
+ * The Maximum Bit Mask.
+ */
+ private static final int TOPBIT = 0x80;
+
+ /**
+ * The Zuc256 Engine.
+ */
+ private final InternalZuc256Engine theEngine;
+
+ /**
+ * The mac length.
+ */
+ private final int theMacLength;
+
+ /**
+ * The calculated Mac in words.
+ */
+ private final int[] theMac;
+
+ /**
+ * The active keyStream.
+ */
+ private final int[] theKeyStream;
+
+ /**
+ * The initialised state.
+ */
+ private Zuc256CoreEngine theState;
+
+ /**
+ * The current word index.
+ */
+ private int theWordIndex;
+
+ /**
+ * The current byte index.
+ */
+ private int theByteIndex;
+
+ /**
+ * Constructor.
+ *
+ * @param pLength the bit length of the Mac
+ */
+ public Zuc256Mac(final int pLength)
+ {
+ theEngine = new InternalZuc256Engine(pLength);
+ theMacLength = pLength;
+ final int numWords = pLength / 32; // Integer.SIZE
+ theMac = new int[numWords];
+ theKeyStream = new int[numWords + 1];
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc256Mac-" + theMacLength;
+ }
+
+ /**
+ * Obtain Mac Size.
+ *
+ * @return the size in Bytes
+ */
+ public int getMacSize()
+ {
+ return theMacLength / 8; //Byte.SIZE
+ }
+
+ /**
+ * Initialise the Mac.
+ *
+ * @param pParams the parameters
+ */
+ public void init(final CipherParameters pParams)
+ {
+ /* Initialise the engine */
+ theEngine.init(true, pParams);
+ theState = (Zuc256CoreEngine)theEngine.copy();
+ initKeyStream();
+ }
+
+ /**
+ * Initialise the keyStream.
+ */
+ private void initKeyStream()
+ {
+ /* Initialise the Mac */
+ for (int i = 0; i < theMac.length; i++)
+ {
+ theMac[i] = theEngine.createKeyStreamWord();
+ }
+
+ /* Initialise the KeyStream */
+ for (int i = 0; i < theKeyStream.length - 1; i++)
+ {
+ theKeyStream[i] = theEngine.createKeyStreamWord();
+ }
+ theWordIndex = theKeyStream.length - 1;
+ theByteIndex = 4 - 1; // Integer.SIZE
+ }
+
+ /**
+ * Update the mac with a single byte.
+ *
+ * @param in the byte to update with
+ */
+ public void update(final byte in)
+ {
+ /* shift for next byte */
+ shift4NextByte();
+
+ /* Loop through the bits */
+ final int bitBase = theByteIndex * 8; //Byte.SIZE;
+ for (int bitMask = TOPBIT, bitNo = 0; bitMask > 0; bitMask >>= 1, bitNo++)
+ {
+ /* If the bit is set */
+ if ((in & bitMask) != 0)
+ {
+ /* update theMac */
+ updateMac(bitBase + bitNo);
+ }
+ }
+ }
+
+ /**
+ * Shift for next byte.
+ */
+ private void shift4NextByte()
+ {
+ /* Adjust the byte index */
+ theByteIndex = (theByteIndex + 1) % 4; //Integer.BYTES
+
+ /* Adjust keyStream if required */
+ if (theByteIndex == 0)
+ {
+ theKeyStream[theWordIndex] = theEngine.createKeyStreamWord();
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ }
+ }
+
+ /**
+ * Shift for final update.
+ */
+ private void shift4Final()
+ {
+ /* Adjust the byte index */
+ theByteIndex = (theByteIndex + 1) % 4; //Integer.BYTES
+
+ /* No need to read another word to the keyStream */
+ if (theByteIndex == 0)
+ {
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ }
+ }
+
+ /**
+ * Update the Mac.
+ *
+ * @param bitNo the bit number
+ */
+ private void updateMac(final int bitNo)
+ {
+ /* Loop through the Mac */
+ for (int wordNo = 0; wordNo < theMac.length; wordNo++)
+ {
+ theMac[wordNo] ^= getKeyStreamWord(wordNo, bitNo);
+ }
+ }
+
+ /**
+ * Obtain the keyStreamWord.
+ *
+ * @param wordNo the wordNumber
+ * @param bitNo the bitNumber
+ * @return the word
+ */
+ private int getKeyStreamWord(final int wordNo, final int bitNo)
+ {
+ /* Access the first word and return it if this is bit 0 */
+ final int myFirst = theKeyStream[(theWordIndex + wordNo) % theKeyStream.length];
+ if (bitNo == 0)
+ {
+ return myFirst;
+ }
+
+ /* Access the second word */
+ final int mySecond = theKeyStream[(theWordIndex + wordNo + 1) % theKeyStream.length];
+ return (myFirst << bitNo) | (mySecond >>> (32 - bitNo)); //Integer.SIZE - bitNo
+ }
+
+ /**
+ * Update the mac.
+ *
+ * @param in the input buffer
+ * @param inOff the starting offset in the input buffer
+ * @param len the length of data to process
+ */
+ public void update(final byte[] in, final int inOff, final int len)
+ {
+ for (int byteNo = 0; byteNo < len; byteNo++)
+ {
+ update(in[inOff + byteNo]);
+ }
+ }
+
+ /**
+ * Finalize the mac.
+ *
+ * @param out the output buffer
+ * @param outOff the starting offset in the output buffer
+ * @return the size of the mac
+ */
+ public int doFinal(final byte[] out, final int outOff)
+ {
+ /* shift for final update */
+ shift4Final();
+
+ /* Finish the Mac and output it */
+ updateMac(theByteIndex * 8); //Byte.SIZE)
+ for (int i = 0; i < theMac.length; i++)
+ {
+ Zuc256CoreEngine.encode32be(theMac[i], out, outOff + i * 4); //Integer.BYTES)
+ }
+
+ /* Reset the Mac */
+ reset();
+ return getMacSize();
+ }
+
+ /**
+ * Reset the Mac.
+ */
+ public void reset()
+ {
+ if (theState != null)
+ {
+ theEngine.reset(theState);
+ }
+ initKeyStream();
+ }
+
+ private static class InternalZuc256Engine
+ extends Zuc256CoreEngine
+ {
+ public InternalZuc256Engine(int pLength)
+ {
+ super(pLength);
+ }
+
+ int createKeyStreamWord()
+ {
+ return super.makeKeyStreamWord();
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CBCBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CBCBlockCipher.java
index 765d4c0..1282c26 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CBCBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CBCBlockCipher.java
@@ -4,6 +4,7 @@
import com.android.org.bouncycastle.crypto.BlockCipher;
import com.android.org.bouncycastle.crypto.CipherParameters;
import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.DefaultMultiBlockCipher;
import com.android.org.bouncycastle.crypto.params.ParametersWithIV;
import com.android.org.bouncycastle.util.Arrays;
@@ -12,7 +13,8 @@
* @hide This class is not part of the Android public SDK API
*/
public class CBCBlockCipher
- implements BlockCipher
+ extends DefaultMultiBlockCipher
+ implements CBCModeCipher
{
private byte[] IV;
private byte[] cbcV;
@@ -23,9 +25,20 @@
private boolean encrypting;
/**
+ * Return a new CBC mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the CBC mode.
+ */
+ public static CBCModeCipher newInstance(BlockCipher cipher)
+ {
+ return new CBCBlockCipher(cipher);
+ }
+
+ /**
* Basic constructor.
*
* @param cipher the block cipher to be used as the basis of chaining.
+ * @deprecated use the CBCBlockCipher.newInstance() static method.
*/
public CBCBlockCipher(
BlockCipher cipher)
@@ -79,31 +92,23 @@
System.arraycopy(iv, 0, IV, 0, iv.length);
- reset();
-
- // if null it's an IV changed only.
- if (ivParam.getParameters() != null)
- {
- cipher.init(encrypting, ivParam.getParameters());
- }
- else if (oldEncrypting != encrypting)
- {
- throw new IllegalArgumentException("cannot change encrypting state without providing key.");
- }
+ params = ivParam.getParameters();
}
else
{
- reset();
+ Arrays.fill(IV, (byte)0);
+ }
- // if it's null, key is to be reused.
- if (params != null)
- {
- cipher.init(encrypting, params);
- }
- else if (oldEncrypting != encrypting)
- {
- throw new IllegalArgumentException("cannot change encrypting state without providing key.");
- }
+ reset();
+
+ // if null it's an IV changed only (key is to be reused).
+ if (params != null)
+ {
+ cipher.init(encrypting, params);
+ }
+ else if (oldEncrypting != encrypting)
+ {
+ throw new IllegalArgumentException("cannot change encrypting state without providing key.");
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CBCModeCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CBCModeCipher.java
new file mode 100644
index 0000000..2bac162
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CBCModeCipher.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.modes;
+
+import com.android.org.bouncycastle.crypto.BlockCipher;
+import com.android.org.bouncycastle.crypto.MultiBlockCipher;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CBCModeCipher
+ extends MultiBlockCipher
+{
+ /**
+ * return the underlying block cipher that we are wrapping.
+ *
+ * @return the underlying block cipher that we are wrapping.
+ */
+ BlockCipher getUnderlyingCipher();
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMBlockCipher.java
index 7bd69d2..1be6a3c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMBlockCipher.java
@@ -22,7 +22,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class CCMBlockCipher
- implements AEADBlockCipher
+ implements CCMModeCipher
{
private BlockCipher cipher;
private int blockSize;
@@ -36,9 +36,20 @@
private ExposedByteArrayOutputStream data = new ExposedByteArrayOutputStream();
/**
+ * Return a new CCM mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the CCM mode.
+ */
+ public static CCMModeCipher newInstance(BlockCipher cipher)
+ {
+ return new CCMBlockCipher(cipher);
+ }
+
+ /**
* Basic constructor.
*
* @param c the block cipher to be used.
+ * @deprecated use the CCMBlockCipher.newInstance() static method.
*/
public CCMBlockCipher(BlockCipher c)
{
@@ -262,7 +273,7 @@
iv[0] = (byte)((q - 1) & 0x7);
System.arraycopy(nonce, 0, iv, 1, nonce.length);
- BlockCipher ctrCipher = new SICBlockCipher(cipher);
+ BlockCipher ctrCipher = SICBlockCipher.newInstance(cipher);
ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv));
int outputLen;
@@ -456,7 +467,7 @@
return getAssociatedTextLength() > 0;
}
- private class ExposedByteArrayOutputStream
+ private static class ExposedByteArrayOutputStream
extends ByteArrayOutputStream
{
public ExposedByteArrayOutputStream()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMModeCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMModeCipher.java
new file mode 100644
index 0000000..fdcf5f1
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMModeCipher.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.modes;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CCMModeCipher
+ extends AEADBlockCipher
+{
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBBlockCipher.java
index 341ef89..ca84869 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBBlockCipher.java
@@ -14,6 +14,7 @@
*/
public class CFBBlockCipher
extends StreamBlockCipher
+ implements CFBModeCipher
{
private byte[] IV;
private byte[] cfbV;
@@ -26,11 +27,23 @@
private int byteCount;
/**
+ * Return a new CFB mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the CFB mode.
+ * @param blockSize the block size (in bits) used for the CFB mode.
+ */
+ public static CFBModeCipher newInstance(BlockCipher cipher, int blockSize)
+ {
+ return new CFBBlockCipher(cipher, blockSize);
+ }
+
+ /**
* Basic constructor.
*
* @param cipher the block cipher to be used as the basis of the
* feedback mode.
* @param bitBlockSize the block size in bits (note: a multiple of 8)
+ * @deprecated use the equivalent CFBBlockCipher.newInstance() static method.
*/
public CFBBlockCipher(
BlockCipher cipher,
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBModeCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBModeCipher.java
new file mode 100644
index 0000000..31bf193
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBModeCipher.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.modes;
+
+import com.android.org.bouncycastle.crypto.MultiBlockCipher;
+import com.android.org.bouncycastle.crypto.StreamCipher;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CFBModeCipher
+ extends MultiBlockCipher, StreamCipher
+{
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CTRModeCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CTRModeCipher.java
new file mode 100644
index 0000000..5281554
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CTRModeCipher.java
@@ -0,0 +1,20 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.modes;
+
+import com.android.org.bouncycastle.crypto.BlockCipher;
+import com.android.org.bouncycastle.crypto.MultiBlockCipher;
+import com.android.org.bouncycastle.crypto.SkippingStreamCipher;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CTRModeCipher
+ extends MultiBlockCipher, SkippingStreamCipher
+{
+ /**
+ * return the underlying block cipher that we are wrapping.
+ *
+ * @return the underlying block cipher that we are wrapping.
+ */
+ BlockCipher getUnderlyingCipher();
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CTSBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CTSBlockCipher.java
index 8233865..87dd1e0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CTSBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CTSBlockCipher.java
@@ -2,8 +2,8 @@
package com.android.org.bouncycastle.crypto.modes;
import com.android.org.bouncycastle.crypto.BlockCipher;
-import com.android.org.bouncycastle.crypto.BufferedBlockCipher;
import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import com.android.org.bouncycastle.crypto.InvalidCipherTextException;
import com.android.org.bouncycastle.crypto.OutputLengthException;
import com.android.org.bouncycastle.crypto.StreamBlockCipher;
@@ -14,7 +14,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class CTSBlockCipher
- extends BufferedBlockCipher
+ extends DefaultBufferedBlockCipher
{
private int blockSize;
@@ -223,9 +223,9 @@
buf[i] ^= block[i - blockSize];
}
- if (cipher instanceof CBCBlockCipher)
+ if (cipher instanceof CBCModeCipher)
{
- BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher();
+ BlockCipher c = ((CBCModeCipher)cipher).getUnderlyingCipher();
c.processBlock(buf, blockSize, out, outOff);
}
@@ -252,9 +252,9 @@
if (bufOff > blockSize)
{
- if (cipher instanceof CBCBlockCipher)
+ if (cipher instanceof CBCModeCipher)
{
- BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher();
+ BlockCipher c = ((CBCModeCipher)cipher).getUnderlyingCipher();
c.processBlock(buf, 0, block, 0);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/GCMBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/GCMBlockCipher.java
index 398d0f5..a549455 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/GCMBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/GCMBlockCipher.java
@@ -23,7 +23,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class GCMBlockCipher
- implements AEADBlockCipher
+ implements GCMModeCipher
{
private static final int BLOCK_SIZE = 16;
// BEGIN Android-added: Max input size limitation from NIST.
@@ -60,11 +60,45 @@
private long atLength;
private long atLengthPre;
+ /**
+ * Return a new GCM mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the GCM mode.
+ */
+ public static GCMModeCipher newInstance(BlockCipher cipher)
+ {
+ return new GCMBlockCipher(cipher);
+ }
+
+ /**
+ * Return a new GCM mode cipher based on the passed in base cipher and multiplier.
+ *
+ * @param cipher the base cipher for the GCM mode.
+ * @param m the GCM multiplier to use.
+ */
+ public static GCMModeCipher newInstance(BlockCipher cipher, GCMMultiplier m)
+ {
+ return new GCMBlockCipher(cipher, m);
+ }
+
+ /**
+ * Base constructor - GCM mode over base cipher c.
+ *
+ * @param c the base cipher.
+ * @deprecated use the GCMBlockCipher.newInstance() static method.
+ */
public GCMBlockCipher(BlockCipher c)
{
this(c, null);
}
+ /**
+ * Base constructor - GCM mode over base cipher c over base multiplier m.
+ *
+ * @param c the base cipher.
+ * @param m the GCM multiplier to use.
+ * @deprecated use the CBCBlockCipher.newInstance() static method.
+ */
public GCMBlockCipher(BlockCipher c, GCMMultiplier m)
{
if (c.getBlockSize() != BLOCK_SIZE)
@@ -289,17 +323,35 @@
}
// END Android-added: Max input size limitation from NIST.
- for (int i = 0; i < len; ++i)
+ if (atBlockPos > 0)
{
- atBlock[atBlockPos] = in[inOff + i];
- if (++atBlockPos == BLOCK_SIZE)
+ int available = BLOCK_SIZE - atBlockPos;
+ if (len < available)
{
- // Hash each block as it fills
- gHASHBlock(S_at, atBlock);
- atBlockPos = 0;
- atLength += BLOCK_SIZE;
+ System.arraycopy(in, inOff, atBlock, atBlockPos, len);
+ atBlockPos += len;
+ return;
}
+
+ System.arraycopy(in, inOff, atBlock, atBlockPos, available);
+ gHASHBlock(S_at, atBlock);
+ atLength += BLOCK_SIZE;
+ inOff += available;
+ len -= available;
+ //atBlockPos = 0;
}
+
+ int inLimit = inOff + len - BLOCK_SIZE;
+
+ while (inOff <= inLimit)
+ {
+ gHASHBlock(S_at, in, inOff);
+ atLength += BLOCK_SIZE;
+ inOff += BLOCK_SIZE;
+ }
+
+ atBlockPos = BLOCK_SIZE + inLimit - inOff;
+ System.arraycopy(in, inOff, atBlock, 0, atBlockPos);
}
private void initCipher()
@@ -336,13 +388,14 @@
bufBlock[bufOff] = in;
if (++bufOff == bufBlock.length)
{
- processBlock(bufBlock, 0, out, outOff);
if (forEncryption)
{
+ encryptBlock(bufBlock, 0, out, outOff);
bufOff = 0;
}
else
{
+ decryptBlock(bufBlock, 0, out, outOff);
System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize);
bufOff = macSize;
}
@@ -370,49 +423,79 @@
if (forEncryption)
{
- if (bufOff != 0)
+ if (bufOff > 0)
{
- while (len > 0)
+ int available = BLOCK_SIZE - bufOff;
+ if (len < available)
{
- --len;
- bufBlock[bufOff] = in[inOff++];
- if (++bufOff == BLOCK_SIZE)
- {
- processBlock(bufBlock, 0, out, outOff);
- bufOff = 0;
- resultLen += BLOCK_SIZE;
- break;
- }
+ System.arraycopy(in, inOff, bufBlock, bufOff, len);
+ bufOff += len;
+ return 0;
}
+
+ System.arraycopy(in, inOff, bufBlock, bufOff, available);
+ encryptBlock(bufBlock, 0, out, outOff);
+ inOff += available;
+ len -= available;
+ resultLen = BLOCK_SIZE;
+ //bufOff = 0;
}
- while (len >= BLOCK_SIZE)
+ int inLimit = inOff + len - BLOCK_SIZE;
+
+ while (inOff <= inLimit)
{
- processBlock(in, inOff, out, outOff + resultLen);
+ encryptBlock(in, inOff, out, outOff + resultLen);
inOff += BLOCK_SIZE;
- len -= BLOCK_SIZE;
resultLen += BLOCK_SIZE;
}
- if (len > 0)
- {
- System.arraycopy(in, inOff, bufBlock, 0, len);
- bufOff = len;
- }
+ bufOff = BLOCK_SIZE + inLimit - inOff;
+ System.arraycopy(in, inOff, bufBlock, 0, bufOff);
}
else
{
- for (int i = 0; i < len; ++i)
+ int available = bufBlock.length - bufOff;
+ if (len < available)
{
- bufBlock[bufOff] = in[inOff + i];
- if (++bufOff == bufBlock.length)
+ System.arraycopy(in, inOff, bufBlock, bufOff, len);
+ bufOff += len;
+ return 0;
+ }
+
+ if (bufOff >= BLOCK_SIZE)
+ {
+ decryptBlock(bufBlock, 0, out, outOff);
+ System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, bufOff -= BLOCK_SIZE);
+ resultLen = BLOCK_SIZE;
+
+ available += BLOCK_SIZE;
+ if (len < available)
{
- processBlock(bufBlock, 0, out, outOff + resultLen);
- System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize);
- bufOff = macSize;
- resultLen += BLOCK_SIZE;
+ System.arraycopy(in, inOff, bufBlock, bufOff, len);
+ bufOff += len;
+ return resultLen;
}
}
+
+ int inLimit = inOff + len - bufBlock.length;
+
+ available = BLOCK_SIZE - bufOff;
+ System.arraycopy(in, inOff, bufBlock, bufOff, available);
+ decryptBlock(bufBlock, 0, out, outOff + resultLen);
+ inOff += available;
+ resultLen += BLOCK_SIZE;
+ //bufOff = 0;
+
+ while (inOff <= inLimit)
+ {
+ decryptBlock(in, inOff, out, outOff + resultLen);
+ inOff += BLOCK_SIZE;
+ resultLen += BLOCK_SIZE;
+ }
+
+ bufOff = bufBlock.length + inLimit - inOff;
+ System.arraycopy(in, inOff, bufBlock, 0, bufOff);
}
return resultLen;
@@ -585,7 +668,7 @@
}
}
- private void processBlock(byte[] buf, int bufOff, byte[] out, int outOff)
+ private void decryptBlock(byte[] buf, int bufOff, byte[] out, int outOff)
{
if ((out.length - outOff) < BLOCK_SIZE)
{
@@ -599,18 +682,30 @@
byte[] ctrBlock = new byte[BLOCK_SIZE];
getNextCTRBlock(ctrBlock);
- if (forEncryption)
+ gHASHBlock(S, buf, bufOff);
+ GCMUtil.xor(ctrBlock, 0, buf, bufOff, out, outOff);
+
+ totalLength += BLOCK_SIZE;
+ }
+
+ private void encryptBlock(byte[] buf, int bufOff, byte[] out, int outOff)
+ {
+ if ((out.length - outOff) < BLOCK_SIZE)
{
- GCMUtil.xor(ctrBlock, buf, bufOff);
- gHASHBlock(S, ctrBlock);
- System.arraycopy(ctrBlock, 0, out, outOff, BLOCK_SIZE);
+ throw new OutputLengthException("Output buffer too short");
}
- else
+ if (totalLength == 0)
{
- gHASHBlock(S, buf, bufOff);
- GCMUtil.xor(ctrBlock, 0, buf, bufOff, out, outOff);
+ initCipher();
}
+ byte[] ctrBlock = new byte[BLOCK_SIZE];
+
+ getNextCTRBlock(ctrBlock);
+ GCMUtil.xor(ctrBlock, buf, bufOff);
+ gHASHBlock(S, ctrBlock);
+ System.arraycopy(ctrBlock, 0, out, outOff, BLOCK_SIZE);
+
totalLength += BLOCK_SIZE;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/GCMModeCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/GCMModeCipher.java
new file mode 100644
index 0000000..3ac9332
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/GCMModeCipher.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.modes;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface GCMModeCipher
+ extends AEADBlockCipher
+{
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java
new file mode 100644
index 0000000..3a5fa4d
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java
@@ -0,0 +1,973 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.modes;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.org.bouncycastle.crypto.BlockCipher;
+import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.org.bouncycastle.crypto.OutputLengthException;
+import com.android.org.bouncycastle.crypto.engines.AESEngine;
+import com.android.org.bouncycastle.crypto.modes.gcm.GCMMultiplier;
+import com.android.org.bouncycastle.crypto.modes.gcm.Tables4kGCMMultiplier;
+import com.android.org.bouncycastle.crypto.params.AEADParameters;
+import com.android.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Bytes;
+import com.android.org.bouncycastle.util.Integers;
+import com.android.org.bouncycastle.util.Longs;
+import com.android.org.bouncycastle.util.Pack;
+
+/**
+ * GCM-SIV Mode.
+ * <p>It should be noted that the specified limit of 2<sup>36</sup> bytes is not supported. This is because all bytes are
+ * cached in a <b>ByteArrayOutputStream</b> object (which has a limit of a little less than 2<sup>31</sup> bytes),
+ * and are output on the <b>doFinal</b>() call (which can only process a maximum of 2<sup>31</sup> bytes).</p>
+ * <p>The practical limit of 2<sup>31</sup> - 24 bytes is policed, and attempts to breach the limit will be rejected</p>
+ * <p>In order to properly support the higher limit, an extended form of <b>ByteArrayOutputStream</b> would be needed
+ * which would use multiple arrays to store the data. In addition, a new <b>doOutput</b> method would be required (similar
+ * to that in <b>XOF</b> digests), which would allow the data to be output over multiple calls. Alternatively an extended
+ * form of <b>ByteArrayInputStream</b> could be used to deliver the data.</p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GCMSIVBlockCipher
+ implements AEADBlockCipher
+{
+ /**
+ * The buffer length.
+ */
+ private static final int BUFLEN = 16;
+
+ /**
+ * The halfBuffer length.
+ */
+ private static final int HALFBUFLEN = BUFLEN >> 1;
+
+ /**
+ * The nonce length.
+ */
+ private static final int NONCELEN = 12;
+
+ /**
+ * The maximum data length (AEAD/PlainText). Due to implementation constraints this is restricted to the maximum
+ * array length (https://programming.guide/java/array-maximum-length.html) minus the BUFLEN to allow for the MAC
+ */
+ private static final int MAX_DATALEN = Integer.MAX_VALUE - 8 - BUFLEN;
+
+ /**
+ * The top bit mask.
+ */
+ private static final byte MASK = (byte) 0x80;
+
+ /**
+ * The addition constant.
+ */
+ private static final byte ADD = (byte) 0xE1;
+
+ /**
+ * The initialisation flag.
+ */
+ private static final int INIT = 1;
+
+ /**
+ * The aeadComplete flag.
+ */
+ private static final int AEAD_COMPLETE = 2;
+
+ /**
+ * The cipher.
+ */
+ private final BlockCipher theCipher;
+
+ /**
+ * The multiplier.
+ */
+ private final GCMMultiplier theMultiplier;
+
+ /**
+ * The gHash buffer.
+ */
+ private final byte[] theGHash = new byte[BUFLEN];
+
+ /**
+ * The reverse buffer.
+ */
+ private final byte[] theReverse = new byte[BUFLEN];
+
+ /**
+ * The aeadHasher.
+ */
+ private final GCMSIVHasher theAEADHasher;
+
+ /**
+ * The dataHasher.
+ */
+ private final GCMSIVHasher theDataHasher;
+
+ /**
+ * The plainDataStream.
+ */
+ private GCMSIVCache thePlain;
+
+ /**
+ * The encryptedDataStream (decryption only).
+ */
+ private GCMSIVCache theEncData;
+
+ /**
+ * Are we encrypting?
+ */
+ private boolean forEncryption;
+
+ /**
+ * The initialAEAD.
+ */
+ private byte[] theInitialAEAD;
+
+ /**
+ * The nonce.
+ */
+ private byte[] theNonce;
+
+ /**
+ * The flags.
+ */
+ private int theFlags;
+
+ // defined fixed
+ private byte[] macBlock = new byte[16];
+
+ /**
+ * Constructor.
+ */
+ public GCMSIVBlockCipher()
+ {
+ this(AESEngine.newInstance());
+ }
+
+ /**
+ * Constructor.
+ * @param pCipher the underlying cipher
+ */
+ public GCMSIVBlockCipher(final BlockCipher pCipher)
+ {
+ this(pCipher, new Tables4kGCMMultiplier());
+ }
+
+ /**
+ * Constructor.
+ * @param pCipher the underlying cipher
+ * @param pMultiplier the multiplier
+ */
+ public GCMSIVBlockCipher(final BlockCipher pCipher,
+ final GCMMultiplier pMultiplier)
+ {
+ /* Ensure that the cipher is the correct size */
+ if (pCipher.getBlockSize() != BUFLEN)
+ {
+ throw new IllegalArgumentException("Cipher required with a block size of " + BUFLEN + ".");
+ }
+
+ /* Store parameters */
+ theCipher = pCipher;
+ theMultiplier = pMultiplier;
+
+ /* Create the hashers */
+ theAEADHasher = new GCMSIVHasher();
+ theDataHasher = new GCMSIVHasher();
+ }
+
+ public BlockCipher getUnderlyingCipher()
+ {
+ return theCipher;
+ }
+
+ public void init(final boolean pEncrypt,
+ final CipherParameters cipherParameters) throws IllegalArgumentException
+ {
+ /* Set defaults */
+ byte[] myInitialAEAD = null;
+ byte[] myNonce = null;
+ KeyParameter myKey = null;
+
+ /* Access parameters */
+ if (cipherParameters instanceof AEADParameters)
+ {
+ final AEADParameters myAEAD = (AEADParameters) cipherParameters;
+ myInitialAEAD = myAEAD.getAssociatedText();
+ myNonce = myAEAD.getNonce();
+ myKey = myAEAD.getKey();
+ }
+ else if (cipherParameters instanceof ParametersWithIV)
+ {
+ final ParametersWithIV myParms = (ParametersWithIV) cipherParameters;
+ myNonce = myParms.getIV();
+ myKey = (KeyParameter) myParms.getParameters();
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid parameters passed to GCM-SIV");
+ }
+
+ /* Check nonceSize */
+ if (myNonce == null || myNonce.length != NONCELEN)
+ {
+ throw new IllegalArgumentException("Invalid nonce");
+ }
+
+ /* Check keysize */
+ if (myKey == null
+ || (myKey.getKeyLength() != BUFLEN
+ && myKey.getKeyLength() != (BUFLEN << 1)))
+ {
+ throw new IllegalArgumentException("Invalid key");
+ }
+
+ /* Reset details */
+ forEncryption = pEncrypt;
+ theInitialAEAD = myInitialAEAD;
+ theNonce = myNonce;
+
+ /* Initialise the keys */
+ deriveKeys(myKey);
+ resetStreams();
+ }
+
+ public String getAlgorithmName()
+ {
+ return theCipher.getAlgorithmName() + "-GCM-SIV";
+ }
+
+ /**
+ * check AEAD status.
+ * @param pLen the aeadLength
+ */
+ private void checkAEADStatus(final int pLen)
+ {
+ /* Check we are initialised */
+ if ((theFlags & INIT) == 0)
+ {
+ throw new IllegalStateException("Cipher is not initialised");
+ }
+
+ /* Check AAD is allowed */
+ if ((theFlags & AEAD_COMPLETE) != 0)
+ {
+ throw new IllegalStateException("AEAD data cannot be processed after ordinary data");
+ }
+
+ /* Make sure that we haven't breached AEAD data limit */
+ if (theAEADHasher.getBytesProcessed() + Long.MIN_VALUE
+ > (MAX_DATALEN - pLen) + Long.MIN_VALUE)
+ {
+ throw new IllegalStateException("AEAD byte count exceeded");
+ }
+ }
+
+ /**
+ * check status.
+ * @param pLen the dataLength
+ */
+ private void checkStatus(final int pLen)
+ {
+ /* Check we are initialised */
+ if ((theFlags & INIT) == 0)
+ {
+ throw new IllegalStateException("Cipher is not initialised");
+ }
+
+ /* Complete the AEAD section if this is the first data */
+ if ((theFlags & AEAD_COMPLETE) == 0)
+ {
+ theAEADHasher.completeHash();
+ theFlags |= AEAD_COMPLETE;
+ }
+
+ /* Make sure that we haven't breached data limit */
+ long dataLimit = MAX_DATALEN;
+ long currBytes = thePlain.size();
+ if (!forEncryption)
+ {
+ dataLimit += BUFLEN;
+ currBytes = theEncData.size();
+ }
+ if (currBytes + Long.MIN_VALUE
+ > (dataLimit - pLen) + Long.MIN_VALUE)
+ {
+ throw new IllegalStateException("byte count exceeded");
+ }
+ }
+
+ public void processAADByte(final byte pByte)
+ {
+ /* Check that we can supply AEAD */
+ checkAEADStatus(1);
+
+ /* Process the aead */
+ theAEADHasher.updateHash(pByte);
+ }
+
+ public void processAADBytes(final byte[] pData,
+ final int pOffset,
+ final int pLen)
+ {
+ /* Check that we can supply AEAD */
+ checkAEADStatus(pLen);
+
+ /* Check input buffer */
+ checkBuffer(pData, pOffset, pLen, false);
+
+ /* Process the aead */
+ theAEADHasher.updateHash(pData, pOffset, pLen);
+ }
+
+ public int processByte(final byte pByte,
+ final byte[] pOutput,
+ final int pOutOffset) throws DataLengthException
+ {
+ /* Check that we have initialised */
+ checkStatus(1);
+
+ /* Store the data */
+ if (forEncryption)
+ {
+ thePlain.write(pByte);
+ theDataHasher.updateHash(pByte);
+ }
+ else
+ {
+ theEncData.write(pByte);
+ }
+
+ /* No data returned */
+ return 0;
+ }
+
+ public int processBytes(final byte[] pData,
+ final int pOffset,
+ final int pLen,
+ final byte[] pOutput,
+ final int pOutOffset) throws DataLengthException
+ {
+ /* Check that we have initialised */
+ checkStatus(pLen);
+
+ /* Check input buffer */
+ checkBuffer(pData, pOffset, pLen, false);
+
+ /* Store the data */
+ if (forEncryption)
+ {
+ thePlain.write(pData, pOffset, pLen);
+ theDataHasher.updateHash(pData, pOffset, pLen);
+ }
+ else
+ {
+ theEncData.write(pData, pOffset, pLen);
+ }
+
+ /* No data returned */
+ return 0;
+ }
+
+ public int doFinal(final byte[] pOutput,
+ final int pOffset) throws IllegalStateException, InvalidCipherTextException
+ {
+ /* Check that we have initialised */
+ checkStatus(0);
+
+ /* Check output buffer */
+ checkBuffer(pOutput, pOffset, getOutputSize(0), true);
+
+ /* If we are encrypting */
+ if (forEncryption)
+ {
+ /* Derive the tag */
+ final byte[] myTag = calculateTag();
+
+ /* encrypt the plain text */
+ final int myDataLen = BUFLEN + encryptPlain(myTag, pOutput, pOffset);
+
+ /* Add the tag to the output */
+ System.arraycopy(myTag, 0, pOutput, pOffset + thePlain.size(), BUFLEN);
+
+ System.arraycopy(myTag, 0, macBlock, 0, macBlock.length);
+
+ /* Reset the streams */
+ resetStreams();
+ return myDataLen;
+
+ /* else we are decrypting */
+ }
+ else
+ {
+ /* decrypt to plain text */
+ decryptPlain();
+
+ /* Release plain text */
+ final int myDataLen = thePlain.size();
+ final byte[] mySrc = thePlain.getBuffer();
+ System.arraycopy(mySrc, 0, pOutput, pOffset, myDataLen);
+
+ /* Reset the streams */
+ resetStreams();
+ return myDataLen;
+ }
+ }
+
+ public byte[] getMac()
+ {
+ return Arrays.clone(macBlock);
+ }
+
+ public int getUpdateOutputSize(final int pLen)
+ {
+ return 0;
+ }
+
+ public int getOutputSize(final int pLen)
+ {
+ if (forEncryption)
+ {
+ return pLen + thePlain.size() + BUFLEN;
+ }
+ final int myCurr = pLen + theEncData.size();
+ return myCurr > BUFLEN ? myCurr - BUFLEN : 0;
+ }
+
+ public void reset()
+ {
+ resetStreams();
+ }
+
+ /**
+ * Reset Streams.
+ */
+ private void resetStreams()
+ {
+ /* Clear the plainText buffer */
+ if (thePlain != null)
+ {
+ thePlain.clearBuffer();
+ }
+
+ /* Reset hashers */
+ theAEADHasher.reset();
+ theDataHasher.reset();
+
+ /* Recreate streams (to release memory) */
+ thePlain = new GCMSIVCache();
+ theEncData = forEncryption ? null : new GCMSIVCache();
+
+ /* Initialise AEAD if required */
+ theFlags &= ~AEAD_COMPLETE;
+ Arrays.fill(theGHash, (byte) 0);
+ if (theInitialAEAD != null)
+ {
+ theAEADHasher.updateHash(theInitialAEAD, 0, theInitialAEAD.length);
+ }
+ }
+
+ /**
+ * Obtain buffer length (allowing for null).
+ * @param pBuffer the buffere
+ * @return the length
+ */
+ private static int bufLength(final byte[] pBuffer)
+ {
+ return pBuffer == null ? 0 : pBuffer.length;
+ }
+
+ /**
+ * Check buffer.
+ * @param pBuffer the buffer
+ * @param pOffset the offset
+ * @param pLen the length
+ * @param pOutput is this an output buffer?
+ */
+ private static void checkBuffer(final byte[] pBuffer,
+ final int pOffset,
+ final int pLen,
+ final boolean pOutput)
+ {
+ /* Access lengths */
+ final int myBufLen = bufLength(pBuffer);
+ final int myLast = pOffset + pLen;
+
+ /* Check for negative values and buffer overflow */
+ final boolean badLen = pLen < 0 || pOffset < 0 || myLast < 0;
+ if (badLen || myLast > myBufLen)
+ {
+ throw pOutput
+ ? new OutputLengthException("Output buffer too short.")
+ : new DataLengthException("Input buffer too short.");
+ }
+ }
+
+ /**
+ * encrypt data stream.
+ * @param pCounter the counter
+ * @param pTarget the target buffer
+ * @param pOffset the target offset
+ * @return the length of data encrypted
+ */
+ private int encryptPlain(final byte[] pCounter,
+ final byte[] pTarget,
+ final int pOffset)
+ {
+ /* Access buffer and length */
+ final byte[] mySrc = thePlain.getBuffer();
+ final byte[] myCounter = Arrays.clone(pCounter);
+ myCounter[BUFLEN - 1] |= MASK;
+ final byte[] myMask = new byte[BUFLEN];
+ int myRemaining = thePlain.size();
+ int myOff = 0;
+
+ /* While we have data to process */
+ while (myRemaining > 0)
+ {
+ /* Generate the next mask */
+ theCipher.processBlock(myCounter, 0, myMask, 0);
+
+ /* Xor data into mask */
+ final int myLen = Math.min(BUFLEN, myRemaining);
+ xorBlock(myMask, mySrc, myOff, myLen);
+
+ /* Copy encrypted data to output */
+ System.arraycopy(myMask, 0, pTarget, pOffset + myOff, myLen);
+
+ /* Adjust counters */
+ myRemaining -= myLen;
+ myOff += myLen;
+ incrementCounter(myCounter);
+ }
+
+ /* Return the amount of data processed */
+ return thePlain.size();
+ }
+
+ /**
+ * decrypt data stream.
+ * @throws InvalidCipherTextException on data too short or mac check failed
+ */
+ private void decryptPlain() throws InvalidCipherTextException
+ {
+ /* Access buffer and length */
+ final byte[] mySrc = theEncData.getBuffer();
+ int myRemaining = theEncData.size() - BUFLEN;
+
+ /* Check for insufficient data */
+ if (myRemaining < 0)
+ {
+ throw new InvalidCipherTextException("Data too short");
+ }
+
+ /* Access counter */
+ final byte[] myExpected = Arrays.copyOfRange(mySrc, myRemaining, myRemaining + BUFLEN);
+ final byte[] myCounter = Arrays.clone(myExpected);
+ myCounter[BUFLEN - 1] |= MASK;
+ final byte[] myMask = new byte[BUFLEN];
+ int myOff = 0;
+
+ /* While we have data to process */
+ while (myRemaining > 0)
+ {
+ /* Generate the next mask */
+ theCipher.processBlock(myCounter, 0, myMask, 0);
+
+ /* Xor data into mask */
+ final int myLen = Math.min(BUFLEN, myRemaining);
+ xorBlock(myMask, mySrc, myOff, myLen);
+
+ /* Write data to plain dataStream */
+ thePlain.write(myMask, 0, myLen);
+ theDataHasher.updateHash(myMask, 0, myLen);
+
+ /* Adjust counters */
+ myRemaining -= myLen;
+ myOff += myLen;
+ incrementCounter(myCounter);
+ }
+
+ /* Derive and check the tag */
+ final byte[] myTag = calculateTag();
+ if (!Arrays.constantTimeAreEqual(myTag, myExpected))
+ {
+ reset();
+ throw new InvalidCipherTextException("mac check failed");
+ }
+
+ System.arraycopy(myTag, 0, macBlock, 0, macBlock.length);
+ }
+
+ /**
+ * calculate tag.
+ * @return the calculated tag
+ */
+ private byte[] calculateTag()
+ {
+ /* Complete the hash */
+ theDataHasher.completeHash();
+ final byte[] myPolyVal = completePolyVal();
+
+ /* calculate polyVal */
+ final byte[] myResult = new byte[BUFLEN];
+
+ /* Fold in the nonce */
+ for (int i = 0; i < NONCELEN; i++)
+ {
+ myPolyVal[i] ^= theNonce[i];
+ }
+
+ /* Clear top bit */
+ myPolyVal[BUFLEN - 1] &= (MASK - 1);
+
+ /* Calculate tag and return it */
+ theCipher.processBlock(myPolyVal, 0, myResult, 0);
+ return myResult;
+ }
+
+ /**
+ * complete polyVAL.
+ * @return the calculated value
+ */
+ private byte[] completePolyVal()
+ {
+ /* Build the polyVal result */
+ final byte[] myResult = new byte[BUFLEN];
+ gHashLengths();
+ fillReverse(theGHash, 0, BUFLEN, myResult);
+ return myResult;
+ }
+
+ /**
+ * process lengths.
+ */
+ private void gHashLengths()
+ {
+ /* Create reversed bigEndian buffer to keep it simple */
+ final byte[] myIn = new byte[BUFLEN];
+ Pack.longToBigEndian(Bytes.SIZE * theDataHasher.getBytesProcessed(), myIn, 0);
+ Pack.longToBigEndian(Bytes.SIZE * theAEADHasher.getBytesProcessed(), myIn, Longs.BYTES);
+
+ /* hash value */
+ gHASH(myIn);
+ }
+
+ /**
+ * perform the next GHASH step.
+ * @param pNext the next value
+ */
+ private void gHASH(final byte[] pNext)
+ {
+ xorBlock(theGHash, pNext);
+ theMultiplier.multiplyH(theGHash);
+ }
+
+ /**
+ * Byte reverse a buffer.
+ * @param pInput the input buffer
+ * @param pOffset the offset
+ * @param pLength the length of data (<= BUFLEN)
+ * @param pOutput the output buffer
+ */
+ private static void fillReverse(final byte[] pInput,
+ final int pOffset,
+ final int pLength,
+ final byte[] pOutput)
+ {
+ /* Loop through the buffer */
+ for (int i = 0, j = BUFLEN - 1; i < pLength; i++, j--)
+ {
+ /* Copy byte */
+ pOutput[j] = pInput[pOffset + i];
+ }
+ }
+
+ /**
+ * xor a full block buffer.
+ * @param pLeft the left operand and result
+ * @param pRight the right operand
+ */
+ private static void xorBlock(final byte[] pLeft,
+ final byte[] pRight)
+ {
+ /* Loop through the bytes */
+ for (int i = 0; i < BUFLEN; i++)
+ {
+ pLeft[i] ^= pRight[i];
+ }
+ }
+
+ /**
+ * xor a partial block buffer.
+ * @param pLeft the left operand and result
+ * @param pRight the right operand
+ * @param pOffset the offset in the right operand
+ * @param pLength the length of data in the right operand
+ */
+ private static void xorBlock(final byte[] pLeft,
+ final byte[] pRight,
+ final int pOffset,
+ final int pLength)
+ {
+ /* Loop through the bytes */
+ for (int i = 0; i < pLength; i++)
+ {
+ pLeft[i] ^= pRight[i + pOffset];
+ }
+ }
+
+ /**
+ * increment the counter.
+ * @param pCounter the counter to increment
+ */
+ private static void incrementCounter(final byte[] pCounter)
+ {
+ /* Loop through the bytes incrementing counter */
+ for (int i = 0; i < Integers.BYTES; i++)
+ {
+ if (++pCounter[i] != 0)
+ {
+ break;
+ }
+ }
+ }
+
+ /**
+ * multiply by X.
+ * @param pValue the value to adjust
+ */
+ private static void mulX(final byte[] pValue)
+ {
+ /* Loop through the bytes */
+ byte myMask = (byte) 0;
+ for (int i = 0; i < BUFLEN; i++)
+ {
+ final byte myValue = pValue[i];
+ pValue[i] = (byte) (((myValue >> 1) & ~MASK) | myMask);
+ myMask = (myValue & 1) == 0 ? 0 : MASK;
+ }
+
+ /* Xor in addition if last bit was set */
+ if (myMask != 0)
+ {
+ pValue[0] ^= ADD;
+ }
+ }
+
+ /**
+ * Derive Keys.
+ * @param pKey the keyGeneration key
+ */
+ private void deriveKeys(final KeyParameter pKey)
+ {
+ /* Create the buffers */
+ final byte[] myIn = new byte[BUFLEN];
+ final byte[] myOut = new byte[BUFLEN];
+ final byte[] myResult = new byte[BUFLEN];
+ final byte[] myEncKey = new byte[pKey.getKeyLength()];
+
+ /* Prepare for encryption */
+ System.arraycopy(theNonce, 0, myIn, BUFLEN - NONCELEN, NONCELEN);
+ theCipher.init(true, pKey);
+
+ /* Derive authentication key */
+ int myOff = 0;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myResult, myOff, HALFBUFLEN);
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myResult, myOff, HALFBUFLEN);
+
+ /* Derive encryption key */
+ myIn[0]++;
+ myOff = 0;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+
+ /* If we have a 32byte key */
+ if (myEncKey.length == BUFLEN << 1)
+ {
+ /* Derive remainder of encryption key */
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+ }
+
+ /* Initialise the Cipher */
+ theCipher.init(true, new KeyParameter(myEncKey));
+
+ /* Initialise the multiplier */
+ fillReverse(myResult, 0, BUFLEN, myOut);
+ mulX(myOut);
+ theMultiplier.init(myOut);
+ theFlags |= INIT;
+ }
+
+ /**
+ * GCMSIVCache.
+ */
+ private static class GCMSIVCache
+ extends ByteArrayOutputStream
+ {
+ /**
+ * Constructor.
+ */
+ GCMSIVCache()
+ {
+ }
+
+ /**
+ * Obtain the buffer.
+ * @return the buffer
+ */
+ byte[] getBuffer()
+ {
+ return this.buf;
+ }
+
+ /**
+ * Clear the buffer.
+ */
+ void clearBuffer()
+ {
+ Arrays.fill(getBuffer(), (byte) 0);
+ }
+ }
+
+ /**
+ * Hash Control.
+ */
+ private class GCMSIVHasher
+ {
+ /**
+ * Cache.
+ */
+ private final byte[] theBuffer = new byte[BUFLEN];
+
+ /**
+ * Single byte cache.
+ */
+ private final byte[] theByte = new byte[1];
+
+ /**
+ * Count of active bytes in cache.
+ */
+ private int numActive;
+
+ /**
+ * Count of hashed bytes.
+ */
+ private long numHashed;
+
+ /**
+ * Obtain the count of bytes hashed.
+ * @return the count
+ */
+ long getBytesProcessed()
+ {
+ return numHashed;
+ }
+
+ /**
+ * Reset the hasher.
+ */
+ void reset()
+ {
+ numActive = 0;
+ numHashed = 0;
+ }
+
+ /**
+ * update hash.
+ * @param pByte the byte
+ */
+ void updateHash(final byte pByte)
+ {
+ theByte[0] = pByte;
+ updateHash(theByte, 0, 1);
+ }
+
+ /**
+ * update hash.
+ * @param pBuffer the buffer
+ * @param pOffset the offset within the buffer
+ * @param pLen the length of data
+ */
+ void updateHash(final byte[] pBuffer,
+ final int pOffset,
+ final int pLen)
+ {
+ /* If we should process the cache */
+ final int mySpace = BUFLEN - numActive;
+ int numProcessed = 0;
+ int myRemaining = pLen;
+ if (numActive > 0
+ && pLen >= mySpace)
+ {
+ /* Copy data into the cache and hash it */
+ System.arraycopy(pBuffer, pOffset, theBuffer, numActive, mySpace);
+ fillReverse(theBuffer, 0, BUFLEN, theReverse);
+ gHASH(theReverse);
+
+ /* Adjust counters */
+ numProcessed += mySpace;
+ myRemaining -= mySpace;
+ numActive = 0;
+ }
+
+ /* While we have full blocks */
+ while (myRemaining >= BUFLEN)
+ {
+ /* Access the next data */
+ fillReverse(pBuffer, pOffset + numProcessed, BUFLEN, theReverse);
+ gHASH(theReverse);
+
+ /* Adjust counters */
+ numProcessed += BUFLEN;
+ myRemaining -= BUFLEN;
+ }
+
+ /* If we have remaining data */
+ if (myRemaining > 0)
+ {
+ /* Copy data into the cache */
+ System.arraycopy(pBuffer, pOffset + numProcessed, theBuffer, numActive, myRemaining);
+ numActive += myRemaining;
+ }
+
+ /* Adjust the number of bytes processed */
+ numHashed += pLen;
+ }
+
+ /**
+ * complete hash.
+ */
+ void completeHash()
+ {
+ /* If we have remaining data */
+ if (numActive > 0)
+ {
+ /* Access the next data */
+ Arrays.fill(theReverse, (byte) 0);
+ fillReverse(theBuffer, 0, numActive, theReverse);
+
+ /* hash value */
+ gHASH(theReverse);
+ }
+ }
+ }
+ }
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/SICBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/SICBlockCipher.java
index 73bdc58..1745112 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/SICBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/SICBlockCipher.java
@@ -4,7 +4,7 @@
import com.android.org.bouncycastle.crypto.BlockCipher;
import com.android.org.bouncycastle.crypto.CipherParameters;
import com.android.org.bouncycastle.crypto.DataLengthException;
-import com.android.org.bouncycastle.crypto.SkippingStreamCipher;
+import com.android.org.bouncycastle.crypto.OutputLengthException;
import com.android.org.bouncycastle.crypto.StreamBlockCipher;
import com.android.org.bouncycastle.crypto.params.ParametersWithIV;
import com.android.org.bouncycastle.util.Arrays;
@@ -17,7 +17,7 @@
*/
public class SICBlockCipher
extends StreamBlockCipher
- implements SkippingStreamCipher
+ implements CTRModeCipher
{
private final BlockCipher cipher;
private final int blockSize;
@@ -28,9 +28,20 @@
private int byteCount;
/**
+ * Return a new SIC/CTR mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the SIC/CTR mode.
+ */
+ public static CTRModeCipher newInstance(BlockCipher cipher)
+ {
+ return new SICBlockCipher(cipher);
+ }
+
+ /**
* Basic constructor.
*
* @param c the block cipher to be used.
+ * @deprecated use newInstance() method.
*/
public SICBlockCipher(BlockCipher c)
{
@@ -93,16 +104,75 @@
public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
throws DataLengthException, IllegalStateException
{
- processBytes(in, inOff, blockSize, out, outOff);
+ if (byteCount != 0)
+ {
+ processBytes(in, inOff, blockSize, out, outOff);
+ return blockSize;
+ }
+ if (inOff + blockSize > in.length)
+ {
+ throw new DataLengthException("input buffer too small");
+ }
+ if (outOff + blockSize > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ cipher.processBlock(counter, 0, counterOut, 0);
+ for (int i = 0; i < blockSize; ++i)
+ {
+ out[outOff + i] = (byte)(in[inOff + i] ^ counterOut[i]);
+ }
+ incrementCounter();
return blockSize;
}
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ if (inOff + len > in.length)
+ {
+ throw new DataLengthException("input buffer too small");
+ }
+ if (outOff + len > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ for (int i = 0; i < len; ++i)
+ {
+ byte next;
+
+ if (byteCount == 0)
+ {
+ checkLastIncrement();
+
+ cipher.processBlock(counter, 0, counterOut, 0);
+ next = (byte)(in[inOff + i] ^ counterOut[byteCount++]);
+ }
+ else
+ {
+ next = (byte)(in[inOff + i] ^ counterOut[byteCount++]);
+ if (byteCount == counter.length)
+ {
+ byteCount = 0;
+ incrementCounter();
+ }
+ }
+ out[outOff + i] = next;
+ }
+
+ return len;
+ }
+
protected byte calculateByte(byte in)
throws DataLengthException, IllegalStateException
{
if (byteCount == 0)
{
+ checkLastIncrement();
+
cipher.processBlock(counter, 0, counterOut, 0);
return (byte)(counterOut[byteCount++] ^ in);
@@ -113,10 +183,7 @@
if (byteCount == counter.length)
{
byteCount = 0;
-
- incrementCounterAt(0);
-
- checkCounter();
+ incrementCounter();
}
return rv;
@@ -127,7 +194,7 @@
// if the IV is the same as the blocksize we assume the user knows what they are doing
if (IV.length < blockSize)
{
- for (int i = 0; i != IV.length; i++)
+ for (int i = IV.length - 1; i >= 0; i--)
{
if (counter[i] != IV[i])
{
@@ -137,6 +204,30 @@
}
}
+ private void checkLastIncrement()
+ {
+ // if the IV is the same as the blocksize we assume the user knows what they are doing
+ if (IV.length < blockSize)
+ {
+ if (counter[IV.length - 1] != IV[IV.length - 1])
+ {
+ throw new IllegalStateException("Counter in CTR/SIC mode out of range.");
+ }
+ }
+ }
+
+ private void incrementCounter()
+ {
+ int i = counter.length;
+ while (--i >= 0)
+ {
+ if (++counter[i] != 0)
+ {
+ break;
+ }
+ }
+ }
+
private void incrementCounterAt(int pos)
{
int i = counter.length - pos;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java
index dd1ed48..ff33927 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java
@@ -1,8 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.modes.gcm;
-import com.android.org.bouncycastle.util.Arrays;
-
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -23,7 +21,9 @@
if (pow > 0)
{
- long[] powX = Arrays.clone(x);
+ long[] powX = new long[GCMUtil.SIZE_LONGS];
+ GCMUtil.copy(x, powX);
+
do
{
if ((pow & 1L) != 0)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/GCMUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
index e56c31e..c436d26 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
@@ -10,76 +10,119 @@
*/
public abstract class GCMUtil
{
+ public static final int SIZE_BYTES = 16;
+ public static final int SIZE_INTS = 4;
+ public static final int SIZE_LONGS = 2;
+
private static final int E1 = 0xe1000000;
private static final long E1L = (E1 & 0xFFFFFFFFL) << 32;
public static byte[] oneAsBytes()
{
- byte[] tmp = new byte[16];
+ byte[] tmp = new byte[SIZE_BYTES];
tmp[0] = (byte)0x80;
return tmp;
}
public static int[] oneAsInts()
{
- int[] tmp = new int[4];
+ int[] tmp = new int[SIZE_INTS];
tmp[0] = 1 << 31;
return tmp;
}
public static long[] oneAsLongs()
{
- long[] tmp = new long[2];
+ long[] tmp = new long[SIZE_LONGS];
tmp[0] = 1L << 63;
return tmp;
}
+ public static byte areEqual(byte[] x, byte[] y)
+ {
+ int d = 0;
+ for (int i = 0; i < SIZE_BYTES; ++i)
+ {
+ d |= x[i] ^ y[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (byte)((d - 1) >> 31);
+ }
+
+ public static int areEqual(int[] x, int[] y)
+ {
+ int d = 0;
+ d |= x[0] ^ y[0];
+ d |= x[1] ^ y[1];
+ d |= x[2] ^ y[2];
+ d |= x[3] ^ y[3];
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static long areEqual(long[] x, long[] y)
+ {
+ long d = 0L;
+ d |= x[0] ^ y[0];
+ d |= x[1] ^ y[1];
+ d = (d >>> 1) | (d & 1L);
+ return (d - 1L) >> 63;
+ }
+
public static byte[] asBytes(int[] x)
{
- byte[] z = new byte[16];
- Pack.intToBigEndian(x, z, 0);
+ byte[] z = new byte[SIZE_BYTES];
+ Pack.intToBigEndian(x, 0, SIZE_INTS, z, 0);
return z;
}
public static void asBytes(int[] x, byte[] z)
{
- Pack.intToBigEndian(x, z, 0);
+ Pack.intToBigEndian(x, 0, SIZE_INTS, z, 0);
}
public static byte[] asBytes(long[] x)
{
- byte[] z = new byte[16];
- Pack.longToBigEndian(x, z, 0);
+ byte[] z = new byte[SIZE_BYTES];
+ Pack.longToBigEndian(x, 0, SIZE_LONGS, z, 0);
return z;
}
public static void asBytes(long[] x, byte[] z)
{
- Pack.longToBigEndian(x, z, 0);
+ Pack.longToBigEndian(x, 0, SIZE_LONGS, z, 0);
}
public static int[] asInts(byte[] x)
{
- int[] z = new int[4];
- Pack.bigEndianToInt(x, 0, z);
+ int[] z = new int[SIZE_INTS];
+ Pack.bigEndianToInt(x, 0, z, 0, SIZE_INTS);
return z;
}
public static void asInts(byte[] x, int[] z)
{
- Pack.bigEndianToInt(x, 0, z);
+ Pack.bigEndianToInt(x, 0, z, 0, SIZE_INTS);
}
public static long[] asLongs(byte[] x)
{
- long[] z = new long[2];
- Pack.bigEndianToLong(x, 0, z);
+ long[] z = new long[SIZE_LONGS];
+ Pack.bigEndianToLong(x, 0, z, 0, SIZE_LONGS);
return z;
}
public static void asLongs(byte[] x, long[] z)
{
- Pack.bigEndianToLong(x, 0, z);
+ Pack.bigEndianToLong(x, 0, z, 0, SIZE_LONGS);
+ }
+
+ public static void copy(byte[] x, byte[] z)
+ {
+ for (int i = 0; i < SIZE_BYTES; ++i)
+ {
+ z[i] = x[i];
+ }
}
public static void copy(int[] x, int[] z)
@@ -107,10 +150,48 @@
public static void multiply(byte[] x, byte[] y)
{
- long[] t1 = GCMUtil.asLongs(x);
- long[] t2 = GCMUtil.asLongs(y);
- GCMUtil.multiply(t1, t2);
- GCMUtil.asBytes(t1, x);
+ long[] t1 = asLongs(x);
+ long[] t2 = asLongs(y);
+ multiply(t1, t2);
+ asBytes(t1, x);
+ }
+
+ static void multiply(byte[] x, long[] y)
+ {
+ /*
+ * "Three-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
+ *
+ * Without access to the high part of a 64x64 product x * y, we use a bit reversal to calculate it:
+ * rev(x) * rev(y) == rev((x * y) << 1)
+ */
+
+ long x0 = Pack.bigEndianToLong(x, 0);
+ long x1 = Pack.bigEndianToLong(x, 8);
+ long y0 = y[0], y1 = y[1];
+ long x0r = Longs.reverse(x0), x1r = Longs.reverse(x1);
+ long y0r = Longs.reverse(y0), y1r = Longs.reverse(y1);
+
+ long h0 = Longs.reverse(implMul64(x0r, y0r));
+ long h1 = implMul64(x0, y0) << 1;
+ long h2 = Longs.reverse(implMul64(x1r, y1r));
+ long h3 = implMul64(x1, y1) << 1;
+ long h4 = Longs.reverse(implMul64(x0r ^ x1r, y0r ^ y1r));
+ long h5 = implMul64(x0 ^ x1, y0 ^ y1) << 1;
+
+ long z0 = h0;
+ long z1 = h1 ^ h0 ^ h2 ^ h4;
+ long z2 = h2 ^ h1 ^ h3 ^ h5;
+ long z3 = h3;
+
+ z1 ^= z3 ^ (z3 >>> 1) ^ (z3 >>> 2) ^ (z3 >>> 7);
+// z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57);
+ z2 ^= (z3 << 62) ^ (z3 << 57);
+
+ z0 ^= z2 ^ (z2 >>> 1) ^ (z2 >>> 2) ^ (z2 >>> 7);
+ z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
+
+ Pack.longToBigEndian(z0, x, 0);
+ Pack.longToBigEndian(z1, x, 8);
}
public static void multiply(int[] x, int[] y)
@@ -118,7 +199,7 @@
int y0 = y[0], y1 = y[1], y2 = y[2], y3 = y[3];
int z0 = 0, z1 = 0, z2 = 0, z3 = 0;
- for (int i = 0; i < 4; ++i)
+ for (int i = 0; i < SIZE_INTS; ++i)
{
int bits = x[i];
for (int j = 0; j < 32; ++j)
@@ -301,16 +382,24 @@
y[1] = (x1 >>> 8) | (x0 << 56);
}
+ public static void multiplyP16(long[] x)
+ {
+ long x0 = x[0], x1 = x[1];
+ long c = x1 << 48;
+ x[0] = (x0 >>> 16) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
+ x[1] = (x1 >>> 16) | (x0 << 48);
+ }
+
public static long[] pAsLongs()
{
- long[] tmp = new long[2];
+ long[] tmp = new long[SIZE_LONGS];
tmp[0] = 1L << 62;
return tmp;
}
public static void square(long[] x, long[] z)
{
- long[] t = new long[4];
+ long[] t = new long[SIZE_LONGS * 2];
Interleave.expand64To128Rev(x[0], t, 0);
Interleave.expand64To128Rev(x[1], t, 2);
@@ -336,7 +425,7 @@
x[i] ^= y[i]; ++i;
x[i] ^= y[i]; ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(byte[] x, byte[] y, int yOff)
@@ -349,7 +438,7 @@
x[i] ^= y[yOff + i]; ++i;
x[i] ^= y[yOff + i]; ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff)
@@ -362,7 +451,7 @@
z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(byte[] x, byte[] y, int yOff, int yLen)
@@ -391,7 +480,7 @@
z[i] = (byte)(x[i] ^ y[i]); ++i;
z[i] = (byte)(x[i] ^ y[i]); ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(int[] x, int[] y)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java
index 1adb197..087e33e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java
@@ -1,9 +1,8 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.modes.gcm;
-import java.util.Vector;
-
-import com.android.org.bouncycastle.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
/**
* @hide This class is not part of the Android public SDK API
@@ -13,18 +12,18 @@
{
// A lookup table of the power-of-two powers of 'x'
// - lookupPowX2[i] = x^(2^i)
- private Vector lookupPowX2;
+ private List lookupPowX2;
public void init(byte[] x)
{
long[] y = GCMUtil.asLongs(x);
- if (lookupPowX2 != null && Arrays.areEqual(y, (long[])lookupPowX2.elementAt(0)))
+ if (lookupPowX2 != null && 0L != GCMUtil.areEqual(y, (long[])lookupPowX2.get(0)))
{
return;
}
- lookupPowX2 = new Vector(8);
- lookupPowX2.addElement(y);
+ lookupPowX2 = new ArrayList(8);
+ lookupPowX2.add(y);
}
public void exponentiateX(long pow, byte[] output)
@@ -35,8 +34,7 @@
{
if ((pow & 1L) != 0)
{
- ensureAvailable(bit);
- GCMUtil.multiply(y, (long[])lookupPowX2.elementAt(bit));
+ GCMUtil.multiply(y, getPowX2(bit));
}
++bit;
pow >>>= 1;
@@ -45,19 +43,22 @@
GCMUtil.asBytes(y, output);
}
- private void ensureAvailable(int bit)
+ private long[] getPowX2(int bit)
{
- int count = lookupPowX2.size();
- if (count <= bit)
+ int last = lookupPowX2.size() - 1;
+ if (last < bit)
{
- long[] tmp = (long[])lookupPowX2.elementAt(count - 1);
+ long[] prev = (long[])lookupPowX2.get(last);
do
{
- tmp = Arrays.clone(tmp);
- GCMUtil.square(tmp, tmp);
- lookupPowX2.addElement(tmp);
+ long[] next = new long[GCMUtil.SIZE_LONGS];
+ GCMUtil.square(prev, next);
+ lookupPowX2.add(next);
+ prev = next;
}
- while (++count <= bit);
+ while (++last < bit);
}
+
+ return (long[])lookupPowX2.get(bit);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java
index 0580d01..251d043 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.modes.gcm;
-import com.android.org.bouncycastle.util.Arrays;
import com.android.org.bouncycastle.util.Pack;
/**
@@ -19,12 +18,13 @@
{
T = new long[256][2];
}
- else if (Arrays.areEqual(this.H, H))
+ else if (0 != GCMUtil.areEqual(this.H, H))
{
return;
}
- this.H = Arrays.clone(H);
+ this.H = new byte[GCMUtil.SIZE_BYTES];
+ GCMUtil.copy(H, this.H);
// T[0] = 0
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java
index 8b2dd22..2c4a546 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.modes.gcm;
-import com.android.org.bouncycastle.util.Arrays;
import com.android.org.bouncycastle.util.Pack;
/**
@@ -17,16 +16,17 @@
{
if (T == null)
{
- T = new long[32][16][2];
+ T = new long[2][256][2];
}
- else if (Arrays.areEqual(this.H, H))
+ else if (0 != GCMUtil.areEqual(this.H, H))
{
return;
}
- this.H = Arrays.clone(H);
+ this.H = new byte[GCMUtil.SIZE_BYTES];
+ GCMUtil.copy(H, this.H);
- for (int i = 0; i < 32; ++i)
+ for (int i = 0; i < 2; ++i)
{
long[][] t = T[i];
@@ -34,17 +34,17 @@
if (i == 0)
{
- // t[1] = H.p^3
+ // t[1] = H.p^7
GCMUtil.asLongs(this.H, t[1]);
- GCMUtil.multiplyP3(t[1], t[1]);
+ GCMUtil.multiplyP7(t[1], t[1]);
}
else
{
- // t[1] = T[i-1][1].p^4
- GCMUtil.multiplyP4(T[i - 1][1], t[1]);
+ // t[1] = T[i-1][1].p^8
+ GCMUtil.multiplyP8(T[i - 1][1], t[1]);
}
- for (int n = 2; n < 16; n += 2)
+ for (int n = 2; n < 256; n += 2)
{
// t[2.n] = t[n].p^-1
GCMUtil.divideP(t[n >> 1], t[n]);
@@ -53,28 +53,33 @@
GCMUtil.xor(t[n], t[1], t[n + 1]);
}
}
-
}
public void multiplyH(byte[] x)
{
+ long[][] T0 = T[0], T1 = T[1];
+
// long[] z = new long[2];
-// for (int i = 15; i >= 0; --i)
+// for (int i = 14; i >= 0; i -= 2)
// {
-// GCMUtil.xor(z, T[i + i + 1][(x[i] & 0x0F)]);
-// GCMUtil.xor(z, T[i + i ][(x[i] & 0xF0) >>> 4]);
+// GCMUtil.multiplyP16(z);
+// GCMUtil.xor(z, T0[x[i] & 0xFF]);
+// GCMUtil.xor(z, T1[x[i + 1] & 0xFF]);
// }
// Pack.longToBigEndian(z, x, 0);
- long z0 = 0, z1 = 0;
+ long[] u = T0[x[14] & 0xFF];
+ long[] v = T1[x[15] & 0xFF];
+ long z0 = u[0] ^ v[0], z1 = u[1] ^ v[1];
- for (int i = 15; i >= 0; --i)
+ for (int i = 12; i >= 0; i -= 2)
{
- long[] u = T[i + i + 1][(x[i] & 0x0F)];
- long[] v = T[i + i ][(x[i] & 0xF0) >>> 4];
+ u = T0[x[i] & 0xFF];
+ v = T1[x[i + 1] & 0xFF];
- z0 ^= u[0] ^ v[0];
- z1 ^= u[1] ^ v[1];
+ long c = z1 << 48;
+ z1 = u[1] ^ v[1] ^ ((z1 >>> 16) | (z0 << 48));
+ z0 = u[0] ^ v[0] ^ (z0 >>> 16) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
}
Pack.longToBigEndian(z0, x, 0);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
index c7a7b63..91cc024 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
@@ -63,9 +63,11 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in[in.length - 1] & 0xff;
+ int count = in[in.length - 1] & 0xFF;
+ int position = in.length - count;
- if (count > in.length)
+ int failed = (position | (count - 1)) >> 31;
+ if (failed != 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java
index d2eb0e3..d566aaf 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java
@@ -62,18 +62,20 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in.length - 1;
-
- while (count > 0 && in[count] == 0)
+ int position = -1, still00Mask = -1;
+ int i = in.length;
+ while (--i >= 0)
{
- count--;
+ int next = in[i] & 0xFF;
+ int match00Mask = ((next ^ 0x00) - 1) >> 31;
+ int match80Mask = ((next ^ 0x80) - 1) >> 31;
+ position ^= (i ^ position) & (still00Mask & match80Mask);
+ still00Mask &= match00Mask;
}
-
- if (in[count] != (byte)0x80)
+ if (position < 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
-
- return in.length - count;
+ return in.length - position;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/PKCS7Padding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/PKCS7Padding.java
index f1712b6..ffa4e62 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/PKCS7Padding.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/PKCS7Padding.java
@@ -58,18 +58,16 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in[in.length - 1] & 0xff;
- byte countAsbyte = (byte)count;
+ byte countAsByte = in[in.length - 1];
+ int count = countAsByte & 0xFF;
+ int position = in.length - count;
- // constant time version
- boolean failed = (count > in.length | count == 0);
-
- for (int i = 0; i < in.length; i++)
+ int failed = (position | (count - 1)) >> 31;
+ for (int i = 0; i < in.length; ++i)
{
- failed |= (in.length - i <= count) & (in[i] != countAsbyte);
+ failed |= (in[i] ^ countAsByte) & ~((i - position) >> 31);
}
-
- if (failed)
+ if (failed != 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java
index 54e0b85..7baeb09 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java
@@ -2,9 +2,9 @@
package com.android.org.bouncycastle.crypto.paddings;
import com.android.org.bouncycastle.crypto.BlockCipher;
-import com.android.org.bouncycastle.crypto.BufferedBlockCipher;
import com.android.org.bouncycastle.crypto.CipherParameters;
import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import com.android.org.bouncycastle.crypto.InvalidCipherTextException;
import com.android.org.bouncycastle.crypto.OutputLengthException;
import com.android.org.bouncycastle.crypto.params.ParametersWithRandom;
@@ -18,7 +18,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class PaddedBufferedBlockCipher
- extends BufferedBlockCipher
+ extends DefaultBufferedBlockCipher
{
BlockCipherPadding padding;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/TBCPadding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/TBCPadding.java
index 333eef0..b4ee693 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/TBCPadding.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/TBCPadding.java
@@ -78,14 +78,15 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- byte code = in[in.length - 1];
-
- int index = in.length - 1;
- while (index > 0 && in[index - 1] == code)
+ int i = in.length;
+ int code = in[--i] & 0xFF, count = 1, countingMask = -1;
+ while (--i >= 0)
{
- index--;
+ int next = in[i] & 0xFF;
+ int matchMask = ((next ^ code) - 1) >> 31;
+ countingMask &= matchMask;
+ count -= countingMask;
}
-
- return in.length - index;
+ return count;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/X923Padding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/X923Padding.java
index c93135f..4129bad 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/X923Padding.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/X923Padding.java
@@ -70,9 +70,11 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in[in.length - 1] & 0xff;
+ int count = in[in.length - 1] & 0xFF;
+ int position = in.length - count;
- if (count > in.length)
+ int failed = (position | (count - 1)) >> 31;
+ if (failed != 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ZeroBytePadding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ZeroBytePadding.java
index 783b2a9..a068c0b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ZeroBytePadding.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ZeroBytePadding.java
@@ -58,18 +58,15 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in.length;
-
- while (count > 0)
+ int count = 0, still00Mask = -1;
+ int i = in.length;
+ while (--i >= 0)
{
- if (in[count - 1] != 0)
- {
- break;
- }
-
- count--;
+ int next = in[i] & 0xFF;
+ int match00Mask = ((next ^ 0x00) - 1) >> 31;
+ still00Mask &= match00Mask;
+ count -= still00Mask;
}
-
- return in.length - count;
+ return count;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/Blake3Parameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/Blake3Parameters.java
new file mode 100644
index 0000000..a30e8e8
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/Blake3Parameters.java
@@ -0,0 +1,86 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.params;
+
+import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * Blake3 Parameters.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Blake3Parameters
+ implements CipherParameters
+{
+ /**
+ * The key length.
+ */
+ private static final int KEYLEN = 32;
+
+ /**
+ * The key.
+ */
+ private byte[] theKey;
+
+ /**
+ * The context.
+ */
+ private byte[] theContext;
+
+ /**
+ * Create a key parameter.
+ * @param pContext the context
+ * @return the parameter
+ */
+ public static Blake3Parameters context(final byte[] pContext)
+ {
+ if (pContext == null)
+ {
+ throw new IllegalArgumentException("Invalid context");
+ }
+ final Blake3Parameters myParams = new Blake3Parameters();
+ myParams.theContext = Arrays.clone(pContext);
+ return myParams;
+ }
+
+ /**
+ * Create a key parameter.
+ * @param pKey the key
+ * @return the parameter
+ */
+ public static Blake3Parameters key(final byte[] pKey)
+ {
+ if (pKey == null || pKey.length != KEYLEN)
+ {
+ throw new IllegalArgumentException("Invalid keyLength");
+ }
+ final Blake3Parameters myParams = new Blake3Parameters();
+ myParams.theKey = Arrays.clone(pKey);
+ return myParams;
+ }
+
+ /**
+ * Obtain the key.
+ * @return the key
+ */
+ public byte[] getKey()
+ {
+ return Arrays.clone(theKey);
+ }
+
+ /**
+ * Clear the key bytes.
+ */
+ public void clearKey()
+ {
+ Arrays.fill(theKey, (byte) 0);
+ }
+
+ /**
+ * Obtain the salt.
+ * @return the salt
+ */
+ public byte[] getContext()
+ {
+ return Arrays.clone(theContext);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/FPEParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/FPEParameters.java
new file mode 100644
index 0000000..5ec0f90
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/FPEParameters.java
@@ -0,0 +1,61 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.params;
+
+import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.util.RadixConverter;
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class FPEParameters
+ implements CipherParameters
+{
+ private final KeyParameter key;
+ private final RadixConverter radixConverter;
+ private final byte[] tweak;
+ private final boolean useInverse;
+
+ public FPEParameters(KeyParameter key, int radix, byte[] tweak)
+ {
+ this(key, radix, tweak, false);
+ }
+
+ public FPEParameters(KeyParameter key, int radix, byte[] tweak, boolean useInverse)
+ {
+ this(key, new RadixConverter(radix), tweak, useInverse);
+ }
+
+ public FPEParameters(KeyParameter key, RadixConverter radixConverter, byte[] tweak, boolean useInverse)
+ {
+ this.key = key;
+ this.radixConverter = radixConverter;
+ this.tweak = Arrays.clone(tweak);
+ this.useInverse = useInverse;
+ }
+
+ public KeyParameter getKey()
+ {
+ return key;
+ }
+
+ public int getRadix()
+ {
+ return radixConverter.getRadix();
+ }
+
+ public RadixConverter getRadixConverter()
+ {
+ return radixConverter;
+ }
+
+ public byte[] getTweak()
+ {
+ return Arrays.clone(tweak);
+ }
+
+ public boolean isUsingInverseFunction()
+ {
+ return useInverse;
+ }
+}
\ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/KeyParameter.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/KeyParameter.java
index ad8fa0c..2657e4b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/KeyParameter.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/KeyParameter.java
@@ -2,6 +2,7 @@
package com.android.org.bouncycastle.crypto.params;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.util.Arrays;
/**
* @hide This class is not part of the Android public SDK API
@@ -22,13 +23,38 @@
int keyOff,
int keyLen)
{
- this.key = new byte[keyLen];
+ this(keyLen);
System.arraycopy(key, keyOff, this.key, 0, keyLen);
}
+ private KeyParameter(int length)
+ {
+ this.key = new byte[length];
+ }
+
+ public void copyTo(byte[] buf, int off, int len)
+ {
+ if (key.length != len)
+ throw new IllegalArgumentException("len");
+
+ System.arraycopy(key, 0, buf, off, len);
+ }
+
public byte[] getKey()
{
return key;
}
+
+ public int getKeyLength()
+ {
+ return key.length;
+ }
+
+ public KeyParameter reverse()
+ {
+ KeyParameter reversed = new KeyParameter(key.length);
+ Arrays.reverse(this.key, reversed.key);
+ return reversed;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAKeyParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAKeyParameters.java
index ac7c2ee..7839449 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAKeyParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAKeyParameters.java
@@ -3,6 +3,9 @@
import java.math.BigInteger;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.org.bouncycastle.math.Primes;
+import com.android.org.bouncycastle.util.BigIntegers;
import com.android.org.bouncycastle.util.Properties;
/**
@@ -11,6 +14,8 @@
public class RSAKeyParameters
extends AsymmetricKeyParameter
{
+ private static final BigIntegers.Cache validated = new BigIntegers.Cache();
+
// Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
"8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
@@ -29,6 +34,15 @@
BigInteger modulus,
BigInteger exponent)
{
+ this(isPrivate, modulus, exponent, false);
+ }
+
+ public RSAKeyParameters(
+ boolean isPrivate,
+ BigInteger modulus,
+ BigInteger exponent,
+ boolean isInternal)
+ {
super(isPrivate);
if (!isPrivate)
@@ -38,13 +52,20 @@
throw new IllegalArgumentException("RSA publicExponent is even");
}
}
-
- this.modulus = validate(modulus);
+
+ this.modulus = validated.contains(modulus) ? modulus : validate(modulus, isInternal);
this.exponent = exponent;
- }
+ }
- private BigInteger validate(BigInteger modulus)
+ private BigInteger validate(BigInteger modulus, boolean isInternal)
{
+ if (isInternal)
+ {
+ validated.add(modulus);
+
+ return modulus;
+ }
+
if ((modulus.intValue() & 1) == 0)
{
throw new IllegalArgumentException("RSA modulus is even");
@@ -57,16 +78,45 @@
return modulus;
}
+ int maxBitLength = Properties.asInteger("com.android.org.bouncycastle.rsa.max_size", 15360);
+
+ int modBitLength = modulus.bitLength();
+ if (maxBitLength < modBitLength)
+ {
+ throw new IllegalArgumentException("modulus value out of range");
+ }
+
if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE))
{
throw new IllegalArgumentException("RSA modulus has a small prime factor");
}
- // TODO: add additional primePower/Composite test - expensive!!
+ int bits = modulus.bitLength() / 2;
+ int iterations = Properties.asInteger("com.android.org.bouncycastle.rsa.max_mr_tests", getMRIterations(bits));
+ if (iterations > 0)
+ {
+ Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), iterations);
+ if (!mr.isProvablyComposite())
+ {
+ throw new IllegalArgumentException("RSA modulus is not composite");
+ }
+ }
+
+ validated.add(modulus);
+
return modulus;
}
+ private static int getMRIterations(int bits)
+ {
+ int iterations = bits >= 1536 ? 3
+ : bits >= 1024 ? 4
+ : bits >= 512 ? 7
+ : 50;
+ return iterations;
+ }
+
public BigInteger getModulus()
{
return modulus;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java
index 81ecfa6..32aa2be 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java
@@ -20,6 +20,19 @@
*
*/
public RSAPrivateCrtKeyParameters(
+ BigInteger modulus,
+ BigInteger publicExponent,
+ BigInteger privateExponent,
+ BigInteger p,
+ BigInteger q,
+ BigInteger dP,
+ BigInteger dQ,
+ BigInteger qInv)
+ {
+ this(modulus, publicExponent, privateExponent, p, q, dP, dQ, qInv, false);
+ }
+
+ public RSAPrivateCrtKeyParameters(
BigInteger modulus,
BigInteger publicExponent,
BigInteger privateExponent,
@@ -27,9 +40,10 @@
BigInteger q,
BigInteger dP,
BigInteger dQ,
- BigInteger qInv)
+ BigInteger qInv,
+ boolean isInternal)
{
- super(true, modulus, privateExponent);
+ super(true, modulus, privateExponent, isInternal);
this.e = publicExponent;
this.p = p;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/DSASigner.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/DSASigner.java
index 1d3c992..9a977e6 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/DSASigner.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/DSASigner.java
@@ -70,6 +70,8 @@
this.key = (DSAPublicKeyParameters)param;
}
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("DSA", key, forSigning));
+
this.random = initSecureRandom(forSigning && !kCalculator.isDeterministic(), providedRandom);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/ECDSASigner.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/ECDSASigner.java
index e81ab37..c5e0d80 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/ECDSASigner.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/ECDSASigner.java
@@ -76,6 +76,8 @@
this.key = (ECPublicKeyParameters)param;
}
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("ECDSA", key, forSigning));
+
this.random = initSecureRandom(forSigning && !kCalculator.isDeterministic(), providedRandom);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/Utils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/Utils.java
new file mode 100644
index 0000000..79c9a96
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/Utils.java
@@ -0,0 +1,41 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.signers;
+
+import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import com.android.org.bouncycastle.crypto.params.DSAKeyParameters;
+import com.android.org.bouncycastle.crypto.params.ECKeyParameters;
+// Android-removed: unsupported algorithm
+// import org.bouncycastle.crypto.params.GOST3410KeyParameters;
+
+class Utils
+{
+ static CryptoServiceProperties getDefaultProperties(String algorithm, DSAKeyParameters k, boolean forSigning)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getP()), k, getPurpose(forSigning));
+ }
+
+ // Android-removed: unsupported algorithm
+ // static CryptoServiceProperties getDefaultProperties(String algorithm, GOST3410KeyParameters k, boolean forSigning)
+ // {
+ // return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getP()), k, getPurpose(forSigning));
+ // }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, ECKeyParameters k, boolean forSigning)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getCurve()), k, getPurpose(forSigning));
+ }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, int bitsOfSecurity, CipherParameters k, boolean forSigning)
+ {
+ return new DefaultServiceProperties(algorithm, bitsOfSecurity, k, getPurpose(forSigning));
+ }
+
+ static CryptoServicePurpose getPurpose(boolean forSigning)
+ {
+ return forSigning ? CryptoServicePurpose.SIGNING : CryptoServicePurpose.VERIFYING;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/BasicAlphabetMapper.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/BasicAlphabetMapper.java
new file mode 100644
index 0000000..1ef1ef7
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/BasicAlphabetMapper.java
@@ -0,0 +1,107 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.org.bouncycastle.crypto.AlphabetMapper;
+
+/**
+ * A basic alphabet mapper that just creates a mapper based on the
+ * passed in array of characters.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BasicAlphabetMapper
+ implements AlphabetMapper
+{
+ private Map<Character, Integer> indexMap = new HashMap<Character, Integer>();
+ private Map<Integer, Character> charMap = new HashMap<Integer, Character>();
+
+ /**
+ * Base constructor.
+ *
+ * @param alphabet a String of characters making up the alphabet.
+ */
+ public BasicAlphabetMapper(String alphabet)
+ {
+ this(alphabet.toCharArray());
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param alphabet an array of characters making up the alphabet.
+ */
+ public BasicAlphabetMapper(char[] alphabet)
+ {
+ for (int i = 0; i != alphabet.length; i++)
+ {
+ if (indexMap.containsKey(alphabet[i]))
+ {
+ throw new IllegalArgumentException("duplicate key detected in alphabet: " + alphabet[i]);
+ }
+ indexMap.put(alphabet[i], i);
+ charMap.put(i, alphabet[i]);
+ }
+ }
+
+ public int getRadix()
+ {
+ return indexMap.size();
+ }
+
+ public byte[] convertToIndexes(char[] input)
+ {
+ byte[] out;
+
+ if (indexMap.size() <= 256)
+ {
+ out = new byte[input.length];
+ for (int i = 0; i != input.length; i++)
+ {
+ out[i] = indexMap.get(input[i]).byteValue();
+ }
+ }
+ else
+ {
+ out = new byte[input.length * 2];
+ for (int i = 0; i != input.length; i++)
+ {
+ int idx = indexMap.get(input[i]);
+ out[i * 2] = (byte)((idx >> 8) & 0xff);
+ out[i * 2 + 1] = (byte)(idx & 0xff);
+ }
+ }
+
+ return out;
+ }
+
+ public char[] convertToChars(byte[] input)
+ {
+ char[] out;
+
+ if (charMap.size() <= 256)
+ {
+ out = new char[input.length];
+ for (int i = 0; i != input.length; i++)
+ {
+ out[i] = charMap.get(input[i] & 0xff);
+ }
+ }
+ else
+ {
+ if ((input.length & 0x1) != 0)
+ {
+ throw new IllegalArgumentException("two byte radix and input string odd length");
+ }
+
+ out = new char[input.length / 2];
+ for (int i = 0; i != input.length; i += 2)
+ {
+ out[i / 2] = charMap.get(((input[i] << 8) & 0xff00) | (input[i + 1] & 0xff));
+ }
+ }
+
+ return out;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PrivateKeyFactory.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PrivateKeyFactory.java
index 4c3ea49..9cddb2b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PrivateKeyFactory.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PrivateKeyFactory.java
@@ -70,6 +70,14 @@
public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData)
throws IOException
{
+ if (privateKeyInfoData == null)
+ {
+ throw new IllegalArgumentException("privateKeyInfoData array null");
+ }
+ if (privateKeyInfoData.length == 0)
+ {
+ throw new IllegalArgumentException("privateKeyInfoData array empty");
+ }
return createKey(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(privateKeyInfoData)));
}
@@ -97,6 +105,11 @@
public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo)
throws IOException
{
+ if (keyInfo == null)
+ {
+ throw new IllegalArgumentException("keyInfo argument null");
+ }
+
AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm();
ASN1ObjectIdentifier algOID = algId.getAlgorithm();
@@ -139,12 +152,12 @@
else if (algOID.equals(X9ObjectIdentifiers.id_dsa))
{
ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
- ASN1Encodable de = algId.getParameters();
+ ASN1Encodable algParameters = algId.getParameters();
DSAParameters parameters = null;
- if (de != null)
+ if (algParameters != null)
{
- DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive());
+ DSAParameter params = DSAParameter.getInstance(algParameters.toASN1Primitive());
parameters = new DSAParameters(params.getP(), params.getQ(), params.getG());
}
@@ -184,32 +197,44 @@
/*
else if (algOID.equals(EdECObjectIdentifiers.id_X25519))
{
- return new X25519PrivateKeyParameters(getRawKey(keyInfo, X25519PrivateKeyParameters.KEY_SIZE), 0);
+ // Java 11 bug: exact length of X25519/X448 secret used in Java 11
+ if (X25519PrivateKeyParameters.KEY_SIZE == keyInfo.getPrivateKeyLength())
+ {
+ return new X25519PrivateKeyParameters(keyInfo.getPrivateKey().getOctets());
+ }
+
+ return new X25519PrivateKeyParameters(getRawKey(keyInfo));
}
else if (algOID.equals(EdECObjectIdentifiers.id_X448))
{
- return new X448PrivateKeyParameters(getRawKey(keyInfo, X448PrivateKeyParameters.KEY_SIZE), 0);
+ // Java 11 bug: exact length of X25519/X448 secret used in Java 11
+ if (X448PrivateKeyParameters.KEY_SIZE == keyInfo.getPrivateKeyLength())
+ {
+ return new X448PrivateKeyParameters(keyInfo.getPrivateKey().getOctets());
+ }
+
+ return new X448PrivateKeyParameters(getRawKey(keyInfo));
}
else if (algOID.equals(EdECObjectIdentifiers.id_Ed25519))
{
- return new Ed25519PrivateKeyParameters(getRawKey(keyInfo, Ed25519PrivateKeyParameters.KEY_SIZE), 0);
+ return new Ed25519PrivateKeyParameters(getRawKey(keyInfo));
}
else if (algOID.equals(EdECObjectIdentifiers.id_Ed448))
{
- return new Ed448PrivateKeyParameters(getRawKey(keyInfo, Ed448PrivateKeyParameters.KEY_SIZE), 0);
+ return new Ed448PrivateKeyParameters(getRawKey(keyInfo));
}
else if (
algOID.equals(CryptoProObjectIdentifiers.gostR3410_2001) ||
algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) ||
algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256))
{
- GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters());
+ ASN1Encodable algParameters = algId.getParameters();
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(algParameters);
ECGOST3410Parameters ecSpec = null;
BigInteger d = null;
- ASN1Primitive p = keyInfo.getPrivateKeyAlgorithm().getParameters().toASN1Primitive();
+ ASN1Primitive p = algParameters.toASN1Primitive();
if (p instanceof ASN1Sequence && (ASN1Sequence.getInstance(p).size() == 2 || ASN1Sequence.getInstance(p).size() == 3))
{
-
X9ECParameters ecP = ECGOST3410NamedCurves.getByOIDX9(gostParams.getPublicKeyParamSet());
ecSpec = new ECGOST3410Parameters(
@@ -218,11 +243,12 @@
gostParams.getPublicKeyParamSet(),
gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet());
- ASN1OctetString privEnc = keyInfo.getPrivateKey();
- if (privEnc.getOctets().length == 32 || privEnc.getOctets().length == 64)
+ int privateKeyLength = keyInfo.getPrivateKeyLength();
+
+ if (privateKeyLength == 32 || privateKeyLength == 64)
{
- d = new BigInteger(1, Arrays.reverse(privEnc.getOctets()));
+ d = new BigInteger(1, Arrays.reverse(keyInfo.getPrivateKey().getOctets()));
}
else
{
@@ -240,7 +266,7 @@
}
else
{
- X962Parameters params = X962Parameters.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters());
+ X962Parameters params = X962Parameters.getInstance(algId.getParameters());
if (params.isNamedCurve())
{
@@ -296,14 +322,8 @@
}
}
- private static byte[] getRawKey(PrivateKeyInfo keyInfo, int expectedSize)
- throws IOException
+ private static byte[] getRawKey(PrivateKeyInfo keyInfo) throws IOException
{
- byte[] result = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets();
- if (expectedSize != result.length)
- {
- throw new RuntimeException("private key encoding has incorrect length");
- }
- return result;
+ return ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets();
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PublicKeyFactory.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PublicKeyFactory.java
index 39e0967..55639f7 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PublicKeyFactory.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PublicKeyFactory.java
@@ -7,13 +7,13 @@
import java.util.HashMap;
import java.util.Map;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1InputStream;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DEROctetString;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
@@ -115,6 +115,14 @@
public static AsymmetricKeyParameter createKey(byte[] keyInfoData)
throws IOException
{
+ if (keyInfoData == null)
+ {
+ throw new IllegalArgumentException("keyInfoData array null");
+ }
+ if (keyInfoData.length == 0)
+ {
+ throw new IllegalArgumentException("keyInfoData array empty");
+ }
return createKey(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(keyInfoData)));
}
@@ -141,6 +149,10 @@
public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo)
throws IOException
{
+ if (keyInfo == null)
+ {
+ throw new IllegalArgumentException("keyInfo argument null");
+ }
return createKey(keyInfo, null);
}
@@ -155,6 +167,11 @@
public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Object defaultParams)
throws IOException
{
+ if (keyInfo == null)
+ {
+ throw new IllegalArgumentException("keyInfo argument null");
+ }
+
AlgorithmIdentifier algID = keyInfo.getAlgorithm();
SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algID.getAlgorithm());
@@ -306,7 +323,7 @@
dParams = new ECDomainParameters(x9);
}
- DERBitString bits = keyInfo.getPublicKeyData();
+ ASN1BitString bits = keyInfo.getPublicKeyData();
byte[] data = bits.getBytes();
ASN1OctetString key = new DEROctetString(data);
@@ -483,7 +500,7 @@
}
BigInteger b = new BigInteger(1, b_bytes);
DSTU4145BinaryField field = binary.getField();
- ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), b);
+ ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), b, null, null);
byte[] g_bytes = binary.getG();
if (algOid.equals(UAObjectIdentifiers.dstu4145le))
{
@@ -516,7 +533,7 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new X25519PublicKeyParameters(getRawKey(keyInfo, defaultParams, X25519PublicKeyParameters.KEY_SIZE), 0);
+ return new X25519PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
@@ -525,7 +542,7 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new X448PublicKeyParameters(getRawKey(keyInfo, defaultParams, X448PublicKeyParameters.KEY_SIZE), 0);
+ return new X448PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
@@ -534,7 +551,7 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new Ed25519PublicKeyParameters(getRawKey(keyInfo, defaultParams, Ed25519PublicKeyParameters.KEY_SIZE), 0);
+ return new Ed25519PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
@@ -543,24 +560,19 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new Ed448PublicKeyParameters(getRawKey(keyInfo, defaultParams, Ed448PublicKeyParameters.KEY_SIZE), 0);
+ return new Ed448PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
*/
// END Android-removed: Unsupported algorithms
- private static byte[] getRawKey(SubjectPublicKeyInfo keyInfo, Object defaultParams, int expectedSize)
+ private static byte[] getRawKey(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
/*
* TODO[RFC 8422]
* - Require defaultParams == null?
* - Require keyInfo.getAlgorithm().getParameters() == null?
*/
- byte[] result = keyInfo.getPublicKeyData().getOctets();
- if (expectedSize != result.length)
- {
- throw new RuntimeException("public key encoding has incorrect length");
- }
- return result;
+ return keyInfo.getPublicKeyData().getOctets();
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/RadixConverter.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/RadixConverter.java
new file mode 100644
index 0000000..81ba33d
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/RadixConverter.java
@@ -0,0 +1,190 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.util;
+
+import java.math.BigInteger;
+
+import com.android.org.bouncycastle.util.BigIntegers;
+
+/**
+ * Utility class to convert decimal numbers (BigInteger) into a number in the base provided and the other way round.
+ * <p>For an application of this see the FPE parameter classes.</p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RadixConverter
+{
+
+ /*
+ The conversions in this class are more complex than the standard ways of converting between basis because we want to improve the performance by limiting the
+ operations on BigInteger which are not very efficient.
+ The general idea is to perform math operations on primitive long as much as we can and just work with BigInteger when necessary.
+ Converting between basis uses the fact that a number in base 'B' have a unique representation in polynomial form.
+
+ num = ... + r8B^8 + r7B^7 + r6B^6 + r5B^5 + r4B^4 + r3B^3 + r2B^2 + r1B + r0
+
+ We can compute how many digits in base 'B' can fit in a long. For example, for a radix R=2^16 the number of digits 'n' that we can fit into a long is the
+ max 'n' that still satisfies: R^n < Long.MAX_VALUE (i.e. 2^63 -1). In this case 'n' is 3. To convert 'num' from its decimal representation to base 'B'
+ representation we can write down 'num' in a polynomial form of B^3:
+
+ num = (((...)B^3 + r8B^2 + r7B + r6)B^3 + r5B^2 + r4B + r3)B^3 + (r2B^2 + r1B + r0)
+
+ B^3 would be our intermediate base. We can convert numbers in base B^3 while operating on primitive long.
+ To convert a decimal num to its representation in base B we can first build its B^3 representation and then figure out the digits in base B from the single
+ digit in base B^3. num % B^3 gives us a single digit in base B^3 which corresponds to a group of 3 digits in base B.
+
+ An equivalent way of writing the polynomial form of num would be:
+
+ num = (...)B^9 + (r8B^8 + r7B^7 + r6B^6)B^6 + (r5B^5 + r4B^4 + r3)B^3 + (r2B^2 + r1B + r0)
+
+ In this form it becomes clear that to obtain 'num' from a sequence of digits, one can group the digits in group of 3 and compute the corresponding decimal
+ number for the group in base B. We can then multiply the decimal numbers by the corresponding power of B^3 and sum up the result to obtain the decimal
+ representation of num in base B,
+ */
+ private static final double LOG_LONG_MAX_VALUE = Math.log(Long.MAX_VALUE);
+ private static final int DEFAULT_POWERS_TO_CACHE = 10;
+ // the max number of digits in base 'radix' that fits in a long
+ private final int digitsGroupLength;
+ // the total number of digits combination in a group. radix ^ digitsGroupLength
+ private final BigInteger digitsGroupSpaceSize;
+ private final int radix;
+ private final BigInteger[] digitsGroupSpacePowers;
+
+ /**
+ * @param radix the radix to use for base conversions
+ * @param numberOfCachedPowers number of intermediate base powers to precompute and cache.
+ */
+ public RadixConverter(int radix, int numberOfCachedPowers)
+ {
+ this.radix = radix;
+ // solves radix^n < Long.MAX_VALUE to find n (maxDigitsFitsInLong)
+ this.digitsGroupLength = (int)Math.floor(LOG_LONG_MAX_VALUE / Math.log(radix));
+ this.digitsGroupSpaceSize = BigInteger.valueOf(radix).pow(digitsGroupLength);
+ this.digitsGroupSpacePowers = precomputeDigitsGroupPowers(numberOfCachedPowers, digitsGroupSpaceSize);
+ }
+
+ /**
+ * @param radix the radix to use for base conversions.
+ */
+ public RadixConverter(int radix)
+ {
+ this(radix, DEFAULT_POWERS_TO_CACHE);
+ }
+
+ public int getRadix()
+ {
+ return radix;
+ }
+
+ public void toEncoding(BigInteger number, int messageLength, short[] out)
+ {
+ if (number.signum() < 0)
+ {
+ throw new IllegalArgumentException();
+ }
+ // convert number into its representation in base 'radix'.
+ // writes leading '0' if the messageLength is greater than the number of digits required to encode in base 'radix'
+ int digitIndex = messageLength - 1;
+ do
+ {
+ if (number.equals(BigInteger.ZERO))
+ {
+ out[digitIndex--] = 0;
+ continue;
+ }
+ BigInteger[] quotientAndRemainder = number.divideAndRemainder(digitsGroupSpaceSize);
+ number = quotientAndRemainder[0];
+ digitIndex = toEncoding(quotientAndRemainder[1].longValue(), digitIndex, out);
+ }
+ while (digitIndex >= 0);
+ if (number.signum() != 0)
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private int toEncoding(long number, int digitIndex, short[] out)
+ {
+ for (int i = 0; i < digitsGroupLength && digitIndex >= 0; i++)
+ {
+ if (number == 0)
+ {
+ out[digitIndex--] = 0;
+ continue;
+ }
+ out[digitIndex--] = (short)(number % radix);
+ number = number / radix;
+ }
+ if (number != 0)
+ {
+ throw new IllegalStateException("Failed to convert decimal number");
+ }
+ return digitIndex;
+ }
+
+ public BigInteger fromEncoding(short[] digits)
+ {
+ // from a sequence of digits in base 'radix' to a decimal number
+ // iterate through groups of digits right to left
+ // digitsGroupLength = 2; digits: [22, 45, 11, 31, 24]
+ // groups are, in order of iteration: [31, 24], [45, 11], [22]
+ BigInteger currentGroupCardinality = BigIntegers.ONE;
+ BigInteger res = null;
+ int indexGroup = 0;
+ int numberOfDigits = digits.length;
+ for (int groupStartDigitIndex = numberOfDigits - digitsGroupLength;
+ groupStartDigitIndex > -digitsGroupLength;
+ groupStartDigitIndex = groupStartDigitIndex - digitsGroupLength)
+ {
+ int actualDigitsInGroup = digitsGroupLength;
+ if (groupStartDigitIndex < 0)
+ {
+ // last group might contain fewer digits so adjust offsets
+ actualDigitsInGroup = digitsGroupLength + groupStartDigitIndex;
+ groupStartDigitIndex = 0;
+ }
+ int groupEndDigitIndex = Math.min(groupStartDigitIndex + actualDigitsInGroup, numberOfDigits);
+ long groupInBaseRadix = fromEncoding(groupStartDigitIndex, groupEndDigitIndex, digits);
+ BigInteger bigInteger = BigInteger.valueOf(groupInBaseRadix);
+ if (indexGroup == 0)
+ {
+ res = bigInteger;
+ }
+ else
+ {
+ currentGroupCardinality =
+ indexGroup <= digitsGroupSpacePowers.length
+ ? digitsGroupSpacePowers[indexGroup - 1]
+ : currentGroupCardinality.multiply(digitsGroupSpaceSize);
+ res = res.add(bigInteger.multiply(currentGroupCardinality));
+ }
+ indexGroup++;
+ }
+ return res;
+ }
+
+ public int getDigitsGroupLength()
+ {
+ return digitsGroupLength;
+ }
+
+ private long fromEncoding(int groupStartDigitIndex, int groupEndDigitIndex, short[] digits)
+ {
+ long decimalNumber = 0;
+ for (int digitIndex = groupStartDigitIndex; digitIndex < groupEndDigitIndex; digitIndex++)
+ {
+ decimalNumber = (decimalNumber * radix) + (digits[digitIndex] & 0xFFFF);
+ }
+ return decimalNumber;
+ }
+
+ private BigInteger[] precomputeDigitsGroupPowers(int numberOfCachedPowers, BigInteger digitsGroupSpaceSize)
+ {
+ BigInteger[] cachedPowers = new BigInteger[numberOfCachedPowers];
+ BigInteger currentPower = digitsGroupSpaceSize;
+ for (int i = 0; i < numberOfCachedPowers; i++)
+ {
+ cachedPowers[i] = currentPower;
+ currentPower = currentPower.multiply(digitsGroupSpaceSize);
+ }
+ return cachedPowers;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/SSHNamedCurves.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/SSHNamedCurves.java
index 7c65234..a5ae9f7 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/SSHNamedCurves.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/SSHNamedCurves.java
@@ -73,8 +73,8 @@
while (e.hasMoreElements())
{
String name = (String)e.nextElement();
- X9ECParameters parameters = CustomNamedCurves.getByName(name);
- put(parameters.getCurve(), name);
+ ECCurve curve = CustomNamedCurves.getByNameLazy(name).getCurve();
+ put(curve, name);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/GCMParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/internal/asn1/cms/GCMParameters.java
similarity index 89%
rename from repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/GCMParameters.java
rename to repackaged/bcprov/src/main/java/com/android/org/bouncycastle/internal/asn1/cms/GCMParameters.java
index 17e3ba0..1443718 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/GCMParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/internal/asn1/cms/GCMParameters.java
@@ -1,5 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1.cms;
+package com.android.org.bouncycastle.internal.asn1.cms;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Integer;
@@ -33,8 +33,8 @@
* Accepted inputs:
* <ul>
* <li> null → null
- * <li> {@link com.android.org.bouncycastle.asn1.cms.GCMParameters} object
- * <li> {@link com.android.org.bouncycastle.asn1.ASN1Sequence#getInstance(Object) ASN1Sequence} input formats with GCMParameters structure inside
+ * <li> {@link GCMParameters} object
+ * <li> {@link ASN1Sequence#getInstance(Object) ASN1Sequence} input formats with GCMParameters structure inside
* </ul>
*
* @param obj the object we want converted.
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java
similarity index 94%
rename from repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java
rename to repackaged/bcprov/src/main/java/com/android/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java
index e2f0901..511fb95 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java
@@ -1,5 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1.isismtt;
+package com.android.org.bouncycastle.internal.asn1.isismtt;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -105,8 +105,6 @@
* </pre>
* <p>
* OID: 1.3.36.8.3.8
- *
- * @see com.android.org.bouncycastle.asn1.isismtt.x509.Restriction
*/
static final ASN1ObjectIdentifier id_isismtt_at_restriction = id_isismtt_at.branch("8");
@@ -131,8 +129,6 @@
* returned in this extension.
* <p>
* OID: 1.3.36.8.3.10
- *
- * @see com.android.org.bouncycastle.asn1.isismtt.ocsp.RequestedCertificate
*/
static final ASN1ObjectIdentifier id_isismtt_at_requestedCertificate = id_isismtt_at.branch("10");
@@ -161,8 +157,7 @@
* Hash of a certificate in OCSP.
* <p>
* OID: 1.3.36.8.3.13
- *
- * @see com.android.org.bouncycastle.asn1.isismtt.ocsp.CertHash
+ *
*/
static final ASN1ObjectIdentifier id_isismtt_at_certHash = id_isismtt_at.branch("13");
@@ -188,8 +183,7 @@
* </pre>
* <p>
* OID: 1.3.36.8.3.15
- *
- * @see com.android.org.bouncycastle.asn1.isismtt.x509.AdditionalInformationSyntax
+ *
*/
static final ASN1ObjectIdentifier id_isismtt_at_additionalInformation = id_isismtt_at.branch("15");
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EndEntityType.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EndEntityType.java
deleted file mode 100644
index b95294a..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EndEntityType.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.its.asn1;
-
-import com.android.org.bouncycastle.asn1.ASN1BitString;
-import com.android.org.bouncycastle.asn1.ASN1Object;
-import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.DERBitString;
-
-/**
- * <pre>
- * EndEntityType ::= BIT STRING { app(0), enrol(1) } (SIZE (8)) (ALL EXCEPT ())
- * </pre>
- * @hide This class is not part of the Android public SDK API
- */
-public class EndEntityType
- extends ASN1Object
-{
- public static final int app = (1 << 7);
- public static final int enrol = (1 << 6);
-
- private final ASN1BitString type;
-
- public EndEntityType(int type)
- {
- if (type != app && type != enrol)
- {
- throw new IllegalArgumentException("value out of range");
- }
-
- this.type = new DERBitString(type);
- }
-
- private EndEntityType(DERBitString str)
- {
- this.type = str;
- }
-
- public static EndEntityType getInstance(Object src)
- {
- if (src instanceof EndEntityType)
- {
- return (EndEntityType)src;
- }
- else if (src != null)
- {
- return new EndEntityType(DERBitString.getInstance(src));
- }
-
- return null;
- }
-
- public ASN1Primitive toASN1Primitive()
- {
- return type;
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PsidGroupPermissions.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PsidGroupPermissions.java
deleted file mode 100644
index 1ad2194..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PsidGroupPermissions.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.its.asn1;
-
-import java.math.BigInteger;
-
-import com.android.org.bouncycastle.asn1.ASN1Integer;
-import com.android.org.bouncycastle.asn1.ASN1Object;
-import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.ASN1Sequence;
-
-/**
- * <pre>
- * PsidGroupPermissions ::= SEQUENCE {
- * subjectPermissions SubjectPermissions,
- * minChainLength INTEGER DEFAULT 1,
- * chainLengthRange INTEGER DEFAULT 0,
- * eeType EndEntityType DEFAULT (app)
- * }
- * </pre>
- * @hide This class is not part of the Android public SDK API
- */
-public class PsidGroupPermissions
- extends ASN1Object
-{
- private final SubjectPermissions subjectPermissions;
- private final BigInteger minChainLength;
- private final BigInteger chainLengthRange;
- private final Object eeType;
-
- private PsidGroupPermissions(ASN1Sequence seq)
- {
- if (seq.size() != 2)
- {
- throw new IllegalArgumentException("sequence not length 2");
- }
-
- this.subjectPermissions = SubjectPermissions.getInstance(seq.getObjectAt(0));
- this.minChainLength = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue();
- this.chainLengthRange = ASN1Integer.getInstance(seq.getObjectAt(2)).getValue();
- this.eeType = EndEntityType.getInstance(seq.getObjectAt(3));
- }
-
- public static PsidGroupPermissions getInstance(Object src)
- {
- if (src instanceof PsidGroupPermissions)
- {
- return (PsidGroupPermissions)src;
- }
- else if (src != null)
- {
- return new PsidGroupPermissions(ASN1Sequence.getInstance(src));
- }
-
- return null;
- }
-
- public ASN1Primitive toASN1Primitive()
- {
- return null;
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/BCLoadStoreParameter.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/BCLoadStoreParameter.java
new file mode 100644
index 0000000..88c7e9b
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/BCLoadStoreParameter.java
@@ -0,0 +1,75 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCLoadStoreParameter
+ implements KeyStore.LoadStoreParameter
+{
+ private final InputStream in;
+ private final OutputStream out;
+ private final KeyStore.ProtectionParameter protectionParameter;
+
+ /**
+ * Base constructor for
+ *
+ * @param out
+ * @param password
+ */
+ public BCLoadStoreParameter(OutputStream out, char[] password)
+ {
+ this(out, new KeyStore.PasswordProtection(password));
+ }
+
+ public BCLoadStoreParameter(InputStream in, char[] password)
+ {
+ this(in, new KeyStore.PasswordProtection(password));
+ }
+
+ public BCLoadStoreParameter(InputStream in, KeyStore.ProtectionParameter protectionParameter)
+ {
+ this(in, null, protectionParameter);
+ }
+
+ public BCLoadStoreParameter(OutputStream out, KeyStore.ProtectionParameter protectionParameter)
+ {
+ this(null, out, protectionParameter);
+ }
+
+ BCLoadStoreParameter(InputStream in, OutputStream out, KeyStore.ProtectionParameter protectionParameter)
+ {
+ this.in = in;
+ this.out = out;
+ this.protectionParameter = protectionParameter;
+ }
+
+ public KeyStore.ProtectionParameter getProtectionParameter()
+ {
+ return protectionParameter;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ if (out == null)
+ {
+ throw new UnsupportedOperationException("parameter not configured for storage - no OutputStream");
+ }
+
+ return out;
+ }
+
+ public InputStream getInputStream()
+ {
+ if (out != null)
+ {
+ throw new UnsupportedOperationException("parameter configured for storage OutputStream present");
+ }
+
+ return in;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePrivateKey.java
index f5edf6d..d65f44e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePrivateKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePrivateKey.java
@@ -75,7 +75,7 @@
try
{
return new PrivateKeyInfo(
- new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_composite_key), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
}
catch (IOException e)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePublicKey.java
index d7161e8..aa57747 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePublicKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePublicKey.java
@@ -75,7 +75,7 @@
try
{
return new SubjectPublicKeyInfo(
- new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_composite_key), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
}
catch (IOException e)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/ExternalPublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/ExternalPublicKey.java
new file mode 100644
index 0000000..dd894b3
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/ExternalPublicKey.java
@@ -0,0 +1,105 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+
+import com.android.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.org.bouncycastle.asn1.bc.BCObjectIdentifiers;
+import com.android.org.bouncycastle.asn1.bc.ExternalValue;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.org.bouncycastle.jcajce.util.MessageDigestUtils;
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * Wrapper class which returns an "ExternalValue" for the public key encoding. In this case
+ * the key encoding is a hash and the actual key needs to be looked up somewhere else. Useful
+ * for where the public keys are really large but it's required to keep certificates small.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExternalPublicKey
+ implements PublicKey
+{
+ private final GeneralName location;
+ private final AlgorithmIdentifier digestAlg;
+ private final byte[] digest;
+
+ /**
+ * Base constructor with fundamental contents.
+ *
+ * @param location location URI for the actual public key.
+ * @param digestAlg hashing algorithm used to hash the actual public key encoding.
+ * @param digest digest of the actual public key.
+ */
+ public ExternalPublicKey(GeneralName location, AlgorithmIdentifier digestAlg, byte[] digest)
+ {
+ this.location = location;
+ this.digestAlg = digestAlg;
+ this.digest = Arrays.clone(digest);
+ }
+
+ /**
+ * Helper constructor with JCA contents.
+ *
+ * @param key the public key we are externalising.
+ * @param location location URI for the actual public key.
+ * @param digest digest to use for hashing the key.
+ */
+ // Android-removed: unsupported
+ // public ExternalPublicKey(PublicKey key, GeneralName location, MessageDigest digest)
+ // {
+ // this(location, MessageDigestUtils.getDigestAlgID(digest.getAlgorithm()), digest.digest(key.getEncoded()));
+ // }
+
+ /**
+ * Base constructor with ASN.1 structure.
+ *
+ * @param extKey structure with location, hashing algorithm and hash for the public key.
+ */
+ public ExternalPublicKey(ExternalValue extKey)
+ {
+ this(extKey.getLocation(), extKey.getHashAlg(), extKey.getHashValue());
+ }
+
+ /**
+ * Return "ExternalKey"
+ *
+ * @return "ExternalKey"
+ */
+ public String getAlgorithm()
+ {
+ return "ExternalKey";
+ }
+
+ /**
+ * Return "X.509" (DER encoded SubjectPublicKeyInfo)
+ *
+ * @return "X.509"
+ */
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ /**
+ * Return a SubjectPublicKeyInfo structure containing an ExternalValue encoding for the key.
+ *
+ * @return a DER encoding of SubjectPublicKeyInfo containing an ExternalValue structure.
+ */
+ public byte[] getEncoded()
+ {
+ try
+ {
+ return new SubjectPublicKeyInfo(
+ new AlgorithmIdentifier(BCObjectIdentifiers.external_value),
+ new ExternalValue(location, digestAlg, digest)).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode composite key: " + e.getMessage());
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/SecretKeyWithEncapsulation.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/SecretKeyWithEncapsulation.java
new file mode 100644
index 0000000..4abb0fa
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/SecretKeyWithEncapsulation.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce;
+
+import javax.crypto.SecretKey;
+
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * Carrier class for a KEM/KTS secret key plus its encapsulation.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class SecretKeyWithEncapsulation
+ implements SecretKey
+{
+ private final SecretKey secretKey;
+ private final byte[] encapsulation;
+
+ /**
+ * Basic constructor.
+ *
+ * @param secretKey the secret key that was arrived at.
+ * @param encapsulation the encapsulation the key data was carried in.
+ */
+ public SecretKeyWithEncapsulation(SecretKey secretKey, byte[] encapsulation)
+ {
+ this.secretKey = secretKey;
+ this.encapsulation = Arrays.clone(encapsulation);
+ }
+
+ /**
+ * Return the algorithm for the agreed secret key.
+ *
+ * @return the secret key value.
+ */
+ public String getAlgorithm()
+ {
+ return secretKey.getAlgorithm();
+ }
+
+ /**
+ * Return the format for the agreed secret key.
+ *
+ * @return the secret key format.
+ */
+ public String getFormat()
+ {
+ return secretKey.getFormat();
+ }
+
+ /**
+ * Return the encoding of the agreed secret key.
+ *
+ * @return the secret key encoding.
+ */
+ public byte[] getEncoded()
+ {
+ return secretKey.getEncoded();
+ }
+
+ /**
+ * Return the encapsulation that carried the key material used in creating the agreed secret key.
+ *
+ * @return the encrypted encapsulation of the agreed secret key.
+ */
+ public byte[] getEncapsulation()
+ {
+ return Arrays.clone(encapsulation);
+ }
+
+ public boolean equals(Object o)
+ {
+ return secretKey.equals(o);
+ }
+
+ public int hashCode()
+ {
+ return secretKey.hashCode();
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java
index c96bcf2..db02afa 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java
@@ -6,6 +6,8 @@
import java.security.Signature;
import java.security.SignatureException;
+import com.android.org.bouncycastle.util.Exceptions;
+
class SignatureUpdatingOutputStream
extends OutputStream
{
@@ -25,7 +27,7 @@
}
catch (SignatureException e)
{
- throw new IOException(e.getMessage());
+ throw Exceptions.ioException(e.getMessage(), e);
}
}
@@ -38,7 +40,7 @@
}
catch (SignatureException e)
{
- throw new IOException(e.getMessage());
+ throw Exceptions.ioException(e.getMessage(), e);
}
}
@@ -51,7 +53,7 @@
}
catch (SignatureException e)
{
- throw new IOException(e.getMessage());
+ throw Exceptions.ioException(e.getMessage(), e);
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java
new file mode 100644
index 0000000..58e8b06
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java
@@ -0,0 +1,149 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.asymmetric;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.org.bouncycastle.jcajce.CompositePrivateKey;
+import com.android.org.bouncycastle.jcajce.CompositePublicKey;
+import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class COMPOSITE
+{
+ private static final String PREFIX = "com.android.org.bouncycastle.jcajce.provider.asymmetric.COMPOSITE";
+
+ private static final Map<String, String> compositeAttributes = new HashMap<String, String>();
+
+ static
+ {
+ compositeAttributes.put("SupportedKeyClasses", "com.android.org.bouncycastle.jcajce.CompositePublicKey|com.android.org.bouncycastle.jcajce.CompositePrivateKey");
+ compositeAttributes.put("SupportedKeyFormats", "PKCS#8|X.509");
+ }
+
+ private static AsymmetricKeyInfoConverter baseConverter;
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyFactory
+ extends BaseKeyFactorySpi
+ {
+ protected Key engineTranslateKey(Key key)
+ throws InvalidKeyException
+ {
+ try
+ {
+ if (key instanceof PrivateKey)
+ {
+ return generatePrivate(PrivateKeyInfo.getInstance(key.getEncoded()));
+ }
+ else if (key instanceof PublicKey)
+ {
+ return generatePublic(SubjectPublicKeyInfo.getInstance(key.getEncoded()));
+ }
+ }
+ catch (IOException e)
+ {
+ throw new InvalidKeyException("key could not be parsed: " + e.getMessage());
+ }
+
+ throw new InvalidKeyException("key not recognized");
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePrivate(keyInfo);
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePublic(keyInfo);
+ }
+ }
+
+ private static class CompositeKeyInfoConverter
+ implements AsymmetricKeyInfoConverter
+ {
+ private final ConfigurableProvider provider;
+
+ public CompositeKeyInfoConverter(ConfigurableProvider provider)
+ {
+ this.provider = provider;
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(keyInfo.parsePrivateKey());
+ PrivateKey[] privKeys = new PrivateKey[keySeq.size()];
+
+ for (int i = 0; i != keySeq.size(); i++)
+ {
+ PrivateKeyInfo privInfo = PrivateKeyInfo.getInstance(keySeq.getObjectAt(i));
+
+ privKeys[i] = provider.getKeyInfoConverter(
+ privInfo.getPrivateKeyAlgorithm().getAlgorithm()).generatePrivate(privInfo);
+ }
+
+ return new CompositePrivateKey(privKeys);
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(keyInfo.getPublicKeyData().getBytes());
+ PublicKey[] pubKeys = new PublicKey[keySeq.size()];
+
+ for (int i = 0; i != keySeq.size(); i++)
+ {
+ SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(keySeq.getObjectAt(i));
+
+ pubKeys[i] = provider.getKeyInfoConverter((pubInfo.getAlgorithm().getAlgorithm())).generatePublic(pubInfo);
+ }
+
+ return new CompositePublicKey(pubKeys);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyFactory.COMPOSITE", PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory." + MiscObjectIdentifiers.id_alg_composite, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory.OID." + MiscObjectIdentifiers.id_alg_composite, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory." + MiscObjectIdentifiers.id_composite_key, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory.OID." + MiscObjectIdentifiers.id_composite_key, PREFIX + "$KeyFactory");
+
+ baseConverter = new CompositeKeyInfoConverter(provider);
+
+ provider.addKeyInfoConverter(MiscObjectIdentifiers.id_alg_composite, baseConverter);
+ provider.addKeyInfoConverter(MiscObjectIdentifiers.id_composite_key, baseConverter);
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/DSA.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
index da4e38d..646004a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
@@ -24,7 +24,7 @@
public Mappings()
{
}
-
+
public void configure(ConfigurableProvider provider)
{
provider.addAlgorithm("AlgorithmParameters.DSA", PREFIX + "AlgorithmParametersSpi");
@@ -91,6 +91,8 @@
provider.addAlgorithm("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA");
// END Android-changed: Change primary ID from DSA to SHA1withDSA
+ // addSignatureAlgorithm(provider, "RIPEMD160", "DSA", PREFIX + "DSASigner$dsaRMD160");
+
AsymmetricKeyInfoConverter keyFact = new KeyFactorySpi();
for (int i = 0; i != DSAUtil.dsaOids.length; i++)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EC.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EC.java
index 2dfdd58..3a12bd9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EC.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EC.java
@@ -12,6 +12,9 @@
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
// END Android-removed: Unsupported algorithms
import com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.cms.CMSObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.eac.EACObjectIdentifiers;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi;
import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
@@ -50,77 +53,73 @@
/*
provider.addAlgorithm("AlgorithmParameters.EC", PREFIX + "AlgorithmParametersSpi");
- provider.addAttributes("KeyAgreement.ECDH", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH");
- provider.addAttributes("KeyAgreement.ECDHC", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHC", PREFIX + "KeyAgreementSpi$DHC");
- provider.addAttributes("KeyAgreement.ECCDH", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDH", PREFIX + "KeyAgreementSpi$DHC");
+ provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECDHC", PREFIX + "KeyAgreementSpi$DHC", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDH", PREFIX + "KeyAgreementSpi$DHC", generalEcAttributes);
+
+ provider.addAlgorithm("KeyAgreement.ECCDHU", PREFIX + "KeyAgreementSpi$DHUC", generalEcAttributes);
- provider.addAttributes("KeyAgreement.ECCDHU", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHU", PREFIX + "KeyAgreementSpi$DHUC");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA1CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA256CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA384CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA512CKDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA1CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA256CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA384CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA512CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512CKDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512KDF");
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA1KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA224KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA256KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA384KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA512KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA1KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA224KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA256KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA384KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA512KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF");
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA1, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA224, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA256, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA384, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA512, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA1, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA224, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA256, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA384, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA512, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF");
-
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_RIPEMD160, PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHRIPEMD160KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_RIPEMD160, PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHRIPEMD160KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF", generalEcAttributes);
registerOid(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC", new KeyFactorySpi.EC());
@@ -158,25 +157,25 @@
if (!Properties.isOverrideSet("org.bouncycastle.ec.disable_mqv"))
{
- provider.addAlgorithm("KeyAgreement.ECMQV", PREFIX + "KeyAgreementSpi$MQV");
+ provider.addAlgorithm("KeyAgreement.ECMQV", PREFIX + "KeyAgreementSpi$MQV", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512CKDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512CKDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512KDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA1KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA224KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA256KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA384KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA512KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA1KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA224KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA256KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA384KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA512KDFAndSharedInfo", generalEcAttributes);
registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
@@ -210,17 +209,42 @@
provider.addAlgorithm("KeyPairGenerator.ECDHC", PREFIX + "KeyPairGeneratorSpi$ECDHC");
provider.addAlgorithm("KeyPairGenerator.ECIES", PREFIX + "KeyPairGeneratorSpi$ECDH");
- provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES");
+ provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA1", PREFIX + "IESCipher$ECIES", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA1", PREFIX + "IESCipher$ECIES", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA256", PREFIX + "IESCipher$ECIESwithSHA256", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA256", PREFIX + "IESCipher$ECIESwithSHA256", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA384", PREFIX + "IESCipher$ECIESwithSHA384", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA384", PREFIX + "IESCipher$ECIESwithSHA384", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA512", PREFIX + "IESCipher$ECIESwithSHA512", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA512", PREFIX + "IESCipher$ECIESwithSHA512", generalEcAttributes);
- provider.addAlgorithm("Cipher.ECIESwithAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC");
- provider.addAlgorithm("Cipher.ECIESWITHAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC");
- provider.addAlgorithm("Cipher.ECIESwithDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
- provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
+ provider.addAlgorithm("Cipher.ECIESwithAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA1andAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA1ANDAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA256andAES-CBC", PREFIX + "IESCipher$ECIESwithSHA256andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA256ANDAES-CBC", PREFIX + "IESCipher$ECIESwithSHA256andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA384andAES-CBC", PREFIX + "IESCipher$ECIESwithSHA384andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA384ANDAES-CBC", PREFIX + "IESCipher$ECIESwithSHA384andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA512andAES-CBC", PREFIX + "IESCipher$ECIESwithSHA512andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA512ANDAES-CBC", PREFIX + "IESCipher$ECIESwithSHA512andAESCBC", generalEcAttributes);
- provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA");
+ provider.addAlgorithm("Cipher.ECIESwithDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA1andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA1ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA256andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA256andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA256ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA256andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA384andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA384andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA384ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA384andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA512andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA512andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA512ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA512andDESedeCBC", generalEcAttributes);
- provider.addAlgorithm("Signature.SHA1withECDSA", PREFIX + "SignatureSpi$ecDSA");
- provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone");
+ provider.addAlgorithm("Cipher.ETSIKEMWITHSHA256", PREFIX + "IESKEMCipher$KEMwithSHA256", generalEcAttributes);
+
+ provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA", generalEcAttributes);
+ provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone", generalEcAttributes);
provider.addAlgorithm("Alg.Alias.Signature.ECDSA", "SHA1withECDSA");
provider.addAlgorithm("Alg.Alias.Signature.ECDSAwithSHA1", "SHA1withECDSA");
@@ -231,16 +255,16 @@
provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
provider.addAlgorithm("Alg.Alias.Signature." + TeleTrusTObjectIdentifiers.ecSignWithSha1, "ECDSA");
- provider.addAlgorithm("Signature.ECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
- provider.addAlgorithm("Signature.SHA1WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
- provider.addAlgorithm("Signature.SHA224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA224");
- provider.addAlgorithm("Signature.SHA256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA256");
- provider.addAlgorithm("Signature.SHA384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA384");
- provider.addAlgorithm("Signature.SHA512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512");
- provider.addAlgorithm("Signature.SHA3-224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_224");
- provider.addAlgorithm("Signature.SHA3-256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_256");
- provider.addAlgorithm("Signature.SHA3-384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_384");
- provider.addAlgorithm("Signature.SHA3-512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_512");
+ provider.addAlgorithm("Signature.ECDDSA", PREFIX + "SignatureSpi$ecDetDSA", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA1WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA224", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA256", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA384", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_224", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_256", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_384", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_512", generalEcAttributes);
provider.addAlgorithm("Alg.Alias.Signature.DETECDSA", "ECDDSA");
provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHDETECDSA", "SHA1WITHECDDSA");
@@ -249,22 +273,29 @@
provider.addAlgorithm("Alg.Alias.Signature.SHA384WITHDETECDSA", "SHA384WITHECDDSA");
provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHDETECDSA", "SHA512WITHECDDSA");
- addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224);
- addSignatureAlgorithm(provider, "SHA256", "ECDSA", PREFIX + "SignatureSpi$ecDSA256", X9ObjectIdentifiers.ecdsa_with_SHA256);
- addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384);
- addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512);
- addSignatureAlgorithm(provider, "SHA3-224", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_224", NISTObjectIdentifiers.id_ecdsa_with_sha3_224);
- addSignatureAlgorithm(provider, "SHA3-256", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_256", NISTObjectIdentifiers.id_ecdsa_with_sha3_256);
- addSignatureAlgorithm(provider, "SHA3-384", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_384", NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
- addSignatureAlgorithm(provider, "SHA3-512", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_512", NISTObjectIdentifiers.id_ecdsa_with_sha3_512);
+ addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA256", "ECDSA", PREFIX + "SignatureSpi$ecDSA256", X9ObjectIdentifiers.ecdsa_with_SHA256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-224", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_224", NISTObjectIdentifiers.id_ecdsa_with_sha3_224, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-256", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_256", NISTObjectIdentifiers.id_ecdsa_with_sha3_256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-384", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_384", NISTObjectIdentifiers.id_ecdsa_with_sha3_384, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-512", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_512", NISTObjectIdentifiers.id_ecdsa_with_sha3_512, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHAKE128", "ECDSA", PREFIX + "SignatureSpi$ecDSAShake128", CMSObjectIdentifiers.id_ecdsa_with_shake128, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHAKE256", "ECDSA", PREFIX + "SignatureSpi$ecDSAShake256", CMSObjectIdentifiers.id_ecdsa_with_shake256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "RIPEMD160", "ECDSA", PREFIX + "SignatureSpi$ecDSARipeMD160",TeleTrusTObjectIdentifiers.ecSignWithRipemd160, generalEcAttributes);
- addSignatureAlgorithm(provider, "RIPEMD160", "ECDSA", PREFIX + "SignatureSpi$ecDSARipeMD160",TeleTrusTObjectIdentifiers.ecSignWithRipemd160);
+ provider.addAlgorithm("Signature.SHA1WITHECNR", PREFIX + "SignatureSpi$ecNR", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA224WITHECNR", PREFIX + "SignatureSpi$ecNR224", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA256WITHECNR", PREFIX + "SignatureSpi$ecNR256", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA384WITHECNR", PREFIX + "SignatureSpi$ecNR384", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA512WITHECNR", PREFIX + "SignatureSpi$ecNR512", generalEcAttributes);
- provider.addAlgorithm("Signature.SHA1WITHECNR", PREFIX + "SignatureSpi$ecNR");
- provider.addAlgorithm("Signature.SHA224WITHECNR", PREFIX + "SignatureSpi$ecNR224");
- provider.addAlgorithm("Signature.SHA256WITHECNR", PREFIX + "SignatureSpi$ecNR256");
- provider.addAlgorithm("Signature.SHA384WITHECNR", PREFIX + "SignatureSpi$ecNR384");
- provider.addAlgorithm("Signature.SHA512WITHECNR", PREFIX + "SignatureSpi$ecNR512");
+ addSignatureAlgorithm(provider, "SHA1", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA224", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA224", EACObjectIdentifiers.id_TA_ECDSA_SHA_224, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA256", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA256", EACObjectIdentifiers.id_TA_ECDSA_SHA_256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA384", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA384", EACObjectIdentifiers.id_TA_ECDSA_SHA_384, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA512", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA512", EACObjectIdentifiers.id_TA_ECDSA_SHA_512, generalEcAttributes);
addSignatureAlgorithm(provider, "SHA1", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1);
addSignatureAlgorithm(provider, "SHA224", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA224", EACObjectIdentifiers.id_TA_ECDSA_SHA_224);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EXTERNAL.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EXTERNAL.java
new file mode 100644
index 0000000..eefaa09
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EXTERNAL.java
@@ -0,0 +1,128 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.asymmetric;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.org.bouncycastle.asn1.bc.BCObjectIdentifiers;
+import com.android.org.bouncycastle.asn1.bc.ExternalValue;
+import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.org.bouncycastle.jcajce.ExternalPublicKey;
+import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EXTERNAL
+{
+ private static final String PREFIX = "com.android.org.bouncycastle.jcajce.provider.asymmetric.EXTERNAL";
+
+ private static final Map<String, String> externalAttributes = new HashMap<String, String>();
+
+ static
+ {
+ externalAttributes.put("SupportedKeyClasses", "com.android.org.bouncycastle.jcajce.ExternalPublicKey");
+ externalAttributes.put("SupportedKeyFormats", "X.509");
+ }
+
+ private static AsymmetricKeyInfoConverter baseConverter;
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyFactory
+ extends BaseKeyFactorySpi
+ {
+ protected Key engineTranslateKey(Key key)
+ throws InvalidKeyException
+ {
+ try
+ {
+ if (key instanceof PrivateKey)
+ {
+ return generatePrivate(PrivateKeyInfo.getInstance(key.getEncoded()));
+ }
+ else if (key instanceof PublicKey)
+ {
+ return generatePublic(SubjectPublicKeyInfo.getInstance(key.getEncoded()));
+ }
+ }
+ catch (IOException e)
+ {
+ throw new InvalidKeyException("key could not be parsed: " + e.getMessage());
+ }
+
+ throw new InvalidKeyException("key not recognized");
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePrivate(keyInfo);
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePublic(keyInfo);
+ }
+ }
+
+ private static class ExternalKeyInfoConverter
+ implements AsymmetricKeyInfoConverter
+ {
+ private final ConfigurableProvider provider;
+
+ public ExternalKeyInfoConverter(ConfigurableProvider provider)
+ {
+ this.provider = provider;
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ throw new UnsupportedOperationException("no support for private key");
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ ExternalValue extKey = ExternalValue.getInstance(keyInfo.parsePublicKey());
+
+ // TODO: maybe implement some sort of cache lookup?
+
+ return new ExternalPublicKey(extKey);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyFactory.EXTERNAL", PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory." + BCObjectIdentifiers.external_value, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory.OID." + BCObjectIdentifiers.external_value, PREFIX + "$KeyFactory");
+
+ baseConverter = new ExternalKeyInfoConverter(provider);
+
+ provider.addKeyInfoConverter(BCObjectIdentifiers.external_value, baseConverter);
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/LMS.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/LMS.java
new file mode 100644
index 0000000..07b87da
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/LMS.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.asymmetric;
+
+import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class LMS
+{
+ private static final String PREFIX = "com.android.org.bouncycastle.pqc.jcajce.provider" + ".lms.";
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyFactory.LMS", PREFIX + "LMSKeyFactorySpi");
+ provider.addAlgorithm("Alg.Alias.KeyFactory." + PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, "LMS");
+
+ provider.addAlgorithm("KeyPairGenerator.LMS", PREFIX + "LMSKeyPairGeneratorSpi");
+ provider.addAlgorithm("Alg.Alias.KeyPairGenerator." + PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, "LMS");
+
+ provider.addAlgorithm("Signature.LMS", PREFIX + "LMSSignatureSpi$generic");
+ provider.addAlgorithm("Alg.Alias.Signature." + PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, "LMS");
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/RSA.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
index c4a0400..7c44e45 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
@@ -11,6 +11,7 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.cms.CMSObjectIdentifiers;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi;
import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
@@ -27,7 +28,7 @@
static
{
- generalRsaAttributes.put("SupportedKeyClasses", "javax.crypto.interfaces.RSAPublicKey|javax.crypto.interfaces.RSAPrivateKey");
+ generalRsaAttributes.put("SupportedKeyClasses", "java.security.interfaces.RSAPublicKey|java.security.interfaces.RSAPrivateKey");
generalRsaAttributes.put("SupportedKeyFormats", "PKCS#8|X.509");
}
@@ -80,8 +81,8 @@
// BEGIN Android-removed: Unsupported algorithms
/*
provider.addAlgorithm("Cipher.RSA/PKCS1", PREFIX + "CipherSpi$PKCS1v1_5Padding");
- provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.rsaEncryption, PREFIX + "CipherSpi$PKCS1v1_5Padding");
- provider.addAlgorithm("Cipher", X509ObjectIdentifiers.id_ea_rsa, PREFIX + "CipherSpi$PKCS1v1_5Padding");
+ provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.rsaEncryption, PREFIX + "CipherSpi$PKCS1v1_5Padding", generalRsaAttributes);
+ provider.addAlgorithm("Cipher", X509ObjectIdentifiers.id_ea_rsa, PREFIX + "CipherSpi$PKCS1v1_5Padding", generalRsaAttributes);
provider.addAlgorithm("Cipher.RSA/1", PREFIX + "CipherSpi$PKCS1v1_5Padding_PrivateOnly");
provider.addAlgorithm("Cipher.RSA/2", PREFIX + "CipherSpi$PKCS1v1_5Padding_PublicOnly");
provider.addAlgorithm("Cipher.RSA/OAEP", PREFIX + "CipherSpi$OAEPPadding");
@@ -122,12 +123,12 @@
registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSAES_OAEP, "OAEP");
registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSASSA_PSS, "PSS");
- provider.addAlgorithm("Signature.RSASSA-PSS", PREFIX + "PSSSignatureSpi$PSSwithRSA");
- provider.addAlgorithm("Signature." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA");
- provider.addAlgorithm("Signature.OID." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA");
+ provider.addAlgorithm("Signature.RSASSA-PSS", PREFIX + "PSSSignatureSpi$PSSwithRSA", generalRsaAttributes);
+ provider.addAlgorithm("Alg.Alias.Signature." + PKCSObjectIdentifiers.id_RSASSA_PSS, "RSASSA-PSS");
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + PKCSObjectIdentifiers.id_RSASSA_PSS, "RSASSA-PSS");
- provider.addAlgorithm("Signature.RSA", PREFIX + "DigestSignatureSpi$noneRSA");
- provider.addAlgorithm("Signature.RAWRSASSA-PSS", PREFIX + "PSSSignatureSpi$nonePSS");
+ provider.addAlgorithm("Signature.RSA", PREFIX + "DigestSignatureSpi$noneRSA", generalRsaAttributes);
+ provider.addAlgorithm("Signature.RAWRSASSA-PSS", PREFIX + "PSSSignatureSpi$nonePSS", generalRsaAttributes);
provider.addAlgorithm("Alg.Alias.Signature.RAWRSA", "RSA");
provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSA", "RSA");
@@ -137,17 +138,43 @@
provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSAANDMGF1", "RAWRSASSA-PSS");
provider.addAlgorithm("Alg.Alias.Signature.RSAPSS", "RSASSA-PSS");
- addPSSSignature(provider, "SHA224", PREFIX + "PSSSignatureSpi$SHA224withRSA");
- addPSSSignature(provider, "SHA256", PREFIX + "PSSSignatureSpi$SHA256withRSA");
- addPSSSignature(provider, "SHA384", PREFIX + "PSSSignatureSpi$SHA384withRSA");
- addPSSSignature(provider, "SHA512", PREFIX + "PSSSignatureSpi$SHA512withRSA");
- addPSSSignature(provider, "SHA512(224)", PREFIX + "PSSSignatureSpi$SHA512_224withRSA");
- addPSSSignature(provider, "SHA512(256)", PREFIX + "PSSSignatureSpi$SHA512_256withRSA");
+ addPSSSignature(provider, "SHA224", "MGF1", PREFIX + "PSSSignatureSpi$SHA224withRSA");
+ addPSSSignature(provider, "SHA256", "MGF1", PREFIX + "PSSSignatureSpi$SHA256withRSA");
+ addPSSSignature(provider, "SHA384", "MGF1", PREFIX + "PSSSignatureSpi$SHA384withRSA");
+ addPSSSignature(provider, "SHA512", "MGF1", PREFIX + "PSSSignatureSpi$SHA512withRSA");
+ addPSSSignature(provider, "SHA512(224)", "MGF1", PREFIX + "PSSSignatureSpi$SHA512_224withRSA");
+ addPSSSignature(provider, "SHA512(256)", "MGF1", PREFIX + "PSSSignatureSpi$SHA512_256withRSA");
- addPSSSignature(provider, "SHA3-224", PREFIX + "PSSSignatureSpi$SHA3_224withRSA");
- addPSSSignature(provider, "SHA3-256", PREFIX + "PSSSignatureSpi$SHA3_256withRSA");
- addPSSSignature(provider, "SHA3-384", PREFIX + "PSSSignatureSpi$SHA3_384withRSA");
- addPSSSignature(provider, "SHA3-512", PREFIX + "PSSSignatureSpi$SHA3_512withRSA");
+ addPSSSignature(provider, "SHA3-224", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_224withRSA");
+ addPSSSignature(provider, "SHA3-256", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_256withRSA");
+ addPSSSignature(provider, "SHA3-384", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_384withRSA");
+ addPSSSignature(provider, "SHA3-512", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_512withRSA");
+ addPSSSignature(provider, "SHAKE128", PREFIX + "PSSSignatureSpi$SHAKE128WithRSAPSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128);
+ addPSSSignature(provider, "SHAKE256", PREFIX + "PSSSignatureSpi$SHAKE256WithRSAPSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256);
+
+ addPSSSignature(provider, "SHA224", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA224withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA256", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA256withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA384", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA384withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA512", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA512withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA512(224)", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA512_224withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA512(256)", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA512_256withRSAandSHAKE128");
+
+ addPSSSignature(provider, "SHA224", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA224withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA256", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA256withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA384", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA384withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA512", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA512withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA512(224)", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA512_224withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA512(256)", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA512_256withRSAandSHAKE256");
+
+ addPSSSignature(provider, "SHA3-224", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_224withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA3-256", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_256withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA3-384", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_384withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA3-512", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_512withRSAandSHAKE128");
+
+ addPSSSignature(provider, "SHA3-224", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_224withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA3-256", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_256withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA3-384", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_384withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA3-512", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_512withRSAandSHAKE256");
if (provider.hasAlgorithm("MessageDigest", "MD2"))
{
@@ -170,7 +197,9 @@
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1withRSA/PSS", "PSS");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1WITHRSAANDMGF1", "PSS");
- addPSSSignature(provider, "SHA1", PREFIX + "PSSSignatureSpi$SHA1withRSA");
+ addPSSSignature(provider, "SHA1", "MGF1", PREFIX + "PSSSignatureSpi$SHA1withRSA");
+ addPSSSignature(provider, "SHA1", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA1withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA1", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA1withRSAandSHAKE256");
addDigestSignature(provider, "SHA1", PREFIX + "DigestSignatureSpi$SHA1", PKCSObjectIdentifiers.sha1WithRSAEncryption);
addISO9796Signature(provider, "SHA1", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption");
@@ -270,6 +299,7 @@
provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
}
+ provider.addAttributes("Signature." + mainName, generalRsaAttributes);
}
private void addISO9796Signature(
@@ -280,12 +310,37 @@
provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/ISO9796-2", digest + "WITHRSA/ISO9796-2");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/ISO9796-2", digest + "WITHRSA/ISO9796-2");
provider.addAlgorithm("Signature." + digest + "WITHRSA/ISO9796-2", className);
+ provider.addAttributes("Signature." + digest + "WITHRSA/ISO9796-2", generalRsaAttributes);
+ }
+
+ private void addPSSSignature(
+ ConfigurableProvider provider,
+ String digest, String mgf,
+ String className)
+ {
+ String stem = "WITHRSAAND" + mgf;
+ if (mgf.equals("MGF1"))
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WITHRSA/PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSASSA-PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSASSA-PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WITHRSASSA-PSS", digest + stem);
+ }
+
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSAand" + mgf, digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSAAnd" + mgf, digest + stem);
+
+ provider.addAlgorithm("Signature." + digest + "WITHRSAAND" + mgf, className);
+ provider.addAttributes("Signature." + digest + "WITHRSAAND" + mgf, generalRsaAttributes);
}
private void addPSSSignature(
ConfigurableProvider provider,
String digest,
- String className)
+ String className,
+ ASN1ObjectIdentifier sigOid)
{
provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/PSS", digest + "WITHRSAANDMGF1");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/PSS", digest + "WITHRSAANDMGF1");
@@ -306,6 +361,7 @@
provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/X9.31", digest + "WITHRSA/X9.31");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/X9.31", digest + "WITHRSA/X9.31");
provider.addAlgorithm("Signature." + digest + "WITHRSA/X9.31", className);
+ provider.addAttributes("Signature." + digest + "WITHRSA/X9.31", generalRsaAttributes);
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
index 9e812a6..8463920 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
@@ -41,6 +41,7 @@
// import org.bouncycastle.jcajce.spec.DHUParameterSpec;
// import org.bouncycastle.jcajce.spec.MQVParameterSpec;
import com.android.org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec;
+import com.android.org.bouncycastle.util.BigIntegers;
/**
* Diffie-Hellman key agreement. There's actually a better way of doing this
@@ -117,30 +118,9 @@
//
int expectedLength = (p.bitLength() + 7) / 8;
- byte[] tmp = r.toByteArray();
-
- if (tmp.length == expectedLength)
- {
- return tmp;
- }
-
- if (tmp[0] == 0 && tmp.length == expectedLength + 1)
- {
- byte[] rv = new byte[tmp.length - 1];
-
- System.arraycopy(tmp, 1, rv, 0, rv.length);
- return rv;
- }
-
- // tmp must be shorter than expectedLength
- // pad to the left with zeros.
- byte[] rv = new byte[expectedLength];
-
- System.arraycopy(tmp, 0, rv, rv.length - tmp.length, tmp.length);
-
- return rv;
+ return BigIntegers.asUnsignedByteArray(expectedLength, r);
}
-
+
protected Key engineDoPhase(
Key key,
boolean lastPhase)
@@ -268,7 +248,7 @@
return super.engineGenerateSecret(algorithm);
}
- protected void engineInit(
+ protected void doInitFromKey(
Key key,
AlgorithmParameterSpec params,
SecureRandom random)
@@ -387,7 +367,7 @@
this.result = bigIntToBytes(x);
}
- protected byte[] calcSecret()
+ protected byte[] doCalcSecret()
{
return result;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java
index 3655de0..b6647e8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java
@@ -71,7 +71,7 @@
}
else
{
- pGen = new DSAParametersGenerator(new SHA256Digest());
+ pGen = new DSAParametersGenerator(SHA256Digest.newInstance());
}
if (random == null)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
index c7e20d2..0275b58 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
@@ -1,6 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.jcajce.provider.asymmetric.dsa;
+package com.android.org.bouncycastle.jcajce.provider.asymmetric.dsa;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
@@ -10,7 +10,6 @@
import java.security.SignatureException;
import java.security.SignatureSpi;
import java.security.spec.AlgorithmParameterSpec;
-
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import com.android.org.bouncycastle.crypto.CipherParameters;
@@ -29,7 +28,6 @@
// import org.bouncycastle.crypto.util.DigestFactory;
import com.android.org.bouncycastle.crypto.digests.AndroidDigestFactory;
import com.android.org.bouncycastle.util.Arrays;
-
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -41,7 +39,6 @@
private DSAExt signer;
private DSAEncoding encoding = StandardDSAEncoding.INSTANCE;
private SecureRandom random;
-
protected DSASigner(
Digest digest,
DSAExt signer)
@@ -49,17 +46,14 @@
this.digest = digest;
this.signer = signer;
}
-
protected void engineInitVerify(
PublicKey publicKey)
throws InvalidKeyException
{
CipherParameters param = DSAUtil.generatePublicKeyParameter(publicKey);
-
digest.reset();
signer.init(false, param);
}
-
protected void engineInitSign(
PrivateKey privateKey,
SecureRandom random)
@@ -68,53 +62,43 @@
this.random = random;
engineInitSign(privateKey);
}
-
protected void engineInitSign(
PrivateKey privateKey)
throws InvalidKeyException
{
CipherParameters param = DSAUtil.generatePrivateKeyParameter(privateKey);
-
// Android-added: Check DSA keys when generated
DSAParameters dsaParam = ((DSAKeyParameters) param).getParameters();
checkKey(dsaParam);
-
if (random != null)
{
param = new ParametersWithRandom(param, random);
}
-
digest.reset();
signer.init(true, param);
}
-
protected void engineUpdate(
byte b)
throws SignatureException
{
digest.update(b);
}
-
protected void engineUpdate(
byte[] b,
int off,
- int len)
+ int len)
throws SignatureException
{
digest.update(b, off, len);
}
-
protected byte[] engineSign()
throws SignatureException
{
byte[] hash = new byte[digest.getDigestSize()];
-
digest.doFinal(hash, 0);
-
try
{
BigInteger[] sig = signer.generateSignature(hash);
-
return encoding.encode(signer.getOrder(), sig[0], sig[1]);
}
catch (Exception e)
@@ -122,17 +106,13 @@
throw new SignatureException(e.toString());
}
}
-
protected boolean engineVerify(
- byte[] sigBytes)
+ byte[] sigBytes)
throws SignatureException
{
byte[] hash = new byte[digest.getDigestSize()];
-
digest.doFinal(hash, 0);
-
BigInteger[] sig;
-
try
{
sig = encoding.decode(signer.getOrder(), sigBytes);
@@ -141,27 +121,22 @@
{
throw new SignatureException("error decoding signature bytes.");
}
-
return signer.verifySignature(hash, sig[0], sig[1]);
}
-
protected AlgorithmParameters engineGetParameters()
{
return null;
}
-
protected void engineSetParameter(
AlgorithmParameterSpec params)
{
throw new UnsupportedOperationException("engineSetParameter unsupported");
}
-
// BEGIN Android-added: Check DSA keys when generated
protected void checkKey(DSAParameters params) throws InvalidKeyException {
int valueL = params.getP().bitLength();
int valueN = params.getQ().bitLength();
int digestSize = digest.getDigestSize();
-
// The checks are consistent with DSAParametersGenerator's init method.
if ((valueL < 1024 || valueL > 3072) || valueL % 1024 != 0) {
throw new InvalidKeyException("valueL values must be between 1024 and 3072 and a multiple of 1024");
@@ -176,7 +151,6 @@
throw new InvalidKeyException("Key is too strong for this signature algorithm");
}
}
-
// END Android-added: Check DSA keys when generated
/**
* @deprecated replaced with #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
@@ -187,7 +161,6 @@
{
throw new UnsupportedOperationException("engineSetParameter unsupported");
}
-
/**
* @deprecated
*/
@@ -196,7 +169,6 @@
{
throw new UnsupportedOperationException("engineGetParameter unsupported");
}
-
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -210,7 +182,6 @@
super(AndroidDigestFactory.getSHA1(), new com.android.org.bouncycastle.crypto.signers.DSASigner());
}
}
-
// BEGIN Android-removed: Unsupported algorithm
/*
static public class detDSA
@@ -221,6 +192,14 @@
super(DigestFactory.createSHA1(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA1())));
}
}
+ static public class dsaRMD160
+ extends DSASigner
+ {
+ public dsaRMD160()
+ {
+ super(new RIPEMD160Digest(), new org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
*/
// END Android-removed: Unsupported algorithm
@@ -237,7 +216,6 @@
super(AndroidDigestFactory.getSHA224(), new com.android.org.bouncycastle.crypto.signers.DSASigner());
}
}
-
// BEGIN Android-removed: Unsupported algorithm
/*
static public class detDSA224
@@ -250,7 +228,6 @@
}
*/
// END Android-removed: Unsupported algorithm
-
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -264,7 +241,6 @@
super(AndroidDigestFactory.getSHA256(), new com.android.org.bouncycastle.crypto.signers.DSASigner());
}
}
-
// BEGIN Android-removed: Unsupported algorithms
/*
static public class detDSA256
@@ -275,7 +251,6 @@
super(DigestFactory.createSHA256(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA256())));
}
}
-
static public class dsa384
extends DSASigner
{
@@ -284,7 +259,6 @@
super(DigestFactory.createSHA384(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSA384
extends DSASigner
{
@@ -293,7 +267,6 @@
super(DigestFactory.createSHA384(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA384())));
}
}
-
static public class dsa512
extends DSASigner
{
@@ -302,7 +275,6 @@
super(DigestFactory.createSHA512(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSA512
extends DSASigner
{
@@ -311,7 +283,6 @@
super(DigestFactory.createSHA512(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA512())));
}
}
-
static public class dsaSha3_224
extends DSASigner
{
@@ -320,7 +291,6 @@
super(DigestFactory.createSHA3_224(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_224
extends DSASigner
{
@@ -329,7 +299,6 @@
super(DigestFactory.createSHA3_224(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_224())));
}
}
-
static public class dsaSha3_256
extends DSASigner
{
@@ -338,7 +307,6 @@
super(DigestFactory.createSHA3_256(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_256
extends DSASigner
{
@@ -347,7 +315,6 @@
super(DigestFactory.createSHA3_256(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_256())));
}
}
-
static public class dsaSha3_384
extends DSASigner
{
@@ -356,7 +323,6 @@
super(DigestFactory.createSHA3_384(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_384
extends DSASigner
{
@@ -365,7 +331,6 @@
super(DigestFactory.createSHA3_384(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_384())));
}
}
-
static public class dsaSha3_512
extends DSASigner
{
@@ -374,7 +339,6 @@
super(DigestFactory.createSHA3_512(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_512
extends DSASigner
{
@@ -385,7 +349,6 @@
}
*/
// END Android-removed: Unsupported algorithms
-
/**
* @hide This class is not part of the Android public SDK API
*/
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
index 6ff1651..96e1904 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
@@ -152,7 +152,7 @@
else if (strength > 1024)
{
dsaParams = new DSAParameterGenerationParameters(strength, 256, certainty, random);
- pGen = new DSAParametersGenerator(new SHA256Digest());
+ pGen = new DSAParametersGenerator(SHA256Digest.newInstance());
pGen.init(dsaParams);
}
else
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
index a1f852f..76a15d8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
@@ -16,6 +16,7 @@
import com.android.org.bouncycastle.asn1.x9.X9ECPoint;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.org.bouncycastle.jce.spec.ECNamedCurveSpec;
import com.android.org.bouncycastle.math.ec.ECCurve;
@@ -41,12 +42,14 @@
if (algorithmParameterSpec instanceof ECGenParameterSpec)
{
ECGenParameterSpec ecGenParameterSpec = (ECGenParameterSpec)algorithmParameterSpec;
- X9ECParameters params = ECUtils.getDomainParametersFromGenSpec(ecGenParameterSpec);
+ ProviderConfiguration configuration = BouncyCastleProvider.CONFIGURATION;
- if (params == null)
+ X9ECParameters params = ECUtils.getDomainParametersFromGenSpec(ecGenParameterSpec, configuration);
+ if (null == params)
{
throw new InvalidParameterSpecException("EC curve name not recognized: " + ecGenParameterSpec.getName());
}
+
curveName = ecGenParameterSpec.getName();
ECParameterSpec baseSpec = EC5Util.convertToSpec(params);
ecParameterSpec = new ECNamedCurveSpec(curveName,
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
index ced733f..ddc8420 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
@@ -11,18 +11,20 @@
import java.security.spec.EllipticCurve;
import java.util.Enumeration;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.org.bouncycastle.asn1.x9.ECNamedCurveTable;
import com.android.org.bouncycastle.asn1.x9.X962Parameters;
import com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.org.bouncycastle.crypto.params.ECNamedDomainParameters;
import com.android.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
@@ -31,7 +33,9 @@
import com.android.org.bouncycastle.jce.interfaces.ECPointEncoder;
import com.android.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import com.android.org.bouncycastle.math.ec.ECCurve;
+import com.android.org.bouncycastle.util.Arrays;
/**
* @hide This class is not part of the Android public SDK API
@@ -41,16 +45,20 @@
{
static final long serialVersionUID = 994553197664784084L;
- private String algorithm = "EC";
- private boolean withCompression;
+ private String algorithm = "EC";
+ private boolean withCompression;
- private transient BigInteger d;
- private transient ECParameterSpec ecSpec;
- private transient ProviderConfiguration configuration;
- private transient DERBitString publicKey;
+ private transient BigInteger d;
+ private transient ECParameterSpec ecSpec;
+ private transient ProviderConfiguration configuration;
+ private transient ASN1BitString publicKey;
+ private transient PrivateKeyInfo privateKeyInfo;
+ private transient byte[] encoding;
+ private transient ECPrivateKeyParameters baseKey;
private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
protected BCECPrivateKey()
{
}
@@ -63,6 +71,7 @@
this.algorithm = key.getAlgorithm();
this.ecSpec = key.getParams();
this.configuration = configuration;
+ this.baseKey = convertToBaseKey(this);
}
public BCECPrivateKey(
@@ -88,6 +97,7 @@
}
this.configuration = configuration;
+ this.baseKey = convertToBaseKey(this);
}
@@ -100,6 +110,7 @@
this.d = spec.getS();
this.ecSpec = spec.getParams();
this.configuration = configuration;
+ this.baseKey = convertToBaseKey(this);
}
public BCECPrivateKey(
@@ -113,6 +124,7 @@
this.attrCarrier = key.attrCarrier;
this.publicKey = key.publicKey;
this.configuration = key.configuration;
+ this.baseKey = key.baseKey;
}
public BCECPrivateKey(
@@ -125,6 +137,7 @@
this.algorithm = algorithm;
this.d = params.getD();
this.configuration = configuration;
+ this.baseKey = params;
if (spec == null)
{
@@ -155,6 +168,7 @@
this.algorithm = algorithm;
this.d = params.getD();
this.configuration = configuration;
+ this.baseKey = params;
if (spec == null)
{
@@ -193,10 +207,11 @@
this.d = params.getD();
this.ecSpec = null;
this.configuration = configuration;
+ this.baseKey = params;
}
BCECPrivateKey(
- String algorithm,
+ String algorithm,
PrivateKeyInfo info,
ProviderConfiguration configuration)
throws IOException
@@ -217,7 +232,7 @@
ASN1Encodable privKey = info.parsePrivateKey();
if (privKey instanceof ASN1Integer)
{
- ASN1Integer derD = ASN1Integer.getInstance(privKey);
+ ASN1Integer derD = ASN1Integer.getInstance(privKey);
this.d = derD.getValue();
}
@@ -228,6 +243,7 @@
this.d = ec.getKey();
this.publicKey = ec.getPublicKey();
}
+ this.baseKey = convertToBaseKey(this);
}
public String getAlgorithm()
@@ -253,40 +269,71 @@
*/
public byte[] getEncoded()
{
- X962Parameters params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
+ if (encoding == null)
+ {
+ PrivateKeyInfo info = getPrivateKeyInfo();
- int orderBitLength;
- if (ecSpec == null)
- {
- orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS());
- }
- else
- {
- orderBitLength = ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS());
- }
-
- PrivateKeyInfo info;
- com.android.org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
+ if (info == null)
+ {
+ return null;
+ }
- if (publicKey != null)
- {
- keyStructure = new com.android.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params);
- }
- else
- {
- keyStructure = new com.android.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
+ try
+ {
+ encoding = info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
}
- try
- {
- info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure);
+ return Arrays.clone(encoding);
+ }
- return info.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
+ private PrivateKeyInfo getPrivateKeyInfo()
+ {
+ if (privateKeyInfo == null)
{
- return null;
+ X962Parameters params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
+
+ int orderBitLength;
+ if (ecSpec == null)
+ {
+ orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS());
+ }
+ else
+ {
+ orderBitLength = ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS());
+ }
+
+ com.android.org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
+
+ if (publicKey != null)
+ {
+ keyStructure = new com.android.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params);
+ }
+ else
+ {
+ keyStructure = new com.android.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
+ }
+
+ try
+ {
+ privateKeyInfo = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
}
+
+ return privateKeyInfo;
+ }
+
+ public ECPrivateKeyParameters engineGetKeyParameters()
+ {
+ return baseKey;
}
public ECParameterSpec getParams()
@@ -300,7 +347,6 @@
{
return null;
}
-
return EC5Util.convertSpec(ecSpec);
}
@@ -323,10 +369,10 @@
{
return d;
}
-
+
public void setBagAttribute(
ASN1ObjectIdentifier oid,
- ASN1Encodable attribute)
+ ASN1Encodable attribute)
{
attrCarrier.setBagAttribute(oid, attribute);
}
@@ -344,19 +390,37 @@
public void setPointFormat(String style)
{
- withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
}
public boolean equals(Object o)
{
- if (!(o instanceof BCECPrivateKey))
+ if (o instanceof ECPrivateKey)
{
- return false;
+ ECPrivateKey other = (ECPrivateKey)o;
+
+ PrivateKeyInfo info = this.getPrivateKeyInfo();
+ PrivateKeyInfo otherInfo = (other instanceof BCECPrivateKey) ? ((BCECPrivateKey)other).getPrivateKeyInfo() : PrivateKeyInfo.getInstance(other.getEncoded());
+
+ if (info == null || otherInfo == null)
+ {
+ return false;
+ }
+
+ try
+ {
+ boolean algEquals = Arrays.constantTimeAreEqual(info.getPrivateKeyAlgorithm().getEncoded(), otherInfo.getPrivateKeyAlgorithm().getEncoded());
+ boolean keyEquals = Arrays.constantTimeAreEqual(this.getS().toByteArray(), other.getS().toByteArray());
+
+ return algEquals & keyEquals;
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
}
- BCECPrivateKey other = (BCECPrivateKey)o;
-
- return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec()));
+ return false;
}
public int hashCode()
@@ -369,7 +433,7 @@
return ECUtil.privateKeyToString("EC", d, engineGetSpec());
}
- private DERBitString getPublicKeyDetails(BCECPublicKey pub)
+ private ASN1BitString getPublicKeyDetails(BCECPublicKey pub)
{
try
{
@@ -406,4 +470,31 @@
out.writeObject(this.getEncoded());
}
+
+ private static ECPrivateKeyParameters convertToBaseKey(BCECPrivateKey key)
+ {
+ com.android.org.bouncycastle.jce.interfaces.ECPrivateKey k = (com.android.org.bouncycastle.jce.interfaces.ECPrivateKey)key;
+ com.android.org.bouncycastle.jce.spec.ECParameterSpec s = k.getParameters();
+
+ if (s == null)
+ {
+ s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+ }
+
+ if (k.getParameters() instanceof ECNamedCurveParameterSpec)
+ {
+ String name = ((ECNamedCurveParameterSpec)k.getParameters()).getName();
+ if (name != null)
+ {
+ return new ECPrivateKeyParameters(
+ k.getD(),
+ new ECNamedDomainParameters(ECNamedCurveTable.getOID(name),
+ s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
+ }
+ }
+
+ return new ECPrivateKeyParameters(
+ k.getD(),
+ new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
index 94e7415..db8fb19 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
@@ -10,9 +10,9 @@
import java.security.spec.ECPublicKeySpec;
import java.security.spec.EllipticCurve;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DEROctetString;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
@@ -29,6 +29,7 @@
import com.android.org.bouncycastle.jce.interfaces.ECPointEncoder;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.org.bouncycastle.math.ec.ECCurve;
+import com.android.org.bouncycastle.util.Arrays;
import com.android.org.bouncycastle.util.Properties;
/**
@@ -45,6 +46,8 @@
private transient ECPublicKeyParameters ecPublicKey;
private transient ECParameterSpec ecSpec;
private transient ProviderConfiguration configuration;
+ private transient byte[] encoding;
+ private transient boolean oldPcSet;
public BCECPublicKey(
String algorithm,
@@ -197,7 +200,7 @@
ECCurve curve = EC5Util.getCurve(configuration, params);
ecSpec = EC5Util.convertToSpec(params, curve);
- DERBitString bits = info.getPublicKeyData();
+ ASN1BitString bits = info.getPublicKeyData();
byte[] data = bits.getBytes();
ASN1OctetString key = new DEROctetString(data);
@@ -239,16 +242,23 @@
public byte[] getEncoded()
{
- boolean compress = withCompression || Properties.isOverrideSet("com.android.org.bouncycastle.ec.enable_pc");
+ boolean pcSet = Properties.isOverrideSet("com.android.org.bouncycastle.ec.enable_pc");
+ if (encoding == null || oldPcSet != pcSet)
+ {
+ boolean compress = withCompression || pcSet;
- AlgorithmIdentifier algId = new AlgorithmIdentifier(
- X9ObjectIdentifiers.id_ecPublicKey,
- ECUtils.getDomainParametersFromName(ecSpec, compress));
+ AlgorithmIdentifier algId = new AlgorithmIdentifier(
+ X9ObjectIdentifiers.id_ecPublicKey,
+ ECUtils.getDomainParametersFromName(ecSpec, compress));
- byte[] pubKeyOctets = ecPublicKey.getQ().getEncoded(compress);
+ byte[] pubKeyOctets = ecPublicKey.getQ().getEncoded(compress);
- // stored curve is null if ImplicitlyCa
- return KeyUtil.getEncodedSubjectPublicKeyInfo(algId, pubKeyOctets);
+ // stored curve is null if ImplicitlyCa
+ encoding = KeyUtil.getEncodedSubjectPublicKeyInfo(algId, pubKeyOctets);
+ oldPcSet = pcSet;
+ }
+
+ return Arrays.clone(encoding);
}
public ECParameterSpec getParams()
@@ -306,18 +316,26 @@
public void setPointFormat(String style)
{
withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ encoding = null;
}
public boolean equals(Object o)
{
- if (!(o instanceof BCECPublicKey))
+ if (o instanceof BCECPublicKey)
{
- return false;
+ BCECPublicKey other = (BCECPublicKey)o;
+
+ return ecPublicKey.getQ().equals(other.ecPublicKey.getQ()) && (engineGetSpec().equals(other.engineGetSpec()));
}
- BCECPublicKey other = (BCECPublicKey)o;
+ if (o instanceof ECPublicKey)
+ {
+ ECPublicKey other = (ECPublicKey)o;
- return ecPublicKey.getQ().equals(other.ecPublicKey.getQ()) && (engineGetSpec().equals(other.engineGetSpec()));
+ return Arrays.areEqual(getEncoded(), other.getEncoded());
+ }
+
+ return false;
}
public int hashCode()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
index 99bdedb..3cb1f10 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
@@ -3,9 +3,11 @@
import java.math.BigInteger;
import java.security.InvalidKeyException;
+import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
+import java.util.Map;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.DERNull;
@@ -15,6 +17,7 @@
import com.android.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import com.android.org.bouncycastle.jce.spec.ECNamedCurveSpec;
import com.android.org.bouncycastle.math.ec.ECCurve;
@@ -27,39 +30,49 @@
return (key instanceof BCECPublicKey) ? ((BCECPublicKey)key).engineGetKeyParameters() : ECUtil.generatePublicKeyParameter(key);
}
- static X9ECParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec)
+ static AsymmetricKeyParameter generatePrivateKeyParameter(
+ PrivateKey key)
+ throws InvalidKeyException
{
- return getDomainParametersFromName(genSpec.getName());
+ return (key instanceof BCECPrivateKey) ? ((BCECPrivateKey)key).engineGetKeyParameters() : ECUtil.generatePrivateKeyParameter(key);
}
- static X9ECParameters getDomainParametersFromName(String curveName)
+ static X9ECParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec, ProviderConfiguration configuration)
{
- X9ECParameters domainParameters;
- try
+ return getDomainParametersFromName(genSpec.getName(), configuration);
+ }
+
+ static X9ECParameters getDomainParametersFromName(String curveName, ProviderConfiguration configuration)
+ {
+ if (null == curveName || curveName.length() < 1)
{
- if (curveName.charAt(0) >= '0' && curveName.charAt(0) <= '2')
+ return null;
+ }
+
+ int spacePos = curveName.indexOf(' ');
+ if (spacePos > 0)
+ {
+ curveName = curveName.substring(spacePos + 1);
+ }
+
+ ASN1ObjectIdentifier oid = getOID(curveName);
+ if (null == oid)
+ {
+ return ECUtil.getNamedCurveByName(curveName);
+ }
+
+ X9ECParameters x9 = ECUtil.getNamedCurveByOid(oid);
+ if (null == x9)
+ {
+ if (null != configuration)
{
- ASN1ObjectIdentifier oidID = new ASN1ObjectIdentifier(curveName);
- domainParameters = ECUtil.getNamedCurveByOid(oidID);
- }
- else
- {
- if (curveName.indexOf(' ') > 0)
- {
- curveName = curveName.substring(curveName.indexOf(' ') + 1);
- domainParameters = ECUtil.getNamedCurveByName(curveName);
- }
- else
- {
- domainParameters = ECUtil.getNamedCurveByName(curveName);
- }
+ Map extraCurves = configuration.getAdditionalECParameters();
+
+ x9 = (X9ECParameters)extraCurves.get(oid);
}
}
- catch (IllegalArgumentException ex)
- {
- domainParameters = ECUtil.getNamedCurveByName(curveName);
- }
- return domainParameters;
+
+ return x9;
}
static X962Parameters getDomainParametersFromName(ECParameterSpec ecSpec, boolean withCompression)
@@ -95,4 +108,20 @@
return params;
}
+
+ private static ASN1ObjectIdentifier getOID(String curveName)
+ {
+ char firstChar = curveName.charAt(0);
+ if (firstChar >= '0' && firstChar <= '2')
+ {
+ try
+ {
+ return new ASN1ObjectIdentifier(curveName);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ return null;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java
new file mode 100644
index 0000000..1cbf0a8
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java
@@ -0,0 +1,259 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.util.Hashtable;
+
+import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.org.bouncycastle.crypto.generators.ECKeyPairGenerator;
+import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.org.bouncycastle.crypto.params.ECKeyGenerationParameters;
+import com.android.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
+import com.android.org.bouncycastle.jce.spec.ECNamedCurveSpec;
+import com.android.org.bouncycastle.jce.spec.ECParameterSpec;
+import com.android.org.bouncycastle.math.ec.ECCurve;
+import com.android.org.bouncycastle.math.ec.ECPoint;
+import com.android.org.bouncycastle.util.Integers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class GMKeyPairGeneratorSpi
+ extends java.security.KeyPairGenerator
+{
+ public GMKeyPairGeneratorSpi(String algorithmName)
+ {
+ super(algorithmName);
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class BaseSM2
+ extends GMKeyPairGeneratorSpi
+ {
+ ECKeyGenerationParameters param;
+ ECKeyPairGenerator engine = new ECKeyPairGenerator();
+ Object ecParams = null;
+ int strength = 239;
+ SecureRandom random = CryptoServicesRegistrar.getSecureRandom();
+ boolean initialised = false;
+ String algorithm;
+ ProviderConfiguration configuration;
+
+ static private Hashtable ecParameters;
+
+ static
+ {
+ ecParameters = new Hashtable();
+
+ ecParameters.put(Integers.valueOf(192), new ECNamedCurveGenParameterSpec("prime192v1")); // a.k.a P-192
+ ecParameters.put(Integers.valueOf(239), new ECNamedCurveGenParameterSpec("prime239v1"));
+ ecParameters.put(Integers.valueOf(256), new ECNamedCurveGenParameterSpec("prime256v1")); // a.k.a P-256
+
+ ecParameters.put(Integers.valueOf(224), new ECNamedCurveGenParameterSpec("P-224"));
+ ecParameters.put(Integers.valueOf(384), new ECNamedCurveGenParameterSpec("P-384"));
+ ecParameters.put(Integers.valueOf(521), new ECNamedCurveGenParameterSpec("P-521"));
+ }
+
+ public BaseSM2()
+ {
+ super("EC");
+ this.algorithm = "EC";
+ this.configuration = BouncyCastleProvider.CONFIGURATION;
+ }
+
+ public BaseSM2(
+ String algorithm,
+ ProviderConfiguration configuration)
+ {
+ super(algorithm);
+ this.algorithm = algorithm;
+ this.configuration = configuration;
+ }
+
+ public void initialize(
+ int strength,
+ SecureRandom random)
+ {
+ this.strength = strength;
+ this.random = random;
+
+ ECNamedCurveGenParameterSpec ecParams = (ECNamedCurveGenParameterSpec)ecParameters.get(Integers.valueOf(strength));
+ if (ecParams == null)
+ {
+ throw new InvalidParameterException("unknown key size.");
+ }
+
+ try
+ {
+ initialize(ecParams, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ throw new InvalidParameterException("key size not configurable.");
+ }
+ }
+
+ public void initialize(
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ if (params == null)
+ {
+ ECParameterSpec implicitCA = configuration.getEcImplicitlyCa();
+ if (implicitCA == null)
+ {
+ throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set");
+ }
+
+ this.ecParams = null;
+ this.param = createKeyGenParamsBC(implicitCA, random);
+ }
+ else if (params instanceof ECParameterSpec)
+ {
+ this.ecParams = params;
+ this.param = createKeyGenParamsBC((ECParameterSpec)params, random);
+ }
+ else if (params instanceof java.security.spec.ECParameterSpec)
+ {
+ this.ecParams = params;
+ this.param = createKeyGenParamsJCE((java.security.spec.ECParameterSpec)params, random);
+ }
+ else if (params instanceof ECGenParameterSpec)
+ {
+ initializeNamedCurve(((ECGenParameterSpec)params).getName(), random);
+ }
+ else if (params instanceof ECNamedCurveGenParameterSpec)
+ {
+ initializeNamedCurve(((ECNamedCurveGenParameterSpec)params).getName(), random);
+ }
+ else
+ {
+ String name = ECUtil.getNameFrom(params);
+
+ if (name != null)
+ {
+ initializeNamedCurve(name, random);
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("invalid parameterSpec: " + params);
+ }
+ }
+
+ engine.init(param);
+ initialised = true;
+ }
+
+ public KeyPair generateKeyPair()
+ {
+ if (!initialised)
+ {
+ initialize(strength, new SecureRandom());
+ }
+
+ AsymmetricCipherKeyPair pair = engine.generateKeyPair();
+ ECPublicKeyParameters pub = (ECPublicKeyParameters)pair.getPublic();
+ ECPrivateKeyParameters priv = (ECPrivateKeyParameters)pair.getPrivate();
+
+ if (ecParams instanceof ECParameterSpec)
+ {
+ ECParameterSpec p = (ECParameterSpec)ecParams;
+
+ BCECPublicKey pubKey = new BCECPublicKey(algorithm, pub, p, configuration);
+ return new KeyPair(pubKey,
+ new BCECPrivateKey(algorithm, priv, pubKey, p, configuration));
+ }
+ else if (ecParams == null)
+ {
+ return new KeyPair(new BCECPublicKey(algorithm, pub, configuration),
+ new BCECPrivateKey(algorithm, priv, configuration));
+ }
+ else
+ {
+ java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams;
+
+ BCECPublicKey pubKey = new BCECPublicKey(algorithm, pub, p, configuration);
+
+ return new KeyPair(pubKey, new BCECPrivateKey(algorithm, priv, pubKey, p, configuration));
+ }
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsBC(ECParameterSpec p, SecureRandom r)
+ {
+ return new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH()), r);
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsJCE(java.security.spec.ECParameterSpec p, SecureRandom r)
+ {
+ if (p instanceof ECNamedCurveSpec)
+ {
+ String curveName = ((ECNamedCurveSpec)p).getName();
+
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null != x9)
+ {
+ return createKeyGenParamsJCE(x9, r);
+ }
+ }
+
+ ECCurve curve = EC5Util.convertCurve(p.getCurve());
+ ECPoint g = EC5Util.convertPoint(curve, p.getGenerator());
+ BigInteger n = p.getOrder();
+ BigInteger h = BigInteger.valueOf(p.getCofactor());
+ ECDomainParameters dp = new ECDomainParameters(curve, g, n, h);
+ return new ECKeyGenerationParameters(dp, r);
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsJCE(X9ECParameters x9, SecureRandom r)
+ {
+ ECDomainParameters dp = new ECDomainParameters(x9.getCurve(), x9.getG(), x9.getN(), x9.getH());
+
+ return new ECKeyGenerationParameters(dp, r);
+ }
+
+ protected void initializeNamedCurve(String curveName, SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null == x9)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
+ }
+
+ // Work-around for JDK bug -- it won't look up named curves properly if seed is present
+ byte[] seed = null; //p.getSeed();
+
+ this.ecParams = new ECNamedCurveSpec(curveName, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), seed);
+ this.param = createKeyGenParamsJCE(x9, random);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class SM2
+ extends BaseSM2
+ {
+ public SM2()
+ {
+ super("SM2", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+}
\ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
index a2dc9b1..2aee422 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
@@ -197,21 +197,18 @@
return null;
}
- protected void engineInit(
- Key key,
- AlgorithmParameterSpec params,
- SecureRandom random)
+ protected void doInitFromKey(Key key, AlgorithmParameterSpec parameterSpec, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
// Android-removed: Unsupported algorithms
- // if (params != null &&
- // !(params instanceof MQVParameterSpec || params instanceof UserKeyingMaterialSpec || params instanceof DHUParameterSpec))
- if (params != null && !(params instanceof UserKeyingMaterialSpec))
+ // if (parameterSpec != null &&
+ // !(parameterSpec instanceof MQVParameterSpec || parameterSpec instanceof UserKeyingMaterialSpec || params instanceof DHUParameterSpec))
+ if (parameterSpec != null && !(parameterSpec instanceof UserKeyingMaterialSpec))
{
throw new InvalidAlgorithmParameterException("No algorithm parameters supported");
}
- initFromKey(key, params);
+ initFromKey(key, parameterSpec);
}
protected void engineInit(
@@ -251,9 +248,9 @@
{
MQVPrivateKey mqvPrivKey = (MQVPrivateKey)key;
staticPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey());
+ ECUtils.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey());
ephemPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey());
+ ECUtils.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey());
ephemPubKey = null;
if (mqvPrivKey.getEphemeralPublicKey() != null)
@@ -267,9 +264,9 @@
MQVParameterSpec mqvParameterSpec = (MQVParameterSpec)parameterSpec;
staticPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ ECUtils.generatePrivateKeyParameter((PrivateKey)key);
ephemPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(mqvParameterSpec.getEphemeralPrivateKey());
+ ECUtils.generatePrivateKeyParameter(mqvParameterSpec.getEphemeralPrivateKey());
ephemPubKey = null;
if (mqvParameterSpec.getEphemeralPublicKey() != null)
@@ -301,9 +298,9 @@
ECPublicKeyParameters ephemPubKey;
staticPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ ECUtils.generatePrivateKeyParameter((PrivateKey)key);
ephemPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(dheParameterSpec.getEphemeralPrivateKey());
+ ECUtils.generatePrivateKeyParameter(dheParameterSpec.getEphemeralPrivateKey());
ephemPubKey = null;
if (dheParameterSpec.getEphemeralPublicKey() != null)
@@ -332,7 +329,7 @@
{
throw new InvalidAlgorithmParameterException("no KDF specified for UserKeyingMaterialSpec");
}
- ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtils.generatePrivateKeyParameter((PrivateKey)key);
this.parameters = privKey.getParameters();
ukmParameters = (parameterSpec instanceof UserKeyingMaterialSpec) ? ((UserKeyingMaterialSpec)parameterSpec).getUserKeyingMaterial() : null;
((BasicAgreement)agreement).init(privKey);
@@ -346,7 +343,7 @@
return fullName.substring(fullName.lastIndexOf('.') + 1);
}
- protected byte[] calcSecret()
+ protected byte[] doCalcSecret()
{
return Arrays.clone(result);
}
@@ -762,8 +759,8 @@
{
super("ECKAEGwithSHA1KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA1()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -775,8 +772,8 @@
{
super("ECKAEGwithRIPEMD160KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(new RIPEMD160Digest()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -788,8 +785,8 @@
{
super("ECKAEGwithSHA224KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA224()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -801,8 +798,8 @@
{
super("ECKAEGwithSHA256KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA256()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -814,8 +811,8 @@
{
super("ECKAEGwithSHA384KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA384()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
index 72c5880..1f2f88e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
@@ -241,7 +241,11 @@
try
{
- return new BCECPrivateKey(algorithm, new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ecKey.getParameters()), ecKey), configuration);
+ return new BCECPrivateKey(algorithm,
+ new PrivateKeyInfo(
+ new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ecKey.getParametersObject()),
+ ecKey),
+ configuration);
}
catch (IOException e)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
index b2dd4cf..756e081 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
@@ -9,10 +9,7 @@
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.util.Hashtable;
-import java.util.Map;
-import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import com.android.org.bouncycastle.asn1.x9.ECNamedCurveTable;
import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
@@ -63,7 +60,8 @@
static private Hashtable ecParameters;
- static {
+ static
+ {
ecParameters = new Hashtable();
ecParameters.put(Integers.valueOf(192), new ECGenParameterSpec("prime192v1")); // a.k.a P-192
@@ -220,13 +218,12 @@
{
if (p instanceof ECNamedCurveSpec)
{
- X9ECParameters x9P = ECUtils.getDomainParametersFromName(((ECNamedCurveSpec)p).getName());
+ String curveName = ((ECNamedCurveSpec)p).getName();
- if (x9P != null)
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null != x9)
{
- ECDomainParameters dp = new ECDomainParameters(x9P.getCurve(), x9P.getG(), x9P.getN(), x9P.getH());
-
- return new ECKeyGenerationParameters(dp, r);
+ return createKeyGenParamsJCE(x9, r);
}
}
@@ -238,48 +235,27 @@
return new ECKeyGenerationParameters(dp, r);
}
- protected ECNamedCurveSpec createNamedCurveSpec(String curveName)
- throws InvalidAlgorithmParameterException
+ protected ECKeyGenerationParameters createKeyGenParamsJCE(X9ECParameters x9, SecureRandom r)
{
- // NOTE: Don't bother with custom curves here as the curve will be converted to JCE type shortly
+ ECDomainParameters dp = new ECDomainParameters(x9.getCurve(), x9.getG(), x9.getN(), x9.getH());
- X9ECParameters p = ECUtils.getDomainParametersFromName(curveName);
- if (p == null)
- {
- try
- {
- // Check whether it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug)
- p = ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(curveName));
- if (p == null)
- {
- Map extraCurves = configuration.getAdditionalECParameters();
-
- p = (X9ECParameters)extraCurves.get(new ASN1ObjectIdentifier(curveName));
-
- if (p == null)
- {
- throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName);
- }
- }
- }
- catch (IllegalArgumentException ex)
- {
- throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
- }
- }
-
- // Work-around for JDK bug -- it won't look up named curves properly if seed is present
- byte[] seed = null; //p.getSeed();
-
- return new ECNamedCurveSpec(curveName, p.getCurve(), p.getG(), p.getN(), p.getH(), seed);
+ return new ECKeyGenerationParameters(dp, r);
}
protected void initializeNamedCurve(String curveName, SecureRandom random)
throws InvalidAlgorithmParameterException
{
- ECNamedCurveSpec namedCurve = createNamedCurveSpec(curveName);
- this.ecParams = namedCurve;
- this.param = createKeyGenParamsJCE(namedCurve, random);
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null == x9)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
+ }
+
+ // Work-around for JDK bug -- it won't look up named curves properly if seed is present
+ byte[] seed = null; //p.getSeed();
+
+ this.ecParams = new ECNamedCurveSpec(curveName, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), seed);
+ this.param = createKeyGenParamsJCE(x9, random);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
index 4543176..655ffaa 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
@@ -12,6 +12,7 @@
import com.android.org.bouncycastle.crypto.digests.NullDigest;
// BEGIN Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
+// import org.bouncycastle.crypto.digests.SHAKEDigest;
// END Android-removed: Unsupported algorithms
import com.android.org.bouncycastle.crypto.params.ParametersWithRandom;
import com.android.org.bouncycastle.crypto.signers.DSAEncoding;
@@ -26,7 +27,6 @@
// import org.bouncycastle.crypto.util.DigestFactory;
import com.android.org.bouncycastle.crypto.digests.AndroidDigestFactory;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.DSABase;
-import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
/**
* @hide This class is not part of the Android public SDK API
@@ -52,7 +52,7 @@
PrivateKey privateKey)
throws InvalidKeyException
{
- CipherParameters param = ECUtil.generatePrivateKeyParameter(privateKey);
+ CipherParameters param = ECUtils.generatePrivateKeyParameter(privateKey);
digest.reset();
@@ -297,6 +297,26 @@
}
}
+ static public class ecDSAShake128
+ extends SignatureSpi
+ {
+ public ecDSAShake128()
+ {
+ // RFC 8702 specifies deterministic DSA
+ super(new SHAKEDigest(128), new ECDSASigner(new HMacDSAKCalculator(new SHAKEDigest(128))), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDSAShake256
+ extends SignatureSpi
+ {
+ public ecDSAShake256()
+ {
+ // RFC 8702 specifies deterministic DSA
+ super(new SHAKEDigest(256), new ECDSASigner(new HMacDSAKCalculator(new SHAKEDigest(256))), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
static public class ecNR
extends SignatureSpi
{
@@ -395,6 +415,41 @@
super(new RIPEMD160Digest(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
}
}
+ static public class ecCVCDSA3_224
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_224()
+ {
+ super(DigestFactory.createSHA3_224(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA3_256
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_256()
+ {
+ super(DigestFactory.createSHA3_256(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA3_384
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_384()
+ {
+ super(DigestFactory.createSHA3_384(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA3_512
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_512()
+ {
+ super(DigestFactory.createSHA3_512(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
index 7dcccc8..ed24090 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
@@ -12,9 +12,11 @@
import com.android.org.bouncycastle.asn1.ASN1Encoding;
import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.DERNull;
import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
import com.android.org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
@@ -184,16 +186,36 @@
throws IOException
{
PSSParameterSpec pssSpec = currentSpec;
- AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(
- DigestFactory.getOID(pssSpec.getDigestAlgorithm()),
- DERNull.INSTANCE);
- MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters();
- AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
- PKCSObjectIdentifiers.id_mgf1,
- new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
- RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField()));
+ ASN1ObjectIdentifier digOid = DigestFactory.getOID(pssSpec.getDigestAlgorithm());
+ AlgorithmIdentifier hashAlgorithm;
+ // RFC 8072
+ if (NISTObjectIdentifiers.id_shake128.equals(digOid) || NISTObjectIdentifiers.id_shake256.equals(digOid))
+ {
+ hashAlgorithm = new AlgorithmIdentifier(digOid);
+ }
+ else
+ {
+ hashAlgorithm = new AlgorithmIdentifier(digOid, DERNull.INSTANCE);
+ }
- return pssP.getEncoded("DER");
+ MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters();
+ if (mgfSpec != null)
+ {
+ AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
+ PKCSObjectIdentifiers.id_mgf1,
+ new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
+ RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField()));
+
+ return pssP.getEncoded("DER");
+ }
+ else
+ {
+ AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
+ pssSpec.getMGFAlgorithm().equals("SHAKE128") ? NISTObjectIdentifiers.id_shake128 : NISTObjectIdentifiers.id_shake256);
+ RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField()));
+
+ return pssP.getEncoded("DER");
+ }
}
protected byte[] engineGetEncoded(
@@ -241,17 +263,29 @@
{
RSASSAPSSparams pssP = RSASSAPSSparams.getInstance(params);
- if (!pssP.getMaskGenAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1))
+ ASN1ObjectIdentifier mgfOid = pssP.getMaskGenAlgorithm().getAlgorithm();
+ if (mgfOid.equals(PKCSObjectIdentifiers.id_mgf1))
+ {
+ currentSpec = new PSSParameterSpec(
+ MessageDigestUtils.getDigestName(pssP.getHashAlgorithm().getAlgorithm()),
+ PSSParameterSpec.DEFAULT.getMGFAlgorithm(),
+ new MGF1ParameterSpec(MessageDigestUtils.getDigestName(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getAlgorithm())),
+ pssP.getSaltLength().intValue(),
+ pssP.getTrailerField().intValue());
+ }
+ else if (mgfOid.equals(NISTObjectIdentifiers.id_shake128) || mgfOid.equals(NISTObjectIdentifiers.id_shake256))
+ {
+ currentSpec = new PSSParameterSpec(
+ MessageDigestUtils.getDigestName(pssP.getHashAlgorithm().getAlgorithm()),
+ mgfOid.equals(NISTObjectIdentifiers.id_shake128) ? "SHAKE128" : "SHAKE256",
+ null,
+ pssP.getSaltLength().intValue(),
+ pssP.getTrailerField().intValue());
+ }
+ else
{
throw new IOException("unknown mask generation function: " + pssP.getMaskGenAlgorithm().getAlgorithm());
}
-
- currentSpec = new PSSParameterSpec(
- MessageDigestUtils.getDigestName(pssP.getHashAlgorithm().getAlgorithm()),
- PSSParameterSpec.DEFAULT.getMGFAlgorithm(),
- new MGF1ParameterSpec(MessageDigestUtils.getDigestName(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getAlgorithm())),
- pssP.getSaltLength().intValue(),
- pssP.getTrailerField().intValue());
}
catch (ClassCastException e)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
index 60f9296..7802c9e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
@@ -31,7 +31,6 @@
// Android-removed: Unsupported algorithm
// import org.bouncycastle.crypto.encodings.ISO9796d1Encoding;
import com.android.org.bouncycastle.crypto.encodings.OAEPEncoding;
-import com.android.org.bouncycastle.crypto.encodings.PKCS1Encoding;
import com.android.org.bouncycastle.crypto.engines.RSABlindedEngine;
import com.android.org.bouncycastle.crypto.params.ParametersWithRandom;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi;
@@ -209,7 +208,7 @@
}
else if (pad.equals("PKCS1PADDING"))
{
- cipher = new PKCS1Encoding(new RSABlindedEngine());
+ cipher = new CustomPKCS1Encoding(new RSABlindedEngine());
}
// BEGIN Android-removed: Unsupported algorithm
// else if (pad.equals("ISO9796-1PADDING"))
@@ -546,15 +545,26 @@
{
try
{
- return cipher.processBlock(bOut.getBuf(), 0, bOut.size());
- }
- catch (InvalidCipherTextException e)
- {
- throw new BadBlockException("unable to decrypt block", e);
- }
- catch (ArrayIndexOutOfBoundsException e)
- {
- throw new BadBlockException("unable to decrypt block", e);
+ byte[] output;
+ try
+ {
+ output = cipher.processBlock(bOut.getBuf(), 0, bOut.size());
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new BadBlockException("unable to decrypt block", e);
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ throw new BadBlockException("unable to decrypt block", e);
+ }
+
+ if (output == null)
+ {
+ throw new BadBlockException("unable to decrypt block", null);
+ }
+
+ return output;
}
finally
{
@@ -583,7 +593,7 @@
{
public PKCS1v1_5Padding()
{
- super(new PKCS1Encoding(new RSABlindedEngine()));
+ super(new CustomPKCS1Encoding(new RSABlindedEngine()));
}
}
@@ -592,7 +602,7 @@
{
public PKCS1v1_5Padding_PrivateOnly()
{
- super(false, true, new PKCS1Encoding(new RSABlindedEngine()));
+ super(false, true, new CustomPKCS1Encoding(new RSABlindedEngine()));
}
}
@@ -601,7 +611,7 @@
{
public PKCS1v1_5Padding_PublicOnly()
{
- super(true, false, new PKCS1Encoding(new RSABlindedEngine()));
+ super(true, false, new CustomPKCS1Encoding(new RSABlindedEngine()));
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java
new file mode 100644
index 0000000..3cb07f8
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java
@@ -0,0 +1,264 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.security.SecureRandom;
+
+import com.android.org.bouncycastle.crypto.AsymmetricBlockCipher;
+import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.org.bouncycastle.crypto.encodings.PKCS1Encoding;
+import com.android.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Properties;
+
+/**
+ * this does your basic PKCS 1 v1.5 padding - whether or not you should be using this
+ * depends on your application - see PKCS1 Version 2 for details.
+ */
+class CustomPKCS1Encoding
+ implements AsymmetricBlockCipher
+{
+ private static final int HEADER_LENGTH = 10;
+
+ private SecureRandom random;
+ private AsymmetricBlockCipher engine;
+ private boolean forEncryption;
+ private boolean forPrivateKey;
+ private boolean useStrictLength;
+ private byte[] blockBuffer;
+
+ /**
+ * Basic constructor.
+ *
+ * @param cipher
+ */
+ CustomPKCS1Encoding(AsymmetricBlockCipher cipher)
+ {
+ this.engine = cipher;
+ this.useStrictLength = useStrict();
+ }
+
+ //
+ // for J2ME compatibility
+ //
+ private boolean useStrict()
+ {
+ if (Properties.isOverrideSetTo(PKCS1Encoding.NOT_STRICT_LENGTH_ENABLED_PROPERTY, true))
+ {
+ return false;
+ }
+
+ return !Properties.isOverrideSetTo(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY, false);
+ }
+
+ public AsymmetricBlockCipher getUnderlyingCipher()
+ {
+ return engine;
+ }
+
+ public void init(boolean forEncryption, CipherParameters param)
+ {
+ AsymmetricKeyParameter kParam;
+
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+ this.random = rParam.getRandom();
+ kParam = (AsymmetricKeyParameter)rParam.getParameters();
+ }
+ else
+ {
+ kParam = (AsymmetricKeyParameter)param;
+ if (!kParam.isPrivate() && forEncryption)
+ {
+ this.random = CryptoServicesRegistrar.getSecureRandom();
+ }
+ }
+
+ engine.init(forEncryption, param);
+
+ this.forPrivateKey = kParam.isPrivate();
+ this.forEncryption = forEncryption;
+ this.blockBuffer = new byte[engine.getOutputBlockSize()];
+ }
+
+ public int getInputBlockSize()
+ {
+ int baseBlockSize = engine.getInputBlockSize();
+
+ if (forEncryption)
+ {
+ return baseBlockSize - HEADER_LENGTH;
+ }
+ else
+ {
+ return baseBlockSize;
+ }
+ }
+
+ public int getOutputBlockSize()
+ {
+ int baseBlockSize = engine.getOutputBlockSize();
+
+ if (forEncryption)
+ {
+ return baseBlockSize;
+ }
+ else
+ {
+ return baseBlockSize - HEADER_LENGTH;
+ }
+ }
+
+ public byte[] processBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException
+ {
+ if (forEncryption)
+ {
+ return encodeBlock(in, inOff, inLen);
+ }
+ else
+ {
+ return decodeBlock(in, inOff, inLen);
+ }
+ }
+
+ private byte[] encodeBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException
+ {
+ if (inLen > getInputBlockSize())
+ {
+ throw new IllegalArgumentException("input data too large");
+ }
+
+ byte[] block = new byte[engine.getInputBlockSize()];
+
+ if (forPrivateKey)
+ {
+ block[0] = 0x01; // type code 1
+
+ for (int i = 1; i != block.length - inLen - 1; i++)
+ {
+ block[i] = (byte)0xFF;
+ }
+ }
+ else
+ {
+ random.nextBytes(block); // random fill
+
+ block[0] = 0x02; // type code 2
+
+ //
+ // a zero byte marks the end of the padding, so all
+ // the pad bytes must be non-zero.
+ //
+ for (int i = 1; i != block.length - inLen - 1; i++)
+ {
+ while (block[i] == 0)
+ {
+ block[i] = (byte)random.nextInt();
+ }
+ }
+ }
+
+ block[block.length - inLen - 1] = 0x00; // mark the end of the padding
+ System.arraycopy(in, inOff, block, block.length - inLen, inLen);
+
+ return engine.processBlock(block, 0, block.length);
+ }
+
+ /**
+ * Check the argument is a valid encoding with type 1. Returns the plaintext length if valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding1(byte[] buf)
+ {
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
+
+ // The first byte should be 0x01
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x01);
+
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
+ {
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ int is0xFFMask = ((padByte ^ 0xFF) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ badPadSign |= ~(foundZeroMask | is0xFFMask);
+ }
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
+ }
+
+ /**
+ * Check the argument is a valid encoding with type 2. Returns the plaintext length if valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding2(byte[] buf)
+ {
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
+
+ // The first byte should be 0x02
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x02);
+
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
+ {
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ }
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
+ }
+
+ /**
+ * @throws InvalidCipherTextException if the decrypted block is not in PKCS1 format.
+ */
+ private byte[] decodeBlock(byte[] in, int inOff, int inLen)
+ throws InvalidCipherTextException
+ {
+ int strictBlockSize = engine.getOutputBlockSize();
+ byte[] block = engine.processBlock(in, inOff, inLen);
+
+ boolean incorrectLength = useStrictLength & (block.length != strictBlockSize);
+
+ byte[] data = block;
+ if (block.length < strictBlockSize)
+ {
+ data = blockBuffer;
+ }
+
+ int plaintextLength = forPrivateKey ? checkPkcs1Encoding2(data) : checkPkcs1Encoding1(data);
+
+ try
+ {
+ if (plaintextLength < 0 | incorrectLength)
+ {
+ // Special behaviour to avoid throw/catch/throw in CipherSpi
+ return null;
+ }
+
+ byte[] result = new byte[plaintextLength];
+ System.arraycopy(data, data.length - plaintextLength, result, 0, plaintextLength);
+ return result;
+ }
+ finally
+ {
+ Arrays.fill(block, (byte)0);
+ Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0);
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
index 759bdc0..e25076c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
@@ -1,7 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jcajce.provider.asymmetric.util;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
@@ -27,6 +32,7 @@
// import org.bouncycastle.crypto.agreement.kdf.DHKEKGenerator;
import com.android.org.bouncycastle.crypto.params.DESParameters;
import com.android.org.bouncycastle.crypto.params.KDFParameters;
+import com.android.org.bouncycastle.jcajce.spec.HybridValueParameterSpec;
import com.android.org.bouncycastle.util.Arrays;
import com.android.org.bouncycastle.util.Integers;
import com.android.org.bouncycastle.util.Strings;
@@ -152,6 +158,7 @@
protected final DerivationFunction kdf;
protected byte[] ukmParameters;
+ private HybridValueParameterSpec hybridSpec;
public BaseAgreementSpi(String kaAlgorithm, DerivationFunction kdf)
{
@@ -225,6 +232,40 @@
}
}
+ protected void engineInit(
+ Key key,
+ SecureRandom random)
+ throws InvalidKeyException
+ {
+ try
+ {
+ doInitFromKey(key, null, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ // this should never occur.
+ throw new InvalidKeyException(e.getMessage());
+ }
+ }
+
+ protected void engineInit(
+ Key key,
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ if (params instanceof HybridValueParameterSpec)
+ {
+ this.hybridSpec = (HybridValueParameterSpec)params;
+ doInitFromKey(key, hybridSpec.getBaseParameterSpec(), random);
+ }
+ else
+ {
+ this.hybridSpec = null;
+ doInitFromKey(key, params, random);
+ }
+ }
+
protected byte[] engineGenerateSecret()
throws IllegalStateException
{
@@ -351,5 +392,26 @@
}
}
- protected abstract byte[] calcSecret();
+ private byte[] calcSecret()
+ {
+ if (hybridSpec != null)
+ {
+ // Set Z' to Z || T
+ byte[] s = doCalcSecret();
+ byte[] sec = Arrays.concatenate(s, hybridSpec.getT());
+
+ Arrays.clear(s);
+
+ return sec;
+ }
+ else
+ {
+ return doCalcSecret();
+ }
+ }
+
+ protected abstract byte[] doCalcSecret();
+
+ protected abstract void doInitFromKey(Key key, AlgorithmParameterSpec parameterSpec, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
index 78423c3..c933301 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
@@ -20,6 +20,7 @@
import com.android.org.bouncycastle.asn1.x9.ECNamedCurveTable;
import com.android.org.bouncycastle.asn1.x9.X962Parameters;
import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.org.bouncycastle.asn1.x9.X9ECParametersHolder;
import com.android.org.bouncycastle.crypto.ec.CustomNamedCurves;
import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
@@ -39,20 +40,41 @@
*/
public class EC5Util
{
- private static Map customCurves = new HashMap();
-
- static
+ private static class CustomCurves
{
- Enumeration e = CustomNamedCurves.getNames();
- while (e.hasMoreElements())
- {
- String name = (String)e.nextElement();
+ private static Map CURVE_MAP = createCurveMap();
- X9ECParameters curveParams = ECNamedCurveTable.getByName(name);
- if (curveParams != null) // there may not be a regular curve, may just be a custom curve.
+ private static Map createCurveMap()
+ {
+ Map map = new HashMap();
+
+ Enumeration e = CustomNamedCurves.getNames();
+ while (e.hasMoreElements())
{
- customCurves.put(curveParams.getCurve(), CustomNamedCurves.getByName(name).getCurve());
+ String name = (String)e.nextElement();
+
+ X9ECParametersHolder curveParams = ECNamedCurveTable.getByNameLazy(name);
+ if (curveParams != null) // there may not be a regular curve, may just be a custom curve.
+ {
+ ECCurve curve = curveParams.getCurve();
+ if (ECAlgorithms.isFpCurve(curve))
+ {
+ map.put(curve, CustomNamedCurves.getByNameLazy(name).getCurve());
+ }
+ }
}
+
+ ECCurve c_25519 = CustomNamedCurves.getByNameLazy("Curve25519").getCurve();
+
+ map.put(new ECCurve.Fp(
+ c_25519.getField().getCharacteristic(),
+ c_25519.getA().toBigInteger(),
+ c_25519.getB().toBigInteger(),
+ c_25519.getOrder(),
+ c_25519.getCofactor(),
+ true), c_25519);
+
+ return map;
}
// BEGIN Android-removed: Unsupported curves
@@ -69,6 +91,11 @@
), c_25519);
*/
// END Android-removed: Unsupported curves
+ static ECCurve substitute(ECCurve c)
+ {
+ ECCurve custom = (ECCurve)CURVE_MAP.get(c);
+ return null != custom ? custom : c;
+ }
}
public static ECCurve getCurve(
@@ -280,21 +307,14 @@
if (field instanceof ECFieldFp)
{
- ECCurve.Fp curve = new ECCurve.Fp(((ECFieldFp)field).getP(), a, b);
-
- if (customCurves.containsKey(curve))
- {
- return (ECCurve)customCurves.get(curve);
- }
-
- return curve;
+ return CustomCurves.substitute(new ECCurve.Fp(((ECFieldFp)field).getP(), a, b, null, null));
}
else
{
ECFieldF2m fieldF2m = (ECFieldF2m)field;
int m = fieldF2m.getM();
int ks[] = ECUtil.convertMidTerms(fieldF2m.getMidTermsOfReductionPolynomial());
- return new ECCurve.F2m(m, ks[0], ks[1], ks[2], a, b);
+ return new ECCurve.F2m(m, ks[0], ks[1], ks[2], a, b, null, null);
}
}
@@ -308,7 +328,7 @@
{
Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
int[] exponents = poly.getExponentsPresent();
- int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
+ int[] ks = Arrays.reverseInPlace(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
return new ECFieldF2m(poly.getDegree(), ks);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
index e3ea672..142237f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
@@ -293,6 +293,11 @@
{
if (order == null) // implicitly CA
{
+ if (configuration == null)
+ {
+ return privateValue.bitLength(); // a guess but better than an exception!
+ }
+
ECParameterSpec implicitCA = configuration.getEcImplicitlyCa();
if (implicitCA == null)
@@ -311,26 +316,24 @@
public static ASN1ObjectIdentifier getNamedCurveOid(
String curveName)
{
- String name = curveName;
+ if (null == curveName || curveName.length() < 1)
+ {
+ return null;
+ }
- int spacePos = name.indexOf(' ');
+ int spacePos = curveName.indexOf(' ');
if (spacePos > 0)
{
- name = name.substring(spacePos + 1);
+ curveName = curveName.substring(spacePos + 1);
}
- try
+ ASN1ObjectIdentifier oid = getOID(curveName);
+ if (null != oid)
{
- if (name.charAt(0) >= '0' && name.charAt(0) <= '2')
- {
- return new ASN1ObjectIdentifier(name);
- }
- }
- catch (IllegalArgumentException ex)
- {
+ return oid;
}
- return ECNamedCurveTable.getOID(name);
+ return ECNamedCurveTable.getOID(curveName);
}
public static ASN1ObjectIdentifier getNamedCurveOid(
@@ -448,4 +451,20 @@
}
});
}
+
+ private static ASN1ObjectIdentifier getOID(String curveName)
+ {
+ char firstChar = curveName.charAt(0);
+ if (firstChar >= '0' && firstChar <= '2')
+ {
+ try
+ {
+ return new ASN1ObjectIdentifier(curveName);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ return null;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
index 1f57708..31acb3b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
@@ -65,10 +65,11 @@
}
private java.security.cert.Certificate readPEMCertificate(
- InputStream in)
+ InputStream in,
+ boolean isFirst)
throws IOException, CertificateParsingException
{
- return getCertificate(PEM_CERT_PARSER.readPEMObject(in));
+ return getCertificate(PEM_CERT_PARSER.readPEMObject(in, isFirst));
}
private java.security.cert.Certificate getCertificate(ASN1Sequence seq)
@@ -123,10 +124,11 @@
}
private CRL readPEMCRL(
- InputStream in)
+ InputStream in,
+ boolean isFirst)
throws IOException, CRLException
{
- return getCRL(PEM_CRL_PARSER.readPEMObject(in));
+ return getCRL(PEM_CRL_PARSER.readPEMObject(in, isFirst));
}
private CRL readDERCRL(
@@ -181,6 +183,14 @@
InputStream in)
throws CertificateException
{
+ return doGenerateCertificate(in, true);
+ }
+
+ private java.security.cert.Certificate doGenerateCertificate(
+ InputStream in,
+ boolean isFirst)
+ throws CertificateException
+ {
if (currentStream == null)
{
currentStream = in;
@@ -254,7 +264,7 @@
if (tag != 0x30) // assume ascii PEM encoded.
{
- return readPEMCertificate(pis);
+ return readPEMCertificate(pis, isFirst);
}
else
{
@@ -286,7 +296,8 @@
// Android-changed: Read from original stream
// while ((cert = engineGenerateCertificate(in)) != null)
- while ((cert = engineGenerateCertificate(inStream)) != null)
+ // if we do read some certificates we'll return them even if junk at end of file
+ while ((cert = doGenerateCertificate(inStream, certs.isEmpty())) != null)
{
certs.add(cert);
}
@@ -302,6 +313,18 @@
InputStream in)
throws CRLException
{
+ return doGenerateCRL(in, true);
+ }
+
+ /**
+ * Generates a certificate revocation list (CRL) object and initializes
+ * it with the data read from the input stream inStream.
+ */
+ private CRL doGenerateCRL(
+ InputStream in,
+ boolean isFirst)
+ throws CRLException
+ {
if (currentCrlStream == null)
{
currentCrlStream = in;
@@ -353,7 +376,7 @@
pis.reset();
if (tag != 0x30) // assume ascii PEM encoded.
{
- return readPEMCRL(pis);
+ return readPEMCRL(pis, isFirst);
}
else
{ // lazy evaluate to help processing of large CRLs
@@ -387,7 +410,8 @@
List crls = new ArrayList();
BufferedInputStream in = new BufferedInputStream(inStream);
- while ((crl = engineGenerateCRL(in)) != null)
+ // if we do read some certificates we'll return them even if junk at end of file
+ while ((crl = doGenerateCRL(in, crls.isEmpty())) != null)
{
crls.add(crl);
}
@@ -435,7 +459,7 @@
return new PKIXCertPath(certificates);
}
- private class ExCertificateException
+ private static class ExCertificateException
extends CertificateException
{
private Throwable cause;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
index 452d386..2c682dd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
@@ -14,7 +14,7 @@
* current PEM object.
*
*/
- private class Boundaries
+ private static class Boundaries
{
private final String _header;
private final String _footer;
@@ -113,7 +113,8 @@
}
ASN1Sequence readPEMObject(
- InputStream in)
+ InputStream in,
+ boolean isFirst)
throws IOException
{
String line;
@@ -132,6 +133,11 @@
if (header == null)
{
+ if (!isFirst)
+ {
+ // just ignore the data
+ return null;
+ }
throw new IOException("malformed PEM data: no header found");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
index fcf84c8..1ffd603 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
@@ -29,6 +29,7 @@
import javax.security.auth.x500.X500Principal;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
import com.android.org.bouncycastle.asn1.ASN1InputStream;
@@ -37,7 +38,6 @@
import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.util.ASN1Dump;
import com.android.org.bouncycastle.asn1.x500.X500Name;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
@@ -159,19 +159,6 @@
return null;
}
- public byte[] getEncoded()
- throws CRLException
- {
- try
- {
- return c.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- throw new CRLException(e.toString());
- }
- }
-
public void verify(PublicKey key)
throws CRLException, NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException, SignatureException
@@ -256,7 +243,7 @@
{
List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != pubKeys.size(); i++)
@@ -278,7 +265,7 @@
checkSignature(
(PublicKey)pubKeys.get(i), signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
catch (SignatureException e)
@@ -300,7 +287,7 @@
else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
{
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != sigSeq.size(); i++)
@@ -317,7 +304,7 @@
checkSignature(
key, signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
index 73cf1bf..3c2aa2e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
@@ -6,25 +6,42 @@
import com.android.org.bouncycastle.asn1.x509.CertificateList;
import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
+/**
+ * This class exists to let {@link #equals(Object)} and {@link #hashCode()} methods be delegated efficiently
+ * to the platform default implementations (especially important for compatibility of {@link #hashCode()}
+ * calculations). Those methods fall back to calling {@link #getEncoded()} for third-party subclasses, and
+ * this class allows us to avoid cloning the return value of {@link #getEncoded()} for those callers.
+ */
class X509CRLInternal extends X509CRLImpl
{
private final byte[] encoding;
+ private final CRLException exception;
X509CRLInternal(JcaJceHelper bcHelper, CertificateList c, String sigAlgName, byte[] sigAlgParams, boolean isIndirect,
- byte[] encoding)
+ byte[] encoding, CRLException exception)
{
super(bcHelper, c, sigAlgName, sigAlgParams, isIndirect);
this.encoding = encoding;
+ this.exception = exception;
}
public byte[] getEncoded() throws CRLException
{
+ if (null != exception)
+ {
+ throw exception;
+ }
+
if (null == encoding)
{
throw new CRLException();
}
+ /*
+ * NOTE: Don't clone this return value. See class javadoc for details. Any necessary cloning is
+ * handled by the X509CRLObject that is holding this instance.
+ */
return encoding;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
index c9635a4..e8fe588 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jcajce.provider.asymmetric.x509;
+import java.io.IOException;
import java.security.cert.CRLException;
import com.android.org.bouncycastle.asn1.ASN1BitString;
@@ -10,6 +11,7 @@
import com.android.org.bouncycastle.asn1.x509.Extension;
import com.android.org.bouncycastle.asn1.x509.IssuingDistributionPoint;
import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.org.bouncycastle.util.Arrays;
class X509CRLObject
extends X509CRLImpl
@@ -25,6 +27,11 @@
super(bcHelper, c, createSigAlgName(c), createSigAlgParams(c), isIndirectCRL(c));
}
+ public byte[] getEncoded() throws CRLException
+ {
+ return Arrays.clone(getInternalCRL().getEncoded());
+ }
+
public boolean equals(Object other)
{
if (this == other)
@@ -51,6 +58,8 @@
return false;
}
}
+
+ return getInternalCRL().equals(otherBC.getInternalCRL());
}
return getInternalCRL().equals(other);
@@ -77,17 +86,19 @@
}
}
- byte[] encoding;
+ byte[] encoding = null;
+ CRLException exception = null;
try
{
- encoding = getEncoded();
+ encoding = c.getEncoded(ASN1Encoding.DER);
}
- catch (CRLException e)
+ catch (IOException e)
{
- encoding = null;
+ exception = new X509CRLException(e);
}
- X509CRLInternal temp = new X509CRLInternal(bcHelper, c, sigAlgName,sigAlgParams, isIndirect, encoding);
+ X509CRLInternal temp = new X509CRLInternal(bcHelper, c, sigAlgName,sigAlgParams, isIndirect, encoding,
+ exception);
synchronized (cacheLock)
{
@@ -108,7 +119,7 @@
}
catch (Exception e)
{
- throw new CRLException("CRL contents invalid: " + e);
+ throw new X509CRLException("CRL contents invalid: " + e.getMessage(), e);
}
}
@@ -147,4 +158,26 @@
throw new ExtCRLException("Exception reading IssuingDistributionPoint", e);
}
}
+
+ private static class X509CRLException
+ extends CRLException
+ {
+ private final Throwable cause;
+
+ X509CRLException(String msg, Throwable cause)
+ {
+ super(msg);
+ this.cause = cause;
+ }
+
+ X509CRLException(Throwable cause)
+ {
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
index 6a3aa06..31c393b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
@@ -32,16 +32,17 @@
import javax.security.auth.x500.X500Principal;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.org.bouncycastle.asn1.ASN1IA5String;
import com.android.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1String;
-import com.android.org.bouncycastle.asn1.DERBitString;
-import com.android.org.bouncycastle.asn1.DERIA5String;
import com.android.org.bouncycastle.asn1.DERNull;
import com.android.org.bouncycastle.asn1.DEROctetString;
import com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
@@ -65,6 +66,7 @@
import com.android.org.bouncycastle.jce.X509Principal;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Exceptions;
import com.android.org.bouncycastle.util.Integers;
import com.android.org.bouncycastle.util.Properties;
import com.android.org.bouncycastle.util.Strings;
@@ -79,7 +81,6 @@
protected boolean[] keyUsage;
protected String sigAlgName;
protected byte[] sigAlgParams;
-
X509CertificateImpl(JcaJceHelper bcHelper, com.android.org.bouncycastle.asn1.x509.Certificate c,
BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams)
{
@@ -230,7 +231,7 @@
public boolean[] getIssuerUniqueID()
{
- DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getIssuerUniqueId();
if (id != null)
{
@@ -250,7 +251,7 @@
public boolean[] getSubjectUniqueID()
{
- DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getSubjectUniqueId();
if (id != null)
{
@@ -298,29 +299,21 @@
throw new CertificateParsingException("error processing extended key usage extension");
}
}
-
+
public int getBasicConstraints()
{
- if (basicConstraints != null)
+ if (basicConstraints == null || !basicConstraints.isCA())
{
- if (basicConstraints.isCA())
- {
- if (basicConstraints.getPathLenConstraint() == null)
- {
- return Integer.MAX_VALUE;
- }
- else
- {
- return basicConstraints.getPathLenConstraint().intValue();
- }
- }
- else
- {
- return -1;
- }
+ return -1;
}
- return -1;
+ ASN1Integer pathLenConstraint = basicConstraints.getPathLenConstraintInteger();
+ if (pathLenConstraint == null)
+ {
+ return Integer.MAX_VALUE;
+ }
+
+ return pathLenConstraint.intPositiveValueExact();
}
public Collection getSubjectAlternativeNames()
@@ -375,7 +368,7 @@
}
catch (Exception e)
{
- throw new IllegalStateException("error parsing " + e.toString());
+ throw Exceptions.illegalStateException("error parsing " + e.getMessage(), e);
}
}
@@ -461,20 +454,7 @@
}
catch (IOException e)
{
- return null; // should never happen...
- }
- }
-
- public byte[] getEncoded()
- throws CertificateEncodingException
- {
- try
- {
- return c.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- throw new CertificateEncodingException(e.toString());
+ throw Exceptions.illegalStateException("failed to recover public key: " + e.getMessage(), e);
}
}
@@ -527,15 +507,15 @@
}
else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
{
- buf.append(new NetscapeCertType(DERBitString.getInstance(dIn.readObject()))).append(nl);
+ buf.append(new NetscapeCertType(ASN1BitString.getInstance(dIn.readObject()))).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
{
- buf.append(new NetscapeRevocationURL(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ buf.append(new NetscapeRevocationURL(ASN1IA5String.getInstance(dIn.readObject()))).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
{
- buf.append(new VerisignCzagExtension(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ buf.append(new VerisignCzagExtension(ASN1IA5String.getInstance(dIn.readObject()))).append(nl);
}
else
{
@@ -647,7 +627,7 @@
{
List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != pubKeys.size(); i++)
@@ -668,7 +648,7 @@
checkSignature(
(PublicKey)pubKeys.get(i), signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
catch (SignatureException e)
@@ -690,7 +670,7 @@
else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
{
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != sigSeq.size(); i++)
@@ -707,7 +687,7 @@
checkSignature(
key, signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
index e74b8be..fc59572 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
@@ -6,25 +6,43 @@
import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
+/**
+ * This class exists to let {@link #equals(Object)} and {@link #hashCode()} methods be delegated efficiently
+ * to the platform default implementations (especially important for compatibility of {@link #hashCode()}
+ * calculations). Those methods fall back to calling {@link #getEncoded()} for third-party subclasses, and
+ * this class allows us to avoid cloning the return value of {@link #getEncoded()} for those callers.
+ */
class X509CertificateInternal extends X509CertificateImpl
{
private final byte[] encoding;
+ private final CertificateEncodingException exception;
X509CertificateInternal(JcaJceHelper bcHelper, com.android.org.bouncycastle.asn1.x509.Certificate c,
- BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams, byte[] encoding)
+ BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams, byte[] encoding,
+ CertificateEncodingException exception)
{
super(bcHelper, c, basicConstraints, keyUsage, sigAlgName, sigAlgParams);
this.encoding = encoding;
+ this.exception = exception;
}
public byte[] getEncoded() throws CertificateEncodingException
{
+ if (null != exception)
+ {
+ throw exception;
+ }
+
if (null == encoding)
{
throw new CertificateEncodingException();
}
+ /*
+ * NOTE: Don't clone this return value. See class javadoc for details. Any necessary cloning is
+ * handled by the X509CertificateObject that is holding this instance.
+ */
return encoding;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
index bfaf29f..037a74c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
@@ -1,57 +1,22 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jcajce.provider.asymmetric.x509;
-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;
-import java.security.Principal;
-import java.security.Provider;
import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
import javax.security.auth.x500.X500Principal;
import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
-import com.android.org.bouncycastle.asn1.ASN1InputStream;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import com.android.org.bouncycastle.asn1.ASN1OutputStream;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.org.bouncycastle.asn1.ASN1String;
-import com.android.org.bouncycastle.asn1.DERBitString;
-import com.android.org.bouncycastle.asn1.DERIA5String;
-import com.android.org.bouncycastle.asn1.DERNull;
-import com.android.org.bouncycastle.asn1.DEROctetString;
-import com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
-import com.android.org.bouncycastle.asn1.misc.NetscapeCertType;
-import com.android.org.bouncycastle.asn1.misc.NetscapeRevocationURL;
-import com.android.org.bouncycastle.asn1.misc.VerisignCzagExtension;
-import com.android.org.bouncycastle.asn1.util.ASN1Dump;
-import com.android.org.bouncycastle.asn1.x500.X500Name;
-import com.android.org.bouncycastle.asn1.x500.style.RFC4519Style;
-import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
import com.android.org.bouncycastle.asn1.x509.Extension;
import com.android.org.bouncycastle.asn1.x509.Extensions;
@@ -62,12 +27,8 @@
// END Android-added: Unknown reason
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
-import com.android.org.bouncycastle.jce.X509Principal;
import com.android.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
-import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
-import com.android.org.bouncycastle.util.Integers;
-import com.android.org.bouncycastle.util.Strings;
-import com.android.org.bouncycastle.util.encoders.Hex;
+import com.android.org.bouncycastle.util.Arrays;
class X509CertificateObject
extends X509CertificateImpl
@@ -254,6 +215,8 @@
return false;
}
}
+
+ return getInternalCertificate().equals(otherBC.getInternalCertificate());
}
return getInternalCertificate().equals(other);
@@ -318,18 +281,19 @@
}
}
- byte[] encoding;
+ byte[] encoding = null;
+ CertificateEncodingException exception = null;
try
{
- encoding = getEncoded();
+ encoding = c.getEncoded(ASN1Encoding.DER);
}
- catch (CertificateEncodingException e)
+ catch (IOException e)
{
- encoding = null;
+ exception = new X509CertificateEncodingException(e);
}
X509CertificateInternal temp = new X509CertificateInternal(bcHelper, c, basicConstraints, keyUsage, sigAlgName,
- sigAlgParams, encoding);
+ sigAlgParams, encoding, exception);
synchronized (cacheLock)
{
@@ -371,7 +335,7 @@
return null;
}
- ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(extOctets));
+ ASN1BitString bits = ASN1BitString.getInstance(ASN1Primitive.fromByteArray(extOctets));
byte[] bytes = bits.getBytes();
int length = (bytes.length * 8) - bits.getPadBits();
@@ -420,4 +384,20 @@
throw new CertificateParsingException("cannot construct SigAlgParams: " + e);
}
}
+
+ private static class X509CertificateEncodingException
+ extends CertificateEncodingException
+ {
+ private final Throwable cause;
+
+ X509CertificateEncodingException(Throwable cause)
+ {
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
index 9903c5f..47bf765 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
@@ -181,6 +181,11 @@
static void prettyPrintSignature(byte[] sig, StringBuffer buf, String nl)
{
+ // -DM Hex.toHexString
+ // -DM Hex.toHexString
+ // -DM Hex.toHexString
+ // -DM Hex.toHexString
+
if (sig.length > 20)
{
buf.append(" Signature: ").append(Hex.toHexString(sig, 0, 20)).append(nl);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
index d6dc21e..76bfd53 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
@@ -47,8 +47,12 @@
void addAlgorithm(String key, String value);
+ void addAlgorithm(String key, String value, Map<String, String> attributes);
+
void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className);
+ void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className, Map<String, String> attributes);
+
boolean hasAlgorithm(String type, String name);
void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
index 2bb2007..24225e3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jcajce.provider.digest;
+import java.security.DigestException;
import java.security.MessageDigest;
import com.android.org.bouncycastle.crypto.Digest;
@@ -69,4 +70,16 @@
return digestBytes;
}
+
+ public int engineDigest(byte[] buf, int off, int len) throws DigestException
+ {
+ if (len < digestSize)
+ throw new DigestException("partial digests not returned");
+ if (buf.length - off < digestSize)
+ throw new DigestException("insufficient space in the output buffer to store the digest");
+
+ digest.doFinal(buf, off);
+
+ return digestSize;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java
index 6597e1d..33183e1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java
@@ -24,6 +24,19 @@
provider.addAlgorithm("Alg.Alias.KeyGenerator.HMAC/" + algorithm, mainName);
}
+ protected void addKMACAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String algorithmClassName,
+ String keyGeneratorClassName)
+ {
+ String mainName = "KMAC" + algorithm;
+
+ provider.addAlgorithm("Mac." + mainName, algorithmClassName);
+ provider.addAlgorithm("KeyGenerator." + mainName, keyGeneratorClassName);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.KMAC" + algorithm, mainName);
+ }
+
protected void addHMACAlias(
ConfigurableProvider provider,
String algorithm,
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/Haraka.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/Haraka.java
new file mode 100644
index 0000000..2d335a8
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/Haraka.java
@@ -0,0 +1,80 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.digest;
+
+import com.android.org.bouncycastle.crypto.digests.Haraka256Digest;
+import com.android.org.bouncycastle.crypto.digests.Haraka512Digest;
+import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Haraka
+{
+ private Haraka()
+ {
+
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class Digest256
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest256()
+ {
+ super(new Haraka256Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest256 d = (Digest256)super.clone();
+ d.digest = new Haraka256Digest((Haraka256Digest)digest);
+
+ return d;
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class Digest512
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest512()
+ {
+ super(new Haraka512Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest512 d = (Digest512)super.clone();
+ d.digest = new Haraka512Digest((Haraka512Digest)digest);
+
+ return d;
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends DigestAlgorithmProvider
+ {
+ private static final String PREFIX = Haraka.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("MessageDigest.HARAKA-256", PREFIX + "$Digest256");
+ provider.addAlgorithm("MessageDigest.HARAKA-512", PREFIX + "$Digest512");
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA256.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA256.java
index a4e8a76..aed2538 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA256.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA256.java
@@ -30,14 +30,14 @@
{
public Digest()
{
- super(new SHA256Digest());
+ super(SHA256Digest.newInstance());
}
public Object clone()
throws CloneNotSupportedException
{
Digest d = (Digest)super.clone();
- d.digest = new SHA256Digest((SHA256Digest)digest);
+ d.digest = SHA256Digest.newInstance(digest);
return d;
}
@@ -51,7 +51,7 @@
{
public HashMac()
{
- super(new HMac(new SHA256Digest()));
+ super(new HMac(SHA256Digest.newInstance()));
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA512.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA512.java
index cdc7018..4f0aa21 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA512.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA512.java
@@ -190,10 +190,16 @@
provider.addAlgorithm("MessageDigest.SHA-512/224", PREFIX + "$DigestT224");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512/224", "SHA-512/224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512224", "SHA-512/224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA-512(224)", "SHA-512/224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512(224)", "SHA-512/224");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_224, "SHA-512/224");
provider.addAlgorithm("MessageDigest.SHA-512/256", PREFIX + "$DigestT256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512/256", "SHA-512/256");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512256", "SHA-512/256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA-512(256)", "SHA-512/256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512(256)", "SHA-512/256");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_256, "SHA-512/256");
provider.addAlgorithm("Mac.OLDHMACSHA512", PREFIX + "$OldSHA512");
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/drbg/EntropyDaemon.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/drbg/EntropyDaemon.java
new file mode 100644
index 0000000..1d0586d
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/drbg/EntropyDaemon.java
@@ -0,0 +1,66 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.drbg;
+
+import java.util.LinkedList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+class EntropyDaemon
+ implements Runnable
+{
+ private static final Logger LOG = Logger.getLogger(EntropyDaemon.class.getName());
+
+ private final LinkedList<Runnable> tasks = new LinkedList<Runnable>();
+
+ public EntropyDaemon()
+ {
+ }
+
+ void addTask(Runnable task)
+ {
+ synchronized (tasks)
+ {
+ tasks.add(task);
+ }
+ }
+
+ public void run()
+ {
+ while (!Thread.currentThread().isInterrupted())
+ {
+ Runnable task;
+ synchronized (tasks)
+ {
+ task = tasks.poll();
+ }
+
+ if (task != null)
+ {
+ try
+ {
+ task.run();
+ }
+ catch (Throwable e)
+ {
+ // ignore
+ }
+ }
+ else
+ {
+ try
+ {
+ Thread.sleep(5000);
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ if (LOG.isLoggable(Level.FINE))
+ {
+ LOG.fine("entropy thread interrupted - exiting");
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/BC.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/BC.java
index aac3db9..aa6e941 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/BC.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/BC.java
@@ -3,6 +3,7 @@
import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+import com.android.org.bouncycastle.util.Properties;
/**
* @hide This class is not part of the Android public SDK API
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
index 9605ced..2138148 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
@@ -58,6 +58,7 @@
import com.android.org.bouncycastle.jce.interfaces.BCKeyStore;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Properties;
import com.android.org.bouncycastle.util.io.Streams;
import com.android.org.bouncycastle.util.io.TeeOutputStream;
@@ -398,6 +399,11 @@
{
byte[] enc = key.getEncoded();
+ if (enc == null)
+ {
+ throw new IOException("unable to store encoding of protected key");
+ }
+
if (key instanceof PrivateKey)
{
dOut.write(KEY_PRIVATE);
@@ -676,9 +682,18 @@
Certificate[] chain)
throws KeyStoreException
{
- if ((key instanceof PrivateKey) && (chain == null))
+ if ((key instanceof PrivateKey))
{
- throw new KeyStoreException("no certificate chain for private key");
+ if (chain == null)
+ {
+ throw new KeyStoreException("no certificate chain for private key");
+ }
+ if (key.getEncoded() == null)
+ {
+ // we ingore the password as the key is already protected.
+ table.put(alias, new StoreEntry(alias, new Date(), KEY, key, chain));
+ return;
+ }
}
try
@@ -1129,6 +1144,10 @@
public Version1()
{
super(1);
+ if (!Properties.isOverrideSet("com.android.org.bouncycastle.bks.enable_v1"))
+ {
+ throw new IllegalStateException("BKS-V1 not enabled");
+ }
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
index 06fbb96..e308252 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
@@ -3,6 +3,7 @@
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
+import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -47,6 +48,7 @@
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
+import com.android.org.bouncycastle.asn1.ASN1BMPString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
@@ -66,6 +68,7 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.GOST28147Parameters;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import com.android.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
// import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
import com.android.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
@@ -84,9 +87,13 @@
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import com.android.org.bouncycastle.asn1.x509.DigestInfo;
+import com.android.org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import com.android.org.bouncycastle.asn1.x509.Extension;
+import com.android.org.bouncycastle.asn1.x509.Extensions;
+import com.android.org.bouncycastle.asn1.x509.KeyPurposeId;
import com.android.org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.org.bouncycastle.asn1.x509.TBSCertificate;
import com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.Digest;
@@ -97,6 +104,9 @@
import com.android.org.bouncycastle.jcajce.PKCS12StoreParameter;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
+// import org.bouncycastle.jcajce.BCLoadStoreParameter;
+import com.android.org.bouncycastle.jcajce.provider.keystore.util.AdaptingKeyStoreSpi;
+import com.android.org.bouncycastle.jcajce.provider.keystore.util.ParameterUtil;
import com.android.org.bouncycastle.jcajce.spec.PBKDF2KeySpec;
import com.android.org.bouncycastle.jcajce.util.BCJcaJceHelper;
import com.android.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
@@ -133,7 +143,7 @@
private static final DefaultSecretKeyProvider keySizeProvider = new DefaultSecretKeyProvider();
private IgnoresCaseHashtable keys = new IgnoresCaseHashtable();
- private Hashtable localIds = new Hashtable();
+ private IgnoresCaseHashtable localIds = new IgnoresCaseHashtable();
private IgnoresCaseHashtable certs = new IgnoresCaseHashtable();
private Hashtable chainCerts = new Hashtable();
private Hashtable keyCerts = new Hashtable();
@@ -257,6 +267,12 @@
this.random = rand;
}
+ public boolean engineProbe(InputStream stream)
+ throws IOException
+ {
+ return false;
+ }
+
public Enumeration engineAliases()
{
Hashtable tab = new Hashtable();
@@ -295,25 +311,23 @@
String alias)
throws KeyStoreException
{
- Key k = (Key)keys.remove(alias);
-
- Certificate c = (Certificate)certs.remove(alias);
-
- if (c != null)
+ Certificate cert = (Certificate)certs.remove(alias);
+ if (cert != null)
{
- chainCerts.remove(new CertId(c.getPublicKey()));
+ chainCerts.remove(new CertId(cert.getPublicKey()));
}
- if (k != null)
+ Key key = (Key)keys.remove(alias);
+ if (key != null)
{
String id = (String)localIds.remove(alias);
if (id != null)
{
- c = (Certificate)keyCerts.remove(id);
- }
- if (c != null)
- {
- chainCerts.remove(new CertId(c.getPublicKey()));
+ Certificate keyCert = (Certificate)keyCerts.remove(id);
+ if (keyCert != null)
+ {
+ chainCerts.remove(new CertId(keyCert.getPublicKey()));
+ }
}
}
}
@@ -658,7 +672,7 @@
try
{
- SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm);
+ SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm);
PBEParameterSpec defParams = new PBEParameterSpec(
pbeParams.getIV(),
pbeParams.getIterations().intValue());
@@ -708,7 +722,7 @@
throw new IOException("exception decrypting data - " + e.toString());
}
}
- else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2))
+ else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2))
{
try
{
@@ -771,6 +785,31 @@
return cipher;
}
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public void engineLoad(KeyStore.LoadStoreParameter loadStoreParameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (loadStoreParameter == null)
+ {
+ engineLoad(null, null);
+ }
+ else if (loadStoreParameter instanceof BCLoadStoreParameter)
+ {
+ BCLoadStoreParameter bcParam = (BCLoadStoreParameter)loadStoreParameter;
+
+ engineLoad(bcParam.getInputStream(), ParameterUtil.extractPassword(loadStoreParameter));
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "no support for 'param' of type " + loadStoreParameter.getClass().getName());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
public void engineLoad(
InputStream stream,
char[] password)
@@ -786,7 +825,10 @@
bufIn.mark(10);
int head = bufIn.read();
-
+ if (head < 0)
+ {
+ throw new EOFException("no data in keystore stream");
+ }
if (head != 0x30)
{
throw new IOException("stream does not represent a PKCS12 key store");
@@ -795,7 +837,7 @@
bufIn.reset();
ASN1InputStream bIn = new ASN1InputStream(bufIn);
-
+
Pfx bag;
try
{
@@ -872,7 +914,7 @@
// END Android-removed: keep v1.61 behaviour to keep backwards-compatibility
keys = new IgnoresCaseHashtable();
- localIds = new Hashtable();
+ localIds = new IgnoresCaseHashtable();
if (info.getContentType().equals(data))
{
@@ -892,86 +934,19 @@
SafeBag b = SafeBag.getInstance(seq.getObjectAt(j));
if (b.getBagId().equals(pkcs8ShroudedKeyBag))
{
- com.android.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = com.android.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
- PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
-
- //
- // set the attributes on the key
- //
- String alias = null;
- ASN1OctetString localId = null;
-
- if (b.getBagAttributes() != null)
- {
- Enumeration e = b.getBagAttributes().getObjects();
- while (e.hasMoreElements())
- {
- ASN1Sequence sq = (ASN1Sequence)e.nextElement();
- ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0);
- ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
- ASN1Primitive attr = null;
-
- if (attrSet.size() > 0)
- {
- attr = (ASN1Primitive)attrSet.getObjectAt(0);
-
- if (privKey instanceof PKCS12BagAttributeCarrier)
- {
- PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
- ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
- if (existing != null)
- {
- // OK, but the value has to be the same
- if (!existing.toASN1Primitive().equals(attr))
- {
- throw new IOException(
- "attempt to add existing attribute with different value");
- }
- }
- else
- {
- bagAttr.setBagAttribute(aOid, attr);
- }
- }
- }
-
- if (aOid.equals(pkcs_9_at_friendlyName))
- {
- alias = ((DERBMPString)attr).getString();
- keys.put(alias, privKey);
- }
- else if (aOid.equals(pkcs_9_at_localKeyId))
- {
- localId = (ASN1OctetString)attr;
- }
- }
- }
-
- if (localId != null)
- {
- String name = new String(Hex.encode(localId.getOctets()));
-
- if (alias == null)
- {
- keys.put(name, privKey);
- }
- else
- {
- localIds.put(alias, name);
- }
- }
- else
- {
- unmarkedKey = true;
- keys.put("unmarked", privKey);
- }
+ unmarkedKey = processShroudedKeyBag(b, password, wrongPKCS12Zero);
}
else if (b.getBagId().equals(certBag))
{
chain.addElement(b);
}
+ else if (b.getBagId().equals(keyBag))
+ {
+ processKeyBag(b);
+ }
else
{
+ // -DM 2 System.out.println
System.out.println("extra in data " + b.getBagId());
System.out.println(ASN1Dump.dumpAsString(b));
}
@@ -987,137 +962,21 @@
for (int j = 0; j != seq.size(); j++)
{
SafeBag b = SafeBag.getInstance(seq.getObjectAt(j));
-
if (b.getBagId().equals(certBag))
{
chain.addElement(b);
}
else if (b.getBagId().equals(pkcs8ShroudedKeyBag))
{
- com.android.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = com.android.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
- PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
-
- //
- // set the attributes on the key
- //
- PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
- String alias = null;
- ASN1OctetString localId = null;
-
- Enumeration e = b.getBagAttributes().getObjects();
- while (e.hasMoreElements())
- {
- ASN1Sequence sq = (ASN1Sequence)e.nextElement();
- ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0);
- ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
- ASN1Primitive attr = null;
-
- if (attrSet.size() > 0)
- {
- attr = (ASN1Primitive)attrSet.getObjectAt(0);
-
- ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
- if (existing != null)
- {
- // OK, but the value has to be the same
- if (!existing.toASN1Primitive().equals(attr))
- {
- throw new IOException(
- "attempt to add existing attribute with different value");
- }
- }
- else
- {
- bagAttr.setBagAttribute(aOid, attr);
- }
- }
-
- if (aOid.equals(pkcs_9_at_friendlyName))
- {
- alias = ((DERBMPString)attr).getString();
- keys.put(alias, privKey);
- }
- else if (aOid.equals(pkcs_9_at_localKeyId))
- {
- localId = (ASN1OctetString)attr;
- }
- }
-
- String name = new String(Hex.encode(localId.getOctets()));
-
- if (alias == null)
- {
- keys.put(name, privKey);
- }
- else
- {
- localIds.put(alias, name);
- }
+ unmarkedKey = processShroudedKeyBag(b, password, wrongPKCS12Zero);
}
else if (b.getBagId().equals(keyBag))
{
- com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue());
- PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo);
-
- //
- // set the attributes on the key
- //
- PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
- String alias = null;
- ASN1OctetString localId = null;
-
- Enumeration e = b.getBagAttributes().getObjects();
- while (e.hasMoreElements())
- {
- ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement());
- ASN1ObjectIdentifier aOid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0));
- ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1));
- ASN1Primitive attr = null;
-
- if (attrSet.size() > 0)
- {
- attr = (ASN1Primitive)attrSet.getObjectAt(0);
-
- ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
- if (existing != null)
- {
- // OK, but the value has to be the same
- if (!existing.toASN1Primitive().equals(attr))
- {
- throw new IOException(
- "attempt to add existing attribute with different value");
- }
- }
- else
- {
- bagAttr.setBagAttribute(aOid, attr);
- }
-
- if (aOid.equals(pkcs_9_at_friendlyName))
- {
- alias = ((DERBMPString)attr).getString();
- keys.put(alias, privKey);
- }
- else if (aOid.equals(pkcs_9_at_localKeyId))
- {
- localId = (ASN1OctetString)attr;
- }
- }
- }
-
- String name = new String(Hex.encode(localId.getOctets()));
-
- if (alias == null)
- {
- keys.put(name, privKey);
- }
- else
- {
- localIds.put(alias, name);
- }
+ processKeyBag(b);
}
else
{
+ // -DM 2 System.out.println
System.out.println("extra in encryptedData " + b.getBagId());
System.out.println(ASN1Dump.dumpAsString(b));
}
@@ -1125,6 +984,7 @@
}
else
{
+ // -DM 2 System.out.println
System.out.println("extra " + c[i].getContentType().getId());
System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent()));
}
@@ -1185,6 +1045,17 @@
ASN1Encodable existing = bagAttr.getBagAttribute(oid);
if (existing != null)
{
+ // we've found more than one - one might be incorrect
+ if (oid.equals(pkcs_9_at_localKeyId))
+ {
+ // -DM Hex.toHexString
+ String id = Hex.toHexString(((ASN1OctetString)attr).getOctets());
+ if (!(keys.keys.containsKey(id) || localIds.keys.containsKey(id)))
+ {
+ continue; // ignore this one - it's not valid
+ }
+ }
+
// OK, but the value has to be the same
if (!existing.toASN1Primitive().equals(attr))
{
@@ -1194,13 +1065,20 @@
}
else
{
- bagAttr.setBagAttribute(oid, attr);
+ if (attrSet.size() > 1)
+ {
+ bagAttr.setBagAttribute(oid, attrSet);
+ }
+ else
+ {
+ bagAttr.setBagAttribute(oid, attr);
+ }
}
}
if (oid.equals(pkcs_9_at_friendlyName))
{
- alias = ((DERBMPString)attr).getString();
+ alias = ((ASN1BMPString)attr).getString();
}
else if (oid.equals(pkcs_9_at_localKeyId))
{
@@ -1241,6 +1119,149 @@
}
}
+ private boolean processShroudedKeyBag(SafeBag b, char[] password, boolean wrongPKCS12Zero)
+ throws IOException
+ {
+ com.android.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = com.android.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
+ PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
+
+ //
+ // set the attributes on the key
+ //
+ String alias = null;
+ ASN1OctetString localId = null;
+
+ if (b.getBagAttributes() != null)
+ {
+ Enumeration e = b.getBagAttributes().getObjects();
+ while (e.hasMoreElements())
+ {
+ ASN1Sequence sq = (ASN1Sequence)e.nextElement();
+ ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0);
+ ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
+ ASN1Primitive attr = null;
+
+ if (attrSet.size() > 0)
+ {
+ attr = (ASN1Primitive)attrSet.getObjectAt(0);
+
+ if (privKey instanceof PKCS12BagAttributeCarrier)
+ {
+ PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
+ ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
+ if (existing != null)
+ {
+ // OK, but the value has to be the same
+ if (!existing.toASN1Primitive().equals(attr))
+ {
+ throw new IOException(
+ "attempt to add existing attribute with different value");
+ }
+ }
+ else
+ {
+ bagAttr.setBagAttribute(aOid, attr);
+ }
+ }
+ }
+
+ if (aOid.equals(pkcs_9_at_friendlyName))
+ {
+ alias = ((ASN1BMPString)attr).getString();
+ keys.put(alias, privKey);
+ }
+ else if (aOid.equals(pkcs_9_at_localKeyId))
+ {
+ localId = (ASN1OctetString)attr;
+ }
+ }
+ }
+
+ if (localId != null)
+ {
+ String name = new String(Hex.encode(localId.getOctets()));
+
+ if (alias == null)
+ {
+ keys.put(name, privKey);
+ }
+ else
+ {
+ localIds.put(alias, name);
+ }
+ return false; // key properly marked
+ }
+ else
+ {
+ keys.put("unmarked", privKey);
+ return true; // key properly marked
+ }
+ }
+
+ private void processKeyBag(SafeBag b)
+ throws IOException
+ {
+ com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue());
+ PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo);
+
+ //
+ // set the attributes on the key
+ //
+ PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
+ String alias = null;
+ ASN1OctetString localId = null;
+
+ Enumeration e = b.getBagAttributes().getObjects();
+ while (e.hasMoreElements())
+ {
+ ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement());
+ ASN1ObjectIdentifier aOid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0));
+ ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1));
+ ASN1Primitive attr = null;
+
+ if (attrSet.size() > 0)
+ {
+ attr = (ASN1Primitive)attrSet.getObjectAt(0);
+
+ ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
+ if (existing != null)
+ {
+ // OK, but the value has to be the same
+ if (!existing.toASN1Primitive().equals(attr))
+ {
+ throw new IOException(
+ "attempt to add existing attribute with different value");
+ }
+ }
+ else
+ {
+ bagAttr.setBagAttribute(aOid, attr);
+ }
+
+ if (aOid.equals(pkcs_9_at_friendlyName))
+ {
+ alias = ((ASN1BMPString)attr).getString();
+ keys.put(alias, privKey);
+ }
+ else if (aOid.equals(pkcs_9_at_localKeyId))
+ {
+ localId = (ASN1OctetString)attr;
+ }
+ }
+ }
+
+ String name = new String(Hex.encode(localId.getOctets()));
+
+ if (alias == null)
+ {
+ keys.put(name, privKey);
+ }
+ else
+ {
+ localIds.put(alias, name);
+ }
+ }
+
private int validateIterationCount(BigInteger i)
{
int count = i.intValue();
@@ -1322,7 +1343,55 @@
// See CtsKeystoreTestCases:android.keystore.cts.KeyStoreTest
if (password == null)
{
- throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
+ if (password == null)
+ {
+ Enumeration cs = certs.keys();
+
+ ASN1EncodableVector certSeq = new ASN1EncodableVector();
+
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ String certId = (String)cs.nextElement();
+ Certificate cert = (Certificate)certs.get(certId);
+
+ SafeBag sBag = createSafeBag(certId, cert);
+
+ certSeq.add(sBag);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ if (useDEREncoding)
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.DER);
+ }
+ else
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.BER);
+ }
+
+ return;
+ }
+ }
+ else
+ {
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied for PKCS#12 KeyStore");
+ }
}
/*
if (keys.size() == 0)
@@ -1409,7 +1478,7 @@
//
// make sure we are using the local alias on store
//
- DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ ASN1BMPString nm = (ASN1BMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(name))
{
bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name));
@@ -1500,7 +1569,7 @@
//
// make sure we are using the local alias on store
//
- DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ ASN1BMPString nm = (ASN1BMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(name))
{
bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name));
@@ -1633,6 +1702,7 @@
}
}
+
SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
certSeq.add(sBag);
@@ -1706,7 +1776,7 @@
//
// make sure we are using the local alias on store
//
- DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ ASN1BMPString nm = (ASN1BMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(certId))
{
if (certId != null)
@@ -1750,6 +1820,43 @@
fName.add(new DERSequence(fSeq));
}
+ // Android-removed: unsupported
+ // add the trusted usage attribute - needed for Oracle key stores
+ // if (cert instanceof X509Certificate)
+ // {
+ // TBSCertificate tbsCert = TBSCertificate.getInstance(((X509Certificate)cert).getTBSCertificate());
+ // Extensions exts = tbsCert.getExtensions();
+ // if (exts != null)
+ // {
+ // Extension extUsage = exts.getExtension(Extension.extendedKeyUsage);
+ // if (extUsage != null)
+ // {
+ // ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ // // oracle trusted key usage OID.
+ // fSeq.add(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage);
+ // fSeq.add(new DERSet(ExtendedKeyUsage.getInstance(extUsage.getParsedValue()).getUsages()));
+ // fName.add(new DERSequence(fSeq));
+ // }
+ // else
+ // {
+ // ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ // fSeq.add(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage);
+ // fSeq.add(new DERSet(KeyPurposeId.anyExtendedKeyUsage));
+ // fName.add(new DERSequence(fSeq));
+ // }
+ // }
+ // else
+ // {
+ // ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ // fSeq.add(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage);
+ // fSeq.add(new DERSet(KeyPurposeId.anyExtendedKeyUsage));
+ // fName.add(new DERSequence(fSeq));
+ // }
+ // }
+
return new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
}
@@ -1757,19 +1864,19 @@
{
Set usedSet = new HashSet();
- for (Enumeration en = keys.keys(); en.hasMoreElements();)
+ for (Enumeration en = keys.keys(); en.hasMoreElements(); )
{
String alias = (String)en.nextElement();
- Certificate[] certs = engineGetCertificateChain(alias);
+ Certificate[] certs = engineGetCertificateChain(alias);
- for (int i = 0; i != certs.length; i++)
- {
- usedSet.add(certs[i]);
- }
+ for (int i = 0; i != certs.length; i++)
+ {
+ usedSet.add(certs[i]);
+ }
}
- for (Enumeration en = certs.keys(); en.hasMoreElements();)
+ for (Enumeration en = certs.keys(); en.hasMoreElements(); )
{
String alias = (String)en.nextElement();
@@ -1801,6 +1908,7 @@
return mac.doFinal();
}
+ // Android-changed: Use default provider for JCA algorithms instead of BC
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -1810,7 +1918,7 @@
public BCPKCS12KeyStore()
{
// Android-changed: Use default provider for JCA algorithms instead of BC
- // Was: super(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
+ // Was: super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC));
super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
}
}
@@ -1818,29 +1926,29 @@
// BEGIN Android-removed: Unsupported algorithms
/*
public static class BCPKCS12KeyStore3DES
- extends PKCS12KeyStoreSpi
+ extends AdaptingKeyStoreSpi
{
public BCPKCS12KeyStore3DES()
{
- super(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC);
+ super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC));
}
}
public static class DefPKCS12KeyStore
- extends PKCS12KeyStoreSpi
+ extends AdaptingKeyStoreSpi
{
public DefPKCS12KeyStore()
{
- super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
+ super(new DefaultJcaJceHelper(), new PKCS12KeyStoreSpi(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC));
}
}
public static class DefPKCS12KeyStore3DES
- extends PKCS12KeyStoreSpi
+ extends AdaptingKeyStoreSpi
{
public DefPKCS12KeyStore3DES()
{
- super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC);
+ super(new DefaultJcaJceHelper(), new PKCS12KeyStoreSpi(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC));
}
}
*/
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/util/AdaptingKeyStoreSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/util/AdaptingKeyStoreSpi.java
new file mode 100644
index 0000000..1a10ae1
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/util/AdaptingKeyStoreSpi.java
@@ -0,0 +1,186 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.keystore.util;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Enumeration;
+
+import com.android.org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi;
+import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.org.bouncycastle.util.Properties;
+
+/**
+ * Implements a certificate only JKS key store.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AdaptingKeyStoreSpi
+ extends KeyStoreSpi
+{
+ public static final String COMPAT_OVERRIDE = "keystore.type.compat";
+
+ private final JKSKeyStoreSpi jksStore;
+ private final KeyStoreSpi primaryStore;
+
+ private KeyStoreSpi keyStoreSpi;
+
+ public AdaptingKeyStoreSpi(JcaJceHelper helper, KeyStoreSpi primaryStore)
+ {
+ this.jksStore = new JKSKeyStoreSpi(helper);
+ this.primaryStore = primaryStore;
+ this.keyStoreSpi = primaryStore;
+ }
+
+ public boolean engineProbe(InputStream stream)
+ throws IOException
+ {
+ if (keyStoreSpi instanceof PKCS12KeyStoreSpi)
+ {
+ return ((PKCS12KeyStoreSpi)keyStoreSpi).engineProbe(stream);
+ }
+ return false;
+ }
+
+ public Key engineGetKey(String alias, char[] password)
+ throws NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ return keyStoreSpi.engineGetKey(alias, password);
+ }
+
+ public Certificate[] engineGetCertificateChain(String alias)
+ {
+ return keyStoreSpi.engineGetCertificateChain(alias);
+ }
+
+ public Certificate engineGetCertificate(String alias)
+ {
+ return keyStoreSpi.engineGetCertificate(alias);
+ }
+
+ public Date engineGetCreationDate(String alias)
+ {
+ return keyStoreSpi.engineGetCreationDate(alias);
+ }
+
+ public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
+ }
+
+ public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineSetKeyEntry(alias, key, chain);
+ }
+
+ public void engineSetCertificateEntry(String alias, Certificate cert)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineSetCertificateEntry(alias, cert);
+ }
+
+ public void engineDeleteEntry(String alias)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineDeleteEntry(alias);
+ }
+
+ public Enumeration<String> engineAliases()
+ {
+ return keyStoreSpi.engineAliases();
+ }
+
+ public boolean engineContainsAlias(String alias)
+ {
+ return keyStoreSpi.engineContainsAlias(alias);
+ }
+
+ public int engineSize()
+ {
+ return keyStoreSpi.engineSize();
+ }
+
+ public boolean engineIsKeyEntry(String alias)
+ {
+ return keyStoreSpi.engineIsKeyEntry(alias);
+ }
+
+ public boolean engineIsCertificateEntry(String alias)
+ {
+ return keyStoreSpi.engineIsCertificateEntry(alias);
+ }
+
+ public String engineGetCertificateAlias(Certificate cert)
+ {
+ return keyStoreSpi.engineGetCertificateAlias(cert);
+ }
+
+ public void engineStore(OutputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ keyStoreSpi.engineStore(stream, password);
+ }
+
+ public void engineStore(KeyStore.LoadStoreParameter parameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ keyStoreSpi.engineStore(parameter);
+ }
+
+ public void engineLoad(InputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (stream == null)
+ {
+ keyStoreSpi = primaryStore;
+ keyStoreSpi.engineLoad(null, password);
+ }
+ else
+ {
+ // the FIPS BCFKS/JKS compatibility is explicit and doesn't use the override.
+ if (Properties.isOverrideSet(COMPAT_OVERRIDE) || !(primaryStore instanceof PKCS12KeyStoreSpi))
+ {
+ if (!stream.markSupported())
+ {
+ stream = new BufferedInputStream(stream);
+ }
+
+ stream.mark(8);
+ if (jksStore.engineProbe(stream))
+ {
+ keyStoreSpi = jksStore;
+ }
+ else
+ {
+ keyStoreSpi = primaryStore;
+ }
+
+ stream.reset();
+ }
+ else
+ {
+ keyStoreSpi = primaryStore;
+ }
+
+ keyStoreSpi.engineLoad(stream, password);
+ }
+ }
+
+ public void engineLoad(KeyStore.LoadStoreParameter parameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ keyStoreSpi.engineLoad(parameter);
+ }
+}
+
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/util/JKSKeyStoreSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/util/JKSKeyStoreSpi.java
new file mode 100644
index 0000000..d27ee78
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/util/JKSKeyStoreSpi.java
@@ -0,0 +1,428 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.keystore.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.android.org.bouncycastle.crypto.Digest;
+import com.android.org.bouncycastle.jcajce.BCLoadStoreParameter;
+import com.android.org.bouncycastle.jcajce.provider.util.DigestFactory;
+import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+import com.android.org.bouncycastle.util.io.Streams;
+
+/**
+ * Implements a certificate only JKS key store.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JKSKeyStoreSpi
+ extends KeyStoreSpi
+{
+ private static final String NOT_IMPLEMENTED_MESSAGE = "BC JKS store is read-only and only supports certificate entries";
+
+ private final Hashtable<String, BCJKSTrustedCertEntry> certificateEntries = new Hashtable<String, BCJKSTrustedCertEntry>();
+ private final JcaJceHelper helper;
+
+ public JKSKeyStoreSpi(JcaJceHelper helper)
+ {
+ this.helper = helper;
+ }
+
+ public boolean engineProbe(InputStream stream)
+ throws IOException
+ {
+ DataInputStream storeStream;
+ if (stream instanceof DataInputStream)
+ {
+ storeStream = (DataInputStream)stream;
+ }
+ else
+ {
+ storeStream = new DataInputStream(stream);
+ }
+
+ int magic = storeStream.readInt();
+ int storeVersion = storeStream.readInt();
+ return magic == (int)0x0000feedfeedL && (storeVersion == 1 || storeVersion == 2);
+ }
+
+ public Key engineGetKey(String alias, char[] password)
+ throws NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ return null; // by definition
+ }
+
+ public Certificate[] engineGetCertificateChain(String alias)
+ {
+ return null; // by definition
+ }
+
+ public Certificate engineGetCertificate(String alias)
+ {
+ synchronized (certificateEntries)
+ {
+ BCJKSTrustedCertEntry ent = certificateEntries.get(alias);
+ if (ent != null)
+ {
+ return ent.cert;
+ }
+ }
+ return null;
+ }
+
+ public Date engineGetCreationDate(String alias)
+ {
+ synchronized (certificateEntries)
+ {
+ BCJKSTrustedCertEntry ent = certificateEntries.get(alias);
+ if (ent != null)
+ {
+ return ent.date;
+ }
+ }
+ return null;
+ }
+
+ public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineSetCertificateEntry(String alias, Certificate cert)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineDeleteEntry(String alias)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public Enumeration<String> engineAliases()
+ {
+ synchronized (certificateEntries)
+ {
+ return certificateEntries.keys();
+ }
+ }
+
+ public boolean engineContainsAlias(String alias)
+ {
+ if (alias == null)
+ {
+ throw new NullPointerException("alias value is null");
+ }
+
+ synchronized (certificateEntries)
+ {
+ return certificateEntries.containsKey(alias);
+ }
+ }
+
+ public int engineSize()
+ {
+ return certificateEntries.size();
+ }
+
+ public boolean engineIsKeyEntry(String alias)
+ {
+ return false; // by definition
+ }
+
+ public boolean engineIsCertificateEntry(String alias)
+ {
+ synchronized (certificateEntries)
+ {
+ return certificateEntries.containsKey(alias);
+ }
+ }
+
+ public String engineGetCertificateAlias(Certificate cert)
+ {
+ synchronized (certificateEntries)
+ {
+ for (Iterator<Map.Entry<String, BCJKSTrustedCertEntry>> it = certificateEntries.entrySet().iterator(); it.hasNext(); )
+ {
+ Map.Entry<String, BCJKSTrustedCertEntry> entry = it.next();
+ if (entry.getValue().cert.equals(cert))
+ {
+ return entry.getKey();
+ }
+ }
+ return null;
+ }
+ }
+
+ public void engineStore(OutputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ throw new IOException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineLoad(KeyStore.LoadStoreParameter loadStoreParameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (loadStoreParameter == null)
+ {
+ engineLoad(null, null);
+ }
+ else if (loadStoreParameter instanceof BCLoadStoreParameter)
+ {
+ BCLoadStoreParameter bcParam = (BCLoadStoreParameter)loadStoreParameter;
+
+ engineLoad(bcParam.getInputStream(), ParameterUtil.extractPassword(loadStoreParameter));
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "no support for 'param' of type " + loadStoreParameter.getClass().getName());
+ }
+ }
+
+ public void engineLoad(InputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (stream == null)
+ {
+ return;
+ }
+
+ ErasableByteStream storeStream = validateStream(stream, password);
+
+ synchronized (certificateEntries)
+ {
+ try
+ {
+ DataInputStream dIn = new DataInputStream(storeStream);
+
+ int magic = dIn.readInt();
+ int storeVersion = dIn.readInt();
+ if (magic == (int)0x0000feedfeedL)
+ {
+ CertificateFactory certFact = null;
+ Hashtable certFactories = null;
+
+ switch (storeVersion)
+ {
+ case 1: // all certs X.509
+ certFact = createCertFactory("X.509");
+ break;
+ case 2: // provision for format in store.
+ certFactories = new Hashtable();
+ break;
+ default:
+ throw new IllegalStateException("unable to discern store version");
+ }
+
+ int numEntries = dIn.readInt();
+ for (int t = 0; t < numEntries; t++)
+ {
+ int tag = dIn.readInt();
+ switch (tag)
+ {
+ case 1: // we can't process keys
+ throw new IOException(NOT_IMPLEMENTED_MESSAGE);
+ case 2: // certificate
+ String alias = dIn.readUTF();
+ Date date = new Date(dIn.readLong());
+
+ if (storeVersion == 2)
+ {
+ String certFormat = dIn.readUTF();
+ if (certFactories.containsKey(certFormat))
+ {
+ certFact = (CertificateFactory)certFactories.get(certFormat);
+ }
+ else
+ {
+ certFact = createCertFactory(certFormat);
+ certFactories.put(certFormat, certFact);
+ }
+ }
+
+ int l = dIn.readInt();
+ byte[] certData = new byte[l];
+ dIn.readFully(certData);
+
+ ErasableByteStream certStream = new ErasableByteStream(certData, 0, certData.length);
+ Certificate cert;
+ try
+ {
+ cert = certFact.generateCertificate(certStream);
+
+ if (certStream.available() != 0)
+ {
+ throw new IOException("password incorrect or store tampered with");
+ }
+ }
+ finally
+ {
+ certStream.erase();
+ }
+
+ certificateEntries.put(alias, new BCJKSTrustedCertEntry(date, cert));
+ break;
+ default:
+ throw new IllegalStateException("unable to discern entry type");
+ }
+ }
+ }
+
+ if (storeStream.available() != 0)
+ {
+ throw new IOException("password incorrect or store tampered with");
+ }
+ }
+ finally
+ {
+ storeStream.erase();
+ }
+ }
+ }
+
+ private CertificateFactory createCertFactory(String certFormat)
+ throws CertificateException
+ {
+ if (helper != null)
+ {
+ try
+ {
+ return helper.createCertificateFactory(certFormat);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new CertificateException(e.toString());
+ }
+ }
+ else
+ {
+ return CertificateFactory.getInstance(certFormat);
+ }
+ }
+
+ /**
+ * Process password updates the digest with the password.
+ *
+ * @param digest The digest instance.
+ * @param password The password.
+ */
+ private void addPassword(Digest digest, char[] password)
+ throws IOException
+ {
+ for (int i = 0; i < password.length; ++i)
+ {
+ digest.update((byte)(password[i] >> 8));
+ digest.update((byte)password[i]);
+ }
+
+ //
+ // This "Mighty Aphrodite" string goes all the way back to the
+ // first java betas in the mid 90's, why who knows? But see
+ // https://cryptosense.com/mighty-aphrodite-dark-secrets-of-the-java-keystore/
+ //
+ digest.update(Strings.toByteArray("Mighty Aphrodite"), 0, 16);
+ }
+
+ /**
+ * Validate password takes the checksum of the store and will either.
+ * 1. If password is null, load the store into memory, return the result.
+ * 2. If password is not null, load the store into memory, test the checksum, and if successful return
+ * a new input stream instance of the store.
+ * 3. Fail if there is a password and an invalid checksum.
+ *
+ * @param inputStream The input stream.
+ * @param password the password.
+ * @return Either the passed in input stream or a new input stream.
+ * @throws IOException
+ */
+ private ErasableByteStream validateStream(InputStream inputStream, char[] password)
+ throws IOException
+ {
+ Digest checksumCalculator = DigestFactory.getDigest("SHA-1");
+ byte[] rawStore = Streams.readAll(inputStream);
+
+ if (password != null)
+ {
+ addPassword(checksumCalculator, password);
+ checksumCalculator.update(rawStore, 0, rawStore.length - checksumCalculator.getDigestSize());
+
+ byte[] checksum = new byte[checksumCalculator.getDigestSize()];
+
+ checksumCalculator.doFinal(checksum, 0);
+
+ byte[] streamChecksum = new byte[checksum.length];
+ System.arraycopy(rawStore, rawStore.length - checksum.length, streamChecksum, 0, checksum.length);
+
+ if (!Arrays.constantTimeAreEqual(checksum, streamChecksum))
+ {
+ Arrays.fill(rawStore, (byte)0);
+ throw new IOException("password incorrect or store tampered with");
+ }
+
+ return new ErasableByteStream(rawStore, 0, rawStore.length - checksum.length);
+ }
+
+ return new ErasableByteStream(rawStore, 0, rawStore.length - checksumCalculator.getDigestSize());
+ }
+
+ /**
+ * BCJKSTrustedCertEntry is a internal container for the certificate entry.
+ */
+ private static final class BCJKSTrustedCertEntry
+ {
+ final Date date;
+ final Certificate cert;
+
+ public BCJKSTrustedCertEntry(Date date, Certificate cert)
+ {
+ this.date = date;
+ this.cert = cert;
+ }
+ }
+
+ private static final class ErasableByteStream
+ extends ByteArrayInputStream
+ {
+ public ErasableByteStream(byte[] buf, int offSet, int length)
+ {
+ super(buf, offSet, length);
+ }
+
+ public void erase()
+ {
+ // this will also erase the checksum from memory.
+ Arrays.fill(buf, (byte)0);
+ }
+ }
+
+
+}
+
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/util/ParameterUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/util/ParameterUtil.java
new file mode 100644
index 0000000..7bf9e06
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/util/ParameterUtil.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.keystore.util;
+
+import java.io.IOException;
+import java.security.KeyStore;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ParameterUtil
+{
+ public static char[] extractPassword(KeyStore.LoadStoreParameter bcParam)
+ throws IOException
+ {
+ KeyStore.ProtectionParameter protParam = bcParam.getProtectionParameter();
+
+ if (protParam == null)
+ {
+ return null;
+ }
+ else if (protParam instanceof KeyStore.PasswordProtection)
+ {
+ return ((KeyStore.PasswordProtection)protParam).getPassword();
+ }
+ else if (protParam instanceof KeyStore.CallbackHandlerProtection)
+ {
+ CallbackHandler handler = ((KeyStore.CallbackHandlerProtection)protParam).getCallbackHandler();
+
+ PasswordCallback passwordCallback = new PasswordCallback("password: ", false);
+
+ try
+ {
+ handler.handle(new Callback[]{passwordCallback});
+
+ return passwordCallback.getPassword();
+ }
+ catch (UnsupportedCallbackException e)
+ {
+ throw new IllegalArgumentException("PasswordCallback not recognised: " + e.getMessage(), e);
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "no support for protection parameter of type " + protParam.getClass().getName());
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/AES.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/AES.java
index 9684f35..7837d1c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/AES.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/AES.java
@@ -19,16 +19,13 @@
import javax.crypto.NoSuchPaddingException;
// END Android-added: Needed for setting padding with GCM
import com.android.org.bouncycastle.asn1.bc.BCObjectIdentifiers;
-// Android-removed: Unsupported algorithms
-// import org.bouncycastle.asn1.cms.CCMParameters;
-import com.android.org.bouncycastle.asn1.cms.GCMParameters;
import com.android.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import com.android.org.bouncycastle.crypto.BlockCipher;
-import com.android.org.bouncycastle.crypto.BufferedBlockCipher;
import com.android.org.bouncycastle.crypto.CipherKeyGenerator;
import com.android.org.bouncycastle.crypto.CipherParameters;
import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import com.android.org.bouncycastle.crypto.InvalidCipherTextException;
import com.android.org.bouncycastle.crypto.Mac;
import com.android.org.bouncycastle.crypto.engines.AESEngine;
@@ -43,9 +40,13 @@
import com.android.org.bouncycastle.crypto.modes.CBCBlockCipher;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.modes.CCMBlockCipher;
+// import org.bouncycastle.crypto.modes.CCMModeCipher;
import com.android.org.bouncycastle.crypto.modes.CFBBlockCipher;
import com.android.org.bouncycastle.crypto.modes.GCMBlockCipher;
import com.android.org.bouncycastle.crypto.modes.OFBBlockCipher;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.internal.asn1.cms.CCMParameters;
+import com.android.org.bouncycastle.internal.asn1.cms.GCMParameters;
import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator;
@@ -78,7 +79,7 @@
private AES()
{
}
-
+
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -91,7 +92,7 @@
{
public BlockCipher get()
{
- return new AESEngine();
+ return AESEngine.newInstance();
}
});
}
@@ -101,11 +102,11 @@
* @hide This class is not part of the Android public SDK API
*/
public static class CBC
- extends BaseBlockCipher
+ extends BaseBlockCipher
{
public CBC()
{
- super(new CBCBlockCipher(new AESEngine()), 128);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 128);
}
}
@@ -117,7 +118,7 @@
{
public CFB()
{
- super(new BufferedBlockCipher(new CFBBlockCipher(new AESEngine(), 128)), 128);
+ super(new DefaultBufferedBlockCipher(CFBBlockCipher.newInstance(AESEngine.newInstance(), 128)), 128);
}
}
@@ -129,7 +130,7 @@
{
public OFB()
{
- super(new BufferedBlockCipher(new OFBBlockCipher(new AESEngine(), 128)), 128);
+ super(new DefaultBufferedBlockCipher(new OFBBlockCipher(AESEngine.newInstance(), 128)), 128);
}
}
@@ -161,7 +162,7 @@
{
public CCM()
{
- super(new CCMBlockCipher(new AESEngine()), false, 12);
+ super(CCMBlockCipher.newInstance(AESEngine.newInstance()), false, 12);
}
}
@@ -170,7 +171,7 @@
{
public AESCMAC()
{
- super(new CMac(new AESEngine()));
+ super(new CMac(AESEngine.newInstance()));
}
}
@@ -179,7 +180,7 @@
{
public AESGMAC()
{
- super(new GMac(new GCMBlockCipher(new AESEngine())));
+ super(new GMac(GCMBlockCipher.newInstance(AESEngine.newInstance())));
}
}
@@ -194,7 +195,7 @@
private static class CCMMac
implements Mac
{
- private final CCMBlockCipher ccm = new CCMBlockCipher(new AESEngine());
+ private final CCMModeCipher ccm = CCMBlockCipher.newInstance(AESEngine.newInstance());
private int macLength = 8;
@@ -249,7 +250,7 @@
}
static public class KeyFactory
- extends BaseSecretKeyFactory
+ extends BaseSecretKeyFactory
{
public KeyFactory()
{
@@ -262,7 +263,7 @@
{
public Poly1305()
{
- super(new org.bouncycastle.crypto.macs.Poly1305(new AESEngine()));
+ super(new org.bouncycastle.crypto.macs.Poly1305(AESEngine.newInstance()));
}
}
@@ -305,7 +306,7 @@
{
public RFC3211Wrap()
{
- super(new RFC3211WrapEngine(new AESEngine()), 16);
+ super(new RFC3211WrapEngine(AESEngine.newInstance()), 16);
}
}
@@ -314,7 +315,7 @@
{
public RFC5649Wrap()
{
- super(new RFC5649WrapEngine(new AESEngine()));
+ super(new RFC5649WrapEngine(AESEngine.newInstance()));
}
}
*/
@@ -329,7 +330,7 @@
{
public PBEWithAESCBC()
{
- super(new CBCBlockCipher(new AESEngine()));
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()));
}
}
@@ -342,7 +343,7 @@
{
public PBEWithSHA1AESCBC128()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 128, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 128, 16);
}
}
@@ -354,7 +355,7 @@
{
public PBEWithSHA1AESCBC192()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 192, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 192, 16);
}
}
@@ -366,7 +367,7 @@
{
public PBEWithSHA1AESCBC256()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 256, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 256, 16);
}
}
@@ -379,7 +380,7 @@
{
public PBEWithSHA256AESCBC128()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 128, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 128, 16);
}
}
@@ -391,7 +392,7 @@
{
public PBEWithSHA256AESCBC192()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 192, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 192, 16);
}
}
@@ -403,7 +404,7 @@
{
public PBEWithSHA256AESCBC256()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 256, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 256, 16);
}
}
@@ -472,7 +473,7 @@
super("PBEWithSHA1And128BitAES-CBC-BC", null, true, PKCS12, SHA1, 128, 128);
}
}
-
+
/**
* PBEWithSHA1And192BitAES-BC
* @hide This class is not part of the Android public SDK API
@@ -485,7 +486,7 @@
super("PBEWithSHA1And192BitAES-CBC-BC", null, true, PKCS12, SHA1, 192, 128);
}
}
-
+
/**
* PBEWithSHA1And256BitAES-BC
* @hide This class is not part of the Android public SDK API
@@ -498,7 +499,7 @@
super("PBEWithSHA1And256BitAES-CBC-BC", null, true, PKCS12, SHA1, 256, 128);
}
}
-
+
/**
* PBEWithSHA256And128BitAES-BC
* @hide This class is not part of the Android public SDK API
@@ -511,7 +512,7 @@
super("PBEWithSHA256And128BitAES-CBC-BC", null, true, PKCS12, SHA256, 128, 128);
}
}
-
+
/**
* PBEWithSHA256And192BitAES-BC
* @hide This class is not part of the Android public SDK API
@@ -524,7 +525,7 @@
super("PBEWithSHA256And192BitAES-CBC-BC", null, true, PKCS12, SHA256, 192, 128);
}
}
-
+
/**
* PBEWithSHA256And256BitAES-BC
* @hide This class is not part of the Android public SDK API
@@ -537,7 +538,7 @@
super("PBEWithSHA256And256BitAES-CBC-BC", null, true, PKCS12, SHA256, 256, 128);
}
}
-
+
/**
* PBEWithMD5And128BitAES-OpenSSL
* @hide This class is not part of the Android public SDK API
@@ -550,7 +551,7 @@
super("PBEWithMD5And128BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 128, 128);
}
}
-
+
/**
* PBEWithMD5And192BitAES-OpenSSL
* @hide This class is not part of the Android public SDK API
@@ -563,7 +564,7 @@
super("PBEWithMD5And192BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 192, 128);
}
}
-
+
/**
* PBEWithMD5And256BitAES-OpenSSL
* @hide This class is not part of the Android public SDK API
@@ -592,7 +593,7 @@
protected AlgorithmParameters engineGenerateParameters()
{
- byte[] iv = new byte[16];
+ byte[] iv = new byte[16];
if (random == null)
{
@@ -631,7 +632,7 @@
protected AlgorithmParameters engineGenerateParameters()
{
- byte[] iv = new byte[12];
+ byte[] iv = new byte[12];
if (random == null)
{
@@ -670,7 +671,7 @@
protected AlgorithmParameters engineGenerateParameters()
{
- byte[] nonce = new byte[12];
+ byte[] nonce = new byte[12];
if (random == null)
{
@@ -778,7 +779,7 @@
{
if (paramSpec == AlgorithmParameterSpec.class || GcmSpecUtil.isGcmSpec(paramSpec))
{
- if (GcmSpecUtil.gcmSpecExists())
+ if (GcmSpecUtil.gcmSpecExtractable())
{
return GcmSpecUtil.extractGcmSpec(gcmParams.toASN1Primitive());
}
@@ -865,7 +866,7 @@
{
if (paramSpec == AlgorithmParameterSpec.class || GcmSpecUtil.isGcmSpec(paramSpec))
{
- if (GcmSpecUtil.gcmSpecExists())
+ if (GcmSpecUtil.gcmSpecExtractable())
{
return GcmSpecUtil.extractGcmSpec(ccmParams.toASN1Primitive());
}
@@ -893,7 +894,7 @@
extends SymmetricAlgorithmProvider
{
private static final String PREFIX = AES.class.getName();
-
+
/**
* These three got introduced in some messages as a result of a typo in an
* early document. We don't produce anything using these OID values, but we'll
@@ -1055,31 +1056,31 @@
provider.addAlgorithm("Cipher.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC128");
provider.addAlgorithm("Cipher.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC192");
provider.addAlgorithm("Cipher.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC256");
-
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
provider.addAlgorithm("Cipher.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
provider.addAlgorithm("Cipher.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
@@ -1093,48 +1094,48 @@
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And128BitAESCBCOpenSSL");
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And192BitAESCBCOpenSSL");
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND256BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And256BitAESCBCOpenSSL");
-
+
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND128BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd128BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND192BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd192BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND256BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd256BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And128BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And192BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And256BitAESBC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc, "PBEWITHSHAAND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc, "PBEWITHSHAAND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc, "PBEWITHSHAAND256BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc, "PBEWITHSHA256AND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc, "PBEWITHSHA256AND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc, "PBEWITHSHA256AND256BITAES-CBC-BC");
-
+
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND192BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND256BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND128BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND192BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND256BITAES-CBC-BC", "PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND128BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND192BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND256BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND128BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND192BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND256BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC","PKCS12PBE");
-
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND128BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND192BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND256BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND128BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND192BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND256BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC", "PKCS12PBE");
+
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), "PKCS12PBE");
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java
deleted file mode 100644
index a29228d..0000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.jcajce.provider.symmetric;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
-
-import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.cms.GCMParameters;
-import com.android.org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil;
-import com.android.org.bouncycastle.util.Integers;
-
-class GcmSpecUtil
-{
- static final Class gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
-
- static boolean gcmSpecExists()
- {
- return gcmSpecClass != null;
- }
-
- static boolean isGcmSpec(AlgorithmParameterSpec paramSpec)
- {
- return gcmSpecClass != null && gcmSpecClass.isInstance(paramSpec);
- }
-
- static boolean isGcmSpec(Class paramSpecClass)
- {
- return gcmSpecClass == paramSpecClass;
- }
-
- static AlgorithmParameterSpec extractGcmSpec(ASN1Primitive spec)
- throws InvalidParameterSpecException
- {
- try
- {
- GCMParameters gcmParams = GCMParameters.getInstance(spec);
- Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
-
- return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() });
- }
- catch (NoSuchMethodException e)
- {
- throw new InvalidParameterSpecException("No constructor found!"); // should never happen
- }
- catch (Exception e)
- {
- throw new InvalidParameterSpecException("Construction failed: " + e.getMessage()); // should never happen
- }
- }
-
- static GCMParameters extractGcmParameters(AlgorithmParameterSpec paramSpec)
- throws InvalidParameterSpecException
- {
- try
- {
- Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
- Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
-
- return new GCMParameters((byte[])iv.invoke(paramSpec, new Object[0]), ((Integer)tLen.invoke(paramSpec, new Object[0])).intValue() / 8);
- }
- catch (Exception e)
- {
- throw new InvalidParameterSpecException("Cannot process GCMParameterSpec");
- }
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
index 15880ad..f0467a1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
@@ -621,6 +621,15 @@
super("PBKDF2", PKCS5S2_UTF8, SM3);
}
}
+
+ public static class PBKDF2withSM3
+ extends BasePBKDF2
+ {
+ public PBKDF2withSM3()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, SM3);
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
index 8013761..b3f7300 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
@@ -73,19 +73,23 @@
public String getAlgorithm()
{
+ String rv = this.algorithm;
+
checkDestroyed(this);
- return algorithm;
+ return rv;
}
public String getFormat()
{
+ checkDestroyed(this);
+
return "RAW";
}
public byte[] getEncoded()
{
- checkDestroyed(this);
+ byte[] enc;
if (param != null)
{
@@ -100,58 +104,72 @@
kParam = (KeyParameter)param;
}
- return kParam.getKey();
+ enc = kParam.getKey();
}
else
{
if (type == PBE.PKCS12)
{
- return PBEParametersGenerator.PKCS12PasswordToBytes(password);
+ enc = PBEParametersGenerator.PKCS12PasswordToBytes(password);
}
else if (type == PBE.PKCS5S2_UTF8)
{
- return PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password);
+ enc = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password);
}
else
{
- return PBEParametersGenerator.PKCS5PasswordToBytes(password);
+ enc = PBEParametersGenerator.PKCS5PasswordToBytes(password);
}
}
+
+ checkDestroyed(this);
+
+ return enc;
}
int getType()
{
+ int rv = type;
+
checkDestroyed(this);
- return type;
+ return rv;
}
int getDigest()
{
+ int rv = digest;
+
checkDestroyed(this);
- return digest;
+ return rv;
}
int getKeySize()
{
+ int rv = keySize;
+
checkDestroyed(this);
- return keySize;
+ return rv;
}
public int getIvSize()
{
+ int rv = ivSize;
+
checkDestroyed(this);
- return ivSize;
+ return rv;
}
public CipherParameters getParam()
{
+ CipherParameters rv = param;
+
checkDestroyed(this);
- return param;
+ return rv;
}
/* (non-Javadoc)
@@ -159,14 +177,16 @@
*/
public char[] getPassword()
{
+ char[] clone = Arrays.clone(password);
+
checkDestroyed(this);
- if (password == null)
+ if (clone == null)
{
throw new IllegalStateException("no password available");
}
- return Arrays.clone(password);
+ return clone;
}
/* (non-Javadoc)
@@ -174,9 +194,11 @@
*/
public byte[] getSalt()
{
+ byte[] clone = Arrays.clone(salt);
+
checkDestroyed(this);
- return Arrays.clone(salt);
+ return clone;
}
/* (non-Javadoc)
@@ -184,16 +206,20 @@
*/
public int getIterationCount()
{
+ int rv = iterationCount;
+
checkDestroyed(this);
- return iterationCount;
+ return rv;
}
public ASN1ObjectIdentifier getOID()
{
+ ASN1ObjectIdentifier rv = oid;
+
checkDestroyed(this);
- return oid;
+ return rv;
}
public void setTryWrongPKCS12Zero(boolean tryWrong)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
index 51310cb..bf16ee9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
@@ -29,17 +29,20 @@
// import javax.crypto.spec.RC5ParameterSpec;
import com.android.org.bouncycastle.asn1.DEROctetString;
-import com.android.org.bouncycastle.asn1.cms.GCMParameters;
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.crypto.BlockCipher;
import com.android.org.bouncycastle.crypto.BufferedBlockCipher;
import com.android.org.bouncycastle.crypto.CipherParameters;
import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import com.android.org.bouncycastle.crypto.InvalidCipherTextException;
import com.android.org.bouncycastle.crypto.OutputLengthException;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.engines.DSTU7624Engine;
+// import org.bouncycastle.crypto.fpe.FPEEngine;
+// import org.bouncycastle.crypto.fpe.FPEFF1Engine;
+// import org.bouncycastle.crypto.fpe.FPEFF3_1Engine;
import com.android.org.bouncycastle.crypto.modes.AEADBlockCipher;
import com.android.org.bouncycastle.crypto.modes.AEADCipher;
import com.android.org.bouncycastle.crypto.modes.CBCBlockCipher;
@@ -51,6 +54,7 @@
// import org.bouncycastle.crypto.modes.GCFBBlockCipher;
import com.android.org.bouncycastle.crypto.modes.GCMBlockCipher;
// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.modes.GCMSIVBlockCipher;
// import org.bouncycastle.crypto.modes.GOFBBlockCipher;
// import org.bouncycastle.crypto.modes.KCCMBlockCipher;
// import org.bouncycastle.crypto.modes.KCTRBlockCipher;
@@ -60,6 +64,8 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher;
// import org.bouncycastle.crypto.modes.PGPCFBBlockCipher;
+import com.android.org.bouncycastle.crypto.paddings.PKCS7Padding;
+// import org.bouncycastle.crypto.params.FPEParameters;
import com.android.org.bouncycastle.crypto.modes.SICBlockCipher;
import com.android.org.bouncycastle.crypto.paddings.BlockCipherPadding;
import com.android.org.bouncycastle.crypto.paddings.ISO10126d2Padding;
@@ -85,6 +91,8 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
// import org.bouncycastle.jcajce.spec.RepeatedSecretKeySpec;
+import com.android.org.bouncycastle.internal.asn1.cms.GCMParameters;
+// import org.bouncycastle.jcajce.spec.FPEParameterSpec;
import com.android.org.bouncycastle.util.Arrays;
import com.android.org.bouncycastle.util.Strings;
@@ -96,7 +104,6 @@
implements PBE
{
private static final int BUF_SIZE = 512;
- private static final Class gcmSpecClass = ClassUtil.loadClass(BaseBlockCipher.class, "javax.crypto.spec.GCMParameterSpec");
//
// specs we can handle.
@@ -106,7 +113,7 @@
// Android-removed: Unsupported alhorithms
// RC2ParameterSpec.class,
// RC5ParameterSpec.class,
- gcmSpecClass,
+ GcmSpecUtil.gcmSpecClass,
// Android-removed: unsupported algorithms
// GOST28147ParameterSpec.class,
IvParameterSpec.class,
@@ -170,7 +177,14 @@
AEADBlockCipher engine)
{
this.baseEngine = engine.getUnderlyingCipher();
- this.ivLength = baseEngine.getBlockSize();
+ if (engine.getAlgorithmName().indexOf("GCM") >= 0)
+ {
+ this.ivLength = 12;
+ }
+ else
+ {
+ this.ivLength = baseEngine.getBlockSize();
+ }
this.cipher = new AEADGenericBlockCipher(engine);
}
@@ -352,7 +366,7 @@
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(
- new CBCBlockCipher(baseEngine));
+ CBCBlockCipher.newInstance(baseEngine));
}
else if (modeName.startsWith("OFB"))
{
@@ -378,12 +392,12 @@
int wordSize = Integer.parseInt(modeName.substring(3));
cipher = new BufferedGenericBlockCipher(
- new CFBBlockCipher(baseEngine, wordSize));
+ CFBBlockCipher.newInstance(baseEngine, wordSize));
}
else
{
cipher = new BufferedGenericBlockCipher(
- new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
+ CFBBlockCipher.newInstance(baseEngine, 8 * baseEngine.getBlockSize()));
}
}
// BEGIN Android-removed: Unsupported modes
@@ -407,6 +421,18 @@
cipher = new BufferedGenericBlockCipher(
new OpenPGPCFBBlockCipher(baseEngine));
}
+ else if (modeName.equals("FF1"))
+ {
+ ivLength = 0;
+ cipher = new BufferedFPEBlockCipher(
+ new FPEFF1Engine(baseEngine));
+ }
+ else if (modeName.equals("FF3-1"))
+ {
+ ivLength = 0;
+ cipher = new BufferedFPEBlockCipher(
+ new FPEFF3_1Engine(baseEngine));
+ }
else if (modeName.equals("SIC"))
{
ivLength = baseEngine.getBlockSize();
@@ -415,8 +441,8 @@
throw new IllegalArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
}
fixedIv = false;
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new SICBlockCipher(baseEngine)));
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
+ SICBlockCipher.newInstance(baseEngine)));
}
*/
// END Android-removed: Unsupported modes
@@ -428,14 +454,14 @@
/*
if (baseEngine instanceof DSTU7624Engine)
{
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
new KCTRBlockCipher(baseEngine)));
}
else
{
*/
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new SICBlockCipher(baseEngine)));
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
+ SICBlockCipher.newInstance(baseEngine)));
/*
}
*/
@@ -445,13 +471,13 @@
else if (modeName.equals("GOFB"))
{
ivLength = baseEngine.getBlockSize();
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
new GOFBBlockCipher(baseEngine)));
}
else if (modeName.equals("GCFB"))
{
ivLength = baseEngine.getBlockSize();
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
new GCFBBlockCipher(baseEngine)));
}
*/
@@ -459,7 +485,7 @@
else if (modeName.equals("CTS"))
{
ivLength = baseEngine.getBlockSize();
- cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(new CBCBlockCipher(baseEngine)));
+ cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(CBCBlockCipher.newInstance(baseEngine)));
}
else if (modeName.equals("CCM"))
{
@@ -473,7 +499,7 @@
else
{
*/
- cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine));
+ cipher = new AEADGenericBlockCipher(CCMBlockCipher.newInstance(baseEngine));
/*
}
*/
@@ -509,12 +535,13 @@
/*
if (baseEngine instanceof DSTU7624Engine)
{
+ ivLength = baseEngine.getBlockSize();
cipher = new AEADGenericBlockCipher(new KGCMBlockCipher(baseEngine));
}
else
{
*/
- cipher = new AEADGenericBlockCipher(new GCMBlockCipher(baseEngine));
+ cipher = new AEADGenericBlockCipher(GCMBlockCipher.newInstance(baseEngine));
/*
}
*/
@@ -540,7 +567,7 @@
{
if (cipher.wrapOnNoPadding())
{
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(cipher.getUnderlyingCipher()));
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(cipher.getUnderlyingCipher()));
}
}
else if (paddingName.equals("WITHCTS") || paddingName.equals("CTSPADDING") || paddingName.equals("CS3PADDING"))
@@ -849,7 +876,7 @@
GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
param = new ParametersWithSBox(
- new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox());
+ new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSBox());
if (gost28147Param.getIV() != null && ivLength != 0)
{
@@ -922,9 +949,15 @@
ivParam = (ParametersWithIV)param;
}
}
+ else if (params instanceof FPEParameterSpec)
+ {
+ FPEParameterSpec spec = (FPEParameterSpec)params;
+
+ param = new FPEParameters((KeyParameter)param, spec.getRadixConverter(), spec.getTweak(), spec.isUsingInverseFunction());
+ }
*/
// END Android-removed: Unsupported algorithms
- else if (gcmSpecClass != null && gcmSpecClass.isInstance(params))
+ else if (GcmSpecUtil.isGcmSpec(params))
{
if (!isAEADModeName(modeName) && !(cipher instanceof AEADGenericBlockCipher))
{
@@ -1048,7 +1081,7 @@
// need to pick up IV and SBox.
GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
- param = new ParametersWithSBox(param, gost28147Param.getSbox());
+ param = new ParametersWithSBox(param, gost28147Param.getSBox());
if (gost28147Param.getIV() != null && ivLength != 0)
{
@@ -1075,7 +1108,7 @@
// need to pick up IV and SBox.
GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
- param = new ParametersWithSBox(param, gost28147Param.getSbox());
+ param = new ParametersWithSBox(param, gost28147Param.getSBox());
if (gost28147Param.getIV() != null && ivLength != 0)
{
@@ -1351,7 +1384,7 @@
BufferedGenericBlockCipher(com.android.org.bouncycastle.crypto.BlockCipher cipher)
{
- this.cipher = new PaddedBufferedBlockCipher(cipher);
+ this(cipher, new PKCS7Padding());
}
BufferedGenericBlockCipher(com.android.org.bouncycastle.crypto.BlockCipher cipher, BlockCipherPadding padding)
@@ -1421,6 +1454,85 @@
}
}
+ // BEGIN Android-removed: unsupported
+ // private static class BufferedFPEBlockCipher
+ // implements GenericBlockCipher
+ // {
+ // private FPEEngine cipher;
+ // private ErasableOutputStream eOut = new ErasableOutputStream();
+
+ // BufferedFPEBlockCipher(FPEEngine cipher)
+ // {
+ // this.cipher = cipher;
+ // }
+
+ // public void init(boolean forEncryption, CipherParameters params)
+ // throws IllegalArgumentException
+ // {
+ // cipher.init(forEncryption, params);
+ // }
+
+ // public boolean wrapOnNoPadding()
+ // {
+ // return false;
+ // }
+
+ // public String getAlgorithmName()
+ // {
+ // return cipher.getAlgorithmName();
+ // }
+
+ // public org.bouncycastle.crypto.BlockCipher getUnderlyingCipher()
+ // {
+ // throw new IllegalStateException("not applicable for FPE");
+ // }
+
+ // public int getOutputSize(int len)
+ // {
+ // return eOut.size() + len;
+ // }
+
+ // public int getUpdateOutputSize(int len)
+ // {
+ // return 0;
+ // }
+
+ // public void updateAAD(byte[] input, int offset, int length)
+ // {
+ // throw new UnsupportedOperationException("AAD is not supported in the current mode.");
+ // }
+
+ // public int processByte(byte in, byte[] out, int outOff)
+ // throws DataLengthException
+ // {
+ // eOut.write(in);
+
+ // return 0;
+ // }
+
+ // public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ // throws DataLengthException
+ // {
+ // eOut.write(in, inOff, len);
+
+ // return 0;
+ // }
+
+ // public int doFinal(byte[] out, int outOff)
+ // throws IllegalStateException, BadPaddingException
+ // {
+ // try
+ // {
+ // return cipher.processBlock(eOut.getBuf(), 0, eOut.size(), out, outOff);
+ // }
+ // finally
+ // {
+ // eOut.erase();
+ // }
+ // }
+ // }
+ // END Android-removed: unsupported
+
private static class AEADGenericBlockCipher
implements GenericBlockCipher
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
index d7b1c4e..5d5855f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
@@ -36,8 +36,6 @@
public class BaseMac
extends MacSpi implements PBE
{
- private static final Class gcmSpecClass = ClassUtil.loadClass(BaseMac.class, "javax.crypto.spec.GCMParameterSpec");
-
private Mac macEngine;
private int scheme = PKCS12;
@@ -215,7 +213,7 @@
{
param = new KeyParameter(key.getEncoded());
}
- else if (gcmSpecClass != null && gcmSpecClass.isAssignableFrom(params.getClass()))
+ else if (GcmSpecUtil.isGcmSpec(params))
{
param = GcmSpecUtil.extractAeadParameters(keyParam, params);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java
index c306ae7..9b1cd28 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java
@@ -27,7 +27,9 @@
{
try
{
- return Class.forName(className);
+ ClassLoader classLoader = ClassLoader.getSystemClassLoader();
+
+ return classLoader.loadClass(className);
}
catch (Exception e)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
index 0099755..bdb07a5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
@@ -11,9 +11,9 @@
import java.security.spec.InvalidParameterSpecException;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.cms.GCMParameters;
import com.android.org.bouncycastle.crypto.params.AEADParameters;
import com.android.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.org.bouncycastle.internal.asn1.cms.GCMParameters;
import com.android.org.bouncycastle.util.Integers;
/**
@@ -21,25 +21,48 @@
*/
public class GcmSpecUtil
{
- static final Class gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
-
- static final Method tLen;
- static final Method iv;
+ static final Class gcmSpecClass;
+ private static final Constructor constructor;
+ private static final Method tLen;
+ private static final Method iv;
static
{
+ gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
+
if (gcmSpecClass != null)
{
+ constructor = extractConstructor();
tLen = extractMethod("getTLen");
iv = extractMethod("getIV");
}
else
{
+ constructor = null;
tLen = null;
iv = null;
}
}
+ private static Constructor extractConstructor()
+ {
+ try
+ {
+ return (Constructor)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return gcmSpecClass.getConstructor(new Class[]{ Integer.TYPE, byte[].class });
+ }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ return null;
+ }
+ }
+
private static Method extractMethod(final String name)
{
try
@@ -64,6 +87,11 @@
return gcmSpecClass != null;
}
+ public static boolean gcmSpecExtractable()
+ {
+ return constructor != null;
+ }
+
public static boolean isGcmSpec(AlgorithmParameterSpec paramSpec)
{
return gcmSpecClass != null && gcmSpecClass.isInstance(paramSpec);
@@ -80,14 +108,9 @@
try
{
GCMParameters gcmParams = GCMParameters.getInstance(spec);
- Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() });
}
- catch (NoSuchMethodException e)
- {
- throw new InvalidParameterSpecException("No constructor found!"); // should never happen
- }
catch (Exception e)
{
throw new InvalidParameterSpecException("Construction failed: " + e.getMessage()); // should never happen
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
index f61f91e..3977c7b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
@@ -15,6 +15,7 @@
import javax.crypto.spec.PBEParameterSpec;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
import com.android.org.bouncycastle.crypto.PBEParametersGenerator;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.digests.GOST3411Digest;
@@ -107,25 +108,25 @@
{
// Android-removed: Unsupported algorithms
// case MD2:
- // generator = new PKCS5S2ParametersGenerator(new MD2Digest());
+ // generator = new PKCS5S2ParametersGenerator(new MD2Digest(CryptoServicePurpose.PRF));
// break;
case MD5:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createMD5());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createMD5PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getMD5());
break;
case SHA1:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA1());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA1PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA1());
break;
// BEGIN Android-removed: Unsupported algorithms
/*
case RIPEMD160:
- generator = new PKCS5S2ParametersGenerator(new RIPEMD160Digest());
+ generator = new PKCS5S2ParametersGenerator(new RIPEMD160Digest(CryptoServicePurpose.PRF));
break;
case TIGER:
- generator = new PKCS5S2ParametersGenerator(new TigerDigest());
+ generator = new PKCS5S2ParametersGenerator(new TigerDigest(CryptoServicePurpose.PRF));
break;
*/
// END Android-removed: Unsupported algorithms
@@ -136,36 +137,43 @@
break;
// Android-removed: Unsupported algorithms
// case GOST3411:
+ // generator = new PKCS5S2ParametersGenerator(new GOST3411Digest(CryptoServicePurpose.PRF));
+ // break;
+ // Android-removed: Unsupported algorithms
+ // case GOST3411:
// generator = new PKCS5S2ParametersGenerator(new GOST3411Digest());
// break;
case SHA224:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA224());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA224PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA224());
break;
case SHA384:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA384());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA384PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA384());
break;
case SHA512:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA512());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA512PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA512());
break;
// BEGIN Android-removed: Unsupported algorithms
/*
case SHA3_224:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_224());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_224PRF());
break;
case SHA3_256:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_256());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_256PRF());
break;
case SHA3_384:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_384());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_384PRF());
break;
case SHA3_512:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_512());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_512PRF());
+ break;
+ case SM3:
+ generator = new PKCS5S2ParametersGenerator(new SM3Digest(CryptoServicePurpose.PRF));
break;
case SM3:
generator = new PKCS5S2ParametersGenerator(new SM3Digest());
@@ -182,50 +190,54 @@
{
// Android-removed: Unsupported algorithms
// case MD2:
- // generator = new PKCS12ParametersGenerator(new MD2Digest());
+ // generator = new PKCS12ParametersGenerator(new MD2Digest(CryptoServicePurpose.PRF));
// break;
case MD5:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createMD5());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createMD5PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getMD5());
break;
case SHA1:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA1());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA1PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA1());
break;
// BEGIN Android-removed: Unsupported algorithms
/*
case RIPEMD160:
- generator = new PKCS12ParametersGenerator(new RIPEMD160Digest());
+ generator = new PKCS12ParametersGenerator(new RIPEMD160Digest(CryptoServicePurpose.PRF));
break;
case TIGER:
- generator = new PKCS12ParametersGenerator(new TigerDigest());
+ generator = new PKCS12ParametersGenerator(new TigerDigest(CryptoServicePurpose.PRF));
break;
*/
// END Android-removed: Unsupported algorithms
case SHA256:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA256());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA256PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA256());
break;
// Android-removed: Unsupported algorithms
// case GOST3411:
+ // generator = new PKCS12ParametersGenerator(new GOST3411Digest(CryptoServicePurpose.PRF));
+ // break;
+ // Android-removed: Unsupported algorithms
+ // case GOST3411:
// generator = new PKCS12ParametersGenerator(new GOST3411Digest());
// break;
case SHA224:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA224());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA224PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA224());
break;
case SHA384:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA384());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA384PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA384());
break;
case SHA512:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA512());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA512PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA512());
break;
default:
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java
index 82b7984..b73bdc2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java
@@ -1,6 +1,8 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jcajce.provider.util;
+import java.util.Map;
+
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
@@ -21,6 +23,24 @@
provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, algorithm);
}
+ protected void addSignatureAlias(
+ ConfigurableProvider provider,
+ String algorithm,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, algorithm);
+ }
+
+ protected void addSignatureAlgorithm(
+ ConfigurableProvider provider,
+ String digest,
+ String algorithm,
+ String className)
+ {
+ addSignatureAlgorithm(provider, digest, algorithm, className, null);
+ }
+
protected void addSignatureAlgorithm(
ConfigurableProvider provider,
String digest,
@@ -37,8 +57,103 @@
provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation1, mainName);
provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation2, mainName);
provider.addAlgorithm("Alg.Alias.Signature." + alias, mainName);
- provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
- provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
+ }
+ }
+
+ protected void addSignatureAlgorithm(
+ ConfigurableProvider provider,
+ String digest,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid,
+ Map<String, String> attributes)
+ {
+ String mainName = digest + "WITH" + algorithm;
+ String jdk11Variation1 = digest + "with" + algorithm;
+ String jdk11Variation2 = digest + "With" + algorithm;
+ String alias = digest + "/" + algorithm;
+
+ provider.addAlgorithm("Signature." + mainName, className);
+ provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation1, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation2, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + alias, mainName);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
+ }
+ provider.addAttributes("Signature." + mainName, attributes);
+ }
+
+ protected void addKeyPairGeneratorAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("KeyPairGenerator." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyPairGenerator." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.KeyPairGenerator.OID." + oid, algorithm);
+ }
+ }
+
+ protected void addKeyFactoryAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid,
+ AsymmetricKeyInfoConverter keyInfoConverter)
+ {
+ provider.addAlgorithm("KeyFactory." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyFactory." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.KeyFactory.OID." + oid, algorithm);
+
+ provider.addKeyInfoConverter(oid, keyInfoConverter);
+ }
+ }
+
+ protected void addKeyGeneratorAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("KeyGenerator." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyGenerator." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.OID." + oid, algorithm);
+ }
+ }
+
+ protected void addCipherAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("Cipher." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.Cipher." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.Cipher.OID." + oid, algorithm);
+ }
+ }
+
+ protected void registerKeyFactoryOid(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name, AsymmetricKeyInfoConverter keyFactory)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyFactory." + oid, name);
+ provider.addAlgorithm("Alg.Alias.KeyFactory.OID." + oid, name);
+
+ provider.addKeyInfoConverter(oid, keyFactory);
}
protected void registerOid(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name, AsymmetricKeyInfoConverter keyFactory)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/util/DigestFactory.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/util/DigestFactory.java
index d30500a..2575cc6 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/util/DigestFactory.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/util/DigestFactory.java
@@ -35,6 +35,8 @@
private static Set sha3_256 = new HashSet();
private static Set sha3_384 = new HashSet();
private static Set sha3_512 = new HashSet();
+ private static Set shake128 = new HashSet();
+ private static Set shake256 = new HashSet();
*/
// END Android-removed: Unsupported algorithms
@@ -86,6 +88,18 @@
sha3_512.add("SHA3-512");
sha3_512.add(NISTObjectIdentifiers.id_sha3_512.getId());
+
+ shake128.add("SHAKE128");
+ shake128.add(NISTObjectIdentifiers.id_shake128.getId());
+
+ shake256.add("SHAKE256");
+ shake256.add(NISTObjectIdentifiers.id_shake256.getId());
+
+ oids.put("SHAKE128", NISTObjectIdentifiers.id_shake128);
+ oids.put(NISTObjectIdentifiers.id_shake128.getId(), NISTObjectIdentifiers.id_shake128);
+
+ oids.put("SHAKE256", NISTObjectIdentifiers.id_shake256);
+ oids.put(NISTObjectIdentifiers.id_shake256.getId(), NISTObjectIdentifiers.id_shake256);
*/
// END Android-removed: Unsupported algorithms
@@ -202,6 +216,14 @@
{
return org.bouncycastle.crypto.util.DigestFactory.createSHA3_512();
}
+ if (shake128.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHAKE128();
+ }
+ if (shake256.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHAKE256();
+ }
*/
// END Android-removed: Unsupported algorithms
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/FPEParameterSpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/FPEParameterSpec.java
new file mode 100644
index 0000000..8a95618
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/FPEParameterSpec.java
@@ -0,0 +1,55 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.android.org.bouncycastle.crypto.util.RadixConverter;
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class FPEParameterSpec
+ implements AlgorithmParameterSpec
+{
+ private final RadixConverter radixConverter;
+ private final byte[] tweak;
+ private final boolean useInverse;
+
+ public FPEParameterSpec(int radix, byte[] tweak)
+ {
+ this(radix, tweak, false);
+ }
+
+ public FPEParameterSpec(int radix, byte[] tweak, boolean useInverse)
+ {
+ this(new RadixConverter(radix), tweak, useInverse);
+ }
+
+ public FPEParameterSpec(RadixConverter radixConverter, byte[] tweak, boolean useInverse)
+ {
+ this.radixConverter = radixConverter;
+ this.tweak = Arrays.clone(tweak);
+ this.useInverse = useInverse;
+ }
+
+ public int getRadix()
+ {
+ return radixConverter.getRadix();
+ }
+
+ public RadixConverter getRadixConverter()
+ {
+ return radixConverter;
+ }
+
+ public byte[] getTweak()
+ {
+ return Arrays.clone(tweak);
+ }
+
+ public boolean isUsingInverseFunction()
+ {
+ return useInverse;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java
new file mode 100644
index 0000000..a684e6a
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java
@@ -0,0 +1,99 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.security.auth.Destroyable;
+
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * SP 800-56C Hybrid Value spec, to allow the secret in a key agreement to be
+ * created as "Z | T" where T is some other secret value as described in Section 2.
+ * <p>
+ * Get methods throw IllegalStateException if destroy() is called.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HybridValueParameterSpec
+ implements AlgorithmParameterSpec, Destroyable
+{
+ private final AtomicBoolean hasBeenDestroyed = new AtomicBoolean(false);
+
+ private volatile byte[] t;
+ private volatile AlgorithmParameterSpec baseSpec;
+
+ /**
+ * Create a spec with T set to t and the spec for the KDF in the agreement to baseSpec.
+ * Note: the t value is not copied.
+ *
+ * @param t a shared secret to be concatenated with the agreement's Z value.
+ * @param baseSpec the base spec for the agreements KDF.
+ */
+ public HybridValueParameterSpec(byte[] t, AlgorithmParameterSpec baseSpec)
+ {
+ this.t = t;
+ this.baseSpec = baseSpec;
+ }
+
+ /**
+ * Return a reference to the T value.
+ *
+ * @return a reference to T.
+ */
+ public byte[] getT()
+ {
+ byte[] tVal = t;
+
+ checkDestroyed();
+
+ return tVal;
+ }
+
+ /**
+ * Return the base parameter spec.
+ *
+ * @return base spec to be applied to the KDF.
+ */
+ public AlgorithmParameterSpec getBaseParameterSpec()
+ {
+ AlgorithmParameterSpec rv = this.baseSpec;
+
+ checkDestroyed();
+
+ return rv;
+ }
+
+ /**
+ * Return true if the destroy() method is called and the contents are
+ * erased.
+ *
+ * @return true if destroyed, false otherwise.
+ */
+ public boolean isDestroyed()
+ {
+ return this.hasBeenDestroyed.get();
+ }
+
+ /**
+ * Destroy this parameter spec, explicitly erasing its contents.
+ */
+ public void destroy()
+ {
+ if (!hasBeenDestroyed.getAndSet(true))
+ {
+ Arrays.clear(t);
+ this.t = null;
+ this.baseSpec = null;
+ }
+ }
+
+ private void checkDestroyed()
+ {
+ if (isDestroyed())
+ {
+ throw new IllegalStateException("spec has been destroyed");
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/IESKEMParameterSpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/IESKEMParameterSpec.java
new file mode 100644
index 0000000..fc07eeb
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/IESKEMParameterSpec.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * Parameter spec for an integrated encryptor KEM, as in IEEE_Std_1609_2
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IESKEMParameterSpec
+ implements AlgorithmParameterSpec
+{
+ private final byte[] recipientInfo;
+ private final boolean usePointCompression;
+
+
+ /**
+ * Set the IESKEM parameters.
+ *
+ * @param recipientInfo recipient data.
+ */
+ public IESKEMParameterSpec(
+ byte[] recipientInfo)
+ {
+ this(recipientInfo, false);
+ }
+
+ /**
+ * Set the IESKEM parameters - specifying point compression.
+ *
+ * @param recipientInfo recipient data.
+ * @param usePointCompression use point compression on output (ignored on input).
+ */
+ public IESKEMParameterSpec(
+ byte[] recipientInfo,
+ boolean usePointCompression)
+ {
+ this.recipientInfo = Arrays.clone(recipientInfo);
+ this.usePointCompression = usePointCompression;
+ }
+
+ public byte[] getRecipientInfo()
+ {
+ return Arrays.clone(recipientInfo);
+ }
+
+ public boolean hasUsePointCompression()
+ {
+ return usePointCompression;
+ }
+}
\ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/KEMExtractSpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/KEMExtractSpec.java
new file mode 100644
index 0000000..868909f
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/KEMExtractSpec.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.spec;
+
+import java.security.PrivateKey;
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KEMExtractSpec
+ implements AlgorithmParameterSpec
+{
+ private final PrivateKey privateKey;
+ private final byte[] encapsulation;
+ private final String keyAlgorithmName;
+ private final int keySizeInBits;
+
+ public KEMExtractSpec(PrivateKey privateKey, byte[] encapsulation, String keyAlgorithmName)
+ {
+ this(privateKey, encapsulation, keyAlgorithmName, 256);
+ }
+
+ public KEMExtractSpec(PrivateKey privateKey, byte[] encapsulation, String keyAlgorithmName, int keySizeInBits)
+ {
+ this.privateKey = privateKey;
+ this.encapsulation = Arrays.clone(encapsulation);
+ this.keyAlgorithmName = keyAlgorithmName;
+ this.keySizeInBits = keySizeInBits;
+ }
+
+ public byte[] getEncapsulation()
+ {
+ return Arrays.clone(encapsulation);
+ }
+
+ public PrivateKey getPrivateKey()
+ {
+ return privateKey;
+ }
+
+ public String getKeyAlgorithmName()
+ {
+ return keyAlgorithmName;
+ }
+
+ public int getKeySize()
+ {
+ return keySizeInBits;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java
new file mode 100644
index 0000000..81457a3
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java
@@ -0,0 +1,43 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.spec;
+
+import java.security.PublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KEMGenerateSpec
+ implements AlgorithmParameterSpec
+{
+ private final PublicKey publicKey;
+ private final String keyAlgorithmName;
+ private final int keySizeInBits;
+
+ public KEMGenerateSpec(PublicKey publicKey, String keyAlgorithmName)
+ {
+ this(publicKey, keyAlgorithmName, 256);
+ }
+
+ public KEMGenerateSpec(PublicKey publicKey, String keyAlgorithmName, int keySizeInBits)
+ {
+ this.publicKey = publicKey;
+ this.keyAlgorithmName = keyAlgorithmName;
+ this.keySizeInBits = keySizeInBits;
+ }
+
+ public PublicKey getPublicKey()
+ {
+ return publicKey;
+ }
+
+ public String getKeyAlgorithmName()
+ {
+ return keyAlgorithmName;
+ }
+
+ public int getKeySize()
+ {
+ return keySizeInBits;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/RawEncodedKeySpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/RawEncodedKeySpec.java
new file mode 100644
index 0000000..d7ff7a0
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/RawEncodedKeySpec.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.EncodedKeySpec;
+
+/**
+ * An encoded key spec that just wraps the minimal data for a public/private key representation.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RawEncodedKeySpec
+ extends EncodedKeySpec
+{
+ /**
+ * Base constructor - just the minimal data.
+ *
+ * @param bytes the public/private key data.
+ */
+ public RawEncodedKeySpec(byte[] bytes)
+ {
+ super(bytes);
+ }
+
+ public String getFormat()
+ {
+ return "RAW";
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
index 36b9234..802c6e0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
@@ -12,14 +12,47 @@
implements AlgorithmParameterSpec
{
private final byte[] userKeyingMaterial;
+ private final byte[] salt;
+ /**
+ * Base constructor.
+ *
+ * @param userKeyingMaterial the bytes to be mixed in to the key agreement's KDF.
+ */
public UserKeyingMaterialSpec(byte[] userKeyingMaterial)
{
- this.userKeyingMaterial = Arrays.clone(userKeyingMaterial);
+ this(userKeyingMaterial, null);
}
+ /**
+ * Base constructor.
+ *
+ * @param userKeyingMaterial the bytes to be mixed in to the key agreement's KDF.
+ * @param salt the salt to use with the underlying KDF.
+ */
+ public UserKeyingMaterialSpec(byte[] userKeyingMaterial, byte[] salt)
+ {
+ this.userKeyingMaterial = Arrays.clone(userKeyingMaterial);
+ this.salt = Arrays.clone(salt);
+ }
+
+ /**
+ * Return a copy of the key material in this object.
+ *
+ * @return the user keying material.
+ */
public byte[] getUserKeyingMaterial()
{
return Arrays.clone(userKeyingMaterial);
}
+
+ /**
+ * Return a copy of the salt in this object.
+ *
+ * @return the KDF salt.
+ */
+ public byte[] getSalt()
+ {
+ return Arrays.clone(salt);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ECKeyUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ECKeyUtil.java
index a0831b6..6869bf5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ECKeyUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ECKeyUtil.java
@@ -12,6 +12,7 @@
import com.android.org.bouncycastle.asn1.x9.ECNamedCurveTable;
import com.android.org.bouncycastle.asn1.x9.X962Parameters;
import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.org.bouncycastle.asn1.x9.X9ECParametersHolder;
import com.android.org.bouncycastle.asn1.x9.X9ECPoint;
import com.android.org.bouncycastle.crypto.ec.CustomNamedCurves;
@@ -70,10 +71,10 @@
{
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
- X9ECParameters x9 = CustomNamedCurves.getByOID(oid);
+ X9ECParametersHolder x9 = CustomNamedCurves.getByOIDLazy(oid);
if (x9 == null)
{
- x9 = ECNamedCurveTable.getByOID(oid);
+ x9 = ECNamedCurveTable.getByOIDLazy(oid);
}
curve = x9.getCurve();
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/MessageDigestUtils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/MessageDigestUtils.java
index 05cfd6c..9f95c95 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/MessageDigestUtils.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/MessageDigestUtils.java
@@ -15,6 +15,9 @@
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+// import org.bouncycastle.asn1.DERNull;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+// import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
/**
* @hide This class is not part of the Android public SDK API
@@ -23,6 +26,9 @@
{
private static Map<ASN1ObjectIdentifier, String> digestOidMap = new HashMap<ASN1ObjectIdentifier, String>();
+ // Android-removed: Unsupported algorithms
+ // private static Map<String, AlgorithmIdentifier> digestAlgIdMap = new HashMap<String, AlgorithmIdentifier>();
+
static
{
// BEGIN Android-removed: Unsupported algorithms
@@ -37,6 +43,8 @@
digestOidMap.put(NISTObjectIdentifiers.id_sha512, "SHA-512");
// BEGIN Android-removed: Unsupported algorithms
/*
+ digestOidMap.put(NISTObjectIdentifiers.id_sha512_224, "SHA-512(224)");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha512_256, "SHA-512(256)");
digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD-128");
digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD-160");
digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD-128");
@@ -49,11 +57,51 @@
digestOidMap.put(NISTObjectIdentifiers.id_sha3_256, "SHA3-256");
digestOidMap.put(NISTObjectIdentifiers.id_sha3_384, "SHA3-384");
digestOidMap.put(NISTObjectIdentifiers.id_sha3_512, "SHA3-512");
+ digestOidMap.put(NISTObjectIdentifiers.id_shake128, "SHAKE128");
+ digestOidMap.put(NISTObjectIdentifiers.id_shake256, "SHAKE256");
digestOidMap.put(GMObjectIdentifiers.sm3, "SM3");
+ digestOidMap.put(MiscObjectIdentifiers.blake3_256, "BLAKE3-256");
+
+ digestAlgIdMap.put("SHA-1", new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE));
+ digestAlgIdMap.put("SHA-224", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224));
+ digestAlgIdMap.put("SHA224", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224));
+ digestAlgIdMap.put("SHA-256", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256));
+ digestAlgIdMap.put("SHA256", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256));
+ digestAlgIdMap.put("SHA-384", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384));
+ digestAlgIdMap.put("SHA384", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384));
+ digestAlgIdMap.put("SHA-512", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512));
+ digestAlgIdMap.put("SHA512", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512));
+ digestAlgIdMap.put("SHA3-224", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_224));
+ digestAlgIdMap.put("SHA3-256", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256));
+ digestAlgIdMap.put("SHA3-384", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_384));
+ digestAlgIdMap.put("SHA3-512", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_512));
+ digestAlgIdMap.put("BLAKE3-256", new AlgorithmIdentifier(MiscObjectIdentifiers.blake3_256));
*/
// END Android-removed: Unsupported algorithms
}
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ * Attempt to find a standard JCA name for the digest represented by the passed in OID.
+ *
+ * @param digestName name of the digest algorithm of interest.
+ * @return an algorithm identifier representing the digest.
+ public static AlgorithmIdentifier getDigestAlgID(String digestName)
+ {
+ if (digestAlgIdMap.containsKey(digestName))
+ {
+ return (AlgorithmIdentifier)digestAlgIdMap.get(digestName);
+ }
+ throw new IllegalArgumentException("unknown digest: " + digestName);
+ }
+
+ public static AlgorithmIdentifier getDigestAlgID(String digestName)
+ {
+ throw new IllegalArgumentException("unknown digest: " + digestName);
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
/**
* Attempt to find a standard JCA name for the digest represented by the passed in OID.
*
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/ECNamedCurveTable.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/ECNamedCurveTable.java
index 6924428..63ca22c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/ECNamedCurveTable.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/ECNamedCurveTable.java
@@ -23,32 +23,35 @@
public static ECNamedCurveParameterSpec getParameterSpec(
String name)
{
- X9ECParameters ecP = com.android.org.bouncycastle.crypto.ec.CustomNamedCurves.getByName(name);
+ ASN1ObjectIdentifier oid;
+ try
+ {
+ oid = possibleOID(name) ? new ASN1ObjectIdentifier(name) : null;
+ }
+ catch (IllegalArgumentException e)
+ {
+ oid = null;
+ }
+
+ X9ECParameters ecP;
+ if (oid != null)
+ {
+ ecP = com.android.org.bouncycastle.crypto.ec.CustomNamedCurves.getByOID(oid);
+ }
+ else
+ {
+ ecP = com.android.org.bouncycastle.crypto.ec.CustomNamedCurves.getByName(name);
+ }
+
if (ecP == null)
{
- try
+ if (oid != null)
{
- ecP = com.android.org.bouncycastle.crypto.ec.CustomNamedCurves.getByOID(new ASN1ObjectIdentifier(name));
+ ecP = com.android.org.bouncycastle.asn1.x9.ECNamedCurveTable.getByOID(oid);
}
- catch (IllegalArgumentException e)
- {
- // ignore - not an oid
- }
-
- if (ecP == null)
+ else
{
ecP = com.android.org.bouncycastle.asn1.x9.ECNamedCurveTable.getByName(name);
- if (ecP == null)
- {
- try
- {
- ecP = com.android.org.bouncycastle.asn1.x9.ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(name));
- }
- catch (IllegalArgumentException e)
- {
- // ignore - not an oid
- }
- }
}
}
@@ -75,4 +78,21 @@
{
return com.android.org.bouncycastle.asn1.x9.ECNamedCurveTable.getNames();
}
+
+ private static boolean possibleOID(
+ String identifier)
+ {
+ if (identifier.length() < 3 || identifier.charAt(1) != '.')
+ {
+ return false;
+ }
+
+ char first = identifier.charAt(0);
+ if (first < '0' || first > '2')
+ {
+ return false;
+ }
+
+ return true;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/netscape/NetscapeCertRequest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
index f6bcc66..c81ca6d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
@@ -18,6 +18,7 @@
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.org.bouncycastle.asn1.ASN1IA5String;
import com.android.org.bouncycastle.asn1.ASN1InputStream;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
@@ -105,7 +106,7 @@
+ pkac.size());
}
- challenge = ((DERIA5String)pkac.getObjectAt(1)).getString();
+ challenge = ((ASN1IA5String)pkac.getObjectAt(1)).getString();
//this could be dangerous, as ASN.1 decoding/encoding
//could potentially alter the bytes
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProvider.java
index 798bb8e..7507797 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProvider.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProvider.java
@@ -13,12 +13,20 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
// import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.org.bouncycastle.crypto.CryptoServiceConstraintsException;
+import com.android.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import com.android.org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil;
@@ -35,6 +43,16 @@
// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSKeyFactorySpi;
// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSMTKeyFactorySpi;
// import org.bouncycastle.pqc.jcajce.provider.lms.LMSKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.bike.BIKEKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.cmce.CMCEKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.dilithium.DilithiumKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.falcon.FalconKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.hqc.HQCKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.kyber.KyberKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.ntru.NTRUKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.picnic.PicnicKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.sphincsplus.SPHINCSPlusKeyFactorySpi;
+import com.android.org.bouncycastle.util.Strings;
/**
* To add the provider at runtime use:
@@ -64,7 +82,9 @@
public final class BouncyCastleProvider extends Provider
implements ConfigurableProvider
{
- private static String info = "BouncyCastle Security Provider v1.68";
+ private static final Logger LOG = Logger.getLogger(BouncyCastleProvider.class.getName());
+
+ private static String info = "BouncyCastle Security Provider v1.77";
public static final String PROVIDER_NAME = "BC";
@@ -89,17 +109,27 @@
private static final String[] SYMMETRIC_MACS =
{
// Android-removed: Unsupported algorithms
- // "SipHash", "Poly1305"
+ // "SipHash", "SipHash128", "Poly1305"
};
- private static final String[] SYMMETRIC_CIPHERS =
+ private static final CryptoServiceProperties[] SYMMETRIC_CIPHERS =
{
// Android-changed: Unsupported algorithms
- // "AES", "ARC4", "ARIA", "Blowfish", "Camellia", "CAST5", "CAST6", "ChaCha", "DES", "DESede",
- // "GOST28147", "Grainv1", "Grain128", "HC128", "HC256", "IDEA", "Noekeon", "RC2", "RC5",
- // "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Shacal2", "Skipjack", "SM4", "TEA", "Twofish", "Threefish",
- // "VMPC", "VMPCKSA3", "XTEA", "XSalsa20", "OpenSSLPBKDF", "DSTU7624", "GOST3412_2015"
- "AES", "ARC4", "Blowfish", "DES", "DESede", "RC2", "Twofish",
+ // TODO: these numbers need a bit more work, we cap at 256 bits.
+ // service("ARIA", 256), service("Camellia", 256), service("CAST5", 128),
+ // service("CAST6", 256), service("ChaCha", 128), service("GOST28147", 128),
+ // service("Grainv1", 128), service("Grain128", 128), service("HC128", 128),
+ // service("HC256", 256), service("IDEA", 128), service("Noekeon", 128),
+ // service("RC6", 256), service("Rijndael", 256), service("Salsa20", 128),
+ // service("SEED", 128), service("Serpent", 256), service("Shacal2", 128),
+ // service("Skipjack", 80), service("SM4", 128), service("TEA", 128),
+ // service("RC5", 128), service("Threefish", 128), service("VMPC", 128),
+ // service("VMPCKSA3", 128), service("XTEA", 128), service("XSalsa20", 128),
+ // service("OpenSSLPBKDF", 128), service("DSTU7624", 256), service("GOST3412_2015", 256),
+ // service("Zuc", 128)
+ service("AES", 256), service("ARC4", 20), service("Blowfish", 128),
+ service("DES", 56), service("DESede", 112), service("RC2", 128),
+ service("Twofish", 256)
};
/*
@@ -112,14 +142,14 @@
private static final String[] ASYMMETRIC_GENERIC =
{
// Android-changed: Unsupported algorithms
- // "X509", "IES", "COMPOSITE"
+ // "X509", "IES", "COMPOSITE", "EXTERNAL"
"X509"
};
private static final String[] ASYMMETRIC_CIPHERS =
{
// Android-changed: Unsupported algorithms
- // "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC"
+ // "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC", "LMS", "SPHINCSPlus", "Dilithium", "Falcon", "NTRU"
"DSA", "DH", "EC", "RSA",
};
@@ -155,6 +185,8 @@
// "DRBG"
// };
+ private Map<String, Service> serviceMap = new ConcurrentHashMap<String, Service>();
+
/**
* Construct a new provider. This should only be required when
* using runtime registration of the provider using the
@@ -163,7 +195,7 @@
@android.compat.annotation.UnsupportedAppUsage
public BouncyCastleProvider()
{
- super(PROVIDER_NAME, 1.68, info);
+ super(PROVIDER_NAME, 1.77, info);
AccessController.doPrivileged(new PrivilegedAction()
{
@@ -229,13 +261,9 @@
put("Cipher.OLDPBEWITHSHAANDTWOFISH-CBC", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$OldPBEWithSHAAndTwofish");
// Certification Path API
- put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi");
- put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
- put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
- put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
-
if (revChkClass != null)
{
+ put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi");
put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi_8");
put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi_8");
@@ -262,33 +290,149 @@
// put("CertStore.Multi", "org.bouncycastle.jce.provider.MultiCertStoreSpi");
// put("Alg.Alias.CertStore.X509LDAP", "LDAP");
// END Android-removed: Unsupported algorithms
+
+ getService("SecureRandom", "DEFAULT"); // prime for new SecureRandom() on 1.8 JVMs.
+ }
+
+ public final Service getService(final String type, final String algorithm)
+ {
+ String upperCaseAlgName = Strings.toUpperCase(algorithm);
+ final String key = type + "." + upperCaseAlgName;
+
+ Service service = serviceMap.get(key);
+
+ if (service == null)
+ {
+ synchronized (this)
+ {
+ if (!serviceMap.containsKey(key))
+ {
+ service = AccessController.doPrivileged(new PrivilegedAction<Service>()
+ {
+ @Override
+ public Service run()
+ {
+ Service service = BouncyCastleProvider.super.getService(type, algorithm);
+ if (service == null)
+ {
+ return null;
+ }
+ serviceMap.put(key, service);
+ // remove legacy entry and swap to service entry
+ BouncyCastleProvider.super.remove(service.getType() + "." + service.getAlgorithm());
+ BouncyCastleProvider.super.putService(service);
+
+ return service;
+ }
+ });
+ }
+ else
+ {
+ service = serviceMap.get(key);
+ }
+ }
+ }
+
+ return service;
}
private void loadAlgorithms(String packageName, String[] names)
{
for (int i = 0; i != names.length; i++)
{
- Class clazz = ClassUtil.loadClass(BouncyCastleProvider.class, packageName + names[i] + "$Mappings");
+ loadServiceClass(packageName, names[i]);
+ }
+ }
- if (clazz != null)
+ private void loadAlgorithms(String packageName, CryptoServiceProperties[] services)
+ {
+ for (int i = 0; i != services.length; i++)
+ {
+ CryptoServiceProperties service = services[i];
+ try
{
- try
+ CryptoServicesRegistrar.checkConstraints(service);
+
+ loadServiceClass(packageName, service.getServiceName());
+ }
+ catch (CryptoServiceConstraintsException e)
+ {
+ if (LOG.isLoggable(Level.FINE))
{
- ((AlgorithmProvider)clazz.newInstance()).configure(this);
- }
- catch (Exception e)
- { // this should never ever happen!!
- throw new InternalError("cannot create instance of "
- + packageName + names[i] + "$Mappings : " + e);
+ LOG.fine("service for " + service.getServiceName() + " ignored due to constraints");
}
}
}
}
+ private void loadServiceClass(String packageName, String serviceName)
+ {
+ Class clazz = ClassUtil.loadClass(BouncyCastleProvider.class, packageName + serviceName + "$Mappings");
+
+ if (clazz != null)
+ {
+ try
+ {
+ ((AlgorithmProvider)clazz.newInstance()).configure(this);
+ }
+ catch (Exception e)
+ { // this should never ever happen!!
+ throw new InternalError("cannot create instance of "
+ + packageName + serviceName + "$Mappings : " + e);
+ }
+ }
+ }
// BEGIN Android-removed: Unsupported algorithms
/*
+
private void loadPQCKeys()
{
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192s, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256s, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(new ASN1ObjectIdentifier("1.3.9999.6.4.10"), new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128f, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192f, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f, new SPHINCSPlusKeyFactorySpi());
+
addKeyInfoConverter(PQCObjectIdentifiers.sphincs256, new Sphincs256KeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.newHope, new NHKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.xmss, new XMSSKeyFactorySpi());
@@ -301,6 +445,37 @@
addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_I, new QTESLAKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_III, new QTESLAKeyFactorySpi());
addKeyInfoConverter(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, new LMSKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.picnic_key, new PicnicKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.falcon_512, new FalconKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.falcon_1024, new FalconKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium2, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium3, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium5, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium2_aes, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium3_aes, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium5_aes, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber512, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber768, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber1024, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece348864_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece460896_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece6688128_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece6960119_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece8192128_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.bike128, new BIKEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.bike192, new BIKEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.bike256, new BIKEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.hqc128, new HQCKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.hqc192, new HQCKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.hqc256, new HQCKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber1024, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber512_aes, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber768_aes, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber1024_aes, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhps2048509, new NTRUKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhps2048677, new NTRUKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhps4096821, new NTRUKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhrss701, new NTRUKeyFactorySpi());
}
*/
// END Android-removed: Unsupported algorithms
@@ -328,12 +503,25 @@
put(key, value);
}
+ public void addAlgorithm(String key, String value, Map<String, String> attributes)
+ {
+ addAlgorithm(key, value);
+ addAttributes(key, attributes);
+ }
+
public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className)
{
addAlgorithm(type + "." + oid, className);
addAlgorithm(type + ".OID." + oid, className);
}
+ public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className, Map<String, String> attributes)
+ {
+ addAlgorithm(type, oid, className);
+ addAttributes(type + "." + oid, attributes);
+ addAttributes(type + ".OID." + oid, attributes);
+ }
+
public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter)
{
synchronized (keyInfoConverters)
@@ -349,6 +537,8 @@
public void addAttributes(String key, Map<String, String> attributeMap)
{
+ put(key + " ImplementedIn", "Software");
+
for (Iterator it = attributeMap.keySet().iterator(); it.hasNext();)
{
String attributeName = (String)it.next();
@@ -389,6 +579,11 @@
}
// Android-removed: see above
/*
+ if (publicKeyInfo.getAlgorithm().getAlgorithm().on(BCObjectIdentifiers.picnic_key))
+ {
+ return new PicnicKeyFactorySpi().generatePublic(publicKeyInfo);
+ }
+
AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(publicKeyInfo.getAlgorithm().getAlgorithm());
if (converter == null)
@@ -462,4 +657,42 @@
return privateProvider;
}
// END Android-added: Allow algorithms to be provided privately for BC internals.
+ private static CryptoServiceProperties service(String name, int bitsOfSecurity)
+ {
+ return new JcaCryptoService(name, bitsOfSecurity);
+ }
+
+ private static class JcaCryptoService
+ implements CryptoServiceProperties
+ {
+
+ private final String name;
+ private final int bitsOfSecurity;
+
+ JcaCryptoService(String name, int bitsOfSecurity)
+ {
+ this.name = name;
+ this.bitsOfSecurity = bitsOfSecurity;
+ }
+
+ public int bitsOfSecurity()
+ {
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return name;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return CryptoServicePurpose.ANY;
+ }
+
+ public Object getParams()
+ {
+ return null;
+ }
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
index 80bf4e9..96915f1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
@@ -45,7 +45,6 @@
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Enumerated;
import com.android.org.bouncycastle.asn1.ASN1GeneralizedTime;
-import com.android.org.bouncycastle.asn1.ASN1InputStream;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
@@ -55,7 +54,6 @@
import com.android.org.bouncycastle.asn1.ASN1String;
import com.android.org.bouncycastle.asn1.DEROctetString;
import com.android.org.bouncycastle.asn1.DERSequence;
-import com.android.org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers;
import com.android.org.bouncycastle.asn1.x500.X500Name;
import com.android.org.bouncycastle.asn1.x500.style.RFC4519Style;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
@@ -69,6 +67,7 @@
import com.android.org.bouncycastle.asn1.x509.GeneralNames;
import com.android.org.bouncycastle.asn1.x509.PolicyInformation;
import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.org.bouncycastle.internal.asn1.isismtt.ISISMTTObjectIdentifiers;
import com.android.org.bouncycastle.jcajce.PKIXCRLStore;
import com.android.org.bouncycastle.jcajce.PKIXCRLStoreSelector;
import com.android.org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
@@ -84,7 +83,6 @@
import com.android.org.bouncycastle.util.Store;
import com.android.org.bouncycastle.util.StoreException;
import com.android.org.bouncycastle.x509.X509AttributeCertificate;
-import com.android.org.bouncycastle.x509.extension.X509ExtensionUtil;
class CertPathValidatorUtilities
{
@@ -777,7 +775,7 @@
for (int j = 0; j < genNames.length; j++)
{
- GeneralName name = genNames[i];
+ GeneralName name = genNames[j];
if (name.getTagNo() == GeneralName.uniformResourceIdentifier)
{
try
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEDHPrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEDHPrivateKey.java
index 1c024a8..106e077 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEDHPrivateKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEDHPrivateKey.java
@@ -20,7 +20,7 @@
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import com.android.org.bouncycastle.asn1.x9.DHDomainParameters;
+import com.android.org.bouncycastle.asn1.x9.DomainParameters;
import com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import com.android.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
@@ -85,9 +85,9 @@
}
else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
{
- DHDomainParameters params = DHDomainParameters.getInstance(seq);
+ DomainParameters params = DomainParameters.getInstance(seq);
- this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue());
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
}
else
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEDHPublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEDHPublicKey.java
index 156ebba..3170816 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEDHPublicKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEDHPublicKey.java
@@ -17,7 +17,7 @@
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import com.android.org.bouncycastle.asn1.x9.DHDomainParameters;
+import com.android.org.bouncycastle.asn1.x9.DomainParameters;
import com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import com.android.org.bouncycastle.crypto.params.DHPublicKeyParameters;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
@@ -80,8 +80,8 @@
this.y = derY.getValue();
- ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithmId().getParameters());
- ASN1ObjectIdentifier id = info.getAlgorithmId().getAlgorithm();
+ ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithm().getParameters());
+ ASN1ObjectIdentifier id = info.getAlgorithm().getAlgorithm();
// we need the PKCS check to handle older keys marked with the X9 oid.
if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement) || isPKCSParam(seq))
@@ -99,9 +99,9 @@
}
else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
{
- DHDomainParameters params = DHDomainParameters.getInstance(seq);
+ DomainParameters params = DomainParameters.getInstance(seq);
- this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue());
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
}
else
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPrivateKey.java
index 5a165bd..7afb23d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPrivateKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPrivateKey.java
@@ -7,24 +7,21 @@
import java.math.BigInteger;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.EllipticCurve;
import java.util.Enumeration;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DERNull;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
-import com.android.org.bouncycastle.asn1.sec.ECPrivateKeyStructure;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import com.android.org.bouncycastle.asn1.x9.X962Parameters;
@@ -53,7 +50,7 @@
private ECParameterSpec ecSpec;
private boolean withCompression;
- private DERBitString publicKey;
+ private ASN1BitString publicKey;
private PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
@@ -218,6 +215,7 @@
else
*/
// END Android-removed: Unsupported algorithms
+ if (ecP != null)
{
EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed());
@@ -254,7 +252,7 @@
}
else
{
- ECPrivateKeyStructure ec = new ECPrivateKeyStructure((ASN1Sequence)privKey);
+ com.android.org.bouncycastle.asn1.sec.ECPrivateKey ec = com.android.org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(privKey);
this.d = ec.getKey();
this.publicKey = ec.getPublicKey();
@@ -314,15 +312,25 @@
}
PrivateKeyInfo info;
- ECPrivateKeyStructure keyStructure;
+ com.android.org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
- if (publicKey != null)
+ int orderBitLength;
+ if (ecSpec == null)
{
- keyStructure = new ECPrivateKeyStructure(this.getS(), publicKey, params);
+ orderBitLength = ECUtil.getOrderBitLength(null, null, this.getS());
}
else
{
- keyStructure = new ECPrivateKeyStructure(this.getS(), params);
+ orderBitLength = ECUtil.getOrderBitLength(null, ecSpec.getOrder(), this.getS());
+ }
+
+ if (publicKey != null)
+ {
+ keyStructure = new com.android.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params);
+ }
+ else
+ {
+ keyStructure = new com.android.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
}
try
@@ -434,7 +442,7 @@
}
- private DERBitString getPublicKeyDetails(JCEECPublicKey pub)
+ private ASN1BitString getPublicKeyDetails(JCEECPublicKey pub)
{
try
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPublicKey.java
index 8fcdeb0..df9978f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPublicKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPublicKey.java
@@ -11,11 +11,11 @@
import java.security.spec.ECPublicKeySpec;
import java.security.spec.EllipticCurve;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DERNull;
import com.android.org.bouncycastle.asn1.DEROctetString;
// Android-removed: Unsupported algorithms
@@ -192,7 +192,7 @@
if (algID.getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001))
{
- DERBitString bits = info.getPublicKeyData();
+ ASN1BitString bits = info.getPublicKeyData();
ASN1OctetString key;
this.algorithm = "ECGOST3410";
@@ -273,7 +273,7 @@
ecP.getH().intValue());
}
- DERBitString bits = info.getPublicKeyData();
+ ASN1BitString bits = info.getPublicKeyData();
byte[] data = bits.getBytes();
ASN1OctetString key = new DEROctetString(data);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCRLUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCRLUtil.java
index 897d0ce..0d5c595 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCRLUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCRLUtil.java
@@ -41,8 +41,9 @@
for (Iterator it = initialSet.iterator(); it.hasNext();)
{
X509CRL crl = (X509CRL)it.next();
-
- if (crl.getNextUpdate().after(validityDate))
+
+ Date nextUpdate = crl.getNextUpdate();
+ if (nextUpdate == null || nextUpdate.after(validityDate))
{
X509Certificate cert = crlselect.getCertificateChecking();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
index 6df4ad1..3a40cf9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
@@ -2,7 +2,6 @@
package com.android.org.bouncycastle.jce.provider;
import java.io.IOException;
-import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.security.cert.CertPath;
@@ -2099,18 +2098,12 @@
throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
index);
}
- if (bc != null)
+ if (bc != null && bc.isCA()) // if there is a path len constraint and we're not a CA, ignore it! (yes, it happens).
{
- BigInteger _pathLengthConstraint = bc.getPathLenConstraint();
-
- if (_pathLengthConstraint != null)
+ ASN1Integer pathLenConstraint = bc.getPathLenConstraintInteger();
+ if (pathLenConstraint != null)
{
- int _plc = _pathLengthConstraint.intValue();
-
- if (_plc < maxPathLength)
- {
- return _plc;
- }
+ maxPathLength = Math.min(maxPathLength, pathLenConstraint.intPositiveValueExact());
}
}
return maxPathLength;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CRLEntryObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CRLEntryObject.java
index 6fd0239..01641ce 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CRLEntryObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CRLEntryObject.java
@@ -24,7 +24,6 @@
import com.android.org.bouncycastle.asn1.x509.GeneralName;
import com.android.org.bouncycastle.asn1.x509.GeneralNames;
import com.android.org.bouncycastle.asn1.x509.TBSCertList;
-import com.android.org.bouncycastle.asn1.x509.X509Extension;
import com.android.org.bouncycastle.util.Strings;
/**
@@ -288,11 +287,11 @@
buf.append(" critical(").append(ext.isCritical()).append(") ");
try
{
- if (oid.equals(X509Extension.reasonCode))
+ if (oid.equals(Extension.reasonCode))
{
buf.append(CRLReason.getInstance(ASN1Enumerated.getInstance(dIn.readObject()))).append(nl);
}
- else if (oid.equals(X509Extension.certificateIssuer))
+ else if (oid.equals(Extension.certificateIssuer))
{
buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CertificateObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CertificateObject.java
index ad690b6..201ed8d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CertificateObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CertificateObject.java
@@ -35,13 +35,13 @@
import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.org.bouncycastle.asn1.ASN1IA5String;
import com.android.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1String;
-import com.android.org.bouncycastle.asn1.DERBitString;
-import com.android.org.bouncycastle.asn1.DERIA5String;
import com.android.org.bouncycastle.asn1.DERNull;
import com.android.org.bouncycastle.asn1.DEROctetString;
import com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
@@ -110,7 +110,7 @@
byte[] bytes = this.getExtensionBytes("2.5.29.15");
if (bytes != null)
{
- ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes));
+ ASN1BitString bits = ASN1BitString.getInstance(ASN1Primitive.fromByteArray(bytes));
bytes = bits.getBytes();
int length = (bytes.length * 8) - bits.getPadBits();
@@ -293,7 +293,7 @@
public boolean[] getIssuerUniqueID()
{
- DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getIssuerUniqueId();
if (id != null)
{
@@ -313,7 +313,7 @@
public boolean[] getSubjectUniqueID()
{
- DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getSubjectUniqueId();
if (id != null)
{
@@ -367,26 +367,18 @@
public int getBasicConstraints()
{
- if (basicConstraints != null)
+ if (basicConstraints == null || !basicConstraints.isCA())
{
- if (basicConstraints.isCA())
- {
- if (basicConstraints.getPathLenConstraint() == null)
- {
- return Integer.MAX_VALUE;
- }
- else
- {
- return basicConstraints.getPathLenConstraint().intValue();
- }
- }
- else
- {
- return -1;
- }
+ return -1;
}
- return -1;
+ ASN1Integer pathLenConstraint = basicConstraints.getPathLenConstraintInteger();
+ if (pathLenConstraint == null)
+ {
+ return Integer.MAX_VALUE;
+ }
+
+ return pathLenConstraint.intPositiveValueExact();
}
public Collection getSubjectAlternativeNames()
@@ -712,15 +704,15 @@
}
else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
{
- buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl);
+ buf.append(new NetscapeCertType((ASN1BitString)dIn.readObject())).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
{
- buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl);
+ buf.append(new NetscapeRevocationURL((ASN1IA5String)dIn.readObject())).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
{
- buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl);
+ buf.append(new VerisignCzagExtension((ASN1IA5String)dIn.readObject())).append(nl);
}
else
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/spec/ECNamedCurveSpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
index 62566fb..4028dbe 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
@@ -45,7 +45,7 @@
{
Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
int[] exponents = poly.getExponentsPresent();
- int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
+ int[] ks = Arrays.reverseInPlace(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
return new ECFieldF2m(poly.getDegree(), ks);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECCurve.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECCurve.java
index 1d0c04e..46fdafd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECCurve.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECCurve.java
@@ -3,9 +3,14 @@
import java.math.BigInteger;
import java.security.SecureRandom;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.Random;
+import java.util.Set;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.org.bouncycastle.math.Primes;
import com.android.org.bouncycastle.math.ec.endo.ECEndomorphism;
import com.android.org.bouncycastle.math.ec.endo.GLVEndomorphism;
import com.android.org.bouncycastle.math.field.FiniteField;
@@ -13,6 +18,7 @@
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.util.BigIntegers;
import com.android.org.bouncycastle.util.Integers;
+import com.android.org.bouncycastle.util.Properties;
/**
* base class for an elliptic curve
@@ -677,6 +683,8 @@
public static class Fp extends AbstractFp
{
private static final int FP_DEFAULT_COORDS = ECCurve.COORD_JACOBIAN_MODIFIED;
+ private static final Set<BigInteger> knownQs = Collections.synchronizedSet(new HashSet<BigInteger>());
+ private static final BigIntegers.Cache validatedQs = new BigIntegers.Cache();
BigInteger q, r;
ECPoint.Fp infinity;
@@ -691,9 +699,44 @@
public Fp(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor)
{
+ this(q, a, b, order, cofactor, false);
+ }
+
+ public Fp(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor, boolean isInternal)
+ {
super(q);
- this.q = q;
+ if (isInternal)
+ {
+ this.q = q;
+ knownQs.add(q);
+ }
+ else if (knownQs.contains(q) || validatedQs.contains(q))
+ {
+ this.q = q;
+ }
+ else
+ {
+ int maxBitLength = Properties.asInteger("com.android.org.bouncycastle.ec.fp_max_size", 1042); // 2 * 521
+ int certainty = Properties.asInteger("com.android.org.bouncycastle.ec.fp_certainty", 100);
+
+ int qBitLength = q.bitLength();
+ if (maxBitLength < qBitLength)
+ {
+ throw new IllegalArgumentException("Fp q value out of range");
+ }
+
+ if (Primes.hasAnySmallFactors(q) || !Primes.isMRProbablePrime(
+ q, CryptoServicesRegistrar.getSecureRandom(), getNumberOfIterations(qBitLength, certainty)))
+ {
+ throw new IllegalArgumentException("Fp q value not prime");
+ }
+
+ validatedQs.add(q);
+
+ this.q = q;
+ }
+
this.r = ECFieldElement.Fp.calculateResidue(q);
this.infinity = new ECPoint.Fp(this, null, null);
@@ -750,6 +793,11 @@
public ECFieldElement fromBigInteger(BigInteger x)
{
+ if (x == null || x.signum() < 0 || x.compareTo(q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for Fp field element");
+ }
+
return new ECFieldElement.Fp(this.q, this.r, x);
}
@@ -809,32 +857,11 @@
private static FiniteField buildField(int m, int k1, int k2, int k3)
{
- if (k1 == 0)
- {
- throw new IllegalArgumentException("k1 must be > 0");
- }
+ int[] exponents = (k2 | k3) == 0
+ ? new int[]{ 0, k1, m }
+ : new int[]{ 0, k1, k2, k3, m };
- if (k2 == 0)
- {
- if (k3 != 0)
- {
- throw new IllegalArgumentException("k3 must be 0 if k2 == 0");
- }
-
- return FiniteFields.getBinaryExtensionField(new int[]{ 0, k1, m });
- }
-
- if (k2 <= k1)
- {
- throw new IllegalArgumentException("k2 must be > k1");
- }
-
- if (k3 <= k2)
- {
- throw new IllegalArgumentException("k3 must be > k2");
- }
-
- return FiniteFields.getBinaryExtensionField(new int[]{ 0, k1, k2, k3, m });
+ return FiniteFields.getBinaryExtensionField(exponents);
}
protected AbstractF2m(int m, int k1, int k2, int k3)
@@ -927,7 +954,7 @@
y = this.getB().sqrt();
}
else
- {
+ {
ECFieldElement beta = x.square().invert().multiply(this.getB()).add(this.getA()).add(x);
ECFieldElement z = solveQuadraticEquation(beta);
if (z != null)
@@ -1288,7 +1315,16 @@
public ECFieldElement fromBigInteger(BigInteger x)
{
- return new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, x);
+ if (x == null || x.signum() < 0 || x.bitLength() > m)
+ {
+ throw new IllegalArgumentException("x value invalid in F2m field element");
+ }
+
+ int[] ks = (k2 | k3) == 0
+ ? new int[]{ k1 }
+ : new int[]{ k1, k2, k3 };
+
+ return new ECFieldElement.F2m(m, ks, new LongArray(x));
}
protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
@@ -1403,4 +1439,36 @@
};
}
}
+
+ private static int getNumberOfIterations(int bits, int certainty)
+ {
+ /*
+ * NOTE: We enforce a minimum 'certainty' of 100 for bits >= 1024 (else 80). Where the
+ * certainty is higher than the FIPS 186-4 tables (C.2/C.3) cater to, extra iterations
+ * are added at the "worst case rate" for the excess.
+ */
+ if (bits >= 1536)
+ {
+ return certainty <= 100 ? 3
+ : certainty <= 128 ? 4
+ : 4 + (certainty - 128 + 1) / 2;
+ }
+ else if (bits >= 1024)
+ {
+ return certainty <= 100 ? 4
+ : certainty <= 112 ? 5
+ : 5 + (certainty - 112 + 1) / 2;
+ }
+ else if (bits >= 512)
+ {
+ return certainty <= 80 ? 5
+ : certainty <= 100 ? 7
+ : 7 + (certainty - 100 + 1) / 2;
+ }
+ else
+ {
+ return certainty <= 80 ? 40
+ : 40 + (certainty - 80 + 1) / 2;
+ }
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECFieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECFieldElement.java
index 84b197c..307d661 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECFieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECFieldElement.java
@@ -120,21 +120,8 @@
return null;
}
- /**
- * @deprecated Use ECCurve.fromBigInteger to construct field elements
- */
- public Fp(BigInteger q, BigInteger x)
- {
- this(q, calculateResidue(q), x);
- }
-
Fp(BigInteger q, BigInteger r, BigInteger x)
{
- if (x == null || x.signum() < 0 || x.compareTo(q) >= 0)
- {
- throw new IllegalArgumentException("x value invalid in Fp field element");
- }
-
this.q = q;
this.r = r;
this.x = x;
@@ -626,59 +613,6 @@
*/
LongArray x;
- /**
- * Constructor for PPB.
- * @param m The exponent <code>m</code> of
- * <code>F<sub>2<sup>m</sup></sub></code>.
- * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> +
- * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
- * represents the reduction polynomial <code>f(z)</code>.
- * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> +
- * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
- * represents the reduction polynomial <code>f(z)</code>.
- * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> +
- * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
- * represents the reduction polynomial <code>f(z)</code>.
- * @param x The BigInteger representing the value of the field element.
- * @deprecated Use ECCurve.fromBigInteger to construct field elements
- */
- public F2m(
- int m,
- int k1,
- int k2,
- int k3,
- BigInteger x)
- {
- if (x == null || x.signum() < 0 || x.bitLength() > m)
- {
- throw new IllegalArgumentException("x value invalid in F2m field element");
- }
-
- if ((k2 == 0) && (k3 == 0))
- {
- this.representation = TPB;
- this.ks = new int[]{ k1 };
- }
- else
- {
- if (k2 >= k3)
- {
- throw new IllegalArgumentException(
- "k2 must be smaller than k3");
- }
- if (k2 <= 0)
- {
- throw new IllegalArgumentException(
- "k2 must be larger than 0");
- }
- this.representation = PPB;
- this.ks = new int[]{ k1, k2, k3 };
- }
-
- this.m = m;
- this.x = new LongArray(x);
- }
-
F2m(int m, int[] ks, LongArray x)
{
this.m = m;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/Tnaf.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/Tnaf.java
index db41bfb..0b2b68a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/Tnaf.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/Tnaf.java
@@ -3,6 +3,8 @@
import java.math.BigInteger;
+import com.android.org.bouncycastle.util.BigIntegers;
+
/**
* Class holding methods for point multiplication based on the window
* τ-adic nonadjacent form (WTNAF). The algorithms are based on the
@@ -29,20 +31,19 @@
public static final byte WIDTH = 4;
/**
- * 2<sup>4</sup>
- */
- public static final byte POW_2_WIDTH = 16;
-
- /**
* The <code>α<sub>u</sub></code>'s for <code>a=0</code> as an array
* of <code>ZTauElement</code>s.
*/
- public static final ZTauElement[] alpha0 = {
- null,
- new ZTauElement(ECConstants.ONE, ECConstants.ZERO), null,
- new ZTauElement(MINUS_THREE, MINUS_ONE), null,
- new ZTauElement(MINUS_ONE, MINUS_ONE), null,
- new ZTauElement(ECConstants.ONE, MINUS_ONE), null
+ public static final ZTauElement[] alpha0 =
+ {
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ZERO),
+ null, new ZTauElement(MINUS_THREE, MINUS_ONE),
+ null, new ZTauElement(MINUS_ONE, MINUS_ONE),
+ null, new ZTauElement(ECConstants.ONE, MINUS_ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ONE),
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ONE),
+ null, new ZTauElement(ECConstants.THREE, ECConstants.ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ZERO),
};
/**
@@ -57,11 +58,16 @@
* The <code>α<sub>u</sub></code>'s for <code>a=1</code> as an array
* of <code>ZTauElement</code>s.
*/
- public static final ZTauElement[] alpha1 = {null,
- new ZTauElement(ECConstants.ONE, ECConstants.ZERO), null,
- new ZTauElement(MINUS_THREE, ECConstants.ONE), null,
- new ZTauElement(MINUS_ONE, ECConstants.ONE), null,
- new ZTauElement(ECConstants.ONE, ECConstants.ONE), null
+ public static final ZTauElement[] alpha1 =
+ {
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ZERO),
+ null, new ZTauElement(MINUS_THREE, ECConstants.ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ONE),
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ONE),
+ null, new ZTauElement(MINUS_ONE, MINUS_ONE),
+ null, new ZTauElement(ECConstants.ONE, MINUS_ONE),
+ null, new ZTauElement(ECConstants.THREE, MINUS_ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ZERO),
};
/**
@@ -82,31 +88,29 @@
*/
public static BigInteger norm(final byte mu, ZTauElement lambda)
{
- BigInteger norm;
-
// s1 = u^2
BigInteger s1 = lambda.u.multiply(lambda.u);
// s2 = u * v
- BigInteger s2 = lambda.u.multiply(lambda.v);
+// BigInteger s2 = lambda.u.multiply(lambda.v);
// s3 = 2 * v^2
- BigInteger s3 = lambda.v.multiply(lambda.v).shiftLeft(1);
+// BigInteger s3 = lambda.v.multiply(lambda.v).shiftLeft(1);
if (mu == 1)
{
- norm = s1.add(s2).add(s3);
+// return s1.add(s2).add(s3);
+ return lambda.v.shiftLeft(1).add(lambda.u).multiply(lambda.v).add(s1);
}
else if (mu == -1)
{
- norm = s1.subtract(s2).add(s3);
+// return s1.subtract(s2).add(s3);
+ return lambda.v.shiftLeft(1).subtract(lambda.u).multiply(lambda.v).add(s1);
}
else
{
throw new IllegalArgumentException("mu must be 1 or -1");
}
-
- return norm;
}
/**
@@ -452,10 +456,7 @@
throw new IllegalArgumentException("mu must be 1 or -1");
}
- BigInteger u0;
- BigInteger u1;
- BigInteger u2;
-
+ BigInteger u0, u1, u2;
if (doV)
{
u0 = ECConstants.TWO;
@@ -470,26 +471,18 @@
for (int i = 1; i < k; i++)
{
// u2 = mu*u1 - 2*u0;
- BigInteger s = null;
- if (mu == 1)
+ BigInteger s = u1;
+ if (mu < 0)
{
- s = u1;
+ s = s.negate();
}
- else
- {
- // mu == -1
- s = u1.negate();
- }
-
+
u2 = s.subtract(u0.shiftLeft(1));
u0 = u1;
u1 = u2;
-// System.out.println(i + ": " + u2);
-// System.out.println();
}
- BigInteger[] retVal = {u0, u1};
- return retVal;
+ return new BigInteger[]{ u0, u1 };
}
/**
@@ -520,11 +513,7 @@
BigInteger[] us = getLucas(mu, w, false);
BigInteger twoToW = ECConstants.ZERO.setBit(w);
BigInteger u1invert = us[1].modInverse(twoToW);
- BigInteger tw;
- tw = ECConstants.TWO.multiply(us[0]).multiply(u1invert).mod(twoToW);
-// System.out.println("mu = " + mu);
-// System.out.println("tw = " + tw);
- return tw;
+ return us[0].shiftLeft(1).multiply(u1invert).mod(twoToW);
}
}
@@ -543,22 +532,7 @@
throw new IllegalArgumentException("si is defined for Koblitz curves only");
}
- int m = curve.getFieldSize();
- int a = curve.getA().toBigInteger().intValue();
- byte mu = getMu(a);
- int shifts = getShiftsForCofactor(curve.getCofactor());
- int index = m + 3 - a;
- BigInteger[] ui = getLucas(mu, index, false);
- if (mu == 1)
- {
- ui[0] = ui[0].negate();
- ui[1] = ui[1].negate();
- }
-
- BigInteger dividend0 = ECConstants.ONE.add(ui[1]).shiftRight(shifts);
- BigInteger dividend1 = ECConstants.ONE.add(ui[0]).shiftRight(shifts).negate();
-
- return new BigInteger[] { dividend0, dividend1 };
+ return getSi(curve.getFieldSize(), curve.getA().toBigInteger().intValue(), curve.getCofactor());
}
public static BigInteger[] getSi(int fieldSize, int curveA, BigInteger cofactor)
@@ -609,9 +583,11 @@
* modular reduction.
* @return <code>ρ := k partmod (τ<sup>m</sup> - 1)/(τ - 1)</code>
*/
- public static ZTauElement partModReduction(BigInteger k, int m, byte a,
- BigInteger[] s, byte mu, byte c)
+ public static ZTauElement partModReduction(ECCurve.AbstractF2m curve, BigInteger k, byte a, byte mu, byte c)
{
+ int m = curve.getFieldSize();
+ BigInteger[] s = curve.getSi();
+
// d0 = s[0] + mu*s[1]; mu is either 1 or -1
BigInteger d0;
if (mu == 1)
@@ -623,20 +599,29 @@
d0 = s[0].subtract(s[1]);
}
- BigInteger[] v = getLucas(mu, m, true);
- BigInteger vm = v[1];
+ BigInteger vm;
+ if (curve.isKoblitz())
+ {
+ /*
+ * Jerome A. Solinas, "Improved Algorithms for Arithmetic on Anomalous Binary Curves", (21).
+ */
+ vm = ECConstants.ONE.shiftLeft(m).add(ECConstants.ONE).subtract(
+ curve.getOrder().multiply(curve.getCofactor()));
+ }
+ else
+ {
+ BigInteger[] v = getLucas(mu, m, true);
+ vm = v[1];
+ }
- SimpleBigDecimal lambda0 = approximateDivisionByN(
- k, s[0], vm, a, m, c);
-
- SimpleBigDecimal lambda1 = approximateDivisionByN(
- k, s[1], vm, a, m, c);
+ SimpleBigDecimal lambda0 = approximateDivisionByN(k, s[0], vm, a, m, c);
+ SimpleBigDecimal lambda1 = approximateDivisionByN(k, s[1], vm, a, m, c);
ZTauElement q = round(lambda0, lambda1, mu);
// r0 = n - d0*q0 - 2*s1*q1
BigInteger r0 = k.subtract(d0.multiply(q.u)).subtract(
- BigInteger.valueOf(2).multiply(s[1]).multiply(q.v));
+ s[1].multiply(q.v).shiftLeft(1));
// r1 = s1*q0 - s0*q1
BigInteger r1 = s[1].multiply(q.u).subtract(s[0].multiply(q.v));
@@ -655,11 +640,10 @@
public static ECPoint.AbstractF2m multiplyRTnaf(ECPoint.AbstractF2m p, BigInteger k)
{
ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m) p.getCurve();
- int m = curve.getFieldSize();
int a = curve.getA().toBigInteger().intValue();
byte mu = getMu(a);
- BigInteger[] s = curve.getSi();
- ZTauElement rho = partModReduction(k, m, (byte)a, s, mu, (byte)10);
+
+ ZTauElement rho = partModReduction(curve, k, (byte)a, mu, (byte)10);
return multiplyTnaf(p, rho);
}
@@ -676,12 +660,11 @@
public static ECPoint.AbstractF2m multiplyTnaf(ECPoint.AbstractF2m p, ZTauElement lambda)
{
ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
+ ECPoint.AbstractF2m pNeg = (ECPoint.AbstractF2m)p.negate();
byte mu = getMu(curve.getA());
byte[] u = tauAdicNaf(mu, lambda);
- ECPoint.AbstractF2m q = multiplyFromTnaf(p, u);
-
- return q;
+ return multiplyFromTnaf(p, pNeg, u);
}
/**
@@ -693,11 +676,10 @@
* @param u The the TNAF of <code>λ</code>..
* @return <code>λ * p</code>
*/
- public static ECPoint.AbstractF2m multiplyFromTnaf(ECPoint.AbstractF2m p, byte[] u)
+ public static ECPoint.AbstractF2m multiplyFromTnaf(ECPoint.AbstractF2m p, ECPoint.AbstractF2m pNeg, byte[] u)
{
ECCurve curve = p.getCurve();
ECPoint.AbstractF2m q = (ECPoint.AbstractF2m)curve.getInfinity();
- ECPoint.AbstractF2m pNeg = (ECPoint.AbstractF2m)p.negate();
int tauCount = 0;
for (int i = u.length - 1; i >= 0; i--)
{
@@ -733,10 +715,9 @@
* @return The <code>[τ]</code>-adic window NAF of
* <code>λ</code>.
*/
- public static byte[] tauAdicWNaf(byte mu, ZTauElement lambda,
- byte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha)
+ public static byte[] tauAdicWNaf(byte mu, ZTauElement lambda, int width, int tw, ZTauElement[] alpha)
{
- if (!((mu == 1) || (mu == -1)))
+ if (!(mu == 1 || mu == -1))
{
throw new IllegalArgumentException("mu must be 1 or -1");
}
@@ -752,75 +733,72 @@
// The array holding the TNAF
byte[] u = new byte[maxLength];
- // 2^(width - 1)
- BigInteger pow2wMin1 = pow2w.shiftRight(1);
+ int pow2Width = 1 << width;
+ int pow2Mask = pow2Width - 1;
+ int s = 32 - width;
// Split lambda into two BigIntegers to simplify calculations
- BigInteger r0 = lambda.u;
- BigInteger r1 = lambda.v;
- int i = 0;
+ BigInteger R0 = lambda.u;
+ BigInteger R1 = lambda.v;
+ int uPos = 0;
// while lambda <> (0, 0)
- while (!((r0.equals(ECConstants.ZERO))&&(r1.equals(ECConstants.ZERO))))
+ while (R0.bitLength() > 62 || R1.bitLength() > 62)
{
- // if r0 is odd
- if (r0.testBit(0))
+ if (R0.testBit(0))
{
- // uUnMod = r0 + r1*tw mod 2^width
- BigInteger uUnMod
- = r0.add(r1.multiply(tw)).mod(pow2w);
-
- byte uLocal;
- // if uUnMod >= 2^(width - 1)
- if (uUnMod.compareTo(pow2wMin1) >= 0)
- {
- uLocal = (byte) uUnMod.subtract(pow2w).intValue();
- }
- else
- {
- uLocal = (byte) uUnMod.intValue();
- }
- // uLocal is now in [-2^(width-1), 2^(width-1)-1]
+ int uVal = R0.intValue() + (R1.intValue() * tw);
+ int alphaPos = uVal & pow2Mask;
- u[i] = uLocal;
- boolean s = true;
- if (uLocal < 0)
- {
- s = false;
- uLocal = (byte)-uLocal;
- }
- // uLocal is now >= 0
-
- if (s)
- {
- r0 = r0.subtract(alpha[uLocal].u);
- r1 = r1.subtract(alpha[uLocal].v);
- }
- else
- {
- r0 = r0.add(alpha[uLocal].u);
- r1 = r1.add(alpha[uLocal].v);
- }
- }
- else
- {
- u[i] = 0;
+ u[uPos] = (byte)((uVal << s) >> s);
+ R0 = R0.subtract(alpha[alphaPos].u);
+ R1 = R1.subtract(alpha[alphaPos].v);
}
- BigInteger t = r0;
+ ++uPos;
+ BigInteger t = R0.shiftRight(1);
if (mu == 1)
{
- r0 = r1.add(r0.shiftRight(1));
+ R0 = R1.add(t);
}
- else
+ else // mu == -1
{
- // mu == -1
- r0 = r1.subtract(r0.shiftRight(1));
+ R0 = R1.subtract(t);
}
- r1 = t.shiftRight(1).negate();
- i++;
+ R1 = t.negate();
}
+
+ long r0_64 = BigIntegers.longValueExact(R0);
+ long r1_64 = BigIntegers.longValueExact(R1);
+
+ // while lambda <> (0, 0)
+ while ((r0_64 | r1_64) != 0L)
+ {
+ if ((r0_64 & 1L) != 0L)
+ {
+ int uVal = (int)r0_64 + ((int)r1_64 * tw);
+ int alphaPos = uVal & pow2Mask;
+
+ u[uPos] = (byte)((uVal << s) >> s);
+ r0_64 -= alpha[alphaPos].u.intValue();
+ r1_64 -= alpha[alphaPos].v.intValue();
+ }
+
+ ++uPos;
+
+ long t_64 = r0_64 >> 1;
+ if (mu == 1)
+ {
+ r0_64 = r1_64 + t_64;
+ }
+ else // mu == -1
+ {
+ r0_64 = r1_64 - t_64;
+ }
+ r1_64 = -t_64;
+ }
+
return u;
}
@@ -832,6 +810,7 @@
*/
public static ECPoint.AbstractF2m[] getPreComp(ECPoint.AbstractF2m p, byte a)
{
+ ECPoint.AbstractF2m pNeg = (ECPoint.AbstractF2m)p.negate();
byte[][] alphaTnaf = (a == 0) ? Tnaf.alpha0Tnaf : Tnaf.alpha1Tnaf;
ECPoint.AbstractF2m[] pu = new ECPoint.AbstractF2m[(alphaTnaf.length + 1) >>> 1];
@@ -840,7 +819,7 @@
int precompLen = alphaTnaf.length;
for (int i = 3; i < precompLen; i += 2)
{
- pu[i >>> 1] = Tnaf.multiplyFromTnaf(p, alphaTnaf[i]);
+ pu[i >>> 1] = Tnaf.multiplyFromTnaf(p, pNeg, alphaTnaf[i]);
}
p.getCurve().normalizeAll(pu);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WTauNafMultiplier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WTauNafMultiplier.java
index 8ce3931..be24e23 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WTauNafMultiplier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WTauNafMultiplier.java
@@ -31,12 +31,10 @@
ECPoint.AbstractF2m p = (ECPoint.AbstractF2m)point;
ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
- int m = curve.getFieldSize();
byte a = curve.getA().toBigInteger().byteValue();
byte mu = Tnaf.getMu(a);
- BigInteger[] s = curve.getSi();
- ZTauElement rho = Tnaf.partModReduction(k, m, a, s, mu, (byte)10);
+ ZTauElement rho = Tnaf.partModReduction(curve, k, a, mu, (byte)10);
return multiplyWTnaf(p, rho, a, mu);
}
@@ -57,8 +55,7 @@
BigInteger tw = Tnaf.getTw(mu, Tnaf.WIDTH);
- byte[]u = Tnaf.tauAdicWNaf(mu, lambda, Tnaf.WIDTH,
- BigInteger.valueOf(Tnaf.POW_2_WIDTH), tw, alpha);
+ byte[] u = Tnaf.tauAdicWNaf(mu, lambda, Tnaf.WIDTH, tw.intValue(), alpha);
return multiplyFromWTnaf(p, u);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
index 0d2ca9c..dc8c19a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
@@ -102,6 +102,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ Nat256.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
{
int c = Nat256.mulAddTo(x, y, zz);
@@ -175,6 +181,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ Nat256.square(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -190,6 +202,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ Nat256.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat256.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat256.sub(x, y, z);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
index f5077be..ed3c080 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
@@ -150,49 +150,51 @@
return this;
}
+ int[] tt0 = Nat256.createExt();
+
int[] x2 = Nat256.create();
- SecP256K1Field.square(x1, x2);
- SecP256K1Field.multiply(x2, x1, x2);
+ SecP256K1Field.square(x1, x2, tt0);
+ SecP256K1Field.multiply(x2, x1, x2, tt0);
int[] x3 = Nat256.create();
- SecP256K1Field.square(x2, x3);
- SecP256K1Field.multiply(x3, x1, x3);
+ SecP256K1Field.square(x2, x3, tt0);
+ SecP256K1Field.multiply(x3, x1, x3, tt0);
int[] x6 = Nat256.create();
- SecP256K1Field.squareN(x3, 3, x6);
- SecP256K1Field.multiply(x6, x3, x6);
+ SecP256K1Field.squareN(x3, 3, x6, tt0);
+ SecP256K1Field.multiply(x6, x3, x6, tt0);
int[] x9 = x6;
- SecP256K1Field.squareN(x6, 3, x9);
- SecP256K1Field.multiply(x9, x3, x9);
+ SecP256K1Field.squareN(x6, 3, x9, tt0);
+ SecP256K1Field.multiply(x9, x3, x9, tt0);
int[] x11 = x9;
- SecP256K1Field.squareN(x9, 2, x11);
- SecP256K1Field.multiply(x11, x2, x11);
+ SecP256K1Field.squareN(x9, 2, x11, tt0);
+ SecP256K1Field.multiply(x11, x2, x11, tt0);
int[] x22 = Nat256.create();
- SecP256K1Field.squareN(x11, 11, x22);
- SecP256K1Field.multiply(x22, x11, x22);
+ SecP256K1Field.squareN(x11, 11, x22, tt0);
+ SecP256K1Field.multiply(x22, x11, x22, tt0);
int[] x44 = x11;
- SecP256K1Field.squareN(x22, 22, x44);
- SecP256K1Field.multiply(x44, x22, x44);
+ SecP256K1Field.squareN(x22, 22, x44, tt0);
+ SecP256K1Field.multiply(x44, x22, x44, tt0);
int[] x88 = Nat256.create();
- SecP256K1Field.squareN(x44, 44, x88);
- SecP256K1Field.multiply(x88, x44, x88);
+ SecP256K1Field.squareN(x44, 44, x88, tt0);
+ SecP256K1Field.multiply(x88, x44, x88, tt0);
int[] x176 = Nat256.create();
- SecP256K1Field.squareN(x88, 88, x176);
- SecP256K1Field.multiply(x176, x88, x176);
+ SecP256K1Field.squareN(x88, 88, x176, tt0);
+ SecP256K1Field.multiply(x176, x88, x176, tt0);
int[] x220 = x88;
- SecP256K1Field.squareN(x176, 44, x220);
- SecP256K1Field.multiply(x220, x44, x220);
+ SecP256K1Field.squareN(x176, 44, x220, tt0);
+ SecP256K1Field.multiply(x220, x44, x220, tt0);
int[] x223 = x44;
- SecP256K1Field.squareN(x220, 3, x223);
- SecP256K1Field.multiply(x223, x3, x223);
+ SecP256K1Field.squareN(x220, 3, x223, tt0);
+ SecP256K1Field.multiply(x223, x3, x223, tt0);
int[] t1 = x223;
- SecP256K1Field.squareN(t1, 23, t1);
- SecP256K1Field.multiply(t1, x22, t1);
- SecP256K1Field.squareN(t1, 6, t1);
- SecP256K1Field.multiply(t1, x2, t1);
- SecP256K1Field.squareN(t1, 2, t1);
+ SecP256K1Field.squareN(t1, 23, t1, tt0);
+ SecP256K1Field.multiply(t1, x22, t1, tt0);
+ SecP256K1Field.squareN(t1, 6, t1, tt0);
+ SecP256K1Field.multiply(t1, x2, t1, tt0);
+ SecP256K1Field.squareN(t1, 2, t1, tt0);
int[] t2 = x2;
- SecP256K1Field.square(t1, t2);
+ SecP256K1Field.square(t1, t2, tt0);
return Nat256.eq(x1, t2) ? new SecP256K1FieldElement(t1) : null;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
index 733663c..c2c01f5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
@@ -52,6 +52,7 @@
SecP256K1FieldElement Z2 = (SecP256K1FieldElement)b.getZCoord(0);
int c;
+ int[] tt0 = Nat256.createExt();
int[] tt1 = Nat256.createExt();
int[] t2 = Nat256.create();
int[] t3 = Nat256.create();
@@ -67,13 +68,13 @@
else
{
S2 = t3;
- SecP256K1Field.square(Z1.x, S2);
+ SecP256K1Field.square(Z1.x, S2, tt0);
U2 = t2;
- SecP256K1Field.multiply(S2, X2.x, U2);
+ SecP256K1Field.multiply(S2, X2.x, U2, tt0);
- SecP256K1Field.multiply(S2, Z1.x, S2);
- SecP256K1Field.multiply(S2, Y2.x, S2);
+ SecP256K1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP256K1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -86,13 +87,13 @@
else
{
S1 = t4;
- SecP256K1Field.square(Z2.x, S1);
+ SecP256K1Field.square(Z2.x, S1, tt0);
U1 = tt1;
- SecP256K1Field.multiply(S1, X1.x, U1);
+ SecP256K1Field.multiply(S1, X1.x, U1, tt0);
- SecP256K1Field.multiply(S1, Z2.x, S1);
- SecP256K1Field.multiply(S1, Y1.x, S1);
+ SecP256K1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP256K1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat256.create();
@@ -115,13 +116,13 @@
}
int[] HSquared = t3;
- SecP256K1Field.square(H, HSquared);
+ SecP256K1Field.square(H, HSquared, tt0);
int[] G = Nat256.create();
- SecP256K1Field.multiply(HSquared, H, G);
+ SecP256K1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP256K1Field.multiply(HSquared, U1, V);
+ SecP256K1Field.multiply(HSquared, U1, V, tt0);
SecP256K1Field.negate(G, G);
Nat256.mul(S1, G, tt1);
@@ -130,7 +131,7 @@
SecP256K1Field.reduce32(c, G);
SecP256K1FieldElement X3 = new SecP256K1FieldElement(t4);
- SecP256K1Field.square(R, X3.x);
+ SecP256K1Field.square(R, X3.x, tt0);
SecP256K1Field.subtract(X3.x, G, X3.x);
SecP256K1FieldElement Y3 = new SecP256K1FieldElement(G);
@@ -141,11 +142,11 @@
SecP256K1FieldElement Z3 = new SecP256K1FieldElement(H);
if (!Z1IsOne)
{
- SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP256K1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP256K1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
@@ -172,20 +173,21 @@
SecP256K1FieldElement X1 = (SecP256K1FieldElement)this.x, Z1 = (SecP256K1FieldElement)this.zs[0];
int c;
+ int[] tt0 = Nat256.createExt();
int[] Y1Squared = Nat256.create();
- SecP256K1Field.square(Y1.x, Y1Squared);
+ SecP256K1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat256.create();
- SecP256K1Field.square(Y1Squared, T);
+ SecP256K1Field.square(Y1Squared, T, tt0);
int[] M = Nat256.create();
- SecP256K1Field.square(X1.x, M);
+ SecP256K1Field.square(X1.x, M, tt0);
c = Nat256.addBothTo(M, M, M);
SecP256K1Field.reduce32(c, M);
int[] S = Y1Squared;
- SecP256K1Field.multiply(Y1Squared, X1.x, S);
+ SecP256K1Field.multiply(Y1Squared, X1.x, S, tt0);
c = Nat.shiftUpBits(8, S, 2, 0);
SecP256K1Field.reduce32(c, S);
@@ -194,20 +196,20 @@
SecP256K1Field.reduce32(c, t1);
SecP256K1FieldElement X3 = new SecP256K1FieldElement(T);
- SecP256K1Field.square(M, X3.x);
+ SecP256K1Field.square(M, X3.x, tt0);
SecP256K1Field.subtract(X3.x, S, X3.x);
SecP256K1Field.subtract(X3.x, S, X3.x);
SecP256K1FieldElement Y3 = new SecP256K1FieldElement(S);
SecP256K1Field.subtract(S, X3.x, Y3.x);
- SecP256K1Field.multiply(Y3.x, M, Y3.x);
+ SecP256K1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP256K1Field.subtract(Y3.x, t1, Y3.x);
SecP256K1FieldElement Z3 = new SecP256K1FieldElement(M);
SecP256K1Field.twice(Y1.x, Z3.x);
if (!Z1.isOne())
{
- SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP256K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
index 9d3b898..56b9382 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
@@ -98,6 +98,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ Nat256.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
{
int c = Nat256.mulAddTo(x, y, zz);
@@ -244,6 +250,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ Nat256.square(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -259,6 +271,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ Nat256.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat256.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat256.sub(x, y, z);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
index e84cd47..5f879db 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
@@ -141,32 +141,33 @@
return this;
}
+ int[] tt0 = Nat256.createExt();
int[] t1 = Nat256.create();
int[] t2 = Nat256.create();
- SecP256R1Field.square(x1, t1);
- SecP256R1Field.multiply(t1, x1, t1);
+ SecP256R1Field.square(x1, t1, tt0);
+ SecP256R1Field.multiply(t1, x1, t1, tt0);
- SecP256R1Field.squareN(t1, 2, t2);
- SecP256R1Field.multiply(t2, t1, t2);
+ SecP256R1Field.squareN(t1, 2, t2, tt0);
+ SecP256R1Field.multiply(t2, t1, t2, tt0);
- SecP256R1Field.squareN(t2, 4, t1);
- SecP256R1Field.multiply(t1, t2, t1);
+ SecP256R1Field.squareN(t2, 4, t1, tt0);
+ SecP256R1Field.multiply(t1, t2, t1, tt0);
- SecP256R1Field.squareN(t1, 8, t2);
- SecP256R1Field.multiply(t2, t1, t2);
+ SecP256R1Field.squareN(t1, 8, t2, tt0);
+ SecP256R1Field.multiply(t2, t1, t2, tt0);
- SecP256R1Field.squareN(t2, 16, t1);
- SecP256R1Field.multiply(t1, t2, t1);
+ SecP256R1Field.squareN(t2, 16, t1, tt0);
+ SecP256R1Field.multiply(t1, t2, t1, tt0);
- SecP256R1Field.squareN(t1, 32, t1);
- SecP256R1Field.multiply(t1, x1, t1);
+ SecP256R1Field.squareN(t1, 32, t1, tt0);
+ SecP256R1Field.multiply(t1, x1, t1, tt0);
- SecP256R1Field.squareN(t1, 96, t1);
- SecP256R1Field.multiply(t1, x1, t1);
+ SecP256R1Field.squareN(t1, 96, t1, tt0);
+ SecP256R1Field.multiply(t1, x1, t1, tt0);
- SecP256R1Field.squareN(t1, 94, t1);
- SecP256R1Field.square(t1, t2);
+ SecP256R1Field.squareN(t1, 94, t1, tt0);
+ SecP256R1Field.square(t1, t2, tt0);
return Nat256.eq(x1, t2) ? new SecP256R1FieldElement(t1) : null;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
index 74627ca..70130e2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
@@ -51,6 +51,7 @@
SecP256R1FieldElement Z2 = (SecP256R1FieldElement)b.getZCoord(0);
int c;
+ int[] tt0 = Nat256.createExt();
int[] tt1 = Nat256.createExt();
int[] t2 = Nat256.create();
int[] t3 = Nat256.create();
@@ -66,13 +67,13 @@
else
{
S2 = t3;
- SecP256R1Field.square(Z1.x, S2);
+ SecP256R1Field.square(Z1.x, S2, tt0);
U2 = t2;
- SecP256R1Field.multiply(S2, X2.x, U2);
+ SecP256R1Field.multiply(S2, X2.x, U2, tt0);
- SecP256R1Field.multiply(S2, Z1.x, S2);
- SecP256R1Field.multiply(S2, Y2.x, S2);
+ SecP256R1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP256R1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -85,13 +86,13 @@
else
{
S1 = t4;
- SecP256R1Field.square(Z2.x, S1);
+ SecP256R1Field.square(Z2.x, S1, tt0);
U1 = tt1;
- SecP256R1Field.multiply(S1, X1.x, U1);
+ SecP256R1Field.multiply(S1, X1.x, U1, tt0);
- SecP256R1Field.multiply(S1, Z2.x, S1);
- SecP256R1Field.multiply(S1, Y1.x, S1);
+ SecP256R1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP256R1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat256.create();
@@ -114,13 +115,13 @@
}
int[] HSquared = t3;
- SecP256R1Field.square(H, HSquared);
+ SecP256R1Field.square(H, HSquared, tt0);
int[] G = Nat256.create();
- SecP256R1Field.multiply(HSquared, H, G);
+ SecP256R1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP256R1Field.multiply(HSquared, U1, V);
+ SecP256R1Field.multiply(HSquared, U1, V, tt0);
SecP256R1Field.negate(G, G);
Nat256.mul(S1, G, tt1);
@@ -129,7 +130,7 @@
SecP256R1Field.reduce32(c, G);
SecP256R1FieldElement X3 = new SecP256R1FieldElement(t4);
- SecP256R1Field.square(R, X3.x);
+ SecP256R1Field.square(R, X3.x, tt0);
SecP256R1Field.subtract(X3.x, G, X3.x);
SecP256R1FieldElement Y3 = new SecP256R1FieldElement(G);
@@ -140,11 +141,11 @@
SecP256R1FieldElement Z3 = new SecP256R1FieldElement(H);
if (!Z1IsOne)
{
- SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP256R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP256R1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
@@ -170,14 +171,15 @@
SecP256R1FieldElement X1 = (SecP256R1FieldElement)this.x, Z1 = (SecP256R1FieldElement)this.zs[0];
int c;
+ int[] tt0 = Nat256.createExt();
int[] t1 = Nat256.create();
int[] t2 = Nat256.create();
int[] Y1Squared = Nat256.create();
- SecP256R1Field.square(Y1.x, Y1Squared);
+ SecP256R1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat256.create();
- SecP256R1Field.square(Y1Squared, T);
+ SecP256R1Field.square(Y1Squared, T, tt0);
boolean Z1IsOne = Z1.isOne();
@@ -185,19 +187,19 @@
if (!Z1IsOne)
{
Z1Squared = t2;
- SecP256R1Field.square(Z1.x, Z1Squared);
+ SecP256R1Field.square(Z1.x, Z1Squared, tt0);
}
SecP256R1Field.subtract(X1.x, Z1Squared, t1);
int[] M = t2;
SecP256R1Field.add(X1.x, Z1Squared, M);
- SecP256R1Field.multiply(M, t1, M);
+ SecP256R1Field.multiply(M, t1, M, tt0);
c = Nat256.addBothTo(M, M, M);
SecP256R1Field.reduce32(c, M);
int[] S = Y1Squared;
- SecP256R1Field.multiply(Y1Squared, X1.x, S);
+ SecP256R1Field.multiply(Y1Squared, X1.x, S, tt0);
c = Nat.shiftUpBits(8, S, 2, 0);
SecP256R1Field.reduce32(c, S);
@@ -205,20 +207,20 @@
SecP256R1Field.reduce32(c, t1);
SecP256R1FieldElement X3 = new SecP256R1FieldElement(T);
- SecP256R1Field.square(M, X3.x);
+ SecP256R1Field.square(M, X3.x, tt0);
SecP256R1Field.subtract(X3.x, S, X3.x);
SecP256R1Field.subtract(X3.x, S, X3.x);
SecP256R1FieldElement Y3 = new SecP256R1FieldElement(S);
SecP256R1Field.subtract(S, X3.x, Y3.x);
- SecP256R1Field.multiply(Y3.x, M, Y3.x);
+ SecP256R1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP256R1Field.subtract(Y3.x, t1, Y3.x);
SecP256R1FieldElement Z3 = new SecP256R1FieldElement(M);
SecP256R1Field.twice(Y1.x, Z3.x);
if (!Z1IsOne)
{
- SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP256R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
index 8115b8e..9b30caa 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
@@ -104,6 +104,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ Nat384.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void negate(int[] x, int[] z)
{
if (0 != isZero(x))
@@ -240,6 +246,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ Nat384.square(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -255,6 +267,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ Nat384.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat384.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat.sub(12, x, y, z);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
index 2c7cd14..d5ef6d3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
@@ -141,54 +141,55 @@
return this;
}
+ int[] tt0 = Nat.create(24);
int[] t1 = Nat.create(12);
int[] t2 = Nat.create(12);
int[] t3 = Nat.create(12);
int[] t4 = Nat.create(12);
- SecP384R1Field.square(x1, t1);
- SecP384R1Field.multiply(t1, x1, t1);
+ SecP384R1Field.square(x1, t1, tt0);
+ SecP384R1Field.multiply(t1, x1, t1, tt0);
- SecP384R1Field.squareN(t1, 2, t2);
- SecP384R1Field.multiply(t2, t1, t2);
+ SecP384R1Field.squareN(t1, 2, t2, tt0);
+ SecP384R1Field.multiply(t2, t1, t2, tt0);
- SecP384R1Field.square(t2, t2);
- SecP384R1Field.multiply(t2, x1, t2);
+ SecP384R1Field.square(t2, t2, tt0);
+ SecP384R1Field.multiply(t2, x1, t2, tt0);
- SecP384R1Field.squareN(t2, 5, t3);
- SecP384R1Field.multiply(t3, t2, t3);
+ SecP384R1Field.squareN(t2, 5, t3, tt0);
+ SecP384R1Field.multiply(t3, t2, t3, tt0);
- SecP384R1Field.squareN(t3, 5, t4);
- SecP384R1Field.multiply(t4, t2, t4);
+ SecP384R1Field.squareN(t3, 5, t4, tt0);
+ SecP384R1Field.multiply(t4, t2, t4, tt0);
- SecP384R1Field.squareN(t4, 15, t2);
- SecP384R1Field.multiply(t2, t4, t2);
+ SecP384R1Field.squareN(t4, 15, t2, tt0);
+ SecP384R1Field.multiply(t2, t4, t2, tt0);
- SecP384R1Field.squareN(t2, 2, t3);
- SecP384R1Field.multiply(t1, t3, t1);
+ SecP384R1Field.squareN(t2, 2, t3, tt0);
+ SecP384R1Field.multiply(t1, t3, t1, tt0);
- SecP384R1Field.squareN(t3, 28, t3);
- SecP384R1Field.multiply(t2, t3, t2);
+ SecP384R1Field.squareN(t3, 28, t3, tt0);
+ SecP384R1Field.multiply(t2, t3, t2, tt0);
- SecP384R1Field.squareN(t2, 60, t3);
- SecP384R1Field.multiply(t3, t2, t3);
+ SecP384R1Field.squareN(t2, 60, t3, tt0);
+ SecP384R1Field.multiply(t3, t2, t3, tt0);
int[] r = t2;
- SecP384R1Field.squareN(t3, 120, r);
- SecP384R1Field.multiply(r, t3, r);
+ SecP384R1Field.squareN(t3, 120, r, tt0);
+ SecP384R1Field.multiply(r, t3, r, tt0);
- SecP384R1Field.squareN(r, 15, r);
- SecP384R1Field.multiply(r, t4, r);
+ SecP384R1Field.squareN(r, 15, r, tt0);
+ SecP384R1Field.multiply(r, t4, r, tt0);
- SecP384R1Field.squareN(r, 33, r);
- SecP384R1Field.multiply(r, t1, r);
+ SecP384R1Field.squareN(r, 33, r, tt0);
+ SecP384R1Field.multiply(r, t1, r, tt0);
- SecP384R1Field.squareN(r, 64, r);
- SecP384R1Field.multiply(r, x1, r);
+ SecP384R1Field.squareN(r, 64, r, tt0);
+ SecP384R1Field.multiply(r, x1, r, tt0);
- SecP384R1Field.squareN(r, 30, t1);
- SecP384R1Field.square(t1, t2);
+ SecP384R1Field.squareN(r, 30, t1, tt0);
+ SecP384R1Field.square(t1, t2, tt0);
return Nat.eq(12, x1, t2) ? new SecP384R1FieldElement(t1) : null;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
index c0ccd53..e0e86b5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
@@ -51,6 +51,7 @@
SecP384R1FieldElement Z2 = (SecP384R1FieldElement)b.getZCoord(0);
int c;
+ int[] tt0 = Nat.create(24);
int[] tt1 = Nat.create(24);
int[] tt2 = Nat.create(24);
int[] t3 = Nat.create(12);
@@ -66,13 +67,13 @@
else
{
S2 = t3;
- SecP384R1Field.square(Z1.x, S2);
+ SecP384R1Field.square(Z1.x, S2, tt0);
U2 = tt2;
- SecP384R1Field.multiply(S2, X2.x, U2);
+ SecP384R1Field.multiply(S2, X2.x, U2, tt0);
- SecP384R1Field.multiply(S2, Z1.x, S2);
- SecP384R1Field.multiply(S2, Y2.x, S2);
+ SecP384R1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP384R1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -85,13 +86,13 @@
else
{
S1 = t4;
- SecP384R1Field.square(Z2.x, S1);
+ SecP384R1Field.square(Z2.x, S1, tt0);
U1 = tt1;
- SecP384R1Field.multiply(S1, X1.x, U1);
+ SecP384R1Field.multiply(S1, X1.x, U1, tt0);
- SecP384R1Field.multiply(S1, Z2.x, S1);
- SecP384R1Field.multiply(S1, Y1.x, S1);
+ SecP384R1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP384R1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat.create(12);
@@ -114,13 +115,13 @@
}
int[] HSquared = t3;
- SecP384R1Field.square(H, HSquared);
+ SecP384R1Field.square(H, HSquared, tt0);
int[] G = Nat.create(12);
- SecP384R1Field.multiply(HSquared, H, G);
+ SecP384R1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP384R1Field.multiply(HSquared, U1, V);
+ SecP384R1Field.multiply(HSquared, U1, V, tt0);
SecP384R1Field.negate(G, G);
Nat384.mul(S1, G, tt1);
@@ -129,7 +130,7 @@
SecP384R1Field.reduce32(c, G);
SecP384R1FieldElement X3 = new SecP384R1FieldElement(t4);
- SecP384R1Field.square(R, X3.x);
+ SecP384R1Field.square(R, X3.x, tt0);
SecP384R1Field.subtract(X3.x, G, X3.x);
SecP384R1FieldElement Y3 = new SecP384R1FieldElement(G);
@@ -141,11 +142,11 @@
SecP384R1FieldElement Z3 = new SecP384R1FieldElement(H);
if (!Z1IsOne)
{
- SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP384R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP384R1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
@@ -171,14 +172,15 @@
SecP384R1FieldElement X1 = (SecP384R1FieldElement)this.x, Z1 = (SecP384R1FieldElement)this.zs[0];
int c;
+ int[] tt0 = Nat.create(24);
int[] t1 = Nat.create(12);
int[] t2 = Nat.create(12);
int[] Y1Squared = Nat.create(12);
- SecP384R1Field.square(Y1.x, Y1Squared);
+ SecP384R1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat.create(12);
- SecP384R1Field.square(Y1Squared, T);
+ SecP384R1Field.square(Y1Squared, T, tt0);
boolean Z1IsOne = Z1.isOne();
@@ -186,19 +188,19 @@
if (!Z1IsOne)
{
Z1Squared = t2;
- SecP384R1Field.square(Z1.x, Z1Squared);
+ SecP384R1Field.square(Z1.x, Z1Squared, tt0);
}
SecP384R1Field.subtract(X1.x, Z1Squared, t1);
int[] M = t2;
SecP384R1Field.add(X1.x, Z1Squared, M);
- SecP384R1Field.multiply(M, t1, M);
+ SecP384R1Field.multiply(M, t1, M, tt0);
c = Nat.addBothTo(12, M, M, M);
SecP384R1Field.reduce32(c, M);
int[] S = Y1Squared;
- SecP384R1Field.multiply(Y1Squared, X1.x, S);
+ SecP384R1Field.multiply(Y1Squared, X1.x, S, tt0);
c = Nat.shiftUpBits(12, S, 2, 0);
SecP384R1Field.reduce32(c, S);
@@ -206,20 +208,20 @@
SecP384R1Field.reduce32(c, t1);
SecP384R1FieldElement X3 = new SecP384R1FieldElement(T);
- SecP384R1Field.square(M, X3.x);
+ SecP384R1Field.square(M, X3.x, tt0);
SecP384R1Field.subtract(X3.x, S, X3.x);
SecP384R1Field.subtract(X3.x, S, X3.x);
SecP384R1FieldElement Y3 = new SecP384R1FieldElement(S);
SecP384R1Field.subtract(S, X3.x, Y3.x);
- SecP384R1Field.multiply(Y3.x, M, Y3.x);
+ SecP384R1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP384R1Field.subtract(Y3.x, t1, Y3.x);
SecP384R1FieldElement Z3 = new SecP384R1FieldElement(M);
SecP384R1Field.twice(Y1.x, Z3.x);
if (!Z1IsOne)
{
- SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP384R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
index 0e4431d..9d446be 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
@@ -81,6 +81,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ implMultiply(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void negate(int[] x, int[] z)
{
if (0 != isZero(x))
@@ -149,6 +155,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ implSquare(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -164,6 +176,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ implSquare(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ implSquare(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat.sub(16, x, y, z) + x[16] - y[16];
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
index 8f50293..893ec85 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
@@ -142,11 +142,12 @@
return this;
}
+ int[] tt0 = Nat.create(33);
int[] t1 = Nat.create(17);
int[] t2 = Nat.create(17);
- SecP521R1Field.squareN(x1, 519, t1);
- SecP521R1Field.square(t1, t2);
+ SecP521R1Field.squareN(x1, 519, t1, tt0);
+ SecP521R1Field.square(t1, t2, tt0);
return Nat.eq(17, x1, t2) ? new SecP521R1FieldElement(t1) : null;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
index 6e91cd4..af635fd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
@@ -49,6 +49,7 @@
SecP521R1FieldElement Z1 = (SecP521R1FieldElement)this.zs[0];
SecP521R1FieldElement Z2 = (SecP521R1FieldElement)b.getZCoord(0);
+ int[] tt0 = Nat.create(33);
int[] t1 = Nat.create(17);
int[] t2 = Nat.create(17);
int[] t3 = Nat.create(17);
@@ -64,13 +65,13 @@
else
{
S2 = t3;
- SecP521R1Field.square(Z1.x, S2);
+ SecP521R1Field.square(Z1.x, S2, tt0);
U2 = t2;
- SecP521R1Field.multiply(S2, X2.x, U2);
+ SecP521R1Field.multiply(S2, X2.x, U2, tt0);
- SecP521R1Field.multiply(S2, Z1.x, S2);
- SecP521R1Field.multiply(S2, Y2.x, S2);
+ SecP521R1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP521R1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -83,13 +84,13 @@
else
{
S1 = t4;
- SecP521R1Field.square(Z2.x, S1);
+ SecP521R1Field.square(Z2.x, S1, tt0);
U1 = t1;
- SecP521R1Field.multiply(S1, X1.x, U1);
+ SecP521R1Field.multiply(S1, X1.x, U1, tt0);
- SecP521R1Field.multiply(S1, Z2.x, S1);
- SecP521R1Field.multiply(S1, Y1.x, S1);
+ SecP521R1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP521R1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat.create(17);
@@ -112,35 +113,35 @@
}
int[] HSquared = t3;
- SecP521R1Field.square(H, HSquared);
+ SecP521R1Field.square(H, HSquared, tt0);
int[] G = Nat.create(17);
- SecP521R1Field.multiply(HSquared, H, G);
+ SecP521R1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP521R1Field.multiply(HSquared, U1, V);
+ SecP521R1Field.multiply(HSquared, U1, V, tt0);
- SecP521R1Field.multiply(S1, G, t1);
+ SecP521R1Field.multiply(S1, G, t1, tt0);
SecP521R1FieldElement X3 = new SecP521R1FieldElement(t4);
- SecP521R1Field.square(R, X3.x);
+ SecP521R1Field.square(R, X3.x, tt0);
SecP521R1Field.add(X3.x, G, X3.x);
SecP521R1Field.subtract(X3.x, V, X3.x);
SecP521R1Field.subtract(X3.x, V, X3.x);
SecP521R1FieldElement Y3 = new SecP521R1FieldElement(G);
SecP521R1Field.subtract(V, X3.x, Y3.x);
- SecP521R1Field.multiply(Y3.x, R, t2);
+ SecP521R1Field.multiply(Y3.x, R, t2, tt0);
SecP521R1Field.subtract(t2, t1, Y3.x);
SecP521R1FieldElement Z3 = new SecP521R1FieldElement(H);
if (!Z1IsOne)
{
- SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP521R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP521R1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
@@ -165,14 +166,15 @@
SecP521R1FieldElement X1 = (SecP521R1FieldElement)this.x, Z1 = (SecP521R1FieldElement)this.zs[0];
+ int[] tt0 = Nat.create(33);
int[] t1 = Nat.create(17);
int[] t2 = Nat.create(17);
int[] Y1Squared = Nat.create(17);
- SecP521R1Field.square(Y1.x, Y1Squared);
+ SecP521R1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat.create(17);
- SecP521R1Field.square(Y1Squared, T);
+ SecP521R1Field.square(Y1Squared, T, tt0);
boolean Z1IsOne = Z1.isOne();
@@ -180,19 +182,19 @@
if (!Z1IsOne)
{
Z1Squared = t2;
- SecP521R1Field.square(Z1.x, Z1Squared);
+ SecP521R1Field.square(Z1.x, Z1Squared, tt0);
}
SecP521R1Field.subtract(X1.x, Z1Squared, t1);
int[] M = t2;
SecP521R1Field.add(X1.x, Z1Squared, M);
- SecP521R1Field.multiply(M, t1, M);
+ SecP521R1Field.multiply(M, t1, M, tt0);
Nat.addBothTo(17, M, M, M);
SecP521R1Field.reduce23(M);
int[] S = Y1Squared;
- SecP521R1Field.multiply(Y1Squared, X1.x, S);
+ SecP521R1Field.multiply(Y1Squared, X1.x, S, tt0);
Nat.shiftUpBits(17, S, 2, 0);
SecP521R1Field.reduce23(S);
@@ -200,20 +202,20 @@
SecP521R1Field.reduce23(t1);
SecP521R1FieldElement X3 = new SecP521R1FieldElement(T);
- SecP521R1Field.square(M, X3.x);
+ SecP521R1Field.square(M, X3.x, tt0);
SecP521R1Field.subtract(X3.x, S, X3.x);
SecP521R1Field.subtract(X3.x, S, X3.x);
SecP521R1FieldElement Y3 = new SecP521R1FieldElement(S);
SecP521R1Field.subtract(S, X3.x, Y3.x);
- SecP521R1Field.multiply(Y3.x, M, Y3.x);
+ SecP521R1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP521R1Field.subtract(Y3.x, t1, Y3.x);
SecP521R1FieldElement Z3 = new SecP521R1FieldElement(M);
SecP521R1Field.twice(Y1.x, Z3.x);
if (!Z1IsOne)
{
- SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP521R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
index e7f3fe0..e26c5ef 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
@@ -11,17 +11,6 @@
protected final BigInteger beta, lambda;
protected final ScalarSplitParameters splitParams;
- /**
- * @deprecated Use constructor taking a {@link ScalarSplitParameters} instead.
- */
- public GLVTypeBParameters(BigInteger beta, BigInteger lambda, BigInteger[] v1, BigInteger[] v2, BigInteger g1,
- BigInteger g2, int bits)
- {
- this.beta = beta;
- this.lambda = lambda;
- this.splitParams = new ScalarSplitParameters(v1, v2, g1, g2, bits);
- }
-
public GLVTypeBParameters(BigInteger beta, BigInteger lambda, ScalarSplitParameters splitParams)
{
this.beta = beta;
@@ -43,60 +32,4 @@
{
return splitParams;
}
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV1A()
- {
- return getSplitParams().getV1A();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV1B()
- {
- return getSplitParams().getV1B();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV2A()
- {
- return getSplitParams().getV2A();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV2B()
- {
- return getSplitParams().getV2B();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getG1()
- {
- return getSplitParams().getG1();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getG2()
- {
- return getSplitParams().getG2();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public int getBits()
- {
- return getSplitParams().getBits();
- }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/field/FiniteFields.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/field/FiniteFields.java
index 3b2f617..4f1ae40 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/field/FiniteFields.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/field/FiniteFields.java
@@ -3,6 +3,8 @@
import java.math.BigInteger;
+import com.android.org.bouncycastle.util.BigIntegers;
+
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -43,7 +45,7 @@
if (bitLength < 3)
{
- switch (characteristic.intValue())
+ switch (BigIntegers.intValueExact(characteristic))
{
case 2:
return GF_2;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Mod.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Mod.java
index 80e45ca..e775375 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Mod.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Mod.java
@@ -18,17 +18,6 @@
private static final int M30 = 0x3FFFFFFF;
private static final long M32L = 0xFFFFFFFFL;
- /** @deprecated Will be removed. */
- public static void add(int[] p, int[] x, int[] y, int[] z)
- {
- int len = p.length;
- int c = Nat.add(len, x, y, z);
- if (c != 0)
- {
- Nat.subFrom(len, p, z);
- }
- }
-
public static void checkedModOddInverse(int[] m, int[] x, int[] z)
{
if (0 == modOddInverse(m, x, z))
@@ -58,12 +47,6 @@
return x;
}
- /** @deprecated Use {@link #checkedModOddInverseVar(int[], int[], int[])} instead. */
- public static void invert(int[] m, int[] x, int[] z)
- {
- checkedModOddInverseVar(m, x, z);
- }
-
public static int modOddInverse(int[] m, int[] x, int[] z)
{
int len32 = m.length;
@@ -86,13 +69,13 @@
encode30(bits, m, 0, M, 0);
System.arraycopy(M, 0, F, 0, len30);
- int eta = -1;
+ int delta = 0;
int m0Inv32 = inverse32(M[0]);
int maxDivsteps = getMaximumDivsteps(bits);
for (int divSteps = 0; divSteps < maxDivsteps; divSteps += 30)
{
- eta = divsteps30(eta, F[0], G[0], t);
+ delta = divsteps30(delta, F[0], G[0], t);
updateDE30(len30, D, E, t, m0Inv32, M);
updateFG30(len30, F, G, t);
}
@@ -232,17 +215,6 @@
return s;
}
- /** @deprecated Will be removed. */
- public static void subtract(int[] p, int[] x, int[] y, int[] z)
- {
- int len = p.length;
- int c = Nat.sub(len, x, y, z);
- if (c != 0)
- {
- Nat.addTo(len, p, z);
- }
- }
-
private static int add30(int len30, int[] D, int[] M)
{
// assert len30 > 0;
@@ -280,7 +252,6 @@
// assert len30 > 0;
// assert D.length >= len30;
// assert M.length >= len30;
-
int last = len30 - 1;
{
@@ -335,38 +306,38 @@
}
}
- private static int divsteps30(int eta, int f0, int g0, int[] t)
+ private static int divsteps30(int delta, int f0, int g0, int[] t)
{
- int u = 1, v = 0, q = 0, r = 1;
+ int u = 1 << 30, v = 0, q = 0, r = 1 << 30;
int f = f0, g = g0;
for (int i = 0; i < 30; ++i)
{
// assert (f & 1) == 1;
-// assert (u * f0 + v * g0) == f << i;
-// assert (q * f0 + r * g0) == g << i;
+// assert ((u >> (30 - i)) * f0 + (v >> (30 - i)) * g0) == f << i;
+// assert ((q >> (30 - i)) * f0 + (r >> (30 - i)) * g0) == g << i;
- int c1 = eta >> 31;
+ int c1 = delta >> 31;
int c2 = -(g & 1);
- int x = (f ^ c1) - c1;
- int y = (u ^ c1) - c1;
- int z = (v ^ c1) - c1;
+ int x = f ^ c1;
+ int y = u ^ c1;
+ int z = v ^ c1;
- g += x & c2;
- q += y & c2;
- r += z & c2;
+ g -= x & c2;
+ q -= y & c2;
+ r -= z & c2;
- c1 &= c2;
- eta = (eta ^ c1) - (c1 + 1);
+ c2 &= ~c1;
+ delta = (delta ^ c2) - (c2 - 1);
- f += g & c1;
- u += q & c1;
- v += r & c1;
+ f += g & c2;
+ u += q & c2;
+ v += r & c2;
g >>= 1;
- u <<= 1;
- v <<= 1;
+ q >>= 1;
+ r >>= 1;
}
t[0] = u;
@@ -374,7 +345,7 @@
t[2] = q;
t[3] = r;
- return eta;
+ return delta;
}
private static int divsteps30Var(int eta, int f0, int g0, int[] t)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat.java
index cb15aea..0787776 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat.java
@@ -236,6 +236,19 @@
return (int)c;
}
+ public static int caddTo(int len, int mask, int[] x, int[] z)
+ {
+ long MASK = -(mask & 1) & M;
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (z[i] & M) + (x[i] & MASK);
+ z[i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
public static void cmov(int len, int mask, int[] x, int xOff, int[] z, int zOff)
{
mask = -(mask & 1);
@@ -1129,41 +1142,6 @@
shiftUpBit(extLen, zz, zzOff, x[xOff] << 31);
}
- /**
- * @deprecated Use {@link #squareWordAddTo(int[], int, int[])} instead.
- */
- public static int squareWordAdd(int[] x, int xPos, int[] z)
- {
- long c = 0, xVal = x[xPos] & M;
- int i = 0;
- do
- {
- c += xVal * (x[i] & M) + (z[xPos + i] & M);
- z[xPos + i] = (int)c;
- c >>>= 32;
- }
- while (++i < xPos);
- return (int)c;
- }
-
- /**
- * @deprecated Use {@link #squareWordAddTo(int[], int, int, int[], int)} instead.
- */
- public static int squareWordAdd(int[] x, int xOff, int xPos, int[] z, int zOff)
- {
- long c = 0, xVal = x[xOff + xPos] & M;
- int i = 0;
- do
- {
- c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M);
- z[xPos + zOff] = (int)c;
- c >>>= 32;
- ++zOff;
- }
- while (++i < xPos);
- return (int)c;
- }
-
public static int squareWordAddTo(int[] x, int xPos, int[] z)
{
long c = 0, xVal = x[xPos] & M;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat224.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat224.java
index 9f5b623..986bac2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat224.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat224.java
@@ -147,6 +147,33 @@
return (int)c;
}
+ public static int addTo(int[] x, int[] z, int cIn)
+ {
+ long c = cIn & M;
+ c += (x[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
{
long c = cIn & M;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat256.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat256.java
index b38e430..dfa2284 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat256.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat256.java
@@ -162,6 +162,36 @@
return (int)c;
}
+ public static int addTo(int[] x, int[] z, int cIn)
+ {
+ long c = cIn & M;
+ c += (x[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ c += (x[7] & M) + (z[7] & M);
+ z[7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
{
long c = cIn & M;
@@ -606,6 +636,77 @@
}
}
+ public static void mul128(int[] x, int[] y128, int[] zz)
+ {
+ long x_0 = x[0] & M;
+ long x_1 = x[1] & M;
+ long x_2 = x[2] & M;
+ long x_3 = x[3] & M;
+ long x_4 = x[4] & M;
+ long x_5 = x[5] & M;
+ long x_6 = x[6] & M;
+ long x_7 = x[7] & M;
+
+ {
+ long c = 0, y_0 = y128[0] & M;
+ c += y_0 * x_0;
+ zz[0] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_1;
+ zz[1] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_2;
+ zz[2] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_3;
+ zz[3] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_4;
+ zz[4] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_5;
+ zz[5] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_6;
+ zz[6] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_7;
+ zz[7] = (int)c;
+ c >>>= 32;
+ zz[8] = (int)c;
+ }
+
+ for (int i = 1; i < 4; ++i)
+ {
+ long c = 0, y_i = y128[i] & M;
+ c += y_i * x_0 + (zz[i + 0] & M);
+ zz[i + 0] = (int)c;
+ c >>>= 32;
+ c += y_i * x_1 + (zz[i + 1] & M);
+ zz[i + 1] = (int)c;
+ c >>>= 32;
+ c += y_i * x_2 + (zz[i + 2] & M);
+ zz[i + 2] = (int)c;
+ c >>>= 32;
+ c += y_i * x_3 + (zz[i + 3] & M);
+ zz[i + 3] = (int)c;
+ c >>>= 32;
+ c += y_i * x_4 + (zz[i + 4] & M);
+ zz[i + 4] = (int)c;
+ c >>>= 32;
+ c += y_i * x_5 + (zz[i + 5] & M);
+ zz[i + 5] = (int)c;
+ c >>>= 32;
+ c += y_i * x_6 + (zz[i + 6] & M);
+ zz[i + 6] = (int)c;
+ c >>>= 32;
+ c += y_i * x_7 + (zz[i + 7] & M);
+ zz[i + 7] = (int)c;
+ c >>>= 32;
+ zz[i + 8] = (int)c;
+ }
+ }
+
public static int mulAddTo(int[] x, int[] y, int[] zz)
{
long y_0 = y[0] & M;
@@ -1351,6 +1452,36 @@
return (int)c;
}
+ public static int subFrom(int[] x, int[] z, int cIn)
+ {
+ long c = cIn & M;
+ c += (z[0] & M) - (x[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - (x[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M) - (x[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (z[3] & M) - (x[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) - (x[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M) - (x[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ c += (z[6] & M) - (x[6] & M);
+ z[6] = (int)c;
+ c >>= 32;
+ c += (z[7] & M) - (x[7] & M);
+ z[7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
public static int subFrom(int[] x, int xOff, int[] z, int zOff)
{
long c = 0;
@@ -1381,6 +1512,36 @@
return (int)c;
}
+ public static int subFrom(int[] x, int xOff, int[] z, int zOff, int cIn)
+ {
+ long c = cIn & M;
+ c += (z[zOff + 0] & M) - (x[xOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 1] & M) - (x[xOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 2] & M) - (x[xOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 3] & M) - (x[xOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 4] & M) - (x[xOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 5] & M) - (x[xOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 6] & M) - (x[xOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 7] & M) - (x[xOff + 7] & M);
+ z[zOff + 7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
public static BigInteger toBigInteger(int[] x)
{
byte[] bs = new byte[32];
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Arrays.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Arrays.java
index 5c66305..dd06d04 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Arrays.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Arrays.java
@@ -151,6 +151,47 @@
return 0 == d;
}
+ /**
+ * A constant time equals comparison - does not terminate early if
+ * comparison fails. For best results always pass the expected value
+ * as the first parameter.
+ *
+ * @param expected first array
+ * @param supplied second array
+ * @return true if arrays equal, false otherwise.
+ */
+ public static boolean constantTimeAreEqual(
+ char[] expected,
+ char[] supplied)
+ {
+ if (expected == null || supplied == null)
+ {
+ return false;
+ }
+
+ if (expected == supplied)
+ {
+ return true;
+ }
+
+ int len = Math.min(expected.length, supplied.length);
+
+ int nonEqual = expected.length ^ supplied.length;
+
+ // do the char-wise comparison
+ for (int i = 0; i != len; i++)
+ {
+ nonEqual |= (expected[i] ^ supplied[i]);
+ }
+ // If supplied is longer than expected, iterate over rest of supplied with NOPs
+ for (int i = len; i < supplied.length; i++)
+ {
+ nonEqual |= ((byte)supplied[i] ^ (byte)~supplied[i]);
+ }
+
+ return nonEqual == 0;
+ }
+
public static int compareUnsigned(byte[] a, byte[] b)
{
if (a == b)
@@ -276,14 +317,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(byte[], int, int, byte)} instead.
- */
- public static void fill(byte[] a, int fromIndex, byte val)
- {
- fill(a, fromIndex, a.length, val);
- }
-
public static void fill(byte[] a, int fromIndex, int toIndex, byte val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -304,14 +337,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(int[], int, int, int)} instead.
- */
- public static void fill(int[] a, int fromIndex, int val)
- {
- java.util.Arrays.fill(a, fromIndex, a.length, val);
- }
-
public static void fill(int[] a, int fromIndex, int toIndex, int val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -322,14 +347,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(long[], int, int, long)} instead.
- */
- public static void fill(long[] a, int fromIndex, long val)
- {
- java.util.Arrays.fill(a, fromIndex, a.length, val);
- }
-
public static void fill(long[] a, int fromIndex, int toIndex, long val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -350,14 +367,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(short[], int, int, short)} instead.
- */
- public static void fill(short[] a, int fromIndex, short val)
- {
- java.util.Arrays.fill(a, fromIndex, a.length, val);
- }
-
public static void fill(short[] a, int fromIndex, int toIndex, short val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -796,9 +805,7 @@
int newLength = to - from;
if (newLength < 0)
{
- StringBuffer sb = new StringBuffer(from);
- sb.append(" > ").append(to);
- throw new IllegalArgumentException(sb.toString());
+ throw new IllegalArgumentException(from + " > " + to);
}
return newLength;
}
@@ -1065,6 +1072,80 @@
return result;
}
+ public static void reverse(byte[] input, byte[] output)
+ {
+ int last = input.length - 1;
+ for (int i = 0; i <= last; ++i)
+ {
+ output[i] = input[last - i];
+ }
+ }
+
+ public static byte[] reverseInPlace(byte[] a)
+ {
+ if (null == a)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length - 1;
+ while (p1 < p2)
+ {
+ byte t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+
+ return a;
+ }
+
+ public static void reverseInPlace(byte[] a, int aOff, int aLen)
+ {
+ int p1 = aOff, p2 = aOff + aLen - 1;
+ while (p1 < p2)
+ {
+ byte t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+ }
+
+ public static short[] reverseInPlace(short[] a)
+ {
+ if (null == a)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length - 1;
+ while (p1 < p2)
+ {
+ short t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+
+ return a;
+ }
+
+ public static int[] reverseInPlace(int[] a)
+ {
+ if (null == a)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length - 1;
+ while (p1 < p2)
+ {
+ int t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+
+ return a;
+ }
+
/**
* Iterator backed by a specific array.
* @hide This class is not part of the Android public SDK API
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/BigIntegers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/BigIntegers.java
index 8b06237..2a05b22 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/BigIntegers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/BigIntegers.java
@@ -3,6 +3,11 @@
import java.math.BigInteger;
import java.security.SecureRandom;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import com.android.org.bouncycastle.math.raw.Mod;
+import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
@@ -23,7 +28,7 @@
/**
* Return the passed in value as an unsigned byte array.
- *
+ *
* @param value the value to be converted.
* @return a byte array without a leading zero byte if present in the signed encoding.
*/
@@ -31,16 +36,15 @@
BigInteger value)
{
byte[] bytes = value.toByteArray();
-
if (bytes[0] == 0 && bytes.length != 1)
{
byte[] tmp = new byte[bytes.length - 1];
-
+
System.arraycopy(bytes, 1, tmp, 0, tmp.length);
-
+
return tmp;
}
-
+
return bytes;
}
@@ -48,10 +52,8 @@
* Return the passed in value as an unsigned byte array of the specified length, padded with
* leading zeros as necessary..
*
- * @param length
- * the fixed length of the result
- * @param value
- * the value to be converted.
+ * @param length the fixed length of the result
+ * @param value the value to be converted.
* @return a byte array padded to a fixed length with leading zeros.
*/
public static byte[] asUnsignedByteArray(int length, BigInteger value)
@@ -79,14 +81,10 @@
* Write the passed in value as unsigned bytes to the specified buffer range, padded with
* leading zeros as necessary.
*
- * @param value
- * the value to be converted.
- * @param buf
- * the buffer to which the value is written.
- * @param off
- * the start offset in array <code>buf</code> at which the data is written.
- * @param len
- * the fixed length of data written (possibly padded with leading zeros).
+ * @param value the value to be converted.
+ * @param buf the buffer to which the value is written.
+ * @param off the start offset in array <code>buf</code> at which the data is written.
+ * @param len the fixed length of data written (possibly padded with leading zeros).
*/
public static void asUnsignedByteArray(BigInteger value, byte[] buf, int off, int len)
{
@@ -106,22 +104,23 @@
}
int padLen = len - count;
- Arrays.fill(buf, off, off + padLen, (byte)0x00);
+ Arrays.fill(buf, off, off + padLen, (byte)0x00);
System.arraycopy(bytes, start, buf, off + padLen, count);
}
+
/**
* Return a random BigInteger not less than 'min' and not greater than 'max'
- *
- * @param min the least value that may be generated
- * @param max the greatest value that may be generated
+ *
+ * @param min the least value that may be generated
+ * @param max the greatest value that may be generated
* @param random the source of randomness
* @return a random BigInteger value in the range [min,max]
*/
public static BigInteger createRandomInRange(
- BigInteger min,
- BigInteger max,
- SecureRandom random)
+ BigInteger min,
+ BigInteger max,
+ SecureRandom random)
{
int cmp = min.compareTo(max);
if (cmp >= 0)
@@ -152,6 +151,7 @@
return createRandomBigInteger(max.subtract(min).bitLength() - 1, random).add(min);
}
+
public static BigInteger fromUnsignedByteArray(byte[] buf)
{
return new BigInteger(1, buf);
@@ -168,6 +168,28 @@
return new BigInteger(1, mag);
}
+ public static byte byteValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.byteValueExact instead
+ if (x.bitLength() > 7)
+ {
+ throw new ArithmeticException("BigInteger out of int range");
+ }
+
+ return x.byteValue();
+ }
+
+ public static short shortValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.shortValueExact instead
+ if (x.bitLength() > 15)
+ {
+ throw new ArithmeticException("BigInteger out of int range");
+ }
+
+ return x.shortValue();
+ }
+
public static int intValueExact(BigInteger x)
{
// Since Java 1.8 could use BigInteger.intValueExact instead
@@ -176,7 +198,7 @@
throw new ArithmeticException("BigInteger out of int range");
}
- return x.intValue();
+ return x.intValue();
}
public static long longValueExact(BigInteger x)
@@ -187,7 +209,7 @@
throw new ArithmeticException("BigInteger out of long range");
}
- return x.longValue();
+ return x.longValue();
}
public static BigInteger modOddInverse(BigInteger M, BigInteger X)
@@ -266,7 +288,7 @@
* Return a positive BigInteger in the range of 0 to 2**bitLength - 1.
*
* @param bitLength maximum bit length for the generated BigInteger.
- * @param random a source of randomness.
+ * @param random a source of randomness.
* @return a positive BigInteger
*/
public static BigInteger createRandomBigInteger(int bitLength, SecureRandom random)
@@ -276,7 +298,7 @@
// Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
- "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
+ "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
+ "73d893fa424cd2edc8636a6c3285e022b0e3866a565ae8108eed8591cd4fe8d2"
+ "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8"
+ "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f",
@@ -287,7 +309,7 @@
* Return a prime number candidate of the specified bit length.
*
* @param bitLength bit length for the generated BigInteger.
- * @param random a source of randomness.
+ * @param random a source of randomness.
* @return a positive BigInteger of numBits length
*/
public static BigInteger createRandomPrime(int bitLength, int certainty, SecureRandom random)
@@ -349,4 +371,41 @@
return rv;
}
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Cache
+ {
+ private final Map<BigInteger, Boolean> values = new WeakHashMap<BigInteger, Boolean>();
+ private final BigInteger[] preserve = new BigInteger[8];
+
+ private int preserveCounter = 0;
+
+ public synchronized void add(BigInteger value)
+ {
+ values.put(value, Boolean.TRUE);
+ preserve[preserveCounter] = value;
+ preserveCounter = (preserveCounter + 1) % preserve.length;
+ }
+
+ public synchronized boolean contains(BigInteger value)
+ {
+ return values.containsKey(value);
+ }
+
+ public synchronized int size()
+ {
+ return values.size();
+ }
+
+ public synchronized void clear()
+ {
+ values.clear();
+ for (int i = 0; i != preserve.length; i++)
+ {
+ preserve[i] = null;
+ }
+ }
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Bytes.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Bytes.java
new file mode 100644
index 0000000..2862502
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Bytes.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.util;
+
+/**
+ * Utility methods and constants for bytes.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Bytes
+{
+ public static final int BYTES = 1;
+ public static final int SIZE = Byte.SIZE;
+
+ public static void xor(int len, byte[] x, byte[] y, byte[] z)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] = (byte)(x[i] ^ y[i]);
+ }
+ }
+
+ public static void xor(int len, byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]);
+ }
+ }
+
+ public static void xorTo(int len, byte[] x, byte[] z)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] ^= x[i];
+ }
+ }
+
+ public static void xorTo(int len, byte[] x, int xOff, byte[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[zOff + i] ^= x[xOff + i];
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Characters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Characters.java
new file mode 100644
index 0000000..7e16b78
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Characters.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.util;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Characters
+{
+ public static Character valueOf(char c)
+ {
+ return Character.valueOf(c);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Exceptions.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Exceptions.java
new file mode 100644
index 0000000..3bf6646
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Exceptions.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.util;
+
+import java.io.IOException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Exceptions
+{
+ public static IllegalArgumentException illegalArgumentException(String message, Throwable cause)
+ {
+ return new IllegalArgumentException(message, cause);
+ }
+
+ public static IllegalStateException illegalStateException(String message, Throwable cause)
+ {
+ return new IllegalStateException(message, cause);
+ }
+
+ public static IOException ioException(String message, Throwable cause)
+ {
+ return new IOException(message, cause);
+ }
+
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/IPAddress.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/IPAddress.java
index b5f960c..f8f791b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/IPAddress.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/IPAddress.java
@@ -14,8 +14,7 @@
*
* @return true if a valid address, false otherwise
*/
- public static boolean isValid(
- String address)
+ public static boolean isValid(String address)
{
return isValidIPv4(address) || isValidIPv6(address);
}
@@ -27,8 +26,7 @@
*
* @return true if a valid address with netmask, false otherwise
*/
- public static boolean isValidWithNetMask(
- String address)
+ public static boolean isValidWithNetMask(String address)
{
return isValidIPv4WithNetmask(address) || isValidIPv6WithNetmask(address);
}
@@ -40,79 +38,42 @@
*
* @return true if a valid IPv4 address, false otherwise
*/
- public static boolean isValidIPv4(
- String address)
+ public static boolean isValidIPv4(String address)
{
- if (address.length() == 0)
+ int length = address.length();
+ if (length < 7 || length > 15)
{
return false;
}
- int octet;
- int octets = 0;
-
- String temp = address+".";
-
- int pos;
- int start = 0;
- while (start < temp.length()
- && (pos = temp.indexOf('.', start)) > start)
+ int pos = 0;
+ for (int octetIndex = 0; octetIndex < 3; ++octetIndex)
{
- if (octets == 4)
+ int end = address.indexOf('.', pos);
+
+ if (!isParseableIPv4Octet(address, pos, end))
{
return false;
}
- try
- {
- octet = Integer.parseInt(temp.substring(start, pos));
- }
- catch (NumberFormatException ex)
- {
- return false;
- }
- if (octet < 0 || octet > 255)
- {
- return false;
- }
- start = pos + 1;
- octets++;
+
+ pos = end + 1;
}
- return octets == 4;
+ return isParseableIPv4Octet(address, pos, length);
}
- public static boolean isValidIPv4WithNetmask(
- String address)
+ public static boolean isValidIPv4WithNetmask(String address)
{
int index = address.indexOf("/");
- String mask = address.substring(index + 1);
-
- return (index > 0) && isValidIPv4(address.substring(0, index))
- && (isValidIPv4(mask) || isMaskValue(mask, 32));
- }
-
- public static boolean isValidIPv6WithNetmask(
- String address)
- {
- int index = address.indexOf("/");
- String mask = address.substring(index + 1);
-
- return (index > 0) && (isValidIPv6(address.substring(0, index))
- && (isValidIPv6(mask) || isMaskValue(mask, 128)));
- }
-
- private static boolean isMaskValue(String component, int size)
- {
- try
- {
- int value = Integer.parseInt(component);
-
- return value >= 0 && value <= size;
- }
- catch (NumberFormatException e)
+ if (index < 1)
{
return false;
}
+
+ String before = address.substring(0, index);
+ String after = address.substring(index + 1);
+
+ return isValidIPv4(before) && (isValidIPv4(after) || isParseableIPv4Mask(after));
}
/**
@@ -122,72 +83,131 @@
*
* @return true if a valid IPv6 address, false otherwise
*/
- public static boolean isValidIPv6(
- String address)
+ public static boolean isValidIPv6(String address)
{
if (address.length() == 0)
{
return false;
}
- int octet;
- int octets = 0;
+ char firstChar = address.charAt(0);
+ if (firstChar != ':' && Character.digit(firstChar, 16) < 0)
+ {
+ return false;
+ }
+ int segmentCount = 0;
String temp = address + ":";
boolean doubleColonFound = false;
- int pos;
- int start = 0;
- while (start < temp.length()
- && (pos = temp.indexOf(':', start)) >= start)
+
+ int pos = 0, end;
+ while (pos < temp.length() && (end = temp.indexOf(':', pos)) >= pos)
{
- if (octets == 8)
+ if (segmentCount == 8)
{
return false;
}
- if (start != pos)
+ if (pos != end)
{
- String value = temp.substring(start, pos);
+ String value = temp.substring(pos, end);
- if (pos == (temp.length() - 1) && value.indexOf('.') > 0)
+ if (end == temp.length() - 1 && value.indexOf('.') > 0)
{
+ // add an extra one as address covers 2 words.
+ if (++segmentCount == 8)
+ {
+ return false;
+ }
if (!isValidIPv4(value))
{
return false;
}
-
- octets++; // add an extra one as address covers 2 words.
}
- else
+ else if (!isParseableIPv6Segment(temp, pos, end))
{
- try
- {
- octet = Integer.parseInt(temp.substring(start, pos), 16);
- }
- catch (NumberFormatException ex)
- {
- return false;
- }
- if (octet < 0 || octet > 0xffff)
- {
- return false;
- }
+ return false;
}
}
else
{
- if (pos != 1 && pos != temp.length() - 1 && doubleColonFound)
+ if (end != 1 && end != temp.length() - 1 && doubleColonFound)
{
return false;
}
doubleColonFound = true;
}
- start = pos + 1;
- octets++;
+
+ pos = end + 1;
+ ++segmentCount;
}
- return octets == 8 || doubleColonFound;
+ return segmentCount == 8 || doubleColonFound;
+ }
+
+ public static boolean isValidIPv6WithNetmask(String address)
+ {
+ int index = address.indexOf("/");
+ if (index < 1)
+ {
+ return false;
+ }
+
+ String before = address.substring(0, index);
+ String after = address.substring(index + 1);
+
+ return isValidIPv6(before) && (isValidIPv6(after) || isParseableIPv6Mask(after));
+ }
+
+ private static boolean isParseableIPv4Mask(String s)
+ {
+ return isParseable(s, 0, s.length(), 10, 2, false, 0, 32);
+ }
+
+ private static boolean isParseableIPv4Octet(String s, int pos, int end)
+ {
+ return isParseable(s, pos, end, 10, 3, true, 0, 255);
+ }
+
+ private static boolean isParseableIPv6Mask(String s)
+ {
+ return isParseable(s, 0, s.length(), 10, 3, false, 1, 128);
+ }
+
+ private static boolean isParseableIPv6Segment(String s, int pos, int end)
+ {
+ return isParseable(s, pos, end, 16, 4, true, 0x0000, 0xFFFF);
+ }
+
+ private static boolean isParseable(String s, int pos, int end, int radix, int maxLength, boolean allowLeadingZero,
+ int minValue, int maxValue)
+ {
+ int length = end - pos;
+ if (length < 1 | length > maxLength)
+ {
+ return false;
+ }
+
+ boolean checkLeadingZero = length > 1 & !allowLeadingZero;
+ if (checkLeadingZero && Character.digit(s.charAt(pos), radix) <= 0)
+ {
+ return false;
+ }
+
+ int value = 0;
+ while (pos < end)
+ {
+ char c = s.charAt(pos++);
+ int d = Character.digit(c, radix);
+ if (d < 0)
+ {
+ return false;
+ }
+
+ value *= radix;
+ value += d;
+ }
+
+ return value >= minValue & value <= maxValue;
}
}
-
-
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Integers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Integers.java
index b6627eb..afd4b9d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Integers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Integers.java
@@ -2,11 +2,29 @@
package com.android.org.bouncycastle.util;
/**
- * Utility methods for ints.
+ * Utility methods and constants for ints.
* @hide This class is not part of the Android public SDK API
*/
public class Integers
{
+ public static final int BYTES = 4;
+ public static final int SIZE = Integer.SIZE;
+
+ public static int bitCount(int i)
+ {
+ return Integer.bitCount(i);
+ }
+
+ public static int highestOneBit(int i)
+ {
+ return Integer.highestOneBit(i);
+ }
+
+ public static int lowestOneBit(int i)
+ {
+ return Integer.lowestOneBit(i);
+ }
+
public static int numberOfLeadingZeros(int i)
{
return Integer.numberOfLeadingZeros(i);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Longs.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Longs.java
index 2a812f4..915fa8b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Longs.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Longs.java
@@ -2,10 +2,34 @@
package com.android.org.bouncycastle.util;
/**
+ * Utility methods and constants for longs.
* @hide This class is not part of the Android public SDK API
*/
public class Longs
{
+ public static final int BYTES = 8;
+ public static final int SIZE = Long.SIZE;
+
+ public static long highestOneBit(long i)
+ {
+ return Long.highestOneBit(i);
+ }
+
+ public static long lowestOneBit(long i)
+ {
+ return Long.lowestOneBit(i);
+ }
+
+ public static int numberOfLeadingZeros(long i)
+ {
+ return Long.numberOfLeadingZeros(i);
+ }
+
+ public static int numberOfTrailingZeros(long i)
+ {
+ return Long.numberOfTrailingZeros(i);
+ }
+
public static long reverse(long i)
{
return Long.reverse(i);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Memoable.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Memoable.java
index 4c71b23..d9a332d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Memoable.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Memoable.java
@@ -3,7 +3,7 @@
/**
* Interface for Memoable objects. Memoable objects allow the taking of a snapshot of their internal state
- * via the copy() method and then reseting the object back to that state later using the reset() method.
+ * via the copy() method and then resetting the object back to that state later using the reset() method.
* @hide This class is not part of the Android public SDK API
*/
public interface Memoable
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Pack.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Pack.java
index 7297e85..d043555 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Pack.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Pack.java
@@ -149,7 +149,6 @@
* @param bs The target.
* @param off Position in target to start.
* @param bytes number of bytes to write.
- *
* @deprecated Will be removed
*/
public static void longToBigEndian(long value, byte[] bs, int off, int bytes)
@@ -177,6 +176,25 @@
return n;
}
+ public static int littleEndianToInt_High(byte[] bs, int off, int len)
+ {
+ return littleEndianToInt_Low(bs, off, len) << ((4 - len) << 3);
+ }
+
+ public static int littleEndianToInt_Low(byte[] bs, int off, int len)
+ {
+// assert 1 <= len && len <= 4;
+
+ int result = bs[off] & 0xff;
+ int pos = 0;
+ for (int i = 1; i < len; ++i)
+ {
+ pos += 8;
+ result |= (bs[off + i] & 0xff) << pos;
+ }
+ return result;
+ }
+
public static void littleEndianToInt(byte[] bs, int off, int[] ns)
{
for (int i = 0; i < ns.length; ++i)
@@ -299,6 +317,40 @@
}
}
+ public static void longToLittleEndian_High(long n, byte[] bs, int off, int len)
+ {
+ //Debug.Assert(1 <= len && len <= 8);
+ int pos = 56;
+ bs[off] = (byte)(n >>> pos);
+ for (int i = 1; i < len; ++i)
+ {
+ pos -= 8;
+ bs[off + i] = (byte)(n >>> pos);
+ }
+ }
+
+// public static void longToLittleEndian_Low(long n, byte[] bs, int off, int len)
+// {
+// longToLittleEndian_High(n << ((8 - len) << 3), bs, off, len);
+// }
+
+ public static long littleEndianToLong_High(byte[] bs, int off, int len)
+ {
+ return littleEndianToLong_Low(bs, off, len) << ((8 - len) << 3);
+ }
+
+ public static long littleEndianToLong_Low(byte[] bs, int off, int len)
+ {
+ //Debug.Assert(1 <= len && len <= 8);
+ long result = bs[off] & 0xFF;
+ for (int i = 1; i < len; ++i)
+ {
+ result <<= 8;
+ result |= bs[off + i] & 0xFF;
+ }
+ return result;
+ }
+
public static byte[] longToLittleEndian(long n)
{
byte[] bs = new byte[8];
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Properties.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Properties.java
index 87f5275..f28ffbf 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Properties.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Properties.java
@@ -14,11 +14,18 @@
import java.util.StringTokenizer;
/**
- * Utility method for accessing system properties.
+ * Utility method for accessing properties values - properties can be set in java.security,
+ * thread local, and system properties. They are checked for in the same order with
+ * checking stopped as soon as a value is found.
* @hide This class is not part of the Android public SDK API
*/
public class Properties
{
+ /**
+ * If set the provider will attempt, where possible, to behave the same way as the oracle one.
+ */
+ public static final String EMULATE_ORACLE = "com.android.org.bouncycastle.emulate.oracle";
+
private Properties()
{
}
@@ -117,6 +124,31 @@
return false;
}
+ /**
+ * Return propertyName as an integer, defaultValue used if not defined.
+ *
+ * @param propertyName name of property.
+ * @param defaultValue integer to return if property not defined.
+ * @return value of property, or default if not found, as an int.
+ */
+ public static int asInteger(String propertyName, int defaultValue)
+ {
+ String p = getPropertyValue(propertyName);
+
+ if (p != null)
+ {
+ return Integer.parseInt(p);
+ }
+
+ return defaultValue;
+ }
+
+ /**
+ * Return propertyName as a BigInteger.
+ *
+ * @param propertyName name of property.
+ * @return value of property as a BigInteger, null if not defined.
+ */
public static BigInteger asBigInteger(String propertyName)
{
String p = getPropertyValue(propertyName);
@@ -147,6 +179,13 @@
return Collections.unmodifiableSet(set);
}
+ /**
+ * Return the String value of the property propertyName. Property valuation
+ * starts with java.security, then thread local, then system properties.
+ *
+ * @param propertyName name of property.
+ * @return value of property as a String, null if not defined.
+ */
public static String getPropertyValue(final String propertyName)
{
String val = (String)AccessController.doPrivileged(new PrivilegedAction()
@@ -180,6 +219,18 @@
});
}
+ public static String getPropertyValue(final String propertyName, String defValue)
+ {
+ String rv = getPropertyValue(propertyName);
+
+ if (rv == null)
+ {
+ return defValue;
+ }
+
+ return rv;
+ }
+
private static boolean isSetFalse(String p)
{
if (p == null || p.length() != 5)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Strings.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Strings.java
index cf3b206..2a5f512 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Strings.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Strings.java
@@ -58,6 +58,17 @@
return new String(chars, 0, len);
}
+ public static String fromUTF8ByteArray(byte[] bytes, int off, int length)
+ {
+ char[] chars = new char[length];
+ int len = UTF8.transcodeToUTF16(bytes, off, length, chars);
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Invalid UTF-8 input");
+ }
+ return new String(chars, 0, len);
+ }
+
public static byte[] toUTF8ByteArray(String string)
{
return toUTF8ByteArray(string.toCharArray());
@@ -230,6 +241,37 @@
}
/**
+ * Constant time string comparison.
+ *
+ * @param a a string.
+ * @param b another string to compare to a.
+ *
+ * @return true if a and b represent the same string, false otherwise.
+ */
+ public static boolean constantTimeAreEqual(String a, String b)
+ {
+ boolean isEqual = a.length() == b.length();
+ int len = a.length();
+
+ if (isEqual)
+ {
+ for (int i = 0; i != len; i++)
+ {
+ isEqual &= (a.charAt(i) == b.charAt(i));
+ }
+ }
+ else
+ {
+ for (int i = 0; i != len; i++)
+ {
+ isEqual &= (a.charAt(i) == ' ');
+ }
+ }
+
+ return isEqual;
+ }
+
+ /**
* Convert an array of 8 bit characters into a string.
*
* @param bytes 8 bit characters.
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base32.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base32.java
new file mode 100644
index 0000000..2e384d7
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base32.java
@@ -0,0 +1,176 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.util.encoders;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * Utility class for converting Base32 data to bytes and back again.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Base32
+{
+ private static final Encoder encoder = new Base32Encoder();
+
+ public static String toBase32String(
+ byte[] data)
+ {
+ return toBase32String(data, 0, data.length);
+ }
+
+ public static String toBase32String(
+ byte[] data,
+ int off,
+ int length)
+ {
+ byte[] encoded = encode(data, off, length);
+ return Strings.fromByteArray(encoded);
+ }
+
+ /**
+ * encode the input data producing a base 32 encoded byte array.
+ *
+ * @return a byte array containing the base 32 encoded data.
+ */
+ public static byte[] encode(
+ byte[] data)
+ {
+ return encode(data, 0, data.length);
+ }
+
+ /**
+ * encode the input data producing a base 32 encoded byte array.
+ *
+ * @return a byte array containing the base 32 encoded data.
+ */
+ public static byte[] encode(
+ byte[] data,
+ int off,
+ int length)
+ {
+ int len = encoder.getEncodedLength(length);
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.encode(data, off, length, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new EncoderException("exception encoding base32 string: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * Encode the byte data to base 32 writing it to the given output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int encode(
+ byte[] data,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.encode(data, 0, data.length, out);
+ }
+
+ /**
+ * Encode the byte data to base 32 writing it to the given output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int encode(
+ byte[] data,
+ int off,
+ int length,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.encode(data, off, length, out);
+ }
+
+ /**
+ * decode the base 32 encoded input data. It is assumed the input data is valid.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ byte[] data)
+ {
+ int len = data.length / 8 * 5;
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.decode(data, 0, data.length, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base32 data: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * decode the base 32 encoded String data - whitespace will be ignored.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ String data)
+ {
+ int len = data.length() / 8 * 5;
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.decode(data, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base32 string: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * decode the base 32 encoded String data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int decode(
+ String data,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.decode(data, out);
+ }
+
+ /**
+ * Decode to an output stream;
+ *
+ * @param base32Data The source data.
+ * @param start Start position.
+ * @param length the length.
+ * @param out The output stream to write to.
+ */
+ public static int decode(byte[] base32Data, int start, int length, OutputStream out)
+ {
+ try
+ {
+ return encoder.decode(base32Data, start, length, out);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base32 data: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base32Encoder.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base32Encoder.java
new file mode 100644
index 0000000..8b913dd
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base32Encoder.java
@@ -0,0 +1,455 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.util.encoders;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * A streaming Base32 encoder.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Base32Encoder
+ implements Encoder
+{
+ private static final byte[] DEAULT_ENCODING_TABLE =
+ {
+ (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+ (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+ (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+ (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+ (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7'
+ };
+
+ private static final byte DEFAULT_PADDING = (byte)'=';
+
+ /*
+ * set up the decoding table.
+ */
+ private final byte[] encodingTable;
+ private final byte padding;
+ private final byte[] decodingTable = new byte[128];
+
+ 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;
+ }
+ }
+
+ /**
+ * Base constructor for RFC 4648, Section 6.
+ */
+ public Base32Encoder()
+ {
+ this.encodingTable = DEAULT_ENCODING_TABLE;
+ this.padding = DEFAULT_PADDING;
+
+ initialiseDecodingTable();
+ }
+
+ /**
+ * Constructor allowing the setting of an alternative alphabet.
+ *
+ * @param encodingTable a 32 entry encoding table to do the mapping.
+ * @param padding the padding value to use.
+ */
+ public Base32Encoder(byte[] encodingTable, byte padding)
+ {
+ if (encodingTable.length != 32)
+ {
+ throw new IllegalArgumentException("encoding table needs to be length 32");
+ }
+
+ this.encodingTable = Arrays.clone(encodingTable);
+ this.padding = padding;
+
+ initialiseDecodingTable();
+ }
+
+ public int encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) throws IOException
+ {
+ int inPos = inOff;
+ int inEnd = inOff + inLen - 4;
+ int outPos = outOff;
+
+ while (inPos < inEnd)
+ {
+ encodeBlock(inBuf, inPos, outBuf, outPos);
+ inPos += 5;
+ outPos += 8;
+ }
+
+ int extra = inLen - (inPos - inOff);
+ if (extra > 0)
+ {
+ byte[] in = new byte[5];
+ System.arraycopy(inBuf, inPos, in, 0, extra);
+ encodeBlock(in, 0, outBuf, outPos);
+ switch (extra)
+ {
+ case 1:
+ outBuf[outPos + 2] = padding;
+ outBuf[outPos + 3] = padding;
+ outBuf[outPos + 4] = padding;
+ outBuf[outPos + 5] = padding;
+ outBuf[outPos + 6] = padding;
+ outBuf[outPos + 7] = padding;
+ break;
+ case 2:
+ outBuf[outPos + 4] = padding;
+ outBuf[outPos + 5] = padding;
+ outBuf[outPos + 6] = padding;
+ outBuf[outPos + 7] = padding;
+ break;
+ case 3:
+ outBuf[outPos + 5] = padding;
+ outBuf[outPos + 6] = padding;
+ outBuf[outPos + 7] = padding;
+ break;
+ case 4:
+ outBuf[outPos + 7] = padding;
+ break;
+ }
+
+ outPos += 8;
+ }
+
+ return outPos - outOff;
+ }
+
+ private void encodeBlock(byte[] inBuf, int inPos, byte[] outBuf, int outPos)
+ {
+ int a1 = inBuf[inPos++];
+ int a2 = inBuf[inPos++] & 0xFF;
+ int a3 = inBuf[inPos++] & 0xFF;
+ int a4 = inBuf[inPos++] & 0xFF;
+ int a5 = inBuf[inPos] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[(a1 >>> 3) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a1 << 2) | (a2 >>> 6)) & 0x1F];
+ outBuf[outPos++] = encodingTable[(a2 >>> 1) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a2 << 4) | (a3 >>> 4)) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a3 << 1) | (a4 >>> 7)) & 0x1F];
+ outBuf[outPos++] = encodingTable[(a4 >>> 2) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a4 << 3) | (a5 >>> 5)) & 0x1F];
+ outBuf[outPos] = encodingTable[a5 & 0x1F];
+ }
+
+ public int getEncodedLength(int inputLength)
+ {
+ return (inputLength + 4) / 5 * 8;
+ }
+
+ public int getMaxDecodedLength(int inputLength)
+ {
+ return inputLength / 8 * 5;
+ }
+
+ /**
+ * encode the input data producing a base 32 output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public int encode(byte[] buf, int off, int len, OutputStream out)
+ throws IOException
+ {
+ if (len < 0)
+ {
+ return 0;
+ }
+
+ byte[] tmp = new byte[72];
+ int remaining = len;
+ while (remaining > 0)
+ {
+ int inLen = Math.min(45, remaining);
+ int outLen = encode(buf, off, inLen, tmp, 0);
+ out.write(tmp, 0, outLen);
+ off += inLen;
+ remaining -= inLen;
+ }
+ return (len + 2) / 3 * 4;
+ }
+
+ private boolean ignore(
+ char c)
+ {
+ return (c == '\n' || c =='\r' || c == '\t' || c == ' ');
+ }
+
+ /**
+ * decode the base 32 encoded byte data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public int decode(
+ byte[] data,
+ int off,
+ int length,
+ OutputStream out)
+ throws IOException
+ {
+ byte b1, b2, b3, b4, b5, b6, b7, b8;
+ byte[] outBuffer = new byte[55];
+ int bufOff = 0;
+ int outLen = 0;
+
+ int end = off + length;
+
+ while (end > off)
+ {
+ if (!ignore((char)data[end - 1]))
+ {
+ break;
+ }
+
+ end--;
+ }
+
+ // empty data!
+ if (end == 0)
+ {
+ return 0;
+ }
+
+ int i = 0;
+ int finish = end;
+
+ while (finish > off && i != 8)
+ {
+ if (!ignore((char)data[finish - 1]))
+ {
+ i++;
+ }
+
+ finish--;
+ }
+
+ i = nextI(data, off, finish);
+
+ while (i < finish)
+ {
+ b1 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b2 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b3 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b4 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b5 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b6 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b7 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b8 = decodingTable[data[i++]];
+
+ if ((b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8) < 0)
+ {
+ throw new IOException("invalid characters encountered in base32 data");
+ }
+
+ outBuffer[bufOff++] = (byte)((b1 << 3) | (b2 >> 2));
+ outBuffer[bufOff++] = (byte)((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ outBuffer[bufOff++] = (byte)((b4 << 4) | (b5 >> 1));
+ outBuffer[bufOff++] = (byte)((b5 << 7) | (b6 << 2) | (b7 >> 3));
+ outBuffer[bufOff++] = (byte)((b7 << 5) | b8);
+
+ if (bufOff == outBuffer.length)
+ {
+ out.write(outBuffer);
+ bufOff = 0;
+ }
+
+ outLen += 5;
+
+ i = nextI(data, i, finish);
+ }
+
+ if (bufOff > 0)
+ {
+ out.write(outBuffer, 0, bufOff);
+ }
+
+ int e0 = nextI(data, i, end);
+ int e1 = nextI(data, e0 + 1, end);
+ int e2 = nextI(data, e1 + 1, end);
+ int e3 = nextI(data, e2 + 1, end);
+ int e4 = nextI(data, e3 + 1, end);
+ int e5 = nextI(data, e4 + 1, end);
+ int e6 = nextI(data, e5 + 1, end);
+ int e7 = nextI(data, e6 + 1, end);
+
+ outLen += decodeLastBlock(out,
+ (char)data[e0], (char)data[e1], (char)data[e2], (char)data[e3],
+ (char)data[e4], (char)data[e5], (char)data[e6], (char)data[e7]);
+
+ return outLen;
+ }
+
+ private int nextI(byte[] data, int i, int finish)
+ {
+ while ((i < finish) && ignore((char)data[i]))
+ {
+ i++;
+ }
+ return i;
+ }
+
+ /**
+ * decode the base 32 encoded String data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public int decode(
+ String data,
+ OutputStream out)
+ throws IOException
+ {
+ byte[] bytes = Strings.toByteArray(data);
+ return decode(bytes, 0, bytes.length, out);
+ }
+
+ private int decodeLastBlock(OutputStream out,
+ char c1, char c2, char c3, char c4,
+ char c5, char c6, char c7, char c8)
+ throws IOException
+ {
+ byte b1, b2, b3, b4, b5, b6, b7, b8;
+
+ if (c8 == padding)
+ {
+ if (c7 != padding)
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+ b5 = decodingTable[c5];
+ b6 = decodingTable[c6];
+ b7 = decodingTable[c7];
+
+ if ((b1 | b2 | b3 | b4 | b5 | b6 | b7) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ out.write((b4 << 4) | (b5 >> 1));
+ out.write((b5 << 7) | (b6 << 2) | (b7 >> 3));
+
+ return 4;
+ }
+ if (c6 != padding)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ if (c5 != padding)
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+ b5 = decodingTable[c5];
+
+ if ((b1 | b2 | b3 | b4 | b5) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ out.write((b4 << 4) | (b5 >> 1));
+
+ return 3;
+ }
+
+ if (c4 != padding)
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+
+ if ((b1 | b2 | b3 | b4) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+
+ return 2;
+ }
+
+ if (c3 != padding)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+
+ if ((b1 | b2) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+
+ return 1;
+ }
+ else
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+ b5 = decodingTable[c5];
+ b6 = decodingTable[c6];
+ b7 = decodingTable[c7];
+ b8 = decodingTable[c8];
+
+ if ((b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ out.write((b4 << 4) | (b5 >> 1));
+ out.write((b5 << 7) | (b6 << 2) | (b7 >> 3));
+ out.write((b7 << 5) | b8);
+
+ return 5;
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64.java
index a685400..3a03470 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64.java
@@ -51,7 +51,7 @@
int off,
int length)
{
- int len = (length + 2) / 3 * 4;
+ int len = encoder.getEncodedLength(length);
ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
try
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64Encoder.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64Encoder.java
index 1fee863..0fba03a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64Encoder.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64Encoder.java
@@ -98,24 +98,40 @@
return outPos - outOff;
}
+ public int getEncodedLength(int inputLength)
+ {
+ return (inputLength + 2) / 3 * 4;
+ }
+
+ public int getMaxDecodedLength(int inputLength)
+ {
+ return inputLength / 4 * 3;
+ }
+
/**
* encode the input data producing a base 64 output stream.
*
* @return the number of bytes produced.
*/
- public int encode(byte[] buf, int off, int len, OutputStream out)
+ public int encode(byte[] buf, int off, int len, OutputStream out)
throws IOException
{
- byte[] tmp = new byte[72];
- while (len > 0)
+ if (len < 0)
{
- int inLen = Math.min(54, len);
+ return 0;
+ }
+
+ byte[] tmp = new byte[72];
+ int remaining = len;
+ while (remaining > 0)
+ {
+ int inLen = Math.min(54, remaining);
int outLen = encode(buf, off, inLen, tmp, 0);
out.write(tmp, 0, outLen);
off += inLen;
- len -= inLen;
+ remaining -= inLen;
}
- return ((len + 2) / 3) * 4;
+ return (len + 2) / 3 * 4;
}
private boolean ignore(
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Encoder.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Encoder.java
index 5c5dc1b..38c16d0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Encoder.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Encoder.java
@@ -11,6 +11,23 @@
*/
public interface Encoder
{
+ /**
+ * Return the expected output length of the encoding.
+ *
+ * @param inputLength the input length of the data.
+ * @return the output length of an encoding.
+ */
+ int getEncodedLength(int inputLength);
+
+ /**
+ * Return the maximum expected output length of a decoding. If padding
+ * is present the value returned will be greater than the decoded data length.
+ *
+ * @param inputLength the input length of the encoded data.
+ * @return the upper bound of the output length of a decoding.
+ */
+ int getMaxDecodedLength(int inputLength);
+
int encode(byte[] data, int off, int length, OutputStream out) throws IOException;
int decode(byte[] data, int off, int length, OutputStream out) throws IOException;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/HexEncoder.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/HexEncoder.java
index 2a37631..c234813 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/HexEncoder.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/HexEncoder.java
@@ -64,6 +64,16 @@
return outPos - outOff;
}
+ public int getEncodedLength(int inputLength)
+ {
+ return inputLength * 2;
+ }
+
+ public int getMaxDecodedLength(int inputLength)
+ {
+ return inputLength / 2;
+ }
+
/**
* encode the input data producing a Hex output stream.
*
@@ -72,14 +82,20 @@
public int encode(byte[] buf, int off, int len, OutputStream out)
throws IOException
{
- byte[] tmp = new byte[72];
- while (len > 0)
+ if (len < 0)
{
- int inLen = Math.min(36, len);
+ return 0;
+ }
+
+ byte[] tmp = new byte[72];
+ int remaining = len;
+ while (remaining > 0)
+ {
+ int inLen = Math.min(36, remaining);
int outLen = encode(buf, off, inLen, tmp, 0);
out.write(tmp, 0, outLen);
off += inLen;
- len -= inLen;
+ remaining -= inLen;
}
return len * 2;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/UTF8.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/UTF8.java
index 78ced9c..7dff001 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/UTF8.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/UTF8.java
@@ -3,7 +3,7 @@
/**
* Utilities for working with UTF-8 encodings.
- *
+ * <p>
* Decoding of UTF-8 is based on a presentation by Bob Steagall at CppCon2018 (see
* https://github.com/BobSteagall/CppCon2018). It uses a Deterministic Finite Automaton (DFA) to
* recognize and decode multi-byte code points.
@@ -73,8 +73,8 @@
fill(transitionTable, S_P4A + 0x9, S_P4A + 0xB, S_CS2);
fill(transitionTable, S_P4B + 0x8, S_P4B + 0x8, S_CS2);
- byte[] firstUnitMasks = { 0x00, 0x00, 0x00, 0x00, 0x1F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07 };
- byte[] firstUnitTransitions = { S_ERR, S_ERR, S_ERR, S_ERR, S_CS1, S_P3A, S_CS2, S_P3B, S_P4A, S_CS3, S_P4B };
+ byte[] firstUnitMasks = {0x00, 0x00, 0x00, 0x00, 0x1F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07};
+ byte[] firstUnitTransitions = {S_ERR, S_ERR, S_ERR, S_ERR, S_CS1, S_P3A, S_CS2, S_P3B, S_P4A, S_CS3, S_P4B};
for (int i = 0x00; i < 0x80; ++i)
{
@@ -96,26 +96,52 @@
* "overlong" encodings, and unmappable code points. In particular, no unmatched surrogates will
* be produced. An error will also result if {@code utf16} is found to be too small to store the
* complete output.
- *
- * @param utf8
- * A non-null array containing a well-formed UTF-8 encoding.
- * @param utf16
- * A non-null array, at least as long as the {@code utf8} array in order to ensure
- * the output will fit.
+ *
+ * @param utf8 A non-null array containing a well-formed UTF-8 encoding.
+ * @param utf16 A non-null array, at least as long as the {@code utf8} array in order to ensure
+ * the output will fit.
* @return The number of UTF-16 code units written to {@code utf16} (beginning from index 0), or
- * else -1 if the input was either malformed or encoded any unmappable characters, or if
- * the {@code utf16} is too small.
+ * else -1 if the input was either malformed or encoded any unmappable characters, or if
+ * the {@code utf16} is too small.
*/
public static int transcodeToUTF16(byte[] utf8, char[] utf16)
{
- int i = 0, j = 0;
+ return transcodeToUTF16(utf8, 0, utf8.length, utf16);
+ }
- while (i < utf8.length)
+ /**
+ * Transcode a UTF-8 encoding into a UTF-16 representation. In the general case the output
+ * {@code utf16} array should be at least as long as the input length from {@code utf8} to handle
+ * arbitrary inputs. The number of output UTF-16 code units is returned, or -1 if any errors are
+ * encountered (in which case an arbitrary amount of data may have been written into the output
+ * array). Errors that will be detected are malformed UTF-8, including incomplete, truncated or
+ * "overlong" encodings, and unmappable code points. In particular, no unmatched surrogates will
+ * be produced. An error will also result if {@code utf16} is found to be too small to store the
+ * complete output.
+ *
+ * @param utf8 A non-null array containing a well-formed UTF-8 encoding.
+ * @param utf8Off start position in the array for the well-formed encoding.
+ * @param utf8Length length in bytes of the well-formed encoding.
+ * @param utf16 A non-null array, at least as long as the {@code utf8} array in order to ensure
+ * the output will fit.
+ * @return The number of UTF-16 code units written to {@code utf16} (beginning from index 0), or
+ * else -1 if the input was either malformed or encoded any unmappable characters, or if
+ * the {@code utf16} is too small.
+ */
+ public static int transcodeToUTF16(byte[] utf8, int utf8Off, int utf8Length, char[] utf16)
+ {
+ int i = utf8Off, j = 0;
+ int maxI = utf8Off + utf8Length;
+
+ while (i < maxI)
{
byte codeUnit = utf8[i++];
if (codeUnit >= 0)
{
- if (j >= utf16.length) { return -1; }
+ if (j >= utf16.length)
+ {
+ return -1;
+ }
utf16[j++] = (char)codeUnit;
continue;
@@ -127,25 +153,37 @@
while (state >= 0)
{
- if (i >= utf8.length) { return -1; }
+ if (i >= maxI)
+ {
+ return -1;
+ }
codeUnit = utf8[i++];
codePoint = (codePoint << 6) | (codeUnit & 0x3F);
state = transitionTable[state + ((codeUnit & 0xFF) >>> 4)];
}
- if (state == S_ERR) { return -1; }
+ if (state == S_ERR)
+ {
+ return -1;
+ }
if (codePoint <= 0xFFFF)
{
- if (j >= utf16.length) { return -1; }
+ if (j >= utf16.length)
+ {
+ return -1;
+ }
// Code points from U+D800 to U+DFFF are caught by the DFA
utf16[j++] = (char)codePoint;
}
else
{
- if (j >= utf16.length - 1) { return -1; }
+ if (j >= utf16.length - 1)
+ {
+ return -1;
+ }
// Code points above U+10FFFF are caught by the DFA
utf16[j++] = (char)(0xD7C0 + (codePoint >>> 10));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/Streams.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/Streams.java
index 5ab96d9..95e376f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/Streams.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/Streams.java
@@ -30,6 +30,64 @@
}
/**
+ * Write the full contents of inStr to the destination stream outStr.
+ *
+ * @param inStr source input stream.
+ * @param outStr destination output stream.
+ * @throws IOException in case of underlying IOException.
+ */
+ public static void pipeAll(InputStream inStr, OutputStream outStr)
+ throws IOException
+ {
+ pipeAll(inStr, outStr, BUFFER_SIZE);
+ }
+
+ /**
+ * Write the full contents of inStr to the destination stream outStr.
+ *
+ * @param inStr source input stream.
+ * @param outStr destination output stream.
+ * @param bufferSize the size of temporary buffer to use.
+ * @throws IOException in case of underlying IOException.
+ */
+ public static void pipeAll(InputStream inStr, OutputStream outStr, int bufferSize)
+ throws IOException
+ {
+ byte[] bs = new byte[bufferSize];
+ int numRead;
+ while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ {
+ outStr.write(bs, 0, numRead);
+ }
+ }
+
+ /**
+ * Write up to limit bytes of data from inStr to the destination stream outStr.
+ *
+ * @param inStr source input stream.
+ * @param limit the maximum number of bytes allowed to be read.
+ * @param outStr destination output stream.
+ * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it.
+ */
+ public static long pipeAllLimited(InputStream inStr, long limit, OutputStream outStr)
+ throws IOException
+ {
+ long total = 0;
+ byte[] bs = new byte[BUFFER_SIZE];
+ int numRead;
+ while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ {
+ if ((limit - total) < numRead)
+ {
+ throw new StreamOverflowException("Data Overflow");
+ }
+ total += numRead;
+ outStr.write(bs, 0, numRead);
+ }
+ return total;
+ }
+
+ /**
* Read stream fully, returning contents in a byte array.
*
* @param inStr stream to be read.
@@ -98,51 +156,22 @@
}
totalRead += numRead;
}
+
return totalRead;
}
- /**
- * Write the full contents of inStr to the destination stream outStr.
- *
- * @param inStr source input stream.
- * @param outStr destination output stream.
- * @throws IOException in case of underlying IOException.
- */
- public static void pipeAll(InputStream inStr, OutputStream outStr)
- throws IOException
+ public static void validateBufferArguments(byte[] buf, int off, int len)
{
- byte[] bs = new byte[BUFFER_SIZE];
- int numRead;
- while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ if (buf == null)
{
- outStr.write(bs, 0, numRead);
+ throw new NullPointerException();
}
- }
-
- /**
- * Write up to limit bytes of data from inStr to the destination stream outStr.
- *
- * @param inStr source input stream.
- * @param limit the maximum number of bytes allowed to be read.
- * @param outStr destination output stream.
- * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it.
- */
- public static long pipeAllLimited(InputStream inStr, long limit, OutputStream outStr)
- throws IOException
- {
- long total = 0;
- byte[] bs = new byte[BUFFER_SIZE];
- int numRead;
- while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ int available = buf.length - off;
+ int remaining = available - len;
+ if ((off | len | available | remaining) < 0)
{
- if ((limit - total) < numRead)
- {
- throw new StreamOverflowException("Data Overflow");
- }
- total += numRead;
- outStr.write(bs, 0, numRead);
+ throw new IndexOutOfBoundsException();
}
- return total;
}
public static void writeBufTo(ByteArrayOutputStream buf, OutputStream output)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemReader.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemReader.java
index 5a9ebb2..9846cef 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemReader.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemReader.java
@@ -66,9 +66,9 @@
while ((line = readLine()) != null)
{
- if (line.indexOf(":") >= 0)
+ int index = line.indexOf(':');
+ if (index >= 0)
{
- int index = line.indexOf(':');
String hdr = line.substring(0, index);
String value = line.substring(index + 1).trim();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V2AttributeCertificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V2AttributeCertificate.java
index 5eac49a..2c09768 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V2AttributeCertificate.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V2AttributeCertificate.java
@@ -22,12 +22,12 @@
import java.util.List;
import java.util.Set;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
import com.android.org.bouncycastle.asn1.ASN1InputStream;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.x509.AttributeCertificate;
import com.android.org.bouncycastle.asn1.x509.Extension;
import com.android.org.bouncycastle.asn1.x509.Extensions;
@@ -125,7 +125,7 @@
public boolean[] getIssuerUniqueID()
{
- DERBitString id = cert.getAcinfo().getIssuerUniqueID();
+ ASN1BitString id = cert.getAcinfo().getIssuerUniqueID();
if (id != null)
{
diff --git a/repackaged/bcprov/src/test/java/com/android/org/bouncycastle/math/ec/test/ECPointTest.java b/repackaged/bcprov/src/test/java/com/android/org/bouncycastle/math/ec/test/ECPointTest.java
index 0978d2e..ca93afc 100644
--- a/repackaged/bcprov/src/test/java/com/android/org/bouncycastle/math/ec/test/ECPointTest.java
+++ b/repackaged/bcprov/src/test/java/com/android/org/bouncycastle/math/ec/test/ECPointTest.java
@@ -1,6 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.math.ec.test;
+package com.android.org.bouncycastle.math.ec.test;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
@@ -10,7 +10,6 @@
import java.util.List;
import java.util.Random;
import java.util.Set;
-
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
@@ -28,9 +27,7 @@
import com.android.org.bouncycastle.util.BigIntegers;
import com.android.org.bouncycastle.util.Integers;
import com.android.org.bouncycastle.util.encoders.Hex;
-
import android.platform.test.annotations.LargeTest;
-
/**
* Test class for {@link com.android.org.bouncycastle.math.ec.ECPoint ECPoint}. All
* literature values are taken from "Guide to elliptic curve cryptography",
@@ -44,11 +41,8 @@
* Random source used to generate random points
*/
private SecureRandom secRand = new SecureRandom();
-
private ECPointTest.Fp fp = null;
-
private ECPointTest.F2m f2m = null;
-
/**
* Nested class containing sample literature values for <code>Fp</code>.
* @hide This class is not part of the Android public SDK API
@@ -56,23 +50,14 @@
public static class Fp
{
private final BigInteger q = new BigInteger("1063");
-
private final BigInteger a = new BigInteger("4");
-
private final BigInteger b = new BigInteger("20");
-
private final BigInteger n = new BigInteger("38");
-
private final BigInteger h = new BigInteger("1");
-
private final ECCurve curve = new ECCurve.Fp(q, a, b, n, h);
-
private final ECPoint infinity = curve.getInfinity();
-
private final int[] pointSource = { 1, 5, 4, 10, 234, 1024, 817, 912 };
-
private ECPoint[] p = new ECPoint[pointSource.length / 2];
-
/**
* Creates the points on the curve with literature values.
*/
@@ -86,7 +71,6 @@
}
}
}
-
/**
* Nested class containing sample literature values for <code>F2m</code>.
* @hide This class is not part of the Android public SDK API
@@ -95,28 +79,18 @@
{
// Irreducible polynomial for TPB z^4 + z + 1
private final int m = 4;
-
private final int k1 = 1;
-
// a = z^3
private final BigInteger aTpb = new BigInteger("1000", 2);
-
// b = z^3 + 1
private final BigInteger bTpb = new BigInteger("1001", 2);
-
private final BigInteger n = new BigInteger("23");
-
private final BigInteger h = new BigInteger("1");
-
private final ECCurve.F2m curve = new ECCurve.F2m(m, k1, aTpb, bTpb, n, h);
-
private final ECPoint.F2m infinity = (ECPoint.F2m) curve.getInfinity();
-
private final String[] pointSource = { "0010", "1111", "1100", "1100",
"0001", "0001", "1011", "0010" };
-
private ECPoint[] p = new ECPoint[pointSource.length / 2];
-
/**
* Creates the points on the curve with literature values.
*/
@@ -130,16 +104,13 @@
}
}
}
-
public void setUp()
{
fp = new ECPointTest.Fp();
fp.createPoints();
-
f2m = new ECPointTest.F2m();
f2m.createPoints();
}
-
/**
* Tests, if inconsistent points can be created, i.e. points with exactly
* one null coordinate (not permitted).
@@ -154,7 +125,6 @@
catch (IllegalArgumentException expected)
{
}
-
try
{
ECPoint bad = fp.curve.createPoint(null, new BigInteger("12"));
@@ -163,7 +133,6 @@
catch (IllegalArgumentException expected)
{
}
-
try
{
ECPoint bad = f2m.curve.createPoint(new BigInteger("1011"), null);
@@ -172,7 +141,6 @@
catch (IllegalArgumentException expected)
{
}
-
try
{
ECPoint bad = f2m.curve.createPoint(null, new BigInteger("1011"));
@@ -182,7 +150,6 @@
{
}
}
-
/**
* Tests <code>ECPoint.add()</code> against literature values.
*
@@ -201,7 +168,6 @@
assertPointsEqual("Adding to infinity failed", p[i], infinity.add(p[i]));
}
}
-
/**
* Calls <code>implTestAdd()</code> for <code>Fp</code> and
* <code>F2m</code>.
@@ -211,7 +177,6 @@
implTestAdd(fp.p, fp.infinity);
implTestAdd(f2m.p, f2m.infinity);
}
-
/**
* Tests <code>ECPoint.twice()</code> against literature values.
*
@@ -223,7 +188,6 @@
assertPointsEqual("Twice incorrect", p[3], p[0].twice());
assertPointsEqual("Add same point incorrect", p[3], p[0].add(p[0]));
}
-
/**
* Calls <code>implTestTwice()</code> for <code>Fp</code> and
* <code>F2m</code>.
@@ -233,7 +197,6 @@
implTestTwice(fp.p);
implTestTwice(f2m.p);
}
-
private void implTestThreeTimes(ECPoint[] p)
{
ECPoint P = p[0];
@@ -241,7 +204,6 @@
assertPointsEqual("ThreeTimes incorrect", _3P, P.threeTimes());
assertPointsEqual("TwicePlus incorrect", _3P, P.twicePlus(P));
}
-
/**
* Calls <code>implTestThreeTimes()</code> for <code>Fp</code> and
* <code>F2m</code>.
@@ -251,7 +213,6 @@
implTestThreeTimes(fp.p);
implTestThreeTimes(f2m.p);
}
-
/**
* Goes through all points on an elliptic curve and checks, if adding a
* point <code>k</code>-times is the same as multiplying the point by
@@ -267,7 +228,6 @@
{
ECPoint adder = infinity;
ECPoint multiplier = infinity;
-
BigInteger i = BigInteger.valueOf(1);
do
{
@@ -279,7 +239,6 @@
}
while (!(adder.equals(infinity)));
}
-
/**
* Calls <code>implTestAllPoints()</code> for the small literature curves,
* both for <code>Fp</code> and <code>F2m</code>.
@@ -290,13 +249,11 @@
{
implTestAllPoints(fp.p[i], fp.infinity);
}
-
for (int i = 0; i < f2m.p.length; i++)
{
implTestAllPoints(f2m.p[i], f2m.infinity);
}
}
-
/**
* Checks, if the point multiplication algorithm of the given point yields
* the same result as point multiplication done by the reference
@@ -316,7 +273,6 @@
ECPoint q = p.multiply(k);
assertPointsEqual("ECPoint.multiply is incorrect", ref, q);
}
-
/**
* Checks, if the point multiplication algorithm of the given point yields
* the same result as point multiplication done by the reference
@@ -333,7 +289,6 @@
{
BigInteger bound = BigInteger.ONE.shiftLeft(numBits);
BigInteger k = BigInteger.ZERO;
-
do
{
ECPoint ref = ECAlgorithms.referenceMultiply(p, k);
@@ -343,7 +298,6 @@
}
while (k.compareTo(bound) < 0);
}
-
/**
* Tests <code>ECPoint.add()</code> and <code>ECPoint.subtract()</code>
* for the given point and the given point at infinity.
@@ -364,7 +318,6 @@
assertPointsEqual("infinity plus infinity is not infinity ", infinity, infinity.add(infinity));
assertPointsEqual("Twice infinity is not infinity ", infinity, infinity.twice());
}
-
/**
* Calls <code>implTestAddSubtract()</code> for literature values, both
* for <code>Fp</code> and <code>F2m</code>.
@@ -375,21 +328,17 @@
for (int iFp = 0; iFp < fp.pointSource.length / 2; iFp++)
{
implTestAddSubtract(fp.p[iFp], fp.infinity);
-
implTestMultiplyAll(fp.p[iFp], fpBits);
implTestMultiplyAll(fp.infinity, fpBits);
}
-
int f2mBits = f2m.curve.getOrder().bitLength();
for (int iF2m = 0; iF2m < f2m.pointSource.length / 2; iF2m++)
{
implTestAddSubtract(f2m.p[iF2m], f2m.infinity);
-
implTestMultiplyAll(f2m.p[iF2m], f2mBits);
implTestMultiplyAll(f2m.infinity, f2mBits);
}
}
-
/**
* Test encoding with and without point compression.
*
@@ -402,25 +351,20 @@
byte[] unCompBarr = p.getEncoded(false);
ECPoint decUnComp = p.getCurve().decodePoint(unCompBarr);
assertPointsEqual("Error decoding uncompressed point", p, decUnComp);
-
// Point compression
byte[] compBarr = p.getEncoded(true);
ECPoint decComp = p.getCurve().decodePoint(compBarr);
assertPointsEqual("Error decoding compressed point", p, decComp);
}
-
private void implAddSubtractMultiplyTwiceEncodingTest(ECCurve curve, ECPoint q, BigInteger n)
{
// Get point at infinity on the curve
ECPoint infinity = curve.getInfinity();
-
implTestAddSubtract(q, infinity);
implTestMultiply(q, n.bitLength());
implTestMultiply(infinity, n.bitLength());
-
int logSize = 32 - Integers.numberOfLeadingZeros(curve.getFieldSize() - 1);
int rounds = Math.max(2, Math.min(10, 32 - 3 * logSize));
-
ECPoint p = q;
for (int i = 0; i < rounds; ++i)
{
@@ -428,7 +372,6 @@
p = p.twice();
}
}
-
private void implSqrtTest(ECCurve c)
{
if (ECAlgorithms.isFpCurve(c))
@@ -436,19 +379,15 @@
BigInteger p = c.getField().getCharacteristic();
BigInteger pMinusOne = p.subtract(ECConstants.ONE);
BigInteger legendreExponent = p.shiftRight(1);
-
ECFieldElement zero = c.fromBigInteger(BigInteger.ZERO);
assertEquals(zero, zero.sqrt());
-
ECFieldElement one = c.fromBigInteger(BigInteger.ONE);
assertEquals(one, one.sqrt());
-
for (int i = 0; i < 20; ++i)
{
BigInteger x = BigIntegers.createRandomInRange(ECConstants.TWO, pMinusOne, secRand);
ECFieldElement fe = c.fromBigInteger(x);
ECFieldElement root = fe.sqrt();
-
if (root == null)
{
assertEquals(pMinusOne, x.modPow(legendreExponent, p));
@@ -473,11 +412,9 @@
}
}
}
-
private void implValidityTest(ECCurve c, ECPoint g)
{
assertTrue(g.isValid());
-
if (ECAlgorithms.isF2mCurve(c))
{
BigInteger h = c.getCofactor();
@@ -493,7 +430,6 @@
assertFalse(bad2.isValid());
ECPoint good2 = bad2.add(order2);
assertTrue(good2.isValid());
-
if (!h.testBit(1))
{
ECFieldElement L = solveQuadraticEquation(c, c.getA());
@@ -517,13 +453,11 @@
}
}
}
-
private void implAddSubtractMultiplyTwiceEncodingTestAllCoords(X9ECParameters x9ECParameters)
{
BigInteger n = x9ECParameters.getN();
ECPoint G = x9ECParameters.getG();
ECCurve C = x9ECParameters.getCurve();
-
int[] coords = ECCurve.getAllCoordinateSystems();
for (int i = 0; i < coords.length; ++i)
{
@@ -532,26 +466,20 @@
{
ECCurve c = C;
ECPoint g = G;
-
if (c.getCoordinateSystem() != coord)
{
c = C.configure().setCoordinateSystem(coord).create();
g = c.importPoint(G);
}
-
// The generator is multiplied by random b to get random q
BigInteger b = new BigInteger(n.bitLength(), secRand);
ECPoint q = g.multiply(b).normalize();
-
implAddSubtractMultiplyTwiceEncodingTest(c, q, n);
-
implSqrtTest(c);
-
implValidityTest(c, g);
}
}
}
-
/**
* Calls <code>implTestAddSubtract()</code>,
* <code>implTestMultiply</code> and <code>implTestEncoding</code> for
@@ -562,15 +490,12 @@
{
Set names = new HashSet(enumToList(ECNamedCurveTable.getNames()));
names.addAll(enumToList(CustomNamedCurves.getNames()));
-
Iterator it = names.iterator();
while (it.hasNext())
{
String name = (String)it.next();
-
X9ECParameters x9A = ECNamedCurveTable.getByName(name);
X9ECParameters x9B = CustomNamedCurves.getByName(name);
-
if (x9A != null && x9B != null)
{
assertEquals(x9A.getCurve().getField(), x9B.getCurve().getField());
@@ -578,31 +503,25 @@
assertEquals(x9A.getCurve().getB().toBigInteger(), x9B.getCurve().getB().toBigInteger());
assertOptionalValuesAgree(x9A.getCurve().getCofactor(), x9B.getCurve().getCofactor());
assertOptionalValuesAgree(x9A.getCurve().getOrder(), x9B.getCurve().getOrder());
-
assertPointsEqual("Custom curve base-point inconsistency", x9A.getG(), x9B.getG());
-
assertEquals(x9A.getH(), x9B.getH());
assertEquals(x9A.getN(), x9B.getN());
assertOptionalValuesAgree(x9A.getSeed(), x9B.getSeed());
-
BigInteger k = new BigInteger(x9A.getN().bitLength(), secRand);
ECPoint pA = x9A.getG().multiply(k);
ECPoint pB = x9B.getG().multiply(k);
assertPointsEqual("Custom curve multiplication inconsistency", pA, pB);
}
-
if (x9A != null)
{
implAddSubtractMultiplyTwiceEncodingTestAllCoords(x9A);
}
-
if (x9B != null)
{
implAddSubtractMultiplyTwiceEncodingTestAllCoords(x9B);
}
}
}
-
public void testExampleFpB0() throws Exception
{
/*
@@ -623,9 +542,7 @@
byte[] S = null;
BigInteger n = p.add(BigInteger.valueOf(1)).shiftRight(2);
BigInteger h = BigInteger.valueOf(4);
-
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
-
X9ECPoint G = configureBasepoint(curve, "04"
// Px
+ "53FC09EE332C29AD0A7990053ED9B52A"
@@ -645,19 +562,15 @@
+ "AC6F1E80164AA989492D979FC5A4D5F2"
+ "13515AD7E9CB99A980BDAD5AD5BB4636"
+ "ADB9B5706A67DCDE75573FD71BEF16D7");
-
X9ECParameters x9 = new X9ECParameters(curve, G, n, h, S);
-
implAddSubtractMultiplyTwiceEncodingTestAllCoords(x9);
}
-
private void assertPointsEqual(String message, ECPoint a, ECPoint b)
{
// NOTE: We intentionally test points for equality in both directions
assertEquals(message, a, b);
assertEquals(message, b, a);
}
-
private void assertOptionalValuesAgree(Object a, Object b)
{
if (a != null && b != null)
@@ -665,7 +578,6 @@
assertEquals(a, b);
}
}
-
private void assertOptionalValuesAgree(byte[] a, byte[] b)
{
if (a != null && b != null)
@@ -673,46 +585,37 @@
assertTrue(Arrays.areEqual(a, b));
}
}
-
private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
{
X9ECPoint G = new X9ECPoint(curve, Hex.decode(encoding));
WNafUtil.configureBasepoint(G.getPoint());
return G;
}
-
private static ECCurve configureCurve(ECCurve curve)
{
return curve;
}
-
private List enumToList(Enumeration en)
{
List rv = new ArrayList();
-
while (en.hasMoreElements())
{
rv.add(en.nextElement());
}
-
return rv;
}
-
private static BigInteger fromHex(
String hex)
{
return new BigInteger(1, Hex.decode(hex));
}
-
private static ECFieldElement solveQuadraticEquation(ECCurve c, ECFieldElement rhs)
{
if (rhs.isZero())
{
return rhs;
}
-
ECFieldElement gamma, z, zeroElement = c.fromBigInteger(ECConstants.ZERO);
-
int m = c.getFieldSize();
Random rand = new Random();
do
@@ -733,12 +636,11 @@
gamma = z.square().add(z);
}
while (gamma.isZero());
-
return z;
}
-
public static Test suite()
{
return new TestSuite(ECPointTest.class);
}
}
+
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateHolder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateHolder.java
index 58541a8..e70381c 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateHolder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateHolder.java
@@ -325,9 +325,9 @@
digOut.close();
- if (!Arrays.areEqual(digCalc.getDigest(), getObjectDigest()))
+ if (Arrays.areEqual(digCalc.getDigest(), getObjectDigest()))
{
- return false;
+ return true;
}
}
catch (Exception e)
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertUtils.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertUtils.java
index ff8383e..c7e6408 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertUtils.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertUtils.java
@@ -13,6 +13,7 @@
import java.util.List;
import java.util.Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
@@ -20,9 +21,12 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DERNull;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.AttributeCertificate;
import com.android.internal.org.bouncycastle.asn1.x509.AttributeCertificateInfo;
@@ -78,28 +82,6 @@
}
}
- static X509CRLHolder generateFullCRL(ContentSigner signer, TBSCertList tbsCertList)
- {
- try
- {
- return new X509CRLHolder(generateCRLStructure(tbsCertList, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCertList)));
- }
- catch (IOException e)
- {
- throw new IllegalStateException("cannot produce certificate signature");
- }
- }
-
- private static byte[] generateSig(ContentSigner signer, ASN1Object tbsObj)
- throws IOException
- {
- OutputStream sOut = signer.getOutputStream();
- tbsObj.encodeTo(sOut, ASN1Encoding.DER);
- sOut.close();
-
- return signer.getSignature();
- }
-
private static Certificate generateStructure(TBSCertificate tbsCert, AlgorithmIdentifier sigAlgId, byte[] signature)
{
ASN1EncodableVector v = new ASN1EncodableVector();
@@ -198,12 +180,12 @@
}
}
- static boolean[] bitStringToBoolean(DERBitString bitString)
+ static boolean[] bitStringToBoolean(ASN1BitString bitString)
{
if (bitString != null)
{
- byte[] bytes = bitString.getBytes();
- boolean[] boolId = new boolean[bytes.length * 8 - bitString.getPadBits()];
+ byte[] bytes = bitString.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - bitString.getPadBits()];
for (int i = 0; i != boolId.length; i++)
{
@@ -235,40 +217,40 @@
return false;
}
- if (Properties.isOverrideSet("com.android.internal.org.bouncycastle.x509.allow_absent_equiv_NULL"))
- {
- if (id1.getParameters() == null)
- {
- if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
- {
- return false;
- }
+ if (Properties.isOverrideSet("com.android.internal.org.bouncycastle.x509.allow_absent_equiv_NULL"))
+ {
+ if (id1.getParameters() == null)
+ {
+ if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
+ {
+ return false;
+ }
- return true;
- }
+ return true;
+ }
- if (id2.getParameters() == null)
- {
- if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
- {
- return false;
- }
+ if (id2.getParameters() == null)
+ {
+ if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
+ {
+ return false;
+ }
- return true;
- }
- }
+ return true;
+ }
+ }
- if (id1.getParameters() != null)
- {
- return id1.getParameters().equals(id2.getParameters());
- }
+ if (id1.getParameters() != null)
+ {
+ return id1.getParameters().equals(id2.getParameters());
+ }
- if (id2.getParameters() != null)
- {
- return id2.getParameters().equals(id1.getParameters());
- }
+ if (id2.getParameters() != null)
+ {
+ return id2.getParameters().equals(id1.getParameters());
+ }
- return true;
+ return true;
}
static ExtensionsGenerator doReplaceExtension(ExtensionsGenerator extGenerator, Extension ext)
@@ -277,7 +259,7 @@
Extensions exts = extGenerator.generate();
extGenerator = new ExtensionsGenerator();
- for (Enumeration en = exts.oids(); en.hasMoreElements();)
+ for (Enumeration en = exts.oids(); en.hasMoreElements(); )
{
ASN1ObjectIdentifier extOid = (ASN1ObjectIdentifier)en.nextElement();
@@ -300,13 +282,13 @@
return extGenerator;
}
- static ExtensionsGenerator doRemoveExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid)
+ static ExtensionsGenerator doRemoveExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid)
{
boolean isRemoved = false;
Extensions exts = extGenerator.generate();
extGenerator = new ExtensionsGenerator();
- for (Enumeration en = exts.oids(); en.hasMoreElements();)
+ for (Enumeration en = exts.oids(); en.hasMoreElements(); )
{
ASN1ObjectIdentifier extOid = (ASN1ObjectIdentifier)en.nextElement();
@@ -327,4 +309,31 @@
return extGenerator;
}
+
+ private static byte[] generateSig(ContentSigner signer, ASN1Object tbsObj)
+ throws IOException
+ {
+ OutputStream sOut = signer.getOutputStream();
+ tbsObj.encodeTo(sOut, ASN1Encoding.DER);
+ sOut.close();
+
+ return signer.getSignature();
+ }
+
+ static ASN1TaggedObject trimExtensions(int tagNo, Extensions exts)
+ {
+ ASN1Sequence extSeq = ASN1Sequence.getInstance(exts.toASN1Primitive());
+ ASN1EncodableVector extV = new ASN1EncodableVector();
+ for (int i = 0; i != extSeq.size(); i++)
+ {
+ ASN1Sequence ext = ASN1Sequence.getInstance(extSeq.getObjectAt(i));
+
+ if (!Extension.altSignatureValue.equals(ext.getObjectAt(0)))
+ {
+ extV.add(ext);
+ }
+ }
+
+ return new DERTaggedObject(true, tagNo, new DERSequence(extV));
+ }
}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/DeltaCertificateTool.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/DeltaCertificateTool.java
new file mode 100644
index 0000000..f2fd22f
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/DeltaCertificateTool.java
@@ -0,0 +1,187 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.ExtensionsGenerator;
+
+/**
+ * General tool for handling the extension described in: https://datatracker.ietf.org/doc/draft-bonnell-lamps-chameleon-certs/
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DeltaCertificateTool
+{
+ public static Extension makeDeltaCertificateExtension(boolean isCritical, X509CertificateHolder deltaCert)
+ throws IOException
+ {
+ ASN1EncodableVector deltaV = new ASN1EncodableVector();
+
+ deltaV.add(new ASN1Integer(deltaCert.getSerialNumber()));
+ deltaV.add(new DERTaggedObject(false, 0, deltaCert.getSignatureAlgorithm()));
+ deltaV.add(new DERTaggedObject(false, 1, deltaCert.getIssuer()));
+
+ ASN1EncodableVector validity = new ASN1EncodableVector(2);
+ validity.add(deltaCert.toASN1Structure().getStartDate());
+ validity.add(deltaCert.toASN1Structure().getEndDate());
+
+ deltaV.add(new DERTaggedObject(false, 2, new DERSequence(validity)));
+ deltaV.add(new DERTaggedObject(false, 3, deltaCert.getSubject()));
+ deltaV.add(deltaCert.getSubjectPublicKeyInfo());
+ if (deltaCert.getExtensions() != null)
+ {
+ deltaV.add(new DERTaggedObject(false, 4, deltaCert.getExtensions()));
+ }
+ deltaV.add(new DERBitString(deltaCert.getSignature()));
+
+ return new Extension(Extension.deltaCertificateDescriptor, isCritical, new DERSequence(deltaV).getEncoded(ASN1Encoding.DER));
+ }
+
+ public static X509CertificateHolder extractDeltaCertificate(X509CertificateHolder originCert)
+ {
+ ASN1ObjectIdentifier deltaExtOid = Extension.deltaCertificateDescriptor;
+ Extension deltaExt = originCert.getExtension(deltaExtOid);
+
+ ASN1Sequence seq = ASN1Sequence.getInstance(deltaExt.getParsedValue());
+// * version [ 0 ] Version DEFAULT v1(0),
+// * serialNumber CertificateSerialNumber,
+// * signature AlgorithmIdentifier,
+// * issuer Name,
+// * validity Validity,
+// * subject Name,
+// * subjectPublicKeyInfo SubjectPublicKeyInfo,
+// * issuerUniqueID [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
+// * subjectUniqueID [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
+// * extensions [ 3 ] Extensions OPTIONAL
+ ASN1Sequence originTbs = ASN1Sequence.getInstance(originCert.toASN1Structure().getTBSCertificate().toASN1Primitive());
+ int idx = 0;
+ ASN1Encodable[] extracted = originTbs.toArray();
+
+ extracted[0] = originTbs.getObjectAt(0);
+ extracted[1] = ASN1Integer.getInstance(seq.getObjectAt(idx++));
+
+ ASN1Encodable next = seq.getObjectAt(idx++);
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ extracted[2] = ASN1Sequence.getInstance(tagged, false);
+ break;
+ case 1:
+ extracted[3] = ASN1Sequence.getInstance(tagged, true); // issuer
+ break;
+ case 2:
+ extracted[4] = ASN1Sequence.getInstance(tagged, false);
+ break;
+ case 3:
+ extracted[5] = ASN1Sequence.getInstance((ASN1TaggedObject)next, true); // subject
+ break;
+ }
+ next = seq.getObjectAt(idx++);
+ }
+
+ extracted[6] = next; // subjectPublicKey
+
+ if (extracted[2] == null)
+ {
+ extracted[2] = originTbs.getObjectAt(2);
+ }
+
+ if (extracted[3] == null)
+ {
+ extracted[3] = originTbs.getObjectAt(3);
+ }
+
+ if (extracted[4] == null)
+ {
+ extracted[4] = originTbs.getObjectAt(4);
+ }
+
+ if (extracted[5] == null)
+ {
+ extracted[5] = originTbs.getObjectAt(5);
+ }
+
+ ExtensionsGenerator extGen = extractExtensions(originTbs);
+
+ if (idx < (seq.size() - 1)) // last element is the signature
+ {
+ next = seq.getObjectAt(idx++);
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ if (tagged.getTagNo() != 4)
+ {
+ throw new IllegalArgumentException("malformed delta extension");
+ }
+
+ ASN1Sequence deltaExts = ASN1Sequence.getInstance(tagged, false);
+
+ for (int i = 0; i != deltaExts.size(); i++)
+ {
+ Extension ext = Extension.getInstance(deltaExts.getObjectAt(i));
+
+ extGen.replaceExtension(ext);
+ }
+
+ extracted[7] = new DERTaggedObject(3, extGen.generate());
+ }
+ else
+ {
+ if (!extGen.isEmpty())
+ {
+ extracted[7] = new DERTaggedObject(3, extGen.generate());
+ }
+ else
+ {
+ extracted[7] = null;
+ }
+ }
+
+ ASN1EncodableVector tbsDeltaCertV = new ASN1EncodableVector(7);
+ for (int i = 0; i != extracted.length; i++)
+ {
+ if (extracted[i] != null)
+ {
+ tbsDeltaCertV.add(extracted[i]);
+ }
+ }
+
+ ASN1EncodableVector certV = new ASN1EncodableVector();
+ certV.add(new DERSequence(tbsDeltaCertV));
+ certV.add(ASN1Sequence.getInstance(extracted[2]));
+ certV.add(ASN1BitString.getInstance(seq.getObjectAt(seq.size() - 1)));
+
+ return new X509CertificateHolder(Certificate.getInstance(new DERSequence(certV)));
+ }
+
+ private static ExtensionsGenerator extractExtensions(ASN1Sequence originTbs)
+ {
+ ASN1ObjectIdentifier deltaExtOid = Extension.deltaCertificateDescriptor;
+ ASN1Sequence originExt = ASN1Sequence.getInstance(ASN1TaggedObject.getInstance(originTbs.getObjectAt(originTbs.size() - 1)), true);
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+
+ for (int i = 0; i != originExt.size(); i++)
+ {
+ Extension ext = Extension.getInstance(originExt.getObjectAt(i));
+ if (!deltaExtOid.equals(ext.getExtnId()))
+ {
+ extGen.addExtension(ext);
+ }
+ }
+
+ return extGen;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLHolder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLHolder.java
index ef13899..b8a718d 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLHolder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLHolder.java
@@ -16,11 +16,18 @@
import java.util.List;
import java.util.Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.AltSignatureAlgorithm;
+import com.android.internal.org.bouncycastle.asn1.x509.AltSignatureValue;
import com.android.internal.org.bouncycastle.asn1.x509.CertificateList;
import com.android.internal.org.bouncycastle.asn1.x509.Extension;
import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
@@ -41,7 +48,7 @@
implements Encodable, Serializable
{
private static final long serialVersionUID = 20170722001L;
-
+
private transient CertificateList x509CRL;
private transient boolean isIndirect;
private transient Extensions extensions;
@@ -164,7 +171,7 @@
public X509CRLEntryHolder getRevokedCertificate(BigInteger serialNumber)
{
GeneralNames currentCA = issuerName;
- for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements();)
+ for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements(); )
{
TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)en.nextElement();
@@ -199,7 +206,7 @@
List l = new ArrayList(entries.length);
GeneralNames currentCA = issuerName;
- for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements();)
+ for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements(); )
{
TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)en.nextElement();
X509CRLEntryHolder crlEntry = new X509CRLEntryHolder(entry, isIndirect, currentCA);
@@ -211,7 +218,7 @@
return l;
}
-
+
/**
* Return whether or not the holder's CRL contains extensions.
*
@@ -226,7 +233,6 @@
* Look up the extension associated with the passed in OID.
*
* @param oid the OID of the extension of interest.
- *
* @return the extension if present, null otherwise.
*/
public Extension getExtension(ASN1ObjectIdentifier oid)
@@ -327,6 +333,51 @@
return verifier.verify(x509CRL.getSignature().getOctets());
}
+ public boolean isAlternativeSignatureValid(ContentVerifierProvider verifierProvider)
+ throws CertException
+ {
+ TBSCertList tbsCrList = x509CRL.getTBSCertList();
+ AltSignatureAlgorithm altSigAlg = AltSignatureAlgorithm.fromExtensions(tbsCrList.getExtensions());
+ AltSignatureValue altSigValue = AltSignatureValue.fromExtensions(tbsCrList.getExtensions());
+
+ ContentVerifier verifier;
+
+ try
+ {
+ verifier = verifierProvider.get(AlgorithmIdentifier.getInstance(altSigAlg.toASN1Primitive()));
+
+ OutputStream sOut = verifier.getOutputStream();
+
+ ASN1Sequence tbsSeq = ASN1Sequence.getInstance(tbsCrList.toASN1Primitive());
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ int start = 1; // want to skip signature field
+ if (tbsSeq.getObjectAt(0) instanceof ASN1Integer)
+ {
+ v.add(tbsSeq.getObjectAt(0));
+ start++;
+ }
+
+ for (int i = start; i != tbsSeq.size() - 1; i++)
+ {
+ v.add(tbsSeq.getObjectAt(i));
+ }
+
+ v.add(CertUtils.trimExtensions(0, tbsCrList.getExtensions()));
+
+ new DERSequence(v).encodeTo(sOut, ASN1Encoding.DER);
+
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new CertException("unable to process signature: " + e.getMessage(), e);
+ }
+
+ return verifier.verify(altSigValue.getSignature().getOctets());
+ }
+
+
public boolean equals(
Object o)
{
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CertificateHolder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CertificateHolder.java
index 9ca4a28..f302f89 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CertificateHolder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CertificateHolder.java
@@ -11,10 +11,15 @@
import java.util.List;
import java.util.Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.AltSignatureAlgorithm;
+import com.android.internal.org.bouncycastle.asn1.x509.AltSignatureValue;
import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
import com.android.internal.org.bouncycastle.asn1.x509.Extension;
import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
@@ -245,9 +250,9 @@
}
/**
- * Return the bytes making up the signature associated with this attribute certificate.
+ * Return the bytes making up the signature associated with this certificate.
*
- * @return the attribute certificate signature bytes.
+ * @return the certificate signature bytes.
*/
public byte[] getSignature()
{
@@ -300,6 +305,53 @@
return verifier.verify(this.getSignature());
}
+ /**
+ * Validate the signature on the certificate in this holder.
+ *
+ * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature.
+ * @return true if the signature is valid, false otherwise.
+ * @throws CertException if the signature cannot be processed or is inappropriate.
+ */
+ public boolean isAlternativeSignatureValid(ContentVerifierProvider verifierProvider)
+ throws CertException
+ {
+ TBSCertificate tbsCert = x509Certificate.getTBSCertificate();
+ AltSignatureAlgorithm altSigAlg = AltSignatureAlgorithm.fromExtensions(tbsCert.getExtensions());
+ AltSignatureValue altSigValue = AltSignatureValue.fromExtensions(tbsCert.getExtensions());
+
+ ContentVerifier verifier;
+
+ try
+ {
+ verifier = verifierProvider.get(AlgorithmIdentifier.getInstance(altSigAlg.toASN1Primitive()));
+
+ OutputStream sOut = verifier.getOutputStream();
+
+ ASN1Sequence tbsSeq = ASN1Sequence.getInstance(tbsCert.toASN1Primitive());
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != tbsSeq.size() - 1; i++)
+ {
+ if (i != 2) // signature field - must be ver 3 so version always present
+ {
+ v.add(tbsSeq.getObjectAt(i));
+ }
+ }
+
+ v.add(CertUtils.trimExtensions(3, tbsCert.getExtensions()));
+
+ new DERSequence(v).encodeTo(sOut, ASN1Encoding.DER);
+
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new CertException("unable to process signature: " + e.getMessage(), e);
+ }
+
+ return verifier.verify(altSigValue.getSignature().getOctets());
+ }
+
public boolean equals(
Object o)
{
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java
index cd446d0..0faeadf 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java
@@ -15,10 +15,12 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
+import com.android.internal.org.bouncycastle.asn1.x509.DeltaCertificateDescriptor;
import com.android.internal.org.bouncycastle.asn1.x509.Extension;
import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
import com.android.internal.org.bouncycastle.asn1.x509.ExtensionsGenerator;
@@ -27,6 +29,7 @@
import com.android.internal.org.bouncycastle.asn1.x509.Time;
import com.android.internal.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
import com.android.internal.org.bouncycastle.operator.ContentSigner;
+import com.android.internal.org.bouncycastle.util.Exceptions;
/**
@@ -114,7 +117,16 @@
for (Enumeration en = exts.oids(); en.hasMoreElements();)
{
- extGenerator.addExtension(exts.getExtension((ASN1ObjectIdentifier)en.nextElement()));
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)en.nextElement();
+ // we remove the altSignatureAlgorithm, altSignatureValue, and subjectAltPublicKeyInfo
+ // extensions as they probably need to be regenerated.
+ if (Extension.subjectAltPublicKeyInfo.equals(oid)
+ || Extension.altSignatureAlgorithm.equals(oid)
+ || Extension.altSignatureValue.equals(oid))
+ {
+ continue;
+ }
+ extGenerator.addExtension(exts.getExtension(oid));
}
}
@@ -142,6 +154,11 @@
private Extension doGetExtension(ASN1ObjectIdentifier oid)
{
+ if (extGenerator.isEmpty())
+ {
+ return null;
+ }
+
Extensions exts = extGenerator.generate();
return exts.getExtension(oid);
@@ -365,6 +382,21 @@
if (!extGenerator.isEmpty())
{
+ if (extGenerator.hasExtension(Extension.deltaCertificateDescriptor))
+ {
+ Extension deltaExt = extGenerator.getExtension(Extension.deltaCertificateDescriptor);
+ DeltaCertificateDescriptor deltaDesc = DeltaCertificateDescriptor.getInstance(deltaExt.getParsedValue());
+
+ try
+ {
+ extGenerator.replaceExtension(Extension.deltaCertificateDescriptor, deltaExt.isCritical(),
+ deltaDesc.trimTo(tbsGen.generateTBSCertificate(), extGenerator.generate()));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to replace deltaCertificateDescriptor: " + e.getMessage()) ;
+ }
+ }
tbsGen.setExtensions(extGenerator.generate());
}
@@ -375,7 +407,75 @@
}
catch (IOException e)
{
- throw new IllegalArgumentException("cannot produce certificate signature");
+ throw Exceptions.illegalArgumentException("cannot produce certificate signature", e);
+ }
+ }
+
+ /**
+ * Generate an X.509 certificate, based on the current issuer and subject
+ * using the passed in signer and containing altSignatureAlgorithm and altSignatureValue extensions
+ * based on the passed altSigner.
+ *
+ * @param signer the content signer to be used to generate the signature validating the certificate.
+ * @param altSigner the content signer used to create the altSignatureAlgorithm and altSignatureValue extension.
+ * @return a holder containing the resulting signed certificate.
+ */
+ public X509CertificateHolder build(
+ ContentSigner signer,
+ boolean isCritical,
+ ContentSigner altSigner)
+ {
+ try
+ {
+ extGenerator.addExtension(Extension.altSignatureAlgorithm, isCritical, altSigner.getAlgorithmIdentifier());
+ }
+ catch (IOException e)
+ {
+ throw Exceptions.illegalStateException("cannot add altSignatureAlgorithm extension", e);
+ }
+
+ if (extGenerator.hasExtension(Extension.deltaCertificateDescriptor))
+ {
+ tbsGen.setSignature(signer.getAlgorithmIdentifier());
+
+ Extension deltaExt = extGenerator.getExtension(Extension.deltaCertificateDescriptor);
+ DeltaCertificateDescriptor deltaDesc = DeltaCertificateDescriptor.getInstance(deltaExt.getParsedValue());
+
+ try
+ {
+ // the altSignatureValue is not present yet, but it must be in the deltaCertificate and
+ // it must be different (by definition!). We add a dummy one to trigger inclusion.
+ ExtensionsGenerator tmpExtGen = new ExtensionsGenerator();
+ tmpExtGen.addExtension(extGenerator.generate());
+ tmpExtGen.addExtension(Extension.altSignatureValue, false, DERNull.INSTANCE);
+
+ extGenerator.replaceExtension(Extension.deltaCertificateDescriptor, deltaExt.isCritical(),
+ deltaDesc.trimTo(tbsGen.generateTBSCertificate(), tmpExtGen.generate()));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to replace deltaCertificateDescriptor: " + e.getMessage());
+ }
+ }
+
+ tbsGen.setSignature(null);
+
+ tbsGen.setExtensions(extGenerator.generate());
+
+ try
+ {
+ extGenerator.addExtension(Extension.altSignatureValue, isCritical, new DERBitString(generateSig(altSigner, tbsGen.generatePreTBSCertificate())));
+
+ tbsGen.setSignature(signer.getAlgorithmIdentifier());
+
+ tbsGen.setExtensions(extGenerator.generate());
+
+ TBSCertificate tbsCert = tbsGen.generateTBSCertificate();
+ return new X509CertificateHolder(generateStructure(tbsCert, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCert)));
+ }
+ catch (IOException e)
+ {
+ throw Exceptions.illegalArgumentException("cannot produce certificate signature", e);
}
}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/BasicOCSPResp.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/BasicOCSPResp.java
new file mode 100644
index 0000000..ce6beb8
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/BasicOCSPResp.java
@@ -0,0 +1,228 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ocsp.BasicOCSPResponse;
+import com.android.internal.org.bouncycastle.asn1.ocsp.ResponseData;
+import com.android.internal.org.bouncycastle.asn1.ocsp.SingleResponse;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.operator.ContentVerifier;
+import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider;
+import com.android.internal.org.bouncycastle.util.Encodable;
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * BasicOCSPResponse ::= SEQUENCE {
+ * tbsResponseData ResponseData,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BasicOCSPResp
+ implements Encodable
+{
+ private BasicOCSPResponse resp;
+ private ResponseData data;
+ private Extensions extensions;
+
+ public BasicOCSPResp(
+ BasicOCSPResponse resp)
+ {
+ this.resp = resp;
+ this.data = resp.getTbsResponseData();
+ this.extensions = Extensions.getInstance(resp.getTbsResponseData().getResponseExtensions());
+ }
+
+ /**
+ * Return the DER encoding of the tbsResponseData field.
+ * @return DER encoding of tbsResponseData
+ */
+ public byte[] getTBSResponseData()
+ {
+ try
+ {
+ return resp.getTbsResponseData().getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Return the algorithm identifier describing the signature used in the response.
+ *
+ * @return an AlgorithmIdentifier
+ */
+ public AlgorithmIdentifier getSignatureAlgorithmID()
+ {
+ return resp.getSignatureAlgorithm();
+ }
+
+ public int getVersion()
+ {
+ return data.getVersion().intValueExact() + 1;
+ }
+
+ public RespID getResponderId()
+ {
+ return new RespID(data.getResponderID());
+ }
+
+ public Date getProducedAt()
+ {
+ return OCSPUtils.extractDate(data.getProducedAt());
+ }
+
+ public SingleResp[] getResponses()
+ {
+ ASN1Sequence s = data.getResponses();
+ SingleResp[] rs = new SingleResp[s.size()];
+
+ for (int i = 0; i != rs.length; i++)
+ {
+ rs[i] = new SingleResp(SingleResponse.getInstance(s.getObjectAt(i)));
+ }
+
+ return rs;
+ }
+
+ public boolean hasExtensions()
+ {
+ return extensions != null;
+ }
+
+ public Extension getExtension(ASN1ObjectIdentifier oid)
+ {
+ if (extensions != null)
+ {
+ return extensions.getExtension(oid);
+ }
+
+ return null;
+ }
+
+ public List getExtensionOIDs()
+ {
+ return OCSPUtils.getExtensionOIDs(extensions);
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ return OCSPUtils.getCriticalExtensionOIDs(extensions);
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return OCSPUtils.getNonCriticalExtensionOIDs(extensions);
+ }
+
+
+ public ASN1ObjectIdentifier getSignatureAlgOID()
+ {
+ return resp.getSignatureAlgorithm().getAlgorithm();
+ }
+
+ public byte[] getSignature()
+ {
+ return resp.getSignature().getOctets();
+ }
+
+ public X509CertificateHolder[] getCerts()
+ {
+ //
+ // load the certificates if we have any
+ //
+ if (resp.getCerts() != null)
+ {
+ ASN1Sequence s = resp.getCerts();
+
+ if (s != null)
+ {
+ X509CertificateHolder[] certs = new X509CertificateHolder[s.size()];
+
+ for (int i = 0; i != certs.length; i++)
+ {
+ certs[i] = new X509CertificateHolder(Certificate.getInstance(s.getObjectAt(i)));
+ }
+
+ return certs;
+ }
+
+ return OCSPUtils.EMPTY_CERTS;
+ }
+ else
+ {
+ return OCSPUtils.EMPTY_CERTS;
+ }
+ }
+
+ /**
+ * verify the signature against the tbsResponseData object we contain.
+ */
+ public boolean isSignatureValid(
+ ContentVerifierProvider verifierProvider)
+ throws OCSPException
+ {
+ try
+ {
+ ContentVerifier verifier = verifierProvider.get(resp.getSignatureAlgorithm());
+ OutputStream vOut = verifier.getOutputStream();
+
+ vOut.write(resp.getTbsResponseData().getEncoded(ASN1Encoding.DER));
+ vOut.close();
+
+ return verifier.verify(this.getSignature());
+ }
+ catch (Exception e)
+ {
+ throw new OCSPException("exception processing sig: " + e, e);
+ }
+ }
+
+ /**
+ * return the ASN.1 encoded representation of this object.
+ */
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return resp.getEncoded();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof BasicOCSPResp))
+ {
+ return false;
+ }
+
+ BasicOCSPResp r = (BasicOCSPResp)o;
+
+ return resp.equals(r.resp);
+ }
+
+ public int hashCode()
+ {
+ return resp.hashCode();
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java
new file mode 100644
index 0000000..988b852
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java
@@ -0,0 +1,285 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERGeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.ocsp.BasicOCSPResponse;
+import com.android.internal.org.bouncycastle.asn1.ocsp.CertStatus;
+import com.android.internal.org.bouncycastle.asn1.ocsp.ResponseData;
+import com.android.internal.org.bouncycastle.asn1.ocsp.RevokedInfo;
+import com.android.internal.org.bouncycastle.asn1.ocsp.SingleResponse;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLReason;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.operator.ContentSigner;
+import com.android.internal.org.bouncycastle.operator.DigestCalculator;
+
+/**
+ * Generator for basic OCSP response objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BasicOCSPRespBuilder
+{
+ private List list = new ArrayList();
+ private Extensions responseExtensions = null;
+ private RespID responderID;
+
+ private static class ResponseObject
+ {
+ CertificateID certId;
+ CertStatus certStatus;
+ ASN1GeneralizedTime thisUpdate;
+ ASN1GeneralizedTime nextUpdate;
+ Extensions extensions;
+
+ public ResponseObject(
+ CertificateID certId,
+ CertificateStatus certStatus,
+ Date thisUpdate,
+ Date nextUpdate,
+ Extensions extensions)
+ {
+ this.certId = certId;
+
+ if (certStatus == null)
+ {
+ this.certStatus = new CertStatus();
+ }
+ else if (certStatus instanceof UnknownStatus)
+ {
+ this.certStatus = new CertStatus(2, DERNull.INSTANCE);
+ }
+ else
+ {
+ RevokedStatus rs = (RevokedStatus)certStatus;
+
+ if (rs.hasRevocationReason())
+ {
+ this.certStatus = new CertStatus(
+ new RevokedInfo(new ASN1GeneralizedTime(rs.getRevocationTime()), CRLReason.lookup(rs.getRevocationReason())));
+ }
+ else
+ {
+ this.certStatus = new CertStatus(
+ new RevokedInfo(new ASN1GeneralizedTime(rs.getRevocationTime()), null));
+ }
+ }
+
+ this.thisUpdate = new DERGeneralizedTime(thisUpdate);
+
+ if (nextUpdate != null)
+ {
+ this.nextUpdate = new DERGeneralizedTime(nextUpdate);
+ }
+ else
+ {
+ this.nextUpdate = null;
+ }
+
+ this.extensions = extensions;
+ }
+
+ public SingleResponse toResponse()
+ throws Exception
+ {
+ return new SingleResponse(certId.toASN1Primitive(), certStatus, thisUpdate, nextUpdate, extensions);
+ }
+ }
+
+ /**
+ * basic constructor
+ */
+ public BasicOCSPRespBuilder(
+ RespID responderID)
+ {
+ this.responderID = responderID;
+ }
+
+ /**
+ * construct with the responderID to be the SHA-1 keyHash of the passed in public key.
+ *
+ * @param key the key info of the responder public key.
+ * @param digCalc a SHA-1 digest calculator
+ */
+ public BasicOCSPRespBuilder(
+ SubjectPublicKeyInfo key,
+ DigestCalculator digCalc)
+ throws OCSPException
+ {
+ this.responderID = new RespID(key, digCalc);
+ }
+
+ /**
+ * Add a response for a particular Certificate ID.
+ *
+ * @param certID certificate ID details
+ * @param certStatus status of the certificate - null if okay
+ */
+ public BasicOCSPRespBuilder addResponse(
+ CertificateID certID,
+ CertificateStatus certStatus)
+ {
+ this.addResponse(certID, certStatus, new Date(), null, null);
+
+ return this;
+ }
+
+ /**
+ * Add a response for a particular Certificate ID.
+ *
+ * @param certID certificate ID details
+ * @param certStatus status of the certificate - null if okay
+ * @param singleExtensions optional extensions
+ */
+ public BasicOCSPRespBuilder addResponse(
+ CertificateID certID,
+ CertificateStatus certStatus,
+ Extensions singleExtensions)
+ {
+ this.addResponse(certID, certStatus, new Date(), null, singleExtensions);
+
+ return this;
+ }
+
+ /**
+ * Add a response for a particular Certificate ID.
+ *
+ * @param certID certificate ID details
+ * @param nextUpdate date when next update should be requested
+ * @param certStatus status of the certificate - null if okay
+ * @param singleExtensions optional extensions
+ */
+ public BasicOCSPRespBuilder addResponse(
+ CertificateID certID,
+ CertificateStatus certStatus,
+ Date nextUpdate,
+ Extensions singleExtensions)
+ {
+ this.addResponse(certID, certStatus, new Date(), nextUpdate, singleExtensions);
+
+ return this;
+ }
+
+ /**
+ * Add a response for a particular Certificate ID.
+ *
+ * @param certID certificate ID details
+ * @param thisUpdate date this response was valid on
+ * @param nextUpdate date when next update should be requested
+ * @param certStatus status of the certificate - null if okay
+ */
+ public BasicOCSPRespBuilder addResponse(
+ CertificateID certID,
+ CertificateStatus certStatus,
+ Date thisUpdate,
+ Date nextUpdate)
+ {
+ this.addResponse(certID, certStatus, thisUpdate, nextUpdate, null);
+
+ return this;
+ }
+
+ /**
+ * Add a response for a particular Certificate ID.
+ *
+ * @param certID certificate ID details
+ * @param thisUpdate date this response was valid on
+ * @param nextUpdate date when next update should be requested
+ * @param certStatus status of the certificate - null if okay
+ * @param singleExtensions optional extensions
+ */
+ public BasicOCSPRespBuilder addResponse(
+ CertificateID certID,
+ CertificateStatus certStatus,
+ Date thisUpdate,
+ Date nextUpdate,
+ Extensions singleExtensions)
+ {
+ list.add(new ResponseObject(certID, certStatus, thisUpdate, nextUpdate, singleExtensions));
+
+ return this;
+ }
+
+ /**
+ * Set the extensions for the response.
+ *
+ * @param responseExtensions the extension object to carry.
+ */
+ public BasicOCSPRespBuilder setResponseExtensions(
+ Extensions responseExtensions)
+ {
+ this.responseExtensions = responseExtensions;
+
+ return this;
+ }
+
+ public BasicOCSPResp build(
+ ContentSigner signer,
+ X509CertificateHolder[] chain,
+ Date producedAt)
+ throws OCSPException
+ {
+ Iterator it = list.iterator();
+
+ ASN1EncodableVector responses = new ASN1EncodableVector();
+
+ while (it.hasNext())
+ {
+ try
+ {
+ responses.add(((ResponseObject)it.next()).toResponse());
+ }
+ catch (Exception e)
+ {
+ throw new OCSPException("exception creating Request", e);
+ }
+ }
+
+ ResponseData tbsResp = new ResponseData(responderID.toASN1Primitive(), new ASN1GeneralizedTime(producedAt), new DERSequence(responses), responseExtensions);
+ DERBitString bitSig;
+
+ try
+ {
+ OutputStream sigOut = signer.getOutputStream();
+
+ sigOut.write(tbsResp.getEncoded(ASN1Encoding.DER));
+ sigOut.close();
+
+ bitSig = new DERBitString(signer.getSignature());
+ }
+ catch (Exception e)
+ {
+ throw new OCSPException("exception processing TBSRequest: " + e.getMessage(), e);
+ }
+
+ AlgorithmIdentifier sigAlgId = signer.getAlgorithmIdentifier();
+
+ DERSequence chainSeq = null;
+ if (chain != null && chain.length > 0)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != chain.length; i++)
+ {
+ v.add(chain[i].toASN1Structure());
+ }
+
+ chainSeq = new DERSequence(v);
+ }
+
+ return new BasicOCSPResp(new BasicOCSPResponse(tbsResp, sigAlgId, bitSig, chainSeq));
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/CertificateID.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/CertificateID.java
new file mode 100644
index 0000000..611aae6
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/CertificateID.java
@@ -0,0 +1,160 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.io.OutputStream;
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.ocsp.CertID;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.operator.DigestCalculator;
+import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider;
+import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertificateID
+{
+ public static final AlgorithmIdentifier HASH_SHA1 = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
+
+ private final CertID id;
+
+ public CertificateID(
+ CertID id)
+ {
+ if (id == null)
+ {
+ throw new IllegalArgumentException("'id' cannot be null");
+ }
+ this.id = id;
+ }
+
+ /**
+ * create from an issuer certificate and the serial number of the
+ * certificate it signed.
+ *
+ * @param issuerCert issuing certificate
+ * @param number serial number
+ *
+ * @exception OCSPException if any problems occur creating the id fields.
+ */
+ public CertificateID(
+ DigestCalculator digestCalculator, X509CertificateHolder issuerCert,
+ BigInteger number)
+ throws OCSPException
+ {
+ this.id = createCertID(digestCalculator, issuerCert, new ASN1Integer(number));
+ }
+
+ public ASN1ObjectIdentifier getHashAlgOID()
+ {
+ return id.getHashAlgorithm().getAlgorithm();
+ }
+
+ public byte[] getIssuerNameHash()
+ {
+ return id.getIssuerNameHash().getOctets();
+ }
+
+ public byte[] getIssuerKeyHash()
+ {
+ return id.getIssuerKeyHash().getOctets();
+ }
+
+ /**
+ * return the serial number for the certificate associated
+ * with this request.
+ */
+ public BigInteger getSerialNumber()
+ {
+ return id.getSerialNumber().getValue();
+ }
+
+ public boolean matchesIssuer(X509CertificateHolder issuerCert, DigestCalculatorProvider digCalcProvider)
+ throws OCSPException
+ {
+ try
+ {
+ return createCertID(digCalcProvider.get(id.getHashAlgorithm()), issuerCert, id.getSerialNumber()).equals(id);
+ }
+ catch (OperatorCreationException e)
+ {
+ throw new OCSPException("unable to create digest calculator: " + e.getMessage(), e);
+ }
+ }
+
+ public CertID toASN1Primitive()
+ {
+ return id;
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof CertificateID))
+ {
+ return false;
+ }
+
+ CertificateID obj = (CertificateID)o;
+
+ return id.toASN1Primitive().equals(obj.id.toASN1Primitive());
+ }
+
+ public int hashCode()
+ {
+ return id.toASN1Primitive().hashCode();
+ }
+
+ /**
+ * Create a new CertificateID for a new serial number derived from a previous one
+ * calculated for the same CA certificate.
+ *
+ * @param original the previously calculated CertificateID for the CA.
+ * @param newSerialNumber the serial number for the new certificate of interest.
+ *
+ * @return a new CertificateID for newSerialNumber
+ */
+ public static CertificateID deriveCertificateID(CertificateID original, BigInteger newSerialNumber)
+ {
+ return new CertificateID(new CertID(original.id.getHashAlgorithm(), original.id.getIssuerNameHash(), original.id.getIssuerKeyHash(), new ASN1Integer(newSerialNumber)));
+ }
+
+ private static CertID createCertID(DigestCalculator digCalc, X509CertificateHolder issuerCert, ASN1Integer serialNumber)
+ throws OCSPException
+ {
+ try
+ {
+ OutputStream dgOut = digCalc.getOutputStream();
+
+ dgOut.write(issuerCert.toASN1Structure().getSubject().getEncoded(ASN1Encoding.DER));
+ dgOut.close();
+
+ ASN1OctetString issuerNameHash = new DEROctetString(digCalc.getDigest());
+
+ SubjectPublicKeyInfo info = issuerCert.getSubjectPublicKeyInfo();
+
+ dgOut = digCalc.getOutputStream();
+
+ dgOut.write(info.getPublicKeyData().getBytes());
+ dgOut.close();
+
+ ASN1OctetString issuerKeyHash = new DEROctetString(digCalc.getDigest());
+
+ return new CertID(digCalc.getAlgorithmIdentifier(), issuerNameHash, issuerKeyHash, serialNumber);
+ }
+ catch (Exception e)
+ {
+ throw new OCSPException("problem creating ID: " + e, e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/CertificateStatus.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/CertificateStatus.java
new file mode 100644
index 0000000..84321c8
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/CertificateStatus.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CertificateStatus
+{
+ public static final CertificateStatus GOOD = null;
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPException.java
new file mode 100644
index 0000000..c7cee8d
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPException.java
@@ -0,0 +1,31 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OCSPException
+ extends Exception
+{
+ private Throwable cause;
+
+ public OCSPException(
+ String name)
+ {
+ super(name);
+ }
+
+ public OCSPException(
+ String name,
+ Throwable cause)
+ {
+ super(name);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPReq.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPReq.java
new file mode 100644
index 0000000..14f1eab
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPReq.java
@@ -0,0 +1,255 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Exception;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OutputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ocsp.OCSPRequest;
+import com.android.internal.org.bouncycastle.asn1.ocsp.Request;
+import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.internal.org.bouncycastle.cert.CertIOException;
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.operator.ContentVerifier;
+import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider;
+
+/**
+ * <pre>
+ * OCSPRequest ::= SEQUENCE {
+ * tbsRequest TBSRequest,
+ * optionalSignature [0] EXPLICIT Signature OPTIONAL }
+ *
+ * TBSRequest ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * requestorName [1] EXPLICIT GeneralName OPTIONAL,
+ * requestList SEQUENCE OF Request,
+ * requestExtensions [2] EXPLICIT Extensions OPTIONAL }
+ *
+ * Signature ::= SEQUENCE {
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
+ *
+ * Version ::= INTEGER { v1(0) }
+ *
+ * Request ::= SEQUENCE {
+ * reqCert CertID,
+ * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
+ *
+ * CertID ::= SEQUENCE {
+ * hashAlgorithm AlgorithmIdentifier,
+ * issuerNameHash OCTET STRING, -- Hash of Issuer's DN
+ * issuerKeyHash OCTET STRING, -- Hash of Issuers public key
+ * serialNumber CertificateSerialNumber }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OCSPReq
+{
+ private static final X509CertificateHolder[] EMPTY_CERTS = new X509CertificateHolder[0];
+
+ private OCSPRequest req;
+ private Extensions extensions;
+
+ public OCSPReq(
+ OCSPRequest req)
+ {
+ this.req = req;
+ this.extensions = req.getTbsRequest().getRequestExtensions();
+ }
+
+ public OCSPReq(
+ byte[] req)
+ throws IOException
+ {
+ this(new ASN1InputStream(req));
+ }
+
+ private OCSPReq(
+ ASN1InputStream aIn)
+ throws IOException
+ {
+ try
+ {
+ this.req = OCSPRequest.getInstance(aIn.readObject());
+ if (req == null)
+ {
+ throw new CertIOException("malformed request: no request data found");
+ }
+ this.extensions = req.getTbsRequest().getRequestExtensions();
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new CertIOException("malformed request: " + e.getMessage(), e);
+ }
+ catch (ClassCastException e)
+ {
+ throw new CertIOException("malformed request: " + e.getMessage(), e);
+ }
+ catch (ASN1Exception e)
+ {
+ throw new CertIOException("malformed request: " + e.getMessage(), e);
+ }
+ }
+
+ public int getVersionNumber()
+ {
+ return req.getTbsRequest().getVersion().intValueExact() + 1;
+ }
+
+ public GeneralName getRequestorName()
+ {
+ return GeneralName.getInstance(req.getTbsRequest().getRequestorName());
+ }
+
+ public Req[] getRequestList()
+ {
+ ASN1Sequence seq = req.getTbsRequest().getRequestList();
+ Req[] requests = new Req[seq.size()];
+
+ for (int i = 0; i != requests.length; i++)
+ {
+ requests[i] = new Req(Request.getInstance(seq.getObjectAt(i)));
+ }
+
+ return requests;
+ }
+
+ public boolean hasExtensions()
+ {
+ return extensions != null;
+ }
+
+ public Extension getExtension(ASN1ObjectIdentifier oid)
+ {
+ if (extensions != null)
+ {
+ return extensions.getExtension(oid);
+ }
+
+ return null;
+ }
+
+ public List getExtensionOIDs()
+ {
+ return OCSPUtils.getExtensionOIDs(extensions);
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ return OCSPUtils.getCriticalExtensionOIDs(extensions);
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return OCSPUtils.getNonCriticalExtensionOIDs(extensions);
+ }
+
+ /**
+ * return the object identifier representing the signature algorithm
+ */
+ public ASN1ObjectIdentifier getSignatureAlgOID()
+ {
+ if (!this.isSigned())
+ {
+ return null;
+ }
+
+ return req.getOptionalSignature().getSignatureAlgorithm().getAlgorithm();
+ }
+
+ public byte[] getSignature()
+ {
+ if (!this.isSigned())
+ {
+ return null;
+ }
+
+ return req.getOptionalSignature().getSignature().getOctets();
+ }
+
+ public X509CertificateHolder[] getCerts()
+ {
+ //
+ // load the certificates if we have any
+ //
+ if (req.getOptionalSignature() != null)
+ {
+ ASN1Sequence s = req.getOptionalSignature().getCerts();
+
+ if (s != null)
+ {
+ X509CertificateHolder[] certs = new X509CertificateHolder[s.size()];
+
+ for (int i = 0; i != certs.length; i++)
+ {
+ certs[i] = new X509CertificateHolder(Certificate.getInstance(s.getObjectAt(i)));
+ }
+
+ return certs;
+ }
+
+ return EMPTY_CERTS;
+ }
+ else
+ {
+ return EMPTY_CERTS;
+ }
+ }
+
+ /**
+ * Return whether or not this request is signed.
+ *
+ * @return true if signed false otherwise.
+ */
+ public boolean isSigned()
+ {
+ return req.getOptionalSignature() != null;
+ }
+
+ /**
+ * verify the signature against the TBSRequest object we contain.
+ */
+ public boolean isSignatureValid(
+ ContentVerifierProvider verifierProvider)
+ throws OCSPException
+ {
+ if (!this.isSigned())
+ {
+ throw new OCSPException("attempt to verify signature on unsigned object");
+ }
+
+ try
+ {
+ ContentVerifier verifier = verifierProvider.get(req.getOptionalSignature().getSignatureAlgorithm());
+ OutputStream sOut = verifier.getOutputStream();
+
+ sOut.write(req.getTbsRequest().getEncoded(ASN1Encoding.DER));
+
+ return verifier.verify(this.getSignature());
+ }
+ catch (Exception e)
+ {
+ throw new OCSPException("exception processing signature: " + e, e);
+ }
+ }
+
+ /**
+ * return the ASN.1 encoded representation of this object.
+ */
+ public byte[] getEncoded() throws IOException
+ {
+ return req.getEncoded();
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java
new file mode 100644
index 0000000..428ccb7
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java
@@ -0,0 +1,203 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.ocsp.OCSPRequest;
+import com.android.internal.org.bouncycastle.asn1.ocsp.Request;
+import com.android.internal.org.bouncycastle.asn1.ocsp.Signature;
+import com.android.internal.org.bouncycastle.asn1.ocsp.TBSRequest;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.operator.ContentSigner;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OCSPReqBuilder
+{
+ private List list = new ArrayList();
+ private GeneralName requestorName = null;
+ private Extensions requestExtensions = null;
+
+ private static class RequestObject
+ {
+ CertificateID certId;
+ Extensions extensions;
+
+ public RequestObject(
+ CertificateID certId,
+ Extensions extensions)
+ {
+ this.certId = certId;
+ this.extensions = extensions;
+ }
+
+ public Request toRequest()
+ throws Exception
+ {
+ return new Request(certId.toASN1Primitive(), extensions);
+ }
+ }
+
+ /**
+ * Add a request for the given CertificateID.
+ *
+ * @param certId certificate ID of interest
+ */
+ public OCSPReqBuilder addRequest(
+ CertificateID certId)
+ {
+ list.add(new RequestObject(certId, null));
+
+ return this;
+ }
+
+ /**
+ * Add a request with extensions
+ *
+ * @param certId certificate ID of interest
+ * @param singleRequestExtensions the extensions to attach to the request
+ */
+ public OCSPReqBuilder addRequest(
+ CertificateID certId,
+ Extensions singleRequestExtensions)
+ {
+ list.add(new RequestObject(certId, singleRequestExtensions));
+
+ return this;
+ }
+
+ /**
+ * Set the requestor name to the passed in X500Name
+ *
+ * @param requestorName an X500Name representing the requestor name.
+ */
+ public OCSPReqBuilder setRequestorName(
+ X500Name requestorName)
+ {
+ this.requestorName = new GeneralName(GeneralName.directoryName, requestorName);
+
+ return this;
+ }
+
+ public OCSPReqBuilder setRequestorName(
+ GeneralName requestorName)
+ {
+ this.requestorName = requestorName;
+
+ return this;
+ }
+
+ public OCSPReqBuilder setRequestExtensions(
+ Extensions requestExtensions)
+ {
+ this.requestExtensions = requestExtensions;
+
+ return this;
+ }
+
+ private OCSPReq generateRequest(
+ ContentSigner contentSigner,
+ X509CertificateHolder[] chain)
+ throws OCSPException
+ {
+ Iterator it = list.iterator();
+
+ ASN1EncodableVector requests = new ASN1EncodableVector();
+
+ while (it.hasNext())
+ {
+ try
+ {
+ requests.add(((RequestObject)it.next()).toRequest());
+ }
+ catch (Exception e)
+ {
+ throw new OCSPException("exception creating Request", e);
+ }
+ }
+
+ TBSRequest tbsReq = new TBSRequest(requestorName, new DERSequence(requests), requestExtensions);
+
+ Signature signature = null;
+
+ if (contentSigner != null)
+ {
+ if (requestorName == null)
+ {
+ throw new OCSPException("requestorName must be specified if request is signed.");
+ }
+
+ try
+ {
+ OutputStream sOut = contentSigner.getOutputStream();
+
+ sOut.write(tbsReq.getEncoded(ASN1Encoding.DER));
+
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new OCSPException("exception processing TBSRequest: " + e, e);
+ }
+
+ DERBitString bitSig = new DERBitString(contentSigner.getSignature());
+
+ AlgorithmIdentifier sigAlgId = contentSigner.getAlgorithmIdentifier();
+
+ if (chain != null && chain.length > 0)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != chain.length; i++)
+ {
+ v.add(chain[i].toASN1Structure());
+ }
+
+ signature = new Signature(sigAlgId, bitSig, new DERSequence(v));
+ }
+ else
+ {
+ signature = new Signature(sigAlgId, bitSig);
+ }
+ }
+
+ return new OCSPReq(new OCSPRequest(tbsReq, signature));
+ }
+
+ /**
+ * Generate an unsigned request
+ *
+ * @return the OCSPReq
+ * @throws com.android.internal.org.bouncycastle.cert.ocsp.OCSPException
+ */
+ public OCSPReq build()
+ throws OCSPException
+ {
+ return generateRequest(null, null);
+ }
+
+ public OCSPReq build(
+ ContentSigner signer,
+ X509CertificateHolder[] chain)
+ throws OCSPException, IllegalArgumentException
+ {
+ if (signer == null)
+ {
+ throw new IllegalArgumentException("no signer specified");
+ }
+
+ return generateRequest(signer, chain);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPResp.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPResp.java
new file mode 100644
index 0000000..7293e66
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPResp.java
@@ -0,0 +1,145 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Exception;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ocsp.BasicOCSPResponse;
+import com.android.internal.org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.ocsp.OCSPResponse;
+import com.android.internal.org.bouncycastle.asn1.ocsp.ResponseBytes;
+import com.android.internal.org.bouncycastle.cert.CertIOException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OCSPResp
+{
+ public static final int SUCCESSFUL = 0; // Response has valid confirmations
+ public static final int MALFORMED_REQUEST = 1; // Illegal confirmation request
+ public static final int INTERNAL_ERROR = 2; // Internal error in issuer
+ public static final int TRY_LATER = 3; // Try again later
+ // (4) is not used
+ public static final int SIG_REQUIRED = 5; // Must sign the request
+ public static final int UNAUTHORIZED = 6; // Request unauthorized
+
+ private OCSPResponse resp;
+
+ public OCSPResp(
+ OCSPResponse resp)
+ {
+ this.resp = resp;
+ }
+
+ public OCSPResp(
+ byte[] resp)
+ throws IOException
+ {
+ this(new ByteArrayInputStream(resp));
+ }
+
+ public OCSPResp(
+ InputStream resp)
+ throws IOException
+ {
+ this(new ASN1InputStream(resp));
+ }
+
+ private OCSPResp(
+ ASN1InputStream aIn)
+ throws IOException
+ {
+ try
+ {
+ this.resp = OCSPResponse.getInstance(aIn.readObject());
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new CertIOException("malformed response: " + e.getMessage(), e);
+ }
+ catch (ClassCastException e)
+ {
+ throw new CertIOException("malformed response: " + e.getMessage(), e);
+ }
+ catch (ASN1Exception e)
+ {
+ throw new CertIOException("malformed response: " + e.getMessage(), e);
+ }
+
+ if (resp == null)
+ {
+ throw new CertIOException("malformed response: no response data found");
+ }
+ }
+
+ public int getStatus()
+ {
+ return this.resp.getResponseStatus().getIntValue();
+ }
+
+ public Object getResponseObject()
+ throws OCSPException
+ {
+ ResponseBytes rb = this.resp.getResponseBytes();
+
+ if (rb == null)
+ {
+ return null;
+ }
+
+ if (rb.getResponseType().equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic))
+ {
+ try
+ {
+ ASN1Primitive obj = ASN1Primitive.fromByteArray(rb.getResponse().getOctets());
+ return new BasicOCSPResp(BasicOCSPResponse.getInstance(obj));
+ }
+ catch (Exception e)
+ {
+ throw new OCSPException("problem decoding object: " + e, e);
+ }
+ }
+
+ return rb.getResponse();
+ }
+
+ /**
+ * return the ASN.1 encoded representation of this object.
+ */
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return resp.getEncoded();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof OCSPResp))
+ {
+ return false;
+ }
+
+ OCSPResp r = (OCSPResp)o;
+
+ return resp.equals(r.resp);
+ }
+
+ public int hashCode()
+ {
+ return resp.hashCode();
+ }
+
+ public OCSPResponse toASN1Structure()
+ {
+ return resp;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPRespBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPRespBuilder.java
new file mode 100644
index 0000000..9ba31fa
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPRespBuilder.java
@@ -0,0 +1,61 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.ocsp.OCSPResponse;
+import com.android.internal.org.bouncycastle.asn1.ocsp.OCSPResponseStatus;
+import com.android.internal.org.bouncycastle.asn1.ocsp.ResponseBytes;
+
+/**
+ * base generator for an OCSP response - at the moment this only supports the
+ * generation of responses containing BasicOCSP responses.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OCSPRespBuilder
+{
+ public static final int SUCCESSFUL = 0; // Response has valid confirmations
+ public static final int MALFORMED_REQUEST = 1; // Illegal confirmation request
+ public static final int INTERNAL_ERROR = 2; // Internal error in issuer
+ public static final int TRY_LATER = 3; // Try again later
+ // (4) is not used
+ public static final int SIG_REQUIRED = 5; // Must sign the request
+ public static final int UNAUTHORIZED = 6; // Request unauthorized
+
+ public OCSPResp build(
+ int status,
+ Object response)
+ throws OCSPException
+ {
+ if (response == null)
+ {
+ return new OCSPResp(new OCSPResponse(new OCSPResponseStatus(status), null));
+ }
+
+ if (response instanceof BasicOCSPResp)
+ {
+ BasicOCSPResp r = (BasicOCSPResp)response;
+ ASN1OctetString octs;
+
+ try
+ {
+ octs = new DEROctetString(r.getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new OCSPException("can't encode object.", e);
+ }
+
+ ResponseBytes rb = new ResponseBytes(
+ OCSPObjectIdentifiers.id_pkix_ocsp_basic, octs);
+
+ return new OCSPResp(new OCSPResponse(
+ new OCSPResponseStatus(status), rb));
+ }
+
+ throw new OCSPException("unknown response object");
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPUtils.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPUtils.java
new file mode 100644
index 0000000..320ec85
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/OCSPUtils.java
@@ -0,0 +1,65 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+
+class OCSPUtils
+{
+ static final X509CertificateHolder[] EMPTY_CERTS = new X509CertificateHolder[0];
+
+ static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet());
+ static List EMPTY_LIST = Collections.unmodifiableList(new ArrayList());
+
+ static Date extractDate(ASN1GeneralizedTime time)
+ {
+ try
+ {
+ return time.getDate();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("exception processing GeneralizedTime: " + e.getMessage());
+ }
+ }
+
+ static Set getCriticalExtensionOIDs(Extensions extensions)
+ {
+ if (extensions == null)
+ {
+ return EMPTY_SET;
+ }
+
+ return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getCriticalExtensionOIDs())));
+ }
+
+ static Set getNonCriticalExtensionOIDs(Extensions extensions)
+ {
+ if (extensions == null)
+ {
+ return EMPTY_SET;
+ }
+
+ // TODO: should probably produce a set that imposes correct ordering
+ return Collections.unmodifiableSet(new HashSet(Arrays.asList(extensions.getNonCriticalExtensionOIDs())));
+ }
+
+ static List getExtensionOIDs(Extensions extensions)
+ {
+ if (extensions == null)
+ {
+ return EMPTY_LIST;
+ }
+
+ return Collections.unmodifiableList(Arrays.asList(extensions.getExtensionOIDs()));
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/Req.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/Req.java
new file mode 100644
index 0000000..df884fe
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/Req.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ocsp.Request;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Req
+{
+ private Request req;
+
+ public Req(
+ Request req)
+ {
+ this.req = req;
+ }
+
+ public CertificateID getCertID()
+ {
+ return new CertificateID(req.getReqCert());
+ }
+
+ public Extensions getSingleRequestExtensions()
+ {
+ return req.getSingleRequestExtensions();
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/RespData.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/RespData.java
new file mode 100644
index 0000000..1e39a39
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/RespData.java
@@ -0,0 +1,65 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.util.Date;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ocsp.ResponseData;
+import com.android.internal.org.bouncycastle.asn1.ocsp.SingleResponse;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * ResponseData ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * responderID ResponderID,
+ * producedAt GeneralizedTime,
+ * responses SEQUENCE OF SingleResponse,
+ * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RespData
+{
+ private ResponseData data;
+
+ public RespData(
+ ResponseData data)
+ {
+ this.data = data;
+ }
+
+ public int getVersion()
+ {
+ return data.getVersion().intValueExact() + 1;
+ }
+
+ public RespID getResponderId()
+ {
+ return new RespID(data.getResponderID());
+ }
+
+ public Date getProducedAt()
+ {
+ return OCSPUtils.extractDate(data.getProducedAt());
+ }
+
+ public SingleResp[] getResponses()
+ {
+ ASN1Sequence s = data.getResponses();
+ SingleResp[] rs = new SingleResp[s.size()];
+
+ for (int i = 0; i != rs.length; i++)
+ {
+ rs[i] = new SingleResp(SingleResponse.getInstance(s.getObjectAt(i)));
+ }
+
+ return rs;
+ }
+
+ public Extensions getResponseExtensions()
+ {
+ return data.getResponseExtensions();
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/RespID.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/RespID.java
new file mode 100644
index 0000000..82d0ebb
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/RespID.java
@@ -0,0 +1,91 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.ocsp.ResponderID;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.operator.DigestCalculator;
+
+/**
+ * Carrier for a ResponderID.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RespID
+{
+ public static final AlgorithmIdentifier HASH_SHA1 = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
+
+ ResponderID id;
+
+ public RespID(
+ ResponderID id)
+ {
+ this.id = id;
+ }
+
+ public RespID(
+ X500Name name)
+ {
+ this.id = new ResponderID(name);
+ }
+
+ /**
+ * Calculate a RespID based on the public key of the responder.
+ *
+ * @param subjectPublicKeyInfo the info structure for the responder public key.
+ * @param digCalc a SHA-1 digest calculator.
+ * @throws OCSPException on exception creating ID.
+ */
+ public RespID(
+ SubjectPublicKeyInfo subjectPublicKeyInfo,
+ DigestCalculator digCalc)
+ throws OCSPException
+ {
+ try
+ {
+ if (!digCalc.getAlgorithmIdentifier().equals(HASH_SHA1))
+ {
+ throw new IllegalArgumentException("only SHA-1 can be used with RespID - found: " + digCalc.getAlgorithmIdentifier().getAlgorithm());
+ }
+
+ OutputStream digOut = digCalc.getOutputStream();
+
+ digOut.write(subjectPublicKeyInfo.getPublicKeyData().getBytes());
+ digOut.close();
+
+ this.id = new ResponderID(new DEROctetString(digCalc.getDigest()));
+ }
+ catch (Exception e)
+ {
+ throw new OCSPException("problem creating ID: " + e, e);
+ }
+ }
+
+ public ResponderID toASN1Primitive()
+ {
+ return id;
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof RespID))
+ {
+ return false;
+ }
+
+ RespID obj = (RespID)o;
+
+ return id.equals(obj.id);
+ }
+
+ public int hashCode()
+ {
+ return id.hashCode();
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/RevokedStatus.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/RevokedStatus.java
new file mode 100644
index 0000000..b383892
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/RevokedStatus.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.util.Date;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ocsp.RevokedInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLReason;
+
+/**
+ * wrapper for the RevokedInfo object
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RevokedStatus
+ implements CertificateStatus
+{
+ RevokedInfo info;
+
+ public RevokedStatus(
+ RevokedInfo info)
+ {
+ this.info = info;
+ }
+
+ public RevokedStatus(Date revocationDate)
+ {
+ this.info = new RevokedInfo(new ASN1GeneralizedTime(revocationDate));
+ }
+
+ public RevokedStatus(
+ Date revocationDate,
+ int reason)
+ {
+ this.info = new RevokedInfo(new ASN1GeneralizedTime(revocationDate), CRLReason.lookup(reason));
+ }
+
+ public Date getRevocationTime()
+ {
+ return OCSPUtils.extractDate(info.getRevocationTime());
+ }
+
+ public boolean hasRevocationReason()
+ {
+ return (info.getRevocationReason() != null);
+ }
+
+ /**
+ * return the revocation reason. Note: this field is optional, test for it
+ * with hasRevocationReason() first.
+ * @return the revocation reason value.
+ * @exception IllegalStateException if a reason is asked for and none is avaliable
+ */
+ public int getRevocationReason()
+ {
+ if (info.getRevocationReason() == null)
+ {
+ throw new IllegalStateException("attempt to get a reason where none is available");
+ }
+
+ return info.getRevocationReason().getValue().intValue();
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/SingleResp.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/SingleResp.java
new file mode 100644
index 0000000..a328c1b
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/SingleResp.java
@@ -0,0 +1,106 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ocsp.CertStatus;
+import com.android.internal.org.bouncycastle.asn1.ocsp.RevokedInfo;
+import com.android.internal.org.bouncycastle.asn1.ocsp.SingleResponse;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SingleResp
+{
+ private SingleResponse resp;
+ private Extensions extensions;
+
+ public SingleResp(
+ SingleResponse resp)
+ {
+ this.resp = resp;
+ this.extensions = resp.getSingleExtensions();
+ }
+
+ public CertificateID getCertID()
+ {
+ return new CertificateID(resp.getCertID());
+ }
+
+ /**
+ * Return the status object for the response - null indicates good.
+ *
+ * @return the status object for the response, null if it is good.
+ */
+ public CertificateStatus getCertStatus()
+ {
+ CertStatus s = resp.getCertStatus();
+
+ if (s.getTagNo() == 0)
+ {
+ return null; // good
+ }
+ else if (s.getTagNo() == 1)
+ {
+ return new RevokedStatus(RevokedInfo.getInstance(s.getStatus()));
+ }
+
+ return new UnknownStatus();
+ }
+
+ public Date getThisUpdate()
+ {
+ return OCSPUtils.extractDate(resp.getThisUpdate());
+ }
+
+ /**
+ * return the NextUpdate value - note: this is an optional field so may
+ * be returned as null.
+ *
+ * @return nextUpdate, or null if not present.
+ */
+ public Date getNextUpdate()
+ {
+ if (resp.getNextUpdate() == null)
+ {
+ return null;
+ }
+
+ return OCSPUtils.extractDate(resp.getNextUpdate());
+ }
+
+ public boolean hasExtensions()
+ {
+ return extensions != null;
+ }
+
+ public Extension getExtension(ASN1ObjectIdentifier oid)
+ {
+ if (extensions != null)
+ {
+ return extensions.getExtension(oid);
+ }
+
+ return null;
+ }
+
+ public List getExtensionOIDs()
+ {
+ return OCSPUtils.getExtensionOIDs(extensions);
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ return OCSPUtils.getCriticalExtensionOIDs(extensions);
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return OCSPUtils.getNonCriticalExtensionOIDs(extensions);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/UnknownStatus.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/UnknownStatus.java
new file mode 100644
index 0000000..229d191
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/UnknownStatus.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp;
+
+/**
+ * wrapper for the UnknownInfo object
+ * @hide This class is not part of the Android public SDK API
+ */
+public class UnknownStatus
+ implements CertificateStatus
+{
+ public UnknownStatus()
+ {
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java
new file mode 100644
index 0000000..30d769b
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp.jcajce;
+
+import java.security.PublicKey;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
+import com.android.internal.org.bouncycastle.cert.ocsp.OCSPException;
+import com.android.internal.org.bouncycastle.operator.DigestCalculator;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JcaBasicOCSPRespBuilder
+ extends BasicOCSPRespBuilder
+{
+ public JcaBasicOCSPRespBuilder(X500Principal principal)
+ {
+ super(new JcaRespID(principal));
+ }
+
+ public JcaBasicOCSPRespBuilder(PublicKey key, DigestCalculator digCalc)
+ throws OCSPException
+ {
+ super(SubjectPublicKeyInfo.getInstance(key.getEncoded()), digCalc);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/jcajce/JcaCertificateID.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/jcajce/JcaCertificateID.java
new file mode 100644
index 0000000..1497d7f
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/jcajce/JcaCertificateID.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import com.android.internal.org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
+import com.android.internal.org.bouncycastle.cert.ocsp.CertificateID;
+import com.android.internal.org.bouncycastle.cert.ocsp.OCSPException;
+import com.android.internal.org.bouncycastle.operator.DigestCalculator;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JcaCertificateID
+ extends CertificateID
+{
+ public JcaCertificateID(DigestCalculator digestCalculator, X509Certificate issuerCert, BigInteger number)
+ throws OCSPException, CertificateEncodingException
+ {
+ super(digestCalculator, new JcaX509CertificateHolder(issuerCert), number);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java
new file mode 100644
index 0000000..aabbac4
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.ocsp.jcajce;
+
+import java.security.PublicKey;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.cert.ocsp.OCSPException;
+import com.android.internal.org.bouncycastle.cert.ocsp.RespID;
+import com.android.internal.org.bouncycastle.operator.DigestCalculator;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JcaRespID
+ extends RespID
+{
+ public JcaRespID(X500Principal name)
+ {
+ super(X500Name.getInstance(name.getEncoded()));
+ }
+
+ public JcaRespID(PublicKey pubKey, DigestCalculator digCalc)
+ throws OCSPException
+ {
+ super(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), digCalc);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cmc/CMCException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cmc/CMCException.java
new file mode 100644
index 0000000..173c809
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cmc/CMCException.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cmc;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMCException
+ extends Exception
+{
+ private final Throwable cause;
+
+ public CMCException(String msg)
+ {
+ this(msg, null);
+ }
+
+ public CMCException(String msg, Throwable cause)
+ {
+ super(msg);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cmc/SimplePKIResponse.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cmc/SimplePKIResponse.java
new file mode 100644
index 0000000..a6a2fb2
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cmc/SimplePKIResponse.java
@@ -0,0 +1,108 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cmc;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.cms.ContentInfo;
+import com.android.internal.org.bouncycastle.cert.X509CRLHolder;
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.cms.CMSException;
+import com.android.internal.org.bouncycastle.cms.CMSSignedData;
+import com.android.internal.org.bouncycastle.util.Encodable;
+import com.android.internal.org.bouncycastle.util.Store;
+
+/**
+ * Carrier for a Simple PKI Response.
+ * <p>
+ * A Simple PKI Response is defined in RFC 5272 as a CMS SignedData object with no EncapsulatedContentInfo
+ * and no SignerInfos attached.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SimplePKIResponse
+ implements Encodable
+{
+ private final CMSSignedData certificateResponse;
+
+ private static ContentInfo parseBytes(byte[] responseEncoding)
+ throws CMCException
+ {
+ try
+ {
+ return ContentInfo.getInstance(ASN1Primitive.fromByteArray(responseEncoding));
+ }
+ catch (Exception e)
+ {
+ throw new CMCException("malformed data: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Create a SimplePKIResponse from the passed in bytes.
+ *
+ * @param responseEncoding BER/DER encoding of the certificate.
+ * @throws CMCException in the event of corrupted data, or an incorrect structure.
+ */
+ public SimplePKIResponse(byte[] responseEncoding)
+ throws CMCException
+ {
+ this(parseBytes(responseEncoding));
+ }
+
+ /**
+ * Create a SimplePKIResponse from the passed in ASN.1 structure.
+ *
+ * @param signedData a ContentInfo containing a SignedData.
+ */
+ public SimplePKIResponse(ContentInfo signedData)
+ throws CMCException
+ {
+ try
+ {
+ this.certificateResponse = new CMSSignedData(signedData);
+ }
+ catch (CMSException e)
+ {
+ throw new CMCException("malformed response: " + e.getMessage(), e);
+ }
+
+ if (certificateResponse.getSignerInfos().size() != 0)
+ {
+ throw new CMCException("malformed response: SignerInfo structures found");
+ }
+ if (certificateResponse.getSignedContent() != null)
+ {
+ throw new CMCException("malformed response: Signed Content found");
+ }
+ }
+
+ /**
+ * Return any X.509 certificate objects in this SimplePKIResponse structure as a Store of X509CertificateHolder objects.
+ *
+ * @return a Store of X509CertificateHolder objects.
+ */
+ public Store<X509CertificateHolder> getCertificates()
+ {
+ return certificateResponse.getCertificates();
+ }
+
+ /**
+ * Return any X.509 CRL objects in this SimplePKIResponse structure as a Store of X509CRLHolder objects.
+ *
+ * @return a Store of X509CRLHolder objects.
+ */
+ public Store<X509CRLHolder> getCRLs()
+ {
+ return certificateResponse.getCRLs();
+ }
+
+ /**
+ * return the ASN.1 encoded representation of this object.
+ */
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return certificateResponse.getEncoded();
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSPatchKit.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSPatchKit.java
new file mode 100644
index 0000000..883a68f
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSPatchKit.java
@@ -0,0 +1,73 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.cms.SignerInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * Toolkit methods for dealing with common errors in CMS
+ * classes.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMSPatchKit
+{
+ /**
+ * Create a SignerInformation based on original which uses definite-length
+ * rather than DER encoding for verifying the signature on the signed attributes.
+ *
+ * @param original the source SignerInformation
+ */
+ public static SignerInformation createNonDERSignerInfo(
+ SignerInformation original)
+ {
+ return new DLSignerInformation(original);
+ }
+
+ /**
+ * Create a SignerInformation based on original has it's signatureAlgorithm replaced
+ * with the passed in AlgorithmIdentifier.
+ *
+ * @param original the source SignerInformation
+ */
+ public static SignerInformation createWithSignatureAlgorithm(
+ SignerInformation original,
+ AlgorithmIdentifier signatureAlgorithm)
+ {
+ return new ModEncAlgSignerInformation(original, signatureAlgorithm);
+ }
+
+ private static class DLSignerInformation
+ extends SignerInformation
+ {
+ protected DLSignerInformation(SignerInformation baseInfo)
+ {
+ super(baseInfo);
+ }
+
+ public byte[] getEncodedSignedAttributes()
+ throws IOException
+ {
+ return signedAttributeSet.getEncoded(ASN1Encoding.DL);
+ }
+ }
+
+ private static class ModEncAlgSignerInformation
+ extends SignerInformation
+ {
+ protected ModEncAlgSignerInformation(
+ SignerInformation baseInfo,
+ AlgorithmIdentifier signatureAlgorithm)
+ {
+ super(baseInfo, editEncAlg(baseInfo.info, signatureAlgorithm));
+ }
+
+ private static SignerInfo editEncAlg(SignerInfo info, AlgorithmIdentifier signatureAlgorithm)
+ {
+ return new SignerInfo(info.getSID(), info.getDigestAlgorithm(), info.getAuthenticatedAttributes(),
+ signatureAlgorithm, info.getEncryptedDigest(), info.getUnauthenticatedAttributes());
+ }
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedData.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedData.java
index f42ea21..2cb9d8a 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedData.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedData.java
@@ -22,7 +22,6 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1Set;
import com.android.internal.org.bouncycastle.asn1.BERSequence;
-import com.android.internal.org.bouncycastle.asn1.DERSet;
import com.android.internal.org.bouncycastle.asn1.DLSet;
import com.android.internal.org.bouncycastle.asn1.cms.ContentInfo;
import com.android.internal.org.bouncycastle.asn1.cms.SignedData;
@@ -31,15 +30,17 @@
import com.android.internal.org.bouncycastle.cert.X509AttributeCertificateHolder;
import com.android.internal.org.bouncycastle.cert.X509CRLHolder;
import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import com.android.internal.org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
import com.android.internal.org.bouncycastle.util.Encodable;
import com.android.internal.org.bouncycastle.util.Store;
/**
* general class for handling a pkcs7-signature message.
- *
+ * <p>
* A simple example of usage - note, in the example below the validity of
- * the certificate isn't verified, just the fact that one of the certs
+ * the certificate isn't verified, just the fact that one of the certs
* matches the given signer...
*
* <pre>
@@ -47,7 +48,7 @@
* SignerInformationStore signers = s.getSignerInfos();
* Collection c = signers.getSigners();
* Iterator it = c.iterator();
- *
+ *
* while (it.hasNext())
* {
* SignerInformation signer = (SignerInformation)it.next();
@@ -55,11 +56,11 @@
*
* Iterator certIt = certCollection.iterator();
* X509CertificateHolder cert = (X509CertificateHolder)certIt.next();
- *
+ *
* if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)))
* {
* verified++;
- * }
+ * }
* }
* </pre>
* @hide This class is not part of the Android public SDK API
@@ -68,16 +69,18 @@
implements Encodable
{
private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE;
-
- SignedData signedData;
- ContentInfo contentInfo;
- CMSTypedData signedContent;
- SignerInformationStore signerInfoStore;
+ private static final DefaultDigestAlgorithmIdentifierFinder DIGEST_ALG_ID_FINDER =
+ new DefaultDigestAlgorithmIdentifierFinder();
- private Map hashes;
+ SignedData signedData;
+ ContentInfo contentInfo;
+ CMSTypedData signedContent;
+ SignerInformationStore signerInfoStore;
+
+ private Map hashes;
private CMSSignedData(
- CMSSignedData c)
+ CMSSignedData c)
{
this.signedData = c.signedData;
this.contentInfo = c.contentInfo;
@@ -86,15 +89,15 @@
}
public CMSSignedData(
- byte[] sigBlock)
+ byte[] sigBlock)
throws CMSException
{
this(CMSUtils.readContentInfo(sigBlock));
}
public CMSSignedData(
- CMSProcessable signedContent,
- byte[] sigBlock)
+ CMSProcessable signedContent,
+ byte[] sigBlock)
throws CMSException
{
this(signedContent, CMSUtils.readContentInfo(sigBlock));
@@ -103,12 +106,12 @@
/**
* Content with detached signature, digests precomputed
*
- * @param hashes a map of precomputed digests for content indexed by name of hash.
+ * @param hashes a map of precomputed digests for content indexed by name of hash.
* @param sigBlock the signature object.
*/
public CMSSignedData(
- Map hashes,
- byte[] sigBlock)
+ Map hashes,
+ byte[] sigBlock)
throws CMSException
{
this(hashes, CMSUtils.readContentInfo(sigBlock));
@@ -118,11 +121,11 @@
* base constructor - content with detached signature.
*
* @param signedContent the content that was signed.
- * @param sigData the signature object.
+ * @param sigData the signature object.
*/
public CMSSignedData(
- CMSProcessable signedContent,
- InputStream sigData)
+ CMSProcessable signedContent,
+ InputStream sigData)
throws CMSException
{
this(signedContent, CMSUtils.readContentInfo(new ASN1InputStream(sigData)));
@@ -139,8 +142,8 @@
}
public CMSSignedData(
- final CMSProcessable signedContent,
- ContentInfo sigData)
+ final CMSProcessable signedContent,
+ ContentInfo sigData)
throws CMSException
{
if (signedContent instanceof CMSTypedData)
@@ -174,8 +177,8 @@
}
public CMSSignedData(
- Map hashes,
- ContentInfo sigData)
+ Map hashes,
+ ContentInfo sigData)
throws CMSException
{
this.hashes = hashes;
@@ -246,8 +249,8 @@
{
if (signerInfoStore == null)
{
- ASN1Set s = signedData.getSignerInfos();
- List signerInfos = new ArrayList();
+ ASN1Set s = signedData.getSignerInfos();
+ List signerInfos = new ArrayList();
for (int i = 0; i != s.size(); i++)
{
@@ -330,7 +333,6 @@
* this SignedData structure.
*
* @param otherRevocationInfoFormat OID of the format type been looked for.
- *
* @return a Store of ASN1Encodable objects representing any objects of otherRevocationInfoFormat found.
*
public Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat)
@@ -347,9 +349,9 @@
*/
public Set<AlgorithmIdentifier> getDigestAlgorithmIDs()
{
- Set<AlgorithmIdentifier> digests = new HashSet<AlgorithmIdentifier>(signedData.getDigestAlgorithms().size());
+ Set<AlgorithmIdentifier> digests = new HashSet<AlgorithmIdentifier>();
- for (Enumeration en = signedData.getDigestAlgorithms().getObjects(); en.hasMoreElements();)
+ for (Enumeration en = signedData.getDigestAlgorithms().getObjects(); en.hasMoreElements(); )
{
digests.add(AlgorithmIdentifier.getInstance(en.nextElement()));
}
@@ -360,14 +362,14 @@
/**
* Return the a string representation of the OID associated with the
* encapsulated content info structure carried in the signed data.
- *
+ *
* @return the OID for the content type.
*/
public String getSignedContentTypeOID()
{
return signedData.getEncapContentInfo().getContentType().getId();
}
-
+
public CMSTypedData getSignedContent()
{
return signedContent;
@@ -396,7 +398,18 @@
* return the ASN.1 encoded representation of this object using the specified encoding.
*
* @param encoding the ASN.1 encoding format to use ("BER", "DL", or "DER").
- */
+ *
+ public byte[] getEncoded(String encoding)
+ throws IOException
+ {
+ return contentInfo.getEncoded(encoding);
+ }
+
+ /**
+ * return the ASN.1 encoded representation of this object using the specified encoding.
+ *
+ * @param encoding the ASN.1 encoding format to use ("BER", "DL", or "DER").
+ *
public byte[] getEncoded(String encoding)
throws IOException
{
@@ -407,9 +420,9 @@
* Verify all the SignerInformation objects and their associated counter signatures attached
* to this CMS SignedData object.
*
- * @param verifierProvider a provider of SignerInformationVerifier objects.
+ * @param verifierProvider a provider of SignerInformationVerifier objects.
* @return true if all verify, false otherwise.
- * @throws CMSException if an exception occurs during the verification process.
+ * @throws CMSException if an exception occurs during the verification process.
*
public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider)
throws CMSException
@@ -421,17 +434,17 @@
* Verify all the SignerInformation objects and optionally their associated counter signatures attached
* to this CMS SignedData object.
*
- * @param verifierProvider a provider of SignerInformationVerifier objects.
+ * @param verifierProvider a provider of SignerInformationVerifier objects.
* @param ignoreCounterSignatures if true don't check counter signatures. If false check counter signatures as well.
* @return true if all verify, false otherwise.
- * @throws CMSException if an exception occurs during the verification process.
+ * @throws CMSException if an exception occurs during the verification process.
*
public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider, boolean ignoreCounterSignatures)
throws CMSException
{
Collection signers = this.getSignerInfos().getSigners();
- for (Iterator it = signers.iterator(); it.hasNext();)
+ for (Iterator it = signers.iterator(); it.hasNext(); )
{
SignerInformation signer = (SignerInformation)it.next();
@@ -448,7 +461,7 @@
{
Collection counterSigners = signer.getCounterSignatures().getSigners();
- for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();)
+ for (Iterator cIt = counterSigners.iterator(); cIt.hasNext(); )
{
if (!verifyCounterSignature((SignerInformation)cIt.next(), verifierProvider))
{
@@ -477,7 +490,7 @@
}
Collection counterSigners = counterSigner.getCounterSignatures().getSigners();
- for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();)
+ for (Iterator cIt = counterSigners.iterator(); cIt.hasNext(); )
{
if (!verifyCounterSignature((SignerInformation)cIt.next(), verifierProvider))
{
@@ -491,24 +504,119 @@
// END Android-removed: Unknown reason
/**
+ * Return a new CMSSignedData which guarantees to have the passed in digestAlgorithm
+ * in it. Uses the current DigestAlgorithmIdentifierFinder for creating the digest sets.
+ *
+ * @param signedData the signed data object to be used as a base.
+ * @param digestAlgorithm the digest algorithm to be added to the signed data.
+ * @return a new signed data object.
+ */
+ public static CMSSignedData addDigestAlgorithm(CMSSignedData signedData, AlgorithmIdentifier digestAlgorithm)
+ {
+ return addDigestAlgorithm(signedData, digestAlgorithm, DIGEST_ALG_ID_FINDER);
+ }
+
+ /**
+ * Return a new CMSSignedData which guarantees to have the passed in digestAlgorithm
+ * in it. Uses the passed in DigestAlgorithmIdentifierFinder for creating the digest sets.
+ *
+ * @param signedData the signed data object to be used as a base.
+ * @param digestAlgorithm the digest algorithm to be added to the signed data.
+ * @param digestAlgIdFinder the digest algorithmID map to generate the digest set with.
+ * @return a new signed data object.
+ */
+ public static CMSSignedData addDigestAlgorithm(CMSSignedData signedData, AlgorithmIdentifier digestAlgorithm,
+ DigestAlgorithmIdentifierFinder digestAlgIdFinder)
+ {
+ Set<AlgorithmIdentifier> digestAlgorithms = signedData.getDigestAlgorithmIDs();
+ AlgorithmIdentifier digestAlg = HELPER.fixDigestAlgID(digestAlgorithm, digestAlgIdFinder);
+
+ //
+ // if the algorithm is already present there is no need to add it.
+ //
+ if (digestAlgorithms.contains(digestAlg))
+ {
+ return signedData;
+ }
+
+ //
+ // copy
+ //
+ CMSSignedData cms = new CMSSignedData(signedData);
+
+ //
+ // build up the new set
+ //
+ Set<AlgorithmIdentifier> digestAlgs = new HashSet<AlgorithmIdentifier>();
+
+ Iterator it = digestAlgorithms.iterator();
+ while (it.hasNext())
+ {
+ digestAlgs.add(HELPER.fixDigestAlgID((AlgorithmIdentifier)it.next(), digestAlgIdFinder));
+ }
+ digestAlgs.add(digestAlg);
+
+ ASN1Set digestSet = CMSUtils.convertToDlSet(digestAlgs);
+ ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive();
+
+ //
+ // signers are the last item in the sequence.
+ //
+ ASN1EncodableVector vec = new ASN1EncodableVector(sD.size());
+ vec.add(sD.getObjectAt(0)); // version
+ vec.add(digestSet);
+
+ for (int i = 2; i != sD.size(); i++)
+ {
+ vec.add(sD.getObjectAt(i));
+ }
+
+ cms.signedData = SignedData.getInstance(new BERSequence(vec));
+
+ //
+ // replace the contentInfo with the new one
+ //
+ cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData);
+
+ return cms;
+ }
+
+ /**
* Replace the SignerInformation store associated with this
- * CMSSignedData object with the new one passed in. You would
- * probably only want to do this if you wanted to change the unsigned
+ * CMSSignedData object with the new one passed in using the current
+ * DigestAlgorithmIdentifierFinder for creating the digest sets. You would
+ * probably only want to do this if you wanted to change the unsigned
* attributes associated with a signer, or perhaps delete one.
- *
- * @param signedData the signed data object to be used as a base.
+ *
+ * @param signedData the signed data object to be used as a base.
* @param signerInformationStore the new signer information store to use.
* @return a new signed data object.
*/
- public static CMSSignedData replaceSigners(
- CMSSignedData signedData,
- SignerInformationStore signerInformationStore)
+ public static CMSSignedData replaceSigners(CMSSignedData signedData, SignerInformationStore signerInformationStore)
+ {
+ return replaceSigners(signedData, signerInformationStore, DIGEST_ALG_ID_FINDER);
+ }
+
+ /**
+ * Replace the SignerInformation store associated with this
+ * CMSSignedData object with the new one passed in using the passed in
+ * DigestAlgorithmIdentifierFinder for creating the digest sets. You would
+ * probably only want to do this if you wanted to change the unsigned
+ * attributes associated with a signer, or perhaps delete one.
+ *
+ * @param signedData the signed data object to be used as a base.
+ * @param signerInformationStore the new signer information store to use.
+ * @param digestAlgIdFinder the digest algorithmID map to generate the digest set with.
+ * @return a new signed data object.
+ */
+ public static CMSSignedData replaceSigners(CMSSignedData signedData, SignerInformationStore signerInformationStore,
+ DigestAlgorithmIdentifierFinder digestAlgIdFinder)
{
//
// copy
//
- CMSSignedData cms = new CMSSignedData(signedData);
-
+ CMSSignedData cms = new CMSSignedData(signedData);
+
//
// replace the store
//
@@ -517,43 +625,44 @@
//
// replace the signers in the SignedData object
//
- ASN1EncodableVector digestAlgs = new ASN1EncodableVector();
- ASN1EncodableVector vec = new ASN1EncodableVector();
-
- Iterator it = signerInformationStore.getSigners().iterator();
+ Set<AlgorithmIdentifier> digestAlgs = new HashSet<AlgorithmIdentifier>();
+
+ Collection<SignerInformation> signers = signerInformationStore.getSigners();
+ ASN1EncodableVector vec = new ASN1EncodableVector(signers.size());
+
+ Iterator it = signers.iterator();
while (it.hasNext())
{
SignerInformation signer = (SignerInformation)it.next();
- digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID()));
+ CMSUtils.addDigestAlgs(digestAlgs, signer, digestAlgIdFinder);
vec.add(signer.toASN1Structure());
}
- ASN1Set digests = new DERSet(digestAlgs);
- ASN1Set signers = new DLSet(vec);
- ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive();
+ ASN1Set digestSet = CMSUtils.convertToDlSet(digestAlgs);
+ ASN1Set signerSet = new DLSet(vec);
+ ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive();
- vec = new ASN1EncodableVector();
-
//
// signers are the last item in the sequence.
//
+ vec = new ASN1EncodableVector(sD.size());
vec.add(sD.getObjectAt(0)); // version
- vec.add(digests);
+ vec.add(digestSet);
for (int i = 2; i != sD.size() - 1; i++)
{
vec.add(sD.getObjectAt(i));
}
-
- vec.add(signers);
-
+
+ vec.add(signerSet);
+
cms.signedData = SignedData.getInstance(new BERSequence(vec));
-
+
//
// replace the contentInfo with the new one
//
cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData);
-
+
return cms;
}
@@ -561,24 +670,24 @@
* Replace the certificate and CRL information associated with this
* CMSSignedData object with the new one passed in.
*
- * @param signedData the signed data object to be used as a base.
+ * @param signedData the signed data object to be used as a base.
* @param certificates the new certificates to be used.
- * @param attrCerts the new attribute certificates to be used.
- * @param revocations the new CRLs to be used - a collection of X509CRLHolder objects, OtherRevocationInfoFormat, or both.
+ * @param attrCerts the new attribute certificates to be used.
+ * @param revocations the new CRLs to be used - a collection of X509CRLHolder objects, OtherRevocationInfoFormat, or both.
* @return a new signed data object.
- * @exception CMSException if there is an error processing the CertStore
+ * @throws CMSException if there is an error processing the CertStore
*/
public static CMSSignedData replaceCertificatesAndCRLs(
- CMSSignedData signedData,
- Store certificates,
- Store attrCerts,
- Store revocations)
+ CMSSignedData signedData,
+ Store certificates,
+ Store attrCerts,
+ Store revocations)
throws CMSException
{
//
// copy
//
- CMSSignedData cms = new CMSSignedData(signedData);
+ CMSSignedData cms = new CMSSignedData(signedData);
//
// replace the certs and revocations in the SignedData object
@@ -596,7 +705,7 @@
}
if (attrCerts != null)
{
- certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts));
+ certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts));
}
ASN1Set set = CMSUtils.createBerSetFromList(certs);
@@ -621,10 +730,10 @@
// replace the CMS structure.
//
cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(),
- signedData.signedData.getEncapContentInfo(),
- certSet,
- crlSet,
- signedData.signedData.getSignerInfos());
+ signedData.signedData.getEncapContentInfo(),
+ certSet,
+ crlSet,
+ signedData.signedData.getSignerInfos());
//
// replace the contentInfo with the new one
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedDataGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedDataGenerator.java
index 1fdaaa9..6474962 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedDataGenerator.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedDataGenerator.java
@@ -6,18 +6,23 @@
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Set;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
import com.android.internal.org.bouncycastle.asn1.ASN1Set;
import com.android.internal.org.bouncycastle.asn1.BEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
import com.android.internal.org.bouncycastle.asn1.DERSet;
import com.android.internal.org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.cms.ContentInfo;
import com.android.internal.org.bouncycastle.asn1.cms.SignedData;
import com.android.internal.org.bouncycastle.asn1.cms.SignerInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
/**
* general class for generating a pkcs7-signature message.
@@ -50,6 +55,7 @@
extends CMSSignedGenerator
{
private List signerInfs = new ArrayList();
+ private boolean isDefiniteLength = false;
/**
* base constructor
@@ -59,6 +65,24 @@
}
/**
+ * base constructor with a custom DigestAlgorithmIdentifierFinder
+ */
+ public CMSSignedDataGenerator(DigestAlgorithmIdentifierFinder digestAlgIdFinder)
+ {
+ super(digestAlgIdFinder);
+ }
+
+ /**
+ * Specify use of definite length rather than indefinite length encoding.
+ *
+ * @param isDefiniteLength true use definite length, false use indefinite (default false).
+ */
+ public void setDefiniteLengthEncoding(boolean isDefiniteLength)
+ {
+ this.isDefiniteLength = isDefiniteLength;
+ }
+
+ /**
* Generate a CMS Signed Data object carrying a detached CMS signature.
*
* @param content the content to be signed.
@@ -118,7 +142,7 @@
// // TODO signedAttrs must be present for all signers
// }
- ASN1EncodableVector digestAlgs = new ASN1EncodableVector();
+ Set<AlgorithmIdentifier> digestAlgs = new LinkedHashSet<AlgorithmIdentifier>();
ASN1EncodableVector signerInfos = new ASN1EncodableVector();
digests.clear(); // clear the current preserved digest state
@@ -129,8 +153,7 @@
for (Iterator it = _signers.iterator(); it.hasNext();)
{
SignerInformation signer = (SignerInformation)it.next();
- digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID()));
-
+ CMSUtils.addDigestAlgs(digestAlgs, signer, digestAlgIdFinder);
// TODO Verify the content type and calculated digest match the precalculated SignerInfo
signerInfos.add(signer.toASN1Structure());
}
@@ -169,7 +192,14 @@
if (encapsulate)
{
- octs = new BEROctetString(bOut.toByteArray());
+ if (isDefiniteLength)
+ {
+ octs = new DEROctetString(bOut.toByteArray());
+ }
+ else
+ {
+ octs = new BEROctetString(bOut.toByteArray());
+ }
}
}
@@ -193,20 +223,34 @@
if (certs.size() != 0)
{
- certificates = CMSUtils.createBerSetFromList(certs);
+ if (isDefiniteLength)
+ {
+ certificates = CMSUtils.createDlSetFromList(certs);
+ }
+ else
+ {
+ certificates = CMSUtils.createBerSetFromList(certs);
+ }
}
ASN1Set certrevlist = null;
if (crls.size() != 0)
{
- certrevlist = CMSUtils.createBerSetFromList(crls);
+ if (isDefiniteLength)
+ {
+ certrevlist = CMSUtils.createDlSetFromList(crls);
+ }
+ else
+ {
+ certrevlist = CMSUtils.createBerSetFromList(crls);
+ }
}
ContentInfo encInfo = new ContentInfo(contentTypeOID, octs);
SignedData sd = new SignedData(
- new DERSet(digestAlgs),
+ CMSUtils.convertToDlSet(digestAlgs),
encInfo,
certificates,
certrevlist,
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedGenerator.java
index eae4ff4..14e573a 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedGenerator.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedGenerator.java
@@ -12,8 +12,8 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
-import com.android.internal.org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
// import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
@@ -27,6 +27,8 @@
import com.android.internal.org.bouncycastle.cert.X509AttributeCertificateHolder;
import com.android.internal.org.bouncycastle.cert.X509CRLHolder;
import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import com.android.internal.org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import com.android.internal.org.bouncycastle.util.Arrays;
import com.android.internal.org.bouncycastle.util.Store;
@@ -38,7 +40,6 @@
/**
* Default type for the signed data.
*/
- public static final String DATA = CMSObjectIdentifiers.data.getId();
public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId();
public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId();
@@ -47,6 +48,7 @@
public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId();
public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId();
// BEGIN Android-removed: Unsupported algorithms
+ // public static final String DATA = CMSObjectIdentifiers.data.getId();
// public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId();
// public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId();
// public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId();
@@ -96,11 +98,19 @@
protected List signerGens = new ArrayList();
protected Map digests = new HashMap();
+ protected DigestAlgorithmIdentifierFinder digestAlgIdFinder;
+
/**
* base constructor
*/
protected CMSSignedGenerator()
{
+ this(new DefaultDigestAlgorithmIdentifierFinder());
+ }
+
+ protected CMSSignedGenerator(DigestAlgorithmIdentifierFinder digestAlgIdFinder)
+ {
+ this.digestAlgIdFinder = digestAlgIdFinder;
}
protected Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
@@ -199,7 +209,9 @@
ASN1ObjectIdentifier otherRevocationInfoFormat,
ASN1Encodable otherRevocationInfo)
{
- crls.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, otherRevocationInfo)));
+ OtherRevocationInfoFormat infoFormat = new OtherRevocationInfoFormat(otherRevocationInfoFormat, otherRevocationInfo);
+ CMSUtils.validateInfoFormat(infoFormat);
+ crls.add(new DERTaggedObject(false, 1, infoFormat));
}
/**
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedHelper.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedHelper.java
index bd528bd..f547805 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedHelper.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedHelper.java
@@ -13,11 +13,12 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1Set;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.BERTags;
import com.android.internal.org.bouncycastle.asn1.DERNull;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
-import com.android.internal.org.bouncycastle.asn1.eac.EACObjectIdentifiers;
+// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -32,6 +33,7 @@
import com.android.internal.org.bouncycastle.cert.X509AttributeCertificateHolder;
import com.android.internal.org.bouncycastle.cert.X509CRLHolder;
import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import com.android.internal.org.bouncycastle.util.CollectionStore;
import com.android.internal.org.bouncycastle.util.Store;
@@ -100,9 +102,6 @@
addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_256, "ECDSA");
addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_384, "ECDSA");
addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_512, "ECDSA");
- */
- // END Android-removed: Unsupported algorithms
- addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "DSA");
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "ECDSA");
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "ECDSA");
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "ECDSA");
@@ -112,6 +111,9 @@
addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "RSA");
addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "RSAandMGF1");
addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "RSAandMGF1");
+ */
+ // END Android-removed: Unsupported algorithms
+ addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "DSA");
addEntries(X9ObjectIdentifiers.id_dsa, "DSA");
addEntries(PKCSObjectIdentifiers.rsaEncryption, "RSA");
@@ -153,14 +155,17 @@
return encryptionAlgOID;
}
- AlgorithmIdentifier fixAlgID(AlgorithmIdentifier algId)
+ AlgorithmIdentifier fixDigestAlgID(AlgorithmIdentifier algId, DigestAlgorithmIdentifierFinder dgstAlgFinder)
{
- if (algId.getParameters() == null)
+ ASN1Encodable params = algId.getParameters();
+ if (params == null || DERNull.INSTANCE.equals(params))
{
- return new AlgorithmIdentifier(algId.getAlgorithm(), DERNull.INSTANCE);
+ return dgstAlgFinder.find(algId.getAlgorithm());
}
-
- return algId;
+ else
+ {
+ return algId;
+ }
}
void setSigningEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName)
@@ -202,7 +207,18 @@
if (obj instanceof ASN1TaggedObject)
{
- certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(((ASN1TaggedObject)obj).getObject())));
+ ASN1TaggedObject tObj = (ASN1TaggedObject)obj;
+
+ // CertificateChoices ::= CHOICE {
+ // certificate Certificate,
+ // extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete
+ // v1AttrCert [1] IMPLICIT AttributeCertificateV1, -- Obsolete
+ // v2AttrCert [2] IMPLICIT AttributeCertificateV2,
+ // other [3] IMPLICIT OtherCertificateFormat }
+ if (tObj.getTagNo() == 1 || tObj.getTagNo() == 2)
+ {
+ certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(tObj.getBaseUniversal(false, BERTags.SEQUENCE))));
+ }
}
}
@@ -250,7 +266,7 @@
{
ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(obj);
- if (tObj.getTagNo() == 1)
+ if (tObj.hasContextTag(1))
{
OtherRevocationInfoFormat other = OtherRevocationInfoFormat.getInstance(tObj, false);
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSUtils.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSUtils.java
index a803260..3b9933a 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSUtils.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSUtils.java
@@ -22,6 +22,7 @@
import com.android.internal.org.bouncycastle.asn1.DERNull;
import com.android.internal.org.bouncycastle.asn1.DERSet;
import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DLSet;
import com.android.internal.org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.cms.ContentInfo;
// Android-removed: Unsupported algorithms
@@ -38,6 +39,7 @@
import com.android.internal.org.bouncycastle.cert.X509AttributeCertificateHolder;
import com.android.internal.org.bouncycastle.cert.X509CRLHolder;
import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import com.android.internal.org.bouncycastle.operator.DigestCalculator;
import com.android.internal.org.bouncycastle.util.Store;
import com.android.internal.org.bouncycastle.util.Strings;
@@ -60,7 +62,6 @@
/*
des.add(OIWObjectIdentifiers.desCBC.getId());
des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId());
- des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId());
des.add(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId());
mqvAlgs.add(X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme);
@@ -156,6 +157,23 @@
return readContentInfo(new ASN1InputStream(input));
}
+ static ASN1Set convertToDlSet(Set<AlgorithmIdentifier> digestAlgs)
+ {
+ return new DLSet((AlgorithmIdentifier[])digestAlgs.toArray(new AlgorithmIdentifier[digestAlgs.size()]));
+ }
+
+ static void addDigestAlgs(Set<AlgorithmIdentifier> digestAlgs, SignerInformation signer, DigestAlgorithmIdentifierFinder dgstAlgFinder)
+ {
+ digestAlgs.add(CMSSignedHelper.INSTANCE.fixDigestAlgID(signer.getDigestAlgorithmID(), dgstAlgFinder));
+ SignerInformationStore counterSignaturesStore = signer.getCounterSignatures();
+ Iterator<SignerInformation> counterSignatureIt = counterSignaturesStore.iterator();
+ while (counterSignatureIt.hasNext())
+ {
+ SignerInformation counterSigner = (SignerInformation)counterSignatureIt.next();
+ digestAlgs.add(CMSSignedHelper.INSTANCE.fixDigestAlgID(counterSigner.getDigestAlgorithmID(), dgstAlgFinder));
+ }
+ }
+
static List getCertificatesFromStore(Store certStore)
throws CMSException
{
@@ -244,7 +262,7 @@
// BEGIN Android-removed: OtherRevocationInfoFormat isn't supported
/*
- private static void validateInfoFormat(OtherRevocationInfoFormat infoFormat)
+ static void validateInfoFormat(OtherRevocationInfoFormat infoFormat)
{
if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(infoFormat.getInfoFormat()))
{
@@ -288,6 +306,18 @@
return new BERSet(v);
}
+ static ASN1Set createDlSetFromList(List derObjects)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (Iterator it = derObjects.iterator(); it.hasNext(); )
+ {
+ v.add((ASN1Encodable)it.next());
+ }
+
+ return new DLSet(v);
+ }
+
static ASN1Set createDerSetFromList(List derObjects)
{
ASN1EncodableVector v = new ASN1EncodableVector();
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
index 45a401c..51ef394 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
@@ -6,11 +6,14 @@
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
-import com.android.internal.org.bouncycastle.asn1.eac.EACObjectIdentifiers;
+// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -28,6 +31,7 @@
{
private final Map encryptionAlgs = new HashMap();
private final Map digestAlgs = new HashMap();
+ private final Map simpleAlgs = new HashMap();
private void addEntries(ASN1ObjectIdentifier alias, String digest, String encryption)
{
@@ -74,12 +78,22 @@
addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256", "RSA");
addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384", "RSA");
addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512", "RSA");
+ addEntries(PKCSObjectIdentifiers.sha512_224WithRSAEncryption, "SHA512(224)", "RSA");
+ addEntries(PKCSObjectIdentifiers.sha512_256WithRSAEncryption, "SHA512(256)", "RSA");
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224, "SHA3-224", "RSA");
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256, "SHA3-256", "RSA");
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384, "SHA3-384", "RSA");
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512, "SHA3-512", "RSA");
// BEGIN Android-removed: Unsupported algorithms
/*
+ addEntries(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128, "SHAKE128", "RSAPSS");
+ addEntries(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256, "SHAKE256", "RSAPSS");
addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, "RIPEMD128", "RSA");
addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, "RIPEMD160", "RSA");
addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, "RIPEMD256", "RSA");
+ addEntries(CMSObjectIdentifiers.id_ecdsa_with_shake128, "SHAKE128", "ECDSA");
+ addEntries(CMSObjectIdentifiers.id_ecdsa_with_shake256, "SHAKE256", "ECDSA");
*/
// END Android-removed: Unsupported algorithms
@@ -89,6 +103,8 @@
addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384", "ECDSA");
addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512", "ECDSA");
addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1", "DSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1", "ECDSA");
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224", "ECDSA");
addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256", "ECDSA");
@@ -98,14 +114,31 @@
addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA");
addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1");
addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1");
- // BEGIN Android-removed: Unsupported algorithms
- /*
addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1", "PLAIN-ECDSA");
addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224", "PLAIN-ECDSA");
addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256", "PLAIN-ECDSA");
addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384", "PLAIN-ECDSA");
addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512", "PLAIN-ECDSA");
addEntries(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA3_224, "SHA3-224", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA3_256, "SHA3-256", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA3_384, "SHA3-384", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA3_512, "SHA3-512", "PLAIN-ECDSA");
+
+// addEntries(GMObjectIdentifiers.sm2sign_with_rmd160, "RIPEMD160", "SM2");
+// addEntries(GMObjectIdentifiers.sm2sign_with_sha1, "SHA1", "SM2");
+// addEntries(GMObjectIdentifiers.sm2sign_with_sha224, "SHA224", "SM2");
+ addEntries(GMObjectIdentifiers.sm2sign_with_sha256, "SHA256", "SM2");
+// addEntries(GMObjectIdentifiers.sm2sign_with_sha384, "SHA384", "SM2");
+// addEntries(GMObjectIdentifiers.sm2sign_with_sha512, "SHA512", "SM2");
+ addEntries(GMObjectIdentifiers.sm2sign_with_sm3, "SM3", "SM2");
+
+ addEntries(BCObjectIdentifiers.sphincs256_with_SHA512, "SHA512", "SPHINCS256");
+ addEntries(BCObjectIdentifiers.sphincs256_with_SHA3_512, "SHA3-512", "SPHINCS256");
+
+ addEntries(BCObjectIdentifiers.picnic_with_shake256, "SHAKE256", "Picnic");
+ addEntries(BCObjectIdentifiers.picnic_with_sha512, "SHA512", "Picnic");
+ addEntries(BCObjectIdentifiers.picnic_with_sha3_512, "SHA3-512", "Picnic");
addEntries(GMObjectIdentifiers.sm2sign_with_rmd160, "RIPEMD160", "SM2");
addEntries(GMObjectIdentifiers.sm2sign_with_sha1, "SHA1", "SM2");
@@ -134,6 +167,7 @@
encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3410");
encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "ECGOST3410-2012-256");
encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "ECGOST3410-2012-512");
+ encryptionAlgs.put(X9ObjectIdentifiers.id_ecPublicKey, "ECDSA");
digestAlgs.put(PKCSObjectIdentifiers.md2, "MD2");
digestAlgs.put(PKCSObjectIdentifiers.md4, "MD4");
@@ -147,6 +181,10 @@
digestAlgs.put(NISTObjectIdentifiers.id_sha512, "SHA512");
// BEGIN Android-removed: Unsupported algorithms
/*
+ digestAlgs.put(NISTObjectIdentifiers.id_sha512_224, "SHA512(224)");
+ digestAlgs.put(NISTObjectIdentifiers.id_sha512_256, "SHA512(256)");
+ digestAlgs.put(NISTObjectIdentifiers.id_shake128, "SHAKE128");
+ digestAlgs.put(NISTObjectIdentifiers.id_shake256, "SHAKE256");
digestAlgs.put(NISTObjectIdentifiers.id_sha3_224, "SHA3-224");
digestAlgs.put(NISTObjectIdentifiers.id_sha3_256, "SHA3-256");
digestAlgs.put(NISTObjectIdentifiers.id_sha3_384, "SHA3-384");
@@ -159,6 +197,34 @@
digestAlgs.put(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256, "GOST3411-2012-256");
digestAlgs.put(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, "GOST3411-2012-512");
digestAlgs.put(GMObjectIdentifiers.sm3, "SM3");
+
+ simpleAlgs.put(EdECObjectIdentifiers.id_Ed25519, "Ed25519");
+ simpleAlgs.put(EdECObjectIdentifiers.id_Ed448, "Ed448");
+ simpleAlgs.put(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, "LMS");
+
+ simpleAlgs.put(MiscObjectIdentifiers.id_alg_composite, "COMPOSITE");
+ simpleAlgs.put(BCObjectIdentifiers.falcon_512, "Falcon-512");
+ simpleAlgs.put(BCObjectIdentifiers.falcon_1024, "Falcon-1024");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium2, "Dilithium2");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium3, "Dilithium3");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium5, "Dilithium5");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_128s, "SPHINCS+-SHA2-128s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_128f, "SPHINCS+-SHA2-128f");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_192s, "SPHINCS+-SHA2-192s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_192f, "SPHINCS+-SHA2-192f");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_256s, "SPHINCS+-SHA2-256s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_sha2_256f, "SPHINCS+-SHA2-256f");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_128s, "SPHINCS+-SHAKE-128s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_128f, "SPHINCS+-SHAKE-128f");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_192s, "SPHINCS+-SHAKE-192s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_192f, "SPHINCS+-SHAKE-192f");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_256s, "SPHINCS+-SHAKE-256s");
+ simpleAlgs.put(BCObjectIdentifiers.sphincsPlus_shake_256f, "SPHINCS+-SHAKE-256f");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium2, "Dilithium2");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium3, "Dilithium3");
+ simpleAlgs.put(BCObjectIdentifiers.dilithium5, "Dilithium5");
+
+ simpleAlgs.put(BCObjectIdentifiers.picnic_signature, "Picnic");
*/
// END Android-removed: Unsupported algorithms
}
@@ -234,16 +300,29 @@
{
return "Ed448";
}
+
+ // if (encryptionAlgOID.on(BCObjectIdentifiers.sphincsPlus))
+ // {
+ // return "SPHINCSPlus";
+ // }
*/
// END Android-removed: unsupported algorithms
- String digestName = getDigestAlgName(encryptionAlg.getAlgorithm());
+ ASN1ObjectIdentifier encryptionAlgOID = encryptionAlg.getAlgorithm();
- if (!digestName.equals(encryptionAlg.getAlgorithm().getId()))
+ String simpleAlgName = (String)simpleAlgs.get(encryptionAlgOID);
+ if (simpleAlgName != null)
{
- return digestName + "with" + getEncryptionAlgName(encryptionAlg.getAlgorithm());
+ return simpleAlgName;
}
- return getDigestAlgName(digestAlg.getAlgorithm()) + "with" + getEncryptionAlgName(encryptionAlg.getAlgorithm());
+ String digestName = getDigestAlgName(encryptionAlgOID);
+
+ if (!digestName.equals(encryptionAlgOID.getId()))
+ {
+ return digestName + "with" + getEncryptionAlgName(encryptionAlgOID);
+ }
+
+ return getDigestAlgName(digestAlg.getAlgorithm()) + "with" + getEncryptionAlgName(encryptionAlgOID);
}
}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
index f82906b..0c34339 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
@@ -20,8 +20,8 @@
public class DefaultCMSSignatureEncryptionAlgorithmFinder
implements CMSSignatureEncryptionAlgorithmFinder
{
- private static final Set RSA_PKCS1d5 = new HashSet();
- private static final Map GOST_ENC = new HashMap();
+ protected static final Set RSA_PKCS1d5 = new HashSet();
+ protected static final Map GOST_ENC = new HashMap();
static
{
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/KEMRecipient.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/KEMRecipient.java
new file mode 100644
index 0000000..b754f97
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/KEMRecipient.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface KEMRecipient
+ extends Recipient
+{
+ RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentKey)
+ throws CMSException;
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGenerator.java
index b6d006a..c08fcd0 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGenerator.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGenerator.java
@@ -20,11 +20,7 @@
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
import com.android.internal.org.bouncycastle.operator.ContentSigner;
-import com.android.internal.org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
-import com.android.internal.org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import com.android.internal.org.bouncycastle.operator.DigestCalculator;
-import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider;
-import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
import com.android.internal.org.bouncycastle.util.Arrays;
import com.android.internal.org.bouncycastle.util.io.TeeOutputStream;
@@ -38,7 +34,7 @@
private final CMSAttributeTableGenerator unsAttrGen;
private final ContentSigner signer;
private final DigestCalculator digester;
- private final DigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+ private final AlgorithmIdentifier digestAlgorithm;
private final CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder;
private byte[] calculatedDigest = null;
@@ -47,44 +43,32 @@
SignerInfoGenerator(
SignerIdentifier signerIdentifier,
ContentSigner signer,
- DigestCalculatorProvider digesterProvider,
+ AlgorithmIdentifier digesterAlgorithm,
CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder)
- throws OperatorCreationException
{
- this(signerIdentifier, signer, digesterProvider, sigEncAlgFinder, false);
+ this.signerIdentifier = signerIdentifier;
+ this.signer = signer;
+ this.digestAlgorithm = digesterAlgorithm;
+ this.digester = null;
+ this.sAttrGen = null;
+ this.unsAttrGen = null;
+ this.sigEncAlgFinder = sigEncAlgFinder;
}
SignerInfoGenerator(
SignerIdentifier signerIdentifier,
ContentSigner signer,
- DigestCalculatorProvider digesterProvider,
+ DigestCalculator digester,
CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder,
- boolean isDirectSignature)
- throws OperatorCreationException
+ CMSAttributeTableGenerator sAttrGen,
+ CMSAttributeTableGenerator unsAttrGen)
{
this.signerIdentifier = signerIdentifier;
this.signer = signer;
-
- if (digesterProvider != null)
- {
- this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier()));
- }
- else
- {
- this.digester = null;
- }
-
- if (isDirectSignature)
- {
- this.sAttrGen = null;
- this.unsAttrGen = null;
- }
- else
- {
- this.sAttrGen = new DefaultSignedAttributeTableGenerator();
- this.unsAttrGen = null;
- }
-
+ this.digestAlgorithm = digester.getAlgorithmIdentifier();
+ this.digester = digester;
+ this.sAttrGen = sAttrGen;
+ this.unsAttrGen = unsAttrGen;
this.sigEncAlgFinder = sigEncAlgFinder;
}
@@ -95,38 +79,13 @@
{
this.signerIdentifier = original.signerIdentifier;
this.signer = original.signer;
+ this.digestAlgorithm = original.digestAlgorithm;
this.digester = original.digester;
this.sigEncAlgFinder = original.sigEncAlgFinder;
this.sAttrGen = sAttrGen;
this.unsAttrGen = unsAttrGen;
}
- SignerInfoGenerator(
- SignerIdentifier signerIdentifier,
- ContentSigner signer,
- DigestCalculatorProvider digesterProvider,
- CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder,
- CMSAttributeTableGenerator sAttrGen,
- CMSAttributeTableGenerator unsAttrGen)
- throws OperatorCreationException
- {
- this.signerIdentifier = signerIdentifier;
- this.signer = signer;
-
- if (digesterProvider != null)
- {
- this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier()));
- }
- else
- {
- this.digester = null;
- }
-
- this.sAttrGen = sAttrGen;
- this.unsAttrGen = unsAttrGen;
- this.sigEncAlgFinder = sigEncAlgFinder;
- }
-
public SignerIdentifier getSID()
{
return signerIdentifier;
@@ -149,12 +108,7 @@
public AlgorithmIdentifier getDigestAlgorithm()
{
- if (digester != null)
- {
- return digester.getAlgorithmIdentifier();
- }
-
- return digAlgFinder.find(signer.getAlgorithmIdentifier());
+ return digestAlgorithm;
}
public OutputStream getCalculatingOutputStream()
@@ -211,14 +165,13 @@
}
else
{
+ digestAlg = digestAlgorithm;
if (digester != null)
{
- digestAlg = digester.getAlgorithmIdentifier();
calculatedDigest = digester.getDigest();
}
else
{
- digestAlg = digAlgFinder.find(signer.getAlgorithmIdentifier());
calculatedDigest = null;
}
}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
index e6aea68..b818671 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
@@ -4,8 +4,12 @@
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
import com.android.internal.org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
import com.android.internal.org.bouncycastle.asn1.cms.SignerIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
import com.android.internal.org.bouncycastle.operator.ContentSigner;
+import com.android.internal.org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import com.android.internal.org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
+import com.android.internal.org.bouncycastle.operator.DigestCalculator;
import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider;
import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
@@ -15,11 +19,14 @@
*/
public class SignerInfoGeneratorBuilder
{
+ private final DigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+
private DigestCalculatorProvider digestProvider;
private boolean directSignature;
private CMSAttributeTableGenerator signedGen;
private CMSAttributeTableGenerator unsignedGen;
private CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder;
+ private AlgorithmIdentifier contentDigest;
/**
* Base constructor.
@@ -57,6 +64,18 @@
}
/**
+ * Set the algorithm identifier for the contentDigest to be used for processing the data.
+ *
+ * @return the builder object
+ */
+ public SignerInfoGeneratorBuilder setContentDigest(AlgorithmIdentifier contentDigest)
+ {
+ this.contentDigest = contentDigest;
+
+ return this;
+ }
+
+ /**
* Provide a custom signed attribute generator.
*
* @param signedGen a generator of signed attributes.
@@ -122,9 +141,19 @@
private SignerInfoGenerator createGenerator(ContentSigner contentSigner, SignerIdentifier sigId)
throws OperatorCreationException
{
+ DigestCalculator digester;
+ if (contentDigest != null)
+ {
+ digester = digestProvider.get(contentDigest);
+ }
+ else
+ {
+ digester = digestProvider.get(digAlgFinder.find(contentSigner.getAlgorithmIdentifier()));
+ }
+
if (directSignature)
{
- return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, true);
+ return new SignerInfoGenerator(sigId, contentSigner, digester.getAlgorithmIdentifier(), sigEncAlgFinder);
}
if (signedGen != null || unsignedGen != null)
@@ -134,9 +163,9 @@
signedGen = new DefaultSignedAttributeTableGenerator();
}
- return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, signedGen, unsignedGen);
+ return new SignerInfoGenerator(sigId, contentSigner, digester, sigEncAlgFinder, signedGen, unsignedGen);
}
- return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder);
+ return new SignerInfoGenerator(sigId, contentSigner, digester, sigEncAlgFinder, new DefaultSignedAttributeTableGenerator(), null);
}
}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformation.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformation.java
index 1f70626..9393e25 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformation.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformation.java
@@ -25,6 +25,8 @@
import com.android.internal.org.bouncycastle.asn1.cms.SignerIdentifier;
import com.android.internal.org.bouncycastle.asn1.cms.SignerInfo;
import com.android.internal.org.bouncycastle.asn1.cms.Time;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.DigestInfo;
import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
@@ -41,34 +43,34 @@
*/
public class SignerInformation
{
- private final SignerId sid;
- private final CMSProcessable content;
- private final byte[] signature;
- private final ASN1ObjectIdentifier contentType;
- private final boolean isCounterSignature;
+ private final SignerId sid;
+ private final CMSProcessable content;
+ private final byte[] signature;
+ private final ASN1ObjectIdentifier contentType;
+ private final boolean isCounterSignature;
// Derived
- private AttributeTable signedAttributeValues;
- private AttributeTable unsignedAttributeValues;
- private byte[] resultDigest;
+ private AttributeTable signedAttributeValues;
+ private AttributeTable unsignedAttributeValues;
+ private byte[] resultDigest;
- protected final SignerInfo info;
- protected final AlgorithmIdentifier digestAlgorithm;
- protected final AlgorithmIdentifier encryptionAlgorithm;
- protected final ASN1Set signedAttributeSet;
- protected final ASN1Set unsignedAttributeSet;
+ protected final SignerInfo info;
+ protected final AlgorithmIdentifier digestAlgorithm;
+ protected final AlgorithmIdentifier encryptionAlgorithm;
+ protected final ASN1Set signedAttributeSet;
+ protected final ASN1Set unsignedAttributeSet;
SignerInformation(
- SignerInfo info,
+ SignerInfo info,
ASN1ObjectIdentifier contentType,
- CMSProcessable content,
- byte[] resultDigest)
+ CMSProcessable content,
+ byte[] resultDigest)
{
this.info = info;
this.contentType = contentType;
this.isCounterSignature = contentType == null;
- SignerIdentifier s = info.getSID();
+ SignerIdentifier s = info.getSID();
if (s.isTagged())
{
@@ -78,7 +80,7 @@
}
else
{
- IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.getInstance(s.getId());
+ IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.getInstance(s.getId());
sid = new SignerId(iAnds.getName(), iAnds.getSerialNumber().getValue());
}
@@ -111,7 +113,7 @@
* that by also tweaking the SignerInfo so that these issues can be dealt with.
*
* @param baseInfo the SignerInformation to base this one on.
- * @param info the SignerInfo to associate with the existing baseInfo data.
+ * @param info the SignerInfo to associate with the existing baseInfo data.
*/
protected SignerInformation(SignerInformation baseInfo, SignerInfo info)
{
@@ -126,8 +128,8 @@
this.signature = info.getEncryptedDigest().getOctets();
this.content = baseInfo.content;
this.resultDigest = baseInfo.resultDigest;
- this.signedAttributeValues = baseInfo.signedAttributeValues;
- this.unsignedAttributeValues = baseInfo.unsignedAttributeValues;
+ this.signedAttributeValues = getSignedAttributes();
+ this.unsignedAttributeValues = getUnsignedAttributes();
}
public boolean isCounterSignature()
@@ -141,7 +143,7 @@
}
private byte[] encodeObj(
- ASN1Encodable obj)
+ ASN1Encodable obj)
throws IOException
{
if (obj != null)
@@ -202,10 +204,10 @@
{
throw new IllegalStateException("method can only be called after verify.");
}
-
+
return Arrays.clone(resultDigest);
}
-
+
/**
* return the object identifier for the signature.
*/
@@ -228,7 +230,7 @@
{
throw new RuntimeException("exception getting encryption parameters " + e);
}
- }
+ }
/**
* return a table of the signed attributes - indexed by
@@ -278,7 +280,7 @@
The countersignature attribute MUST be an unsigned attribute; it MUST
NOT be a signed attribute, an authenticated attribute, an
unauthenticated attribute, or an unprotected attribute.
- */
+ */
AttributeTable unsignedAttributeTable = getUnsignedAttributes();
if (unsignedAttributeTable == null)
{
@@ -309,7 +311,7 @@
// TODO Throw an appropriate exception?
}
- for (Enumeration en = values.getObjects(); en.hasMoreElements();)
+ for (Enumeration en = values.getObjects(); en.hasMoreElements(); )
{
/*
Countersignature values have the same meaning as SignerInfo values
@@ -333,9 +335,10 @@
return new SignerInformationStore(counterSignatures);
}
-
+
/**
* return the DER encoding of the signed attributes.
+ *
* @throws IOException if an encoding error occurs.
*/
public byte[] getEncodedSignedAttributes()
@@ -353,12 +356,14 @@
SignerInformationVerifier verifier)
throws CMSException
{
- String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID());
+ String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID());
+ AlgorithmIdentifier realDigestAlgorithm = signedAttributeSet != null ?
+ info.getDigestAlgorithm() : translateBrokenRSAPkcs7(encryptionAlgorithm, info.getDigestAlgorithm());
ContentVerifier contentVerifier;
try
{
- contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, info.getDigestAlgorithm());
+ contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, realDigestAlgorithm);
}
catch (OperatorCreationException e)
{
@@ -371,10 +376,10 @@
if (resultDigest == null)
{
- DigestCalculator calc = verifier.getDigestCalculator(this.getDigestAlgorithmID());
+ DigestCalculator calc = verifier.getDigestCalculator(realDigestAlgorithm);
if (content != null)
{
- OutputStream digOut = calc.getOutputStream();
+ OutputStream digOut = calc.getOutputStream();
if (signedAttributeSet == null)
{
@@ -438,128 +443,18 @@
}
// RFC 3852 11.1 Check the content-type attribute is correct
- {
- ASN1Primitive validContentType = getSingleValuedSignedAttribute(
- CMSAttributes.contentType, "content-type");
- if (validContentType == null)
- {
- if (!isCounterSignature && signedAttributeSet != null)
- {
- throw new CMSException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
- }
- }
- else
- {
- if (isCounterSignature)
- {
- throw new CMSException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
- }
-
- if (!(validContentType instanceof ASN1ObjectIdentifier))
- {
- throw new CMSException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
- }
-
- ASN1ObjectIdentifier signedContentType = (ASN1ObjectIdentifier)validContentType;
-
- if (!signedContentType.equals(contentType))
- {
- throw new CMSException("content-type attribute value does not match eContentType");
- }
- }
- }
+ verifyContentTypeAttributeValue();
AttributeTable signedAttrTable = this.getSignedAttributes();
// RFC 6211 Validate Algorithm Identifier protection attribute if present
- {
- AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
- if (unsignedAttrTable != null && unsignedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect).size() > 0)
- {
- throw new CMSException("A cmsAlgorithmProtect attribute MUST be a signed attribute");
- }
- if (signedAttrTable != null)
- {
- ASN1EncodableVector protectionAttributes = signedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect);
- if (protectionAttributes.size() > 1)
- {
- throw new CMSException("Only one instance of a cmsAlgorithmProtect attribute can be present");
- }
-
- if (protectionAttributes.size() > 0)
- {
- Attribute attr = Attribute.getInstance(protectionAttributes.get(0));
- if (attr.getAttrValues().size() != 1)
- {
- throw new CMSException("A cmsAlgorithmProtect attribute MUST contain exactly one value");
- }
-
- CMSAlgorithmProtection algorithmProtection = CMSAlgorithmProtection.getInstance(attr.getAttributeValues()[0]);
-
- if (!CMSUtils.isEquivalent(algorithmProtection.getDigestAlgorithm(), info.getDigestAlgorithm()))
- {
- throw new CMSException("CMS Algorithm Identifier Protection check failed for digestAlgorithm");
- }
-
- if (!CMSUtils.isEquivalent(algorithmProtection.getSignatureAlgorithm(), info.getDigestEncryptionAlgorithm()))
- {
- throw new CMSException("CMS Algorithm Identifier Protection check failed for signatureAlgorithm");
- }
- }
- }
- }
+ verifyAlgorithmIdentifierProtectionAttribute(signedAttrTable);
// RFC 3852 11.2 Check the message-digest attribute is correct
- {
- ASN1Primitive validMessageDigest = getSingleValuedSignedAttribute(
- CMSAttributes.messageDigest, "message-digest");
- if (validMessageDigest == null)
- {
- if (signedAttributeSet != null)
- {
- throw new CMSException("the message-digest signed attribute type MUST be present when there are any signed attributes present");
- }
- }
- else
- {
- if (!(validMessageDigest instanceof ASN1OctetString))
- {
- throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
- }
-
- ASN1OctetString signedMessageDigest = (ASN1OctetString)validMessageDigest;
-
- if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets()))
- {
- throw new CMSSignerDigestMismatchException("message-digest attribute value does not match calculated value");
- }
- }
- }
+ verifyMessageDigestAttribute();
// RFC 3852 11.4 Validate countersignature attribute(s)
- {
- if (signedAttrTable != null
- && signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0)
- {
- throw new CMSException("A countersignature attribute MUST NOT be a signed attribute");
- }
-
- AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
- if (unsignedAttrTable != null)
- {
- ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature);
- for (int i = 0; i < csAttrs.size(); ++i)
- {
- Attribute csAttr = Attribute.getInstance(csAttrs.get(i));
- if (csAttr.getAttrValues().size() < 1)
- {
- throw new CMSException("A countersignature attribute MUST contain at least one AttributeValue");
- }
-
- // Note: We don't recursively validate the countersignature value
- }
- }
- }
+ verifyCounterSignatureAttribute(signedAttrTable);
try
{
@@ -571,7 +466,7 @@
if (encName.equals("RSA"))
{
- DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest);
+ DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(realDigestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest);
return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature());
}
@@ -589,6 +484,154 @@
}
/**
+ * RFC 3852 11.1 Check the content-type attribute is correct
+ *
+ * @throws CMSException when content-type was invalid.
+ */
+ private void verifyContentTypeAttributeValue()
+ throws CMSException
+ {
+ ASN1Primitive validContentType = getSingleValuedSignedAttribute(
+ CMSAttributes.contentType, "content-type");
+ if (validContentType == null)
+ {
+ if (!isCounterSignature && signedAttributeSet != null)
+ {
+ throw new CMSException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
+ }
+ }
+ else
+ {
+ if (isCounterSignature)
+ {
+ throw new CMSException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
+ }
+
+ if (!(validContentType instanceof ASN1ObjectIdentifier))
+ {
+ throw new CMSException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
+ }
+
+ ASN1ObjectIdentifier signedContentType = (ASN1ObjectIdentifier)validContentType;
+
+ if (!signedContentType.equals(contentType))
+ {
+ throw new CMSException("content-type attribute value does not match eContentType");
+ }
+ }
+ }
+
+ /**
+ * RFC 3852 11.2 Check the message-digest attribute is correct
+ *
+ * @throws CMSException when message-digest attribute was rejected
+ */
+ private void verifyMessageDigestAttribute()
+ throws CMSException
+ {
+ ASN1Primitive validMessageDigest = getSingleValuedSignedAttribute(
+ CMSAttributes.messageDigest, "message-digest");
+ if (validMessageDigest == null)
+ {
+ if (signedAttributeSet != null)
+ {
+ throw new CMSException("the message-digest signed attribute type MUST be present when there are any signed attributes present");
+ }
+ }
+ else
+ {
+ if (!(validMessageDigest instanceof ASN1OctetString))
+ {
+ throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
+ }
+
+ ASN1OctetString signedMessageDigest = (ASN1OctetString)validMessageDigest;
+
+ if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets()))
+ {
+ throw new CMSSignerDigestMismatchException("message-digest attribute value does not match calculated value");
+ }
+ }
+ }
+
+ /**
+ * RFC 6211 Validate Algorithm Identifier protection attribute if present
+ *
+ * @param signedAttrTable signed attributes
+ * @throws CMSException when cmsAlgorihmProtect attribute was rejected
+ */
+ private void verifyAlgorithmIdentifierProtectionAttribute(AttributeTable signedAttrTable)
+ throws CMSException
+ {
+ AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
+ if (unsignedAttrTable != null && unsignedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect).size() > 0)
+ {
+ throw new CMSException("A cmsAlgorithmProtect attribute MUST be a signed attribute");
+ }
+ if (signedAttrTable != null)
+ {
+ ASN1EncodableVector protectionAttributes = signedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect);
+ if (protectionAttributes.size() > 1)
+ {
+ throw new CMSException("Only one instance of a cmsAlgorithmProtect attribute can be present");
+ }
+
+ if (protectionAttributes.size() > 0)
+ {
+ Attribute attr = Attribute.getInstance(protectionAttributes.get(0));
+ if (attr.getAttrValues().size() != 1)
+ {
+ throw new CMSException("A cmsAlgorithmProtect attribute MUST contain exactly one value");
+ }
+
+ CMSAlgorithmProtection algorithmProtection = CMSAlgorithmProtection.getInstance(attr.getAttributeValues()[0]);
+
+ if (!CMSUtils.isEquivalent(algorithmProtection.getDigestAlgorithm(), info.getDigestAlgorithm()))
+ {
+ throw new CMSException("CMS Algorithm Identifier Protection check failed for digestAlgorithm");
+ }
+
+ if (!CMSUtils.isEquivalent(algorithmProtection.getSignatureAlgorithm(), info.getDigestEncryptionAlgorithm()))
+ {
+ throw new CMSException("CMS Algorithm Identifier Protection check failed for signatureAlgorithm");
+ }
+ }
+ }
+ }
+
+ /**
+ * RFC 3852 11.4 Validate countersignature attribute(s)
+ *
+ * @param signedAttrTable signed attributes
+ * @throws CMSException when countersignature attribute was rejected
+ */
+ private void verifyCounterSignatureAttribute(AttributeTable signedAttrTable)
+ throws CMSException
+ {
+ if (signedAttrTable != null
+ && signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0)
+ {
+ throw new CMSException("A countersignature attribute MUST NOT be a signed attribute");
+ }
+
+ AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
+ if (unsignedAttrTable != null)
+ {
+ ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature);
+ for (int i = 0; i < csAttrs.size(); ++i)
+ {
+ Attribute csAttr = Attribute.getInstance(csAttrs.get(i));
+ if (csAttr.getAttrValues().size() < 1)
+ {
+ throw new CMSException("A countersignature attribute MUST contain at least one AttributeValue");
+ }
+
+ // Note: We don't recursively validate the countersignature value
+ }
+ }
+ }
+
+ /**
* Verify that the given verifier can successfully verify the signature on
* this SignerInformation object.
*
@@ -649,27 +692,28 @@
ASN1EncodableVector v = signedAttrTable.getAll(attrOID);
switch (v.size())
{
- case 0:
- return null;
- case 1:
+ case 0:
+ return null;
+ case 1:
+ {
+ Attribute t = (Attribute)v.get(0);
+ ASN1Set attrValues = t.getAttrValues();
+ if (attrValues.size() != 1)
{
- Attribute t = (Attribute)v.get(0);
- ASN1Set attrValues = t.getAttrValues();
- if (attrValues.size() != 1)
- {
- throw new CMSException("A " + printableName
- + " attribute MUST have a single attribute value");
- }
-
- return attrValues.getObjectAt(0).toASN1Primitive();
+ throw new CMSException("A " + printableName
+ + " attribute MUST have a single attribute value");
}
- default:
- throw new CMSException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the "
- + printableName + " attribute");
+
+ return attrValues.getObjectAt(0).toASN1Primitive();
+ }
+ default:
+ throw new CMSException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the "
+ + printableName + " attribute");
}
}
- private Time getSigningTime() throws CMSException
+ private Time getSigningTime()
+ throws CMSException
{
ASN1Primitive validSigningTime = getSingleValuedSignedAttribute(
CMSAttributes.signingTime, "signing-time");
@@ -693,27 +737,27 @@
* Return a signer information object with the passed in unsigned
* attributes replacing the ones that are current associated with
* the object passed in.
- *
- * @param signerInformation the signerInfo to be used as the basis.
+ *
+ * @param signerInformation the signerInfo to be used as the basis.
* @param unsignedAttributes the unsigned attributes to add.
* @return a copy of the original SignerInformationObject with the changed attributes.
*/
public static SignerInformation replaceUnsignedAttributes(
- SignerInformation signerInformation,
- AttributeTable unsignedAttributes)
+ SignerInformation signerInformation,
+ AttributeTable unsignedAttributes)
{
- SignerInfo sInfo = signerInformation.info;
- ASN1Set unsignedAttr = null;
-
+ SignerInfo sInfo = signerInformation.info;
+ ASN1Set unsignedAttr = null;
+
if (unsignedAttributes != null)
{
unsignedAttr = new DERSet(unsignedAttributes.toASN1EncodableVector());
}
-
+
return new SignerInformation(
- new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(),
- sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), unsignedAttr),
- signerInformation.contentType, signerInformation.content, null);
+ new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(),
+ sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), unsignedAttr),
+ signerInformation.contentType, signerInformation.content, null);
}
/**
@@ -721,17 +765,17 @@
* signatures attached as an unsigned attribute.
*
* @param signerInformation the signerInfo to be used as the basis.
- * @param counterSigners signer info objects carrying counter signature.
+ * @param counterSigners signer info objects carrying counter signature.
* @return a copy of the original SignerInformationObject with the changed attributes.
*/
public static SignerInformation addCounterSigners(
- SignerInformation signerInformation,
- SignerInformationStore counterSigners)
+ SignerInformation signerInformation,
+ SignerInformationStore counterSigners)
{
// TODO Perform checks from RFC 3852 11.4
- SignerInfo sInfo = signerInformation.info;
- AttributeTable unsignedAttr = signerInformation.getUnsignedAttributes();
+ SignerInfo sInfo = signerInformation.info;
+ AttributeTable unsignedAttr = signerInformation.getUnsignedAttributes();
ASN1EncodableVector v;
if (unsignedAttr != null)
@@ -745,7 +789,7 @@
ASN1EncodableVector sigs = new ASN1EncodableVector();
- for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext();)
+ for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext(); )
{
sigs.add(((SignerInformation)it.next()).toASN1Structure());
}
@@ -753,8 +797,23 @@
v.add(new Attribute(CMSAttributes.counterSignature, new DERSet(sigs)));
return new SignerInformation(
- new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(),
- sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), new DERSet(v)),
- signerInformation.contentType, signerInformation.content, null);
+ new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(),
+ sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), new DERSet(v)),
+ signerInformation.contentType, signerInformation.content, null);
+ }
+
+ private static AlgorithmIdentifier translateBrokenRSAPkcs7(AlgorithmIdentifier encryptionAlgorithm, AlgorithmIdentifier digestAlgorithm)
+ {
+ if (PKCSObjectIdentifiers.rsaEncryption.equals(encryptionAlgorithm.getAlgorithm()))
+ {
+ // Yes, some people really did this.
+ if (OIWObjectIdentifiers.sha1WithRSA.equals(digestAlgorithm.getAlgorithm())
+ || PKCSObjectIdentifiers.sha1WithRSAEncryption.equals(digestAlgorithm.getAlgorithm()))
+ {
+ return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
+ }
+ }
+
+ return digestAlgorithm;
}
}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
index e1b4fa5..082f3f0 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
@@ -4,6 +4,7 @@
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
import com.android.internal.org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import com.android.internal.org.bouncycastle.cms.CMSAttributeTableGenerator;
@@ -56,6 +57,13 @@
return this;
}
+ public JcaSignerInfoGeneratorBuilder setContentDigest(AlgorithmIdentifier contentDigest)
+ {
+ builder.setContentDigest(contentDigest);
+
+ return this;
+ }
+
public JcaSignerInfoGeneratorBuilder setSignedAttributeGenerator(CMSAttributeTableGenerator signedGen)
{
builder.setSignedAttributeGenerator(signedGen);
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java
index 13512d3..b587f40 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java
@@ -85,7 +85,7 @@
return new SignerInformationVerifier(sigAlgNameGen, sigAlgIDFinder, helper.createContentVerifierProvider(pubKey), digestProvider);
}
- private class Helper
+ private static class Helper
{
ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey)
throws OperatorCreationException
@@ -112,7 +112,7 @@
}
}
- private class NamedHelper
+ private static class NamedHelper
extends Helper
{
private final String providerName;
@@ -147,7 +147,7 @@
}
}
- private class ProviderHelper
+ private static class ProviderHelper
extends Helper
{
private final Provider provider;
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java
index b1e22fb..e0e58d3 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java
@@ -55,7 +55,7 @@
return new SignerInformationVerifier(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), helper.createContentVerifierProvider(pubKey), helper.createDigestCalculatorProvider());
}
- private class Helper
+ private static class Helper
{
ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey)
throws OperatorCreationException
@@ -82,7 +82,7 @@
}
}
- private class NamedHelper
+ private static class NamedHelper
extends Helper
{
private final String providerName;
@@ -117,7 +117,7 @@
}
}
- private class ProviderHelper
+ private static class ProviderHelper
extends Helper
{
private final Provider provider;
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JceAADStream.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JceAADStream.java
new file mode 100644
index 0000000..53a1084
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JceAADStream.java
@@ -0,0 +1,32 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms.jcajce;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.crypto.Cipher;
+
+class JceAADStream
+ extends OutputStream
+{
+ private static final byte[] SINGLE_BYTE = new byte[1];
+ private Cipher cipher;
+
+ JceAADStream(Cipher cipher)
+ {
+ this.cipher = cipher;
+ }
+
+ public void write(byte[] buf, int off, int len)
+ throws IOException
+ {
+ cipher.updateAAD(buf, off, len);
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ SINGLE_BYTE[0] = (byte)b;
+ cipher.updateAAD(SINGLE_BYTE, 0, 1);
+ }
+ }
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/openssl/CertificateTrustBlock.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/openssl/CertificateTrustBlock.java
new file mode 100644
index 0000000..8c11861
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/openssl/CertificateTrustBlock.java
@@ -0,0 +1,137 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.openssl;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.ASN1UTF8String;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERUTF8String;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertificateTrustBlock
+{
+ private ASN1Sequence uses;
+ private ASN1Sequence prohibitions;
+ private String alias;
+
+ public CertificateTrustBlock(Set<ASN1ObjectIdentifier> uses)
+ {
+ this(null, uses, null);
+ }
+
+ public CertificateTrustBlock(String alias, Set<ASN1ObjectIdentifier> uses)
+ {
+ this(alias, uses, null);
+ }
+
+ public CertificateTrustBlock(String alias, Set<ASN1ObjectIdentifier> uses, Set<ASN1ObjectIdentifier> prohibitions)
+ {
+ this.alias = alias;
+ this.uses = toSequence(uses);
+ this.prohibitions = toSequence(prohibitions);
+ }
+
+ CertificateTrustBlock(byte[] encoded)
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(encoded);
+
+ for (Enumeration en = seq.getObjects(); en.hasMoreElements();)
+ {
+ ASN1Encodable obj = (ASN1Encodable)en.nextElement();
+
+ if (obj instanceof ASN1Sequence)
+ {
+ this.uses = ASN1Sequence.getInstance(obj);
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ this.prohibitions = ASN1Sequence.getInstance((ASN1TaggedObject)obj, false);
+ }
+ else if (obj instanceof ASN1UTF8String)
+ {
+ this.alias = ASN1UTF8String.getInstance(obj).getString();
+ }
+ }
+ }
+
+ public String getAlias()
+ {
+ return alias;
+ }
+
+ public Set<ASN1ObjectIdentifier> getUses()
+ {
+ return toSet(uses);
+ }
+
+ public Set<ASN1ObjectIdentifier> getProhibitions()
+ {
+ return toSet(prohibitions);
+ }
+
+ private Set<ASN1ObjectIdentifier> toSet(ASN1Sequence seq)
+ {
+ if (seq != null)
+ {
+ Set<ASN1ObjectIdentifier> oids = new HashSet<ASN1ObjectIdentifier>(seq.size());
+
+ for (Enumeration en = seq.getObjects(); en.hasMoreElements(); )
+ {
+ oids.add(ASN1ObjectIdentifier.getInstance(en.nextElement()));
+ }
+
+ return oids;
+ }
+
+ return Collections.EMPTY_SET;
+ }
+
+ private ASN1Sequence toSequence(Set<ASN1ObjectIdentifier> oids)
+ {
+ if (oids == null || oids.isEmpty())
+ {
+ return null;
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (Iterator it = oids.iterator(); it.hasNext();)
+ {
+ v.add((ASN1Encodable)it.next());
+ }
+
+ return new DERSequence(v);
+ }
+
+ ASN1Sequence toASN1Sequence()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (uses != null)
+ {
+ v.add(uses);
+ }
+ if (prohibitions != null)
+ {
+ v.add(new DERTaggedObject(false, 0, prohibitions));
+ }
+ if (alias != null)
+ {
+ v.add(new DERUTF8String(alias));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/AADProcessor.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/AADProcessor.java
new file mode 100644
index 0000000..0477f70
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/AADProcessor.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import java.io.OutputStream;
+
+/**
+ * Base interface for extra methods required for handling associated data in AEAD ciphers.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface AADProcessor
+{
+ /**
+ * Return a stream to write associated data to in order to have it incorporated into the
+ * AEAD cipher's MAC.
+ *
+ * @return a stream for collecting associated data.
+ */
+ OutputStream getAADStream();
+
+ /**
+ * Return the final value of AEAD cipher's MAC.
+ *
+ * @return MAC value for the AEAD cipher.
+ */
+ byte[] getMAC();
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/AlgorithmNameFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/AlgorithmNameFinder.java
new file mode 100644
index 0000000..38776e1
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/AlgorithmNameFinder.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * General finder for converting OIDs and AlgorithmIdentifiers into strings.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface AlgorithmNameFinder
+{
+ /**
+ * Return true if the passed in objectIdentifier has a "human friendly" name associated with it.
+ *
+ * @param objectIdentifier the OID of interest.
+ * @return true if a name lookup exists for the OID, false otherwise.
+ */
+ boolean hasAlgorithmName(ASN1ObjectIdentifier objectIdentifier);
+
+ /**
+ * Return a string representation of the passed in objectIdentifier.
+ *
+ * @param objectIdentifier the OID of interest.
+ * @return a "human friendly" representation of the OID, the OID as a string if none available.
+ */
+ String getAlgorithmName(ASN1ObjectIdentifier objectIdentifier);
+
+ /**
+ * Return a string representation of the passed in AlgorithmIdentifier, based on the OID in the AlgorithmField, with the parameters
+ * included where appropriate.
+ *
+ * @param algorithmIdentifier the AlgorithmIdentifier of interest.
+ * @return a "human friendly" representation of the algorithmIdentifier, the identifiers OID as a string if none available.
+ */
+ String getAlgorithmName(AlgorithmIdentifier algorithmIdentifier);
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
index 0e3edd3..e350e8c 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
@@ -2,7 +2,9 @@
package com.android.internal.org.bouncycastle.operator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -10,6 +12,7 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
@@ -31,6 +34,9 @@
{
private static Map digestOids = new HashMap();
private static Map digestNameToOids = new HashMap();
+ private static Map digestOidToAlgIds = new HashMap();
+
+ private static Set shake256oids = new HashSet(); // signatures that use SHAKE-256
static
{
@@ -41,14 +47,18 @@
// digestOids.put(OIWObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
// digestOids.put(OIWObjectIdentifiers.md4WithRSA, PKCSObjectIdentifiers.md4);
// digestOids.put(OIWObjectIdentifiers.dsaWithSHA1, OIWObjectIdentifiers.idSHA1);
+ // digestOids.put(OIWObjectIdentifiers.md5WithRSA, PKCSObjectIdentifiers.md5);
// END Android-removed: Unsupported algorithms
digestOids.put(OIWObjectIdentifiers.sha1WithRSA, OIWObjectIdentifiers.idSHA1);
+ digestOids.put(PKCSObjectIdentifiers.rsaEncryption, NISTObjectIdentifiers.id_sha256);
digestOids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, NISTObjectIdentifiers.id_sha224);
digestOids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, NISTObjectIdentifiers.id_sha256);
digestOids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, NISTObjectIdentifiers.id_sha384);
digestOids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, NISTObjectIdentifiers.id_sha512);
// BEGIN Android-removed: Unsupported algorithms
+ // digestOids.put(PKCSObjectIdentifiers.sha512_224WithRSAEncryption, NISTObjectIdentifiers.id_sha512_224);
+ // digestOids.put(PKCSObjectIdentifiers.sha512_256WithRSAEncryption, NISTObjectIdentifiers.id_sha512_256);
// digestOids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, PKCSObjectIdentifiers.md2);
// digestOids.put(PKCSObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
// END Android-removed: Unsupported algorithms
@@ -69,6 +79,10 @@
digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, NISTObjectIdentifiers.id_sha256);
digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, NISTObjectIdentifiers.id_sha384);
digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, NISTObjectIdentifiers.id_sha512);
+ digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_224, NISTObjectIdentifiers.id_sha3_224);
+ digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_256, NISTObjectIdentifiers.id_sha3_256);
+ digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_384, NISTObjectIdentifiers.id_sha3_384);
+ digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_512, NISTObjectIdentifiers.id_sha3_512);
digestOids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, TeleTrusTObjectIdentifiers.ripemd160);
digestOids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, OIWObjectIdentifiers.idSHA1);
@@ -118,6 +132,54 @@
digestOids.put(GMObjectIdentifiers.sm2sign_with_sha384, NISTObjectIdentifiers.id_sha384);
digestOids.put(GMObjectIdentifiers.sm2sign_with_sha512, NISTObjectIdentifiers.id_sha512);
digestOids.put(GMObjectIdentifiers.sm2sign_with_sm3, GMObjectIdentifiers.sm3);
+
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(BCObjectIdentifiers.falcon, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.falcon_512, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.falcon_1024, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(BCObjectIdentifiers.picnic_signature, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.picnic_with_sha512, NISTObjectIdentifiers.id_sha512);
+ digestOids.put(BCObjectIdentifiers.picnic_with_sha3_512, NISTObjectIdentifiers.id_sha3_512);
+ digestOids.put(BCObjectIdentifiers.picnic_with_shake256, NISTObjectIdentifiers.id_shake256);
+
+// digestOids.put(GMObjectIdentifiers.sm2sign_with_rmd160, TeleTrusTObjectIdentifiers.ripemd160);
+// digestOids.put(GMObjectIdentifiers.sm2sign_with_sha1, OIWObjectIdentifiers.idSHA1);
+// digestOids.put(GMObjectIdentifiers.sm2sign_with_sha224, NISTObjectIdentifiers.id_sha224);
+ digestOids.put(GMObjectIdentifiers.sm2sign_with_sha256, NISTObjectIdentifiers.id_sha256);
+// digestOids.put(GMObjectIdentifiers.sm2sign_with_sha384, NISTObjectIdentifiers.id_sha384);
+// digestOids.put(GMObjectIdentifiers.sm2sign_with_sha512, NISTObjectIdentifiers.id_sha512);
+ digestOids.put(GMObjectIdentifiers.sm2sign_with_sm3, GMObjectIdentifiers.sm3);
+
+ digestOids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128, NISTObjectIdentifiers.id_shake128);
+ digestOids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(CMSObjectIdentifiers.id_ecdsa_with_shake128, NISTObjectIdentifiers.id_shake128);
+ digestOids.put(CMSObjectIdentifiers.id_ecdsa_with_shake256, NISTObjectIdentifiers.id_shake256);
*/
// END Android-removed: Unsupported algorithms
@@ -144,6 +206,8 @@
digestNameToOids.put("SHA3-384", NISTObjectIdentifiers.id_sha3_384);
digestNameToOids.put("SHA3-512", NISTObjectIdentifiers.id_sha3_512);
+ digestNameToOids.put("SHAKE128", NISTObjectIdentifiers.id_shake128);
+ digestNameToOids.put("SHAKE256", NISTObjectIdentifiers.id_shake256);
digestNameToOids.put("SHAKE-128", NISTObjectIdentifiers.id_shake128);
digestNameToOids.put("SHAKE-256", NISTObjectIdentifiers.id_shake256);
@@ -164,20 +228,106 @@
digestNameToOids.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256);
digestNameToOids.put("SM3", GMObjectIdentifiers.sm3);
+
+ // IETF RFC 3370
+ addDigestAlgId(OIWObjectIdentifiers.idSHA1, true);
+ // IETF RFC 5754
+ addDigestAlgId(NISTObjectIdentifiers.id_sha224, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha256, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha384, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha512, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha512_224, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha512_256, false);
+
+ // NIST CSOR
+ addDigestAlgId(NISTObjectIdentifiers.id_sha3_224, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha3_256, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha3_384, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_sha3_512, false);
+
+ // RFC 8702
+ addDigestAlgId(NISTObjectIdentifiers.id_shake128, false);
+ addDigestAlgId(NISTObjectIdentifiers.id_shake256, false);
+
+ // RFC 4357
+ addDigestAlgId(CryptoProObjectIdentifiers.gostR3411, true);
+
+ // draft-deremin-rfc4491
+ addDigestAlgId(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256, false);
+ addDigestAlgId(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, false);
+
+ // IETF RFC 1319
+ addDigestAlgId(PKCSObjectIdentifiers.md2, true);
+ // IETF RFC 1320
+ addDigestAlgId(PKCSObjectIdentifiers.md4, true);
+ // IETF RFC 1321
+ addDigestAlgId(PKCSObjectIdentifiers.md5, true);
+
+ // found no standard which specified the handle of AlgorithmIdentifier.parameters,
+ // so let it as before.
+ addDigestAlgId(TeleTrusTObjectIdentifiers.ripemd128, true);
+ addDigestAlgId(TeleTrusTObjectIdentifiers.ripemd160, true);
+ addDigestAlgId(TeleTrusTObjectIdentifiers.ripemd256, true);
+
+ shake256oids.add(EdECObjectIdentifiers.id_Ed448);
+
+ shake256oids.add(BCObjectIdentifiers.dilithium2);
+ shake256oids.add(BCObjectIdentifiers.dilithium3);
+ shake256oids.add(BCObjectIdentifiers.dilithium5);
+ shake256oids.add(BCObjectIdentifiers.dilithium2_aes);
+ shake256oids.add(BCObjectIdentifiers.dilithium3_aes);
+ shake256oids.add(BCObjectIdentifiers.dilithium5_aes);
+
+ shake256oids.add(BCObjectIdentifiers.falcon_512);
+ shake256oids.add(BCObjectIdentifiers.falcon_1024);
*/
// END Android-removed: Unsupported algorithms
}
+ private static void addDigestAlgId(ASN1ObjectIdentifier oid, boolean withNullParams)
+ {
+ AlgorithmIdentifier algId;
+ if (withNullParams)
+ {
+ algId = new AlgorithmIdentifier(oid, DERNull.INSTANCE);
+ }
+ else
+ {
+ algId = new AlgorithmIdentifier(oid);
+ }
+ digestOidToAlgIds.put(oid, algId);
+ }
+
public AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId)
{
- AlgorithmIdentifier digAlgId;
+ ASN1ObjectIdentifier sigAlgOid = sigAlgId.getAlgorithm();
- if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ if (shake256oids.contains(sigAlgOid))
{
- digAlgId = RSASSAPSSparams.getInstance(sigAlgId.getParameters()).getHashAlgorithm();
+ // TODO: it seems it's very hard to find people accepting SHAKE256-len at the moment...
+ // Android-removed: unsupported
+ // if (!sigAlgOid.equals(EdECObjectIdentifiers.id_Ed448))
+ // {
+ // return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256);
+ // }
+
+ return new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256_len, new ASN1Integer(512));
+ }
+
+ ASN1ObjectIdentifier digAlgOid;
+ if (sigAlgOid.equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ digAlgOid = RSASSAPSSparams.getInstance(sigAlgId.getParameters()).getHashAlgorithm().getAlgorithm();
+ }
+ else if (sigAlgOid.equals(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig))
+ {
+ digAlgOid = NISTObjectIdentifiers.id_sha256;
}
// BEGIN Android-removed: Unsupported algorithms
- /*
+ /* // else if (sigAlgOid.equals(EdECObjectIdentifiers.id_Ed25519))
+ {
+ digAlgOid = NISTObjectIdentifiers.id_sha512;
+ }
else if (sigAlgId.getAlgorithm().equals(EdECObjectIdentifiers.id_Ed25519))
{
digAlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512);
@@ -190,14 +340,47 @@
// END Android-removed: Unsupported algorithms
else
{
- digAlgId = new AlgorithmIdentifier((ASN1ObjectIdentifier)digestOids.get(sigAlgId.getAlgorithm()), DERNull.INSTANCE);
+ digAlgOid = (ASN1ObjectIdentifier)digestOids.get(sigAlgOid);
}
- return digAlgId;
+ return find(digAlgOid);
+ }
+
+ public AlgorithmIdentifier find(ASN1ObjectIdentifier digAlgOid)
+ {
+ if (digAlgOid == null)
+ {
+ throw new NullPointerException("digest OID is null");
+ }
+
+ AlgorithmIdentifier digAlgId = (AlgorithmIdentifier)digestOidToAlgIds.get(digAlgOid);
+ if (digAlgId == null)
+ {
+ return new AlgorithmIdentifier(digAlgOid);
+ }
+ else
+ {
+ return digAlgId;
+ }
}
public AlgorithmIdentifier find(String digAlgName)
{
- return new AlgorithmIdentifier((ASN1ObjectIdentifier)digestNameToOids.get(digAlgName), DERNull.INSTANCE);
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)digestNameToOids.get(digAlgName);
+ if (oid != null)
+ {
+ return find(oid);
+ }
+
+ try
+ {
+ return find(new ASN1ObjectIdentifier(digAlgName));
+ }
+ catch (RuntimeException e)
+ {
+ // ignore - tried it but it didn't work...
+ }
+
+ return null;
}
-}
\ No newline at end of file
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultMacAlgorithmIdentifierFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultMacAlgorithmIdentifierFinder.java
new file mode 100644
index 0000000..3a2dcff
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultMacAlgorithmIdentifierFinder.java
@@ -0,0 +1,42 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultMacAlgorithmIdentifierFinder
+ implements MacAlgorithmIdentifierFinder
+{
+ private static Map macNameToAlgIds = new HashMap();
+
+ static
+ {
+ macNameToAlgIds.put("HMACSHA1", new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1));
+ macNameToAlgIds.put("HMACSHA224", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA224, DERNull.INSTANCE));
+ macNameToAlgIds.put("HMACSHA256", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA256, DERNull.INSTANCE));
+ macNameToAlgIds.put("HMACSHA384", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA384, DERNull.INSTANCE));
+ macNameToAlgIds.put("HMACSHA512", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA512, DERNull.INSTANCE));
+ macNameToAlgIds.put("HMACSHA512-224", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA512_224, DERNull.INSTANCE));
+ macNameToAlgIds.put("HMACSHA512-256", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA512_256, DERNull.INSTANCE));
+
+ macNameToAlgIds.put("HMACSHA3-224", new AlgorithmIdentifier(NISTObjectIdentifiers.id_hmacWithSHA3_224));
+ macNameToAlgIds.put("HMACSHA3-256", new AlgorithmIdentifier(NISTObjectIdentifiers.id_hmacWithSHA3_256));
+ macNameToAlgIds.put("HMACSHA3-384", new AlgorithmIdentifier(NISTObjectIdentifiers.id_hmacWithSHA3_384));
+ macNameToAlgIds.put("HMACSHA3-512", new AlgorithmIdentifier(NISTObjectIdentifiers.id_hmacWithSHA3_512));
+ }
+
+ public AlgorithmIdentifier find(String macAlgName)
+ {
+ return (AlgorithmIdentifier)macNameToAlgIds.get(Strings.toUpperCase(macAlgName));
+ }
+}
\ No newline at end of file
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
index 0ed6507..f7562d8 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
@@ -13,11 +13,13 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
// import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -54,6 +56,7 @@
static
{
// BEGIN Android-removed: Unsupported algorithms
+ // algorithms.put("COMPOSITE", MiscObjectIdentifiers.id_alg_composite);
// algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption);
// algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption);
// END Android-removed: Unsupported algorithms
@@ -69,6 +72,10 @@
algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption);
algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption);
algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption);
+ algorithms.put("SHA512(224)WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512_224WithRSAEncryption);
+ algorithms.put("SHA512(224)WITHRSA", PKCSObjectIdentifiers.sha512_224WithRSAEncryption);
+ algorithms.put("SHA512(256)WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512_256WithRSAEncryption);
+ algorithms.put("SHA512(256)WITHRSA", PKCSObjectIdentifiers.sha512_256WithRSAEncryption);
algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
@@ -136,12 +143,7 @@
algorithms.put("GOST3411-2012-512WITHECGOST3410-2012-512", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512);
algorithms.put("GOST3411-2012-256WITHGOST3410-2012-256", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256);
algorithms.put("GOST3411-2012-512WITHGOST3410-2012-512", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512);
- algorithms.put("SHA1WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA1);
- algorithms.put("SHA224WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA224);
- algorithms.put("SHA256WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA256);
- algorithms.put("SHA384WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA384);
- algorithms.put("SHA512WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA512);
- algorithms.put("RIPEMD160WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_RIPEMD160);
+
algorithms.put("SHA1WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1);
algorithms.put("SHA224WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_224);
algorithms.put("SHA256WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_256);
@@ -159,12 +161,33 @@
algorithms.put("SHA256WITHSM2", GMObjectIdentifiers.sm2sign_with_sha256);
algorithms.put("SHA384WITHSM2", GMObjectIdentifiers.sm2sign_with_sha384);
algorithms.put("SHA512WITHSM2", GMObjectIdentifiers.sm2sign_with_sha512);
+ algorithms.put("SHA1WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA1);
+ algorithms.put("RIPEMD160WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_RIPEMD160);
+ algorithms.put("SHA224WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA224);
+ algorithms.put("SHA256WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA256);
+ algorithms.put("SHA384WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA384);
+ algorithms.put("SHA512WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA512);
+ algorithms.put("SHA3-224WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA3_224);
+ algorithms.put("SHA3-256WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA3_256);
+ algorithms.put("SHA3-384WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA3_384);
+ algorithms.put("SHA3-512WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA3_512);
+
+ // RFC 8702
+ algorithms.put("SHAKE128WITHRSAPSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128);
+ algorithms.put("SHAKE256WITHRSAPSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256);
+ algorithms.put("SHAKE128WITHRSASSA-PSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128);
+ algorithms.put("SHAKE256WITHRSASSA-PSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256);
+ algorithms.put("SHAKE128WITHECDSA", CMSObjectIdentifiers.id_ecdsa_with_shake128);
+ algorithms.put("SHAKE256WITHECDSA", CMSObjectIdentifiers.id_ecdsa_with_shake256);
+
algorithms.put("SM3WITHSM2", GMObjectIdentifiers.sm2sign_with_sm3);
algorithms.put("SHA256WITHXMSS", BCObjectIdentifiers.xmss_SHA256ph);
algorithms.put("SHA512WITHXMSS", BCObjectIdentifiers.xmss_SHA512ph);
algorithms.put("SHAKE128WITHXMSS", BCObjectIdentifiers.xmss_SHAKE128ph);
algorithms.put("SHAKE256WITHXMSS", BCObjectIdentifiers.xmss_SHAKE256ph);
+ algorithms.put("SHAKE128(512)WITHXMSS", BCObjectIdentifiers.xmss_SHAKE128_512ph);
+ algorithms.put("SHAKE256(1024)WITHXMSS", BCObjectIdentifiers.xmss_SHAKE256_1024ph);
algorithms.put("SHA256WITHXMSSMT", BCObjectIdentifiers.xmss_mt_SHA256ph);
algorithms.put("SHA512WITHXMSSMT", BCObjectIdentifiers.xmss_mt_SHA512ph);
@@ -180,6 +203,8 @@
algorithms.put("SHA512WITHXMSSMT-SHA512", BCObjectIdentifiers.xmss_mt_SHA512ph);
algorithms.put("SHAKE128WITHXMSSMT-SHAKE128", BCObjectIdentifiers.xmss_mt_SHAKE128ph);
algorithms.put("SHAKE256WITHXMSSMT-SHAKE256", BCObjectIdentifiers.xmss_mt_SHAKE256ph);
+ algorithms.put("SHAKE128(512)WITHXMSSMT-SHAKE128", BCObjectIdentifiers.xmss_mt_SHAKE128_512ph);
+ algorithms.put("SHAKE256(1024)WITHXMSSMT-SHAKE256", BCObjectIdentifiers.xmss_mt_SHAKE256_1024ph);
algorithms.put("LMS", PKCSObjectIdentifiers.id_alg_hss_lms_hashsig);
@@ -197,6 +222,47 @@
algorithms.put("QTESLA-P-I", BCObjectIdentifiers.qTESLA_p_I);
algorithms.put("QTESLA-P-III", BCObjectIdentifiers.qTESLA_p_III);
+ algorithms.put("SPHINCS+", BCObjectIdentifiers.sphincsPlus);
+ algorithms.put("SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus);
+ algorithms.put("SPHINCS+-SHA2-128S", BCObjectIdentifiers.sphincsPlus_sha2_128s);
+ algorithms.put("SPHINCS+-SHA2-128F", BCObjectIdentifiers.sphincsPlus_sha2_128f);
+ algorithms.put("SPHINCS+-SHA2-192S", BCObjectIdentifiers.sphincsPlus_sha2_192s);
+ algorithms.put("SPHINCS+-SHA2-192F", BCObjectIdentifiers.sphincsPlus_sha2_192f);
+ algorithms.put("SPHINCS+-SHA2-256S", BCObjectIdentifiers.sphincsPlus_sha2_256s);
+ algorithms.put("SPHINCS+-SHA2-256F", BCObjectIdentifiers.sphincsPlus_sha2_256f);
+ algorithms.put("SPHINCS+-SHAKE-128S", BCObjectIdentifiers.sphincsPlus_shake_128s);
+ algorithms.put("SPHINCS+-SHAKE-128F", BCObjectIdentifiers.sphincsPlus_shake_128f);
+ algorithms.put("SPHINCS+-SHAKE-192S", BCObjectIdentifiers.sphincsPlus_shake_192s);
+ algorithms.put("SPHINCS+-SHAKE-192F", BCObjectIdentifiers.sphincsPlus_shake_192f);
+ algorithms.put("SPHINCS+-SHAKE-256S", BCObjectIdentifiers.sphincsPlus_shake_256s);
+ algorithms.put("SPHINCS+-SHAKE-256F", BCObjectIdentifiers.sphincsPlus_shake_256f);
+ algorithms.put("SPHINCS+-HARAKA-128S-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_128s_r3);
+ algorithms.put("SPHINCS+-HARAKA-128F-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_128f_r3);
+ algorithms.put("SPHINCS+-HARAKA-192S-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_192s_r3);
+ algorithms.put("SPHINCS+-HARAKA-192F-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_192f_r3);
+ algorithms.put("SPHINCS+-HARAKA-256S-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_256s_r3);
+ algorithms.put("SPHINCS+-HARAKA-256F-ROBUST", BCObjectIdentifiers.sphincsPlus_haraka_256f_r3);
+ algorithms.put("SPHINCS+-HARAKA-128S-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple);
+ algorithms.put("SPHINCS+-HARAKA-128F-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple);
+ algorithms.put("SPHINCS+-HARAKA-192S-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple);
+ algorithms.put("SPHINCS+-HARAKA-192F-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple);
+ algorithms.put("SPHINCS+-HARAKA-256S-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple);
+ algorithms.put("SPHINCS+-HARAKA-256F-SIMPLE", BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple);
+ algorithms.put("SPHINCSPLUS", BCObjectIdentifiers.sphincsPlus);
+ algorithms.put("DILITHIUM2", BCObjectIdentifiers.dilithium2);
+ algorithms.put("DILITHIUM3", BCObjectIdentifiers.dilithium3);
+ algorithms.put("DILITHIUM5", BCObjectIdentifiers.dilithium5);
+ algorithms.put("DILITHIUM2-AES", BCObjectIdentifiers.dilithium2_aes);
+ algorithms.put("DILITHIUM3-AES", BCObjectIdentifiers.dilithium3_aes);
+ algorithms.put("DILITHIUM5-AES", BCObjectIdentifiers.dilithium5_aes);
+
+ algorithms.put("FALCON-512", BCObjectIdentifiers.falcon_512);
+ algorithms.put("FALCON-1024", BCObjectIdentifiers.falcon_1024);
+
+ algorithms.put("PICNIC", BCObjectIdentifiers.picnic_signature);
+ algorithms.put("SHA512WITHPICNIC", BCObjectIdentifiers.picnic_with_sha512);
+ algorithms.put("SHA3-512WITHPICNIC", BCObjectIdentifiers.picnic_with_sha3_512);
+ algorithms.put("SHAKE256WITHPICNIC", BCObjectIdentifiers.picnic_with_shake256);
*/
// END Android-removed: Unsupported algorithms
@@ -228,6 +294,15 @@
noParams.add(NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
noParams.add(NISTObjectIdentifiers.id_ecdsa_with_sha3_512);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA224);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA256);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA384);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA512);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA3_224);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA3_256);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA3_384);
+ noParams.add(BSIObjectIdentifiers.ecdsa_plain_SHA3_512);
+
//
// RFC 4491
//
@@ -243,6 +318,67 @@
noParams.add(BCObjectIdentifiers.sphincs256_with_SHA3_512);
//
+ // SPHINCS-PLUS
+ //
+ noParams.add(BCObjectIdentifiers.sphincsPlus);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_128s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_128f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_192s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_192f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_256s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_256f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_128f);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_128s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_128f);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_192s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_192f);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_192s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_192f);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_256s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_sha2_256f);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_256s);
+ noParams.add(BCObjectIdentifiers.sphincsPlus_shake_256f);
+
+ //
+ // Dilithium
+ //
+ noParams.add(BCObjectIdentifiers.dilithium);
+ noParams.add(BCObjectIdentifiers.dilithium2);
+ noParams.add(BCObjectIdentifiers.dilithium3);
+ noParams.add(BCObjectIdentifiers.dilithium5);
+ noParams.add(BCObjectIdentifiers.dilithium2_aes);
+ noParams.add(BCObjectIdentifiers.dilithium3_aes);
+ noParams.add(BCObjectIdentifiers.dilithium5_aes);
+
+ //
+ // Falcon
+ //
+ noParams.add(BCObjectIdentifiers.falcon);
+ noParams.add(BCObjectIdentifiers.falcon_512);
+ noParams.add(BCObjectIdentifiers.falcon_1024);
+
+ //
+ // Picnic
+ //
+ noParams.add(BCObjectIdentifiers.picnic_signature);
+ noParams.add(BCObjectIdentifiers.picnic_with_sha512);
+ noParams.add(BCObjectIdentifiers.picnic_with_sha3_512);
+ noParams.add(BCObjectIdentifiers.picnic_with_shake256);
+
+ //
// XMSS
//
noParams.add(BCObjectIdentifiers.xmss_SHA256ph);
@@ -253,6 +389,8 @@
noParams.add(BCObjectIdentifiers.xmss_mt_SHA512ph);
noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE128ph);
noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE256ph);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE128ph);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE256ph);
noParams.add(BCObjectIdentifiers.xmss_SHA256);
noParams.add(BCObjectIdentifiers.xmss_SHA512);
@@ -286,6 +424,16 @@
noParams.add(EdECObjectIdentifiers.id_Ed25519);
noParams.add(EdECObjectIdentifiers.id_Ed448);
*/
+
+ // EdDSA
+ // noParams.add(EdECObjectIdentifiers.id_Ed25519);
+ // noParams.add(EdECObjectIdentifiers.id_Ed448);
+
+ // RFC 8702
+ // noParams.add(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128);
+ // noParams.add(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256);
+ // noParams.add(CMSObjectIdentifiers.id_ecdsa_with_shake128);
+ // noParams.add(CMSObjectIdentifiers.id_ecdsa_with_shake256);
// END Android-removed: Unsupported algorithms
//
@@ -298,6 +446,8 @@
pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512WithRSAEncryption);
// BEGIN Android-removed: Unsupported algorithms
/*
+ pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512_224WithRSAEncryption);
+ pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512_256WithRSAEncryption);
pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
@@ -361,6 +511,8 @@
// digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, TeleTrusTObjectIdentifiers.ripemd256);
// digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, CryptoProObjectIdentifiers.gostR3411);
// digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, CryptoProObjectIdentifiers.gostR3411);
+ // digestOids.put(PKCSObjectIdentifiers.sha512_224WithRSAEncryption, NISTObjectIdentifiers.id_sha512_224);
+ // digestOids.put(PKCSObjectIdentifiers.sha512_256WithRSAEncryption, NISTObjectIdentifiers.id_sha512_256);
// END Android-removed: Unsupported algorithms
digestOids.put(NISTObjectIdentifiers.dsa_with_sha224, NISTObjectIdentifiers.id_sha224);
digestOids.put(NISTObjectIdentifiers.dsa_with_sha256, NISTObjectIdentifiers.id_sha256);
@@ -404,37 +556,54 @@
digestOids.put(GMObjectIdentifiers.sm2sign_with_sha384, NISTObjectIdentifiers.id_sha384);
digestOids.put(GMObjectIdentifiers.sm2sign_with_sha512, NISTObjectIdentifiers.id_sha512);
digestOids.put(GMObjectIdentifiers.sm2sign_with_sm3, GMObjectIdentifiers.sm3);
+
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128s, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_128f, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128s, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_128f, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192s, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_192f, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192s, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_192f, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256s, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_sha2_256f, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256s, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(BCObjectIdentifiers.sphincsPlus_shake_256f, NISTObjectIdentifiers.id_shake256);
+
+ digestOids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128, NISTObjectIdentifiers.id_shake128);
+ digestOids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256, NISTObjectIdentifiers.id_shake256);
+ digestOids.put(CMSObjectIdentifiers.id_ecdsa_with_shake128, NISTObjectIdentifiers.id_shake128);
+ digestOids.put(CMSObjectIdentifiers.id_ecdsa_with_shake256, NISTObjectIdentifiers.id_shake256);
*/
// END Android-removed: Unsupported algorithms
}
- private static AlgorithmIdentifier generate(String signatureAlgorithm)
- {
- AlgorithmIdentifier sigAlgId;
-
- String algorithmName = Strings.toUpperCase(signatureAlgorithm);
- ASN1ObjectIdentifier sigOID = (ASN1ObjectIdentifier)algorithms.get(algorithmName);
- if (sigOID == null)
- {
- throw new IllegalArgumentException("Unknown signature type requested: " + algorithmName);
- }
-
- if (noParams.contains(sigOID))
- {
- sigAlgId = new AlgorithmIdentifier(sigOID);
- }
- else if (params.containsKey(algorithmName))
- {
- sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable)params.get(algorithmName));
- }
- else
- {
- sigAlgId = new AlgorithmIdentifier(sigOID, DERNull.INSTANCE);
- }
-
- return sigAlgId;
- }
-
private static RSASSAPSSparams createPSSParams(AlgorithmIdentifier hashAlgId, int saltSize)
{
return new RSASSAPSSparams(
@@ -446,6 +615,26 @@
public AlgorithmIdentifier find(String sigAlgName)
{
- return generate(sigAlgName);
+ String algorithmName = Strings.toUpperCase(sigAlgName);
+ ASN1ObjectIdentifier sigOID = (ASN1ObjectIdentifier)algorithms.get(algorithmName);
+ if (sigOID == null)
+ {
+ throw new IllegalArgumentException("Unknown signature type requested: " + sigAlgName);
+ }
+
+ AlgorithmIdentifier sigAlgId;
+ if (noParams.contains(sigOID))
+ {
+ sigAlgId = new AlgorithmIdentifier(sigOID);
+ }
+ else if (params.containsKey(algorithmName))
+ {
+ sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable)params.get(algorithmName));
+ }
+ else
+ {
+ sigAlgId = new AlgorithmIdentifier(sigOID, DERNull.INSTANCE);
+ }
+ return sigAlgId;
}
-}
\ No newline at end of file
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultSignatureNameFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultSignatureNameFinder.java
new file mode 100644
index 0000000..3cfd391
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultSignatureNameFinder.java
@@ -0,0 +1,172 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+// BEGIN Android-removed: unsupported algorithms
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
+// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
+// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+// END Android-removed: unsupported algorithms
+
+/**
+ * Class for return signature names from OIDs or AlgorithmIdentifiers
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultSignatureNameFinder
+ implements AlgorithmNameFinder
+{
+ private static final Map oids = new HashMap();
+ private static final Map digests = new HashMap();
+
+ static
+ {
+ //
+ // reverse mappings
+ //
+ // BEGIN Android-removed: unsupported algorithms
+ oids.put(PKCSObjectIdentifiers.id_RSASSA_PSS, "RSASSA-PSS");
+ // oids.put(EdECObjectIdentifiers.id_Ed25519, "ED25519");
+ // oids.put(EdECObjectIdentifiers.id_Ed448, "ED448");
+ oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA");
+ // oids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128, "SHAKE128WITHRSAPSS");
+ // oids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256, "SHAKE256WITHRSAPSS");
+ // oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410");
+ // oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410");
+ // oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "GOST3411-2012-256WITHECGOST3410-2012-256");
+ // oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "GOST3411-2012-512WITHECGOST3410-2012-512");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_224, "SHA3-224WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_256, "SHA3-256WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_384, "SHA3-384WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA3_512, "SHA3-512WITHPLAIN-ECDSA");
+ // oids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160WITHPLAIN-ECDSA");
+ // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1WITHCVC-ECDSA");
+ // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224WITHCVC-ECDSA");
+ // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256WITHCVC-ECDSA");
+ // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384WITHCVC-ECDSA");
+ // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512WITHCVC-ECDSA");
+ oids.put(IsaraObjectIdentifiers.id_alg_xmss, "XMSS");
+ oids.put(IsaraObjectIdentifiers.id_alg_xmssmt, "XMSSMT");
+ oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, "RIPEMD128WITHRSA");
+ oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, "RIPEMD160WITHRSA");
+ oids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, "RIPEMD256WITHRSA");
+ oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA");
+ oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA");
+ oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA");
+ // oids.put(CMSObjectIdentifiers.id_ecdsa_with_shake128, "SHAKE128WITHECDSA");
+ // oids.put(CMSObjectIdentifiers.id_ecdsa_with_shake256, "SHAKE256WITHECDSA");
+ oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
+ oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA");
+ oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA");
+ oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA");
+ // END Android-removed: unsupported algorithms
+
+ digests.put(OIWObjectIdentifiers.idSHA1, "SHA1");
+ digests.put(NISTObjectIdentifiers.id_sha224, "SHA224");
+ digests.put(NISTObjectIdentifiers.id_sha256, "SHA256");
+ digests.put(NISTObjectIdentifiers.id_sha384, "SHA384");
+ digests.put(NISTObjectIdentifiers.id_sha512, "SHA512");
+ digests.put(NISTObjectIdentifiers.id_sha3_224, "SHA3-224");
+ digests.put(NISTObjectIdentifiers.id_sha3_256, "SHA3-256");
+ digests.put(NISTObjectIdentifiers.id_sha3_384, "SHA3-384");
+ digests.put(NISTObjectIdentifiers.id_sha3_512, "SHA3-512");
+ digests.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD128");
+ digests.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160");
+ digests.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256");
+ }
+
+ public boolean hasAlgorithmName(ASN1ObjectIdentifier objectIdentifier)
+ {
+ return oids.containsKey(objectIdentifier);
+ }
+
+ public String getAlgorithmName(ASN1ObjectIdentifier objectIdentifier)
+ {
+ String name = (String)oids.get(objectIdentifier);
+ if (name != null)
+ {
+ return name;
+ }
+ return objectIdentifier.getId();
+ }
+
+ /**
+ * Return the signature name for the passed in algorithm identifier. For signatures
+ * that require parameters, like RSASSA-PSS, this is the best one to use.
+ *
+ * @param algorithmIdentifier the AlgorithmIdentifier of interest.
+ * @return a string representation of the name.
+ */
+ public String getAlgorithmName(AlgorithmIdentifier algorithmIdentifier)
+ {
+ ASN1Encodable params = algorithmIdentifier.getParameters();
+ if (params != null && !DERNull.INSTANCE.equals(params))
+ {
+ if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
+ AlgorithmIdentifier mgfAlg = rsaParams.getMaskGenAlgorithm();
+ if (mgfAlg.getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1))
+ {
+ AlgorithmIdentifier digAlg = rsaParams.getHashAlgorithm();
+ ASN1ObjectIdentifier mgfHashOid = AlgorithmIdentifier.getInstance(mgfAlg.getParameters()).getAlgorithm();
+ if (mgfHashOid.equals(digAlg.getAlgorithm()))
+ {
+ return getDigestName(digAlg.getAlgorithm()) + "WITHRSAANDMGF1";
+ }
+ else
+ {
+ return getDigestName(digAlg.getAlgorithm()) + "WITHRSAANDMGF1USING" + getDigestName(mgfHashOid);
+ }
+ }
+ return getDigestName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAAND" + mgfAlg.getAlgorithm().getId();
+ }
+ }
+
+ if (oids.containsKey(algorithmIdentifier.getAlgorithm()))
+ {
+ return (String)oids.get(algorithmIdentifier.getAlgorithm());
+ }
+
+ return algorithmIdentifier.getAlgorithm().getId();
+ }
+
+ private static String getDigestName(ASN1ObjectIdentifier oid)
+ {
+ String name = (String)digests.get(oid);
+ if (name != null)
+ {
+ return name;
+ }
+ return oid.getId();
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java
index 168c48d..3fba9b7 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.operator;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
/**
@@ -19,6 +20,15 @@
/**
* Find the algorithm identifier that matches with
+ * the passed in digest OID.
+ *
+ * @param digestOid the OID of the digest algorithm of interest.
+ * @return an algorithm identifier for the digest signature.
+ */
+ AlgorithmIdentifier find(ASN1ObjectIdentifier digestOid);
+
+ /**
+ * Find the algorithm identifier that matches with
* the passed in digest name.
*
* @param digAlgName the name of the digest algorithm of interest.
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/InputAEADDecryptor.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/InputAEADDecryptor.java
new file mode 100644
index 0000000..f7b3a25
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/InputAEADDecryptor.java
@@ -0,0 +1,11 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+/**
+ * Base interface for an input consuming AEAD Decryptor supporting associated text.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface InputAEADDecryptor
+ extends InputDecryptor, AADProcessor
+{
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/MacAlgorithmIdentifierFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/MacAlgorithmIdentifierFinder.java
new file mode 100644
index 0000000..d770380
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/MacAlgorithmIdentifierFinder.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface MacAlgorithmIdentifierFinder
+{
+ /**
+ * Find the algorithm identifier that matches with
+ * the passed in digest name.
+ *
+ * @param macAlgName the name of the digest algorithm of interest.
+ * @return an algorithm identifier for the MAC.
+ */
+ AlgorithmIdentifier find(String macAlgName);
+}
\ No newline at end of file
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/MacCaptureStream.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/MacCaptureStream.java
new file mode 100644
index 0000000..26b0408
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/MacCaptureStream.java
@@ -0,0 +1,69 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * A generic class for capturing the mac data at the end of a encrypted data stream.
+ * <p>
+ * Note: this class will not close the underlying stream.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class MacCaptureStream
+ extends OutputStream
+{
+ private final OutputStream cOut;
+ private final byte[] mac;
+
+ int macIndex = 0;
+
+ public MacCaptureStream(OutputStream cOut, int macLength)
+ {
+ this.cOut = cOut;
+ this.mac = new byte[macLength];
+ }
+
+ public void write(byte[] buf, int off, int len)
+ throws IOException
+ {
+ if (len >= mac.length)
+ {
+ cOut.write(mac, 0, macIndex);
+ macIndex = mac.length;
+ System.arraycopy(buf, off + len - mac.length, mac, 0, mac.length);
+ cOut.write(buf, off, len - mac.length);
+ }
+ else
+ {
+ for (int i = 0; i != len; i++)
+ {
+ write(buf[off + i]);
+ }
+ }
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ if (macIndex == mac.length)
+ {
+ byte b1 = mac[0];
+ System.arraycopy(mac, 1, mac, 0, mac.length - 1);
+ mac[mac.length - 1] = (byte)b;
+ cOut.write(b1);
+ }
+ else
+ {
+ mac[macIndex++] = (byte)b;
+ }
+ }
+
+ public byte[] getMac()
+ {
+ return Arrays.clone(mac);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/PBEMacCalculatorProvider.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/PBEMacCalculatorProvider.java
new file mode 100644
index 0000000..494d32d
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/PBEMacCalculatorProvider.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PBEMacCalculatorProvider
+{
+ MacCalculator get(AlgorithmIdentifier algorithm, char[] password)
+ throws OperatorCreationException;
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
index 0f5b47e..307c667 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
@@ -7,6 +7,9 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.ASN1Integer;
+// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -15,6 +18,25 @@
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.crypto.ExtendedDigest;
import com.android.internal.org.bouncycastle.crypto.digests.*;
+// import org.bouncycastle.crypto.Xof;
+// import org.bouncycastle.crypto.digests.Blake3Digest;
+// import org.bouncycastle.crypto.digests.GOST3411Digest;
+// import org.bouncycastle.crypto.digests.GOST3411_2012_256Digest;
+// import org.bouncycastle.crypto.digests.GOST3411_2012_512Digest;
+// import org.bouncycastle.crypto.digests.MD2Digest;
+// import org.bouncycastle.crypto.digests.MD4Digest;
+// import org.bouncycastle.crypto.digests.MD5Digest;
+// import org.bouncycastle.crypto.digests.RIPEMD128Digest;
+// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
+// import org.bouncycastle.crypto.digests.RIPEMD256Digest;
+// import org.bouncycastle.crypto.digests.SHA1Digest;
+// import org.bouncycastle.crypto.digests.SHA224Digest;
+// import org.bouncycastle.crypto.digests.SHA256Digest;
+// import org.bouncycastle.crypto.digests.SHA384Digest;
+// import org.bouncycastle.crypto.digests.SHA3Digest;
+// import org.bouncycastle.crypto.digests.SHA512Digest;
+// import org.bouncycastle.crypto.digests.SHAKEDigest;
+// import org.bouncycastle.crypto.digests.SM3Digest;
import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
/**
@@ -94,6 +116,34 @@
return new SHA3Digest(512);
}
});
+ table.put(NISTObjectIdentifiers.id_shake128, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHAKEDigest(128);
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_shake256, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHAKEDigest(256);
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_shake128_len, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new AdjustedXof(new SHAKEDigest(128), ASN1Integer.getInstance(digestAlgorithmIdentifier.getParameters()).intValueExact());
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_shake256_len, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new AdjustedXof(new SHAKEDigest(256), ASN1Integer.getInstance(digestAlgorithmIdentifier.getParameters()).intValueExact());
+ }
+ });
table.put(PKCSObjectIdentifiers.md5, new BcDigestProvider()
{
public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
@@ -157,6 +207,20 @@
return new RIPEMD256Digest();
}
});
+ table.put(GMObjectIdentifiers.sm3, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SM3Digest();
+ }
+ });
+ table.put(MiscObjectIdentifiers.blake3_256, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new Blake3Digest(256);
+ }
+ });
*/
// END Android-removed: Unsupported algorithms
@@ -182,4 +246,69 @@
return extProv.get(digestAlgorithmIdentifier);
}
+
+ /**
+ * -len OIDs for SHAKE include an integer representing the bitlength in of the output.
+ */
+ // BEGIN Android-removed: unused
+ /*
+ private static class AdjustedXof
+ implements Xof
+ {
+ private final Xof xof;
+ private final int length;
+
+ AdjustedXof(Xof xof, int length)
+ {
+ this.xof = xof;
+ this.length = length;
+ }
+
+ public String getAlgorithmName()
+ {
+ return xof.getAlgorithmName() + "-" + length;
+ }
+
+ public int getDigestSize()
+ {
+ return (length + 7) / 8;
+ }
+
+ public void update(byte in)
+ {
+ xof.update(in);
+ }
+
+ public void update(byte[] in, int inOff, int len)
+ {
+ xof.update(in, inOff, len);
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ {
+ return doFinal(out, outOff, getDigestSize());
+ }
+
+ public void reset()
+ {
+ xof.reset();
+ }
+
+ public int getByteLength()
+ {
+ return xof.getByteLength();
+ }
+
+ public int doFinal(byte[] out, int outOff, int outLen)
+ {
+ return xof.doFinal(out, outOff, outLen);
+ }
+
+ public int doOutput(byte[] out, int outOff, int outLen)
+ {
+ return xof.doOutput(out, outOff, outLen);
+ }
+ }
+ */
+ // END Android-removed: unused
}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
index 176c681..e2a6607 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
@@ -44,7 +44,7 @@
};
}
- private class DigestOutputStream
+ private static class DigestOutputStream
extends OutputStream
{
private Digest dig;
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
index 6e669d3..0a61a88 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
@@ -12,16 +12,20 @@
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PSSParameterSpec;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import com.android.internal.org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.jcajce.CompositePrivateKey;
@@ -37,6 +41,7 @@
import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
import com.android.internal.org.bouncycastle.operator.RuntimeOperatorException;
import com.android.internal.org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder;
+import com.android.internal.org.bouncycastle.util.Strings;
import com.android.internal.org.bouncycastle.util.io.TeeOutputStream;
/**
@@ -44,17 +49,26 @@
*/
public class JcaContentSignerBuilder
{
+ private static final Set isAlgIdFromPrivate = new HashSet();
+
+ static
+ {
+ isAlgIdFromPrivate.add("DILITHIUM");
+ isAlgIdFromPrivate.add("SPHINCS+");
+ isAlgIdFromPrivate.add("SPHINCSPlus");
+ }
+
+ private final String signatureAlgorithm;
+
private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
private SecureRandom random;
- private String signatureAlgorithm;
+
private AlgorithmIdentifier sigAlgId;
private AlgorithmParameterSpec sigAlgSpec;
public JcaContentSignerBuilder(String signatureAlgorithm)
{
this.signatureAlgorithm = signatureAlgorithm;
- this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm);
- this.sigAlgSpec = null;
}
public JcaContentSignerBuilder(String signatureAlgorithm, AlgorithmParameterSpec sigParamSpec)
@@ -115,8 +129,21 @@
try
{
- final Signature sig = helper.createSignature(sigAlgId);
+ if (sigAlgSpec == null)
+ {
+ if (isAlgIdFromPrivate.contains(Strings.toUpperCase(signatureAlgorithm)))
+ {
+ sigAlgId = PrivateKeyInfo.getInstance(privateKey.getEncoded()).getPrivateKeyAlgorithm();
+ this.sigAlgSpec = null;
+ }
+ else
+ {
+ this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm);
+ this.sigAlgSpec = null;
+ }
+ }
final AlgorithmIdentifier signatureAlgId = sigAlgId;
+ final Signature sig = helper.createSignature(sigAlgId);
if (random != null)
{
@@ -238,8 +265,16 @@
private static RSASSAPSSparams createPSSParams(PSSParameterSpec pssSpec)
{
DigestAlgorithmIdentifierFinder digFinder = new DefaultDigestAlgorithmIdentifierFinder();
- AlgorithmIdentifier digId = digFinder.find(pssSpec.getDigestAlgorithm());
- AlgorithmIdentifier mgfDig = digFinder.find(((MGF1ParameterSpec)pssSpec.getMGFParameters()).getDigestAlgorithm());
+ AlgorithmIdentifier digId = digFinder.find(pssSpec.getDigestAlgorithm());
+ if (digId.getParameters() == null)
+ {
+ digId = new AlgorithmIdentifier(digId.getAlgorithm(), DERNull.INSTANCE);
+ }
+ AlgorithmIdentifier mgfDig = digFinder.find(((MGF1ParameterSpec)pssSpec.getMGFParameters()).getDigestAlgorithm());
+ if (mgfDig.getParameters() == null)
+ {
+ mgfDig = new AlgorithmIdentifier(mgfDig.getAlgorithm(), DERNull.INSTANCE);
+ }
return new RSASSAPSSparams(
digId,
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
index 825f829..dc2be70 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
@@ -12,8 +12,8 @@
import java.security.cert.X509Certificate;
import java.util.List;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
@@ -282,7 +282,7 @@
return rawSig;
}
- private class SigVerifier
+ private static class SigVerifier
implements ContentVerifier
{
private final AlgorithmIdentifier algorithm;
@@ -325,7 +325,7 @@
}
}
- private class RawSigVerifier
+ private static class RawSigVerifier
extends SigVerifier
implements RawContentVerifier
{
@@ -386,7 +386,7 @@
}
}
- private class CompositeVerifier
+ private static class CompositeVerifier
implements ContentVerifier
{
private Signature[] sigs;
@@ -437,7 +437,7 @@
{
if (sigs[i] != null)
{
- if (!sigs[i].verify(DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes()))
+ if (!sigs[i].verify(ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes()))
{
failed = true;
}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java
index 862cbdc..fb1c770 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java
@@ -9,6 +9,7 @@
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
import com.android.internal.org.bouncycastle.jcajce.util.NamedJcaJceHelper;
import com.android.internal.org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
import com.android.internal.org.bouncycastle.operator.DigestCalculator;
@@ -26,6 +27,14 @@
{
}
+
+ public JcaDigestCalculatorProviderBuilder setHelper(JcaJceHelper helper)
+ {
+ this.helper = new OperatorHelper(helper);
+
+ return this;
+ }
+
public JcaDigestCalculatorProviderBuilder setProvider(Provider provider)
{
this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
@@ -67,7 +76,7 @@
{
return algorithm;
}
-
+
public OutputStream getOutputStream()
{
return stream;
@@ -82,7 +91,7 @@
};
}
- private class DigestOutputStream
+ private static class DigestOutputStream
extends OutputStream
{
private MessageDigest dig;
@@ -101,13 +110,13 @@
public void write(byte[] bytes)
throws IOException
{
- dig.update(bytes);
+ dig.update(bytes);
}
public void write(int b)
throws IOException
{
- dig.update((byte)b);
+ dig.update((byte)b);
}
byte[] getDigest()
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/OperatorHelper.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/OperatorHelper.java
index 63efaff..97ac6a1 100644
--- a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/OperatorHelper.java
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/OperatorHelper.java
@@ -45,12 +45,12 @@
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
import com.android.internal.org.bouncycastle.cms.CMSException;
import com.android.internal.org.bouncycastle.jcajce.util.AlgorithmParametersUtils;
import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
import com.android.internal.org.bouncycastle.jcajce.util.MessageDigestUtils;
+import com.android.internal.org.bouncycastle.operator.DefaultSignatureNameFinder;
import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
import com.android.internal.org.bouncycastle.util.Integers;
@@ -62,54 +62,10 @@
private static final Map symmetricKeyAlgNames = new HashMap();
private static final Map symmetricWrapperKeySizes = new HashMap();
+ private static DefaultSignatureNameFinder sigFinder = new DefaultSignatureNameFinder();
+
static
{
- //
- // reverse mappings
- //
- oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA");
- oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA");
- oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA");
- oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA");
- oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA");
- // BEGIN Android-removed: Unsupported algorithms
- /*
- oids.put(EdECObjectIdentifiers.id_Ed25519, "Ed25519");
- oids.put(EdECObjectIdentifiers.id_Ed448, "Ed448");
- oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410");
- oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410");
- oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "GOST3411-2012-256WITHECGOST3410-2012-256");
- oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "GOST3411-2012-512WITHECGOST3410-2012-512");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160WITHPLAIN-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512WITHCVC-ECDSA");
- oids.put(IsaraObjectIdentifiers.id_alg_xmss, "XMSS");
- oids.put(IsaraObjectIdentifiers.id_alg_xmssmt, "XMSSMT");
- */
- // END Android-removed: Unsupported algorithms
-
- oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA");
- // BEGIN Android-removed: Unsupported algorithms
- // oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA");
- // END Android-removed: Unsupported algorithms
- oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA");
- oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA");
- oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA");
- oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA");
- oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA");
- oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA");
- oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
- oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA");
- oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA");
- oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA");
oids.put(OIWObjectIdentifiers.idSHA1, "SHA1");
oids.put(NISTObjectIdentifiers.id_sha224, "SHA224");
@@ -125,6 +81,8 @@
// END Android-removed: Unsupported algorithms
asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding");
+ asymmetricWrapperAlgNames.put(OIWObjectIdentifiers.elGamalAlgorithm, "Elgamal/ECB/PKCS1Padding");
+ asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_RSAES_OAEP, "RSA/ECB/OAEPPadding");
// Android-removed: Unsupported algorithms
// asymmetricWrapperAlgNames.put(CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410");
@@ -322,24 +280,43 @@
AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
throws OperatorCreationException
{
- AlgorithmParameters parameters;
+ AlgorithmParameters parameters = null;
if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
{
return null;
}
- try
+ if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSAES_OAEP))
{
- parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
+ try
+ {
+ parameters = helper.createAlgorithmParameters("OAEP");
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // try below
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
+ }
}
- catch (NoSuchAlgorithmException e)
+
+ if (parameters == null)
{
- return null; // There's a good chance there aren't any!
- }
- catch (NoSuchProviderException e)
- {
- throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
+ try
+ {
+ parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ return null; // There's a good chance there aren't any!
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
+ }
}
try
@@ -365,6 +342,10 @@
{
dig = helper.createMessageDigest("SHAKE256-" + ASN1Integer.getInstance(digAlgId.getParameters()).getValue());
}
+ else if (digAlgId.getAlgorithm().equals(NISTObjectIdentifiers.id_shake128_len))
+ {
+ dig = helper.createMessageDigest("SHAKE128-" + ASN1Integer.getInstance(digAlgId.getParameters()).getValue());
+ }
else
{
dig = helper.createMessageDigest(MessageDigestUtils.getDigestName(digAlgId.getAlgorithm()));
@@ -412,12 +393,6 @@
sig = helper.createSignature(signatureAlgorithm);
}
- else if (oids.get(sigAlgId.getAlgorithm()) != null)
- {
- String signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm());
-
- sig = helper.createSignature(signatureAlgorithm);
- }
else
{
throw e;
@@ -448,7 +423,7 @@
return sig;
}
- public Signature createRawSignature(AlgorithmIdentifier algorithm)
+ Signature createRawSignature(AlgorithmIdentifier algorithm)
{
Signature sig;
@@ -484,27 +459,11 @@
private static String getSignatureName(
AlgorithmIdentifier sigAlgId)
{
- ASN1Encodable params = sigAlgId.getParameters();
-
- if (params != null && !DERNull.INSTANCE.equals(params))
- {
- if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
- {
- RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
- return getDigestName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1";
- }
- }
-
- if (oids.containsKey(sigAlgId.getAlgorithm()))
- {
- return (String)oids.get(sigAlgId.getAlgorithm());
- }
-
- return sigAlgId.getAlgorithm().getId();
+ return sigFinder.getAlgorithmName(sigAlgId);
}
// we need to remove the - to create a correct signature name
- private static String getDigestName(ASN1ObjectIdentifier oid)
+ static String getDigestName(ASN1ObjectIdentifier oid)
{
String name = MessageDigestUtils.getDigestName(oid);
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/DeltaCertAttributeUtils.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/DeltaCertAttributeUtils.java
new file mode 100644
index 0000000..95e2641
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/DeltaCertAttributeUtils.java
@@ -0,0 +1,69 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.pkcs;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.pkcs.Attribute;
+import com.android.internal.org.bouncycastle.asn1.pkcs.CertificationRequest;
+import com.android.internal.org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DeltaCertAttributeUtils
+{
+ public static Extension makeDeltaCertificateExtension(DeltaCertificateRequestAttributeValue deltaReqAttr)
+ throws IOException
+ {
+ return null;
+ }
+
+ public static boolean isDeltaRequestSignatureValid(PKCS10CertificationRequest baseRequest, ContentVerifierProvider contentVerifierProvider)
+ throws PKCSException
+ {
+ Attribute[] attributes = baseRequest.getAttributes(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.2"));
+
+ DeltaCertificateRequestAttributeValue deltaReq = new DeltaCertificateRequestAttributeValue(attributes[0]);
+
+ attributes = baseRequest.getAttributes(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.3"));
+
+ CertificationRequest deltaPkcs10 = baseRequest.toASN1Structure();
+ CertificationRequestInfo deltaInfo = deltaPkcs10.getCertificationRequestInfo();
+
+ ASN1EncodableVector deltaPkcs10InfoV = new ASN1EncodableVector();
+ deltaPkcs10InfoV.add(deltaInfo.getVersion());
+ deltaPkcs10InfoV.add(deltaInfo.getSubject());
+ deltaPkcs10InfoV.add(deltaInfo.getSubjectPublicKeyInfo());
+
+ ASN1EncodableVector attrSetV = new ASN1EncodableVector();
+ for (Enumeration en = deltaInfo.getAttributes().getObjects(); en.hasMoreElements();)
+ {
+ Attribute attr = Attribute.getInstance(en.nextElement());
+
+ if (!attr.getAttrType().equals(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.3")))
+ {
+ attrSetV.add(attr);
+ }
+ }
+
+ deltaPkcs10InfoV.add(new DERTaggedObject(false, 0, new DERSet(attrSetV)));
+
+ ASN1EncodableVector deltaPkcs10V = new ASN1EncodableVector();
+
+ deltaPkcs10V.add(new DERSequence(deltaPkcs10InfoV));
+ deltaPkcs10V.add(deltaReq.getSignatureAlgorithm());
+ deltaPkcs10V.add(attributes[0].getAttributeValues()[0]);
+
+ PKCS10CertificationRequest deltaPkcs10Req = new PKCS10CertificationRequest(CertificationRequest.getInstance(new DERSequence(deltaPkcs10V)));
+
+ return deltaPkcs10Req.isSignatureValid(contentVerifierProvider);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValue.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValue.java
new file mode 100644
index 0000000..75fcf27
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValue.java
@@ -0,0 +1,104 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.pkcs.Attribute;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+
+/**
+ * The delta certificate request attribute defined in: https://datatracker.ietf.org/doc/draft-bonnell-lamps-chameleon-certs/
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DeltaCertificateRequestAttributeValue
+ implements ASN1Encodable
+{
+ private final X500Name subject;
+ private final SubjectPublicKeyInfo subjectPKInfo;
+ private final Extensions extensions;
+ private final AlgorithmIdentifier signatureAlgorithm;
+ private final ASN1Sequence attrSeq;
+
+ public DeltaCertificateRequestAttributeValue(Attribute attribute)
+ {
+ this(ASN1Sequence.getInstance(attribute.getAttributeValues()[0]));
+ }
+
+ DeltaCertificateRequestAttributeValue(ASN1Sequence attrSeq)
+ {
+ this.attrSeq = attrSeq;
+ // TODO: validate attribute size
+
+ int idx = 0;
+ if (attrSeq.getObjectAt(0) instanceof ASN1TaggedObject)
+ {
+ subject = X500Name.getInstance(ASN1TaggedObject.getInstance(attrSeq.getObjectAt(0)), true);
+ idx++;
+ }
+ else
+ {
+ subject = null;
+ }
+
+ subjectPKInfo = SubjectPublicKeyInfo.getInstance(attrSeq.getObjectAt(idx));
+ idx++;
+
+ Extensions ext = null;
+ AlgorithmIdentifier sigAlg = null;
+
+ if (idx != attrSeq.size())
+ {
+ while (idx < attrSeq.size())
+ {
+ ASN1TaggedObject tagObj = ASN1TaggedObject.getInstance(attrSeq.getObjectAt(idx));
+ if (tagObj.getTagNo() == 1)
+ {
+ ext = Extensions.getInstance(tagObj, false);
+ }
+ else if (tagObj.getTagNo() == 2)
+ {
+ sigAlg = AlgorithmIdentifier.getInstance(tagObj, false);
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown tag");
+ }
+ idx++;
+ }
+ }
+
+ this.extensions = ext;
+ this.signatureAlgorithm = sigAlg;
+ }
+
+ public X500Name getSubject()
+ {
+ return subject;
+ }
+
+ public SubjectPublicKeyInfo getSubjectPKInfo()
+ {
+ return subjectPKInfo;
+ }
+
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return signatureAlgorithm;
+ }
+
+ @Override
+ public ASN1Primitive toASN1Primitive()
+ {
+ return attrSeq;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValueBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValueBuilder.java
new file mode 100644
index 0000000..5ffb356
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/DeltaCertificateRequestAttributeValueBuilder.java
@@ -0,0 +1,61 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.pkcs.Attribute;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DeltaCertificateRequestAttributeValueBuilder
+{
+ private final SubjectPublicKeyInfo subjectPublicKey;
+
+ private AlgorithmIdentifier signatureAlgorithm;
+ private X500Name subject;
+
+ public DeltaCertificateRequestAttributeValueBuilder(SubjectPublicKeyInfo subjectPublicKey)
+ {
+ this.subjectPublicKey = subjectPublicKey;
+ }
+
+ public DeltaCertificateRequestAttributeValueBuilder setSignatureAlgorithm(AlgorithmIdentifier signatureAlgorithm)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+
+ return this;
+ }
+
+ public DeltaCertificateRequestAttributeValueBuilder setSubject(X500Name subject)
+ {
+ this.subject = subject;
+
+ return this;
+ }
+
+ public DeltaCertificateRequestAttributeValue build()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (subject != null)
+ {
+ v.add(new DERTaggedObject(false, 0, subject));
+ }
+ v.add(subjectPublicKey);
+ if (signatureAlgorithm != null)
+ {
+ v.add(new DERTaggedObject(false, 2, signatureAlgorithm));
+ }
+
+
+ return new DeltaCertificateRequestAttributeValue(new Attribute(new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.2"),
+ new DERSet(new DERSequence(v))));
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/PKCS10CertificationRequest.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/PKCS10CertificationRequest.java
new file mode 100644
index 0000000..02c98fe
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/PKCS10CertificationRequest.java
@@ -0,0 +1,437 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.pkcs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Boolean;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+import com.android.internal.org.bouncycastle.asn1.pkcs.Attribute;
+import com.android.internal.org.bouncycastle.asn1.pkcs.CertificationRequest;
+import com.android.internal.org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.ExtensionsGenerator;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.operator.ContentVerifier;
+import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider;
+import com.android.internal.org.bouncycastle.util.Exceptions;
+
+/**
+ * Holding class for a PKCS#10 certification request.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS10CertificationRequest
+{
+ private static Attribute[] EMPTY_ARRAY = new Attribute[0];
+
+ private final CertificationRequest certificationRequest;
+ private final boolean isAltRequest;
+ private final AlgorithmIdentifier altSignature;
+ private final SubjectPublicKeyInfo altPublicKey;
+ private final ASN1BitString altSignatureValue;
+
+ private static CertificationRequest parseBytes(byte[] encoding)
+ throws IOException
+ {
+ try
+ {
+ CertificationRequest rv = CertificationRequest.getInstance(ASN1Primitive.fromByteArray(encoding));
+
+ if (rv == null)
+ {
+ throw new PKCSIOException("empty data passed to constructor");
+ }
+
+ return rv;
+ }
+ catch (ClassCastException e)
+ {
+ throw new PKCSIOException("malformed data: " + e.getMessage(), e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new PKCSIOException("malformed data: " + e.getMessage(), e);
+ }
+ }
+
+ private static ASN1Encodable getSingleValue(Attribute at)
+ {
+ ASN1Encodable[] attrValues = at.getAttributeValues();
+ if (attrValues.length!= 1)
+ {
+ throw new IllegalArgumentException("single value attribute value not size of 1");
+ }
+
+ return attrValues[0];
+ }
+
+ /**
+ * Create a PKCS10CertificationRequestHolder from an underlying ASN.1 structure.
+ *
+ * @param certificationRequest the underlying ASN.1 structure representing a request.
+ */
+ public PKCS10CertificationRequest(CertificationRequest certificationRequest)
+ {
+ if (certificationRequest == null)
+ {
+ throw new NullPointerException("certificationRequest cannot be null");
+ }
+ this.certificationRequest = certificationRequest;
+
+ ASN1Set attributes = certificationRequest.getCertificationRequestInfo().getAttributes();
+
+ AlgorithmIdentifier altSig = null;
+ SubjectPublicKeyInfo altPub = null;
+ ASN1BitString altSigValue = null;
+
+ if (attributes != null)
+ {
+ for (Enumeration en = attributes.getObjects(); en.hasMoreElements();)
+ {
+ Attribute at = Attribute.getInstance(en.nextElement());
+
+ if (Extension.altSignatureAlgorithm.equals(at.getAttrType()))
+ {
+ altSig = AlgorithmIdentifier.getInstance(getSingleValue(at));
+ }
+ if (Extension.subjectAltPublicKeyInfo.equals(at.getAttrType()))
+ {
+ altPub = SubjectPublicKeyInfo.getInstance(getSingleValue(at));
+ }
+ if (Extension.altSignatureValue.equals(at.getAttrType()))
+ {
+ altSigValue = ASN1BitString.getInstance(getSingleValue(at));
+ }
+ }
+ }
+
+ this.isAltRequest = (altSig != null) | (altPub != null) | (altSigValue != null);
+ if (isAltRequest)
+ {
+ if (!((altSig != null) & (altPub != null) & (altSigValue != null)))
+ {
+ throw new IllegalArgumentException("invalid alternate public key details found");
+ }
+ }
+
+ this.altSignature = altSig;
+ this.altPublicKey = altPub;
+ this.altSignatureValue = altSigValue;
+ }
+
+ /**
+ * Create a PKCS10CertificationRequestHolder from the passed in bytes.
+ *
+ * @param encoded BER/DER encoding of the CertificationRequest structure.
+ * @throws IOException in the event of corrupted data, or an incorrect structure.
+ */
+ public PKCS10CertificationRequest(byte[] encoded)
+ throws IOException
+ {
+ this(parseBytes(encoded));
+ }
+
+ /**
+ * Return the underlying ASN.1 structure for this request.
+ *
+ * @return a CertificateRequest object.
+ */
+ public CertificationRequest toASN1Structure()
+ {
+ return certificationRequest;
+ }
+
+ /**
+ * Return the subject on this request.
+ *
+ * @return the X500Name representing the request's subject.
+ */
+ public X500Name getSubject()
+ {
+ return X500Name.getInstance(certificationRequest.getCertificationRequestInfo().getSubject());
+ }
+
+ /**
+ * Return the details of the signature algorithm used to create this request.
+ *
+ * @return the AlgorithmIdentifier describing the signature algorithm used to create this request.
+ */
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return certificationRequest.getSignatureAlgorithm();
+ }
+
+ /**
+ * Return the bytes making up the signature associated with this request.
+ *
+ * @return the request signature bytes.
+ */
+ public byte[] getSignature()
+ {
+ return certificationRequest.getSignature().getOctets();
+ }
+
+ /**
+ * Return the SubjectPublicKeyInfo describing the public key this request is carrying.
+ *
+ * @return the public key ASN.1 structure contained in the request.
+ */
+ public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
+ {
+ return certificationRequest.getCertificationRequestInfo().getSubjectPublicKeyInfo();
+ }
+
+ /**
+ * Return the attributes, if any associated with this request.
+ *
+ * @return an array of Attribute, zero length if none present.
+ */
+ public Attribute[] getAttributes()
+ {
+ ASN1Set attrSet = certificationRequest.getCertificationRequestInfo().getAttributes();
+
+ if (attrSet == null)
+ {
+ return EMPTY_ARRAY;
+ }
+
+ Attribute[] attrs = new Attribute[attrSet.size()];
+
+ for (int i = 0; i != attrSet.size(); i++)
+ {
+ attrs[i] = Attribute.getInstance(attrSet.getObjectAt(i));
+ }
+
+ return attrs;
+ }
+
+ /**
+ * Return an array of attributes matching the passed in type OID.
+ *
+ * @param type the type of the attribute being looked for.
+ * @return an array of Attribute of the requested type, zero length if none present.
+ */
+ public Attribute[] getAttributes(ASN1ObjectIdentifier type)
+ {
+ ASN1Set attrSet = certificationRequest.getCertificationRequestInfo().getAttributes();
+
+ if (attrSet == null)
+ {
+ return EMPTY_ARRAY;
+ }
+
+ List list = new ArrayList();
+
+ for (int i = 0; i != attrSet.size(); i++)
+ {
+ Attribute attr = Attribute.getInstance(attrSet.getObjectAt(i));
+ if (attr.getAttrType().equals(type))
+ {
+ list.add(attr);
+ }
+ }
+
+ if (list.size() == 0)
+ {
+ return EMPTY_ARRAY;
+ }
+
+ return (Attribute[])list.toArray(new Attribute[list.size()]);
+ }
+
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return certificationRequest.getEncoded();
+ }
+
+ /**
+ * Validate the signature on the PKCS10 certification request in this holder.
+ *
+ * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature.
+ * @return true if the signature is valid, false otherwise.
+ * @throws PKCSException if the signature cannot be processed or is inappropriate.
+ */
+ public boolean isSignatureValid(ContentVerifierProvider verifierProvider)
+ throws PKCSException
+ {
+ CertificationRequestInfo requestInfo = certificationRequest.getCertificationRequestInfo();
+
+ ContentVerifier verifier;
+
+ try
+ {
+ verifier = verifierProvider.get(certificationRequest.getSignatureAlgorithm());
+
+ OutputStream sOut = verifier.getOutputStream();
+
+ sOut.write(requestInfo.getEncoded(ASN1Encoding.DER));
+
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new PKCSException("unable to process signature: " + e.getMessage(), e);
+ }
+
+ return verifier.verify(this.getSignature());
+ }
+
+ /**
+ * Return true if the certification request has an alternate public key present.
+ *
+ * @return true if this is a dual key request, false otherwise.
+ */
+ public boolean hasAltPublicKey()
+ {
+ return isAltRequest;
+ }
+
+ /**
+ * Validate the alternate signature on the PKCS10 certification request in this holder.
+ *
+ * @param verifierProvider a ContentVerifierProvider that can generate a verifier for the signature.
+ * @return true if the alternate signature is valid, false otherwise.
+ * @throws PKCSException if the signature cannot be processed or is inappropriate.
+ */
+ public boolean isAltSignatureValid(ContentVerifierProvider verifierProvider)
+ throws PKCSException
+ {
+ if (!isAltRequest)
+ {
+ throw new IllegalStateException("no alternate public key present");
+ }
+
+ CertificationRequestInfo requestInfo = certificationRequest.getCertificationRequestInfo();
+ ASN1Set attributes = requestInfo.getAttributes();
+ ASN1EncodableVector atV = new ASN1EncodableVector();
+
+ for (Enumeration en = attributes.getObjects(); en.hasMoreElements();)
+ {
+ Attribute at = Attribute.getInstance(en.nextElement());
+
+ if (Extension.altSignatureValue.equals(at.getAttrType()))
+ {
+ continue;
+ }
+
+ atV.add(at);
+ }
+
+ requestInfo = new CertificationRequestInfo(requestInfo.getSubject(), requestInfo.getSubjectPublicKeyInfo(), new DERSet(atV));
+ ContentVerifier verifier;
+
+ try
+ {
+ verifier = verifierProvider.get(this.altSignature);
+
+ OutputStream sOut = verifier.getOutputStream();
+
+ sOut.write(requestInfo.getEncoded(ASN1Encoding.DER));
+
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new PKCSException("unable to process signature: " + e.getMessage(), e);
+ }
+
+ return verifier.verify(this.altSignatureValue.getOctets());
+ }
+
+ /**
+ * Return any extensions requested in the PKCS#10 request. If none are present, the method
+ * will return null.
+ *
+ * @return the requested extensions, null if none are requested.
+ * @throws IllegalStateException if the extension request is and is somehow invalid.
+ */
+ public Extensions getRequestedExtensions()
+ {
+ Attribute[] attributes = getAttributes();
+ for (int i = 0; i != attributes.length; i++)
+ {
+ Attribute encodable = attributes[i];
+ if (PKCSObjectIdentifiers.pkcs_9_at_extensionRequest.equals(encodable.getAttrType()))
+ {
+ ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
+
+ ASN1Set attrValues = encodable.getAttrValues();
+ if (attrValues == null || attrValues.size() == 0)
+ {
+ throw new IllegalStateException("pkcs_9_at_extensionRequest present but has no value");
+ }
+
+ ASN1Sequence extensionSequence = ASN1Sequence.getInstance(attrValues.getObjectAt(0));
+
+ try
+ {
+ for (Enumeration en = extensionSequence.getObjects(); en.hasMoreElements(); )
+ {
+ ASN1Sequence itemSeq = ASN1Sequence.getInstance(en.nextElement());
+
+ boolean critical = itemSeq.size() == 3 && ASN1Boolean.getInstance(itemSeq.getObjectAt(1)).isTrue();
+ if (itemSeq.size() == 2)
+ {
+ extensionsGenerator.addExtension(ASN1ObjectIdentifier.getInstance(itemSeq.getObjectAt(0)), false, ASN1OctetString.getInstance(itemSeq.getObjectAt(1)).getOctets());
+ }
+ else if (itemSeq.size() == 3)
+ {
+ extensionsGenerator.addExtension(ASN1ObjectIdentifier.getInstance(itemSeq.getObjectAt(0)), critical, ASN1OctetString.getInstance(itemSeq.getObjectAt(2)).getOctets());
+ }
+ else
+ {
+ throw new IllegalStateException("incorrect sequence size of Extension get " + itemSeq.size() + " expected 2 or three");
+ }
+ }
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw Exceptions.illegalStateException("asn1 processing issue: " + e.getMessage(), e);
+ }
+
+ return extensionsGenerator.generate();
+ }
+ }
+ return null;
+ }
+
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof PKCS10CertificationRequest))
+ {
+ return false;
+ }
+
+ PKCS10CertificationRequest other = (PKCS10CertificationRequest)o;
+
+ return this.toASN1Structure().equals(other.toASN1Structure());
+ }
+
+ public int hashCode()
+ {
+ return this.toASN1Structure().hashCode();
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/PKCSException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/PKCSException.java
new file mode 100644
index 0000000..71ec05b
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/PKCSException.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.pkcs;
+
+/**
+ * General checked Exception thrown in the cert package and its sub-packages.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCSException
+ extends Exception
+{
+ private Throwable cause;
+
+ public PKCSException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public PKCSException(String msg)
+ {
+ super(msg);
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/PKCSIOException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/PKCSIOException.java
new file mode 100644
index 0000000..7132b3b
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/pkcs/PKCSIOException.java
@@ -0,0 +1,32 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.pkcs;
+
+import java.io.IOException;
+
+/**
+ * General IOException thrown in the cert package and its sub-packages.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCSIOException
+ extends IOException
+{
+ private Throwable cause;
+
+ public PKCSIOException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public PKCSIOException(String msg)
+ {
+ super(msg);
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Absent.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Absent.java
new file mode 100644
index 0000000..0b3f8f2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Absent.java
@@ -0,0 +1,47 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * An ASN1 class that encodes to nothing, used in the OER library to deal with the Optional type.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1Absent
+ extends ASN1Primitive
+{
+
+ public static final ASN1Absent INSTANCE = new ASN1Absent();
+
+ private ASN1Absent()
+ {
+
+ }
+
+ public int hashCode()
+ {
+ return 0;
+ }
+
+ boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength(boolean withTag)
+ throws IOException
+ {
+ return 0;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag)
+ throws IOException
+ {
+
+ }
+
+ boolean asn1Equals(ASN1Primitive o)
+ {
+ return o == this;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecific.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
deleted file mode 100644
index 38a6d58..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-import com.android.internal.org.bouncycastle.util.encoders.Hex;
-
-/**
- * Base class for an ASN.1 ApplicationSpecific object
- * @hide This class is not part of the Android public SDK API
- */
-public abstract class ASN1ApplicationSpecific
- extends ASN1Primitive
-{
- protected final boolean isConstructed;
- protected final int tag;
- protected final byte[] octets;
-
- ASN1ApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- this.isConstructed = isConstructed;
- this.tag = tag;
- this.octets = Arrays.clone(octets);
- }
-
- /**
- * Return an ASN1ApplicationSpecific from the passed in object, which may be a byte array, or null.
- *
- * @param obj the object to be converted.
- * @return obj's representation as an ASN1ApplicationSpecific object.
- */
- public static ASN1ApplicationSpecific getInstance(Object obj)
- {
- if (obj == null || obj instanceof ASN1ApplicationSpecific)
- {
- return (ASN1ApplicationSpecific)obj;
- }
- else if (obj instanceof byte[])
- {
- try
- {
- return ASN1ApplicationSpecific.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("Failed to construct object from byte[]: " + e.getMessage());
- }
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
- }
-
- protected static int getLengthOfHeader(byte[] data)
- {
- int length = data[1] & 0xff; // TODO: assumes 1 byte tag
-
- if (length == 0x80)
- {
- return 2; // indefinite-length encoding
- }
-
- if (length > 127)
- {
- int size = length & 0x7f;
-
- // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
- if (size > 4)
- {
- throw new IllegalStateException("DER length more than 4 bytes: " + size);
- }
-
- return size + 2;
- }
-
- return 2;
- }
-
- /**
- * Return true if the object is marked as constructed, false otherwise.
- *
- * @return true if constructed, otherwise false.
- */
- public boolean isConstructed()
- {
- return isConstructed;
- }
-
- /**
- * Return the contents of this object as a byte[]
- *
- * @return the encoded contents of the object.
- */
- public byte[] getContents()
- {
- return Arrays.clone(octets);
- }
-
- /**
- * Return the tag number associated with this object,
- *
- * @return the application tag number.
- */
- public int getApplicationTag()
- {
- return tag;
- }
-
- /**
- * Return the enclosed object assuming explicit tagging.
- *
- * @return the resulting object
- * @throws IOException if reconstruction fails.
- */
- public ASN1Primitive getObject()
- throws IOException
- {
- return ASN1Primitive.fromByteArray(getContents());
- }
-
- /**
- * Return the enclosed object assuming implicit tagging.
- *
- * @param derTagNo the type tag that should be applied to the object's contents.
- * @return the resulting object
- * @throws IOException if reconstruction fails.
- */
- public ASN1Primitive getObject(int derTagNo)
- throws IOException
- {
- if (derTagNo >= 0x1f)
- {
- throw new IOException("unsupported tag number");
- }
-
- byte[] orig = this.getEncoded();
- byte[] tmp = replaceTagNumber(derTagNo, orig);
-
- if ((orig[0] & BERTags.CONSTRUCTED) != 0)
- {
- tmp[0] |= BERTags.CONSTRUCTED;
- }
-
- return ASN1Primitive.fromByteArray(tmp);
- }
-
- int encodedLength()
- throws IOException
- {
- return StreamUtil.calculateTagLength(tag) + StreamUtil.calculateBodyLength(octets.length) + octets.length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncoded(withTag, flags, tag, octets);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof ASN1ApplicationSpecific))
- {
- return false;
- }
-
- ASN1ApplicationSpecific other = (ASN1ApplicationSpecific)o;
-
- return isConstructed == other.isConstructed
- && tag == other.tag
- && Arrays.areEqual(octets, other.octets);
- }
-
- public int hashCode()
- {
- return (isConstructed ? 1 : 0) ^ tag ^ Arrays.hashCode(octets);
- }
-
- private byte[] replaceTagNumber(int newTag, byte[] input)
- throws IOException
- {
- int tagNo = input[0] & 0x1f;
- int index = 1;
- //
- // with tagged object tag number is bottom 5 bits, or stored at the start of the content
- //
- if (tagNo == 0x1f)
- {
- int b = input[index++] & 0xff;
-
- // X.690-0207 8.1.2.4.2
- // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
- if ((b & 0x7f) == 0) // Note: -1 will pass
- {
- throw new IOException("corrupted stream - invalid high tag number found");
- }
-
- while ((b & 0x80) != 0)
- {
- b = input[index++] & 0xff;
- }
- }
-
- byte[] tmp = new byte[input.length - index + 1];
-
- System.arraycopy(input, index, tmp, 1, tmp.length - 1);
-
- tmp[0] = (byte)newTag;
-
- return tmp;
- }
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
- sb.append("[");
- if (isConstructed())
- {
- sb.append("CONSTRUCTED ");
- }
- sb.append("APPLICATION ");
- sb.append(Integer.toString(getApplicationTag()));
- sb.append("]");
- // @todo content encoding somehow?
- if (this.octets != null)
- {
- sb.append(" #");
- sb.append(Hex.toHexString(this.octets));
- }
- else
- {
- sb.append(" #null");
- }
- sb.append(" ");
- return sb.toString();
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BMPString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BMPString.java
new file mode 100644
index 0000000..3b455f5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BMPString.java
@@ -0,0 +1,215 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * ASN.1 BMPString object encodes BMP (<i>Basic Multilingual Plane</i>) subset
+ * (aka UCS-2) of UNICODE (ISO 10646) characters in codepoints 0 to 65535.
+ * <p>
+ * At ISO-10646:2011 the term "BMP" has been withdrawn, and replaced by
+ * term "UCS-2".
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1BMPString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1BMPString.class, BERTags.BMP_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a BMP String from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1BMPString instance, or null.
+ */
+ public static ASN1BMPString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1BMPString)
+ {
+ return (ASN1BMPString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1BMPString)
+ {
+ return (ASN1BMPString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1BMPString)TYPE.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());
+ }
+
+ /**
+ * Return a BMP String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1BMPString instance.
+ */
+ public static ASN1BMPString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1BMPString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final char[] string;
+
+ ASN1BMPString(String string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ this.string = string.toCharArray();
+ }
+
+ ASN1BMPString(byte[] string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ int byteLen = string.length;
+ if (0 != (byteLen & 1))
+ {
+ throw new IllegalArgumentException("malformed BMPString encoding encountered");
+ }
+
+ int charLen = byteLen / 2;
+ char[] cs = new char[charLen];
+
+ for (int i = 0; i != charLen; i++)
+ {
+ cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
+ }
+
+ this.string = cs;
+ }
+
+ ASN1BMPString(char[] string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ this.string = string;
+ }
+
+ public final String getString()
+ {
+ return new String(string);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1BMPString))
+ {
+ return false;
+ }
+
+ ASN1BMPString that = (ASN1BMPString)other;
+
+ return Arrays.areEqual(this.string, that.string);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, string.length * 2);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ int count = string.length;
+
+ out.writeIdentifier(withTag, BERTags.BMP_STRING);
+ out.writeDL(count * 2);
+
+ byte[] buf = new byte[8];
+
+ int i = 0, limit = count & -4;
+ while (i < limit)
+ {
+ char c0 = string[i], c1 = string[i + 1], c2 = string[i + 2], c3 = string[i + 3];
+ i += 4;
+
+ buf[0] = (byte)(c0 >> 8);
+ buf[1] = (byte)c0;
+ buf[2] = (byte)(c1 >> 8);
+ buf[3] = (byte)c1;
+ buf[4] = (byte)(c2 >> 8);
+ buf[5] = (byte)c2;
+ buf[6] = (byte)(c3 >> 8);
+ buf[7] = (byte)c3;
+
+ out.write(buf, 0, 8);
+ }
+ if (i < count)
+ {
+ int bufPos = 0;
+ do
+ {
+ char c0 = string[i];
+ i += 1;
+
+ buf[bufPos++] = (byte)(c0 >> 8);
+ buf[bufPos++] = (byte)c0;
+ }
+ while (i < count);
+
+ out.write(buf, 0, bufPos);
+ }
+ }
+
+ static ASN1BMPString createPrimitive(byte[] contents)
+ {
+ return new DERBMPString(contents);
+ }
+
+ static ASN1BMPString createPrimitive(char[] string)
+ {
+ // TODO ASN1InputStream has a validator/converter that should be unified in this class somehow
+ return new DERBMPString(string);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java
index 001dd61..056e9dd 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java
@@ -1,12 +1,11 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.EOFException;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import com.android.internal.org.bouncycastle.util.Arrays;
-import com.android.internal.org.bouncycastle.util.io.Streams;
/**
* Base class for BIT STRING objects
@@ -14,12 +13,57 @@
*/
public abstract class ASN1BitString
extends ASN1Primitive
- implements ASN1String
+ implements ASN1String, ASN1BitStringParser
{
- private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1BitString.class, BERTags.BIT_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
- protected final byte[] data;
- protected final int padBits;
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence.toASN1BitString();
+ }
+ };
+
+ public static ASN1BitString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1BitString)
+ {
+ return (ASN1BitString)obj;
+ }
+// else if (obj instanceof ASN1BitStringParser)
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1BitString)
+ {
+ return (ASN1BitString)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1BitString)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct BIT STRING from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ public static ASN1BitString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1BitString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/**
* @param bitString an int containing the BIT STRING
@@ -101,15 +145,16 @@
return result;
}
- protected ASN1BitString(byte data, int padBits)
+ final byte[] contents;
+
+ ASN1BitString(byte data, int padBits)
{
if (padBits > 7 || padBits < 0)
{
throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
}
- this.data = new byte[]{ data };
- this.padBits = padBits;
+ this.contents = new byte[]{ (byte)padBits, data };
}
/**
@@ -118,9 +163,7 @@
* @param data the octets making up the bit string.
* @param padBits the number of extra bits at the end of the string.
*/
- public ASN1BitString(
- byte[] data,
- int padBits)
+ ASN1BitString(byte[] data, int padBits)
{
if (data == null)
{
@@ -135,8 +178,58 @@
throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
}
- this.data = Arrays.clone(data);
- this.padBits = padBits;
+ this.contents = Arrays.prepend(data, (byte)padBits);
+ }
+
+ ASN1BitString(byte[] contents, boolean check)
+ {
+ if (check)
+ {
+ if (null == contents)
+ {
+ throw new NullPointerException("'contents' cannot be null");
+ }
+ if (contents.length < 1)
+ {
+ throw new IllegalArgumentException("'contents' cannot be empty");
+ }
+
+ int padBits = contents[0] & 0xFF;
+ if (padBits > 0)
+ {
+ if (contents.length < 2)
+ {
+ throw new IllegalArgumentException("zero length data with non-zero pad bits");
+ }
+ if (padBits > 7)
+ {
+ throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
+ }
+ }
+ }
+
+ this.contents = contents;
+ }
+
+ public InputStream getBitStream() throws IOException
+ {
+ return new ByteArrayInputStream(contents, 1, contents.length - 1);
+ }
+
+ public InputStream getOctetStream() throws IOException
+ {
+ int padBits = contents[0] & 0xFF;
+ if (0 != padBits)
+ {
+ throw new IOException("expected octet-aligned bitstring, but found padBits: " + padBits);
+ }
+
+ return getBitStream();
+ }
+
+ public ASN1BitStringParser parser()
+ {
+ return this;
}
/**
@@ -146,8 +239,6 @@
*/
public String getString()
{
- StringBuffer buf = new StringBuffer("#");
-
byte[] string;
try
{
@@ -158,10 +249,14 @@
throw new ASN1ParsingException("Internal error encoding BitString: " + e.getMessage(), e);
}
+ StringBuffer buf = new StringBuffer(1 + string.length * 2);
+ buf.append('#');
+
for (int i = 0; i != string.length; i++)
{
- buf.append(table[(string[i] >>> 4) & 0xf]);
- buf.append(table[string[i] & 0xf]);
+ byte b = string[i];
+ buf.append(table[(b >>> 4) & 0xf]);
+ buf.append(table[b & 0xf]);
}
return buf.toString();
@@ -173,15 +268,16 @@
public int intValue()
{
int value = 0;
- int end = Math.min(4, data.length - 1);
- for (int i = 0; i < end; ++i)
+ int end = Math.min(5, contents.length - 1);
+ for (int i = 1; i < end; ++i)
{
- value |= (data[i] & 0xFF) << (8 * i);
+ value |= (contents[i] & 0xFF) << (8 * (i - 1));
}
- if (0 <= end && end < 4)
+ if (1 <= end && end < 5)
{
- byte der = (byte)(data[end] & (0xFF << padBits));
- value |= (der & 0xFF) << (8 * end);
+ int padBits = contents[0] & 0xFF;
+ byte der = (byte)(contents[end] & (0xFF << padBits));
+ value |= (der & 0xFF) << (8 * (end - 1));
}
return value;
}
@@ -195,30 +291,31 @@
*/
public byte[] getOctets()
{
- if (padBits != 0)
+ if (contents[0] != 0)
{
throw new IllegalStateException("attempt to get non-octet aligned data from BIT STRING");
}
- return Arrays.clone(data);
+ return Arrays.copyOfRange(contents, 1, contents.length);
}
public byte[] getBytes()
{
- if (0 == data.length)
+ if (contents.length == 1)
{
- return data;
+ return ASN1OctetString.EMPTY_OCTETS;
}
- byte[] rv = Arrays.clone(data);
+ int padBits = contents[0] & 0xFF;
+ byte[] rv = Arrays.copyOfRange(contents, 1, contents.length);
// DER requires pad bits be zero
- rv[data.length - 1] &= (0xFF << padBits);
+ rv[rv.length - 1] &= (byte)(0xFF << padBits);
return rv;
}
public int getPadBits()
{
- return padBits;
+ return contents[0] & 0xFF;
}
public String toString()
@@ -228,85 +325,56 @@
public int hashCode()
{
- int end = data.length;
- if (--end < 0)
+ if (contents.length < 2)
{
return 1;
}
- byte der = (byte)(data[end] & (0xFF << padBits));
+ int padBits = contents[0] & 0xFF;
+ int last = contents.length - 1;
- int hc = Arrays.hashCode(data, 0, end);
+ byte lastOctetDER = (byte)(contents[last] & (0xFF << padBits));
+
+ int hc = Arrays.hashCode(contents, 0, last);
hc *= 257;
- hc ^= der;
- return hc ^ padBits;
+ hc ^= lastOctetDER;
+ return hc;
}
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive other)
{
- if (!(o instanceof ASN1BitString))
+ if (!(other instanceof ASN1BitString))
{
return false;
}
- ASN1BitString other = (ASN1BitString)o;
- if (padBits != other.padBits)
+ ASN1BitString that = (ASN1BitString)other;
+ byte[] thisContents = this.contents, thatContents = that.contents;
+
+ int length = thisContents.length;
+ if (thatContents.length != length)
{
return false;
}
- byte[] a = data, b = other.data;
- int end = a.length;
- if (end != b.length)
- {
- return false;
- }
- if (--end < 0)
+ if (length == 1)
{
return true;
}
- for (int i = 0; i < end; ++i)
+
+ int last = length - 1;
+ for (int i = 0; i < last; ++i)
{
- if (a[i] != b[i])
+ if (thisContents[i] != thatContents[i])
{
return false;
}
}
- byte derA = (byte)(a[end] & (0xFF << padBits));
- byte derB = (byte)(b[end] & (0xFF << padBits));
+ int padBits = thisContents[0] & 0xFF;
+ byte thisLastOctetDER = (byte)(thisContents[last] & (0xFF << padBits));
+ byte thatLastOctetDER = (byte)(thatContents[last] & (0xFF << padBits));
- return derA == derB;
- }
-
- static ASN1BitString fromInputStream(int length, InputStream stream)
- throws IOException
- {
- if (length < 1)
- {
- throw new IllegalArgumentException("truncated BIT STRING detected");
- }
-
- int padBits = stream.read();
- byte[] data = new byte[length - 1];
-
- if (data.length != 0)
- {
- if (Streams.readFully(stream, data) != data.length)
- {
- throw new EOFException("EOF encountered in middle of BIT STRING");
- }
-
- if (padBits > 0 && padBits < 8)
- {
- if (data[data.length - 1] != (byte)(data[data.length - 1] & (0xFF << padBits)))
- {
- return new DLBitString(data, padBits);
- }
- }
- }
-
- return new DERBitString(data, padBits);
+ return thisLastOctetDER == thatLastOctetDER;
}
public ASN1Primitive getLoadedObject()
@@ -316,13 +384,37 @@
ASN1Primitive toDERObject()
{
- return new DERBitString(data, padBits);
+ return new DERBitString(contents, false);
}
ASN1Primitive toDLObject()
{
- return new DLBitString(data, padBits);
+ return new DLBitString(contents, false);
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
+ static ASN1BitString createPrimitive(byte[] contents)
+ {
+ int length = contents.length;
+ if (length < 1)
+ {
+ throw new IllegalArgumentException("truncated BIT STRING detected");
+ }
+
+ int padBits = contents[0] & 0xFF;
+ if (padBits > 0)
+ {
+ if (padBits > 7 || length < 2)
+ {
+ throw new IllegalArgumentException("invalid pad bits detected");
+ }
+
+ byte finalOctet = contents[length - 1];
+ if (finalOctet != (byte)(finalOctet & (0xFF << padBits)))
+ {
+ return new DLBitString(contents, false);
+ }
+ }
+
+ return new DERBitString(contents, false);
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitStringParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitStringParser.java
new file mode 100644
index 0000000..8ecd50f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitStringParser.java
@@ -0,0 +1,42 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A basic parser for a BIT STRING object
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ASN1BitStringParser
+ extends ASN1Encodable, InMemoryRepresentable
+{
+ /**
+ * Return an InputStream representing the contents of the BIT STRING. The final
+ * byte, if any, may include pad bits. See {@link #getPadBits()}.
+ *
+ * @return an InputStream with its source as the BIT STRING content.
+ */
+ public InputStream getBitStream() throws IOException;
+
+ /**
+ * Return an InputStream representing the contents of the BIT STRING, where the
+ * content is expected to be octet-aligned (this will be automatically checked
+ * during parsing).
+ *
+ * @return an InputStream with its source as the BIT STRING content.
+ */
+ public InputStream getOctetStream() throws IOException;
+
+ /**
+ * Return the number of pad bits, if any, in the final byte, if any, read from
+ * {@link #getBitStream()}. This number is in the range zero to seven. That
+ * number of the least significant bits of the final byte, if any, are not part
+ * of the contents and should be ignored. NOTE: Must be called AFTER the stream
+ * has been fully processed. (Does not need to be called if
+ * {@link #getOctetStream()} was used instead of {@link #getBitStream()}).
+ *
+ * @return the number of pad bits. In the range zero to seven.
+ */
+ public int getPadBits();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java
index 80d935a..17a34fa 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java
@@ -18,6 +18,14 @@
public class ASN1Boolean
extends ASN1Primitive
{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Boolean.class, BERTags.BOOLEAN)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
private static final byte FALSE_VALUE = 0x00;
private static final byte TRUE_VALUE = (byte)0xFF;
@@ -46,7 +54,7 @@
byte[] enc = (byte[])obj;
try
{
- return (ASN1Boolean)fromByteArray(enc);
+ return (ASN1Boolean)TYPE.fromByteArray(enc);
}
catch (IOException e)
{
@@ -91,25 +99,16 @@
/**
* Return a Boolean from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1Boolean instance.
*/
- public static ASN1Boolean getInstance(ASN1TaggedObject obj, boolean explicit)
+ public static ASN1Boolean getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1Boolean)
- {
- return getInstance(o);
- }
- else
- {
- return ASN1Boolean.fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1Boolean)TYPE.getContextInstance(taggedObject, explicit);
}
private ASN1Boolean(byte value)
@@ -122,19 +121,19 @@
return value != FALSE_VALUE;
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 3;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, 1);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.BOOLEAN, value);
+ out.writeEncodingDL(withTag, BERTags.BOOLEAN, value);
}
boolean asn1Equals(ASN1Primitive other)
@@ -164,14 +163,14 @@
return isTrue() ? "TRUE" : "FALSE";
}
- static ASN1Boolean fromOctetString(byte[] value)
+ static ASN1Boolean createPrimitive(byte[] contents)
{
- if (value.length != 1)
+ if (contents.length != 1)
{
throw new IllegalArgumentException("BOOLEAN value should have 1 byte in it");
}
- byte b = value[0];
+ byte b = contents[0];
switch (b)
{
case FALSE_VALUE: return FALSE;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java
index aabcc62..b61d74e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java
@@ -50,6 +50,16 @@
this.elementCount = minCapacity;
}
+ public void addAll(ASN1Encodable[] others)
+ {
+ if (null == others)
+ {
+ throw new NullPointerException("'others' cannot be null");
+ }
+
+ doAddAll(others, "'others' elements cannot be null");
+ }
+
public void addAll(ASN1EncodableVector other)
{
if (null == other)
@@ -57,7 +67,12 @@
throw new NullPointerException("'other' cannot be null");
}
- int otherElementCount = other.size();
+ doAddAll(other.elements, "'other' elements cannot be null");
+ }
+
+ private void doAddAll(ASN1Encodable[] others, String nullMsg)
+ {
+ int otherElementCount = others.length;
if (otherElementCount < 1)
{
return;
@@ -73,10 +88,10 @@
int i = 0;
do
{
- ASN1Encodable otherElement = other.get(i);
+ ASN1Encodable otherElement = others[i];
if (null == otherElement)
{
- throw new NullPointerException("'other' elements cannot be null");
+ throw new NullPointerException(nullMsg);
}
this.elements[elementCount + i] = otherElement;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java
index d95d62e..6857a3e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java
@@ -13,8 +13,13 @@
public class ASN1Enumerated
extends ASN1Primitive
{
- private final byte[] bytes;
- private final int start;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Enumerated.class, BERTags.ENUMERATED)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets(), false);
+ }
+ };
/**
* return an enumerated from the passed in object
@@ -35,7 +40,7 @@
{
try
{
- return (ASN1Enumerated)fromByteArray((byte[])obj);
+ return (ASN1Enumerated)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -49,29 +54,21 @@
/**
* return an Enumerated from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1Enumerated instance, or null.
*/
- public static ASN1Enumerated getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1Enumerated getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1Enumerated)
- {
- return getInstance(o);
- }
- else
- {
- return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1Enumerated)TYPE.getContextInstance(taggedObject, explicit);
}
+ private final byte[] contents;
+ private final int start;
+
/**
* Constructor from int.
*
@@ -84,7 +81,7 @@
throw new IllegalArgumentException("enumerated must be non-negative");
}
- this.bytes = BigInteger.valueOf(value).toByteArray();
+ this.contents = BigInteger.valueOf(value).toByteArray();
this.start = 0;
}
@@ -100,67 +97,78 @@
throw new IllegalArgumentException("enumerated must be non-negative");
}
- this.bytes = value.toByteArray();
+ this.contents = value.toByteArray();
this.start = 0;
}
/**
* Constructor from encoded BigInteger.
*
- * @param bytes the value of this enumerated as an encoded BigInteger (signed).
+ * @param contents the value of this enumerated as an encoded BigInteger (signed).
*/
- public ASN1Enumerated(byte[] bytes)
+ public ASN1Enumerated(byte[] contents)
{
- if (ASN1Integer.isMalformed(bytes))
+ this(contents, true);
+ }
+
+ ASN1Enumerated(byte[] contents, boolean clone)
+ {
+ if (ASN1Integer.isMalformed(contents))
{
throw new IllegalArgumentException("malformed enumerated");
}
- if (0 != (bytes[0] & 0x80))
+ if (0 != (contents[0] & 0x80))
{
throw new IllegalArgumentException("enumerated must be non-negative");
}
- this.bytes = Arrays.clone(bytes);
- this.start = ASN1Integer.signBytesToSkip(bytes);
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ this.start = ASN1Integer.signBytesToSkip(contents);
}
public BigInteger getValue()
{
- return new BigInteger(bytes);
+ return new BigInteger(contents);
+ }
+
+ public boolean hasValue(int x)
+ {
+ return (contents.length - start) <= 4
+ && ASN1Integer.intValue(contents, start, ASN1Integer.SIGN_EXT_SIGNED) == x;
}
public boolean hasValue(BigInteger x)
{
return null != x
// Fast check to avoid allocation
- && ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED) == x.intValue()
+ && ASN1Integer.intValue(contents, start, ASN1Integer.SIGN_EXT_SIGNED) == x.intValue()
&& getValue().equals(x);
}
public int intValueExact()
{
- int count = bytes.length - start;
+ int count = contents.length - start;
if (count > 4)
{
throw new ArithmeticException("ASN.1 Enumerated out of int range");
}
- return ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED);
+ return ASN1Integer.intValue(contents, start, ASN1Integer.SIGN_EXT_SIGNED);
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.ENUMERATED, bytes);
+ out.writeEncodingDL(withTag, BERTags.ENUMERATED, contents);
}
boolean asn1Equals(
@@ -173,39 +181,39 @@
ASN1Enumerated other = (ASN1Enumerated)o;
- return Arrays.areEqual(this.bytes, other.bytes);
+ return Arrays.areEqual(this.contents, other.contents);
}
public int hashCode()
{
- return Arrays.hashCode(bytes);
+ return Arrays.hashCode(contents);
}
- private static ASN1Enumerated[] cache = new ASN1Enumerated[12];
+ private static final ASN1Enumerated[] cache = new ASN1Enumerated[12];
- static ASN1Enumerated fromOctetString(byte[] enc)
+ static ASN1Enumerated createPrimitive(byte[] contents, boolean clone)
{
- if (enc.length > 1)
+ if (contents.length > 1)
{
- return new ASN1Enumerated(enc);
+ return new ASN1Enumerated(contents, clone);
}
- if (enc.length == 0)
+ if (contents.length == 0)
{
throw new IllegalArgumentException("ENUMERATED has zero length");
}
- int value = enc[0] & 0xff;
+ int value = contents[0] & 0xff;
if (value >= cache.length)
{
- return new ASN1Enumerated(enc);
+ return new ASN1Enumerated(contents, clone);
}
ASN1Enumerated possibleMatch = cache[value];
if (possibleMatch == null)
{
- possibleMatch = cache[value] = new ASN1Enumerated(enc);
+ possibleMatch = cache[value] = new ASN1Enumerated(contents, clone);
}
return possibleMatch;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java
index 4f6aa4c..7cfda82 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java
@@ -3,6 +3,8 @@
import java.io.IOException;
+import com.android.internal.org.bouncycastle.util.Objects;
+
/**
* Class representing the DER-type External
* @hide This class is not part of the Android public SDK API
@@ -10,101 +12,124 @@
public abstract class ASN1External
extends ASN1Primitive
{
- protected ASN1ObjectIdentifier directReference;
- protected ASN1Integer indirectReference;
- protected ASN1Primitive dataValueDescriptor;
- protected int encoding;
- protected ASN1Primitive externalContent;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1External.class, BERTags.EXTERNAL)
+ {
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ // TODO Ideally ASN1External would have no subclasses and just hold the sequence
+ return sequence.toASN1External();
+ }
+ };
- /**
- * Construct an EXTERNAL object, the input encoding vector must have exactly two elements on it.
- * <p>
- * Acceptable input formats are:
- * <ul>
- * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
- * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
- * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
- * </ul>
- *
- * @throws IllegalArgumentException if input size is wrong, or
- */
- public ASN1External(ASN1EncodableVector vector)
+ public static ASN1External getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1External)
+ {
+ return (ASN1External)obj;
+ }
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1External)
+ {
+ return (ASN1External)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1External)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct external from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ public static ASN1External getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1External)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ ASN1ObjectIdentifier directReference;
+ ASN1Integer indirectReference;
+ // TODO Actually use ASN1ObjectDescriptor for this
+ ASN1Primitive dataValueDescriptor;
+ int encoding;
+ ASN1Primitive externalContent;
+
+ ASN1External(ASN1Sequence sequence)
{
int offset = 0;
- ASN1Primitive enc = getObjFromVector(vector, offset);
- if (enc instanceof ASN1ObjectIdentifier)
+ ASN1Primitive asn1 = getObjFromSequence(sequence, offset);
+ if (asn1 instanceof ASN1ObjectIdentifier)
{
- directReference = (ASN1ObjectIdentifier)enc;
- offset++;
- enc = getObjFromVector(vector, offset);
+ directReference = (ASN1ObjectIdentifier)asn1;
+ asn1 = getObjFromSequence(sequence, ++offset);
}
- if (enc instanceof ASN1Integer)
+ if (asn1 instanceof ASN1Integer)
{
- indirectReference = (ASN1Integer) enc;
- offset++;
- enc = getObjFromVector(vector, offset);
+ indirectReference = (ASN1Integer)asn1;
+ asn1 = getObjFromSequence(sequence, ++offset);
}
- if (!(enc instanceof ASN1TaggedObject))
+ if (!(asn1 instanceof ASN1TaggedObject))
{
- dataValueDescriptor = (ASN1Primitive) enc;
- offset++;
- enc = getObjFromVector(vector, offset);
+ dataValueDescriptor = asn1;
+ asn1 = getObjFromSequence(sequence, ++offset);
}
- if (vector.size() != offset + 1)
+ if (sequence.size() != offset + 1)
{
- throw new IllegalArgumentException("input vector too large");
+ throw new IllegalArgumentException("input sequence too large");
}
- if (!(enc instanceof ASN1TaggedObject))
+ if (!(asn1 instanceof ASN1TaggedObject))
{
- throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
+ throw new IllegalArgumentException(
+ "No tagged object found in sequence. Structure doesn't seem to be of type External");
}
- ASN1TaggedObject obj = (ASN1TaggedObject)enc;
- setEncoding(obj.getTagNo());
- externalContent = obj.getObject();
+
+ ASN1TaggedObject obj = (ASN1TaggedObject)asn1;
+ this.encoding = checkEncoding(obj.getTagNo());
+ this.externalContent = getExternalContent(obj);
}
- private ASN1Primitive getObjFromVector(ASN1EncodableVector v, int index)
+ ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor,
+ DERTaggedObject externalData)
{
- if (v.size() <= index)
- {
- throw new IllegalArgumentException("too few objects in input vector");
- }
-
- return v.get(index).toASN1Primitive();
+ this.directReference = directReference;
+ this.indirectReference = indirectReference;
+ this.dataValueDescriptor = dataValueDescriptor;
+ this.encoding = checkEncoding(externalData.getTagNo());
+ this.externalContent = getExternalContent(externalData);
}
- /**
- * Creates a new instance of External
- * See X.690 for more informations about the meaning of these parameters
- * @param directReference The direct reference or <code>null</code> if not set.
- * @param indirectReference The indirect reference or <code>null</code> if not set.
- * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
- * @param externalData The external data in its encoded form.
- */
- public ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor,
+ int encoding, ASN1Primitive externalData)
{
- this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ this.directReference = directReference;
+ this.indirectReference = indirectReference;
+ this.dataValueDescriptor = dataValueDescriptor;
+ this.encoding = checkEncoding(encoding);
+ this.externalContent = checkExternalContent(encoding, externalData);
}
- /**
- * Creates a new instance of External.
- * See X.690 for more informations about the meaning of these parameters
- * @param directReference The direct reference or <code>null</code> if not set.
- * @param indirectReference The indirect reference or <code>null</code> if not set.
- * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
- * @param encoding The encoding to be used for the external data
- * @param externalData The external data
- */
- public ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ abstract ASN1Sequence buildSequence();
+
+ int encodedLength(boolean withTag) throws IOException
{
- setDirectReference(directReference);
- setIndirectReference(indirectReference);
- setDataValueDescriptor(dataValueDescriptor);
- setEncoding(encoding);
- setExternalContent(externalData.toASN1Primitive());
+ return buildSequence().encodedLength(withTag);
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.EXTERNAL);
+ buildSequence().encode(out, false);
}
ASN1Primitive toDERObject()
@@ -117,75 +142,38 @@
return new DLExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
}
- /* (non-Javadoc)
- * @see java.lang.Object#hashCode()
- */
public int hashCode()
{
- int ret = 0;
- if (directReference != null)
- {
- ret = directReference.hashCode();
- }
- if (indirectReference != null)
- {
- ret ^= indirectReference.hashCode();
- }
- if (dataValueDescriptor != null)
- {
- ret ^= dataValueDescriptor.hashCode();
- }
- ret ^= externalContent.hashCode();
- return ret;
+ return Objects.hashCode(this.directReference)
+ ^ Objects.hashCode(this.indirectReference)
+ ^ Objects.hashCode(this.dataValueDescriptor)
+ ^ this.encoding
+ ^ this.externalContent.hashCode();
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return true;
}
- int encodedLength()
- throws IOException
+ boolean asn1Equals(ASN1Primitive primitive)
{
- return this.getEncoded().length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#asn1Equals(org.bouncycastle.asn1.ASN1Primitive)
- */
- boolean asn1Equals(ASN1Primitive o)
- {
- if (!(o instanceof ASN1External))
- {
- return false;
- }
- if (this == o)
+ if (this == primitive)
{
return true;
}
- ASN1External other = (ASN1External)o;
- if (directReference != null)
+ if (!(primitive instanceof ASN1External))
{
- if (other.directReference == null || !other.directReference.equals(directReference))
- {
- return false;
- }
+ return false;
}
- if (indirectReference != null)
- {
- if (other.indirectReference == null || !other.indirectReference.equals(indirectReference))
- {
- return false;
- }
- }
- if (dataValueDescriptor != null)
- {
- if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor))
- {
- return false;
- }
- }
- return externalContent.equals(other.externalContent);
+
+ ASN1External that = (ASN1External)primitive;
+
+ return Objects.areEqual(this.directReference, that.directReference)
+ && Objects.areEqual(this.indirectReference, that.indirectReference)
+ && Objects.areEqual(this.dataValueDescriptor, that.dataValueDescriptor)
+ && this.encoding == that.encoding
+ && this.externalContent.equals(that.externalContent);
}
/**
@@ -219,7 +207,7 @@
{
return encoding;
}
-
+
/**
* Returns the content of this element
* @return The content
@@ -228,7 +216,7 @@
{
return externalContent;
}
-
+
/**
* Returns the indirect reference of this element
* @return The reference
@@ -237,27 +225,9 @@
{
return indirectReference;
}
-
- /**
- * Sets the data value descriptor
- * @param dataValueDescriptor The descriptor
- */
- private void setDataValueDescriptor(ASN1Primitive dataValueDescriptor)
- {
- this.dataValueDescriptor = dataValueDescriptor;
- }
/**
- * Sets the direct reference of the external element
- * @param directReferemce The reference
- */
- private void setDirectReference(ASN1ObjectIdentifier directReferemce)
- {
- this.directReference = directReferemce;
- }
-
- /**
- * Sets the encoding of the content. Valid values are
+ * Checks the encoding of the content. Valid values are
* <ul>
* <li><code>0</code> single-ASN1-type</li>
* <li><code>1</code> OCTET STRING</li>
@@ -265,30 +235,57 @@
* </ul>
* @param encoding The encoding
*/
- private void setEncoding(int encoding)
+ private static int checkEncoding(int encoding)
{
if (encoding < 0 || encoding > 2)
{
throw new IllegalArgumentException("invalid encoding value: " + encoding);
}
- this.encoding = encoding;
+
+ return encoding;
}
-
- /**
- * Sets the content of this element
- * @param externalContent The content
- */
- private void setExternalContent(ASN1Primitive externalContent)
+
+ private static ASN1Primitive checkExternalContent(int tagNo, ASN1Primitive externalContent)
{
- this.externalContent = externalContent;
+ switch (tagNo)
+ {
+ case 1:
+ return ASN1OctetString.TYPE.checkedCast(externalContent);
+ case 2:
+ return ASN1BitString.TYPE.checkedCast(externalContent);
+ default:
+ return externalContent;
+ }
}
-
- /**
- * Sets the indirect reference of this element
- * @param indirectReference The reference
- */
- private void setIndirectReference(ASN1Integer indirectReference)
+
+ private static ASN1Primitive getExternalContent(ASN1TaggedObject encoding)
{
- this.indirectReference = indirectReference;
+ int tagClass = encoding.getTagClass(), tagNo = encoding.getTagNo();
+ if (BERTags.CONTEXT_SPECIFIC != tagClass)
+ {
+ throw new IllegalArgumentException("invalid tag: " + ASN1Util.getTagText(tagClass, tagNo));
+ }
+
+ switch (tagNo)
+ {
+ case 0:
+ return encoding.getExplicitBaseObject().toASN1Primitive();
+ case 1:
+ return ASN1OctetString.getInstance(encoding, false);
+ case 2:
+ return ASN1BitString.getInstance(encoding, false);
+ default:
+ throw new IllegalArgumentException("invalid tag: " + ASN1Util.getTagText(tagClass, tagNo));
+ }
+ }
+
+ private static ASN1Primitive getObjFromSequence(ASN1Sequence sequence, int index)
+ {
+ if (sequence.size() <= index)
+ {
+ throw new IllegalArgumentException("too few objects in input sequence");
+ }
+
+ return sequence.getObjectAt(index).toASN1Primitive();
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ExternalParser.java
similarity index 81%
rename from repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java
rename to repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ExternalParser.java
index f4bc6e3..370be2b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ExternalParser.java
@@ -4,10 +4,10 @@
import java.io.IOException;
/**
- * Interface to parse ASN.1 ApplicationSpecific objects.
+ * Parser DER EXTERNAL tagged objects.
* @hide This class is not part of the Android public SDK API
*/
-public interface ASN1ApplicationSpecificParser
+public interface ASN1ExternalParser
extends ASN1Encodable, InMemoryRepresentable
{
/**
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralString.java
new file mode 100644
index 0000000..4794b81
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralString.java
@@ -0,0 +1,153 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 GENERAL-STRING data type.
+ * <p>
+ * This is an 8-bit encoded ISO 646 (ASCII) character set
+ * with optional escapes to other character sets.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1GeneralString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1GeneralString.class, BERTags.GENERAL_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a GeneralString from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1GeneralString instance, or null.
+ */
+ public static ASN1GeneralString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1GeneralString)
+ {
+ return (ASN1GeneralString) obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1GeneralString)
+ {
+ return (ASN1GeneralString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1GeneralString)TYPE.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());
+ }
+
+ /**
+ * Return a GeneralString from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1GeneralString instance.
+ */
+ public static ASN1GeneralString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1GeneralString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1GeneralString(String string)
+ {
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1GeneralString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ /**
+ * Return a Java String representation of our contained String.
+ *
+ * @return a Java String representing our contents.
+ */
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ /**
+ * Return a byte array representation of our contained String.
+ *
+ * @return a byte array representing our contents.
+ */
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.GENERAL_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1GeneralString))
+ {
+ return false;
+ }
+
+ ASN1GeneralString that = (ASN1GeneralString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1GeneralString createPrimitive(byte[] contents)
+ {
+ return new DERGeneralString(contents, false);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java
index 5e75554..0388518 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java
@@ -48,7 +48,13 @@
public class ASN1GeneralizedTime
extends ASN1Primitive
{
- protected byte[] time;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1GeneralizedTime.class, BERTags.GENERALIZED_TIME)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
/**
* return a generalized time from the passed in object
@@ -64,12 +70,19 @@
{
return (ASN1GeneralizedTime)obj;
}
-
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1GeneralizedTime)
+ {
+ return (ASN1GeneralizedTime)primitive;
+ }
+ }
if (obj instanceof byte[])
{
try
{
- return (ASN1GeneralizedTime)fromByteArray((byte[])obj);
+ return (ASN1GeneralizedTime)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -83,29 +96,19 @@
/**
* return a Generalized Time object from a tagged object.
*
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
* @return an ASN1GeneralizedTime instance.
- * @throws IllegalArgumentException if the tagged object cannot
- * be converted.
+ * @throws IllegalArgumentException if the tagged object cannot be converted.
*/
- public static ASN1GeneralizedTime getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1GeneralizedTime getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1GeneralizedTime)
- {
- return getInstance(o);
- }
- else
- {
- return new ASN1GeneralizedTime(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1GeneralizedTime)TYPE.getContextInstance(taggedObject, explicit);
}
+ final byte[] contents;
+
/**
* The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z
* for local time, or Z+-HHMM on the end, for difference between local
@@ -118,7 +121,7 @@
public ASN1GeneralizedTime(
String time)
{
- this.time = Strings.toByteArray(time);
+ this.contents = Strings.toByteArray(time);
try
{
this.getDate();
@@ -143,7 +146,7 @@
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
/**
@@ -165,7 +168,7 @@
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
ASN1GeneralizedTime(
@@ -175,7 +178,7 @@
{
throw new IllegalArgumentException("GeneralizedTime string too short");
}
- this.time = bytes;
+ this.contents = bytes;
if (!(isDigit(0) && isDigit(1) && isDigit(2) && isDigit(3)))
{
@@ -190,7 +193,7 @@
*/
public String getTimeString()
{
- return Strings.fromByteArray(time);
+ return Strings.fromByteArray(contents);
}
/**
@@ -208,7 +211,7 @@
*/
public String getTime()
{
- String stime = Strings.fromByteArray(time);
+ String stime = Strings.fromByteArray(contents);
//
// standardise the format.
@@ -360,34 +363,26 @@
throws ParseException
{
SimpleDateFormat dateF;
- String stime = Strings.fromByteArray(time);
+ String stime = Strings.fromByteArray(contents);
String d = stime;
if (stime.endsWith("Z"))
{
if (hasFractionalSeconds())
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'", LocaleUtil.EN_Locale);
}
else if (hasSeconds())
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", LocaleUtil.EN_Locale);
}
else if (hasMinutes())
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmm'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHHmm'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHHmm'Z'", LocaleUtil.EN_Locale);
}
else
{
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHH'Z'");
- dateF = new SimpleDateFormat("yyyyMMddHH'Z'", Locale.US);
+ dateF = new SimpleDateFormat("yyyyMMddHH'Z'", LocaleUtil.EN_Locale);
}
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
@@ -432,14 +427,14 @@
d = pruneFractionalSeconds(d);
}
- return DateUtil.epochAdjust(dateF.parse(d));
+ return dateF.parse(d);
}
protected boolean hasFractionalSeconds()
{
- for (int i = 0; i != time.length; i++)
+ for (int i = 0; i != contents.length; i++)
{
- if (time[i] == '.')
+ if (contents[i] == '.')
{
if (i == 14)
{
@@ -462,49 +457,46 @@
private boolean isDigit(int pos)
{
- return time.length > pos && time[pos] >= '0' && time[pos] <= '9';
+ return contents.length > pos && contents[pos] >= '0' && contents[pos] <= '9';
}
- boolean isConstructed()
+ final boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- int length = time.length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, time);
+ out.writeEncodingDL(withTag, BERTags.GENERALIZED_TIME, contents);
}
ASN1Primitive toDERObject()
{
- return new DERGeneralizedTime(time);
+ return new DERGeneralizedTime(contents);
}
- ASN1Primitive toDLObject()
- {
- return new DERGeneralizedTime(time);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive o)
{
if (!(o instanceof ASN1GeneralizedTime))
{
return false;
}
- return Arrays.areEqual(time, ((ASN1GeneralizedTime)o).time);
+ return Arrays.areEqual(contents, ((ASN1GeneralizedTime)o).contents);
}
public int hashCode()
{
- return Arrays.hashCode(time);
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1GeneralizedTime createPrimitive(byte[] contents)
+ {
+ return new ASN1GeneralizedTime(contents);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GraphicString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GraphicString.java
new file mode 100644
index 0000000..9f68f9b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GraphicString.java
@@ -0,0 +1,132 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1GraphicString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1GraphicString.class, BERTags.GRAPHIC_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a GraphicString from the passed in object.
+ *
+ * @param obj an ASN1GraphicString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1GraphicString instance, or null.
+ */
+ public static ASN1GraphicString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1GraphicString)
+ {
+ return (ASN1GraphicString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1GraphicString)
+ {
+ return (ASN1GraphicString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1GraphicString)TYPE.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());
+ }
+
+ /**
+ * Return a GraphicString from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly tagged,
+ * false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1GraphicString instance, or null.
+ */
+ public static ASN1GraphicString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1GraphicString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1GraphicString(byte[] contents, boolean clone)
+ {
+ if (null == contents)
+ {
+ throw new NullPointerException("'contents' cannot be null");
+ }
+
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.GRAPHIC_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1GraphicString))
+ {
+ return false;
+ }
+
+ ASN1GraphicString that = (ASN1GraphicString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ static ASN1GraphicString createPrimitive(byte[] contents)
+ {
+ return new DERGraphicString(contents, false);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1IA5String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1IA5String.java
new file mode 100644
index 0000000..7e87652
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1IA5String.java
@@ -0,0 +1,172 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 IA5String object - this is a ISO 646 (ASCII) string encoding code points 0 to 127.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1IA5String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1IA5String.class, BERTags.IA5_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return an IA5 string from the passed in object
+ *
+ * @param obj an ASN1IA5String or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a ASN1IA5String instance, or null.
+ */
+ public static ASN1IA5String getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1IA5String)
+ {
+ return (ASN1IA5String)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1IA5String)
+ {
+ return (ASN1IA5String)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1IA5String)TYPE.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());
+ }
+
+ /**
+ * Return an IA5 String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1IA5String instance, or null.
+ */
+ public static ASN1IA5String getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1IA5String)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1IA5String(String string, boolean validate)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+ if (validate && !isIA5String(string))
+ {
+ throw new IllegalArgumentException("'string' contains illegal characters");
+ }
+
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1IA5String(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.IA5_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1IA5String))
+ {
+ return false;
+ }
+
+ ASN1IA5String that = (ASN1IA5String)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ /**
+ * return true if the passed in String can be represented without
+ * loss as an IA5String, false otherwise.
+ *
+ * @param str the string to check.
+ * @return true if character set in IA5String set, false otherwise.
+ */
+ public static boolean isIA5String(String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ static ASN1IA5String createPrimitive(byte[] contents)
+ {
+ return new DERIA5String(contents, false);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java
index 482fcff..d9ad81f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java
@@ -22,11 +22,9 @@
{
private final int limit;
private final boolean lazyEvaluate;
-
private final byte[][] tmpBuffers;
- public ASN1InputStream(
- InputStream is)
+ public ASN1InputStream(InputStream is)
{
this(is, StreamUtil.findLimit(is));
}
@@ -37,8 +35,7 @@
*
* @param input array containing ASN.1 encoded data.
*/
- public ASN1InputStream(
- byte[] input)
+ public ASN1InputStream(byte[] input)
{
this(new ByteArrayInputStream(input), input.length);
}
@@ -50,22 +47,18 @@
* @param input array containing ASN.1 encoded data.
* @param lazyEvaluate true if parsing inside constructed objects can be delayed.
*/
- public ASN1InputStream(
- byte[] input,
- boolean lazyEvaluate)
+ public ASN1InputStream(byte[] input, boolean lazyEvaluate)
{
this(new ByteArrayInputStream(input), input.length, lazyEvaluate);
}
-
+
/**
* Create an ASN1InputStream where no DER object will be longer than limit.
*
* @param input stream containing ASN.1 encoded data.
* @param limit maximum size of a DER encoded object.
*/
- public ASN1InputStream(
- InputStream input,
- int limit)
+ public ASN1InputStream(InputStream input, int limit)
{
this(input, limit, false);
}
@@ -77,9 +70,7 @@
* @param input stream containing ASN.1 encoded data.
* @param lazyEvaluate true if parsing inside constructed objects can be delayed.
*/
- public ASN1InputStream(
- InputStream input,
- boolean lazyEvaluate)
+ public ASN1InputStream(InputStream input, boolean lazyEvaluate)
{
this(input, StreamUtil.findLimit(input), lazyEvaluate);
}
@@ -92,15 +83,17 @@
* @param limit maximum size of a DER encoded object.
* @param lazyEvaluate true if parsing inside constructed objects can be delayed.
*/
- public ASN1InputStream(
- InputStream input,
- int limit,
- boolean lazyEvaluate)
+ public ASN1InputStream(InputStream input, int limit, boolean lazyEvaluate)
+ {
+ this(input, limit, lazyEvaluate, new byte[11][]);
+ }
+
+ private ASN1InputStream(InputStream input, int limit, boolean lazyEvaluate, byte[][] tmpBuffers)
{
super(input);
this.limit = limit;
this.lazyEvaluate = lazyEvaluate;
- this.tmpBuffers = new byte[11][];
+ this.tmpBuffers = tmpBuffers;
}
int getLimit()
@@ -118,7 +111,7 @@
byte[] bytes)
throws IOException
{
- if (Streams.readFully(this, bytes) != bytes.length)
+ if (Streams.readFully(this, bytes, 0, bytes.length) != bytes.length)
{
throw new EOFException("EOF encountered in middle of object");
}
@@ -139,82 +132,57 @@
int length)
throws IOException
{
- boolean isConstructed = (tag & CONSTRUCTED) != 0;
+ // TODO[asn1] Special-case zero length first?
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length, limit);
- if ((tag & APPLICATION) != 0)
+ if (0 == (tag & FLAGS))
{
- return new DLApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
+ return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
}
- if ((tag & TAGGED) != 0)
+ int tagClass = tag & PRIVATE;
+ if (0 != tagClass)
{
- return new ASN1StreamParser(defIn).readTaggedObject(isConstructed, tagNo);
+ boolean isConstructed = (tag & CONSTRUCTED) != 0;
+ return readTaggedObjectDL(tagClass, tagNo, isConstructed, defIn);
}
- if (isConstructed)
+ switch (tagNo)
{
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagNo)
+ case BIT_STRING:
+ {
+ return buildConstructedBitString(readVector(defIn));
+ }
+ case OCTET_STRING:
+ {
+ //
+ // yes, people actually do this...
+ //
+ return buildConstructedOctetString(readVector(defIn));
+ }
+ case SEQUENCE:
+ {
+ if (defIn.getRemaining() < 1)
{
- case OCTET_STRING:
- //
- // yes, people actually do this...
- //
- ASN1EncodableVector v = readVector(defIn);
- ASN1OctetString[] strings = new ASN1OctetString[v.size()];
-
- for (int i = 0; i != strings.length; i++)
- {
- ASN1Encodable asn1Obj = v.get(i);
- if (asn1Obj instanceof ASN1OctetString)
- {
- strings[i] = (ASN1OctetString)asn1Obj;
- }
- else
- {
- throw new ASN1Exception("unknown object encountered in constructed OCTET STRING: " + asn1Obj.getClass());
- }
- }
-
- return new BEROctetString(strings);
- case SEQUENCE:
- if (lazyEvaluate)
- {
- return new LazyEncodedSequence(defIn.toByteArray());
- }
- else
- {
- return DLFactory.createSequence(readVector(defIn));
- }
- case SET:
- return DLFactory.createSet(readVector(defIn));
- case EXTERNAL:
- return new DLExternal(readVector(defIn));
- default:
- throw new IOException("unknown tag " + tagNo + " encountered");
+ return DLFactory.EMPTY_SEQUENCE;
+ }
+ else if (lazyEvaluate)
+ {
+ return new LazyEncodedSequence(defIn.toByteArray());
+ }
+ else
+ {
+ return DLFactory.createSequence(readVector(defIn));
}
}
-
- return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
- }
-
- ASN1EncodableVector readVector(DefiniteLengthInputStream dIn) throws IOException
- {
- if (dIn.getRemaining() < 1)
- {
- return new ASN1EncodableVector(0);
+ case SET:
+ return DLFactory.createSet(readVector(defIn));
+ case EXTERNAL:
+ return DLFactory.createSequence(readVector(defIn)).toASN1External();
+ default:
+ throw new IOException("unknown tag " + tagNo + " encountered");
}
-
- ASN1InputStream subStream = new ASN1InputStream(dIn);
- ASN1EncodableVector v = new ASN1EncodableVector();
- ASN1Primitive p;
- while ((p = subStream.readObject()) != null)
- {
- v.add(p);
- }
- return v;
}
public ASN1Primitive readObject()
@@ -231,55 +199,12 @@
return null;
}
- //
- // calculate tag number
- //
int tagNo = readTagNumber(this, tag);
-
- boolean isConstructed = (tag & CONSTRUCTED) != 0;
-
- //
- // calculate length
- //
int length = readLength();
- if (length < 0) // indefinite-length method
+ if (length >= 0)
{
- if (!isConstructed)
- {
- throw new IOException("indefinite-length primitive encoding encountered");
- }
-
- IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit);
- ASN1StreamParser sp = new ASN1StreamParser(indIn, limit);
-
- if ((tag & APPLICATION) != 0)
- {
- return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject();
- }
-
- if ((tag & TAGGED) != 0)
- {
- return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject();
- }
-
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagNo)
- {
- case OCTET_STRING:
- return new BEROctetStringParser(sp).getLoadedObject();
- case SEQUENCE:
- return new BERSequenceParser(sp).getLoadedObject();
- case SET:
- return new BERSetParser(sp).getLoadedObject();
- case EXTERNAL:
- return new DERExternalParser(sp).getLoadedObject();
- default:
- throw new IOException("unknown BER object encountered");
- }
- }
- else
- {
+ // definite-length
try
{
return buildObject(tag, tagNo, length);
@@ -289,6 +214,124 @@
throw new ASN1Exception("corrupted stream detected", e);
}
}
+
+ // indefinite-length
+
+ if (0 == (tag & CONSTRUCTED))
+ {
+ throw new IOException("indefinite-length primitive encoding encountered");
+ }
+
+ IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit);
+ ASN1StreamParser sp = new ASN1StreamParser(indIn, limit, tmpBuffers);
+
+ int tagClass = tag & PRIVATE;
+ if (0 != tagClass)
+ {
+ return sp.loadTaggedIL(tagClass, tagNo);
+ }
+
+ switch (tagNo)
+ {
+ case BIT_STRING:
+ return BERBitStringParser.parse(sp);
+ case OCTET_STRING:
+ return BEROctetStringParser.parse(sp);
+ case EXTERNAL:
+ // TODO[asn1] BERExternalParser
+ return DERExternalParser.parse(sp);
+ case SEQUENCE:
+ return BERSequenceParser.parse(sp);
+ case SET:
+ return BERSetParser.parse(sp);
+ default:
+ throw new IOException("unknown BER object encountered");
+ }
+ }
+
+ ASN1BitString buildConstructedBitString(ASN1EncodableVector contentsElements) throws IOException
+ {
+ ASN1BitString[] strings = new ASN1BitString[contentsElements.size()];
+
+ for (int i = 0; i != strings.length; i++)
+ {
+ ASN1Encodable asn1Obj = contentsElements.get(i);
+ if (asn1Obj instanceof ASN1BitString)
+ {
+ strings[i] = (ASN1BitString)asn1Obj;
+ }
+ else
+ {
+ throw new ASN1Exception(
+ "unknown object encountered in constructed BIT STRING: " + asn1Obj.getClass());
+ }
+ }
+
+ // TODO Probably ought to be DLBitString
+ return new BERBitString(strings);
+ }
+
+ ASN1OctetString buildConstructedOctetString(ASN1EncodableVector contentsElements) throws IOException
+ {
+ ASN1OctetString[] strings = new ASN1OctetString[contentsElements.size()];
+
+ for (int i = 0; i != strings.length; i++)
+ {
+ ASN1Encodable asn1Obj = contentsElements.get(i);
+ if (asn1Obj instanceof ASN1OctetString)
+ {
+ strings[i] = (ASN1OctetString)asn1Obj;
+ }
+ else
+ {
+ throw new ASN1Exception(
+ "unknown object encountered in constructed OCTET STRING: " + asn1Obj.getClass());
+ }
+ }
+
+ // TODO Probably ought to be DEROctetString (no DLOctetString available)
+ return new BEROctetString(strings);
+ }
+
+ ASN1Primitive readTaggedObjectDL(int tagClass, int tagNo, boolean constructed, DefiniteLengthInputStream defIn)
+ throws IOException
+ {
+ if (!constructed)
+ {
+ byte[] contentsOctets = defIn.toByteArray();
+ return ASN1TaggedObject.createPrimitive(tagClass, tagNo, contentsOctets);
+ }
+
+ ASN1EncodableVector contentsElements = readVector(defIn);
+ return ASN1TaggedObject.createConstructedDL(tagClass, tagNo, contentsElements);
+ }
+
+ ASN1EncodableVector readVector() throws IOException
+ {
+ ASN1Primitive p = readObject();
+ if (null == p)
+ {
+ return new ASN1EncodableVector(0);
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ do
+ {
+ v.add(p);
+ }
+ while ((p = readObject()) != null);
+ return v;
+ }
+
+ ASN1EncodableVector readVector(DefiniteLengthInputStream defIn) throws IOException
+ {
+ int remaining = defIn.getRemaining();
+ if (remaining < 1)
+ {
+ return new ASN1EncodableVector(0);
+ }
+
+ return new ASN1InputStream(defIn, remaining, lazyEvaluate, tmpBuffers).readVector();
}
static int readTagNumber(InputStream s, int tag)
@@ -301,32 +344,44 @@
//
if (tagNo == 0x1f)
{
- tagNo = 0;
-
int b = s.read();
+ if (b < 31)
+ {
+ if (b < 0)
+ {
+ throw new EOFException("EOF found inside tag value.");
+ }
+ throw new IOException("corrupted stream - high tag number < 31 found");
+ }
+
+ tagNo = b & 0x7f;
// X.690-0207 8.1.2.4.2
// "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
- if ((b & 0x7f) == 0) // Note: -1 will pass
+ if (0 == tagNo)
{
throw new IOException("corrupted stream - invalid high tag number found");
}
- while ((b >= 0) && ((b & 0x80) != 0))
+ while ((b & 0x80) != 0)
{
- tagNo |= (b & 0x7f);
- tagNo <<= 7;
- b = s.read();
- }
+ if ((tagNo >>> 24) != 0)
+ {
+ throw new IOException("Tag number more than 31 bits");
+ }
- if (b < 0)
- {
- throw new EOFException("EOF found inside tag value.");
+ tagNo <<= 7;
+
+ b = s.read();
+ if (b < 0)
+ {
+ throw new EOFException("EOF found inside tag value.");
+ }
+
+ tagNo |= (b & 0x7f);
}
-
- tagNo |= (b & 0x7f);
}
-
+
return tagNo;
}
@@ -334,48 +389,48 @@
throws IOException
{
int length = s.read();
+ if (0 == (length >>> 7))
+ {
+ // definite-length short form
+ return length;
+ }
+ if (0x80 == length)
+ {
+ // indefinite-length
+ return -1;
+ }
if (length < 0)
{
throw new EOFException("EOF found when length expected");
}
-
- if (length == 0x80)
+ if (0xFF == length)
{
- return -1; // indefinite-length encoding
+ throw new IOException("invalid long form definite-length 0xFF");
}
- if (length > 127)
+ int octetsCount = length & 0x7F, octetsPos = 0;
+
+ length = 0;
+ do
{
- int size = length & 0x7f;
-
- // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
- if (size > 4)
+ int octet = s.read();
+ if (octet < 0)
{
- throw new IOException("DER length more than 4 bytes: " + size);
+ throw new EOFException("EOF found reading length");
}
- length = 0;
- for (int i = 0; i < size; i++)
+ if ((length >>> 23) != 0)
{
- int next = s.read();
-
- if (next < 0)
- {
- throw new EOFException("EOF found reading length");
- }
-
- length = (length << 8) + next;
+ throw new IOException("long form definite-length more than 31 bits");
}
- if (length < 0)
- {
- throw new IOException("corrupted stream - negative length found");
- }
+ length = (length << 8) + octet;
+ }
+ while (++octetsPos < octetsCount);
- if (length >= limit && !isParsing) // after all we must have read at least 1 byte
- {
- throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
- }
+ if (length >= limit && !isParsing) // after all we must have read at least 1 byte
+ {
+ throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
}
return length;
@@ -459,50 +514,79 @@
byte[][] tmpBuffers)
throws IOException
{
- switch (tagNo)
+ /*
+ * TODO[asn1] Lookup the universal type object and get it to parse the stream directly (possibly with
+ * access to a single temporary buffer replacing tmpBuffers).
+ */
+ try
{
+ switch (tagNo)
+ {
case BIT_STRING:
- return ASN1BitString.fromInputStream(defIn.getRemaining(), defIn);
+ return ASN1BitString.createPrimitive(defIn.toByteArray());
case BMP_STRING:
- return new DERBMPString(getBMPCharBuffer(defIn));
+ return ASN1BMPString.createPrimitive(getBMPCharBuffer(defIn));
case BOOLEAN:
- return ASN1Boolean.fromOctetString(getBuffer(defIn, tmpBuffers));
+ return ASN1Boolean.createPrimitive(getBuffer(defIn, tmpBuffers));
case ENUMERATED:
- return ASN1Enumerated.fromOctetString(getBuffer(defIn, tmpBuffers));
- case GENERALIZED_TIME:
- return new ASN1GeneralizedTime(defIn.toByteArray());
+ // TODO Ideally only clone if we used a buffer
+ return ASN1Enumerated.createPrimitive(getBuffer(defIn, tmpBuffers), true);
case GENERAL_STRING:
- return new DERGeneralString(defIn.toByteArray());
- case IA5_STRING:
- return new DERIA5String(defIn.toByteArray());
- case INTEGER:
- return new ASN1Integer(defIn.toByteArray(), false);
- case NULL:
- return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?)
- case NUMERIC_STRING:
- return new DERNumericString(defIn.toByteArray());
- case OBJECT_IDENTIFIER:
- return ASN1ObjectIdentifier.fromOctetString(getBuffer(defIn, tmpBuffers));
- case OCTET_STRING:
- return new DEROctetString(defIn.toByteArray());
- case PRINTABLE_STRING:
- return new DERPrintableString(defIn.toByteArray());
- case T61_STRING:
- return new DERT61String(defIn.toByteArray());
- case UNIVERSAL_STRING:
- return new DERUniversalString(defIn.toByteArray());
- case UTC_TIME:
- return new ASN1UTCTime(defIn.toByteArray());
- case UTF8_STRING:
- return new DERUTF8String(defIn.toByteArray());
- case VISIBLE_STRING:
- return new DERVisibleString(defIn.toByteArray());
+ return ASN1GeneralString.createPrimitive(defIn.toByteArray());
+ case GENERALIZED_TIME:
+ return ASN1GeneralizedTime.createPrimitive(defIn.toByteArray());
case GRAPHIC_STRING:
- return new DERGraphicString(defIn.toByteArray());
+ return ASN1GraphicString.createPrimitive(defIn.toByteArray());
+ case IA5_STRING:
+ return ASN1IA5String.createPrimitive(defIn.toByteArray());
+ case INTEGER:
+ return ASN1Integer.createPrimitive(defIn.toByteArray());
+ case NULL:
+ return ASN1Null.createPrimitive(defIn.toByteArray());
+ case NUMERIC_STRING:
+ return ASN1NumericString.createPrimitive(defIn.toByteArray());
+ case OBJECT_DESCRIPTOR:
+ return ASN1ObjectDescriptor.createPrimitive(defIn.toByteArray());
+ case OBJECT_IDENTIFIER:
+ // TODO Ideally only clone if we used a buffer
+ return ASN1ObjectIdentifier.createPrimitive(getBuffer(defIn, tmpBuffers), true);
+ case OCTET_STRING:
+ return ASN1OctetString.createPrimitive(defIn.toByteArray());
+ case PRINTABLE_STRING:
+ return ASN1PrintableString.createPrimitive(defIn.toByteArray());
+ case RELATIVE_OID:
+ return ASN1RelativeOID.createPrimitive(defIn.toByteArray(), false);
+ case T61_STRING:
+ return ASN1T61String.createPrimitive(defIn.toByteArray());
+ case UNIVERSAL_STRING:
+ return ASN1UniversalString.createPrimitive(defIn.toByteArray());
+ case UTC_TIME:
+ return ASN1UTCTime.createPrimitive(defIn.toByteArray());
+ case UTF8_STRING:
+ return ASN1UTF8String.createPrimitive(defIn.toByteArray());
case VIDEOTEX_STRING:
- return new DERVideotexString(defIn.toByteArray());
+ return ASN1VideotexString.createPrimitive(defIn.toByteArray());
+ case VISIBLE_STRING:
+ return ASN1VisibleString.createPrimitive(defIn.toByteArray());
+ case TIME:
+ case DATE:
+ case TIME_OF_DAY:
+ case DATE_TIME:
+ case DURATION:
+ case OBJECT_IDENTIFIER_IRI:
+ case RELATIVE_OID_IRI:
+ throw new IOException("unsupported tag " + tagNo + " encountered");
default:
throw new IOException("unknown tag " + tagNo + " encountered");
+ }
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception(e.getMessage(), e);
+ }
+ catch (IllegalStateException e)
+ {
+ throw new ASN1Exception(e.getMessage(), e);
}
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java
index d09e343..a07c379 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java
@@ -14,6 +14,14 @@
public class ASN1Integer
extends ASN1Primitive
{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Integer.class, BERTags.INTEGER)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
static final int SIGN_EXT_SIGNED = 0xFFFFFFFF;
static final int SIGN_EXT_UNSIGNED = 0xFF;
@@ -39,7 +47,7 @@
{
try
{
- return (ASN1Integer)fromByteArray((byte[])obj);
+ return (ASN1Integer)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -53,27 +61,16 @@
/**
* Return an Integer from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @return an ASN1Integer instance.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
*/
- public static ASN1Integer getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1Integer getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof ASN1Integer)
- {
- return getInstance(o);
- }
- else
- {
- return new ASN1Integer(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1Integer)TYPE.getContextInstance(taggedObject, explicit);
}
/**
@@ -152,6 +149,18 @@
return new BigInteger(bytes);
}
+ public boolean hasValue(int x)
+ {
+ return (bytes.length - start) <= 4
+ && intValue(bytes, start, SIGN_EXT_SIGNED) == x;
+ }
+
+ public boolean hasValue(long x)
+ {
+ return (bytes.length - start) <= 8
+ && longValue(bytes, start, SIGN_EXT_SIGNED) == x;
+ }
+
public boolean hasValue(BigInteger x)
{
return null != x
@@ -193,19 +202,19 @@
return longValue(bytes, start, SIGN_EXT_SIGNED);
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, bytes.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.INTEGER, bytes);
+ out.writeEncodingDL(withTag, BERTags.INTEGER, bytes);
}
public int hashCode()
@@ -230,6 +239,11 @@
return getValue().toString();
}
+ static ASN1Integer createPrimitive(byte[] contents)
+ {
+ return new ASN1Integer(contents, false);
+ }
+
static int intValue(byte[] bytes, int start, int signExt)
{
int length = bytes.length;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Null.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Null.java
index d47488e..921386d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Null.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Null.java
@@ -1,7 +1,4 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
-/***************************************************************/
-/****** DO NOT EDIT THIS CLASS bc-java SOURCE FILE ******/
-/***************************************************************/
package com.android.internal.org.bouncycastle.asn1;
import java.io.IOException;
@@ -13,10 +10,13 @@
public abstract class ASN1Null
extends ASN1Primitive
{
- ASN1Null()
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Null.class, BERTags.NULL)
{
-
- }
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
/**
* Return an instance of ASN.1 NULL from the passed in object.
@@ -44,21 +44,26 @@
{
try
{
- return ASN1Null.getInstance(ASN1Primitive.fromByteArray((byte[])o));
+ return (ASN1Null)TYPE.fromByteArray((byte[])o);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct NULL from byte[]: " + e.getMessage());
}
- catch (ClassCastException e)
- {
- throw new IllegalArgumentException("unknown object in getInstance(): " + o.getClass().getName());
- }
}
return null;
}
+ public static ASN1Null getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1Null)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ ASN1Null()
+ {
+ }
+
public int hashCode()
{
return -1;
@@ -75,10 +80,17 @@
return true;
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
return "NULL";
}
+
+ static ASN1Null createPrimitive(byte[] contents)
+ {
+ if (0 != contents.length)
+ {
+ throw new IllegalStateException("malformed NULL encoding encountered");
+ }
+ return DERNull.INSTANCE;
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1NumericString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1NumericString.java
new file mode 100644
index 0000000..324060e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1NumericString.java
@@ -0,0 +1,215 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
+ * ASN.1 NUMERIC-STRING object.
+ * <p>
+ * This is an ASCII string of characters {0,1,2,3,4,5,6,7,8,9} + space.
+ * <p>
+ * See X.680 section 37.2.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1NumericString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1NumericString.class, BERTags.NUMERIC_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a Numeric string from the passed in object
+ *
+ * @param obj an ASN1NumericString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1NumericString instance, or null
+ */
+ public static ASN1NumericString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1NumericString)
+ {
+ return (ASN1NumericString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1NumericString)
+ {
+ return (ASN1NumericString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1NumericString)TYPE.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());
+ }
+
+ /**
+ * Return an Numeric String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1NumericString instance, or null.
+ */
+ public static ASN1NumericString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1NumericString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ /**
+ * Constructor with optional validation.
+ *
+ * @param string the base string to wrap.
+ * @param validate whether or not to check the string.
+ * @throws IllegalArgumentException if validate is true and the string
+ * contains characters that should not be in a NumericString.
+ */
+ ASN1NumericString(String string, boolean validate)
+ {
+ if (validate && !isNumericString(string))
+ {
+ throw new IllegalArgumentException("string contains illegal characters");
+ }
+
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1NumericString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.NUMERIC_STRING, contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1NumericString))
+ {
+ return false;
+ }
+
+ ASN1NumericString that = (ASN1NumericString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ /**
+ * Return true if the string can be represented as a NumericString ('0'..'9', ' ')
+ *
+ * @param str string to validate.
+ * @return true if numeric, false otherwise.
+ */
+ public static boolean isNumericString(String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+
+ if (('0' <= ch && ch <= '9') || ch == ' ')
+ {
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ static boolean isNumericString(byte[] contents)
+ {
+ for (int i = 0; i < contents.length; ++i)
+ {
+ switch (contents[i])
+ {
+ case 0x20:
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ case 0x38:
+ case 0x39:
+ break;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ static ASN1NumericString createPrimitive(byte[] contents)
+ {
+ // TODO Validation - sort out exception types
+// if (!isNumericString(contents))
+
+ return new DERNumericString(contents, false);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java
index adcd257..82c48f2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java
@@ -16,12 +16,12 @@
{
public void encodeTo(OutputStream output) throws IOException
{
- ASN1OutputStream.create(output).writeObject(this);
+ toASN1Primitive().encodeTo(output);
}
public void encodeTo(OutputStream output, String encoding) throws IOException
{
- ASN1OutputStream.create(output, encoding).writeObject(this);
+ toASN1Primitive().encodeTo(output, encoding);
}
/**
@@ -33,7 +33,7 @@
public byte[] getEncoded() throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- encodeTo(bOut);
+ toASN1Primitive().encodeTo(bOut);
return bOut.toByteArray();
}
@@ -47,7 +47,7 @@
public byte[] getEncoded(String encoding) throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- encodeTo(bOut, encoding);
+ toASN1Primitive().encodeTo(bOut, encoding);
return bOut.toByteArray();
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectDescriptor.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectDescriptor.java
new file mode 100644
index 0000000..bf99df3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectDescriptor.java
@@ -0,0 +1,145 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class ASN1ObjectDescriptor
+ extends ASN1Primitive
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1ObjectDescriptor.class, BERTags.OBJECT_DESCRIPTOR)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return new ASN1ObjectDescriptor(
+ (ASN1GraphicString)ASN1GraphicString.TYPE.fromImplicitPrimitive(octetString));
+ }
+
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return new ASN1ObjectDescriptor(
+ (ASN1GraphicString)ASN1GraphicString.TYPE.fromImplicitConstructed(sequence));
+ }
+ };
+
+ /**
+ * Return an ObjectDescriptor from the passed in object.
+ *
+ * @param obj an ASN1ObjectDescriptor or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1ObjectDescriptor instance, or null.
+ */
+ public static ASN1ObjectDescriptor getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1ObjectDescriptor)
+ {
+ return (ASN1ObjectDescriptor)obj;
+ }
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1ObjectDescriptor)
+ {
+ return (ASN1ObjectDescriptor)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1ObjectDescriptor)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct object descriptor from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an ObjectDescriptor from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly tagged,
+ * false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1ObjectDescriptor instance, or null.
+ */
+ public static ASN1ObjectDescriptor getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1ObjectDescriptor)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ private final ASN1GraphicString baseGraphicString;
+
+ public ASN1ObjectDescriptor(ASN1GraphicString baseGraphicString)
+ {
+ if (null == baseGraphicString)
+ {
+ throw new NullPointerException("'baseGraphicString' cannot be null");
+ }
+
+ this.baseGraphicString = baseGraphicString;
+ }
+
+ public ASN1GraphicString getBaseGraphicString()
+ {
+ return baseGraphicString;
+ }
+
+ boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength(boolean withTag)
+ {
+ return baseGraphicString.encodedLength(withTag);
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeIdentifier(withTag, BERTags.OBJECT_DESCRIPTOR);
+ baseGraphicString.encode(out, false);
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ ASN1GraphicString der = (ASN1GraphicString)baseGraphicString.toDERObject();
+
+ return der == baseGraphicString ? this : new ASN1ObjectDescriptor(der);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ ASN1GraphicString dl = (ASN1GraphicString)baseGraphicString.toDLObject();
+
+ return dl == baseGraphicString ? this : new ASN1ObjectDescriptor(dl);
+ }
+
+ boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1ObjectDescriptor))
+ {
+ return false;
+ }
+
+ ASN1ObjectDescriptor that = (ASN1ObjectDescriptor)other;
+
+ return this.baseGraphicString.asn1Equals(that.baseGraphicString);
+ }
+
+ public int hashCode()
+ {
+ return ~baseGraphicString.hashCode();
+ }
+
+ static ASN1ObjectDescriptor createPrimitive(byte[] contents)
+ {
+ return new ASN1ObjectDescriptor(ASN1GraphicString.createPrimitive(contents));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
index 0a0eac7..528d8bf 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
@@ -16,9 +16,18 @@
public class ASN1ObjectIdentifier
extends ASN1Primitive
{
- private final String identifier;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1ObjectIdentifier.class, BERTags.OBJECT_IDENTIFIER)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets(), false);
+ }
+ };
- private byte[] body;
+ public static ASN1ObjectIdentifier fromContents(byte[] contents)
+ {
+ return createPrimitive(contents, true);
+ }
/**
* Return an OID from the passed in object
@@ -27,30 +36,25 @@
* @return an ASN1ObjectIdentifier instance, or null.
* @throws IllegalArgumentException if the object cannot be converted.
*/
- public static ASN1ObjectIdentifier getInstance(
- Object obj)
+ public static ASN1ObjectIdentifier getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1ObjectIdentifier)
{
return (ASN1ObjectIdentifier)obj;
}
-
- if (obj instanceof ASN1Encodable)
+ else if (obj instanceof ASN1Encodable)
{
ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
if (primitive instanceof ASN1ObjectIdentifier)
{
return (ASN1ObjectIdentifier)primitive;
}
}
-
- if (obj instanceof byte[])
+ else if (obj instanceof byte[])
{
- byte[] enc = (byte[])obj;
try
{
- return (ASN1ObjectIdentifier)fromByteArray(enc);
+ return (ASN1ObjectIdentifier)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
@@ -64,47 +68,60 @@
/**
* Return an OBJECT IDENTIFIER from a tagged object.
*
- * @param obj the tagged object holding the object we want
+ * @param taggedObject the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @return an ASN1ObjectIdentifier instance, or null.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
*/
- public static ASN1ObjectIdentifier getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1ObjectIdentifier getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Primitive o = obj.getObject();
+ /*
+ * TODO[asn1] This block here is for backward compatibility, but should eventually be removed.
+ *
+ * - see https://github.com/bcgit/bc-java/issues/1015
+ */
+ if (!explicit && !taggedObject.isParsed() && BERTags.CONTEXT_SPECIFIC == taggedObject.getTagClass())
+ {
+ ASN1Primitive base = taggedObject.getBaseObject().toASN1Primitive();
+ if (!(base instanceof ASN1ObjectIdentifier))
+ {
+ return fromContents(ASN1OctetString.getInstance(base).getOctets());
+ }
+ }
- if (explicit || o instanceof ASN1ObjectIdentifier)
- {
- return getInstance(o);
- }
- else
- {
- return ASN1ObjectIdentifier.fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1ObjectIdentifier)TYPE.getContextInstance(taggedObject, explicit);
}
- private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f;
+ private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7F;
- ASN1ObjectIdentifier(
- byte[] bytes)
+ private static final ConcurrentMap<OidHandle, ASN1ObjectIdentifier> pool =
+ new ConcurrentHashMap<OidHandle, ASN1ObjectIdentifier>();
+
+ private final String identifier;
+ private byte[] contents;
+
+ ASN1ObjectIdentifier(byte[] contents, boolean clone)
{
- StringBuffer objId = new StringBuffer();
+ if (contents.length == 0)
+ {
+ throw new IllegalArgumentException("empty OBJECT IDENTIFIER with no sub-identifiers");
+ }
+
+ StringBuilder objId = new StringBuilder();
long value = 0;
BigInteger bigValue = null;
boolean first = true;
- for (int i = 0; i != bytes.length; i++)
+ for (int i = 0; i != contents.length; i++)
{
- int b = bytes[i] & 0xff;
+ int b = contents[i] & 0xff;
if (value <= LONG_LIMIT)
{
- value += (b & 0x7f);
- if ((b & 0x80) == 0) // end of number reached
+ value += b & 0x7F;
+ if ((b & 0x80) == 0)
{
if (first)
{
@@ -140,7 +157,7 @@
{
bigValue = BigInteger.valueOf(value);
}
- bigValue = bigValue.or(BigInteger.valueOf(b & 0x7f));
+ bigValue = bigValue.or(BigInteger.valueOf(b & 0x7F));
if ((b & 0x80) == 0)
{
if (first)
@@ -164,7 +181,7 @@
// Android-changed: Intern the identifier so there aren't hundreds of duplicates in practice.
this.identifier = objId.toString().intern();
- this.body = Arrays.clone(bytes);
+ this.contents = clone ? Arrays.clone(contents) : contents;
}
/**
@@ -196,7 +213,7 @@
*/
ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branchID)
{
- if (!isValidBranchID(branchID, 0))
+ if (!ASN1RelativeOID.isValidIdentifier(branchID, 0))
{
throw new IllegalArgumentException("string " + branchID + " not a valid OID branch");
}
@@ -237,44 +254,6 @@
return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId);
}
- private void writeField(
- ByteArrayOutputStream out,
- long fieldValue)
- {
- byte[] result = new byte[9];
- int pos = 8;
- result[pos] = (byte)((int)fieldValue & 0x7f);
- while (fieldValue >= (1L << 7))
- {
- fieldValue >>= 7;
- result[--pos] = (byte)((int)fieldValue & 0x7f | 0x80);
- }
- out.write(result, pos, 9 - pos);
- }
-
- private void writeField(
- ByteArrayOutputStream out,
- BigInteger fieldValue)
- {
- int byteCount = (fieldValue.bitLength() + 6) / 7;
- if (byteCount == 0)
- {
- out.write(0);
- }
- else
- {
- BigInteger tmpValue = fieldValue;
- byte[] tmp = new byte[byteCount];
- for (int i = byteCount - 1; i >= 0; i--)
- {
- tmp[i] = (byte)((tmpValue.intValue() & 0x7f) | 0x80);
- tmpValue = tmpValue.shiftRight(7);
- }
- tmp[byteCount - 1] &= 0x7f;
- out.write(tmp, 0, tmp.length);
- }
- }
-
private void doOutput(ByteArrayOutputStream aOut)
{
OIDTokenizer tok = new OIDTokenizer(identifier);
@@ -283,11 +262,11 @@
String secondToken = tok.nextToken();
if (secondToken.length() <= 18)
{
- writeField(aOut, first + Long.parseLong(secondToken));
+ ASN1RelativeOID.writeField(aOut, first + Long.parseLong(secondToken));
}
else
{
- writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
+ ASN1RelativeOID.writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
}
while (tok.hasMoreTokens())
@@ -295,45 +274,42 @@
String token = tok.nextToken();
if (token.length() <= 18)
{
- writeField(aOut, Long.parseLong(token));
+ ASN1RelativeOID.writeField(aOut, Long.parseLong(token));
}
else
{
- writeField(aOut, new BigInteger(token));
+ ASN1RelativeOID.writeField(aOut, new BigInteger(token));
}
}
}
- private synchronized byte[] getBody()
+ private synchronized byte[] getContents()
{
- if (body == null)
+ if (contents == null)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
doOutput(bOut);
- body = bOut.toByteArray();
+ contents = bOut.toByteArray();
}
- return body;
+ return contents;
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
- throws IOException
+ int encodedLength(boolean withTag)
{
- int length = getBody().length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContents().length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.OBJECT_IDENTIFIER, getBody());
+ out.writeEncodingDL(withTag, BERTags.OBJECT_IDENTIFIER, getContents());
}
public int hashCode()
@@ -362,45 +338,6 @@
return getId();
}
- private static boolean isValidBranchID(
- String branchID, int start)
- {
- int digitCount = 0;
-
- int pos = branchID.length();
- while (--pos >= start)
- {
- char ch = branchID.charAt(pos);
-
- if (ch == '.')
- {
- if (0 == digitCount
- || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
- {
- return false;
- }
-
- digitCount = 0;
- }
- else if ('0' <= ch && ch <= '9')
- {
- ++digitCount;
- }
- else
- {
- return false;
- }
- }
-
- if (0 == digitCount
- || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
- {
- return false;
- }
-
- return true;
- }
-
private static boolean isValidIdentifier(
String identifier)
{
@@ -415,7 +352,7 @@
return false;
}
- return isValidBranchID(identifier, 2);
+ return ASN1RelativeOID.isValidIdentifier(identifier, 2);
}
/**
@@ -430,30 +367,35 @@
*/
public ASN1ObjectIdentifier intern()
{
- final OidHandle hdl = new OidHandle(getBody());
+ final OidHandle hdl = new OidHandle(getContents());
ASN1ObjectIdentifier oid = pool.get(hdl);
if (oid == null)
{
- oid = pool.putIfAbsent(hdl, this);
- if (oid == null)
+ synchronized (pool)
{
- oid = this;
+ if (!pool.containsKey(hdl))
+ {
+ pool.put(hdl, this);
+ return this;
+ }
+ else
+ {
+ return pool.get(hdl);
+ }
}
}
return oid;
}
- private static final ConcurrentMap<OidHandle, ASN1ObjectIdentifier> pool = new ConcurrentHashMap<OidHandle, ASN1ObjectIdentifier>();
-
private static class OidHandle
{
private final int key;
- private final byte[] enc;
+ private final byte[] contents;
- OidHandle(byte[] enc)
+ OidHandle(byte[] contents)
{
- this.key = Arrays.hashCode(enc);
- this.enc = enc;
+ this.key = Arrays.hashCode(contents);
+ this.contents = contents;
}
public int hashCode()
@@ -465,20 +407,20 @@
{
if (o instanceof OidHandle)
{
- return Arrays.areEqual(enc, ((OidHandle)o).enc);
+ return Arrays.areEqual(contents, ((OidHandle)o).contents);
}
return false;
}
}
- static ASN1ObjectIdentifier fromOctetString(byte[] enc)
+ static ASN1ObjectIdentifier createPrimitive(byte[] contents, boolean clone)
{
- final OidHandle hdl = new OidHandle(enc);
+ final OidHandle hdl = new OidHandle(contents);
ASN1ObjectIdentifier oid = pool.get(hdl);
if (oid == null)
{
- return new ASN1ObjectIdentifier(enc);
+ return new ASN1ObjectIdentifier(contents, clone);
}
return oid;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java
index f7b9617..95f4f95 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java
@@ -102,7 +102,18 @@
extends ASN1Primitive
implements ASN1OctetStringParser
{
- byte[] string;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1OctetString.class, BERTags.OCTET_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return octetString;
+ }
+
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence.toASN1OctetString();
+ }
+ };
/**
* return an Octet String from a tagged object.
@@ -113,70 +124,9 @@
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
- public static ASN1OctetString getInstance(
- ASN1TaggedObject taggedObject,
- boolean explicit)
+ public static ASN1OctetString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- if (explicit)
- {
- if (!taggedObject.isExplicit())
- {
- throw new IllegalArgumentException("object implicit - explicit expected.");
- }
-
- return getInstance(taggedObject.getObject());
- }
-
- ASN1Primitive o = taggedObject.getObject();
-
- /*
- * constructed object which appears to be explicitly tagged and it's really implicit means
- * we have to add the surrounding octet string.
- */
- if (taggedObject.isExplicit())
- {
- ASN1OctetString singleSegment = getInstance(o);
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BEROctetString(new ASN1OctetString[]{ singleSegment });
- }
-
- // TODO Should really be similar to the BERTaggedObject case above:
-// return new DLOctetString(new ASN1OctetString[]{ singleSegment });
- return (ASN1OctetString)new BEROctetString(new ASN1OctetString[]{ singleSegment }).toDLObject();
- }
-
- if (o instanceof ASN1OctetString)
- {
- ASN1OctetString s = (ASN1OctetString)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return s;
- }
-
- return (ASN1OctetString)s.toDLObject();
- }
-
- /*
- * in this case the parser returns a sequence, convert it into an octet string.
- */
- if (o instanceof ASN1Sequence)
- {
- ASN1Sequence s = (ASN1Sequence)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return BEROctetString.fromSequence(s);
- }
-
- // TODO Should really be similar to the BERTaggedObject case above:
-// return DLOctetString.fromSequence(s);
- return (ASN1OctetString)BEROctetString.fromSequence(s).toDLObject();
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ return (ASN1OctetString)TYPE.getContextInstance(taggedObject, explicit);
}
/**
@@ -185,37 +135,40 @@
* @param obj the object we want converted.
* @exception IllegalArgumentException if the object cannot be converted.
*/
- public static ASN1OctetString getInstance(
- Object obj)
+ public static ASN1OctetString getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1OctetString)
{
return (ASN1OctetString)obj;
}
+// else if (obj instanceof ASN1OctetStringParser)
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1OctetString)
+ {
+ return (ASN1OctetString)primitive;
+ }
+ }
else if (obj instanceof byte[])
{
try
{
- return getInstance(fromByteArray((byte[])obj));
+ return (ASN1OctetString)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct OCTET STRING from byte[]: " + e.getMessage());
}
}
- else if (obj instanceof ASN1Encodable)
- {
- ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
- if (primitive instanceof ASN1OctetString)
- {
- return (ASN1OctetString)primitive;
- }
- }
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
+ static final byte[] EMPTY_OCTETS = new byte[0];
+
+ byte[] string;
+
/**
* Base constructor.
*
@@ -261,6 +214,11 @@
return string;
}
+ public int getOctetsLength()
+ {
+ return getOctets().length;
+ }
+
public int hashCode()
{
return Arrays.hashCode(this.getOctets());
@@ -294,10 +252,13 @@
return new DEROctetString(string);
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
return "#" + Strings.fromByteArray(Hex.encode(string));
}
+
+ static ASN1OctetString createPrimitive(byte[] contents)
+ {
+ return new DEROctetString(contents);
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java
index 7447d3b..1792e04 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java
@@ -34,250 +34,33 @@
private OutputStream os;
- /**
- * @deprecated Use {@link ASN1OutputStream#create(OutputStream)} instead.
- */
- public ASN1OutputStream(OutputStream os)
+ ASN1OutputStream(OutputStream os)
{
this.os = os;
}
- final void writeLength(
- int length)
- throws IOException
+ public void close() throws IOException
{
- if (length > 127)
- {
- int size = 1;
- int val = length;
-
- while ((val >>>= 8) != 0)
- {
- size++;
- }
-
- write((byte)(size | 0x80));
-
- for (int i = (size - 1) * 8; i >= 0; i -= 8)
- {
- write((byte)(length >> i));
- }
- }
- else
- {
- write((byte)length);
- }
+ os.close();
}
- final void write(int b)
- throws IOException
+ public void flush() throws IOException
{
- os.write(b);
+ os.flush();
}
- final void write(byte[] bytes, int off, int len)
- throws IOException
+ public final void writeObject(ASN1Encodable encodable) throws IOException
{
- os.write(bytes, off, len);
- }
-
- final void writeElements(ASN1Encodable[] elements)
- throws IOException
- {
- int count = elements.length;
- for (int i = 0; i < count; ++i)
- {
- ASN1Primitive primitive = elements[i].toASN1Primitive();
-
- writePrimitive(primitive, true);
- }
- }
-
- final void writeElements(Enumeration elements)
- throws IOException
- {
- while (elements.hasMoreElements())
- {
- ASN1Primitive primitive = ((ASN1Encodable)elements.nextElement()).toASN1Primitive();
-
- writePrimitive(primitive, true);
- }
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte contents)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(1);
- write(contents);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte[] contents)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(contents.length);
- write(contents, 0, contents.length);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte[] contents,
- int contentsOff,
- int contentsLen)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(contentsLen);
- write(contents, contentsOff, contentsLen);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte headByte,
- byte[] tailBytes)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(1 + tailBytes.length);
- write(headByte);
- write(tailBytes, 0, tailBytes.length);
- }
-
- final void writeEncoded(
- boolean withTag,
- int tag,
- byte headByte,
- byte[] body,
- int bodyOff,
- int bodyLen,
- byte tailByte)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- writeLength(2 + bodyLen);
- write(headByte);
- write(body, bodyOff, bodyLen);
- write(tailByte);
- }
-
- final void writeEncoded(boolean withTag, int flags, int tagNo, byte[] contents)
- throws IOException
- {
- writeTag(withTag, flags, tagNo);
- writeLength(contents.length);
- write(contents, 0, contents.length);
- }
-
- final void writeEncodedIndef(boolean withTag, int flags, int tagNo, byte[] contents)
- throws IOException
- {
- writeTag(withTag, flags, tagNo);
- write(0x80);
- write(contents, 0, contents.length);
- write(0x00);
- write(0x00);
- }
-
- final void writeEncodedIndef(boolean withTag, int tag, ASN1Encodable[] elements)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- write(0x80);
- writeElements(elements);
- write(0x00);
- write(0x00);
- }
-
- final void writeEncodedIndef(boolean withTag, int tag, Enumeration elements)
- throws IOException
- {
- if (withTag)
- {
- write(tag);
- }
- write(0x80);
- writeElements(elements);
- write(0x00);
- write(0x00);
- }
-
- final void writeTag(boolean withTag, int flags, int tagNo)
- throws IOException
- {
- if (!withTag)
- {
- return;
- }
-
- if (tagNo < 31)
- {
- write(flags | tagNo);
- }
- else
- {
- write(flags | 0x1f);
- if (tagNo < 128)
- {
- write(tagNo);
- }
- else
- {
- byte[] stack = new byte[5];
- int pos = stack.length;
-
- stack[--pos] = (byte)(tagNo & 0x7F);
-
- do
- {
- tagNo >>= 7;
- stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
- }
- while (tagNo > 127);
-
- write(stack, pos, stack.length - pos);
- }
- }
- }
-
- public void writeObject(ASN1Encodable obj) throws IOException
- {
- if (null == obj)
+ if (null == encodable)
{
throw new IOException("null object detected");
}
- writePrimitive(obj.toASN1Primitive(), true);
+ writePrimitive(encodable.toASN1Primitive(), true);
flushInternal();
}
- public void writeObject(ASN1Primitive primitive) throws IOException
+ public final void writeObject(ASN1Primitive primitive) throws IOException
{
if (null == primitive)
{
@@ -288,25 +71,7 @@
flushInternal();
}
- void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
- {
- primitive.encode(this, withTag);
- }
-
- public void close()
- throws IOException
- {
- os.close();
- }
-
- public void flush()
- throws IOException
- {
- os.flush();
- }
-
- void flushInternal()
- throws IOException
+ void flushInternal() throws IOException
{
// Placeholder to support future internal buffering
}
@@ -316,8 +81,192 @@
return new DEROutputStream(os);
}
- ASN1OutputStream getDLSubStream()
+ DLOutputStream getDLSubStream()
{
return new DLOutputStream(os);
}
+
+ final void writeDL(int length) throws IOException
+ {
+ if (length < 128)
+ {
+ write(length);
+ }
+ else
+ {
+ byte[] stack = new byte[5];
+ int pos = stack.length;
+
+ do
+ {
+ stack[--pos] = (byte)length;
+ length >>>= 8;
+ }
+ while (length != 0);
+
+ int count = stack.length - pos;
+ stack[--pos] = (byte)(0x80 | count);
+
+ write(stack, pos, count + 1);
+ }
+ }
+
+ final void write(int b) throws IOException
+ {
+ os.write(b);
+ }
+
+ final void write(byte[] bytes, int off, int len) throws IOException
+ {
+ os.write(bytes, off, len);
+ }
+
+ void writeElements(ASN1Encodable[] elements)
+ throws IOException
+ {
+ for (int i = 0, count = elements.length; i < count; ++i)
+ {
+ elements[i].toASN1Primitive().encode(this, true);
+ }
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte contents) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(1);
+ write(contents);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte[] contents) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(contents.length);
+ write(contents, 0, contents.length);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte[] contents, int contentsOff, int contentsLen)
+ throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(contentsLen);
+ write(contents, contentsOff, contentsLen);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte contentsPrefix, byte[] contents, int contentsOff,
+ int contentsLen) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(1 + contentsLen);
+ write(contentsPrefix);
+ write(contents, contentsOff, contentsLen);
+ }
+
+ final void writeEncodingDL(boolean withID, int identifier, byte[] contents, int contentsOff, int contentsLen,
+ byte contentsSuffix) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ writeDL(contentsLen + 1);
+ write(contents, contentsOff, contentsLen);
+ write(contentsSuffix);
+ }
+
+ final void writeEncodingDL(boolean withID, int flags, int tag, byte[] contents) throws IOException
+ {
+ writeIdentifier(withID, flags, tag);
+ writeDL(contents.length);
+ write(contents, 0, contents.length);
+ }
+
+ final void writeEncodingIL(boolean withID, int identifier, ASN1Encodable[] elements) throws IOException
+ {
+ writeIdentifier(withID, identifier);
+ write(0x80);
+ writeElements(elements);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeIdentifier(boolean withID, int identifier) throws IOException
+ {
+ if (withID)
+ {
+ write(identifier);
+ }
+ }
+
+ final void writeIdentifier(boolean withID, int flags, int tag) throws IOException
+ {
+ if (!withID)
+ {
+ // Don't write the identifier
+ }
+ else if (tag < 31)
+ {
+ write(flags | tag);
+ }
+ else
+ {
+ byte[] stack = new byte[6];
+ int pos = stack.length;
+
+ stack[--pos] = (byte)(tag & 0x7F);
+ while (tag > 127)
+ {
+ tag >>>= 7;
+ stack[--pos] = (byte)(tag & 0x7F | 0x80);
+ }
+
+ stack[--pos] = (byte)(flags | 0x1F);
+
+ write(stack, pos, stack.length - pos);
+ }
+ }
+
+ void writePrimitive(ASN1Primitive primitive, boolean withID) throws IOException
+ {
+ primitive.encode(this, withID);
+ }
+
+ void writePrimitives(ASN1Primitive[] primitives) throws IOException
+ {
+ for (int i = 0, count = primitives.length; i < count; ++i)
+ {
+ primitives[i].encode(this, true);
+ }
+ }
+
+ static int getLengthOfDL(int dl)
+ {
+ if (dl < 128)
+ {
+ return 1;
+ }
+
+ int length = 2;
+ while ((dl >>>= 8) != 0)
+ {
+ ++length;
+ }
+ return length;
+ }
+
+ static int getLengthOfEncodingDL(boolean withID, int contentsLength)
+ {
+ return (withID ? 1 : 0) + getLengthOfDL(contentsLength) + contentsLength;
+ }
+
+ static int getLengthOfIdentifier(int tag)
+ {
+ if (tag < 31)
+ {
+ return 1;
+ }
+
+ int length = 2;
+ while ((tag >>>= 7) != 0)
+ {
+ ++length;
+ }
+ return length;
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java
index f8dafff..e9e7d39 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java
@@ -17,12 +17,16 @@
public void encodeTo(OutputStream output) throws IOException
{
- ASN1OutputStream.create(output).writeObject(this);
+ ASN1OutputStream asn1Out = ASN1OutputStream.create(output);
+ asn1Out.writePrimitive(this, true);
+ asn1Out.flushInternal();
}
public void encodeTo(OutputStream output, String encoding) throws IOException
{
- ASN1OutputStream.create(output, encoding).writeObject(this);
+ ASN1OutputStream asn1Out = ASN1OutputStream.create(output, encoding);
+ asn1Out.writePrimitive(this, true);
+ asn1Out.flushInternal();
}
/**
@@ -105,14 +109,9 @@
* Return true if this objected is a CONSTRUCTED one, false otherwise.
* @return true if CONSTRUCTED bit set on object's tag, false otherwise.
*/
- abstract boolean isConstructed();
+ abstract boolean encodeConstructed();
- /**
- * Return the length of the encoding this object will produce.
- * @return the length of the object's encoding.
- * @throws IOException if the encoding length cannot be calculated.
- */
- abstract int encodedLength() throws IOException;
+ abstract int encodedLength(boolean withTag) throws IOException;
abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1PrintableString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1PrintableString.java
new file mode 100644
index 0000000..05d7e87
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1PrintableString.java
@@ -0,0 +1,231 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 PrintableString object.
+ * <p>
+ * X.680 section 37.4 defines PrintableString character codes as ASCII subset of following characters:
+ * </p>
+ * <ul>
+ * <li>Latin capital letters: 'A' .. 'Z'</li>
+ * <li>Latin small letters: 'a' .. 'z'</li>
+ * <li>Digits: '0'..'9'</li>
+ * <li>Space</li>
+ * <li>Apostrophe: '\''</li>
+ * <li>Left parenthesis: '('</li>
+ * <li>Right parenthesis: ')'</li>
+ * <li>Plus sign: '+'</li>
+ * <li>Comma: ','</li>
+ * <li>Hyphen-minus: '-'</li>
+ * <li>Full stop: '.'</li>
+ * <li>Solidus: '/'</li>
+ * <li>Colon: ':'</li>
+ * <li>Equals sign: '='</li>
+ * <li>Question mark: '?'</li>
+ * </ul>
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1PrintableString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1PrintableString.class, BERTags.PRINTABLE_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a printable string from the passed in object.
+ *
+ * @param obj an ASN1PrintableString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1PrintableString instance, or null.
+ */
+ public static ASN1PrintableString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1PrintableString)
+ {
+ return (ASN1PrintableString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1PrintableString)
+ {
+ return (ASN1PrintableString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1PrintableString)TYPE.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());
+ }
+
+ /**
+ * Return a Printable String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1PrintableString instance, or null.
+ */
+ public static ASN1PrintableString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1PrintableString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ /**
+ * Constructor with optional validation.
+ *
+ * @param string the base string to wrap.
+ * @param validate whether or not to check the string.
+ * @throws IllegalArgumentException if validate is true and the string
+ * contains characters that should not be in a PrintableString.
+ */
+ ASN1PrintableString(String string, boolean validate)
+ {
+ if (validate && !isPrintableString(string))
+ {
+ throw new IllegalArgumentException("string contains illegal characters");
+ }
+
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1PrintableString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.PRINTABLE_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1PrintableString))
+ {
+ return false;
+ }
+
+ ASN1PrintableString that = (ASN1PrintableString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ /**
+ * return true if the passed in String can be represented without
+ * loss as a PrintableString, false otherwise.
+ *
+ * @return true if in printable set, false otherwise.
+ */
+ public static boolean isPrintableString(
+ String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+
+ if ('a' <= ch && ch <= 'z')
+ {
+ continue;
+ }
+
+ if ('A' <= ch && ch <= 'Z')
+ {
+ continue;
+ }
+
+ if ('0' <= ch && ch <= '9')
+ {
+ continue;
+ }
+
+ switch (ch)
+ {
+ case ' ':
+ case '\'':
+ case '(':
+ case ')':
+ case '+':
+ case '-':
+ case '.':
+ case ':':
+ case '=':
+ case '?':
+ case '/':
+ case ',':
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ static ASN1PrintableString createPrimitive(byte[] contents)
+ {
+ return new DERPrintableString(contents, false);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1RelativeOID.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1RelativeOID.java
new file mode 100644
index 0000000..e6b61b1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1RelativeOID.java
@@ -0,0 +1,317 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1RelativeOID
+ extends ASN1Primitive
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1RelativeOID.class, BERTags.RELATIVE_OID)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets(), false);
+ }
+ };
+
+ public static ASN1RelativeOID fromContents(byte[] contents)
+ {
+ return createPrimitive(contents, true);
+ }
+
+ public static ASN1RelativeOID getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1RelativeOID)
+ {
+ return (ASN1RelativeOID)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1RelativeOID)
+ {
+ return (ASN1RelativeOID)primitive;
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ byte[] enc = (byte[])obj;
+ try
+ {
+ return (ASN1RelativeOID)TYPE.fromByteArray(enc);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct relative OID from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ public static ASN1RelativeOID getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1RelativeOID)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7F;
+
+ private final String identifier;
+ private byte[] contents;
+
+ public ASN1RelativeOID(String identifier)
+ {
+ if (identifier == null)
+ {
+ throw new NullPointerException("'identifier' cannot be null");
+ }
+ if (!isValidIdentifier(identifier, 0))
+ {
+ throw new IllegalArgumentException("string " + identifier + " not a relative OID");
+ }
+
+ this.identifier = identifier;
+ }
+
+ ASN1RelativeOID(ASN1RelativeOID oid, String branchID)
+ {
+ if (!isValidIdentifier(branchID, 0))
+ {
+ throw new IllegalArgumentException("string " + branchID + " not a valid OID branch");
+ }
+
+ this.identifier = oid.getId() + "." + branchID;
+ }
+
+ private ASN1RelativeOID(byte[] contents, boolean clone)
+ {
+ StringBuffer objId = new StringBuffer();
+ long value = 0;
+ BigInteger bigValue = null;
+ boolean first = true;
+
+ for (int i = 0; i != contents.length; i++)
+ {
+ int b = contents[i] & 0xff;
+
+ if (value <= LONG_LIMIT)
+ {
+ value += b & 0x7F;
+ if ((b & 0x80) == 0)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ objId.append('.');
+ }
+
+ objId.append(value);
+ value = 0;
+ }
+ else
+ {
+ value <<= 7;
+ }
+ }
+ else
+ {
+ if (bigValue == null)
+ {
+ bigValue = BigInteger.valueOf(value);
+ }
+ bigValue = bigValue.or(BigInteger.valueOf(b & 0x7F));
+ if ((b & 0x80) == 0)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ objId.append('.');
+ }
+
+ objId.append(bigValue);
+ bigValue = null;
+ value = 0;
+ }
+ else
+ {
+ bigValue = bigValue.shiftLeft(7);
+ }
+ }
+ }
+
+ this.identifier = objId.toString();
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public ASN1RelativeOID branch(String branchID)
+ {
+ return new ASN1RelativeOID(this, branchID);
+ }
+
+ public String getId()
+ {
+ return identifier;
+ }
+
+ public int hashCode()
+ {
+ return identifier.hashCode();
+ }
+
+ public String toString()
+ {
+ return getId();
+ }
+
+ boolean asn1Equals(ASN1Primitive other)
+ {
+ if (this == other)
+ {
+ return true;
+ }
+ if (!(other instanceof ASN1RelativeOID))
+ {
+ return false;
+ }
+
+ ASN1RelativeOID that = (ASN1RelativeOID)other;
+
+ return this.identifier.equals(that.identifier);
+ }
+
+ int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContents().length);
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.RELATIVE_OID, getContents());
+ }
+
+ boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ private void doOutput(ByteArrayOutputStream aOut)
+ {
+ OIDTokenizer tok = new OIDTokenizer(identifier);
+ while (tok.hasMoreTokens())
+ {
+ String token = tok.nextToken();
+ if (token.length() <= 18)
+ {
+ writeField(aOut, Long.parseLong(token));
+ }
+ else
+ {
+ writeField(aOut, new BigInteger(token));
+ }
+ }
+ }
+
+ private synchronized byte[] getContents()
+ {
+ if (contents == null)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ doOutput(bOut);
+
+ contents = bOut.toByteArray();
+ }
+
+ return contents;
+ }
+
+ static ASN1RelativeOID createPrimitive(byte[] contents, boolean clone)
+ {
+ return new ASN1RelativeOID(contents, clone);
+ }
+
+ static boolean isValidIdentifier(String identifier, int from)
+ {
+ int digitCount = 0;
+
+ int pos = identifier.length();
+ while (--pos >= from)
+ {
+ char ch = identifier.charAt(pos);
+
+ if (ch == '.')
+ {
+ if (0 == digitCount
+ || (digitCount > 1 && identifier.charAt(pos + 1) == '0'))
+ {
+ return false;
+ }
+
+ digitCount = 0;
+ }
+ else if ('0' <= ch && ch <= '9')
+ {
+ ++digitCount;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (0 == digitCount
+ || (digitCount > 1 && identifier.charAt(pos + 1) == '0'))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ static void writeField(ByteArrayOutputStream out, long fieldValue)
+ {
+ byte[] result = new byte[9];
+ int pos = 8;
+ result[pos] = (byte)((int)fieldValue & 0x7F);
+ while (fieldValue >= (1L << 7))
+ {
+ fieldValue >>= 7;
+ result[--pos] = (byte)((int)fieldValue | 0x80);
+ }
+ out.write(result, pos, 9 - pos);
+ }
+
+ static void writeField(ByteArrayOutputStream out, BigInteger fieldValue)
+ {
+ int byteCount = (fieldValue.bitLength() + 6) / 7;
+ if (byteCount == 0)
+ {
+ out.write(0);
+ }
+ else
+ {
+ BigInteger tmpValue = fieldValue;
+ byte[] tmp = new byte[byteCount];
+ for (int i = byteCount - 1; i >= 0; i--)
+ {
+ tmp[i] = (byte)(tmpValue.intValue() | 0x80);
+ tmpValue = tmpValue.shiftRight(7);
+ }
+ tmp[byteCount - 1] &= 0x7F;
+ out.write(tmp, 0, tmp.length);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java
index afbb74f..fbd27d5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java
@@ -62,8 +62,13 @@
extends ASN1Primitive
implements com.android.internal.org.bouncycastle.util.Iterable<ASN1Encodable>
{
- // NOTE: Only non-final to support LazyEncodedSequence
- ASN1Encodable[] elements;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Sequence.class, BERTags.SEQUENCE)
+ {
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence;
+ }
+ };
/**
* Return an ASN1Sequence from the given object.
@@ -72,37 +77,32 @@
* @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Sequence instance, or null.
*/
- public static ASN1Sequence getInstance(
- Object obj)
+ public static ASN1Sequence getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1Sequence)
{
return (ASN1Sequence)obj;
}
- else if (obj instanceof ASN1SequenceParser)
+// else if (obj instanceof ASN1SequenceParser)
+ else if (obj instanceof ASN1Encodable)
{
- return ASN1Sequence.getInstance(((ASN1SequenceParser)obj).toASN1Primitive());
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1Sequence)
+ {
+ return (ASN1Sequence)primitive;
+ }
}
else if (obj instanceof byte[])
{
try
{
- return ASN1Sequence.getInstance(fromByteArray((byte[])obj));
+ return (ASN1Sequence)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage());
}
}
- else if (obj instanceof ASN1Encodable)
- {
- ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
- if (primitive instanceof ASN1Sequence)
- {
- return (ASN1Sequence)primitive;
- }
- }
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
}
@@ -124,51 +124,14 @@
* be converted.
* @return an ASN1Sequence instance.
*/
- public static ASN1Sequence getInstance(
- ASN1TaggedObject taggedObject,
- boolean explicit)
+ public static ASN1Sequence getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- if (explicit)
- {
- if (!taggedObject.isExplicit())
- {
- throw new IllegalArgumentException("object implicit - explicit expected.");
- }
-
- return getInstance(taggedObject.getObject());
- }
-
- ASN1Primitive o = taggedObject.getObject();
-
- /*
- * constructed object which appears to be explicitly tagged when it should be implicit means
- * we have to add the surrounding sequence.
- */
- if (taggedObject.isExplicit())
- {
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BERSequence(o);
- }
-
- return new DLSequence(o);
- }
-
- if (o instanceof ASN1Sequence)
- {
- ASN1Sequence s = (ASN1Sequence)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return s;
- }
-
- return (ASN1Sequence)s.toDLObject();
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ return (ASN1Sequence)TYPE.getContextInstance(taggedObject, explicit);
}
+ // NOTE: Only non-final to support LazyEncodedSequence
+ ASN1Encodable[] elements;
+
/**
* Create an empty SEQUENCE
*/
@@ -342,6 +305,7 @@
ASN1Sequence that = (ASN1Sequence)other;
+ // NOTE: Call size() here (on both) to 'force' a LazyEncodedSequence
int count = this.size();
if (that.size() != count)
{
@@ -380,13 +344,19 @@
return new DLSequence(elements, false);
}
- boolean isConstructed()
+ abstract ASN1BitString toASN1BitString();
+
+ abstract ASN1External toASN1External();
+
+ abstract ASN1OctetString toASN1OctetString();
+
+ abstract ASN1Set toASN1Set();
+
+ boolean encodeConstructed()
{
return true;
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
// NOTE: Call size() here to 'force' a LazyEncodedSequence
@@ -415,4 +385,28 @@
{
return new Arrays.Iterator<ASN1Encodable>(elements);
}
+
+ ASN1BitString[] getConstructedBitStrings()
+ {
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ int count = size();
+ ASN1BitString[] bitStrings = new ASN1BitString[count];
+ for (int i = 0; i < count; ++i)
+ {
+ bitStrings[i] = ASN1BitString.getInstance(elements[i]);
+ }
+ return bitStrings;
+ }
+
+ ASN1OctetString[] getConstructedOctetStrings()
+ {
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ int count = size();
+ ASN1OctetString[] octetStrings = new ASN1OctetString[count];
+ for (int i = 0; i < count; ++i)
+ {
+ octetStrings[i] = ASN1OctetString.getInstance(elements[i]);
+ }
+ return octetStrings;
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java
index 110d200..e46a47e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java
@@ -100,8 +100,13 @@
extends ASN1Primitive
implements com.android.internal.org.bouncycastle.util.Iterable<ASN1Encodable>
{
- protected final ASN1Encodable[] elements;
- protected final boolean isSorted;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1Set.class, BERTags.SET)
+ {
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ return sequence.toASN1Set();
+ }
+ };
/**
* return an ASN1Set from the given object.
@@ -110,37 +115,32 @@
* @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Set instance, or null.
*/
- public static ASN1Set getInstance(
- Object obj)
+ public static ASN1Set getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1Set)
{
return (ASN1Set)obj;
}
- else if (obj instanceof ASN1SetParser)
+// else if (obj instanceof ASN1SetParser)
+ else if (obj instanceof ASN1Encodable)
{
- return ASN1Set.getInstance(((ASN1SetParser)obj).toASN1Primitive());
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1Set)
+ {
+ return (ASN1Set)primitive;
+ }
}
else if (obj instanceof byte[])
{
try
{
- return ASN1Set.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ return (ASN1Set)TYPE.fromByteArray((byte[])obj);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct set from byte[]: " + e.getMessage());
}
}
- else if (obj instanceof ASN1Encodable)
- {
- ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
-
- if (primitive instanceof ASN1Set)
- {
- return (ASN1Set)primitive;
- }
- }
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
}
@@ -162,73 +162,19 @@
* be converted.
* @return an ASN1Set instance.
*/
- public static ASN1Set getInstance(
- ASN1TaggedObject taggedObject,
- boolean explicit)
+ public static ASN1Set getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- if (explicit)
- {
- if (!taggedObject.isExplicit())
- {
- throw new IllegalArgumentException("object implicit - explicit expected.");
- }
-
- return getInstance(taggedObject.getObject());
- }
-
- ASN1Primitive o = taggedObject.getObject();
-
- /*
- * constructed object which appears to be explicitly tagged and it's really implicit means
- * we have to add the surrounding set.
- */
- if (taggedObject.isExplicit())
- {
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BERSet(o);
- }
-
- return new DLSet(o);
- }
-
- if (o instanceof ASN1Set)
- {
- ASN1Set s = (ASN1Set)o;
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return s;
- }
-
- return (ASN1Set)s.toDLObject();
- }
-
- /*
- * in this case the parser returns a sequence, convert it into a set.
- */
- if (o instanceof ASN1Sequence)
- {
- ASN1Sequence s = (ASN1Sequence)o;
-
- // NOTE: Will force() a LazyEncodedSequence
- ASN1Encodable[] elements = s.toArrayInternal();
-
- if (taggedObject instanceof BERTaggedObject)
- {
- return new BERSet(false, elements);
- }
-
- return new DLSet(false, elements);
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ return (ASN1Set)TYPE.getContextInstance(taggedObject, explicit);
}
+ protected final ASN1Encodable[] elements;
+
+ protected ASN1Encodable[] sortedElements;
+
protected ASN1Set()
{
this.elements = ASN1EncodableVector.EMPTY_ELEMENTS;
- this.isSorted = true;
+ this.sortedElements = elements;
}
/**
@@ -243,7 +189,7 @@
}
this.elements = new ASN1Encodable[]{ element };
- this.isSorted = true;
+ this.sortedElements = elements;
}
/**
@@ -270,7 +216,7 @@
}
this.elements = tmp;
- this.isSorted = doSort || tmp.length < 2;
+ this.sortedElements = (doSort || tmp.length < 2) ? elements : null;
}
/**
@@ -292,13 +238,19 @@
}
this.elements = tmp;
- this.isSorted = doSort || tmp.length < 2;
+ this.sortedElements = (doSort || tmp.length < 2) ? elements : null;
}
ASN1Set(boolean isSorted, ASN1Encodable[] elements)
{
this.elements = elements;
- this.isSorted = isSorted || elements.length < 2;
+ this.sortedElements = (isSorted || elements.length < 2) ? elements : null;
+ }
+
+ ASN1Set(ASN1Encodable[] elements, ASN1Encodable[] sortedElements)
+ {
+ this.elements = elements;
+ this.sortedElements = sortedElements;
}
public Enumeration getObjects()
@@ -410,18 +362,13 @@
*/
ASN1Primitive toDERObject()
{
- ASN1Encodable[] tmp;
- if (isSorted)
+ if (sortedElements == null)
{
- tmp = elements;
- }
- else
- {
- tmp = (ASN1Encodable[])elements.clone();
- sort(tmp);
+ sortedElements = (ASN1Encodable[])elements.clone();
+ sort(sortedElements);
}
- return new DERSet(true, tmp);
+ return new DERSet(true, sortedElements);
}
/**
@@ -430,7 +377,7 @@
*/
ASN1Primitive toDLObject()
{
- return new DLSet(isSorted, elements);
+ return new DLSet(elements, sortedElements);
}
boolean asn1Equals(ASN1Primitive other)
@@ -465,13 +412,11 @@
return true;
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return true;
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
int count = size();
@@ -531,8 +476,8 @@
* primitive form accordingly. Failing to ignore the CONSTRUCTED bit could therefore lead to
* ordering inversions.
*/
- int a0 = a[0] & ~BERTags.CONSTRUCTED;
- int b0 = b[0] & ~BERTags.CONSTRUCTED;
+ int a0 = a[0] & (~BERTags.CONSTRUCTED & 0xff);
+ int b0 = b[0] & (~BERTags.CONSTRUCTED & 0xff);
if (a0 != b0)
{
return a0 < b0;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java
index 888a2f6..594c821 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java
@@ -12,214 +12,257 @@
public class ASN1StreamParser
{
private final InputStream _in;
- private final int _limit;
+ private final int _limit;
private final byte[][] tmpBuffers;
- public ASN1StreamParser(
- InputStream in)
+ public ASN1StreamParser(InputStream in)
{
this(in, StreamUtil.findLimit(in));
}
- public ASN1StreamParser(
- InputStream in,
- int limit)
- {
- this._in = in;
- this._limit = limit;
-
- this.tmpBuffers = new byte[11][];
- }
-
- public ASN1StreamParser(
- byte[] encoding)
+ public ASN1StreamParser(byte[] encoding)
{
this(new ByteArrayInputStream(encoding), encoding.length);
}
- ASN1Encodable readIndef(int tagValue) throws IOException
+ public ASN1StreamParser(InputStream in, int limit)
{
- // Note: INDEF => CONSTRUCTED
-
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagValue)
- {
- case BERTags.EXTERNAL:
- return new DERExternalParser(this);
- case BERTags.OCTET_STRING:
- return new BEROctetStringParser(this);
- case BERTags.SEQUENCE:
- return new BERSequenceParser(this);
- case BERTags.SET:
- return new BERSetParser(this);
- default:
- throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(tagValue));
- }
+ this(in, limit, new byte[11][]);
}
- ASN1Encodable readImplicit(boolean constructed, int tag) throws IOException
+ ASN1StreamParser(InputStream in, int limit, byte[][] tmpBuffers)
{
- if (_in instanceof IndefiniteLengthInputStream)
- {
- if (!constructed)
- {
- throw new IOException("indefinite-length primitive encoding encountered");
- }
-
- return readIndef(tag);
- }
-
- if (constructed)
- {
- switch (tag)
- {
- case BERTags.SET:
- return new DLSetParser(this);
- case BERTags.SEQUENCE:
- return new DLSequenceParser(this);
- case BERTags.OCTET_STRING:
- return new BEROctetStringParser(this);
- }
- }
- else
- {
- switch (tag)
- {
- case BERTags.SET:
- throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
- case BERTags.SEQUENCE:
- throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
- case BERTags.OCTET_STRING:
- return new DEROctetStringParser((DefiniteLengthInputStream)_in);
- }
- }
-
- throw new ASN1Exception("implicit tagging not implemented");
+ this._in = in;
+ this._limit = limit;
+ this.tmpBuffers = tmpBuffers;
}
- ASN1Primitive readTaggedObject(boolean constructed, int tag) throws IOException
+ public ASN1Encodable readObject() throws IOException
{
- if (!constructed)
- {
- // Note: !CONSTRUCTED => IMPLICIT
- DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
- return new DLTaggedObject(false, tag, new DEROctetString(defIn.toByteArray()));
- }
-
- ASN1EncodableVector v = readVector();
-
- if (_in instanceof IndefiniteLengthInputStream)
- {
- return v.size() == 1
- ? new BERTaggedObject(true, tag, v.get(0))
- : new BERTaggedObject(false, tag, BERFactory.createSequence(v));
- }
-
- return v.size() == 1
- ? new DLTaggedObject(true, tag, v.get(0))
- : new DLTaggedObject(false, tag, DLFactory.createSequence(v));
- }
-
- public ASN1Encodable readObject()
- throws IOException
- {
- int tag = _in.read();
- if (tag == -1)
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
{
return null;
}
+ return implParseObject(tagHdr);
+ }
+
+ ASN1Encodable implParseObject(int tagHdr) throws IOException
+ {
//
- // turn of looking for "00" while we resolve the tag
+ // turn off looking for "00" while we resolve the tag
//
set00Check(false);
//
// calculate tag number
//
- int tagNo = ASN1InputStream.readTagNumber(_in, tag);
-
- boolean isConstructed = (tag & BERTags.CONSTRUCTED) != 0;
+ int tagNo = ASN1InputStream.readTagNumber(_in, tagHdr);
//
// calculate length
//
int length = ASN1InputStream.readLength(_in, _limit,
- tagNo == BERTags.OCTET_STRING || tagNo == BERTags.SEQUENCE || tagNo == BERTags.SET || tagNo == BERTags.EXTERNAL);
+ tagNo == BERTags.BIT_STRING || tagNo == BERTags.OCTET_STRING || tagNo == BERTags.SEQUENCE
+ || tagNo == BERTags.SET || tagNo == BERTags.EXTERNAL);
if (length < 0) // indefinite-length method
{
- if (!isConstructed)
+ if (0 == (tagHdr & BERTags.CONSTRUCTED))
{
throw new IOException("indefinite-length primitive encoding encountered");
}
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit);
- ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit);
+ ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit, tmpBuffers);
- if ((tag & BERTags.APPLICATION) != 0)
+ int tagClass = tagHdr & BERTags.PRIVATE;
+ if (0 != tagClass)
{
- return new BERApplicationSpecificParser(tagNo, sp);
+ return new BERTaggedObjectParser(tagClass, tagNo, sp);
}
- if ((tag & BERTags.TAGGED) != 0)
- {
- return new BERTaggedObjectParser(true, tagNo, sp);
- }
-
- return sp.readIndef(tagNo);
+ return sp.parseImplicitConstructedIL(tagNo);
}
else
{
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length, _limit);
- if ((tag & BERTags.APPLICATION) != 0)
+ if (0 == (tagHdr & BERTags.FLAGS))
{
- return new DLApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
+ return parseImplicitPrimitive(tagNo, defIn);
}
- if ((tag & BERTags.TAGGED) != 0)
+ ASN1StreamParser sp = new ASN1StreamParser(defIn, defIn.getLimit(), tmpBuffers);
+
+ int tagClass = tagHdr & BERTags.PRIVATE;
+ if (0 != tagClass)
{
- return new BERTaggedObjectParser(isConstructed, tagNo, new ASN1StreamParser(defIn));
+ boolean isConstructed = (tagHdr & BERTags.CONSTRUCTED) != 0;
+
+ return new DLTaggedObjectParser(tagClass, tagNo, isConstructed, sp);
}
- if (isConstructed)
- {
- // TODO There are other tags that may be constructed (e.g. BIT_STRING)
- switch (tagNo)
- {
- case BERTags.OCTET_STRING:
- //
- // yes, people actually do this...
- //
- return new BEROctetStringParser(new ASN1StreamParser(defIn));
- case BERTags.SEQUENCE:
- return new DLSequenceParser(new ASN1StreamParser(defIn));
- case BERTags.SET:
- return new DLSetParser(new ASN1StreamParser(defIn));
- case BERTags.EXTERNAL:
- return new DERExternalParser(new ASN1StreamParser(defIn));
- default:
- throw new IOException("unknown tag " + tagNo + " encountered");
- }
- }
+ return sp.parseImplicitConstructedDL(tagNo);
+ }
+ }
- // Some primitive encodings can be handled by parsers too...
- switch (tagNo)
- {
- case BERTags.OCTET_STRING:
- return new DEROctetStringParser(defIn);
- }
+ ASN1Primitive loadTaggedDL(int tagClass, int tagNo, boolean constructed) throws IOException
+ {
+ if (!constructed)
+ {
+ byte[] contentsOctets = ((DefiniteLengthInputStream) _in).toByteArray();
+ return ASN1TaggedObject.createPrimitive(tagClass, tagNo, contentsOctets);
+ }
- try
+ ASN1EncodableVector contentsElements = readVector();
+ return ASN1TaggedObject.createConstructedDL(tagClass, tagNo, contentsElements);
+ }
+
+ ASN1Primitive loadTaggedIL(int tagClass, int tagNo) throws IOException
+ {
+ ASN1EncodableVector contentsElements = readVector();
+ return ASN1TaggedObject.createConstructedIL(tagClass, tagNo, contentsElements);
+ }
+
+ ASN1Encodable parseImplicitConstructedDL(int univTagNo) throws IOException
+ {
+ switch (univTagNo)
+ {
+ case BERTags.BIT_STRING:
+ // TODO[asn1] DLConstructedBitStringParser
+ return new BERBitStringParser(this);
+ case BERTags.EXTERNAL:
+ return new DERExternalParser(this);
+ case BERTags.OCTET_STRING:
+ // TODO[asn1] DLConstructedOctetStringParser
+ return new BEROctetStringParser(this);
+ case BERTags.SET:
+ return new DLSetParser(this);
+ case BERTags.SEQUENCE:
+ return new DLSequenceParser(this);
+ default:
+ // -DM toHexString
+ throw new ASN1Exception("unknown DL object encountered: 0x" + Integer.toHexString(univTagNo));
+ }
+ }
+
+ ASN1Encodable parseImplicitConstructedIL(int univTagNo) throws IOException
+ {
+ switch (univTagNo)
+ {
+ case BERTags.BIT_STRING:
+ return new BERBitStringParser(this);
+ case BERTags.OCTET_STRING:
+ return new BEROctetStringParser(this);
+ case BERTags.EXTERNAL:
+ // TODO[asn1] BERExternalParser
+ return new DERExternalParser(this);
+ case BERTags.SEQUENCE:
+ return new BERSequenceParser(this);
+ case BERTags.SET:
+ return new BERSetParser(this);
+ default:
+ throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(univTagNo));
+ }
+ }
+
+ ASN1Encodable parseImplicitPrimitive(int univTagNo) throws IOException
+ {
+ return parseImplicitPrimitive(univTagNo, (DefiniteLengthInputStream)_in);
+ }
+
+ ASN1Encodable parseImplicitPrimitive(int univTagNo, DefiniteLengthInputStream defIn) throws IOException
+ {
+ // Some primitive encodings can be handled by parsers too...
+ switch (univTagNo)
+ {
+ case BERTags.BIT_STRING:
+ return new DLBitStringParser(defIn);
+ case BERTags.EXTERNAL:
+ throw new ASN1Exception("externals must use constructed encoding (see X.690 8.18)");
+ case BERTags.OCTET_STRING:
+ return new DEROctetStringParser(defIn);
+ case BERTags.SET:
+ throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
+ case BERTags.SEQUENCE:
+ throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
+ }
+
+ try
+ {
+ return ASN1InputStream.createPrimitiveDERObject(univTagNo, defIn, tmpBuffers);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception("corrupted stream detected", e);
+ }
+ }
+
+ ASN1Encodable parseObject(int univTagNo) throws IOException
+ {
+ if (univTagNo < 0 || univTagNo > 30)
+ {
+ throw new IllegalArgumentException("invalid universal tag number: " + univTagNo);
+ }
+
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
+ {
+ return null;
+ }
+
+ if ((tagHdr & ~BERTags.CONSTRUCTED) != univTagNo)
+ {
+ throw new IOException("unexpected identifier encountered: " + tagHdr);
+ }
+
+ return implParseObject(tagHdr);
+ }
+
+ ASN1TaggedObjectParser parseTaggedObject() throws IOException
+ {
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
+ {
+ return null;
+ }
+
+ int tagClass = tagHdr & BERTags.PRIVATE;
+ if (0 == tagClass)
+ {
+ throw new ASN1Exception("no tagged object found");
+ }
+
+ return (ASN1TaggedObjectParser)implParseObject(tagHdr);
+ }
+
+ // TODO[asn1] Prefer 'loadVector'
+ ASN1EncodableVector readVector() throws IOException
+ {
+ int tagHdr = _in.read();
+ if (tagHdr < 0)
+ {
+ return new ASN1EncodableVector(0);
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ do
+ {
+ ASN1Encodable obj = implParseObject(tagHdr);
+
+ if (obj instanceof InMemoryRepresentable)
{
- return ASN1InputStream.createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
+ v.add(((InMemoryRepresentable) obj).getLoadedObject());
}
- catch (IllegalArgumentException e)
+ else
{
- throw new ASN1Exception("corrupted stream detected", e);
+ v.add(obj.toASN1Primitive());
}
}
+ while ((tagHdr = _in.read()) >= 0);
+ return v;
}
private void set00Check(boolean enabled)
@@ -229,28 +272,4 @@
((IndefiniteLengthInputStream)_in).setEofOn00(enabled);
}
}
-
- ASN1EncodableVector readVector() throws IOException
- {
- ASN1Encodable obj = readObject();
- if (null == obj)
- {
- return new ASN1EncodableVector(0);
- }
-
- ASN1EncodableVector v = new ASN1EncodableVector();
- do
- {
- if (obj instanceof InMemoryRepresentable)
- {
- v.add(((InMemoryRepresentable)obj).getLoadedObject());
- }
- else
- {
- v.add(obj.toASN1Primitive());
- }
- }
- while ((obj = readObject()) != null);
- return v;
- }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1T61String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1T61String.java
new file mode 100644
index 0000000..fb219bf
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1T61String.java
@@ -0,0 +1,147 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 T61String (also the teletex string), try not to use this if you don't need to. The standard support the encoding for
+ * this has been withdrawn.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1T61String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1T61String.class, BERTags.T61_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a T61 string from the passed in object.
+ *
+ * @param obj an ASN1T61String or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1T61String instance, or null
+ */
+ public static ASN1T61String getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1T61String)
+ {
+ return (ASN1T61String)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1T61String)
+ {
+ return (ASN1T61String)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1T61String)TYPE.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());
+ }
+
+ /**
+ * Return an T61 String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1T61String instance, or null
+ */
+ public static ASN1T61String getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1T61String)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1T61String(String string)
+ {
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1T61String(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ /**
+ * Decode the encoded string and return it, 8 bit encoding assumed.
+ * @return the decoded String
+ */
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.T61_STRING, contents);
+ }
+
+ /**
+ * Return the encoded string as a byte array.
+ * @return the actual bytes making up the encoded body of the T61 string.
+ */
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1T61String))
+ {
+ return false;
+ }
+
+ ASN1T61String that = (ASN1T61String)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1T61String createPrimitive(byte[] contents)
+ {
+ return new DERT61String(contents, false);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Tag.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Tag.java
new file mode 100644
index 0000000..fb3c2a4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Tag.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+final class ASN1Tag
+{
+ static ASN1Tag create(int tagClass, int tagNumber)
+ {
+ return new ASN1Tag(tagClass, tagNumber);
+ }
+
+ private final int tagClass;
+ private final int tagNumber;
+
+ private ASN1Tag(int tagClass, int tagNumber)
+ {
+ this.tagClass = tagClass;
+ this.tagNumber = tagNumber;
+ }
+
+ int getTagClass()
+ {
+ return tagClass;
+ }
+
+ int getTagNumber()
+ {
+ return tagNumber;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java
index c0f9627..b5ff2a8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java
@@ -3,6 +3,8 @@
import java.io.IOException;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
/**
* ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by
* a [n] where n is some number - these are assumed to follow the construction
@@ -13,34 +15,32 @@
extends ASN1Primitive
implements ASN1TaggedObjectParser
{
- final int tagNo;
- final boolean explicit;
- final ASN1Encodable obj;
+ private static final int DECLARED_EXPLICIT = 1;
+ private static final int DECLARED_IMPLICIT = 2;
+ // TODO It will probably be better to track parsing constructed vs primitive instead
+ private static final int PARSED_EXPLICIT = 3;
+ private static final int PARSED_IMPLICIT = 4;
- static public ASN1TaggedObject getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- if (explicit)
- {
- return getInstance(obj.getObject());
- }
-
- throw new IllegalArgumentException("implicitly tagged tagged object");
- }
-
- static public ASN1TaggedObject getInstance(
- Object obj)
+ public static ASN1TaggedObject getInstance(Object obj)
{
if (obj == null || obj instanceof ASN1TaggedObject)
{
return (ASN1TaggedObject)obj;
}
+// else if (obj instanceof ASN1TaggedObjectParser)
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1TaggedObject)
+ {
+ return (ASN1TaggedObject)primitive;
+ }
+ }
else if (obj instanceof byte[])
{
try
{
- return ASN1TaggedObject.getInstance(fromByteArray((byte[])obj));
+ return checkedCast(fromByteArray((byte[])obj));
}
catch (IOException e)
{
@@ -51,6 +51,58 @@
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
}
+ public static ASN1TaggedObject getInstance(Object obj, int tagClass)
+ {
+ if (obj == null)
+ {
+ throw new NullPointerException("'obj' cannot be null");
+ }
+
+ ASN1TaggedObject taggedObject = getInstance(obj);
+ if (tagClass != taggedObject.getTagClass())
+ {
+ throw new IllegalArgumentException("unexpected tag in getInstance: " + ASN1Util.getTagText(taggedObject));
+ }
+
+ return taggedObject;
+ }
+
+ public static ASN1TaggedObject getInstance(Object obj, int tagClass, int tagNo)
+ {
+ if (obj == null)
+ {
+ throw new NullPointerException("'obj' cannot be null");
+ }
+
+ ASN1TaggedObject taggedObject = getInstance(obj);
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ throw new IllegalArgumentException("unexpected tag in getInstance: " + ASN1Util.getTagText(taggedObject));
+ }
+
+ return taggedObject;
+ }
+
+ public static ASN1TaggedObject getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
+ {
+ if (BERTags.CONTEXT_SPECIFIC != taggedObject.getTagClass())
+ {
+ throw new IllegalStateException("this method only valid for CONTEXT_SPECIFIC tags");
+ }
+
+ if (declaredExplicit)
+ {
+ return taggedObject.getExplicitBaseTagged();
+ }
+
+ throw new IllegalArgumentException("this method not valid for implicitly tagged tagged objects");
+ }
+
+ final int explicitness;
+ final int tagClass;
+ final int tagNo;
+ final ASN1Encodable obj;
+
/**
* Create a tagged object with the style given by the value of explicit.
* <p>
@@ -61,22 +113,34 @@
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public ASN1TaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
+ protected ASN1TaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
+ {
+ this(explicit, BERTags.CONTEXT_SPECIFIC, tagNo, obj);
+ }
+
+ protected ASN1TaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ this(explicit ? DECLARED_EXPLICIT : DECLARED_IMPLICIT, tagClass, tagNo, obj);
+ }
+
+ ASN1TaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
{
if (null == obj)
{
throw new NullPointerException("'obj' cannot be null");
}
+ if (tagClass == BERTags.UNIVERSAL || (tagClass & BERTags.PRIVATE) != tagClass)
+ {
+ throw new IllegalArgumentException("invalid tag class: " + tagClass);
+ }
+ this.explicitness = (obj instanceof ASN1Choice) ? DECLARED_EXPLICIT : explicitness;
+ this.tagClass = tagClass;
this.tagNo = tagNo;
- this.explicit = explicit || (obj instanceof ASN1Choice);
this.obj = obj;
}
- boolean asn1Equals(ASN1Primitive other)
+ final boolean asn1Equals(ASN1Primitive other)
{
if (!(other instanceof ASN1TaggedObject))
{
@@ -85,20 +149,58 @@
ASN1TaggedObject that = (ASN1TaggedObject)other;
- if (this.tagNo != that.tagNo || this.explicit != that.explicit)
+ if (this.tagNo != that.tagNo ||
+ this.tagClass != that.tagClass)
{
return false;
}
+ if (this.explicitness != that.explicitness)
+ {
+ /*
+ * TODO This seems incorrect for some cases of implicit tags e.g. if one is a
+ * declared-implicit SET and the other a parsed object.
+ */
+ if (this.isExplicit() != that.isExplicit())
+ {
+ return false;
+ }
+ }
+
ASN1Primitive p1 = this.obj.toASN1Primitive();
ASN1Primitive p2 = that.obj.toASN1Primitive();
- return p1 == p2 || p1.asn1Equals(p2);
+ if (p1 == p2)
+ {
+ return true;
+ }
+
+ if (!this.isExplicit())
+ {
+ try
+ {
+ byte[] d1 = this.getEncoded();
+ byte[] d2 = that.getEncoded();
+
+ return Arrays.areEqual(d1, d2);
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
+ }
+
+ return p1.asn1Equals(p2);
}
public int hashCode()
{
- return tagNo ^ (explicit ? 0x0F : 0xF0) ^ obj.toASN1Primitive().hashCode();
+ return (tagClass * 7919) ^ tagNo ^ (isExplicit() ? 0x0F : 0xF0) ^ obj.toASN1Primitive().hashCode();
+ }
+
+ public int getTagClass()
+ {
+ return tagClass;
}
/**
@@ -111,18 +213,24 @@
return tagNo;
}
- /**
- * return whether or not the object may be explicitly tagged.
- * <p>
- * Note: if the object has been read from an input stream, the only
- * time you can be sure if isExplicit is returning the true state of
- * affairs is if it returns false. An implicitly tagged object may appear
- * to be explicitly tagged, so you need to understand the context under
- * which the reading was done as well, see getObject below.
- */
- public boolean isExplicit()
+ public boolean hasContextTag()
{
- return explicit;
+ return this.tagClass == BERTags.CONTEXT_SPECIFIC;
+ }
+
+ public boolean hasContextTag(int tagNo)
+ {
+ return this.tagClass == BERTags.CONTEXT_SPECIFIC && this.tagNo == tagNo;
+ }
+
+ public boolean hasTag(int tagClass, int tagNo)
+ {
+ return this.tagClass == tagClass && this.tagNo == tagNo;
+ }
+
+ public boolean hasTagClass(int tagClass)
+ {
+ return this.tagClass == tagClass;
}
/**
@@ -138,52 +246,246 @@
}
/**
- * Return the object held in this tagged object as a parser assuming it has
- * the type of the passed in tag. If the object doesn't have a parser
- * associated with it, the base object is returned.
+ * return whether or not the object may be explicitly tagged.
+ * <p>
+ * Note: if the object has been read from an input stream, the only
+ * time you can be sure if isExplicit is returning the true state of
+ * affairs is if it returns false. An implicitly tagged object may appear
+ * to be explicitly tagged, so you need to understand the context under
+ * which the reading was done as well, see getObject below.
*/
- public ASN1Encodable getObjectParser(
- int tag,
- boolean isExplicit)
- throws IOException
+ public boolean isExplicit()
{
- switch (tag)
+ // TODO New methods like 'isKnownExplicit' etc. to distinguish uncertain cases?
+ switch (explicitness)
{
- case BERTags.SET:
- return ASN1Set.getInstance(this, isExplicit).parser();
- case BERTags.SEQUENCE:
- return ASN1Sequence.getInstance(this, isExplicit).parser();
+ case DECLARED_EXPLICIT:
+ case PARSED_EXPLICIT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ boolean isParsed()
+ {
+ switch (explicitness)
+ {
+ case PARSED_EXPLICIT:
+ case PARSED_IMPLICIT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Needed for open types, until we have better type-guided parsing support. Use sparingly for other
+ * purposes, and prefer {@link #getExplicitBaseTagged()}, {@link #getImplicitBaseTagged(int, int)} or
+ * {@link #getBaseUniversal(boolean, int)} where possible. Before using, check for matching tag
+ * {@link #getTagClass() class} and {@link #getTagNo() number}.
+ */
+ public ASN1Object getBaseObject()
+ {
+ return obj instanceof ASN1Object ? (ASN1Object)obj : obj.toASN1Primitive();
+ }
+
+ /**
+ * Needed for open types, until we have better type-guided parsing support. Use
+ * sparingly for other purposes, and prefer {@link #getExplicitBaseTagged()} or
+ * {@link #getBaseUniversal(boolean, int)} where possible. Before using, check
+ * for matching tag {@link #getTagClass() class} and {@link #getTagNo() number}.
+ */
+ public ASN1Object getExplicitBaseObject()
+ {
+ if (!isExplicit())
+ {
+ throw new IllegalStateException("object implicit - explicit expected.");
+ }
+
+ return obj instanceof ASN1Object ? (ASN1Object)obj : obj.toASN1Primitive();
+ }
+
+ public ASN1TaggedObject getExplicitBaseTagged()
+ {
+ if (!isExplicit())
+ {
+ throw new IllegalStateException("object implicit - explicit expected.");
+ }
+
+ return checkedCast(obj.toASN1Primitive());
+ }
+
+ public ASN1TaggedObject getImplicitBaseTagged(int baseTagClass, int baseTagNo)
+ {
+ if (baseTagClass == BERTags.UNIVERSAL || (baseTagClass & BERTags.PRIVATE) != baseTagClass)
+ {
+ throw new IllegalArgumentException("invalid base tag class: " + baseTagClass);
+ }
+
+ switch (explicitness)
+ {
+ case DECLARED_EXPLICIT:
+ throw new IllegalStateException("object explicit - implicit expected.");
+
+ case DECLARED_IMPLICIT:
+ {
+ ASN1TaggedObject declared = checkedCast(obj.toASN1Primitive());
+ return ASN1Util.checkTag(declared, baseTagClass, baseTagNo);
+ }
+
+ // Parsed; return a virtual tag (i.e. that couldn't have been present in the encoding)
+ default:
+ return replaceTag(baseTagClass, baseTagNo);
+ }
+ }
+
+ /**
+ * Note: tagged objects are generally context dependent. Before trying to
+ * extract a tagged object this way, make sure you have checked that both the
+ * {@link #getTagClass() tag class} and {@link #getTagNo() tag number} match
+ * what you are looking for.
+ *
+ * @param declaredExplicit Whether the tagged type for this object was declared
+ * EXPLICIT.
+ * @param tagNo The universal {@link BERTags tag number} of the
+ * expected base object.
+ */
+ public ASN1Primitive getBaseUniversal(boolean declaredExplicit, int tagNo)
+ {
+ ASN1UniversalType universalType = ASN1UniversalTypes.get(tagNo);
+ if (null == universalType)
+ {
+ throw new IllegalArgumentException("unsupported UNIVERSAL tag number: " + tagNo);
+ }
+
+ return getBaseUniversal(declaredExplicit, universalType);
+ }
+
+ ASN1Primitive getBaseUniversal(boolean declaredExplicit, ASN1UniversalType universalType)
+ {
+ if (declaredExplicit)
+ {
+ if (!isExplicit())
+ {
+ throw new IllegalStateException("object explicit - implicit expected.");
+ }
+
+ return universalType.checkedCast(obj.toASN1Primitive());
+ }
+
+ if (DECLARED_EXPLICIT == explicitness)
+ {
+ throw new IllegalStateException("object explicit - implicit expected.");
+ }
+
+ ASN1Primitive primitive = obj.toASN1Primitive();
+ switch (explicitness)
+ {
+ case PARSED_EXPLICIT:
+ return universalType.fromImplicitConstructed(rebuildConstructed(primitive));
+ case PARSED_IMPLICIT:
+ {
+ if (primitive instanceof ASN1Sequence)
+ {
+ return universalType.fromImplicitConstructed((ASN1Sequence)primitive);
+ }
+ return universalType.fromImplicitPrimitive((DEROctetString)primitive);
+ }
+ default:
+ return universalType.checkedCast(primitive);
+ }
+ }
+
+ public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ ASN1Primitive primitive = getBaseUniversal(declaredExplicit, baseTagNo);
+
+ switch (baseTagNo)
+ {
+ case BERTags.BIT_STRING:
+ return ((ASN1BitString)primitive).parser();
case BERTags.OCTET_STRING:
- return ASN1OctetString.getInstance(this, isExplicit).parser();
+ return ((ASN1OctetString)primitive).parser();
+ case BERTags.SEQUENCE:
+ return ((ASN1Sequence)primitive).parser();
+ case BERTags.SET:
+ return ((ASN1Set)primitive).parser();
}
- if (isExplicit)
- {
- return getObject();
- }
-
- throw new ASN1Exception("implicit tagging not implemented for tag: " + tag);
+ return primitive;
}
- public ASN1Primitive getLoadedObject()
+ public ASN1Encodable parseExplicitBaseObject() throws IOException
{
- return this.toASN1Primitive();
+ return getExplicitBaseObject();
}
+ public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException
+ {
+ return getExplicitBaseTagged();
+ }
+
+ public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException
+ {
+ return getImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public final ASN1Primitive getLoadedObject()
+ {
+ return this;
+ }
+
+ abstract ASN1Sequence rebuildConstructed(ASN1Primitive primitive);
+
+ abstract ASN1TaggedObject replaceTag(int tagClass, int tagNo);
+
ASN1Primitive toDERObject()
{
- return new DERTaggedObject(explicit, tagNo, obj);
+ return new DERTaggedObject(explicitness, tagClass, tagNo, obj);
}
ASN1Primitive toDLObject()
{
- return new DLTaggedObject(explicit, tagNo, obj);
+ return new DLTaggedObject(explicitness, tagClass, tagNo, obj);
}
- abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
-
public String toString()
{
- return "[" + tagNo + "]" + obj;
+ return ASN1Util.getTagText(tagClass, tagNo) + obj;
+ }
+
+ static ASN1Primitive createConstructedDL(int tagClass, int tagNo, ASN1EncodableVector contentsElements)
+ {
+ boolean maybeExplicit = (contentsElements.size() == 1);
+
+ return maybeExplicit
+ ? new DLTaggedObject(PARSED_EXPLICIT, tagClass, tagNo, contentsElements.get(0))
+ : new DLTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, DLFactory.createSequence(contentsElements));
+ }
+
+ static ASN1Primitive createConstructedIL(int tagClass, int tagNo, ASN1EncodableVector contentsElements)
+ {
+ boolean maybeExplicit = (contentsElements.size() == 1);
+
+ return maybeExplicit
+ ? new BERTaggedObject(PARSED_EXPLICIT, tagClass, tagNo, contentsElements.get(0))
+ : new BERTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, BERFactory.createSequence(contentsElements));
+ }
+
+ static ASN1Primitive createPrimitive(int tagClass, int tagNo, byte[] contentsOctets)
+ {
+ // Note: !CONSTRUCTED => IMPLICIT
+ return new DLTaggedObject(PARSED_IMPLICIT, tagClass, tagNo, new DEROctetString(contentsOctets));
+ }
+
+ private static ASN1TaggedObject checkedCast(ASN1Primitive primitive)
+ {
+ if (primitive instanceof ASN1TaggedObject)
+ {
+ return (ASN1TaggedObject)primitive;
+ }
+
+ throw new IllegalStateException("unexpected object: " + primitive.getClass().getName());
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObjectParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObjectParser.java
index 41fcf42..c150907 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObjectParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObjectParser.java
@@ -11,19 +11,38 @@
extends ASN1Encodable, InMemoryRepresentable
{
/**
- * Return the tag number associated with the underlying tagged object.
- * @return the object's tag number.
+ * Return the tag class associated with this object.
+ *
+ * @return the tag class.
+ */
+ int getTagClass();
+
+ /**
+ * Return the tag number associated with this object.
+ *
+ * @return the tag number.
*/
int getTagNo();
+ boolean hasContextTag();
+
+ boolean hasContextTag(int tagNo);
+
+ boolean hasTag(int tagClass, int tagNo);
+
+ boolean hasTagClass(int tagClass);
+
+ ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException;
+
/**
- * Return a parser for the actual object tagged.
- *
- * @param tag the primitive tag value for the object tagged originally.
- * @param isExplicit true if the tagging was done explicitly.
- * @return a parser for the tagged object.
- * @throws IOException if a parser cannot be constructed.
+ * Needed for open types, until we have better type-guided parsing support. Use sparingly for other
+ * purposes, and prefer {@link #parseExplicitBaseTagged()} or {@link #parseBaseUniversal(boolean, int)}
+ * where possible. Before using, check for matching tag {@link #getTagClass() class} and
+ * {@link #getTagNo() number}.
*/
- ASN1Encodable getObjectParser(int tag, boolean isExplicit)
- throws IOException;
+ ASN1Encodable parseExplicitBaseObject() throws IOException;
+
+ ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException;
+
+ ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Type.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Type.java
new file mode 100644
index 0000000..1116801
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Type.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+abstract class ASN1Type
+{
+ final Class javaClass;
+
+ ASN1Type(Class javaClass)
+ {
+ this.javaClass = javaClass;
+ }
+
+ final Class getJavaClass()
+ {
+ return javaClass;
+ }
+
+ public final boolean equals(Object that)
+ {
+ return this == that;
+ }
+
+ public final int hashCode()
+ {
+ return super.hashCode();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java
index 7bd9298..adfe70c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java
@@ -38,7 +38,13 @@
public class ASN1UTCTime
extends ASN1Primitive
{
- private byte[] time;
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1UTCTime.class, BERTags.UTC_TIME)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
/**
* Return an UTC Time from the passed in object.
@@ -54,12 +60,19 @@
{
return (ASN1UTCTime)obj;
}
-
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1UTCTime)
+ {
+ return (ASN1UTCTime)primitive;
+ }
+ }
if (obj instanceof byte[])
{
try
{
- return (ASN1UTCTime)fromByteArray((byte[])obj);
+ return (ASN1UTCTime)TYPE.fromByteArray((byte[])obj);
}
catch (Exception e)
{
@@ -73,29 +86,19 @@
/**
* Return an UTC Time from a tagged object.
*
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
* @return an ASN1UTCTime instance, or null.
*/
- public static ASN1UTCTime getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1UTCTime getInstance(ASN1TaggedObject taggedObject, boolean explicit)
{
- ASN1Object o = obj.getObject();
-
- if (explicit || o instanceof ASN1UTCTime)
- {
- return getInstance(o);
- }
- else
- {
- return new ASN1UTCTime(ASN1OctetString.getInstance(o).getOctets());
- }
+ return (ASN1UTCTime)TYPE.getContextInstance(taggedObject, explicit);
}
+ final byte[] contents;
+
/**
* The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
* never encoded. When you're creating one of these objects from scratch, that's
@@ -109,7 +112,7 @@
public ASN1UTCTime(
String time)
{
- this.time = Strings.toByteArray(time);
+ this.contents = Strings.toByteArray(time);
try
{
this.getDate();
@@ -133,7 +136,7 @@
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
/**
@@ -155,17 +158,16 @@
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
- this.time = Strings.toByteArray(dateF.format(time));
+ this.contents = Strings.toByteArray(dateF.format(time));
}
- ASN1UTCTime(
- byte[] time)
+ ASN1UTCTime(byte[] contents)
{
- if (time.length < 2)
+ if (contents.length < 2)
{
throw new IllegalArgumentException("UTCTime string too short");
}
- this.time = time;
+ this.contents = contents;
if (!(isDigit(0) && isDigit(1)))
{
throw new IllegalArgumentException("illegal characters in UTCTime string");
@@ -186,7 +188,7 @@
// SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz");
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz", Locale.US);
- return DateUtil.epochAdjust(dateF.parse(getTime()));
+ return dateF.parse(getTime());
}
/**
@@ -204,8 +206,8 @@
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz", Locale.US);
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
-
- return DateUtil.epochAdjust(dateF.parse(getAdjustedTime()));
+
+ return dateF.parse(getAdjustedTime());
}
/**
@@ -226,7 +228,7 @@
*/
public String getTime()
{
- String stime = Strings.fromByteArray(time);
+ String stime = Strings.fromByteArray(contents);
//
// standardise the format.
@@ -287,24 +289,22 @@
private boolean isDigit(int pos)
{
- return time.length > pos && time[pos] >= '0' && time[pos] <= '9';
+ return contents.length > pos && contents[pos] >= '0' && contents[pos] <= '9';
}
- boolean isConstructed()
+ final boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- int length = time.length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.UTC_TIME, time);
+ out.writeEncodingDL(withTag, BERTags.UTC_TIME, contents);
}
boolean asn1Equals(
@@ -315,16 +315,21 @@
return false;
}
- return Arrays.areEqual(time, ((ASN1UTCTime)o).time);
+ return Arrays.areEqual(contents, ((ASN1UTCTime)o).contents);
}
public int hashCode()
{
- return Arrays.hashCode(time);
+ return Arrays.hashCode(contents);
}
public String toString()
{
- return Strings.fromByteArray(time);
+ return Strings.fromByteArray(contents);
+ }
+
+ static ASN1UTCTime createPrimitive(byte[] contents)
+ {
+ return new ASN1UTCTime(contents);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTF8String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTF8String.java
new file mode 100644
index 0000000..629d83e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTF8String.java
@@ -0,0 +1,133 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1UTF8String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1UTF8String.class, BERTags.UTF8_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a UTF8 string from the passed in object.
+ *
+ * @param obj an ASN1UTF8String or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1UTF8String instance, or null
+ */
+ public static ASN1UTF8String getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1UTF8String)
+ {
+ return (ASN1UTF8String)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1UTF8String)
+ {
+ return (ASN1UTF8String)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1UTF8String)TYPE.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());
+ }
+
+ /**
+ * Return an UTF8 String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return a DERUTF8String instance, or null
+ */
+ public static ASN1UTF8String getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1UTF8String)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1UTF8String(String string)
+ {
+ this(Strings.toUTF8ByteArray(string), false);
+ }
+
+ ASN1UTF8String(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromUTF8ByteArray(contents);
+ }
+
+ // TODO Not sure this is useful unless all ASN.1 types have a meaningful one
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1UTF8String))
+ {
+ return false;
+ }
+
+ ASN1UTF8String that = (ASN1UTF8String)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.UTF8_STRING, contents);
+ }
+
+ static ASN1UTF8String createPrimitive(byte[] contents)
+ {
+ return new DERUTF8String(contents, false);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UniversalString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UniversalString.java
new file mode 100644
index 0000000..d1e4805
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UniversalString.java
@@ -0,0 +1,180 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * ASN.1 UniversalString object - encodes UNICODE (ISO 10646) characters using 32-bit format. In Java we
+ * have no way of representing this directly so we rely on byte arrays to carry these.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1UniversalString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1UniversalString.class, BERTags.UNIVERSAL_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ /**
+ * Return a Universal String from the passed in object.
+ *
+ * @param obj an ASN1UniversalString or an object that can be converted into
+ * one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1UniversalString instance, or null
+ */
+ public static ASN1UniversalString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1UniversalString)
+ {
+ return (ASN1UniversalString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1UniversalString)
+ {
+ return (ASN1UniversalString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1UniversalString)TYPE.fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return a Universal String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return a ASN1UniversalString instance, or null
+ */
+ public static ASN1UniversalString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1UniversalString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1UniversalString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ int dl = contents.length;
+ StringBuffer buf = new StringBuffer(3 + 2 * (ASN1OutputStream.getLengthOfDL(dl) + dl));
+ buf.append("#1C");
+ encodeHexDL(buf, dl);
+
+ for (int i = 0; i < dl; ++i)
+ {
+ encodeHexByte(buf, contents[i]);
+ }
+
+ return buf.toString();
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.UNIVERSAL_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1UniversalString))
+ {
+ return false;
+ }
+
+ ASN1UniversalString that = (ASN1UniversalString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1UniversalString createPrimitive(byte[] contents)
+ {
+ return new DERUniversalString(contents, false);
+ }
+
+ private static void encodeHexByte(StringBuffer buf, int i)
+ {
+ buf.append(table[(i >>> 4) & 0xF]);
+ buf.append(table[i & 0xF]);
+ }
+
+ private static void encodeHexDL(StringBuffer buf, int dl)
+ {
+ if (dl < 128)
+ {
+ encodeHexByte(buf, dl);
+ return;
+ }
+
+ byte[] stack = new byte[5];
+ int pos = 5;
+
+ do
+ {
+ stack[--pos] = (byte)dl;
+ dl >>>= 8;
+ }
+ while (dl != 0);
+
+ int count = stack.length - pos;
+ stack[--pos] = (byte)(0x80 | count);
+
+ do
+ {
+ encodeHexByte(buf, stack[pos++]);
+ }
+ while (pos < stack.length);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UniversalType.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UniversalType.java
new file mode 100644
index 0000000..e3cb935
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UniversalType.java
@@ -0,0 +1,57 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+abstract class ASN1UniversalType
+ extends ASN1Type
+{
+ final ASN1Tag tag;
+
+ ASN1UniversalType(Class javaClass, int tagNumber)
+ {
+ super(javaClass);
+
+ this.tag = ASN1Tag.create(BERTags.UNIVERSAL, tagNumber);
+ }
+
+ final ASN1Primitive checkedCast(ASN1Primitive primitive)
+ {
+ if (javaClass.isInstance(primitive))
+ {
+ return primitive;
+ }
+
+ throw new IllegalStateException("unexpected object: " + primitive.getClass().getName());
+ }
+
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ throw new IllegalStateException("unexpected implicit primitive encoding");
+ }
+
+ ASN1Primitive fromImplicitConstructed(ASN1Sequence sequence)
+ {
+ throw new IllegalStateException("unexpected implicit constructed encoding");
+ }
+
+ final ASN1Primitive fromByteArray(byte[] bytes) throws IOException
+ {
+ return checkedCast(ASN1Primitive.fromByteArray(bytes));
+ }
+
+ final ASN1Primitive getContextInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
+ {
+ if (BERTags.CONTEXT_SPECIFIC != taggedObject.getTagClass())
+ {
+ throw new IllegalStateException("this method only valid for CONTEXT_SPECIFIC tags");
+ }
+
+ return checkedCast(taggedObject.getBaseUniversal(declaredExplicit, this));
+ }
+
+ final ASN1Tag getTag()
+ {
+ return tag;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UniversalTypes.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UniversalTypes.java
new file mode 100644
index 0000000..9163f3c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UniversalTypes.java
@@ -0,0 +1,72 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+final class ASN1UniversalTypes
+{
+ private ASN1UniversalTypes()
+ {
+ }
+
+ static ASN1UniversalType get(int tagNumber)
+ {
+ switch (tagNumber)
+ {
+ case BERTags.BOOLEAN:
+ return ASN1Boolean.TYPE;
+ case BERTags.INTEGER:
+ return ASN1Integer.TYPE;
+ case BERTags.BIT_STRING:
+ return ASN1BitString.TYPE;
+ case BERTags.OCTET_STRING:
+ return ASN1OctetString.TYPE;
+ case BERTags.NULL:
+ return ASN1Null.TYPE;
+ case BERTags.OBJECT_IDENTIFIER:
+ return ASN1ObjectIdentifier.TYPE;
+ case BERTags.OBJECT_DESCRIPTOR: // [UNIVERSAL 7] IMPLICIT GraphicString
+ return ASN1ObjectDescriptor.TYPE;
+ case BERTags.EXTERNAL:
+ return ASN1External.TYPE;
+ case BERTags.ENUMERATED:
+ return ASN1Enumerated.TYPE;
+ case BERTags.UTF8_STRING: // [UNIVERSAL 12] IMPLICIT OCTET STRING (encode as if)
+ return ASN1UTF8String.TYPE;
+ case BERTags.RELATIVE_OID:
+ return ASN1RelativeOID.TYPE;
+ case BERTags.SEQUENCE:
+ return ASN1Sequence.TYPE;
+ case BERTags.SET:
+ return ASN1Set.TYPE;
+ case BERTags.NUMERIC_STRING: // [UNIVERSAL 18] IMPLICIT OCTET STRING (encode as if)
+ return ASN1NumericString.TYPE;
+ case BERTags.PRINTABLE_STRING: // [UNIVERSAL 19] IMPLICIT OCTET STRING (encode as if)
+ return ASN1PrintableString.TYPE;
+ case BERTags.T61_STRING: // [UNIVERSAL 20] IMPLICIT OCTET STRING (encode as if)
+ return ASN1T61String.TYPE;
+ case BERTags.VIDEOTEX_STRING: // [UNIVERSAL 21] IMPLICIT OCTET STRING (encode as if)
+ return ASN1VideotexString.TYPE;
+ case BERTags.IA5_STRING: // [UNIVERSAL 22] IMPLICIT OCTET STRING (encode as if)
+ return ASN1IA5String.TYPE;
+ case BERTags.UTC_TIME: // [UNIVERSAL 23] IMPLICIT VisibleString (restricted values)
+ return ASN1UTCTime.TYPE;
+ case BERTags.GENERALIZED_TIME: // [UNIVERSAL 24] IMPLICIT VisibleString (restricted values)
+ return ASN1GeneralizedTime.TYPE;
+ case BERTags.GRAPHIC_STRING: // [UNIVERSAL 25] IMPLICIT OCTET STRING (encode as if)
+ return ASN1GraphicString.TYPE;
+ case BERTags.VISIBLE_STRING: // [UNIVERSAL 26] IMPLICIT OCTET STRING (encode as if)
+ return ASN1VisibleString.TYPE;
+ case BERTags.GENERAL_STRING: // [UNIVERSAL 27] IMPLICIT OCTET STRING (encode as if)
+ return ASN1GeneralString.TYPE;
+ case BERTags.UNIVERSAL_STRING: // [UNIVERSAL 28] IMPLICIT OCTET STRING (encode as if)
+ return ASN1UniversalString.TYPE;
+ case BERTags.BMP_STRING: // [UNIVERSAL 30] IMPLICIT OCTET STRING (encode as if)
+ return ASN1BMPString.TYPE;
+
+ case BERTags.REAL:
+ case BERTags.EMBEDDED_PDV:
+ case BERTags.UNRESTRICTED_STRING:
+ default:
+ return null;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Util.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Util.java
new file mode 100644
index 0000000..17ba06e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Util.java
@@ -0,0 +1,331 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1Util
+{
+ static ASN1TaggedObject checkTag(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ String expected = getTagText(tagClass, tagNo);
+ String found = getTagText(taggedObject);
+ throw new IllegalStateException("Expected " + expected + " tag but found " + found);
+ }
+ return taggedObject;
+ }
+
+ static ASN1TaggedObjectParser checkTag(ASN1TaggedObjectParser taggedObjectParser, int tagClass, int tagNo)
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ String expected = getTagText(tagClass, tagNo);
+ String found = getTagText(taggedObjectParser);
+ throw new IllegalStateException("Expected " + expected + " tag but found " + found);
+ }
+ return taggedObjectParser;
+ }
+
+
+ /*
+ * Tag text methods
+ */
+
+ static String getTagText(ASN1Tag tag)
+ {
+ return getTagText(tag.getTagClass(), tag.getTagNumber());
+ }
+
+ public static String getTagText(ASN1TaggedObject taggedObject)
+ {
+ return getTagText(taggedObject.getTagClass(), taggedObject.getTagNo());
+ }
+
+ public static String getTagText(ASN1TaggedObjectParser taggedObjectParser)
+ {
+ return getTagText(taggedObjectParser.getTagClass(), taggedObjectParser.getTagNo());
+ }
+
+ public static String getTagText(int tagClass, int tagNo)
+ {
+ switch (tagClass)
+ {
+ case BERTags.APPLICATION:
+ return "[APPLICATION " + tagNo + "]";
+ case BERTags.CONTEXT_SPECIFIC:
+ return "[CONTEXT " + tagNo + "]";
+ case BERTags.PRIVATE:
+ return "[PRIVATE " + tagNo + "]";
+ default:
+ return "[UNIVERSAL " + tagNo + "]";
+ }
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getExplicitBaseObject
+ */
+
+ public static ASN1Object getExplicitBaseObject(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getExplicitBaseObject();
+ }
+
+ public static ASN1Object getExplicitContextBaseObject(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return getExplicitBaseObject(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1Object tryGetExplicitBaseObject(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getExplicitBaseObject();
+ }
+
+ public static ASN1Object tryGetExplicitContextBaseObject(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return tryGetExplicitBaseObject(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getExplicitBaseTagged
+ */
+
+ public static ASN1TaggedObject getExplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObject getExplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return getExplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1TaggedObject tryGetExplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObject tryGetExplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo)
+ {
+ return tryGetExplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getImplicitBaseTagged
+ */
+
+ public static ASN1TaggedObject getImplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObject getImplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ return getImplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObject tryGetImplicitBaseTagged(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObject tryGetImplicitContextBaseTagged(ASN1TaggedObject taggedObject, int tagNo,
+ int baseTagClass, int baseTagNo)
+ {
+ return tryGetImplicitBaseTagged(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObject#getBaseUniversal
+ */
+
+ public static ASN1Primitive getBaseUniversal(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ return checkTag(taggedObject, tagClass, tagNo).getBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Primitive getContextBaseUniversal(ASN1TaggedObject taggedObject, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ return getBaseUniversal(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Primitive tryGetBaseUniversal(ASN1TaggedObject taggedObject, int tagClass, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ if (!taggedObject.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObject.getBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Primitive tryGetContextBaseUniversal(ASN1TaggedObject taggedObject, int tagNo,
+ boolean declaredExplicit, int baseTagNo)
+ {
+ return tryGetBaseUniversal(taggedObject, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseExplicitBaseTagged
+ */
+
+ public static ASN1TaggedObjectParser parseExplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObjectParser parseExplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo) throws IOException
+ {
+ return parseExplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1TaggedObjectParser tryParseExplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseExplicitBaseTagged();
+ }
+
+ public static ASN1TaggedObjectParser tryParseExplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo) throws IOException
+ {
+ return tryParseExplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseImplicitBaseTagged
+ */
+
+ public static ASN1TaggedObjectParser parseImplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObjectParser parseImplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ return parseImplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObjectParser tryParseImplicitBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagClass, int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseImplicitBaseTagged(baseTagClass, baseTagNo);
+ }
+
+ public static ASN1TaggedObjectParser tryParseImplicitContextBaseTagged(ASN1TaggedObjectParser taggedObjectParser,
+ int tagNo, int baseTagClass, int baseTagNo) throws IOException
+ {
+ return tryParseImplicitBaseTagged(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, baseTagClass, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseBaseUniversal
+ */
+
+ public static ASN1Encodable parseBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo, boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Encodable parseContextBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagNo,
+ boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ return parseBaseUniversal(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Encodable tryParseBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo, boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseBaseUniversal(declaredExplicit, baseTagNo);
+ }
+
+ public static ASN1Encodable tryParseContextBaseUniversal(ASN1TaggedObjectParser taggedObjectParser, int tagNo,
+ boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ return tryParseBaseUniversal(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo, declaredExplicit, baseTagNo);
+ }
+
+
+ /*
+ * Wrappers for ASN1TaggedObjectParser#parseExplicitBaseObject
+ */
+
+ public static ASN1Encodable parseExplicitBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo) throws IOException
+ {
+ return checkTag(taggedObjectParser, tagClass, tagNo).parseExplicitBaseObject();
+ }
+
+ public static ASN1Encodable parseExplicitContextBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagNo)
+ throws IOException
+ {
+ return parseExplicitBaseObject(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+
+ public static ASN1Encodable tryParseExplicitBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagClass,
+ int tagNo) throws IOException
+ {
+ if (!taggedObjectParser.hasTag(tagClass, tagNo))
+ {
+ return null;
+ }
+
+ return taggedObjectParser.parseExplicitBaseObject();
+ }
+
+ public static ASN1Encodable tryParseExplicitContextBaseObject(ASN1TaggedObjectParser taggedObjectParser, int tagNo)
+ throws IOException
+ {
+ return tryParseExplicitBaseObject(taggedObjectParser, BERTags.CONTEXT_SPECIFIC, tagNo);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1VideotexString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1VideotexString.java
new file mode 100644
index 0000000..52425b4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1VideotexString.java
@@ -0,0 +1,131 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1VideotexString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1VideotexString.class, BERTags.VIDEOTEX_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * return a Videotex String from the passed in object
+ *
+ * @param obj an ASN1VideotexString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1VideotexString instance, or null.
+ */
+ public static ASN1VideotexString getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1VideotexString)
+ {
+ return (ASN1VideotexString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1VideotexString)
+ {
+ return (ASN1VideotexString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1VideotexString)TYPE.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());
+ }
+
+ /**
+ * return a Videotex String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot be converted.
+ * @return an ASN1VideotexString instance, or null.
+ */
+ public static ASN1VideotexString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1VideotexString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ /**
+ * basic constructor - with bytes.
+ * @param string the byte encoding of the characters making up the string.
+ */
+ ASN1VideotexString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.VIDEOTEX_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1VideotexString))
+ {
+ return false;
+ }
+
+ ASN1VideotexString that = (ASN1VideotexString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ static ASN1VideotexString createPrimitive(byte[] contents)
+ {
+ return new DERVideotexString(contents, false);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1VisibleString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1VisibleString.java
new file mode 100644
index 0000000..1a70386
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1VisibleString.java
@@ -0,0 +1,143 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 VisibleString object encoding ISO 646 (ASCII) character code points 32 to 126.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1VisibleString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1VisibleString.class, BERTags.VISIBLE_STRING)
+ {
+ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
+ {
+ return createPrimitive(octetString.getOctets());
+ }
+ };
+
+ /**
+ * Return a Visible String from the passed in object.
+ *
+ * @param obj an ASN1VisibleString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1VisibleString instance, or null
+ */
+ public static ASN1VisibleString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1VisibleString)
+ {
+ return (ASN1VisibleString)obj;
+ }
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+ if (primitive instanceof ASN1VisibleString)
+ {
+ return (ASN1VisibleString)primitive;
+ }
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1VisibleString)TYPE.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());
+ }
+
+ /**
+ * Return a Visible String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1VisibleString instance, or null
+ */
+ public static ASN1VisibleString getInstance(ASN1TaggedObject taggedObject, boolean explicit)
+ {
+ return (ASN1VisibleString)TYPE.getContextInstance(taggedObject, explicit);
+ }
+
+ final byte[] contents;
+
+ ASN1VisibleString(String string)
+ {
+ this.contents = Strings.toByteArray(string);
+ }
+
+ ASN1VisibleString(byte[] contents, boolean clone)
+ {
+ this.contents = clone ? Arrays.clone(contents) : contents;
+ }
+
+ public final String getString()
+ {
+ return Strings.fromByteArray(contents);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public final byte[] getOctets()
+ {
+ return Arrays.clone(contents);
+ }
+
+ final boolean encodeConstructed()
+ {
+ return false;
+ }
+
+ final int encodedLength(boolean withTag)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
+ }
+
+ final void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.VISIBLE_STRING, contents);
+ }
+
+ final boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1VisibleString))
+ {
+ return false;
+ }
+
+ ASN1VisibleString that = (ASN1VisibleString)other;
+
+ return Arrays.areEqual(this.contents, that.contents);
+ }
+
+ public final int hashCode()
+ {
+ return Arrays.hashCode(contents);
+ }
+
+ static ASN1VisibleString createPrimitive(byte[] contents)
+ {
+ return new DERVisibleString(contents, false);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecific.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecific.java
deleted file mode 100644
index cb5023a..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecific.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * An indefinite-length encoding version of an ASN.1 ApplicationSpecific object.
- * @hide This class is not part of the Android public SDK API
- */
-public class BERApplicationSpecific
- extends ASN1ApplicationSpecific
-{
- BERApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- super(isConstructed, tag, octets);
- }
-
- /**
- * Create an application specific object with a tagging of explicit/constructed.
- *
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public BERApplicationSpecific(
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- this(true, tag, object);
- }
-
- /**
- * Create an application specific object with the tagging style given by the value of constructed.
- *
- * @param constructed true if the object is constructed.
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public BERApplicationSpecific(
- boolean constructed,
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
- }
-
- private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
- throws IOException
- {
- byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.BER);
-
- if (explicit)
- {
- return data;
- }
- else
- {
- int lenBytes = getLengthOfHeader(data);
- byte[] tmp = new byte[data.length - lenBytes];
- System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
- return tmp;
- }
- }
-
- /**
- * Create an application specific object which is marked as constructed
- *
- * @param tagNo the tag number for this object.
- * @param vec the objects making up the application specific object.
- */
- public BERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
- {
- super(true, tagNo, getEncodedVector(vec));
- }
-
- private static byte[] getEncodedVector(ASN1EncodableVector vec)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != vec.size(); i++)
- {
- try
- {
- bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.BER));
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("malformed object: " + e, e);
- }
- }
- return bOut.toByteArray();
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncodedIndef(withTag, flags, tag, octets);
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecificParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecificParser.java
deleted file mode 100644
index a1617b4..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecificParser.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-/**
- * A parser for indefinite-length ASN.1 ApplicationSpecific objects.
- * @hide This class is not part of the Android public SDK API
- */
-public class BERApplicationSpecificParser
- implements ASN1ApplicationSpecificParser
-{
- private final int tag;
- private final ASN1StreamParser parser;
-
- BERApplicationSpecificParser(int tag, ASN1StreamParser parser)
- {
- this.tag = tag;
- this.parser = parser;
- }
-
- /**
- * Return the object contained in this application specific object,
- * @return the contained object.
- * @throws IOException if the underlying stream cannot be read, or does not contain an ASN.1 encoding.
- */
- public ASN1Encodable readObject()
- throws IOException
- {
- return parser.readObject();
- }
-
- /**
- * Return an in-memory, encodable, representation of the application specific object.
- *
- * @return a BERApplicationSpecific.
- * @throws IOException if there is an issue loading the data.
- */
- public ASN1Primitive getLoadedObject()
- throws IOException
- {
- return new BERApplicationSpecific(tag, parser.readVector());
- }
-
- /**
- * Return a BERApplicationSpecific representing this parser and its contents.
- *
- * @return a BERApplicationSpecific
- */
- public ASN1Primitive toASN1Primitive()
- {
- try
- {
- return getLoadedObject();
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException(e.getMessage(), e);
- }
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERBitString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERBitString.java
new file mode 100644
index 0000000..c25bf0d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERBitString.java
@@ -0,0 +1,192 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERBitString
+ extends ASN1BitString
+{
+ private static final int DEFAULT_SEGMENT_LIMIT = 1000;
+
+ private final int segmentLimit;
+ private final ASN1BitString[] elements;
+
+ /**
+ * Convert a vector of bit strings into a single bit string
+ */
+ static byte[] flattenBitStrings(ASN1BitString[] bitStrings)
+ {
+ int count = bitStrings.length;
+ switch (count)
+ {
+ case 0:
+ // No bits
+ return new byte[]{ 0 };
+ case 1:
+ return bitStrings[0].contents;
+ default:
+ {
+ int last = count - 1, totalLength = 0;
+ for (int i = 0; i < last; ++i)
+ {
+ byte[] elementContents = bitStrings[i].contents;
+ if (elementContents[0] != 0)
+ {
+ throw new IllegalArgumentException("only the last nested bitstring can have padding");
+ }
+
+ totalLength += elementContents.length - 1;
+ }
+
+ // Last one can have padding
+ byte[] lastElementContents = bitStrings[last].contents;
+ byte padBits = lastElementContents[0];
+ totalLength += lastElementContents.length;
+
+ byte[] contents = new byte[totalLength];
+ contents[0] = padBits;
+
+ int pos = 1;
+ for (int i = 0; i < count; ++i)
+ {
+ byte[] elementContents = bitStrings[i].contents;
+ int length = elementContents.length - 1;
+ System.arraycopy(elementContents, 1, contents, pos, length);
+ pos += length;
+ }
+
+// assert pos == totalLength;
+ return contents;
+ }
+ }
+ }
+
+ public BERBitString(byte[] data)
+ {
+ this(data, 0);
+ }
+
+ public BERBitString(byte data, int padBits)
+ {
+ super(data, padBits);
+ this.elements = null;
+ this.segmentLimit = DEFAULT_SEGMENT_LIMIT;
+ }
+
+ public BERBitString(byte[] data, int padBits)
+ {
+ this(data, padBits, DEFAULT_SEGMENT_LIMIT);
+ }
+
+ public BERBitString(byte[] data, int padBits, int segmentLimit)
+ {
+ super(data, padBits);
+ this.elements = null;
+ this.segmentLimit = segmentLimit;
+ }
+
+ public BERBitString(ASN1Encodable obj) throws IOException
+ {
+ this(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
+ }
+
+ public BERBitString(ASN1BitString[] elements)
+ {
+ this(elements, DEFAULT_SEGMENT_LIMIT);
+ }
+
+ public BERBitString(ASN1BitString[] elements, int segmentLimit)
+ {
+ super(flattenBitStrings(elements), false);
+ this.elements = elements;
+ this.segmentLimit = segmentLimit;
+ }
+
+ BERBitString(byte[] contents, boolean check)
+ {
+ super(contents, check);
+ this.elements = null;
+ this.segmentLimit = DEFAULT_SEGMENT_LIMIT;
+ }
+
+ boolean encodeConstructed()
+ {
+ return null != elements || contents.length > segmentLimit;
+ }
+
+ int encodedLength(boolean withTag)
+ throws IOException
+ {
+ if (!encodeConstructed())
+ {
+ return DLBitString.encodedLength(withTag, contents.length);
+ }
+
+ int totalLength = withTag ? 4 : 3;
+
+ if (null != elements)
+ {
+ for (int i = 0; i < elements.length; ++i)
+ {
+ totalLength += elements[i].encodedLength(true);
+ }
+ }
+ else if (contents.length < 2)
+ {
+ // No bits
+ }
+ else
+ {
+ int extraSegments = (contents.length - 2) / (segmentLimit - 1);
+ totalLength += extraSegments * DLBitString.encodedLength(true, segmentLimit);
+
+ int lastSegmentLength = contents.length - (extraSegments * (segmentLimit - 1));
+ totalLength += DLBitString.encodedLength(true, lastSegmentLength);
+ }
+
+ return totalLength;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ if (!encodeConstructed())
+ {
+ DLBitString.encode(out, withTag, contents, 0, contents.length);
+ return;
+ }
+
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.BIT_STRING);
+ out.write(0x80);
+
+ if (null != elements)
+ {
+ out.writePrimitives(elements);
+ }
+ else if (contents.length < 2)
+ {
+ // No bits
+ }
+ else
+ {
+ byte pad = contents[0];
+ int length = contents.length;
+ int remaining = length - 1;
+ int segmentLength = segmentLimit - 1;
+
+ while (remaining > segmentLength)
+ {
+ DLBitString.encode(out, true, (byte)0, contents, length - remaining, segmentLength);
+ remaining -= segmentLength;
+ }
+
+ DLBitString.encode(out, true, pad, contents, length - remaining, remaining);
+ }
+
+ out.write(0x00);
+ out.write(0x00);
+ }
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERBitStringParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERBitStringParser.java
new file mode 100644
index 0000000..c410260
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERBitStringParser.java
@@ -0,0 +1,68 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.util.io.Streams;
+
+/**
+ * A parser for indefinite-length BIT STRINGs.
+ *
+ * @deprecated Check for 'ASN1BitStringParser' instead
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERBitStringParser
+ implements ASN1BitStringParser
+{
+ private ASN1StreamParser _parser;
+
+ private ConstructedBitStream _bitStream;
+
+ BERBitStringParser(
+ ASN1StreamParser parser)
+ {
+ _parser = parser;
+ }
+
+ public InputStream getOctetStream() throws IOException
+ {
+ return _bitStream = new ConstructedBitStream(_parser, true);
+ }
+
+ public InputStream getBitStream() throws IOException
+ {
+ return _bitStream = new ConstructedBitStream(_parser, false);
+ }
+
+ public int getPadBits()
+ {
+ return _bitStream.getPadBits();
+ }
+
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return parse(_parser);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
+ }
+ }
+
+ static BERBitString parse(ASN1StreamParser sp) throws IOException
+ {
+ ConstructedBitStream bitStream = new ConstructedBitStream(sp, false);
+ byte[] data = Streams.readAll(bitStream);
+ int padBits = bitStream.getPadBits();
+ return new BERBitString(data, padBits);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERConstructedOctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERConstructedOctetString.java
deleted file mode 100644
index 6a67881..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERConstructedOctetString.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Vector;
-
-/**
- * @deprecated use BEROctetString
- * @hide This class is not part of the Android public SDK API
- */
-public class BERConstructedOctetString
- extends BEROctetString
-{
- private static final int MAX_LENGTH = 1000;
-
- /**
- * convert a vector of octet strings into a single byte string
- */
- static private byte[] toBytes(
- Vector octs)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != octs.size(); i++)
- {
- try
- {
- DEROctetString o = (DEROctetString)octs.elementAt(i);
-
- bOut.write(o.getOctets());
- }
- catch (ClassCastException e)
- {
- throw new IllegalArgumentException(octs.elementAt(i).getClass().getName() + " found in input should only contain DEROctetString");
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("exception converting octets " + e.toString());
- }
- }
-
- return bOut.toByteArray();
- }
-
- private Vector octs;
-
- /**
- * @param string the octets making up the octet string.
- */
- public BERConstructedOctetString(
- byte[] string)
- {
- super(string);
- }
-
- public BERConstructedOctetString(
- Vector octs)
- {
- super(toBytes(octs));
-
- this.octs = octs;
- }
-
- public BERConstructedOctetString(
- ASN1Primitive obj)
- {
- super(toByteArray(obj));
- }
-
- private static byte[] toByteArray(ASN1Primitive obj)
- {
- try
- {
- return obj.getEncoded();
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("Unable to encode object");
- }
- }
-
- public BERConstructedOctetString(
- ASN1Encodable obj)
- {
- this(obj.toASN1Primitive());
- }
-
- public byte[] getOctets()
- {
- return string;
- }
-
- /**
- * return the DER octets that make up this string.
- */
- public Enumeration getObjects()
- {
- if (octs == null)
- {
- return generateOcts().elements();
- }
-
- return octs.elements();
- }
-
- private Vector generateOcts()
- {
- Vector vec = new Vector();
- for (int i = 0; i < string.length; i += MAX_LENGTH)
- {
- int end;
-
- if (i + MAX_LENGTH > string.length)
- {
- end = string.length;
- }
- else
- {
- end = i + MAX_LENGTH;
- }
-
- byte[] nStr = new byte[end - i];
-
- System.arraycopy(string, i, nStr, 0, nStr.length);
-
- vec.addElement(new DEROctetString(nStr));
- }
-
- return vec;
- }
-
- public static BEROctetString fromSequence(ASN1Sequence seq)
- {
- Vector v = new Vector();
- Enumeration e = seq.getObjects();
-
- while (e.hasMoreElements())
- {
- v.addElement(e.nextElement());
- }
-
- return new BERConstructedOctetString(v);
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java
index fa9f0df..2528b43 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java
@@ -8,7 +8,7 @@
* Base class for generators for indefinite-length structures.
* @hide This class is not part of the Android public SDK API
*/
-public class BERGenerator
+public abstract class BERGenerator
extends ASN1Generator
{
private boolean _tagged = false;
@@ -45,7 +45,7 @@
{
if (_tagged)
{
- int tagNum = _tagNo | BERTags.TAGGED;
+ int tagNum = _tagNo | BERTags.CONTEXT_SPECIFIC;
if (_isExplicit)
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java
index 8710d81..cac742c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java
@@ -1,10 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
/**
* ASN.1 OctetStrings, with indefinite length rules, and <i>constructed form</i> support.
@@ -24,172 +21,148 @@
public class BEROctetString
extends ASN1OctetString
{
- private static final int DEFAULT_CHUNK_SIZE = 1000;
+ private static final int DEFAULT_SEGMENT_LIMIT = 1000;
- private final int chunkSize;
- private final ASN1OctetString[] octs;
+ private final int segmentLimit;
+ private final ASN1OctetString[] elements;
/**
* Convert a vector of octet strings into a single byte string
*/
- static private byte[] toBytes(
- ASN1OctetString[] octs)
+ static byte[] flattenOctetStrings(ASN1OctetString[] octetStrings)
{
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != octs.length; i++)
+ int count = octetStrings.length;
+ switch (count)
{
- try
+ case 0:
+ return EMPTY_OCTETS;
+ case 1:
+ return octetStrings[0].string;
+ default:
+ {
+ int totalOctets = 0;
+ for (int i = 0; i < count; ++i)
{
- bOut.write(octs[i].getOctets());
+ totalOctets += octetStrings[i].string.length;
}
- catch (IOException e)
+
+ byte[] string = new byte[totalOctets];
+ for (int i = 0, pos = 0; i < count; ++i)
{
- throw new IllegalArgumentException("exception converting octets " + e.toString());
+ byte[] octets = octetStrings[i].string;
+ System.arraycopy(octets, 0, string, pos, octets.length);
+ pos += octets.length;
}
+
+// assert pos == totalOctets;
+ return string;
}
-
- return bOut.toByteArray();
+ }
}
/**
* Create an OCTET-STRING object from a byte[]
* @param string the octets making up the octet string.
*/
- public BEROctetString(
- byte[] string)
+ public BEROctetString(byte[] string)
{
- this(string, DEFAULT_CHUNK_SIZE);
+ this(string, DEFAULT_SEGMENT_LIMIT);
}
/**
* Multiple {@link ASN1OctetString} data blocks are input,
* the result is <i>constructed form</i>.
*
- * @param octs an array of OCTET STRING to construct the BER OCTET STRING from.
+ * @param elements an array of OCTET STRING to construct the BER OCTET STRING from.
*/
- public BEROctetString(
- ASN1OctetString[] octs)
+ public BEROctetString(ASN1OctetString[] elements)
{
- this(octs, DEFAULT_CHUNK_SIZE);
+ this(elements, DEFAULT_SEGMENT_LIMIT);
}
/**
* Create an OCTET-STRING object from a byte[]
* @param string the octets making up the octet string.
- * @param chunkSize the number of octets stored in each DER encoded component OCTET STRING.
+ * @param segmentLimit the number of octets stored in each DER encoded component OCTET STRING.
*/
- public BEROctetString(
- byte[] string,
- int chunkSize)
+ public BEROctetString(byte[] string, int segmentLimit)
{
- this(string, null, chunkSize);
+ this(string, null, segmentLimit);
}
/**
* Multiple {@link ASN1OctetString} data blocks are input,
* the result is <i>constructed form</i>.
*
- * @param octs an array of OCTET STRING to construct the BER OCTET STRING from.
- * @param chunkSize the number of octets stored in each DER encoded component OCTET STRING.
+ * @param elements an array of OCTET STRING to construct the BER OCTET STRING from.
+ * @param segmentLimit the number of octets stored in each DER encoded component OCTET STRING.
*/
- public BEROctetString(
- ASN1OctetString[] octs,
- int chunkSize)
+ public BEROctetString(ASN1OctetString[] elements, int segmentLimit)
{
- this(toBytes(octs), octs, chunkSize);
+ this(flattenOctetStrings(elements), elements, segmentLimit);
}
- private BEROctetString(byte[] string, ASN1OctetString[] octs, int chunkSize)
+ private BEROctetString(byte[] string, ASN1OctetString[] elements, int segmentLimit)
{
super(string);
- this.octs = octs;
- this.chunkSize = chunkSize;
+ this.elements = elements;
+ this.segmentLimit = segmentLimit;
}
- /**
- * Return the OCTET STRINGs that make up this string.
- *
- * @return an Enumeration of the component OCTET STRINGs.
- */
- public Enumeration getObjects()
- {
- if (octs == null)
- {
- return new Enumeration()
- {
- int pos = 0;
-
- public boolean hasMoreElements()
- {
- return pos < string.length;
- }
-
- public Object nextElement()
- {
- if (pos < string.length)
- {
- int length = Math.min(string.length - pos, chunkSize);
- byte[] chunk = new byte[length];
- System.arraycopy(string, pos, chunk, 0, length);
- pos += length;
- return new DEROctetString(chunk);
- }
- throw new NoSuchElementException();
- }
- };
- }
-
- return new Enumeration()
- {
- int counter = 0;
-
- public boolean hasMoreElements()
- {
- return counter < octs.length;
- }
-
- public Object nextElement()
- {
- if (counter < octs.length)
- {
- return octs[counter++];
- }
- throw new NoSuchElementException();
- }
- };
- }
-
- boolean isConstructed()
+ boolean encodeConstructed()
{
return true;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
throws IOException
{
- int length = 0;
- for (Enumeration e = getObjects(); e.hasMoreElements();)
+ int totalLength = withTag ? 4 : 3;
+
+ if (null != elements)
{
- length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
+ for (int i = 0; i < elements.length; ++i)
+ {
+ totalLength += elements[i].encodedLength(true);
+ }
+ }
+ else
+ {
+ int fullSegments = string.length / segmentLimit;
+ totalLength += fullSegments * DEROctetString.encodedLength(true, segmentLimit);
+
+ int lastSegmentLength = string.length - (fullSegments * segmentLimit);
+ if (lastSegmentLength > 0)
+ {
+ totalLength += DEROctetString.encodedLength(true, lastSegmentLength);
+ }
}
- return 2 + length + 2;
+ return totalLength;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncodedIndef(withTag, BERTags.CONSTRUCTED | BERTags.OCTET_STRING, getObjects());
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
+ out.write(0x80);
- static BEROctetString fromSequence(ASN1Sequence seq)
- {
- int count = seq.size();
- ASN1OctetString[] v = new ASN1OctetString[count];
- for (int i = 0; i < count; ++i)
+ if (null != elements)
{
- v[i] = ASN1OctetString.getInstance(seq.getObjectAt(i));
+ out.writePrimitives(elements);
}
- return new BEROctetString(v);
+ else
+ {
+ int pos = 0;
+ while (pos < string.length)
+ {
+ int segmentLength = Math.min(string.length - pos, segmentLimit);
+ DEROctetString.encode(out, true, string, pos, segmentLength);
+ pos += segmentLength;
+ }
+ }
+
+ out.write(0x00);
+ out.write(0x00);
}
}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java
index 877563d..7ff6cab 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java
@@ -98,23 +98,32 @@
public void write(byte[] b, int off, int len) throws IOException
{
- while (len > 0)
+ int bufLen = _buf.length;
+ int available = bufLen - _off;
+ if (len < available)
{
- int numToCopy = Math.min(len, _buf.length - _off);
- System.arraycopy(b, off, _buf, _off, numToCopy);
-
- _off += numToCopy;
- if (_off < _buf.length)
- {
- break;
- }
-
- DEROctetString.encode(_derOut, true, _buf, 0, _buf.length);
- _off = 0;
-
- off += numToCopy;
- len -= numToCopy;
+ System.arraycopy(b, off, _buf, _off, len);
+ _off += len;
+ return;
}
+
+ int count = 0;
+ if (_off > 0)
+ {
+ System.arraycopy(b, off, _buf, _off, available);
+ count += available;
+ DEROctetString.encode(_derOut, true, _buf, 0, bufLen);
+ }
+
+ int remaining;
+ while ((remaining = (len - count)) >= bufLen)
+ {
+ DEROctetString.encode(_derOut, true, b, off + count, bufLen);
+ count += bufLen;
+ }
+
+ System.arraycopy(b, off + count, _buf, 0, remaining);
+ this._off = remaining;
}
public void close()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringParser.java
index 64ce07d..10d6bad 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringParser.java
@@ -8,6 +8,8 @@
/**
* A parser for indefinite-length OCTET STRINGs.
+ *
+ * @deprecated Check for 'ASN1OctetStringParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class BEROctetStringParser
@@ -40,7 +42,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new BEROctetString(Streams.readAll(getOctetStream()));
+ return parse(_parser);
}
/**
@@ -59,4 +61,9 @@
throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
}
}
+
+ static BEROctetString parse(ASN1StreamParser sp) throws IOException
+ {
+ return new BEROctetString(Streams.readAll(new ConstructedOctetStream(sp)));
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java
index e3770e4..ef999b3 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java
@@ -46,22 +46,42 @@
super(elements);
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int count = elements.length;
- int totalLength = 0;
+ int totalLength = withTag ? 4 : 3;
- for (int i = 0; i < count; ++i)
+ for (int i = 0, count = elements.length; i < count; ++i)
{
ASN1Primitive p = elements[i].toASN1Primitive();
- totalLength += p.encodedLength();
+ totalLength += p.encodedLength(true);
}
- return 2 + totalLength + 2;
+ return totalLength;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncodedIndef(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, elements);
+ out.writeEncodingIL(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE, elements);
+ }
+
+ ASN1BitString toASN1BitString()
+ {
+ return new BERBitString(getConstructedBitStrings());
+ }
+
+ ASN1External toASN1External()
+ {
+ // TODO There is currently no BERExternal class
+ return ((ASN1Sequence)toDLObject()).toASN1External();
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ return new BEROctetString(getConstructedOctetStrings());
+ }
+
+ ASN1Set toASN1Set()
+ {
+ return new BERSet(false, toArrayInternal());
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequenceParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequenceParser.java
index d2ce184..3a242fa 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequenceParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequenceParser.java
@@ -5,6 +5,8 @@
/**
* Parser for indefinite-length SEQUENCEs.
+ *
+ * @deprecated Check for 'ASN1SequenceParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class BERSequenceParser
@@ -38,7 +40,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new BERSequence(_parser.readVector());
+ return parse(_parser);
}
/**
@@ -57,4 +59,9 @@
throw new IllegalStateException(e.getMessage());
}
}
+
+ static BERSequence parse(ASN1StreamParser sp) throws IOException
+ {
+ return new BERSequence(sp.readVector());
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java
index fbc6fd1..e955ae6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java
@@ -61,22 +61,21 @@
super(isSorted, elements);
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int count = elements.length;
- int totalLength = 0;
+ int totalLength = withTag ? 4 : 3;
- for (int i = 0; i < count; ++i)
+ for (int i = 0, count = elements.length; i < count; ++i)
{
ASN1Primitive p = elements[i].toASN1Primitive();
- totalLength += p.encodedLength();
+ totalLength += p.encodedLength(true);
}
- return 2 + totalLength + 2;
+ return totalLength;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncodedIndef(withTag, BERTags.SET | BERTags.CONSTRUCTED, elements);
+ out.writeEncodingIL(withTag, BERTags.CONSTRUCTED | BERTags.SET, elements);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSetParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSetParser.java
index e66b756..4f04d58 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSetParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSetParser.java
@@ -5,6 +5,8 @@
/**
* Parser for indefinite-length SETs.
+ *
+ * @deprecated Check for 'ASN1SetParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class BERSetParser
@@ -38,7 +40,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new BERSet(_parser.readVector());
+ return parse(_parser);
}
/**
@@ -57,4 +59,9 @@
throw new ASN1ParsingException(e.getMessage(), e);
}
}
-}
\ No newline at end of file
+
+ static BERSet parse(ASN1StreamParser sp) throws IOException
+ {
+ return new BERSet(sp.readVector());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java
index 3c301b7..2911664 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java
@@ -2,7 +2,6 @@
package com.android.internal.org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* BER TaggedObject - in ASN.1 notation this is any object preceded by
@@ -17,124 +16,96 @@
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public BERTaggedObject(
- int tagNo,
- ASN1Encodable obj)
+ public BERTaggedObject(int tagNo, ASN1Encodable obj)
{
super(true, tagNo, obj);
}
+ public BERTaggedObject(int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ super(true, tagClass, tagNo, obj);
+ }
+
/**
* @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public BERTaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
+ public BERTaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
{
super(explicit, tagNo, obj);
}
- /**
- * create an implicitly tagged object that contains a zero
- * length sequence.
- */
- public BERTaggedObject(
- int tagNo)
+ public BERTaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
{
- super(false, tagNo, new BERSequence());
+ super(explicit, tagClass, tagNo, obj);
}
- boolean isConstructed()
+ BERTaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
{
- return explicit || obj.toASN1Primitive().isConstructed();
+ super(explicitness, tagClass, tagNo, obj);
}
- int encodedLength()
- throws IOException
+ boolean encodeConstructed()
+ {
+ return isExplicit() || obj.toASN1Primitive().encodeConstructed();
+ }
+
+ int encodedLength(boolean withTag) throws IOException
{
ASN1Primitive primitive = obj.toASN1Primitive();
- int length = primitive.encodedLength();
+ boolean explicit = isExplicit();
+
+ int length = primitive.encodedLength(explicit);
if (explicit)
{
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ length += 3;
}
- else
- {
- // header length already in calculation
- length = length - 1;
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ length += withTag ? ASN1OutputStream.getLengthOfIdentifier(tagNo) : 0;
+
+ return length;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeTag(withTag, BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
- out.write(0x80);
+// assert out.getClass().isAssignableFrom(ASN1OutputStream.class);
- if (!explicit)
+ ASN1Primitive primitive = obj.toASN1Primitive();
+ boolean explicit = isExplicit();
+
+ if (withTag)
{
- Enumeration e;
- if (obj instanceof ASN1OctetString)
+ int flags = tagClass;
+ if (explicit || primitive.encodeConstructed())
{
- if (obj instanceof BEROctetString)
- {
- e = ((BEROctetString)obj).getObjects();
- }
- else
- {
- ASN1OctetString octs = (ASN1OctetString)obj;
- BEROctetString berO = new BEROctetString(octs.getOctets());
- e = berO.getObjects();
- }
- }
- else if (obj instanceof ASN1Sequence)
- {
- e = ((ASN1Sequence)obj).getObjects();
- }
- else if (obj instanceof ASN1Set)
- {
- e = ((ASN1Set)obj).getObjects();
- }
- else
- {
- throw new ASN1Exception("not implemented: " + obj.getClass().getName());
+ flags |= BERTags.CONSTRUCTED;
}
- out.writeElements(e);
+ out.writeIdentifier(true, flags, tagNo);
+ }
+
+ if (explicit)
+ {
+ out.write(0x80);
+ primitive.encode(out, true);
+ out.write(0x00);
+ out.write(0x00);
}
else
{
- out.writePrimitive(obj.toASN1Primitive(), true);
+ primitive.encode(out, false);
}
+ }
- out.write(0x00);
- out.write(0x00);
+ ASN1Sequence rebuildConstructed(ASN1Primitive primitive)
+ {
+ return new BERSequence(primitive);
+ }
-// ASN1Primitive primitive = obj.toASN1Primitive();
-//
-// int flags = BERTags.TAGGED;
-// if (explicit || primitive.isConstructed())
-// {
-// flags |= BERTags.CONSTRUCTED;
-// }
-//
-// out.writeTag(withTag, flags, tagNo);
-//
-// if (explicit)
-// {
-// out.write(0x80);
-// out.writePrimitive(obj.toASN1Primitive(), true);
-// out.write(0x00);
-// out.write(0x00);
-// }
-// else
-// {
-// out.writePrimitive(obj.toASN1Primitive(), false);
-// }
+ ASN1TaggedObject replaceTag(int tagClass, int tagNo)
+ {
+ return new BERTaggedObject(explicitness, tagClass, tagNo, obj);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObjectParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObjectParser.java
index 0b8ddfd..64b3313 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObjectParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObjectParser.java
@@ -5,68 +5,49 @@
/**
* Parser for indefinite-length tagged objects.
- * @hide This class is not part of the Android public SDK API
*/
-public class BERTaggedObjectParser
+class BERTaggedObjectParser
implements ASN1TaggedObjectParser
{
- private boolean _constructed;
- private int _tagNumber;
- private ASN1StreamParser _parser;
+ final int _tagClass;
+ final int _tagNo;
+ final ASN1StreamParser _parser;
- BERTaggedObjectParser(
- boolean constructed,
- int tagNumber,
- ASN1StreamParser parser)
+ BERTaggedObjectParser(int tagClass, int tagNo, ASN1StreamParser parser)
{
- _constructed = constructed;
- _tagNumber = tagNumber;
+ _tagClass = tagClass;
+ _tagNo = tagNo;
_parser = parser;
}
- /**
- * Return true if this tagged object is marked as constructed.
- *
- * @return true if constructed, false otherwise.
- */
- public boolean isConstructed()
+ public int getTagClass()
{
- return _constructed;
+ return _tagClass;
}
- /**
- * Return the tag number associated with this object.
- *
- * @return the tag number.
- */
public int getTagNo()
{
- return _tagNumber;
+ return _tagNo;
}
- /**
- * Return an object parser for the contents of this tagged object.
- *
- * @param tag the actual tag number of the object (needed if implicit).
- * @param isExplicit true if the contained object was explicitly tagged, false if implicit.
- * @return an ASN.1 encodable object parser.
- * @throws IOException if there is an issue building the object parser from the stream.
- */
- public ASN1Encodable getObjectParser(
- int tag,
- boolean isExplicit)
- throws IOException
+ public boolean hasContextTag()
{
- if (isExplicit)
- {
- if (!_constructed)
- {
- throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
- }
- return _parser.readObject();
- }
+ return this._tagClass == BERTags.CONTEXT_SPECIFIC;
+ }
- return _parser.readImplicit(_constructed, tag);
+ public boolean hasContextTag(int tagNo)
+ {
+ return this._tagClass == BERTags.CONTEXT_SPECIFIC && this._tagNo == tagNo;
+ }
+
+ public boolean hasTag(int tagClass, int tagNo)
+ {
+ return this._tagClass == tagClass && this._tagNo == tagNo;
+ }
+
+ public boolean hasTagClass(int tagClass)
+ {
+ return this._tagClass == tagClass;
}
/**
@@ -78,7 +59,32 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return _parser.readTaggedObject(_constructed, _tagNumber);
+ return _parser.loadTaggedIL(_tagClass, _tagNo);
+ }
+
+ public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ if (declaredExplicit)
+ {
+ return _parser.parseObject(baseTagNo);
+ }
+
+ return _parser.parseImplicitConstructedIL(baseTagNo);
+ }
+
+ public ASN1Encodable parseExplicitBaseObject() throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException
+ {
+ return _parser.parseTaggedObject();
+ }
+
+ public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException
+ {
+ return new BERTaggedObjectParser(baseTagClass, baseTagNo, _parser);
}
/**
@@ -90,7 +96,7 @@
{
try
{
- return this.getLoadedObject();
+ return getLoadedObject();
}
catch (IOException e)
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTags.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTags.java
index 87649f6..3c81b2a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTags.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTags.java
@@ -6,20 +6,26 @@
*/
public interface BERTags
{
+ // 0x00: Reserved for use by the encoding rules
public static final int BOOLEAN = 0x01;
public static final int INTEGER = 0x02;
public static final int BIT_STRING = 0x03;
public static final int OCTET_STRING = 0x04;
public static final int NULL = 0x05;
public static final int OBJECT_IDENTIFIER = 0x06;
+ public static final int OBJECT_DESCRIPTOR = 0x07;
public static final int EXTERNAL = 0x08;
+ public static final int REAL = 0x09;
public static final int ENUMERATED = 0x0a; // decimal 10
+ public static final int EMBEDDED_PDV = 0x0b; // decimal 11
+ public static final int UTF8_STRING = 0x0c; // decimal 12
+ public static final int RELATIVE_OID = 0x0d; // decimal 13
+ public static final int TIME = 0x0e;
+ // 0x0f: Reserved for future editions of this Recommendation | International Standard
public static final int SEQUENCE = 0x10; // decimal 16
public static final int SEQUENCE_OF = 0x10; // for completeness - used to model a SEQUENCE of the same type.
public static final int SET = 0x11; // decimal 17
public static final int SET_OF = 0x11; // for completeness - used to model a SET of the same type.
-
-
public static final int NUMERIC_STRING = 0x12; // decimal 18
public static final int PRINTABLE_STRING = 0x13; // decimal 19
public static final int T61_STRING = 0x14; // decimal 20
@@ -31,10 +37,23 @@
public static final int VISIBLE_STRING = 0x1a; // decimal 26
public static final int GENERAL_STRING = 0x1b; // decimal 27
public static final int UNIVERSAL_STRING = 0x1c; // decimal 28
+ public static final int UNRESTRICTED_STRING = 0x1d; // decimal 29
public static final int BMP_STRING = 0x1e; // decimal 30
- public static final int UTF8_STRING = 0x0c; // decimal 12
-
+ public static final int DATE = 0x1f;
+ public static final int TIME_OF_DAY = 0x20;
+ public static final int DATE_TIME = 0x21;
+ public static final int DURATION = 0x22;
+ public static final int OBJECT_IDENTIFIER_IRI = 0x23;
+ public static final int RELATIVE_OID_IRI = 0x24;
+ // 0x25..: Reserved for addenda to this Recommendation | International Standard
+
public static final int CONSTRUCTED = 0x20; // decimal 32
+
+ public static final int UNIVERSAL = 0x00; // decimal 32
public static final int APPLICATION = 0x40; // decimal 64
- public static final int TAGGED = 0x80; // decimal 128
+ public static final int TAGGED = 0x80; // decimal 128 - maybe should deprecate this.
+ public static final int CONTEXT_SPECIFIC = 0x80; // decimal 128
+ public static final int PRIVATE = 0xC0; // decimal 192
+
+ public static final int FLAGS = 0xE0;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ConstructedBitStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ConstructedBitStream.java
new file mode 100644
index 0000000..20b9c68
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ConstructedBitStream.java
@@ -0,0 +1,146 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class ConstructedBitStream
+ extends InputStream
+{
+ private final ASN1StreamParser _parser;
+ private final boolean _octetAligned;
+
+ private boolean _first = true;
+ private int _padBits = 0;
+
+ private ASN1BitStringParser _currentParser;
+ private InputStream _currentStream;
+
+ ConstructedBitStream(ASN1StreamParser parser, boolean octetAligned)
+ {
+ _parser = parser;
+ _octetAligned = octetAligned;
+ }
+
+ int getPadBits()
+ {
+ return _padBits;
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException
+ {
+ if (_currentStream == null)
+ {
+ if (!_first)
+ {
+ return -1;
+ }
+
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ return -1;
+ }
+
+ _first = false;
+ _currentStream = _currentParser.getBitStream();
+
+ }
+
+ int totalRead = 0;
+
+ for (;;)
+ {
+ int numRead = _currentStream.read(b, off + totalRead, len - totalRead);
+
+ if (numRead >= 0)
+ {
+ totalRead += numRead;
+
+ if (totalRead == len)
+ {
+ return totalRead;
+ }
+ }
+ else
+ {
+ _padBits = _currentParser.getPadBits();
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ _currentStream = null;
+ return totalRead < 1 ? -1 : totalRead;
+ }
+
+ _currentStream = _currentParser.getBitStream();
+ }
+ }
+ }
+
+ public int read()
+ throws IOException
+ {
+ if (_currentStream == null)
+ {
+ if (!_first)
+ {
+ return -1;
+ }
+
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ return -1;
+ }
+
+ _first = false;
+ _currentStream = _currentParser.getBitStream();
+ }
+
+ for (;;)
+ {
+ int b = _currentStream.read();
+
+ if (b >= 0)
+ {
+ return b;
+ }
+
+ _padBits = _currentParser.getPadBits();
+ _currentParser = getNextParser();
+ if (_currentParser == null)
+ {
+ _currentStream = null;
+ return -1;
+ }
+
+ _currentStream = _currentParser.getBitStream();
+ }
+ }
+
+ private ASN1BitStringParser getNextParser() throws IOException
+ {
+ ASN1Encodable asn1Obj = _parser.readObject();
+ if (asn1Obj == null)
+ {
+ if (_octetAligned && _padBits != 0)
+ {
+ throw new IOException("expected octet-aligned bitstring, but found padBits: " + _padBits);
+ }
+
+ return null;
+ }
+
+ if (asn1Obj instanceof ASN1BitStringParser)
+ {
+ if (_padBits != 0)
+ {
+ throw new IOException("only the last nested bitstring can have padding");
+ }
+
+ return (ASN1BitStringParser)asn1Obj;
+ }
+
+ throw new IOException("unknown object encountered: " + asn1Obj.getClass());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERApplicationSpecific.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERApplicationSpecific.java
deleted file mode 100644
index f3e4589..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERApplicationSpecific.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * A DER encoding version of an application specific object.
- * @hide This class is not part of the Android public SDK API
- */
-public class DERApplicationSpecific
- extends ASN1ApplicationSpecific
-{
- DERApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- super(isConstructed, tag, octets);
- }
-
- /**
- * Create an application specific object from the passed in data. This will assume
- * the data does not represent a constructed object.
- *
- * @param tag the tag number for this object.
- * @param octets the encoding of the object's body.
- */
- public DERApplicationSpecific(
- int tag,
- byte[] octets)
- {
- this(false, tag, octets);
- }
-
- /**
- * Create an application specific object with a tagging of explicit/constructed.
- *
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DERApplicationSpecific(
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- this(true, tag, object);
- }
-
- /**
- * Create an application specific object with the tagging style given by the value of constructed.
- *
- * @param constructed true if the object is constructed.
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DERApplicationSpecific(
- boolean constructed,
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
- }
-
- private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
- throws IOException
- {
- byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.DER);
-
- if (explicit)
- {
- return data;
- }
- else
- {
- int lenBytes = getLengthOfHeader(data);
- byte[] tmp = new byte[data.length - lenBytes];
- System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
- return tmp;
- }
- }
-
- /**
- * Create an application specific object which is marked as constructed
- *
- * @param tagNo the tag number for this object.
- * @param vec the objects making up the application specific object.
- */
- public DERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
- {
- super(true, tagNo, getEncodedVector(vec));
- }
-
- private static byte[] getEncodedVector(ASN1EncodableVector vec)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != vec.size(); i++)
- {
- try
- {
- bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DER));
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("malformed object: " + e, e);
- }
- }
- return bOut.toByteArray();
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncoded(withTag, flags, tag, octets);
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java
index 9ffb1be..d55b353 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java
@@ -1,10 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-
/**
* DER BMPString object encodes BMP (<i>Basic Multilingual Plane</i>) subset
* (aka UCS-2) of UNICODE (ISO 10646) characters in codepoints 0 to 65535.
@@ -15,203 +11,28 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERBMPString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1BMPString
{
- private final char[] string;
-
- /**
- * Return a BMP String from the given object.
- *
- * @param obj the object we want converted.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERBMPString instance, or null.
- */
- public static DERBMPString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERBMPString)
- {
- return (DERBMPString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERBMPString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a BMP String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERBMPString instance.
- */
- public static DERBMPString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERBMPString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERBMPString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - byte encoded string.
- * @param string the encoded BMP STRING to wrap.
- */
- DERBMPString(
- byte[] string)
- {
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
-
- int byteLen = string.length;
- if (0 != (byteLen & 1))
- {
- throw new IllegalArgumentException("malformed BMPString encoding encountered");
- }
-
- int charLen = byteLen / 2;
- char[] cs = new char[charLen];
-
- for (int i = 0; i != charLen; i++)
- {
- cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
- }
-
- this.string = cs;
- }
-
- DERBMPString(char[] string)
- {
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
-
- this.string = string;
- }
-
/**
* Basic constructor
* @param string a String to wrap as a BMP STRING.
*/
- public DERBMPString(
- String string)
+ public DERBMPString(String string)
{
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
-
- this.string = string.toCharArray();
+ super(string);
}
- public String getString()
+ /**
+ * Basic constructor - byte encoded string.
+ * @param contents the encoded BMP STRING to wrap.
+ */
+ DERBMPString(byte[] contents)
{
- return new String(string);
+ super(contents);
}
- public String toString()
+ DERBMPString(char[] string)
{
- return getString();
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- protected boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERBMPString))
- {
- return false;
- }
-
- DERBMPString s = (DERBMPString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length * 2) + (string.length * 2);
- }
-
- void encode(
- ASN1OutputStream out, boolean withTag)
- throws IOException
- {
- int count = string.length;
- if (withTag)
- {
- out.write(BERTags.BMP_STRING);
- }
- out.writeLength(count * 2);
-
- byte[] buf = new byte[8];
-
- int i = 0, limit = count & -4;
- while (i < limit)
- {
- char c0 = string[i], c1 = string[i + 1], c2 = string[i + 2], c3 = string[i + 3];
- i += 4;
-
- buf[0] = (byte)(c0 >> 8);
- buf[1] = (byte)c0;
- buf[2] = (byte)(c1 >> 8);
- buf[3] = (byte)c1;
- buf[4] = (byte)(c2 >> 8);
- buf[5] = (byte)c2;
- buf[6] = (byte)(c3 >> 8);
- buf[7] = (byte)c3;
-
- out.write(buf, 0, 8);
- }
- if (i < count)
- {
- int bufPos = 0;
- do
- {
- char c0 = string[i];
- i += 1;
-
- buf[bufPos++] = (byte)(c0 >> 8);
- buf[bufPos++] = (byte)c0;
- }
- while (i < count);
-
- out.write(buf, 0, bufPos);
- }
+ super(string);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java
index 40d010a..983d862 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java
@@ -10,123 +10,69 @@
public class DERBitString
extends ASN1BitString
{
- /**
- * return a Bit String from the passed in object
- *
- * @param obj a DERBitString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERBitString instance, or null.
- */
- public static DERBitString getInstance(
- Object obj)
+ public static DERBitString convert(ASN1BitString bitString)
{
- if (obj == null || obj instanceof DERBitString)
- {
- return (DERBitString)obj;
- }
- if (obj instanceof DLBitString)
- {
- return new DERBitString(((DLBitString)obj).data, ((DLBitString)obj).padBits);
- }
- if (obj instanceof byte[])
- {
- try
- {
- return (DERBitString)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());
+ return (DERBitString)bitString.toDERObject();
}
- /**
- * return a Bit String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERBitString instance, or null.
- */
- public static DERBitString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERBitString)
- {
- return getInstance(o);
- }
- else
- {
- return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- protected DERBitString(byte data, int padBits)
- {
- super(data, padBits);
- }
-
- /**
- * @param data the octets making up the bit string.
- * @param padBits the number of extra bits at the end of the string.
- */
- public DERBitString(
- byte[] data,
- int padBits)
- {
- super(data, padBits);
- }
-
- public DERBitString(
- byte[] data)
+ public DERBitString(byte[] data)
{
this(data, 0);
}
- public DERBitString(
- int value)
+ public DERBitString(byte data, int padBits)
{
+ super(data, padBits);
+ }
+
+ public DERBitString(byte[] data, int padBits)
+ {
+ super(data, padBits);
+ }
+
+ public DERBitString(int value)
+ {
+ // TODO[asn1] Unify in single allocation of 'contents'
super(getBytes(value), getPadBits(value));
}
- public DERBitString(
- ASN1Encodable obj)
- throws IOException
+ public DERBitString(ASN1Encodable obj) throws IOException
{
+ // TODO[asn1] Unify in single allocation of 'contents'
super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
}
- boolean isConstructed()
+ DERBitString(byte[] contents, boolean check)
+ {
+ super(contents, check);
+ }
+
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- int len = data.length;
- if (0 == len
- || 0 == padBits
- || (data[len - 1] == (byte)(data[len - 1] & (0xFF << padBits))))
+ int padBits = contents[0] & 0xFF;
+ int length = contents.length;
+ int last = length - 1;
+
+ byte lastOctet = contents[last];
+ byte lastOctetDER = (byte)(contents[last] & (0xFF << padBits));
+
+ if (lastOctet == lastOctetDER)
{
- out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, contents);
}
else
{
- byte der = (byte)(data[len - 1] & (0xFF << padBits));
- out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data, 0, len - 1, der);
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, contents, 0, last, lastOctetDER);
}
}
@@ -140,21 +86,8 @@
return this;
}
- static DERBitString fromOctetString(byte[] bytes)
+ static DERBitString fromOctetString(ASN1OctetString octetString)
{
- if (bytes.length < 1)
- {
- throw new IllegalArgumentException("truncated BIT STRING detected");
- }
-
- int padBits = bytes[0];
- byte[] data = new byte[bytes.length - 1];
-
- if (data.length != 0)
- {
- System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
- }
-
- return new DERBitString(data, padBits);
+ return new DERBitString(octetString.getOctets(), true);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREncodableVector.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREncodableVector.java
deleted file mode 100644
index 2c53b69..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREncodableVector.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-/**
- * a general class for building up a vector of DER encodable objects -
- * this will eventually be superseded by ASN1EncodableVector so you should
- * use that class in preference.
- * @hide This class is not part of the Android public SDK API
- */
-public class DEREncodableVector
- extends ASN1EncodableVector
-{
- /**
- * @deprecated use ASN1EncodableVector instead.
- */
- public DEREncodableVector()
- {
-
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREnumerated.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREnumerated.java
deleted file mode 100644
index 6069d1e..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREnumerated.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-import java.math.BigInteger;
-
-/**
- * @deprecated Use ASN1Enumerated instead of this.
- * @hide This class is not part of the Android public SDK API
- */
-public class DEREnumerated
- extends ASN1Enumerated
-{
- /**
- * @param bytes the value of this enumerated as an encoded BigInteger (signed).
- * @deprecated use ASN1Enumerated
- */
- DEREnumerated(byte[] bytes)
- {
- super(bytes);
- }
-
- /**
- * @param value the value of this enumerated.
- * @deprecated use ASN1Enumerated
- */
- public DEREnumerated(BigInteger value)
- {
- super(value);
- }
-
- /**
- * @param value the value of this enumerated.
- * @deprecated use ASN1Enumerated
- */
- public DEREnumerated(int value)
- {
- super(value);
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java
index da29a77..d7614a9 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java
@@ -1,9 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
/**
* Class representing the DER-type External
* @hide This class is not part of the Android public SDK API
@@ -21,11 +18,30 @@
* <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
* </ul>
*
- * @throws IllegalArgumentException if input size is wrong, or
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ *
+ * @deprecated Use {@link DERExternal#DERExternal(DERSequence)} instead.
*/
public DERExternal(ASN1EncodableVector vector)
{
- super(vector);
+ this(DERFactory.createSequence(vector));
+ }
+
+ /**
+ * Construct a DER EXTERNAL object, the input sequence must have exactly two elements on it.
+ * <p>
+ * Acceptable input formats are:
+ * <ul>
+ * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
+ * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
+ * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
+ * </ul>
+ *
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ */
+ public DERExternal(DERSequence sequence)
+ {
+ super(sequence);
}
/**
@@ -36,9 +52,10 @@
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param externalData The external data in its encoded form.
*/
- public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
{
- this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ super(directReference, indirectReference, dataValueDescriptor, externalData);
}
/**
@@ -50,11 +67,33 @@
* @param encoding The encoding to be used for the external data
* @param externalData The external data
*/
- public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
{
super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
}
+ ASN1Sequence buildSequence()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+ if (directReference != null)
+ {
+ v.add(directReference);
+ }
+ if (indirectReference != null)
+ {
+ v.add(indirectReference);
+ }
+ if (dataValueDescriptor != null)
+ {
+ v.add(dataValueDescriptor.toDERObject());
+ }
+
+ v.add(new DERTaggedObject(0 == encoding, encoding, externalContent));
+
+ return new DERSequence(v);
+ }
+
ASN1Primitive toDERObject()
{
return this;
@@ -64,34 +103,4 @@
{
return this;
}
-
- int encodedLength()
- throws IOException
- {
- return this.getEncoded().length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- if (directReference != null)
- {
- baos.write(directReference.getEncoded(ASN1Encoding.DER));
- }
- if (indirectReference != null)
- {
- baos.write(indirectReference.getEncoded(ASN1Encoding.DER));
- }
- if (dataValueDescriptor != null)
- {
- baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DER));
- }
- DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
- baos.write(obj.getEncoded(ASN1Encoding.DER));
-
- out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
- }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternalParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternalParser.java
index c400ab4..aed5dd8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternalParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternalParser.java
@@ -8,7 +8,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERExternalParser
- implements ASN1Encodable, InMemoryRepresentable
+ implements ASN1ExternalParser
{
private ASN1StreamParser _parser;
@@ -37,14 +37,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- try
- {
- return new DLExternal(_parser.readVector());
- }
- catch (IllegalArgumentException e)
- {
- throw new ASN1Exception(e.getMessage(), e);
- }
+ return parse(_parser);
}
/**
@@ -67,4 +60,16 @@
throw new ASN1ParsingException("unable to get DER object", ioe);
}
}
+
+ static DLExternal parse(ASN1StreamParser sp) throws IOException
+ {
+ try
+ {
+ return new DLExternal(new DLSequence(sp.readVector()));
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception(e.getMessage(), e);
+ }
+ }
}
\ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java
index e4dc5f6..291856e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java
@@ -3,10 +3,10 @@
class DERFactory
{
- static final ASN1Sequence EMPTY_SEQUENCE = new DERSequence();
- static final ASN1Set EMPTY_SET = new DERSet();
+ static final DERSequence EMPTY_SEQUENCE = new DERSequence();
+ static final DERSet EMPTY_SET = new DERSet();
- static ASN1Sequence createSequence(ASN1EncodableVector v)
+ static DERSequence createSequence(ASN1EncodableVector v)
{
if (v.size() < 1)
{
@@ -16,7 +16,7 @@
return new DERSequence(v);
}
- static ASN1Set createSet(ASN1EncodableVector v)
+ static DERSet createSet(ASN1EncodableVector v)
{
if (v.size() < 1)
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java
index 660923d..628ac10 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java
@@ -1,11 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-import com.android.internal.org.bouncycastle.util.Strings;
-
/**
* ASN.1 GENERAL-STRING data type.
* <p>
@@ -15,136 +10,20 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERGeneralString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1GeneralString
{
- private final byte[] string;
-
- /**
- * Return a GeneralString from the given object.
- *
- * @param obj the object we want converted.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERBMPString instance, or null.
- */
- public static DERGeneralString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERGeneralString)
- {
- return (DERGeneralString) obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERGeneralString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: "
- + obj.getClass().getName());
- }
-
- /**
- * Return a GeneralString from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERGeneralString instance.
- */
- public static DERGeneralString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERGeneralString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERGeneralString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- DERGeneralString(byte[] string)
- {
- this.string = string;
- }
-
/**
* Construct a GeneralString from the passed in String.
*
* @param string the string to be contained in this object.
*/
- public DERGeneralString(String string)
+ public DERGeneralString(String string)
{
- this.string = Strings.toByteArray(string);
+ super(string);
}
- /**
- * Return a Java String representation of our contained String.
- *
- * @return a Java String representing our contents.
- */
- public String getString()
+ DERGeneralString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- /**
- * Return a byte array representation of our contained String.
- *
- * @return a byte array representing our contents.
- */
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.GENERAL_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(ASN1Primitive o)
- {
- if (!(o instanceof DERGeneralString))
- {
- return false;
- }
- DERGeneralString s = (DERGeneralString)o;
-
- return Arrays.areEqual(string, s.string);
+ super(contents, clone);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java
index 448f169..b78c51d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java
@@ -44,39 +44,39 @@
private byte[] getDERTime()
{
- if (time[time.length - 1] == 'Z')
+ if (contents[contents.length - 1] == 'Z')
{
if (!hasMinutes())
{
- byte[] derTime = new byte[time.length + 4];
+ byte[] derTime = new byte[contents.length + 4];
- System.arraycopy(time, 0, derTime, 0, time.length - 1);
- System.arraycopy(Strings.toByteArray("0000Z"), 0, derTime, time.length - 1, 5);
+ System.arraycopy(contents, 0, derTime, 0, contents.length - 1);
+ System.arraycopy(Strings.toByteArray("0000Z"), 0, derTime, contents.length - 1, 5);
return derTime;
}
else if (!hasSeconds())
{
- byte[] derTime = new byte[time.length + 2];
+ byte[] derTime = new byte[contents.length + 2];
- System.arraycopy(time, 0, derTime, 0, time.length - 1);
- System.arraycopy(Strings.toByteArray("00Z"), 0, derTime, time.length - 1, 3);
+ System.arraycopy(contents, 0, derTime, 0, contents.length - 1);
+ System.arraycopy(Strings.toByteArray("00Z"), 0, derTime, contents.length - 1, 3);
return derTime;
}
else if (hasFractionalSeconds())
{
- int ind = time.length - 2;
- while (ind > 0 && time[ind] == '0')
+ int ind = contents.length - 2;
+ while (ind > 0 && contents[ind] == '0')
{
ind--;
}
- if (time[ind] == '.')
+ if (contents[ind] == '.')
{
byte[] derTime = new byte[ind + 1];
- System.arraycopy(time, 0, derTime, 0, ind);
+ System.arraycopy(contents, 0, derTime, 0, ind);
derTime[ind] = (byte)'Z';
return derTime;
@@ -85,7 +85,7 @@
{
byte[] derTime = new byte[ind + 2];
- System.arraycopy(time, 0, derTime, 0, ind + 1);
+ System.arraycopy(contents, 0, derTime, 0, ind + 1);
derTime[ind + 1] = (byte)'Z';
return derTime;
@@ -93,25 +93,23 @@
}
else
{
- return time;
+ return contents;
}
}
else
{
- return time; // TODO: is there a better way?
+ return contents; // TODO: is there a better way?
}
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- int length = getDERTime().length;
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getDERTime().length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, getDERTime());
+ out.writeEncodingDL(withTag, BERTags.GENERALIZED_TIME, getDERTime());
}
ASN1Primitive toDERObject()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java
index 779c899..acdc382 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java
@@ -1,126 +1,19 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-import com.android.internal.org.bouncycastle.util.Strings;
-
/**
* @hide This class is not part of the Android public SDK API
*/
public class DERGraphicString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1GraphicString
{
- private final byte[] string;
-
- /**
- * return a Graphic String from the passed in object
- *
- * @param obj a DERGraphicString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERGraphicString instance, or null.
- */
- public static DERGraphicString getInstance(
- Object obj)
+ public DERGraphicString(byte[] octets)
{
- if (obj == null || obj instanceof DERGraphicString)
- {
- return (DERGraphicString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERGraphicString)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());
+ this(octets, true);
}
- /**
- * return a Graphic String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERGraphicString instance, or null.
- */
- public static DERGraphicString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ DERGraphicString(byte[] contents, boolean clone)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERGraphicString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERGraphicString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * basic constructor - with bytes.
- * @param string the byte encoding of the characters making up the string.
- */
- public DERGraphicString(
- byte[] string)
- {
- this.string = Arrays.clone(string);
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.GRAPHIC_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERGraphicString))
- {
- return false;
- }
-
- DERGraphicString s = (DERGraphicString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- public String getString()
- {
- return Strings.fromByteArray(string);
+ super(contents, clone);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java
index 7cdb97b..4517496 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java
@@ -1,11 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-import com.android.internal.org.bouncycastle.util.Strings;
-
/**
* DER IA5String object - this is a ISO 646 (ASCII) string encoding code points 0 to 127.
* <p>
@@ -14,83 +9,13 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERIA5String
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1IA5String
{
- private final byte[] string;
-
- /**
- * Return an IA5 string from the passed in object
- *
- * @param obj a DERIA5String or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERIA5String instance, or null.
- */
- public static DERIA5String getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERIA5String)
- {
- return (DERIA5String)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERIA5String)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return an IA5 String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERIA5String instance, or null.
- */
- public static DERIA5String getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERIA5String)
- {
- return getInstance(o);
- }
- else
- {
- return new DERIA5String(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - with bytes.
- * @param string the byte encoding of the characters making up the string.
- */
- DERIA5String(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor - without validation.
* @param string the base string to use..
*/
- public DERIA5String(
- String string)
+ public DERIA5String(String string)
{
this(string, false);
}
@@ -103,90 +28,13 @@
* @throws IllegalArgumentException if validate is true and the string
* contains characters that should not be in an IA5String.
*/
- public DERIA5String(
- String string,
- boolean validate)
+ public DERIA5String(String string, boolean validate)
{
- if (string == null)
- {
- throw new NullPointerException("'string' cannot be null");
- }
- if (validate && !isIA5String(string))
- {
- throw new IllegalArgumentException("'string' contains illegal characters");
- }
-
- this.string = Strings.toByteArray(string);
+ super(string, validate);
}
- public String getString()
+ DERIA5String(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.IA5_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERIA5String))
- {
- return false;
- }
-
- DERIA5String s = (DERIA5String)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- /**
- * return true if the passed in String can be represented without
- * loss as an IA5String, false otherwise.
- *
- * @param str the string to check.
- * @return true if character set in IA5String set, false otherwise.
- */
- public static boolean isIA5String(
- String str)
- {
- for (int i = str.length() - 1; i >= 0; i--)
- {
- char ch = str.charAt(i);
-
- if (ch > 0x007f)
- {
- return false;
- }
- }
-
- return true;
+ super(contents, clone);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERInteger.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERInteger.java
deleted file mode 100644
index bc7d548..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERInteger.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-import java.math.BigInteger;
-
-/**
- * @deprecated Use ASN1Integer instead of this,
- * @hide This class is not part of the Android public SDK API
- */
-public class DERInteger
- extends ASN1Integer
-{
- /**
- * Constructor from a byte array containing a signed representation of the number.
- *
- * @param bytes a byte array containing the signed number.A copy is made of the byte array.
- */
- public DERInteger(byte[] bytes)
- {
- super(bytes, true);
- }
-
- public DERInteger(BigInteger value)
- {
- super(value);
- }
-
- public DERInteger(long value)
- {
- super(value);
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java
index e86c783..c6eaa91 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java
@@ -20,18 +20,18 @@
{
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 2;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, 0);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.NULL, zeroBytes);
+ out.writeEncodingDL(withTag, BERTags.NULL, zeroBytes);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java
index a573f31..6c39623 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java
@@ -1,11 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-import com.android.internal.org.bouncycastle.util.Strings;
-
/**
* DER NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
* ASN.1 NUMERIC-STRING object.
@@ -18,81 +13,12 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERNumericString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1NumericString
{
- private final byte[] string;
-
- /**
- * Return a Numeric string from the passed in object
- *
- * @param obj a DERNumericString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERNumericString instance, or null
- */
- public static DERNumericString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERNumericString)
- {
- return (DERNumericString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERNumericString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return an Numeric String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERNumericString instance, or null.
- */
- public static DERNumericString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERNumericString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERNumericString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - with bytes.
- */
- DERNumericString(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor - without validation..
*/
- public DERNumericString(
- String string)
+ public DERNumericString(String string)
{
this(string, false);
}
@@ -105,92 +31,13 @@
* @throws IllegalArgumentException if validate is true and the string
* contains characters that should not be in a NumericString.
*/
- public DERNumericString(
- String string,
- boolean validate)
+ public DERNumericString(String string, boolean validate)
{
- if (validate && !isNumericString(string))
- {
- throw new IllegalArgumentException("string contains illegal characters");
- }
-
- this.string = Strings.toByteArray(string);
+ super(string, validate);
}
- public String getString()
+ DERNumericString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.NUMERIC_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERNumericString))
- {
- return false;
- }
-
- DERNumericString s = (DERNumericString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- /**
- * Return true if the string can be represented as a NumericString ('0'..'9', ' ')
- *
- * @param str string to validate.
- * @return true if numeric, fale otherwise.
- */
- public static boolean isNumericString(
- String str)
- {
- for (int i = str.length() - 1; i >= 0; i--)
- {
- char ch = str.charAt(i);
-
- if (ch > 0x007f)
- {
- return false;
- }
-
- if (('0' <= ch && ch <= '9') || ch == ' ')
- {
- continue;
- }
-
- return false;
- }
-
- return true;
+ super(contents, clone);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERObjectIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERObjectIdentifier.java
deleted file mode 100644
index 1f497c5..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERObjectIdentifier.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-/**
- *
- * @deprecated Use ASN1ObjectIdentifier instead of this,
- * @hide This class is not part of the Android public SDK API
- */
-public class DERObjectIdentifier
- extends ASN1ObjectIdentifier
-{
- public DERObjectIdentifier(String identifier)
- {
- super(identifier);
- }
-
- DERObjectIdentifier(byte[] bytes)
- {
- super(bytes);
- }
-
- DERObjectIdentifier(ASN1ObjectIdentifier oid, String branch)
- {
- super(oid, branch);
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java
index 7b2dc38..5d6aaea 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java
@@ -33,19 +33,19 @@
super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER));
}
- boolean isConstructed()
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, string.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.OCTET_STRING, string);
+ out.writeEncodingDL(withTag, BERTags.OCTET_STRING, string);
}
ASN1Primitive toDERObject()
@@ -58,8 +58,13 @@
return this;
}
- static void encode(ASN1OutputStream derOut, boolean withTag, byte[] buf, int off, int len) throws IOException
+ static void encode(ASN1OutputStream out, boolean withTag, byte[] buf, int off, int len) throws IOException
{
- derOut.writeEncoded(withTag, BERTags.OCTET_STRING, buf, off, len);
+ out.writeEncodingDL(withTag, BERTags.OCTET_STRING, buf, off, len);
+ }
+
+ static int encodedLength(boolean withTag, int contentsLength)
+ {
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contentsLength);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetStringParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetStringParser.java
index db2da30..72b3b16 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetStringParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetStringParser.java
@@ -6,6 +6,8 @@
/**
* Parser for DER encoded OCTET STRINGS
+ *
+ * @deprecated Check for 'ASN1OctetStringParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class DEROctetStringParser
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java
index 6e08148..80c7e3a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java
@@ -18,18 +18,32 @@
super(os);
}
- void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
- {
- primitive.toDERObject().encode(this, withTag);
- }
-
DEROutputStream getDERSubStream()
{
return this;
}
- ASN1OutputStream getDLSubStream()
+ void writeElements(ASN1Encodable[] elements)
+ throws IOException
{
- return this;
+ for (int i = 0, count = elements.length; i < count; ++i)
+ {
+ elements[i].toASN1Primitive().toDERObject().encode(this, true);
+ }
+ }
+
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
+ {
+ primitive.toDERObject().encode(this, withTag);
+ }
+
+ void writePrimitives(ASN1Primitive[] primitives)
+ throws IOException
+ {
+ int count = primitives.length;
+ for (int i = 0; i < count; ++i)
+ {
+ primitives[i].toDERObject().encode(this, true);
+ }
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java
index e885eb7..0a7df1a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java
@@ -1,11 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-import com.android.internal.org.bouncycastle.util.Strings;
-
/**
* DER PrintableString object.
* <p>
@@ -34,76 +29,8 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERPrintableString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1PrintableString
{
- private final byte[] string;
-
- /**
- * Return a printable string from the passed in object.
- *
- * @param obj a DERPrintableString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERPrintableString instance, or null.
- */
- public static DERPrintableString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERPrintableString)
- {
- return (DERPrintableString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERPrintableString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a Printable String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERPrintableString instance, or null.
- */
- public static DERPrintableString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERPrintableString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERPrintableString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * Basic constructor - byte encoded string.
- */
- DERPrintableString(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor - this does not validate the string
*/
@@ -125,115 +52,11 @@
String string,
boolean validate)
{
- if (validate && !isPrintableString(string))
- {
- throw new IllegalArgumentException("string contains illegal characters");
- }
-
- this.string = Strings.toByteArray(string);
+ super(string, validate);
}
- public String getString()
+ DERPrintableString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.PRINTABLE_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERPrintableString))
- {
- return false;
- }
-
- DERPrintableString s = (DERPrintableString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- /**
- * return true if the passed in String can be represented without
- * loss as a PrintableString, false otherwise.
- *
- * @return true if in printable set, false otherwise.
- */
- public static boolean isPrintableString(
- String str)
- {
- for (int i = str.length() - 1; i >= 0; i--)
- {
- char ch = str.charAt(i);
-
- if (ch > 0x007f)
- {
- return false;
- }
-
- if ('a' <= ch && ch <= 'z')
- {
- continue;
- }
-
- if ('A' <= ch && ch <= 'Z')
- {
- continue;
- }
-
- if ('0' <= ch && ch <= '9')
- {
- continue;
- }
-
- switch (ch)
- {
- case ' ':
- case '\'':
- case '(':
- case ')':
- case '+':
- case '-':
- case '.':
- case ':':
- case '=':
- case '?':
- case '/':
- case ',':
- continue;
- }
-
- return false;
- }
-
- return true;
+ super(contents, clone);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java
index d1593ef..2fb5f49 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java
@@ -18,7 +18,7 @@
return (DERSequence)seq.toDERObject();
}
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* Create an empty sequence
@@ -59,9 +59,9 @@
super(elements, clone);
}
- private int getBodyLength() throws IOException
+ private int getContentsLength() throws IOException
{
- if (bodyLength < 0)
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -69,20 +69,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/*
@@ -95,17 +93,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE);
DEROutputStream derOut = out.getDERSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -122,11 +117,11 @@
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
derObjects[i] = derObject;
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
@@ -135,6 +130,27 @@
}
}
+ ASN1BitString toASN1BitString()
+ {
+ return new DERBitString(BERBitString.flattenBitStrings(getConstructedBitStrings()), false);
+ }
+
+ ASN1External toASN1External()
+ {
+ return new DERExternal(this);
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ return new DEROctetString(BEROctetString.flattenOctetStrings(getConstructedOctetStrings()));
+ }
+
+ ASN1Set toASN1Set()
+ {
+ // NOTE: DLSet is intentional, we don't want sorting
+ return new DLSet(false, toArrayInternal());
+ }
+
ASN1Primitive toDERObject()
{
return this;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequenceParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequenceParser.java
deleted file mode 100644
index a023592..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequenceParser.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-/**
- * @deprecated Use DLSequenceParser instead
- * @hide This class is not part of the Android public SDK API
- */
-public class DERSequenceParser
- implements ASN1SequenceParser
-{
- private ASN1StreamParser _parser;
-
- DERSequenceParser(ASN1StreamParser parser)
- {
- this._parser = parser;
- }
-
- /**
- * Return the next object in the SEQUENCE.
- *
- * @return next object in SEQUENCE.
- * @throws IOException if there is an issue loading the object.
- */
- public ASN1Encodable readObject()
- throws IOException
- {
- return _parser.readObject();
- }
-
- /**
- * Return an in memory, encodable, representation of the SEQUENCE.
- *
- * @return a DERSequence.
- * @throws IOException if there is an issue loading the data.
- */
- public ASN1Primitive getLoadedObject()
- throws IOException
- {
- return new DLSequence(_parser.readVector());
- }
-
- /**
- * Return a DERSequence representing this parser and its contents.
- *
- * @return a DERSequence.
- */
- public ASN1Primitive toASN1Primitive()
- {
- try
- {
- return getLoadedObject();
- }
- catch (IOException e)
- {
- throw new IllegalStateException(e.getMessage());
- }
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java
index d6914ad..42c8b44 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java
@@ -22,7 +22,7 @@
return (DERSet)set.toDERObject();
}
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* create an empty set
@@ -63,9 +63,9 @@
super(checkSorted(isSorted), elements);
}
- private int getBodyLength() throws IOException
+ private int getContentsLength() throws IOException
{
- if (bodyLength < 0)
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -73,20 +73,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/*
@@ -99,17 +97,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SET);
DEROutputStream derOut = out.getDERSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -126,11 +121,11 @@
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
derObjects[i] = derObject;
- totalLength += derObject.encodedLength();
+ totalLength += derObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
@@ -141,7 +136,7 @@
ASN1Primitive toDERObject()
{
- return isSorted ? this : super.toDERObject();
+ return (sortedElements != null) ? this : super.toDERObject();
}
ASN1Primitive toDLObject()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSetParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSetParser.java
deleted file mode 100644
index f640c3c..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSetParser.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-import java.io.IOException;
-
-/**
- * @deprecated Use DLSetParser instead
- * @hide This class is not part of the Android public SDK API
- */
-public class DERSetParser
- implements ASN1SetParser
-{
- private ASN1StreamParser _parser;
-
- DERSetParser(ASN1StreamParser parser)
- {
- this._parser = parser;
- }
-
- /**
- * Return the next object in the SET.
- *
- * @return next object in SET.
- * @throws IOException if there is an issue loading the object.
- */
- public ASN1Encodable readObject()
- throws IOException
- {
- return _parser.readObject();
- }
-
- /**
- * Return an in memory, encodable, representation of the SET.
- *
- * @return a DERSet.
- * @throws IOException if there is an issue loading the data.
- */
- public ASN1Primitive getLoadedObject()
- throws IOException
- {
- return new DLSet(_parser.readVector());
- }
-
- /**
- * Return a DERSet representing this parser and its contents.
- *
- * @return a DERSet
- */
- public ASN1Primitive toASN1Primitive()
- {
- try
- {
- return getLoadedObject();
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException(e.getMessage(), e);
- }
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java
index 2dad092..0f5dbc9 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java
@@ -1,76 +1,22 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-import com.android.internal.org.bouncycastle.util.Strings;
-
/**
* DER T61String (also the teletex string), try not to use this if you don't need to. The standard support the encoding for
* this has been withdrawn.
* @hide This class is not part of the Android public SDK API
*/
public class DERT61String
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1T61String
{
- private byte[] string;
-
/**
- * Return a T61 string from the passed in object.
+ * Basic constructor - with string 8 bit assumed.
*
- * @param obj a DERT61String or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERT61String instance, or null
+ * @param string the string to be wrapped.
*/
- public static DERT61String getInstance(
- Object obj)
+ public DERT61String(String string)
{
- if (obj == null || obj instanceof DERT61String)
- {
- return (DERT61String)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERT61String)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return an T61 String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERT61String instance, or null
- */
- public static DERT61String getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERT61String)
- {
- return getInstance(o);
- }
- else
- {
- return new DERT61String(ASN1OctetString.getInstance(o).getOctets());
- }
+ super(string);
}
/**
@@ -78,74 +24,13 @@
*
* @param string the byte encoding of the string to be wrapped.
*/
- public DERT61String(
- byte[] string)
+ public DERT61String(byte[] string)
{
- this.string = Arrays.clone(string);
+ this(string, true);
}
- /**
- * Basic constructor - with string 8 bit assumed.
- *
- * @param string the string to be wrapped.
- */
- public DERT61String(
- String string)
+ DERT61String(byte[] contents, boolean clone)
{
- this.string = Strings.toByteArray(string);
- }
-
- /**
- * Decode the encoded string and return it, 8 bit encoding assumed.
- * @return the decoded String
- */
- public String getString()
- {
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.T61_STRING, string);
- }
-
- /**
- * Return the encoded string as a byte array.
- * @return the actual bytes making up the encoded body of the T61 string.
- */
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERT61String))
- {
- return false;
- }
-
- return Arrays.areEqual(string, ((DERT61String)o).string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
+ super(contents, clone);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java
index 201a7ed..b43afae 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java
@@ -12,68 +12,94 @@
public class DERTaggedObject
extends ASN1TaggedObject
{
- /**
- * @param explicit true if an explicitly tagged object.
- * @param tagNo the tag number for this object.
- * @param obj the tagged object.
- */
- public DERTaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
- {
- super(explicit, tagNo, obj);
- }
-
public DERTaggedObject(int tagNo, ASN1Encodable encodable)
{
super(true, tagNo, encodable);
}
- boolean isConstructed()
+ public DERTaggedObject(int tagClass, int tagNo, ASN1Encodable obj)
{
- return explicit || obj.toASN1Primitive().toDERObject().isConstructed();
+ super(true, tagClass, tagNo, obj);
}
- int encodedLength()
- throws IOException
+ /**
+ * @param explicit true if an explicitly tagged object.
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public DERTaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
+ {
+ super(explicit, tagNo, obj);
+ }
+
+ public DERTaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ super(explicit, tagClass, tagNo, obj);
+ }
+
+ DERTaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
+ {
+ super(explicitness, tagClass, tagNo, obj);
+ }
+
+ boolean encodeConstructed()
+ {
+ return isExplicit() || obj.toASN1Primitive().toDERObject().encodeConstructed();
+ }
+
+ int encodedLength(boolean withTag) throws IOException
{
ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
- int length = primitive.encodedLength();
+ boolean explicit = isExplicit();
+
+ int length = primitive.encodedLength(explicit);
if (explicit)
{
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ length += ASN1OutputStream.getLengthOfDL(length);
}
- else
- {
- // header length already in calculation
- length = length - 1;
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ length += withTag ? ASN1OutputStream.getLengthOfIdentifier(tagNo) : 0;
+
+ return length;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
+// assert out.getClass().isAssignableFrom(DEROutputStream.class);
+
ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
+ boolean explicit = isExplicit();
- int flags = BERTags.TAGGED;
- if (explicit || primitive.isConstructed())
+ if (withTag)
{
- flags |= BERTags.CONSTRUCTED;
- }
+ int flags = tagClass;
+ if (explicit || primitive.encodeConstructed())
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
- out.writeTag(withTag, flags, tagNo);
+ out.writeIdentifier(true, flags, tagNo);
+ }
if (explicit)
{
- out.writeLength(primitive.encodedLength());
+ out.writeDL(primitive.encodedLength(true));
}
primitive.encode(out.getDERSubStream(), explicit);
}
+ ASN1Sequence rebuildConstructed(ASN1Primitive primitive)
+ {
+ return new DERSequence(primitive);
+ }
+
+ ASN1TaggedObject replaceTag(int tagClass, int tagNo)
+ {
+ return new DERTaggedObject(explicitness, tagClass, tagNo, obj);
+ }
+
ASN1Primitive toDERObject()
{
return this;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTags.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTags.java
deleted file mode 100644
index fb68afe..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTags.java
+++ /dev/null
@@ -1,11 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-/**
- * @deprecated use BERTags
- * @hide This class is not part of the Android public SDK API
- */
-public interface DERTags
- extends BERTags
-{
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java
index d5f753a..ba25816 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java
@@ -1,88 +1,13 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-import com.android.internal.org.bouncycastle.util.Strings;
-
/**
* DER UTF8String object.
* @hide This class is not part of the Android public SDK API
*/
public class DERUTF8String
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1UTF8String
{
- private final byte[] string;
-
- /**
- * Return an UTF8 string from the passed in object.
- *
- * @param obj a DERUTF8String or an object that can be converted into one.
- * @exception IllegalArgumentException
- * if the object cannot be converted.
- * @return a DERUTF8String instance, or null
- */
- public static DERUTF8String getInstance(Object obj)
- {
- if (obj == null || obj instanceof DERUTF8String)
- {
- return (DERUTF8String)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERUTF8String)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: "
- + obj.getClass().getName());
- }
-
- /**
- * Return an UTF8 String from a tagged object.
- *
- * @param obj
- * the tagged object holding the object we want
- * @param explicit
- * true if the object is meant to be explicitly tagged false
- * otherwise.
- * @exception IllegalArgumentException
- * if the tagged object cannot be converted.
- * @return a DERUTF8String instance, or null
- */
- public static DERUTF8String getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERUTF8String)
- {
- return getInstance(o);
- }
- else
- {
- return new DERUTF8String(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /*
- * Basic constructor - byte encoded string.
- */
- DERUTF8String(byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor
*
@@ -90,49 +15,11 @@
*/
public DERUTF8String(String string)
{
- this.string = Strings.toUTF8ByteArray(string);
+ super(string);
}
- public String getString()
+ DERUTF8String(byte[] contents, boolean clone)
{
- return Strings.fromUTF8ByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(ASN1Primitive o)
- {
- if (!(o instanceof DERUTF8String))
- {
- return false;
- }
-
- DERUTF8String s = (DERUTF8String)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- throws IOException
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.UTF8_STRING, string);
+ super(contents, clone);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java
index b4c2a16..87a86ab 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java
@@ -1,150 +1,26 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-
/**
* DER UniversalString object - encodes UNICODE (ISO 10646) characters using 32-bit format. In Java we
* have no way of representing this directly so we rely on byte arrays to carry these.
* @hide This class is not part of the Android public SDK API
*/
public class DERUniversalString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1UniversalString
{
- private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- private final byte[] string;
-
- /**
- * Return a Universal String from the passed in object.
- *
- * @param obj a DERUniversalString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERUniversalString instance, or null
- */
- public static DERUniversalString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERUniversalString)
- {
- return (DERUniversalString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERUniversalString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a Universal String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERUniversalString instance, or null
- */
- public static DERUniversalString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERUniversalString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERUniversalString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
/**
* Basic constructor - byte encoded string.
*
* @param string the byte encoding of the string to be carried in the UniversalString object,
*/
- public DERUniversalString(
- byte[] string)
+ public DERUniversalString(byte[] string)
{
- this.string = Arrays.clone(string);
+ this(string, true);
}
- public String getString()
+ DERUniversalString(byte[] contents, boolean clone)
{
- StringBuffer buf = new StringBuffer("#");
-
- byte[] string;
- try
- {
- string = getEncoded();
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("internal error encoding UniversalString");
- }
-
- for (int i = 0; i != string.length; i++)
- {
- buf.append(table[(string[i] >>> 4) & 0xf]);
- buf.append(table[string[i] & 0xf]);
- }
-
- return buf.toString();
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.UNIVERSAL_STRING, string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERUniversalString))
- {
- return false;
- }
-
- return Arrays.areEqual(string, ((DERUniversalString)o).string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
+ super(contents, clone);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java
index 155d546..19d2a26 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java
@@ -1,126 +1,19 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-import com.android.internal.org.bouncycastle.util.Strings;
-
/**
* @hide This class is not part of the Android public SDK API
*/
public class DERVideotexString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1VideotexString
{
- private final byte[] string;
-
- /**
- * return a Videotex String from the passed in object
- *
- * @param obj a DERVideotexString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERVideotexString instance, or null.
- */
- public static DERVideotexString getInstance(
- Object obj)
+ public DERVideotexString(byte[] octets)
{
- if (obj == null || obj instanceof DERVideotexString)
- {
- return (DERVideotexString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERVideotexString)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());
+ this(octets, true);
}
- /**
- * return a Videotex String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERVideotexString instance, or null.
- */
- public static DERVideotexString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ DERVideotexString(byte[] contents, boolean clone)
{
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERVideotexString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERVideotexString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /**
- * basic constructor - with bytes.
- * @param string the byte encoding of the characters making up the string.
- */
- public DERVideotexString(
- byte[] string)
- {
- this.string = Arrays.clone(string);
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.VIDEOTEX_STRING, string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERVideotexString))
- {
- return false;
- }
-
- DERVideotexString s = (DERVideotexString)o;
-
- return Arrays.areEqual(string, s.string);
- }
-
- public String getString()
- {
- return Strings.fromByteArray(string);
+ super(contents, clone);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java
index e402c13..aaa62a0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java
@@ -1,11 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.IOException;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
-import com.android.internal.org.bouncycastle.util.Strings;
-
/**
* DER VisibleString object encoding ISO 646 (ASCII) character code points 32 to 126.
* <p>
@@ -14,130 +9,20 @@
* @hide This class is not part of the Android public SDK API
*/
public class DERVisibleString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1VisibleString
{
- private final byte[] string;
-
- /**
- * Return a Visible String from the passed in object.
- *
- * @param obj a DERVisibleString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return a DERVisibleString instance, or null
- */
- public static DERVisibleString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DERVisibleString)
- {
- return (DERVisibleString)obj;
- }
-
- if (obj instanceof byte[])
- {
- try
- {
- return (DERVisibleString)fromByteArray((byte[])obj);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
- }
- }
-
- throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
- }
-
- /**
- * Return a Visible String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return a DERVisibleString instance, or null
- */
- public static DERVisibleString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DERVisibleString)
- {
- return getInstance(o);
- }
- else
- {
- return new DERVisibleString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- /*
- * Basic constructor - byte encoded string.
- */
- DERVisibleString(
- byte[] string)
- {
- this.string = string;
- }
-
/**
* Basic constructor
*
* @param string the string to be carried in the VisibleString object,
*/
- public DERVisibleString(
- String string)
+ public DERVisibleString(String string)
{
- this.string = Strings.toByteArray(string);
+ super(string);
}
- public String getString()
+ DERVisibleString(byte[] contents, boolean clone)
{
- return Strings.fromByteArray(string);
- }
-
- public String toString()
- {
- return getString();
- }
-
- public byte[] getOctets()
- {
- return Arrays.clone(string);
- }
-
- boolean isConstructed()
- {
- return false;
- }
-
- int encodedLength()
- {
- return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
- }
-
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- out.writeEncoded(withTag, BERTags.VISIBLE_STRING, this.string);
- }
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERVisibleString))
- {
- return false;
- }
-
- return Arrays.areEqual(string, ((DERVisibleString)o).string);
- }
-
- public int hashCode()
- {
- return Arrays.hashCode(string);
+ super(contents, clone);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLApplicationSpecific.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLApplicationSpecific.java
deleted file mode 100644
index 174ef82..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLApplicationSpecific.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * A DER encoding version of an application specific object.
- * @hide This class is not part of the Android public SDK API
- */
-public class DLApplicationSpecific
- extends ASN1ApplicationSpecific
-{
- DLApplicationSpecific(
- boolean isConstructed,
- int tag,
- byte[] octets)
- {
- super(isConstructed, tag, octets);
- }
-
- /**
- * Create an application specific object from the passed in data. This will assume
- * the data does not represent a constructed object.
- *
- * @param tag the tag number for this object.
- * @param octets the encoding of the object's body.
- */
- public DLApplicationSpecific(
- int tag,
- byte[] octets)
- {
- this(false, tag, octets);
- }
-
- /**
- * Create an application specific object with a tagging of explicit/constructed.
- *
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DLApplicationSpecific(
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- this(true, tag, object);
- }
-
- /**
- * Create an application specific object with the tagging style given by the value of constructed.
- *
- * @param constructed true if the object is constructed.
- * @param tag the tag number for this object.
- * @param object the object to be contained.
- */
- public DLApplicationSpecific(
- boolean constructed,
- int tag,
- ASN1Encodable object)
- throws IOException
- {
- super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
- }
-
- private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
- throws IOException
- {
- byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.DL);
-
- if (explicit)
- {
- return data;
- }
- else
- {
- int lenBytes = getLengthOfHeader(data);
- byte[] tmp = new byte[data.length - lenBytes];
- System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
- return tmp;
- }
- }
-
- /**
- * Create an application specific object which is marked as constructed
- *
- * @param tagNo the tag number for this object.
- * @param vec the objects making up the application specific object.
- */
- public DLApplicationSpecific(int tagNo, ASN1EncodableVector vec)
- {
- super(true, tagNo, getEncodedVector(vec));
- }
-
- private static byte[] getEncodedVector(ASN1EncodableVector vec)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
- for (int i = 0; i != vec.size(); i++)
- {
- try
- {
- bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DL));
- }
- catch (IOException e)
- {
- throw new ASN1ParsingException("malformed object: " + e, e);
- }
- }
- return bOut.toByteArray();
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- int flags = BERTags.APPLICATION;
- if (isConstructed)
- {
- flags |= BERTags.CONSTRUCTED;
- }
-
- out.writeEncoded(withTag, flags, tag, octets);
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java
index cb72e95..b5fcbb5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java
@@ -10,113 +10,51 @@
public class DLBitString
extends ASN1BitString
{
- /**
- * return a Bit String that can be definite-length encoded from the passed in object.
- *
- * @param obj a DL or DER BitString or an object that can be converted into one.
- * @exception IllegalArgumentException if the object cannot be converted.
- * @return an ASN1BitString instance, or null.
- */
- public static ASN1BitString getInstance(
- Object obj)
- {
- if (obj == null || obj instanceof DLBitString)
- {
- return (DLBitString)obj;
- }
- if (obj instanceof DERBitString)
- {
- return (DERBitString)obj;
- }
- if (obj instanceof byte[])
- {
- try
- {
- return (ASN1BitString)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());
- }
-
- /**
- * return a Bit String from a tagged object.
- *
- * @param obj the tagged object holding the object we want
- * @param explicit true if the object is meant to be explicitly
- * tagged false otherwise.
- * @exception IllegalArgumentException if the tagged object cannot
- * be converted.
- * @return an ASN1BitString instance, or null.
- */
- public static ASN1BitString getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
- {
- ASN1Primitive o = obj.getObject();
-
- if (explicit || o instanceof DLBitString)
- {
- return getInstance(o);
- }
- else
- {
- return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
- }
- }
-
- protected DLBitString(byte data, int padBits)
- {
- super(data, padBits);
- }
-
- /**
- * @param data the octets making up the bit string.
- * @param padBits the number of extra bits at the end of the string.
- */
- public DLBitString(
- byte[] data,
- int padBits)
- {
- super(data, padBits);
- }
-
- public DLBitString(
- byte[] data)
+ public DLBitString(byte[] data)
{
this(data, 0);
}
- public DLBitString(
- int value)
+ public DLBitString(byte data, int padBits)
{
+ super(data, padBits);
+ }
+
+ public DLBitString(byte[] data, int padBits)
+ {
+ super(data, padBits);
+ }
+
+ public DLBitString(int value)
+ {
+ // TODO[asn1] Unify in single allocation of 'contents'
super(getBytes(value), getPadBits(value));
}
- public DLBitString(
- ASN1Encodable obj)
- throws IOException
+ public DLBitString(ASN1Encodable obj) throws IOException
{
+ // TODO[asn1] Unify in single allocation of 'contents'
super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
}
- boolean isConstructed()
+ DLBitString(byte[] contents, boolean check)
+ {
+ super(contents, check);
+ }
+
+ boolean encodeConstructed()
{
return false;
}
- int encodedLength()
+ int encodedLength(boolean withTag)
{
- return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length);
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, contents);
}
ASN1Primitive toDLObject()
@@ -124,21 +62,19 @@
return this;
}
- static DLBitString fromOctetString(byte[] bytes)
+ static int encodedLength(boolean withTag, int contentsLength)
{
- if (bytes.length < 1)
- {
- throw new IllegalArgumentException("truncated BIT STRING detected");
- }
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, contentsLength);
+ }
- int padBits = bytes[0];
- byte[] data = new byte[bytes.length - 1];
+ static void encode(ASN1OutputStream out, boolean withTag, byte[] buf, int off, int len) throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, buf, off, len);
+ }
- if (data.length != 0)
- {
- System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
- }
-
- return new DLBitString(data, padBits);
+ static void encode(ASN1OutputStream out, boolean withTag, byte pad, byte[] buf, int off, int len)
+ throws IOException
+ {
+ out.writeEncodingDL(withTag, BERTags.BIT_STRING, pad, buf, off, len);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitStringParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitStringParser.java
new file mode 100644
index 0000000..24efac0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitStringParser.java
@@ -0,0 +1,85 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Parser for a DL encoded BIT STRING.
+ *
+ * @deprecated Check for 'ASN1BitStringParser' instead
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLBitStringParser
+ implements ASN1BitStringParser
+{
+ private final DefiniteLengthInputStream stream;
+ private int padBits = 0;
+
+ DLBitStringParser(
+ DefiniteLengthInputStream stream)
+ {
+ this.stream = stream;
+ }
+
+ public InputStream getBitStream() throws IOException
+ {
+ return getBitStream(false);
+ }
+
+ public InputStream getOctetStream() throws IOException
+ {
+ return getBitStream(true);
+ }
+
+ public int getPadBits()
+ {
+ return padBits;
+ }
+
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return ASN1BitString.createPrimitive(stream.toByteArray());
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
+ }
+ }
+
+ private InputStream getBitStream(boolean octetAligned) throws IOException
+ {
+ int length = stream.getRemaining();
+ if (length < 1)
+ {
+ throw new IllegalStateException("content octets cannot be empty");
+ }
+
+ padBits = stream.read();
+ if (padBits > 0)
+ {
+ if (length < 2)
+ {
+ throw new IllegalStateException("zero length data with non-zero pad bits");
+ }
+ if (padBits > 7)
+ {
+ throw new IllegalStateException("pad bits cannot be greater than 7 or less than 0");
+ }
+ if (octetAligned)
+ {
+ throw new IOException("expected octet-aligned bitstring, but found padBits: " + padBits);
+ }
+ }
+
+ return stream;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java
index 5d8c619..c3a35b9 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java
@@ -1,9 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
/**
* Class representing the Definite-Length-type External
* @hide This class is not part of the Android public SDK API
@@ -21,11 +18,30 @@
* <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
* </ul>
*
- * @throws IllegalArgumentException if input size is wrong, or
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ *
+ * @deprecated Use {@link DLExternal#DLExternal(DLSequence)} instead.
*/
public DLExternal(ASN1EncodableVector vector)
{
- super(vector);
+ this(DLFactory.createSequence(vector));
+ }
+
+ /**
+ * Construct a Definite-Length EXTERNAL object, the input sequence must have exactly two elements on it.
+ * <p>
+ * Acceptable input formats are:
+ * <ul>
+ * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
+ * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
+ * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
+ * </ul>
+ *
+ * @throws IllegalArgumentException if input size is wrong, or input is not an acceptable format
+ */
+ public DLExternal(DLSequence sequence)
+ {
+ super(sequence);
}
/**
@@ -36,9 +52,10 @@
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param externalData The external data in its encoded form.
*/
- public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
{
- this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ super(directReference, indirectReference, dataValueDescriptor, externalData);
}
/**
@@ -50,43 +67,35 @@
* @param encoding The encoding to be used for the external data
* @param externalData The external data
*/
- public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference,
+ ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
{
super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
}
+ ASN1Sequence buildSequence()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+ if (directReference != null)
+ {
+ v.add(directReference);
+ }
+ if (indirectReference != null)
+ {
+ v.add(indirectReference);
+ }
+ if (dataValueDescriptor != null)
+ {
+ v.add(dataValueDescriptor.toDLObject());
+ }
+
+ v.add(new DLTaggedObject(0 == encoding, encoding, externalContent));
+
+ return new DLSequence(v);
+ }
+
ASN1Primitive toDLObject()
{
return this;
}
-
- int encodedLength()
- throws IOException
- {
- return this.getEncoded().length;
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
- */
- void encode(ASN1OutputStream out, boolean withTag) throws IOException
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- if (directReference != null)
- {
- baos.write(directReference.getEncoded(ASN1Encoding.DL));
- }
- if (indirectReference != null)
- {
- baos.write(indirectReference.getEncoded(ASN1Encoding.DL));
- }
- if (dataValueDescriptor != null)
- {
- baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DL));
- }
- ASN1TaggedObject obj = new DLTaggedObject(true, encoding, externalContent);
- baos.write(obj.getEncoded(ASN1Encoding.DL));
-
- out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
- }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLFactory.java
index 5f8d520..509eeb1 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLFactory.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLFactory.java
@@ -3,10 +3,10 @@
class DLFactory
{
- static final ASN1Sequence EMPTY_SEQUENCE = new DLSequence();
- static final ASN1Set EMPTY_SET = new DLSet();
+ static final DLSequence EMPTY_SEQUENCE = new DLSequence();
+ static final DLSet EMPTY_SET = new DLSet();
- static ASN1Sequence createSequence(ASN1EncodableVector v)
+ static DLSequence createSequence(ASN1EncodableVector v)
{
if (v.size() < 1)
{
@@ -16,7 +16,7 @@
return new DLSequence(v);
}
- static ASN1Set createSet(ASN1EncodableVector v)
+ static DLSet createSet(ASN1EncodableVector v)
{
if (v.size() < 1)
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLOutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLOutputStream.java
index 99a0abd..948abc4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLOutputStream.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLOutputStream.java
@@ -15,13 +15,32 @@
super(os);
}
+ DLOutputStream getDLSubStream()
+ {
+ return this;
+ }
+
+ void writeElements(ASN1Encodable[] elements)
+ throws IOException
+ {
+ for (int i = 0, count = elements.length; i < count; ++i)
+ {
+ elements[i].toASN1Primitive().toDLObject().encode(this, true);
+ }
+ }
+
void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
{
primitive.toDLObject().encode(this, withTag);
}
- ASN1OutputStream getDLSubStream()
+ void writePrimitives(ASN1Primitive[] primitives)
+ throws IOException
{
- return this;
+ int count = primitives.length;
+ for (int i = 0; i < count; ++i)
+ {
+ primitives[i].toDLObject().encode(this, true);
+ }
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java
index b4a770f..0fd60c0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java
@@ -10,7 +10,7 @@
public class DLSequence
extends ASN1Sequence
{
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* Create an empty sequence
@@ -51,9 +51,9 @@
super(elements, clone);
}
- private int getBodyLength() throws IOException
+ private int getContentsLength() throws IOException
{
- if (bodyLength < 0)
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -61,20 +61,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/**
@@ -87,17 +85,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE);
ASN1OutputStream dlOut = out.getDLSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -113,11 +108,11 @@
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
dlObjects[i] = dlObject;
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
@@ -126,8 +121,29 @@
}
}
+ ASN1BitString toASN1BitString()
+ {
+ return new DLBitString(BERBitString.flattenBitStrings(getConstructedBitStrings()), false);
+ }
+
+ ASN1External toASN1External()
+ {
+ return new DLExternal(this);
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ // NOTE: There is no DLOctetString
+ return new DEROctetString(BEROctetString.flattenOctetStrings(getConstructedOctetStrings()));
+ }
+
+ ASN1Set toASN1Set()
+ {
+ return new DLSet(false, toArrayInternal());
+ }
+
ASN1Primitive toDLObject()
{
return this;
}
-}
\ No newline at end of file
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequenceParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequenceParser.java
index 62158d0..4065398 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequenceParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequenceParser.java
@@ -6,7 +6,7 @@
/**
* Parser class for DL SEQUENCEs.
*
- * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ * @deprecated Check for 'ASN1SequenceParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class DLSequenceParser
@@ -40,7 +40,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new DLSequence(_parser.readVector());
+ return DLFactory.createSequence(_parser.readVector());
}
/**
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSet.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSet.java
index 543b4f9..968ab84 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSet.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSet.java
@@ -55,7 +55,7 @@
public class DLSet
extends ASN1Set
{
- private int bodyLength = -1;
+ private int contentsLength = -1;
/**
* create an empty set
@@ -93,9 +93,14 @@
super(isSorted, elements);
}
- private int getBodyLength() throws IOException
+ DLSet(ASN1Encodable[] elements, ASN1Encodable[] sortedElements)
{
- if (bodyLength < 0)
+ super(elements, sortedElements);
+ }
+
+ private int getContentsLength() throws IOException
+ {
+ if (contentsLength < 0)
{
int count = elements.length;
int totalLength = 0;
@@ -103,20 +108,18 @@
for (int i = 0; i < count; ++i)
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
+ this.contentsLength = totalLength;
}
- return bodyLength;
+ return contentsLength;
}
- int encodedLength() throws IOException
+ int encodedLength(boolean withTag) throws IOException
{
- int length = getBodyLength();
-
- return 1 + StreamUtil.calculateBodyLength(length) + length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, getContentsLength());
}
/**
@@ -129,17 +132,14 @@
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (withTag)
- {
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- }
+ out.writeIdentifier(withTag, BERTags.CONSTRUCTED | BERTags.SET);
ASN1OutputStream dlOut = out.getDLSubStream();
int count = elements.length;
- if (bodyLength >= 0 || count > 16)
+ if (contentsLength >= 0 || count > 16)
{
- out.writeLength(getBodyLength());
+ out.writeDL(getContentsLength());
for (int i = 0; i < count; ++i)
{
@@ -155,11 +155,11 @@
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
dlObjects[i] = dlObject;
- totalLength += dlObject.encodedLength();
+ totalLength += dlObject.encodedLength(true);
}
- this.bodyLength = totalLength;
- out.writeLength(totalLength);
+ this.contentsLength = totalLength;
+ out.writeDL(totalLength);
for (int i = 0; i < count; ++i)
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSetParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSetParser.java
index 99d2ad9..f9f8161 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSetParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSetParser.java
@@ -6,7 +6,7 @@
/**
* Parser class for DL SETs.
*
- * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ * @deprecated Check for 'ASN1SetParser' instead
* @hide This class is not part of the Android public SDK API
*/
public class DLSetParser
@@ -40,7 +40,7 @@
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new DLSet(_parser.readVector());
+ return DLFactory.createSet(_parser.readVector());
}
/**
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObject.java
index c6904a4..7ad0342 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObject.java
@@ -12,60 +12,92 @@
public class DLTaggedObject
extends ASN1TaggedObject
{
+ public DLTaggedObject(int tagNo, ASN1Encodable encodable)
+ {
+ super(true, tagNo, encodable);
+ }
+
+ public DLTaggedObject(int tagClass, int tagNo, ASN1Encodable encodable)
+ {
+ super(true, tagClass, tagNo, encodable);
+ }
+
/**
* @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public DLTaggedObject(
- boolean explicit,
- int tagNo,
- ASN1Encodable obj)
+ public DLTaggedObject(boolean explicit, int tagNo, ASN1Encodable obj)
{
super(explicit, tagNo, obj);
}
- boolean isConstructed()
+ public DLTaggedObject(boolean explicit, int tagClass, int tagNo, ASN1Encodable obj)
{
- return explicit || obj.toASN1Primitive().toDLObject().isConstructed();
+ super(explicit, tagClass, tagNo, obj);
}
- int encodedLength()
- throws IOException
+ DLTaggedObject(int explicitness, int tagClass, int tagNo, ASN1Encodable obj)
{
- int length = obj.toASN1Primitive().toDLObject().encodedLength();
+ super(explicitness, tagClass, tagNo, obj);
+ }
+
+ boolean encodeConstructed()
+ {
+ return isExplicit() || obj.toASN1Primitive().toDLObject().encodeConstructed();
+ }
+
+ int encodedLength(boolean withTag) throws IOException
+ {
+ ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
+ boolean explicit = isExplicit();
+
+ int length = primitive.encodedLength(explicit);
if (explicit)
{
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ length += ASN1OutputStream.getLengthOfDL(length);
}
- else
- {
- // header length already in calculation
- length = length - 1;
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ length += withTag ? ASN1OutputStream.getLengthOfIdentifier(tagNo) : 0;
+
+ return length;
}
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
+// assert out.getClass().isAssignableFrom(DLOutputStream.class);
+
ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
+ boolean explicit = isExplicit();
- int flags = BERTags.TAGGED;
- if (explicit || primitive.isConstructed())
+ if (withTag)
{
- flags |= BERTags.CONSTRUCTED;
- }
+ int flags = tagClass;
+ if (explicit || primitive.encodeConstructed())
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
- out.writeTag(withTag, flags, tagNo);
+ out.writeIdentifier(true, flags, tagNo);
+ }
if (explicit)
{
- out.writeLength(primitive.encodedLength());
+ out.writeDL(primitive.encodedLength(true));
}
- out.getDLSubStream().writePrimitive(primitive, explicit);
+ primitive.encode(out.getDLSubStream(), explicit);
+ }
+
+ ASN1Sequence rebuildConstructed(ASN1Primitive primitive)
+ {
+ return new DLSequence(primitive);
+ }
+
+ ASN1TaggedObject replaceTag(int tagClass, int tagNo)
+ {
+ return new DLTaggedObject(explicitness, tagClass, tagNo, obj);
}
ASN1Primitive toDLObject()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObjectParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObjectParser.java
new file mode 100644
index 0000000..8799f11
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObjectParser.java
@@ -0,0 +1,74 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser for definite-length tagged objects.
+ */
+class DLTaggedObjectParser
+ extends BERTaggedObjectParser
+{
+ private final boolean _constructed;
+
+ DLTaggedObjectParser(int tagClass, int tagNo, boolean constructed, ASN1StreamParser parser)
+ {
+ super(tagClass, tagNo, parser);
+
+ _constructed = constructed;
+ }
+
+ /**
+ * Return an in-memory, encodable, representation of the tagged object.
+ *
+ * @return an ASN1TaggedObject.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return _parser.loadTaggedDL(_tagClass, _tagNo, _constructed);
+ }
+
+ public ASN1Encodable parseBaseUniversal(boolean declaredExplicit, int baseTagNo) throws IOException
+ {
+ if (declaredExplicit)
+ {
+ if (!_constructed)
+ {
+ throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
+ }
+
+ return _parser.parseObject(baseTagNo);
+ }
+
+ return _constructed
+ ? _parser.parseImplicitConstructedDL(baseTagNo)
+ : _parser.parseImplicitPrimitive(baseTagNo);
+ }
+
+ public ASN1Encodable parseExplicitBaseObject() throws IOException
+ {
+ if (!_constructed)
+ {
+ throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
+ }
+
+ return _parser.readObject();
+ }
+
+ public ASN1TaggedObjectParser parseExplicitBaseTagged() throws IOException
+ {
+ if (!_constructed)
+ {
+ throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
+ }
+
+ return _parser.parseTaggedObject();
+ }
+
+ public ASN1TaggedObjectParser parseImplicitBaseTagged(int baseTagClass, int baseTagNo) throws IOException
+ {
+ return new DLTaggedObjectParser(baseTagClass, baseTagNo, _constructed, _parser);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java
index f951b42..20fc479 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java
@@ -26,18 +26,18 @@
{
super(in, limit);
- if (length < 0)
+ if (length <= 0)
{
- throw new IllegalArgumentException("negative lengths not allowed");
+ if (length < 0)
+ {
+ throw new IllegalArgumentException("negative lengths not allowed");
+ }
+
+ setParentEofDetect(true);
}
this._originalLength = length;
this._remaining = length;
-
- if (length == 0)
- {
- setParentEofDetect(true);
- }
}
int getRemaining()
@@ -112,7 +112,7 @@
throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
}
- if ((_remaining -= Streams.readFully(_in, buf)) != 0)
+ if ((_remaining -= Streams.readFully(_in, buf, 0, buf.length)) != 0)
{
throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
}
@@ -135,7 +135,7 @@
}
byte[] bytes = new byte[_remaining];
- if ((_remaining -= Streams.readFully(_in, bytes)) != 0)
+ if ((_remaining -= Streams.readFully(_in, bytes, 0, bytes.length)) != 0)
{
throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java
index 31ba897..a6d1a86 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java
@@ -41,7 +41,7 @@
}
catch (IOException e)
{
- throw new ASN1ParsingException("malformed DER construction: " + e, e);
+ throw new ASN1ParsingException("malformed ASN.1: " + e, e);
}
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java
index cd914ee..66577bd 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java
@@ -18,18 +18,24 @@
// NOTE: Initially, the actual 'elements' will be empty
super();
+ if (null == encoded)
+ {
+ throw new NullPointerException("'encoded' cannot be null");
+ }
+
this.encoded = encoded;
}
- public synchronized ASN1Encodable getObjectAt(int index)
+ public ASN1Encodable getObjectAt(int index)
{
force();
return super.getObjectAt(index);
}
- public synchronized Enumeration getObjects()
+ public Enumeration getObjects()
{
+ byte[] encoded = getContents();
if (null != encoded)
{
return new LazyConstructionEnumeration(encoded);
@@ -38,28 +44,28 @@
return super.getObjects();
}
- public synchronized int hashCode()
+ public int hashCode()
{
force();
return super.hashCode();
}
- public synchronized Iterator<ASN1Encodable> iterator()
+ public Iterator<ASN1Encodable> iterator()
{
force();
return super.iterator();
}
- public synchronized int size()
+ public int size()
{
force();
return super.size();
}
- public synchronized ASN1Encodable[] toArray()
+ public ASN1Encodable[] toArray()
{
force();
@@ -73,27 +79,48 @@
return super.toArrayInternal();
}
- synchronized int encodedLength()
+ int encodedLength(boolean withTag)
throws IOException
{
+ byte[] encoded = getContents();
if (null != encoded)
{
- return 1 + StreamUtil.calculateBodyLength(encoded.length) + encoded.length;
+ return ASN1OutputStream.getLengthOfEncodingDL(withTag, encoded.length);
}
- return super.toDLObject().encodedLength();
+ return super.toDLObject().encodedLength(withTag);
}
- synchronized void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
+ byte[] encoded = getContents();
if (null != encoded)
{
- out.writeEncoded(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded);
+ out.writeEncodingDL(withTag, BERTags.CONSTRUCTED | BERTags.SEQUENCE, encoded);
+ return;
}
- else
- {
- super.toDLObject().encode(out, withTag);
- }
+
+ super.toDLObject().encode(out, withTag);
+ }
+
+ ASN1BitString toASN1BitString()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1BitString();
+ }
+
+ ASN1External toASN1External()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1External();
+ }
+
+ ASN1OctetString toASN1OctetString()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1OctetString();
+ }
+
+ ASN1Set toASN1Set()
+ {
+ return ((ASN1Sequence)toDLObject()).toASN1Set();
}
synchronized ASN1Primitive toDERObject()
@@ -110,20 +137,28 @@
return super.toDLObject();
}
- private void force()
+ private synchronized void force()
{
if (null != encoded)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
-
- Enumeration en = new LazyConstructionEnumeration(encoded);
- while (en.hasMoreElements())
+ ASN1InputStream aIn = new ASN1InputStream(encoded, true);
+ try
{
- v.add((ASN1Primitive)en.nextElement());
- }
+ ASN1EncodableVector v = aIn.readVector();
+ aIn.close();
- this.elements = v.takeElements();
- this.encoded = null;
+ this.elements = v.takeElements();
+ this.encoded = null;
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("malformed ASN.1: " + e, e);
+ }
}
}
+
+ private synchronized byte[] getContents()
+ {
+ return encoded;
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DateUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LocaleUtil.java
similarity index 76%
rename from repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DateUtil.java
rename to repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LocaleUtil.java
index 8cecd07..9e832fc 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DateUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LocaleUtil.java
@@ -8,13 +8,18 @@
import java.util.Locale;
import java.util.Map;
-class DateUtil
-{
- private static Long ZERO = longValueOf(0);
+import com.android.internal.org.bouncycastle.util.Longs;
+/**
+ * ASN.1 uses an EN locale for its internal formatting. This class finds the nearest equivalent in the
+ * current JVM to ensure date formats are always respected.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class LocaleUtil
+{
private static final Map localeCache = new HashMap();
- static Locale EN_Locale = forEN();
+ public static Locale EN_Locale = forEN();
private static Locale forEN()
{
@@ -53,19 +58,12 @@
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
long v = dateF.parse("19700101000000GMT+00:00").getTime();
- if (v == 0)
- {
- adj = ZERO;
- }
- else
- {
- adj = longValueOf(v);
- }
+ adj = longValueOf(v);
localeCache.put(locale, adj);
}
- if (adj != ZERO)
+ if (adj.longValue() != 0L)
{
return new Date(date.getTime() - adj.longValue());
}
@@ -76,6 +74,6 @@
private static Long longValueOf(long v)
{
- return Long.valueOf(v);
+ return Longs.valueOf(v);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
index 4310f10..6154d33 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
@@ -4,75 +4,103 @@
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
/**
- * Object Identifiers belonging to iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle (1.3.6.1.4.1.22554)
+ * Object Identifiers belonging to iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle (1.3.6.1.4.1.22554)
* @hide This class is not part of the Android public SDK API
*/
public interface BCObjectIdentifiers
{
/**
- * iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle
- *<p>
- * 1.3.6.1.4.1.22554
+ * iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle
+ * <p>
+ * 1.3.6.1.4.1.22554
*/
- public static final ASN1ObjectIdentifier bc = new ASN1ObjectIdentifier("1.3.6.1.4.1.22554");
+ ASN1ObjectIdentifier bc = new ASN1ObjectIdentifier("1.3.6.1.4.1.22554");
/**
* pbe(1) algorithms
* <p>
* 1.3.6.1.4.1.22554.1
*/
- public static final ASN1ObjectIdentifier bc_pbe = bc.branch("1");
+ ASN1ObjectIdentifier bc_pbe = bc.branch("1");
/**
* SHA-1(1)
* <p>
* 1.3.6.1.4.1.22554.1.1
*/
- public static final ASN1ObjectIdentifier bc_pbe_sha1 = bc_pbe.branch("1");
+ ASN1ObjectIdentifier bc_pbe_sha1 = bc_pbe.branch("1");
- /** SHA-2.SHA-256; 1.3.6.1.4.1.22554.1.2.1 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256 = bc_pbe.branch("2.1");
- /** SHA-2.SHA-384; 1.3.6.1.4.1.22554.1.2.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha384 = bc_pbe.branch("2.2");
- /** SHA-2.SHA-512; 1.3.6.1.4.1.22554.1.2.3 */
- public static final ASN1ObjectIdentifier bc_pbe_sha512 = bc_pbe.branch("2.3");
- /** SHA-2.SHA-224; 1.3.6.1.4.1.22554.1.2.4 */
- public static final ASN1ObjectIdentifier bc_pbe_sha224 = bc_pbe.branch("2.4");
+ /**
+ * SHA-2.SHA-256; 1.3.6.1.4.1.22554.1.2.1
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256 = bc_pbe.branch("2.1");
+ /**
+ * SHA-2.SHA-384; 1.3.6.1.4.1.22554.1.2.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha384 = bc_pbe.branch("2.2");
+ /**
+ * SHA-2.SHA-512; 1.3.6.1.4.1.22554.1.2.3
+ */
+ ASN1ObjectIdentifier bc_pbe_sha512 = bc_pbe.branch("2.3");
+ /**
+ * SHA-2.SHA-224; 1.3.6.1.4.1.22554.1.2.4
+ */
+ ASN1ObjectIdentifier bc_pbe_sha224 = bc_pbe.branch("2.4");
/**
* PKCS-5(1)|PKCS-12(2)
*/
- /** SHA-1.PKCS5; 1.3.6.1.4.1.22554.1.1.1 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs5 = bc_pbe_sha1.branch("1");
- /** SHA-1.PKCS12; 1.3.6.1.4.1.22554.1.1.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12 = bc_pbe_sha1.branch("2");
+ /**
+ * SHA-1.PKCS5; 1.3.6.1.4.1.22554.1.1.1
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs5 = bc_pbe_sha1.branch("1");
+ /**
+ * SHA-1.PKCS12; 1.3.6.1.4.1.22554.1.1.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12 = bc_pbe_sha1.branch("2");
- /** SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.1 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs5 = bc_pbe_sha256.branch("1");
- /** SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12 = bc_pbe_sha256.branch("2");
+ /**
+ * SHA-256.PKCS5; 1.3.6.1.4.1.22554.1.2.1.1
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs5 = bc_pbe_sha256.branch("1");
+ /**
+ * SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12 = bc_pbe_sha256.branch("2");
/**
* AES(1) . (CBC-128(2)|CBC-192(22)|CBC-256(42))
*/
- /** 1.3.6.1.4.1.22554.1.1.2.1.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = bc_pbe_sha1_pkcs12.branch("1.2");
- /** 1.3.6.1.4.1.22554.1.1.2.1.22 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = bc_pbe_sha1_pkcs12.branch("1.22");
- /** 1.3.6.1.4.1.22554.1.1.2.1.42 */
- public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = bc_pbe_sha1_pkcs12.branch("1.42");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.1.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = bc_pbe_sha1_pkcs12.branch("1.2");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.1.22
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = bc_pbe_sha1_pkcs12.branch("1.22");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.1.42
+ */
+ ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = bc_pbe_sha1_pkcs12.branch("1.42");
- /** 1.3.6.1.4.1.22554.1.1.2.2.2 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = bc_pbe_sha256_pkcs12.branch("1.2");
- /** 1.3.6.1.4.1.22554.1.1.2.2.22 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = bc_pbe_sha256_pkcs12.branch("1.22");
- /** 1.3.6.1.4.1.22554.1.1.2.2.42 */
- public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = bc_pbe_sha256_pkcs12.branch("1.42");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.2.2
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = bc_pbe_sha256_pkcs12.branch("1.2");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.2.22
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = bc_pbe_sha256_pkcs12.branch("1.22");
+ /**
+ * 1.3.6.1.4.1.22554.1.1.2.2.42
+ */
+ ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = bc_pbe_sha256_pkcs12.branch("1.42");
/**
* signature(2) algorithms
*/
- public static final ASN1ObjectIdentifier bc_sig = bc.branch("2");
+ ASN1ObjectIdentifier bc_sig = bc.branch("2");
// BEGIN Android-removed: Unsupported algorithms
/*
@@ -83,101 +111,329 @@
public static final ASN1ObjectIdentifier sphincs256_with_BLAKE512 = sphincs256.branch("1");
public static final ASN1ObjectIdentifier sphincs256_with_SHA512 = sphincs256.branch("2");
public static final ASN1ObjectIdentifier sphincs256_with_SHA3_512 = sphincs256.branch("3");
+ ASN1ObjectIdentifier sphincs256 = bc_sig.branch("1");
+ ASN1ObjectIdentifier sphincs256_with_BLAKE512 = sphincs256.branch("1");
+ ASN1ObjectIdentifier sphincs256_with_SHA512 = sphincs256.branch("2");
+ ASN1ObjectIdentifier sphincs256_with_SHA3_512 = sphincs256.branch("3");
+ */
/**
* XMSS
*/
- public static final ASN1ObjectIdentifier xmss = bc_sig.branch("2");
- public static final ASN1ObjectIdentifier xmss_SHA256ph = xmss.branch("1");
- public static final ASN1ObjectIdentifier xmss_SHA512ph = xmss.branch("2");
- public static final ASN1ObjectIdentifier xmss_SHAKE128ph = xmss.branch("3");
- public static final ASN1ObjectIdentifier xmss_SHAKE256ph = xmss.branch("4");
- public static final ASN1ObjectIdentifier xmss_SHA256 = xmss.branch("5");
- public static final ASN1ObjectIdentifier xmss_SHA512 = xmss.branch("6");
- public static final ASN1ObjectIdentifier xmss_SHAKE128 = xmss.branch("7");
- public static final ASN1ObjectIdentifier xmss_SHAKE256 = xmss.branch("8");
+ ASN1ObjectIdentifier xmss = bc_sig.branch("2");
+ ASN1ObjectIdentifier xmss_SHA256ph = xmss.branch("1");
+ ASN1ObjectIdentifier xmss_SHA512ph = xmss.branch("2");
+ ASN1ObjectIdentifier xmss_SHAKE128_512ph = xmss.branch("3");
+ ASN1ObjectIdentifier xmss_SHAKE256_1024ph = xmss.branch("4");
+ ASN1ObjectIdentifier xmss_SHA256 = xmss.branch("5");
+ ASN1ObjectIdentifier xmss_SHA512 = xmss.branch("6");
+ ASN1ObjectIdentifier xmss_SHAKE128 = xmss.branch("7");
+ ASN1ObjectIdentifier xmss_SHAKE256 = xmss.branch("8");
+ ASN1ObjectIdentifier xmss_SHAKE128ph = xmss.branch("9");
+ ASN1ObjectIdentifier xmss_SHAKE256ph = xmss.branch("10");
/**
* XMSS^MT
*/
- public static final ASN1ObjectIdentifier xmss_mt = bc_sig.branch("3");
- public static final ASN1ObjectIdentifier xmss_mt_SHA256ph = xmss_mt.branch("1");
- public static final ASN1ObjectIdentifier xmss_mt_SHA512ph = xmss_mt.branch("2");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE128ph = xmss_mt.branch("3");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE256ph = xmss_mt.branch("4");
- public static final ASN1ObjectIdentifier xmss_mt_SHA256 = xmss_mt.branch("5");
- public static final ASN1ObjectIdentifier xmss_mt_SHA512 = xmss_mt.branch("6");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE128 = xmss_mt.branch("7");
- public static final ASN1ObjectIdentifier xmss_mt_SHAKE256 = xmss_mt.branch("8");
-
- // old OIDs.
- /**
- * @deprecated use xmss_SHA256ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHA256 = xmss_SHA256ph;
- /**
- * @deprecated use xmss_SHA512ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHA512 = xmss_SHA512ph;
- /**
- * @deprecated use xmss_SHAKE128ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHAKE128 = xmss_SHAKE128ph;
- /**
- * @deprecated use xmss_SHAKE256ph
- */
- public static final ASN1ObjectIdentifier xmss_with_SHAKE256 = xmss_SHAKE256ph;
-
- /**
- * @deprecated use xmss_mt_SHA256ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHA256 = xmss_mt_SHA256ph;
- /**
- * @deprecated use xmss_mt_SHA512ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHA512 = xmss_mt_SHA512ph;
- /**
- * @deprecated use xmss_mt_SHAKE128ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE128 = xmss_mt_SHAKE128;
- /**
- * @deprecated use xmss_mt_SHAKE256ph
- */
- public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE256 = xmss_mt_SHAKE256;
+ ASN1ObjectIdentifier xmss_mt = bc_sig.branch("3");
+ ASN1ObjectIdentifier xmss_mt_SHA256ph = xmss_mt.branch("1");
+ ASN1ObjectIdentifier xmss_mt_SHA512ph = xmss_mt.branch("2");
+ ASN1ObjectIdentifier xmss_mt_SHAKE128_512ph = xmss_mt.branch("3");
+ ASN1ObjectIdentifier xmss_mt_SHAKE256_1024ph = xmss_mt.branch("4");
+ ASN1ObjectIdentifier xmss_mt_SHA256 = xmss_mt.branch("5");
+ ASN1ObjectIdentifier xmss_mt_SHA512 = xmss_mt.branch("6");
+ ASN1ObjectIdentifier xmss_mt_SHAKE128 = xmss_mt.branch("7");
+ ASN1ObjectIdentifier xmss_mt_SHAKE256 = xmss_mt.branch("8");
+ ASN1ObjectIdentifier xmss_mt_SHAKE128ph = xmss_mt.branch("9");
+ ASN1ObjectIdentifier xmss_mt_SHAKE256ph = xmss_mt.branch("10");
/**
* qTESLA
*/
- public static final ASN1ObjectIdentifier qTESLA = bc_sig.branch("4");
+ ASN1ObjectIdentifier qTESLA = bc_sig.branch("4");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_I = qTESLA.branch("1");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_size = qTESLA.branch("2");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_speed = qTESLA.branch("3");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_I = qTESLA.branch("4");
- public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_III = qTESLA.branch("5");
+ ASN1ObjectIdentifier qTESLA_Rnd1_I = qTESLA.branch("1");
+ ASN1ObjectIdentifier qTESLA_Rnd1_III_size = qTESLA.branch("2");
+ ASN1ObjectIdentifier qTESLA_Rnd1_III_speed = qTESLA.branch("3");
+ ASN1ObjectIdentifier qTESLA_Rnd1_p_I = qTESLA.branch("4");
+ ASN1ObjectIdentifier qTESLA_Rnd1_p_III = qTESLA.branch("5");
- public static final ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("11");
- public static final ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("12");
+ ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("11");
+ ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("12");
+
+ /**
+ * SPHINCS+
+ */
+ ASN1ObjectIdentifier sphincsPlus = bc_sig.branch("5");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128s_r3 = sphincsPlus.branch("1");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128f_r3 = sphincsPlus.branch("2");
+ ASN1ObjectIdentifier sphincsPlus_shake_128s_r3 = sphincsPlus.branch("3");
+ ASN1ObjectIdentifier sphincsPlus_shake_128f_r3 = sphincsPlus.branch("4");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128s_r3 = sphincsPlus.branch("5");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128f_r3 = sphincsPlus.branch("6");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_192s_r3 = sphincsPlus.branch("7");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192f_r3 = sphincsPlus.branch("8");
+ ASN1ObjectIdentifier sphincsPlus_shake_192s_r3 = sphincsPlus.branch("9");
+ ASN1ObjectIdentifier sphincsPlus_shake_192f_r3 = sphincsPlus.branch("10");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192s_r3 = sphincsPlus.branch("11");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192f_r3 = sphincsPlus.branch("12");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_256s_r3 = sphincsPlus.branch("13");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256f_r3 = sphincsPlus.branch("14");
+ ASN1ObjectIdentifier sphincsPlus_shake_256s_r3 = sphincsPlus.branch("15");
+ ASN1ObjectIdentifier sphincsPlus_shake_256f_r3 = sphincsPlus.branch("16");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256s_r3 = sphincsPlus.branch("17");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256f_r3 = sphincsPlus.branch("18");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_128s_r3_simple = sphincsPlus.branch("19");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128f_r3_simple = sphincsPlus.branch("20");
+ ASN1ObjectIdentifier sphincsPlus_shake_128s_r3_simple = sphincsPlus.branch("21");
+ ASN1ObjectIdentifier sphincsPlus_shake_128f_r3_simple = sphincsPlus.branch("22");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128s_r3_simple = sphincsPlus.branch("23");
+ ASN1ObjectIdentifier sphincsPlus_haraka_128f_r3_simple = sphincsPlus.branch("24");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_192s_r3_simple = sphincsPlus.branch("25");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192f_r3_simple = sphincsPlus.branch("26");
+ ASN1ObjectIdentifier sphincsPlus_shake_192s_r3_simple = sphincsPlus.branch("27");
+ ASN1ObjectIdentifier sphincsPlus_shake_192f_r3_simple = sphincsPlus.branch("28");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192s_r3_simple = sphincsPlus.branch("29");
+ ASN1ObjectIdentifier sphincsPlus_haraka_192f_r3_simple = sphincsPlus.branch("30");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_256s_r3_simple = sphincsPlus.branch("31");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256f_r3_simple = sphincsPlus.branch("32");
+ ASN1ObjectIdentifier sphincsPlus_shake_256s_r3_simple = sphincsPlus.branch("33");
+ ASN1ObjectIdentifier sphincsPlus_shake_256f_r3_simple = sphincsPlus.branch("34");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256s_r3_simple = sphincsPlus.branch("35");
+ ASN1ObjectIdentifier sphincsPlus_haraka_256f_r3_simple = sphincsPlus.branch("36");
+
+
+ ASN1ObjectIdentifier sphincsPlus_interop = new ASN1ObjectIdentifier("1.3.9999.6");
+
+ ASN1ObjectIdentifier sphincsPlus_sha2_128f = new ASN1ObjectIdentifier("1.3.9999.6.4.13");
+ ASN1ObjectIdentifier sphincsPlus_sha2_128s = new ASN1ObjectIdentifier("1.3.9999.6.4.16");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192f = new ASN1ObjectIdentifier("1.3.9999.6.5.10");
+ ASN1ObjectIdentifier sphincsPlus_sha2_192s = new ASN1ObjectIdentifier("1.3.9999.6.5.12");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256f = new ASN1ObjectIdentifier("1.3.9999.6.6.10");
+ ASN1ObjectIdentifier sphincsPlus_sha2_256s = new ASN1ObjectIdentifier("1.3.9999.6.6.12");
+
+ ASN1ObjectIdentifier sphincsPlus_shake_128f = new ASN1ObjectIdentifier("1.3.9999.6.7.13");
+ ASN1ObjectIdentifier sphincsPlus_shake_128s = new ASN1ObjectIdentifier("1.3.9999.6.7.16");
+ ASN1ObjectIdentifier sphincsPlus_shake_192f = new ASN1ObjectIdentifier("1.3.9999.6.8.10");
+ ASN1ObjectIdentifier sphincsPlus_shake_192s = new ASN1ObjectIdentifier("1.3.9999.6.8.12");
+ ASN1ObjectIdentifier sphincsPlus_shake_256f = new ASN1ObjectIdentifier("1.3.9999.6.9.10");
+ ASN1ObjectIdentifier sphincsPlus_shake_256s = new ASN1ObjectIdentifier("1.3.9999.6.9.12");
+
+ /**
+ * Picnic
+ */
+ ASN1ObjectIdentifier picnic = bc_sig.branch("6");
+
+ ASN1ObjectIdentifier picnic_key = picnic.branch("1");
+
+ ASN1ObjectIdentifier picnicl1fs = picnic_key.branch("1");
+ ASN1ObjectIdentifier picnicl1ur = picnic_key.branch("2");
+ ASN1ObjectIdentifier picnicl3fs = picnic_key.branch("3");
+ ASN1ObjectIdentifier picnicl3ur = picnic_key.branch("4");
+ ASN1ObjectIdentifier picnicl5fs = picnic_key.branch("5");
+ ASN1ObjectIdentifier picnicl5ur = picnic_key.branch("6");
+ ASN1ObjectIdentifier picnic3l1 = picnic_key.branch("7");
+ ASN1ObjectIdentifier picnic3l3 = picnic_key.branch("8");
+ ASN1ObjectIdentifier picnic3l5 = picnic_key.branch("9");
+ ASN1ObjectIdentifier picnicl1full = picnic_key.branch("10");
+ ASN1ObjectIdentifier picnicl3full = picnic_key.branch("11");
+ ASN1ObjectIdentifier picnicl5full = picnic_key.branch("12");
+
+ ASN1ObjectIdentifier picnic_signature = picnic.branch("2");
+ ASN1ObjectIdentifier picnic_with_sha512 = picnic_signature.branch("1");
+ ASN1ObjectIdentifier picnic_with_shake256 = picnic_signature.branch("2");
+ ASN1ObjectIdentifier picnic_with_sha3_512 = picnic_signature.branch("3");
+
+
+ /*
+ * Falcon
+ */
+ ASN1ObjectIdentifier falcon = bc_sig.branch("7");
+
+ ASN1ObjectIdentifier falcon_512 = new ASN1ObjectIdentifier("1.3.9999.3.6"); // falcon.branch("1");
+ ASN1ObjectIdentifier falcon_1024 = new ASN1ObjectIdentifier("1.3.9999.3.9"); // falcon.branch("2");
+
+ /*
+ * Dilithium
+ */
+ ASN1ObjectIdentifier dilithium = bc_sig.branch("8");
+
+ // OpenSSL OIDs
+ ASN1ObjectIdentifier dilithium2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.4.4"); // dilithium.branch("1");
+ ASN1ObjectIdentifier dilithium3 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.6.5"); // dilithium.branch("2");
+ ASN1ObjectIdentifier dilithium5 = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.12.8.7"); // dilithium.branch("3");
+ ASN1ObjectIdentifier dilithium2_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.4.4"); // dilithium.branch("4");
+ ASN1ObjectIdentifier dilithium3_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.6.5"); // dilithium.branch("5");
+ ASN1ObjectIdentifier dilithium5_aes = new ASN1ObjectIdentifier("1.3.6.1.4.1.2.267.11.8.7"); // dilithium.branch("6");
+
+ /*
+ * Rainbow
+ */
+ ASN1ObjectIdentifier rainbow = bc_sig.branch("9");
+
+ ASN1ObjectIdentifier rainbow_III_classic = rainbow.branch("1");
+ ASN1ObjectIdentifier rainbow_III_circumzenithal = rainbow.branch("2");
+ ASN1ObjectIdentifier rainbow_III_compressed = rainbow.branch("3");
+ ASN1ObjectIdentifier rainbow_V_classic = rainbow.branch("4");
+ ASN1ObjectIdentifier rainbow_V_circumzenithal = rainbow.branch("5");
+ ASN1ObjectIdentifier rainbow_V_compressed = rainbow.branch("6");
/**
* key_exchange(3) algorithms
- *
- public static final ASN1ObjectIdentifier bc_exch = bc.branch("3");
+ */
+ ASN1ObjectIdentifier bc_exch = bc.branch("3");
/**
* NewHope
- *
- public static final ASN1ObjectIdentifier newHope = bc_exch.branch("1");
- */
- // END Android-removed: Unsupported algorithms
+ */
+ ASN1ObjectIdentifier newHope = bc_exch.branch("1");
/**
- * X.509 extension(4) values
+ * X.509 extension/certificate types
* <p>
* 1.3.6.1.4.1.22554.4
*/
- public static final ASN1ObjectIdentifier bc_ext = bc.branch("4");
+ ASN1ObjectIdentifier bc_ext = bc.branch("4");
- public static final ASN1ObjectIdentifier linkedCertificate = bc_ext.branch("1");
+ ASN1ObjectIdentifier linkedCertificate = bc_ext.branch("1");
+ ASN1ObjectIdentifier external_value = bc_ext.branch("2");
+
+ /**
+ * KEM(5) algorithms
+ */
+ ASN1ObjectIdentifier bc_kem = bc.branch("5");
+
+ /**
+ * Classic McEliece
+ */
+ ASN1ObjectIdentifier pqc_kem_mceliece = bc_kem.branch("1");
+
+ ASN1ObjectIdentifier mceliece348864_r3 = pqc_kem_mceliece.branch("1");
+ ASN1ObjectIdentifier mceliece348864f_r3 = pqc_kem_mceliece.branch("2");
+ ASN1ObjectIdentifier mceliece460896_r3 = pqc_kem_mceliece.branch("3");
+ ASN1ObjectIdentifier mceliece460896f_r3 = pqc_kem_mceliece.branch("4");
+ ASN1ObjectIdentifier mceliece6688128_r3 = pqc_kem_mceliece.branch("5");
+ ASN1ObjectIdentifier mceliece6688128f_r3 = pqc_kem_mceliece.branch("6");
+ ASN1ObjectIdentifier mceliece6960119_r3 = pqc_kem_mceliece.branch("7");
+ ASN1ObjectIdentifier mceliece6960119f_r3 = pqc_kem_mceliece.branch("8");
+ ASN1ObjectIdentifier mceliece8192128_r3 = pqc_kem_mceliece.branch("9");
+ ASN1ObjectIdentifier mceliece8192128f_r3 = pqc_kem_mceliece.branch("10");
+
+
+ /**
+ * Frodo
+ */
+ ASN1ObjectIdentifier pqc_kem_frodo = bc_kem.branch("2");
+
+ ASN1ObjectIdentifier frodokem640aes = pqc_kem_frodo.branch("1");
+ ASN1ObjectIdentifier frodokem640shake = pqc_kem_frodo.branch("2");
+ ASN1ObjectIdentifier frodokem976aes = pqc_kem_frodo.branch("3");
+ ASN1ObjectIdentifier frodokem976shake = pqc_kem_frodo.branch("4");
+ ASN1ObjectIdentifier frodokem1344aes = pqc_kem_frodo.branch("5");
+ ASN1ObjectIdentifier frodokem1344shake = pqc_kem_frodo.branch("6");
+
+ /**
+ * SABER
+ */
+ ASN1ObjectIdentifier pqc_kem_saber = bc_kem.branch("3");
+
+ ASN1ObjectIdentifier lightsaberkem128r3 = pqc_kem_saber.branch("1");
+ ASN1ObjectIdentifier saberkem128r3 = pqc_kem_saber.branch("2");
+ ASN1ObjectIdentifier firesaberkem128r3 = pqc_kem_saber.branch("3");
+ ASN1ObjectIdentifier lightsaberkem192r3 = pqc_kem_saber.branch("4");
+ ASN1ObjectIdentifier saberkem192r3 = pqc_kem_saber.branch("5");
+ ASN1ObjectIdentifier firesaberkem192r3 = pqc_kem_saber.branch("6");
+ ASN1ObjectIdentifier lightsaberkem256r3 = pqc_kem_saber.branch("7");
+ ASN1ObjectIdentifier saberkem256r3 = pqc_kem_saber.branch("8");
+ ASN1ObjectIdentifier firesaberkem256r3 = pqc_kem_saber.branch("9");
+ ASN1ObjectIdentifier ulightsaberkemr3 = pqc_kem_saber.branch("10");
+ ASN1ObjectIdentifier usaberkemr3 = pqc_kem_saber.branch("11");
+ ASN1ObjectIdentifier ufiresaberkemr3 = pqc_kem_saber.branch("12");
+ ASN1ObjectIdentifier lightsaberkem90sr3 = pqc_kem_saber.branch("13");
+ ASN1ObjectIdentifier saberkem90sr3 = pqc_kem_saber.branch("14");
+ ASN1ObjectIdentifier firesaberkem90sr3 = pqc_kem_saber.branch("15");
+ ASN1ObjectIdentifier ulightsaberkem90sr3 = pqc_kem_saber.branch("16");
+ ASN1ObjectIdentifier usaberkem90sr3 = pqc_kem_saber.branch("17");
+ ASN1ObjectIdentifier ufiresaberkem90sr3 = pqc_kem_saber.branch("18");
+
+ /**
+ * SIKE
+ */
+ ASN1ObjectIdentifier pqc_kem_sike = bc_kem.branch("4");
+
+ ASN1ObjectIdentifier sikep434 = pqc_kem_sike.branch("1");
+ ASN1ObjectIdentifier sikep503 = pqc_kem_sike.branch("2");
+ ASN1ObjectIdentifier sikep610 = pqc_kem_sike.branch("3");
+ ASN1ObjectIdentifier sikep751 = pqc_kem_sike.branch("4");
+ ASN1ObjectIdentifier sikep434_compressed = pqc_kem_sike.branch("5");
+ ASN1ObjectIdentifier sikep503_compressed = pqc_kem_sike.branch("6");
+ ASN1ObjectIdentifier sikep610_compressed = pqc_kem_sike.branch("7");
+ ASN1ObjectIdentifier sikep751_compressed = pqc_kem_sike.branch("8");
+
+ /**
+ * NTRU
+ */
+ ASN1ObjectIdentifier pqc_kem_ntru = bc_kem.branch("5");
+
+ ASN1ObjectIdentifier ntruhps2048509 = pqc_kem_ntru.branch("1");
+ ASN1ObjectIdentifier ntruhps2048677 = pqc_kem_ntru.branch("2");
+ ASN1ObjectIdentifier ntruhps4096821 = pqc_kem_ntru.branch("3");
+ ASN1ObjectIdentifier ntruhrss701 = pqc_kem_ntru.branch("4");
+
+ /**
+ * Kyber
+ */
+ ASN1ObjectIdentifier pqc_kem_kyber = bc_kem.branch("6");
+
+ ASN1ObjectIdentifier kyber512 = pqc_kem_kyber.branch("1");
+ ASN1ObjectIdentifier kyber768 = pqc_kem_kyber.branch("2");
+ ASN1ObjectIdentifier kyber1024 = pqc_kem_kyber.branch("3");
+ ASN1ObjectIdentifier kyber512_aes = pqc_kem_kyber.branch("4");
+ ASN1ObjectIdentifier kyber768_aes = pqc_kem_kyber.branch("5");
+ ASN1ObjectIdentifier kyber1024_aes = pqc_kem_kyber.branch("6");
+
+ /**
+ * NTRUPrime
+ */
+ ASN1ObjectIdentifier pqc_kem_ntruprime = bc_kem.branch("7");
+
+ ASN1ObjectIdentifier pqc_kem_ntrulprime = pqc_kem_ntruprime.branch("1");
+ ASN1ObjectIdentifier ntrulpr653 = pqc_kem_ntrulprime.branch("1");
+ ASN1ObjectIdentifier ntrulpr761 = pqc_kem_ntrulprime.branch("2");
+ ASN1ObjectIdentifier ntrulpr857 = pqc_kem_ntrulprime.branch("3");
+ ASN1ObjectIdentifier ntrulpr953 = pqc_kem_ntrulprime.branch("4");
+ ASN1ObjectIdentifier ntrulpr1013 = pqc_kem_ntrulprime.branch("5");
+ ASN1ObjectIdentifier ntrulpr1277 = pqc_kem_ntrulprime.branch("6");
+
+ ASN1ObjectIdentifier pqc_kem_sntruprime = pqc_kem_ntruprime.branch("2");
+ ASN1ObjectIdentifier sntrup653 = pqc_kem_sntruprime.branch("1");
+ ASN1ObjectIdentifier sntrup761 = pqc_kem_sntruprime.branch("2");
+ ASN1ObjectIdentifier sntrup857 = pqc_kem_sntruprime.branch("3");
+ ASN1ObjectIdentifier sntrup953 = pqc_kem_sntruprime.branch("4");
+ ASN1ObjectIdentifier sntrup1013 = pqc_kem_sntruprime.branch("5");
+ ASN1ObjectIdentifier sntrup1277 = pqc_kem_sntruprime.branch("6");
+
+ /**
+ * BIKE
+ **/
+ ASN1ObjectIdentifier pqc_kem_bike = bc_kem.branch("8");
+
+ ASN1ObjectIdentifier bike128 = pqc_kem_bike.branch("1");
+ ASN1ObjectIdentifier bike192 = pqc_kem_bike.branch("2");
+ ASN1ObjectIdentifier bike256 = pqc_kem_bike.branch("3");
+
+ /**
+ * HQC
+ **/
+ ASN1ObjectIdentifier pqc_kem_hqc = bc_kem.branch("9");
+
+ ASN1ObjectIdentifier hqc128 = pqc_kem_hqc.branch("1");
+ ASN1ObjectIdentifier hqc192 = pqc_kem_hqc.branch("2");
+ ASN1ObjectIdentifier hqc256 = pqc_kem_hqc.branch("3");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/ExternalValue.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/ExternalValue.java
new file mode 100644
index 0000000..97c1eeb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/ExternalValue.java
@@ -0,0 +1,119 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.bc;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralNames;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Based on External Keys And Signatures For Use In Internet PKI
+ * draft-ounsworth-pq-external-pubkeys-00
+ * <pre>
+ * ExternalValue ::= SEQUENCE {
+ * location GeneralNames, # MUST refer to a DER encoded SubjectPublicKeyInfo/Signature (may be Base64)
+ * hashAlg AlgorithmIdentifier,
+ * hashVal OCTET STRING }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExternalValue
+ extends ASN1Object
+{
+ private final GeneralNames location;
+ private final AlgorithmIdentifier hashAlg;
+ private final byte[] hashValue;
+
+ public ExternalValue(GeneralName location, AlgorithmIdentifier hashAlg, byte[] hashVal)
+ {
+ this.location = new GeneralNames(location);
+ this.hashAlg = hashAlg;
+ this.hashValue = Arrays.clone(hashVal);
+ }
+
+ private ExternalValue(ASN1Sequence seq)
+ {
+ if (seq.size() == 3)
+ {
+ location = GeneralNames.getInstance(seq.getObjectAt(0));
+ hashAlg = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ if (seq.getObjectAt(2) instanceof ASN1BitString) // legacy implementation on 2021 draft
+ {
+ hashValue = ASN1BitString.getInstance(seq.getObjectAt(2)).getOctets();
+ }
+ else
+ {
+ hashValue = ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets();
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown sequence");
+ }
+ }
+
+ public static ExternalValue getInstance(Object o)
+ {
+ if (o instanceof ExternalValue)
+ {
+ return (ExternalValue)o;
+ }
+ else if (o != null)
+ {
+ return new ExternalValue(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public GeneralName getLocation()
+ {
+ return location.getNames()[0];
+ }
+
+ public GeneralName[] getLocations()
+ {
+ return location.getNames();
+ }
+
+ public AlgorithmIdentifier getHashAlg()
+ {
+ return hashAlg;
+ }
+
+ public byte[] getHashValue()
+ {
+ return Arrays.clone(hashValue);
+ }
+
+ /**
+ * Get the hash value as a BIT STRING.
+ *
+ * @return the hash value as a BIT STRING
+ * @deprecated use getHash(), the internal encoding is now an OCTET STRING
+ */
+ public ASN1BitString getHashVal()
+ {
+ return new DERBitString(hashValue);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(location);
+ v.add(hashAlg);
+ v.add(new DEROctetString(hashValue));
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/LinkedCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/LinkedCertificate.java
new file mode 100644
index 0000000..2798bc8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/LinkedCertificate.java
@@ -0,0 +1,128 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.bc;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.DigestInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralNames;
+
+/**
+ * Extension to tie an alternate certificate to the containing certificate.
+ * <pre>
+ * LinkedCertificate := SEQUENCE {
+ * digest DigestInfo, -- digest of PQC certificate
+ * certLocation GeneralName, -- location of PQC certificate
+ * certIssuer [0] Name OPTIONAL, -- issuer of PQC cert (if different from current certificate)
+ * cACerts [1] GeneralNames OPTIONAL, -- CA certificates for PQC cert (one of more locations)
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class LinkedCertificate
+ extends ASN1Object
+{
+ private final DigestInfo digest;
+ private final GeneralName certLocation;
+
+ private X500Name certIssuer;
+ private GeneralNames cACerts;
+
+ public LinkedCertificate(DigestInfo digest, GeneralName certLocation)
+ {
+ this(digest, certLocation, null, null);
+ }
+
+ public LinkedCertificate(DigestInfo digest, GeneralName certLocation, X500Name certIssuer, GeneralNames cACerts)
+ {
+ this.digest = digest;
+ this.certLocation = certLocation;
+ this.certIssuer = certIssuer;
+ this.cACerts = cACerts;
+ }
+
+ private LinkedCertificate(ASN1Sequence seq)
+ {
+ this.digest = DigestInfo.getInstance(seq.getObjectAt(0));
+ this.certLocation = GeneralName.getInstance(seq.getObjectAt(1));
+
+ if (seq.size() > 2)
+ {
+ for (int i = 2; i != seq.size(); i++)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(i));
+
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ certIssuer = X500Name.getInstance(tagged, false);
+ break;
+ case 1:
+ cACerts = GeneralNames.getInstance(tagged, false);
+ break;
+ default:
+ throw new IllegalArgumentException("unknown tag in tagged field");
+ }
+ }
+ }
+ }
+
+ public static LinkedCertificate getInstance(Object o)
+ {
+ if (o instanceof LinkedCertificate)
+ {
+ return (LinkedCertificate)o;
+ }
+ else if (o != null)
+ {
+ return new LinkedCertificate(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public DigestInfo getDigest()
+ {
+ return digest;
+ }
+
+ public GeneralName getCertLocation()
+ {
+ return certLocation;
+ }
+
+ public X500Name getCertIssuer()
+ {
+ return certIssuer;
+ }
+
+ public GeneralNames getCACerts()
+ {
+ return cACerts;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(digest);
+ v.add(certLocation);
+
+ if (certIssuer != null)
+ {
+ v.add(new DERTaggedObject(false, 0, certIssuer));
+ }
+ if (cACerts != null)
+ {
+ v.add(new DERTaggedObject(false, 1, cACerts));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java
index 51bbd3e..632eace 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java
@@ -130,3 +130,4 @@
return new BERSequence(v);
}
}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
deleted file mode 100644
index 798f8a1..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1.eac;
-
-import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-
-/**
- * German Federal Office for Information Security
- * (Bundesamt für Sicherheit in der Informationstechnik)
- * <a href="https://www.bsi.bund.de/">https://www.bsi.bund.de/</a>
- * <p>
- * <a href="https://www.bsi.bund.de/EN/Publications/TechnicalGuidelines/TR03110/BSITR03110.html">BSI TR-03110</a>
- * Technical Guideline Advanced Security Mechanisms for Machine Readable Travel Documents
- * <p>
- * <a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03110/TR-03110_v2.1_P3pdf.pdf">
- * Technical Guideline TR-03110-3</a>
- * Advanced Security Mechanisms for Machine Readable Travel Documents;
- * Part 3: Common Specifications.
- * @hide This class is not part of the Android public SDK API
- */
-public interface EACObjectIdentifiers
-{
- /**
- * <pre>
- * bsi-de OBJECT IDENTIFIER ::= {
- * itu-t(0) identified-organization(4) etsi(0)
- * reserved(127) etsi-identified-organization(0) 7
- * }
- * </pre>
- * OID: 0.4.0.127.0.7
- */
- static final ASN1ObjectIdentifier bsi_de = new ASN1ObjectIdentifier("0.4.0.127.0.7");
-
- /**
- * <pre>
- * id-PK OBJECT IDENTIFIER ::= {
- * bsi-de protocols(2) smartcard(2) 1
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.2.2.1
- */
- static final ASN1ObjectIdentifier id_PK = bsi_de.branch("2.2.1");
-
- /** OID: 0.4.0.127.0.7.2.2.1.1 */
- static final ASN1ObjectIdentifier id_PK_DH = id_PK.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.1.2 */
- static final ASN1ObjectIdentifier id_PK_ECDH = id_PK.branch("2");
-
- /**
- * <pre>
- * id-CA OBJECT IDENTIFIER ::= {
- * bsi-de protocols(2) smartcard(2) 3
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.2.2.3
- */
- static final ASN1ObjectIdentifier id_CA = bsi_de.branch("2.2.3");
- /** OID: 0.4.0.127.0.7.2.2.3.1 */
- static final ASN1ObjectIdentifier id_CA_DH = id_CA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.3.1.1 */
- static final ASN1ObjectIdentifier id_CA_DH_3DES_CBC_CBC = id_CA_DH.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.3.2 */
- static final ASN1ObjectIdentifier id_CA_ECDH = id_CA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.3.2.1 */
- static final ASN1ObjectIdentifier id_CA_ECDH_3DES_CBC_CBC = id_CA_ECDH.branch("1");
-
- /**
- * <pre>
- * id-TA OBJECT IDENTIFIER ::= {
- * bsi-de protocols(2) smartcard(2) 2
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.2.2.2
- */
- static final ASN1ObjectIdentifier id_TA = bsi_de.branch("2.2.2");
-
- /** OID: 0.4.0.127.0.7.2.2.2.1 */
- static final ASN1ObjectIdentifier id_TA_RSA = id_TA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.2.1.1 */
- static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_1 = id_TA_RSA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.2.1.2 */
- static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_256 = id_TA_RSA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.2.1.3 */
- static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_1 = id_TA_RSA.branch("3");
- /** OID: 0.4.0.127.0.7.2.2.2.1.4 */
- static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_256 = id_TA_RSA.branch("4");
- /** OID: 0.4.0.127.0.7.2.2.2.1.5 */
- static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_512 = id_TA_RSA.branch("5");
- /** OID: 0.4.0.127.0.7.2.2.2.1.6 */
- static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_512 = id_TA_RSA.branch("6");
- /** OID: 0.4.0.127.0.7.2.2.2.2 */
- static final ASN1ObjectIdentifier id_TA_ECDSA = id_TA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.2.2.1 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_1 = id_TA_ECDSA.branch("1");
- /** OID: 0.4.0.127.0.7.2.2.2.2.2 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_224 = id_TA_ECDSA.branch("2");
- /** OID: 0.4.0.127.0.7.2.2.2.2.3 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_256 = id_TA_ECDSA.branch("3");
- /** OID: 0.4.0.127.0.7.2.2.2.2.4 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_384 = id_TA_ECDSA.branch("4");
- /** OID: 0.4.0.127.0.7.2.2.2.2.5 */
- static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_512 = id_TA_ECDSA.branch("5");
-
- /**
- * <pre>
- * id-EAC-ePassport OBJECT IDENTIFIER ::= {
- * bsi-de applications(3) mrtd(1) roles(2) 1
- * }
- * </pre>
- * OID: 0.4.0.127.0.7.3.1.2.1
- */
- static final ASN1ObjectIdentifier id_EAC_ePassport = bsi_de.branch("3.1.2.1");
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java
index 52ed008..ed5fdaf 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java
@@ -8,6 +8,8 @@
*/
public interface GMObjectIdentifiers
{
+ //1.2.156.10197: Chinese Cryptography Standardization Technology Committee (CCSTC)
+ //1.2.156.11235: China Broadband Wireless IP Standard Group
ASN1ObjectIdentifier sm_scheme = new ASN1ObjectIdentifier("1.2.156.10197.1");
ASN1ObjectIdentifier sm6_ecb = sm_scheme.branch("101.1");
@@ -50,7 +52,20 @@
ASN1ObjectIdentifier sm2exchange = sm_scheme.branch("301.2");
ASN1ObjectIdentifier sm2encrypt = sm_scheme.branch("301.3");
- ASN1ObjectIdentifier wapip192v1 = sm_scheme.branch("301.101");
+ /**
+ * <Information security technology — Cryptographic application identifier criterion specification>
+ * <url>http://c.gb688.cn/bzgk/gb/showGb?type=online&hcno=252CF0F72A7BE339A56DEA7D774E8994</url>,
+ * Page 21 only cover from 301.1 to 301.3
+ * */
+ ASN1ObjectIdentifier wapip192v1 = sm_scheme.branch("301.101");
+ /**
+ * <WAPI certificate management—Part 5: Example of certificate format (draft)>
+ * <url>http://www.chinabwips.org.cn/zqyjgs1.htm</url> and
+ * <url>http://www.chinabwips.org.cn/doc/101.pdf</url>,
+ * Page 9 and page 10 states the OID of ECDSA-192 algorithm based on SHA-256 is 1.2.156.11235.1.1.1
+ * */
+ ASN1ObjectIdentifier wapi192v1 = new ASN1ObjectIdentifier("1.2.156.11235.1.1.1");
+ ASN1ObjectIdentifier wapi192v1_parameters = new ASN1ObjectIdentifier("1.2.156.11235.1.1.2.1");
ASN1ObjectIdentifier sm2encrypt_recommendedParameters = sm2encrypt.branch("1");
ASN1ObjectIdentifier sm2encrypt_specifiedParameters = sm2encrypt.branch("2");
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java
new file mode 100644
index 0000000..2c30ba0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/isara/IsaraObjectIdentifiers.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.isara;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface IsaraObjectIdentifiers
+{
+ /*
+ id-alg-xmss OBJECT IDENTIFIER ::= { itu-t(0)
+ identified-organization(4) etsi(0) reserved(127)
+ etsi-identified-organization(0) isara(15) algorithms(1)
+ asymmetric(1) xmss(13) 0 }
+ */
+ static ASN1ObjectIdentifier id_alg_xmss = new ASN1ObjectIdentifier("0.4.0.127.0.15.1.1.13.0");
+
+ /*
+ id-alg-xmssmt OBJECT IDENTIFIER ::= { itu-t(0)
+ identified-organization(4) etsi(0) reserved(127)
+ etsi-identified-organization(0) isara(15) algorithms(1)
+ asymmetric(1) xmssmt(14) 0 }
+ */
+ static ASN1ObjectIdentifier id_alg_xmssmt = new ASN1ObjectIdentifier("0.4.0.127.0.15.1.1.14.0");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
index 2f69dde..ddf540d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
@@ -128,7 +128,7 @@
ASN1ObjectIdentifier cryptlib_algorithm_blowfish_OFB = cryptlib_algorithm.branch("1.4");
//
- // Blake2b
+ // Blake2b/Blake2s
//
ASN1ObjectIdentifier blake2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.1722.12.2");
@@ -142,6 +142,10 @@
ASN1ObjectIdentifier id_blake2s224 = blake2.branch("2.7");
ASN1ObjectIdentifier id_blake2s256 = blake2.branch("2.8");
+ ASN1ObjectIdentifier blake3 = blake2.branch("3");
+
+ ASN1ObjectIdentifier blake3_256 = blake3.branch("8");
+
//
// Scrypt
ASN1ObjectIdentifier id_scrypt = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.4.11");
@@ -152,4 +156,15 @@
// iso(1) identified-organization(3) dod(6) internet(1) private(4)
// enterprise(1) OpenCA(18227) Algorithms(2) id-alg-composite(1) }
ASN1ObjectIdentifier id_alg_composite = new ASN1ObjectIdentifier("1.3.6.1.4.1.18227.2.1");
+
+ // -- To be replaced by IANA
+ //
+ //id-composite-key OBJECT IDENTIFIER ::= {
+ //
+ // joint-iso-itu-t(2) country(16) us(840) organization(1) entrust(114027)
+ //
+ // Algorithm(80) Composite(4) CompositeKey(1)
+ ASN1ObjectIdentifier id_composite_key = new ASN1ObjectIdentifier("2.16.840.1.114027.80.4.1");
+
+ ASN1ObjectIdentifier id_oracle_pkcs12_trusted_key_usage = new ASN1ObjectIdentifier("2.16.840.1.113894.746875.1.1");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeCertType.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeCertType.java
index 2fdac51..4e6d53a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeCertType.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeCertType.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.misc;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
/**
@@ -44,13 +45,18 @@
}
public NetscapeCertType(
- DERBitString usage)
+ ASN1BitString usage)
{
super(usage.getBytes(), usage.getPadBits());
}
+ public boolean hasUsages(int usages)
+ {
+ return (intValue() & usages) == usages;
+ }
+
public String toString()
{
- return "NetscapeCertType: 0x" + Integer.toHexString(data[0] & 0xff);
+ return "NetscapeCertType: 0x" + Integer.toHexString(intValue());
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java
index ed0f5e2..52b1912 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.misc;
+import com.android.internal.org.bouncycastle.asn1.ASN1IA5String;
import com.android.internal.org.bouncycastle.asn1.DERIA5String;
/**
@@ -10,7 +11,7 @@
extends DERIA5String
{
public NetscapeRevocationURL(
- DERIA5String str)
+ ASN1IA5String str)
{
super(str.getString());
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/VerisignCzagExtension.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/VerisignCzagExtension.java
index a570d70..1b6cf2a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/VerisignCzagExtension.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/VerisignCzagExtension.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.misc;
+import com.android.internal.org.bouncycastle.asn1.ASN1IA5String;
import com.android.internal.org.bouncycastle.asn1.DERIA5String;
/**
@@ -10,7 +11,7 @@
extends DERIA5String
{
public VerisignCzagExtension(
- DERIA5String str)
+ ASN1IA5String str)
{
super(str.getString());
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java
new file mode 100644
index 0000000..d1c84bb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java
@@ -0,0 +1,116 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.nist;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * KMACwithSHAKE128-params ::= SEQUENCE {
+ * kMACOutputLength INTEGER DEFAULT 256, -- Output length in bits
+ * customizationString OCTET STRING DEFAULT ''H
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KMACwithSHAKE128_params
+ extends ASN1Object
+{
+ private static final byte[] EMPTY_STRING = new byte[0];
+ private static final int DEF_LENGTH = 256;
+
+ private final int outputLength;
+ private final byte[] customizationString;
+
+ public KMACwithSHAKE128_params(int outputLength)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = EMPTY_STRING;
+ }
+
+ public KMACwithSHAKE128_params(int outputLength, byte[] customizationString)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = Arrays.clone(customizationString);
+ }
+
+ public static KMACwithSHAKE128_params getInstance(Object o)
+ {
+ if (o instanceof KMACwithSHAKE128_params)
+ {
+ return (KMACwithSHAKE128_params)o;
+ }
+ else if (o != null)
+ {
+ return new KMACwithSHAKE128_params(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ private KMACwithSHAKE128_params(ASN1Sequence seq)
+ {
+ if (seq.size() > 2)
+ {
+ throw new IllegalArgumentException("sequence size greater than 2");
+ }
+
+ if (seq.size() == 2)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+ }
+ else if (seq.size() == 1)
+ {
+ if (seq.getObjectAt(0) instanceof ASN1Integer)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = EMPTY_STRING;
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
+ }
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = EMPTY_STRING;
+ }
+ }
+
+ public int getOutputLength()
+ {
+ return outputLength;
+ }
+
+ public byte[] getCustomizationString()
+ {
+ return Arrays.clone(customizationString);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (outputLength != DEF_LENGTH)
+ {
+ v.add(new ASN1Integer(outputLength));
+ }
+
+ if (customizationString.length != 0)
+ {
+ v.add(new DEROctetString(getCustomizationString()));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java
new file mode 100644
index 0000000..926c0f7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java
@@ -0,0 +1,116 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.nist;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * KMACwithSHAKE256-params ::= SEQUENCE {
+ * kMACOutputLength INTEGER DEFAULT 512, -- Output length in bits
+ * customizationString OCTET STRING DEFAULT ''H
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KMACwithSHAKE256_params
+ extends ASN1Object
+{
+ private static final byte[] EMPTY_STRING = new byte[0];
+ private static final int DEF_LENGTH = 512;
+
+ private final int outputLength;
+ private final byte[] customizationString;
+
+ public KMACwithSHAKE256_params(int outputLength)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = EMPTY_STRING;
+ }
+
+ public KMACwithSHAKE256_params(int outputLength, byte[] customizationString)
+ {
+ this.outputLength = outputLength;
+ this.customizationString = Arrays.clone(customizationString);
+ }
+
+ public static KMACwithSHAKE256_params getInstance(Object o)
+ {
+ if (o instanceof KMACwithSHAKE256_params)
+ {
+ return (KMACwithSHAKE256_params)o;
+ }
+ else if (o != null)
+ {
+ return new KMACwithSHAKE256_params(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ private KMACwithSHAKE256_params(ASN1Sequence seq)
+ {
+ if (seq.size() > 2)
+ {
+ throw new IllegalArgumentException("sequence size greater than 2");
+ }
+
+ if (seq.size() == 2)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+ }
+ else if (seq.size() == 1)
+ {
+ if (seq.getObjectAt(0) instanceof ASN1Integer)
+ {
+ this.outputLength = ASN1Integer.getInstance(seq.getObjectAt(0)).intValueExact();
+ this.customizationString = EMPTY_STRING;
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
+ }
+ }
+ else
+ {
+ this.outputLength = DEF_LENGTH;
+ this.customizationString = EMPTY_STRING;
+ }
+ }
+
+ public int getOutputLength()
+ {
+ return outputLength;
+ }
+
+ public byte[] getCustomizationString()
+ {
+ return Arrays.clone(customizationString);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (outputLength != DEF_LENGTH)
+ {
+ v.add(new ASN1Integer(outputLength));
+ }
+
+ if (customizationString.length != 0)
+ {
+ v.add(new DEROctetString(getCustomizationString()));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTNamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTNamedCurves.java
index fe9c18b..eba9e2b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTNamedCurves.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTNamedCurves.java
@@ -8,6 +8,7 @@
import com.android.internal.org.bouncycastle.asn1.sec.SECNamedCurves;
import com.android.internal.org.bouncycastle.asn1.sec.SECObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParametersHolder;
import com.android.internal.org.bouncycastle.util.Strings;
/**
@@ -44,17 +45,16 @@
defineCurve("P-192", SECObjectIdentifiers.secp192r1);
}
- public static X9ECParameters getByName(
- String name)
+ public static X9ECParameters getByName(String name)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name));
+ ASN1ObjectIdentifier oid = getOID(name);
+ return null != oid ? SECNamedCurves.getByOID(oid) : null;
+ }
- if (oid != null)
- {
- return getByOID(oid);
- }
-
- return null;
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ ASN1ObjectIdentifier oid = getOID(name);
+ return null != oid ? SECNamedCurves.getByOIDLazy(oid) : null;
}
/**
@@ -63,10 +63,14 @@
*
* @param oid an object identifier representing a named curve, if present.
*/
- public static X9ECParameters getByOID(
- ASN1ObjectIdentifier oid)
+ public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- return SECNamedCurves.getByOID(oid);
+ return names.containsKey(oid) ? SECNamedCurves.getByOID(oid) : null;
+ }
+
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return names.containsKey(oid) ? SECNamedCurves.getByOIDLazy(oid) : null;
}
/**
@@ -75,8 +79,7 @@
*
* @return the object identifier associated with name, if present.
*/
- public static ASN1ObjectIdentifier getOID(
- String name)
+ public static ASN1ObjectIdentifier getOID(String name)
{
return (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name));
}
@@ -84,8 +87,7 @@
/**
* return the named curve name represented by the given object identifier.
*/
- public static String getName(
- ASN1ObjectIdentifier oid)
+ public static String getName(ASN1ObjectIdentifier oid)
{
return (String)names.get(oid);
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
index db60cf0..208b9f9 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
@@ -60,69 +60,137 @@
/** 2.16.840.1.101.3.4.2.19 */
static final ASN1ObjectIdentifier id_KmacWithSHAKE128 = hashAlgs.branch("19");
/** 2.16.840.1.101.3.4.2.20 */
- static final ASN1ObjectIdentifier id_KmacWithSHAKE256 = hashAlgs.branch("20");
+ static final ASN1ObjectIdentifier id_KmacWithSHAKE256 = hashAlgs.branch("20");
- /** 2.16.840.1.101.3.4.1 */
- static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1");
-
- /** 2.16.840.1.101.3.4.1.1 */
- static final ASN1ObjectIdentifier id_aes128_ECB = aes.branch("1");
- /** 2.16.840.1.101.3.4.1.2 */
- static final ASN1ObjectIdentifier id_aes128_CBC = aes.branch("2");
- /** 2.16.840.1.101.3.4.1.3 */
- static final ASN1ObjectIdentifier id_aes128_OFB = aes.branch("3");
- /** 2.16.840.1.101.3.4.1.4 */
- static final ASN1ObjectIdentifier id_aes128_CFB = aes.branch("4");
- /** 2.16.840.1.101.3.4.1.5 */
- static final ASN1ObjectIdentifier id_aes128_wrap = aes.branch("5");
- /** 2.16.840.1.101.3.4.1.6 */
- static final ASN1ObjectIdentifier id_aes128_GCM = aes.branch("6");
- /** 2.16.840.1.101.3.4.1.7 */
- static final ASN1ObjectIdentifier id_aes128_CCM = aes.branch("7");
- /** 2.16.840.1.101.3.4.1.28 */
- static final ASN1ObjectIdentifier id_aes128_wrap_pad = aes.branch("8");
+ /**
+ * 2.16.840.1.101.3.4.1
+ */
+ static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1");
- /** 2.16.840.1.101.3.4.1.21 */
- static final ASN1ObjectIdentifier id_aes192_ECB = aes.branch("21");
- /** 2.16.840.1.101.3.4.1.22 */
- static final ASN1ObjectIdentifier id_aes192_CBC = aes.branch("22");
- /** 2.16.840.1.101.3.4.1.23 */
- static final ASN1ObjectIdentifier id_aes192_OFB = aes.branch("23");
- /** 2.16.840.1.101.3.4.1.24 */
- static final ASN1ObjectIdentifier id_aes192_CFB = aes.branch("24");
- /** 2.16.840.1.101.3.4.1.25 */
- static final ASN1ObjectIdentifier id_aes192_wrap = aes.branch("25");
- /** 2.16.840.1.101.3.4.1.26 */
- static final ASN1ObjectIdentifier id_aes192_GCM = aes.branch("26");
- /** 2.16.840.1.101.3.4.1.27 */
- static final ASN1ObjectIdentifier id_aes192_CCM = aes.branch("27");
- /** 2.16.840.1.101.3.4.1.28 */
- static final ASN1ObjectIdentifier id_aes192_wrap_pad = aes.branch("28");
+ /**
+ * 2.16.840.1.101.3.4.1.1
+ */
+ static final ASN1ObjectIdentifier id_aes128_ECB = aes.branch("1");
+ /**
+ * 2.16.840.1.101.3.4.1.2
+ */
+ static final ASN1ObjectIdentifier id_aes128_CBC = aes.branch("2");
+ /**
+ * 2.16.840.1.101.3.4.1.3
+ */
+ static final ASN1ObjectIdentifier id_aes128_OFB = aes.branch("3");
+ /**
+ * 2.16.840.1.101.3.4.1.4
+ */
+ static final ASN1ObjectIdentifier id_aes128_CFB = aes.branch("4");
+ /**
+ * 2.16.840.1.101.3.4.1.5
+ */
+ static final ASN1ObjectIdentifier id_aes128_wrap = aes.branch("5");
+ /**
+ * 2.16.840.1.101.3.4.1.6
+ */
+ static final ASN1ObjectIdentifier id_aes128_GCM = aes.branch("6");
+ /**
+ * 2.16.840.1.101.3.4.1.7
+ */
+ static final ASN1ObjectIdentifier id_aes128_CCM = aes.branch("7");
+ /**
+ * 2.16.840.1.101.3.4.1.8
+ */
+ static final ASN1ObjectIdentifier id_aes128_wrap_pad = aes.branch("8");
+ /**
+ * 2.16.840.1.101.3.4.1.9
+ */
+ static final ASN1ObjectIdentifier id_aes128_GMAC = aes.branch("9");
- /** 2.16.840.1.101.3.4.1.41 */
- static final ASN1ObjectIdentifier id_aes256_ECB = aes.branch("41");
- /** 2.16.840.1.101.3.4.1.42 */
- static final ASN1ObjectIdentifier id_aes256_CBC = aes.branch("42");
- /** 2.16.840.1.101.3.4.1.43 */
- static final ASN1ObjectIdentifier id_aes256_OFB = aes.branch("43");
- /** 2.16.840.1.101.3.4.1.44 */
- static final ASN1ObjectIdentifier id_aes256_CFB = aes.branch("44");
- /** 2.16.840.1.101.3.4.1.45 */
- static final ASN1ObjectIdentifier id_aes256_wrap = aes.branch("45");
- /** 2.16.840.1.101.3.4.1.46 */
- static final ASN1ObjectIdentifier id_aes256_GCM = aes.branch("46");
- /** 2.16.840.1.101.3.4.1.47 */
- static final ASN1ObjectIdentifier id_aes256_CCM = aes.branch("47");
- /** 2.16.840.1.101.3.4.1.48 */
- static final ASN1ObjectIdentifier id_aes256_wrap_pad = aes.branch("48");
+
+ /**
+ * 2.16.840.1.101.3.4.1.21
+ */
+ static final ASN1ObjectIdentifier id_aes192_ECB = aes.branch("21");
+ /**
+ * 2.16.840.1.101.3.4.1.22
+ */
+ static final ASN1ObjectIdentifier id_aes192_CBC = aes.branch("22");
+ /**
+ * 2.16.840.1.101.3.4.1.23
+ */
+ static final ASN1ObjectIdentifier id_aes192_OFB = aes.branch("23");
+ /**
+ * 2.16.840.1.101.3.4.1.24
+ */
+ static final ASN1ObjectIdentifier id_aes192_CFB = aes.branch("24");
+ /**
+ * 2.16.840.1.101.3.4.1.25
+ */
+ static final ASN1ObjectIdentifier id_aes192_wrap = aes.branch("25");
+ /**
+ * 2.16.840.1.101.3.4.1.26
+ */
+ static final ASN1ObjectIdentifier id_aes192_GCM = aes.branch("26");
+ /**
+ * 2.16.840.1.101.3.4.1.27
+ */
+ static final ASN1ObjectIdentifier id_aes192_CCM = aes.branch("27");
+ /**
+ * 2.16.840.1.101.3.4.1.28
+ */
+ static final ASN1ObjectIdentifier id_aes192_wrap_pad = aes.branch("28");
+
+ /**
+ * 2.16.840.1.101.3.4.1.29
+ */
+ static final ASN1ObjectIdentifier id_aes192_GMAC = aes.branch("29");
+
+
+ /**
+ * 2.16.840.1.101.3.4.1.41
+ */
+ static final ASN1ObjectIdentifier id_aes256_ECB = aes.branch("41");
+ /**
+ * 2.16.840.1.101.3.4.1.42
+ */
+ static final ASN1ObjectIdentifier id_aes256_CBC = aes.branch("42");
+ /**
+ * 2.16.840.1.101.3.4.1.43
+ */
+ static final ASN1ObjectIdentifier id_aes256_OFB = aes.branch("43");
+ /**
+ * 2.16.840.1.101.3.4.1.44
+ */
+ static final ASN1ObjectIdentifier id_aes256_CFB = aes.branch("44");
+ /**
+ * 2.16.840.1.101.3.4.1.45
+ */
+ static final ASN1ObjectIdentifier id_aes256_wrap = aes.branch("45");
+ /**
+ * 2.16.840.1.101.3.4.1.46
+ */
+ static final ASN1ObjectIdentifier id_aes256_GCM = aes.branch("46");
+ /**
+ * 2.16.840.1.101.3.4.1.47
+ */
+ static final ASN1ObjectIdentifier id_aes256_CCM = aes.branch("47");
+ /**
+ * 2.16.840.1.101.3.4.1.48
+ */
+ static final ASN1ObjectIdentifier id_aes256_wrap_pad = aes.branch("48");
+ /**
+ * 2.16.840.1.101.3.4.1.49
+ */
+ static final ASN1ObjectIdentifier id_aes256_GMAC = aes.branch("49");
+
//
// signatures
//
- /** 2.16.840.1.101.3.4.3 */
- static final ASN1ObjectIdentifier sigAlgs = nistAlgorithm.branch("3");
+ /**
+ * 2.16.840.1.101.3.4.3
+ */
+ static final ASN1ObjectIdentifier sigAlgs = nistAlgorithm.branch("3");
- static final ASN1ObjectIdentifier id_dsa_with_sha2 = sigAlgs;
+ static final ASN1ObjectIdentifier id_dsa_with_sha2 = sigAlgs;
/** 2.16.840.1.101.3.4.3.1 */
static final ASN1ObjectIdentifier dsa_with_sha224 = sigAlgs.branch("1");
@@ -152,12 +220,12 @@
static final ASN1ObjectIdentifier id_ecdsa_with_sha3_512 = sigAlgs.branch("12");
// RSA PKCS #1 v1.5 Signature with SHA-3 family.
- /** 2.16.840.1.101.3.4.3.9 */
+ /** 2.16.840.1.101.3.4.3.13 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_224 = sigAlgs.branch("13");
- /** 2.16.840.1.101.3.4.3.10 */
+ /** 2.16.840.1.101.3.4.3.14 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_256 = sigAlgs.branch("14");
- /** 2.16.840.1.101.3.4.3.11 */
+ /** 2.16.840.1.101.3.4.3.15 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_384 = sigAlgs.branch("15");
- /** 2.16.840.1.101.3.4.3.12 */
+ /** 2.16.840.1.101.3.4.3.16 */
static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_512 = sigAlgs.branch("16");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertStatus.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertStatus.java
index 25ba415..286022c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertStatus.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertStatus.java
@@ -3,9 +3,11 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Null;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.ASN1Util;
import com.android.internal.org.bouncycastle.asn1.DERNull;
import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
@@ -46,22 +48,25 @@
private CertStatus(
ASN1TaggedObject choice)
{
- this.tagNo = choice.getTagNo();
+ int tagNo = choice.getTagNo();
- switch (choice.getTagNo())
+ switch (tagNo)
{
case 0:
- value = DERNull.INSTANCE;
+ value = ASN1Null.getInstance(choice, false);
break;
case 1:
value = RevokedInfo.getInstance(choice, false);
break;
case 2:
- value = DERNull.INSTANCE;
+ // UnknownInfo ::= NULL
+ value = ASN1Null.getInstance(choice, false);
break;
default:
- throw new IllegalArgumentException("Unknown tag encountered: " + choice.getTagNo());
+ throw new IllegalArgumentException("Unknown tag encountered: " + ASN1Util.getTagText(choice));
}
+
+ this.tagNo = tagNo;
}
public static CertStatus getInstance(
@@ -83,7 +88,7 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ return getInstance(obj.getExplicitBaseTagged()); // must be explicitly tagged
}
public int getTagNo()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java
index 403a4ac..4247fed 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java
@@ -5,6 +5,7 @@
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1IA5String;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
@@ -20,7 +21,7 @@
public class CrlID
extends ASN1Object
{
- private DERIA5String crlUrl;
+ private ASN1IA5String crlUrl;
private ASN1Integer crlNum;
private ASN1GeneralizedTime crlTime;
@@ -36,7 +37,7 @@
switch (o.getTagNo())
{
case 0:
- crlUrl = DERIA5String.getInstance(o, true);
+ crlUrl = ASN1IA5String.getInstance(o, true);
break;
case 1:
crlNum = ASN1Integer.getInstance(o, true);
@@ -66,8 +67,18 @@
return null;
}
+ /**
+ * @deprecated Use {@link #getCrlUrlIA5()} instead.
+ */
public DERIA5String getCrlUrl()
{
+ return null == crlUrl || crlUrl instanceof DERIA5String
+ ? (DERIA5String)crlUrl
+ : new DERIA5String(crlUrl.getString(), false);
+ }
+
+ public ASN1IA5String getCrlUrlIA5()
+ {
return crlUrl;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponderID.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponderID.java
index ad42120..5bb17f8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponderID.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponderID.java
@@ -64,7 +64,12 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
+ return getInstance(obj.getExplicitBaseObject());
}
public byte[] getKeyHash()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java
index 2480e2f..a0d1ca0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java
@@ -33,10 +33,7 @@
this.response = response;
}
- /**
- * @deprecated use getInstance()
- */
- public ResponseBytes(
+ private ResponseBytes(
ASN1Sequence seq)
{
responseType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java
index 7c6b7b9..9ddb123 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java
@@ -21,6 +21,11 @@
private ASN1GeneralizedTime revocationTime;
private CRLReason revocationReason;
+ public RevokedInfo(ASN1GeneralizedTime revocationTime)
+ {
+ this(revocationTime, null);
+ }
+
public RevokedInfo(
ASN1GeneralizedTime revocationTime,
CRLReason revocationReason)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java
index a12a870..1a048e0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java
@@ -24,8 +24,8 @@
private CRLBag(
ASN1Sequence seq)
{
- this.crlId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
- this.crlValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject();
+ this.crlId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ this.crlValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
}
public static CRLBag getInstance(Object o)
@@ -69,7 +69,7 @@
*
* x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}
* -- DER-encoded X.509 CRL stored in OCTET STRING
- *
+ *
* CRLTypes BAG-TYPE ::= {
* x509CRL,
* ... -- For future extensions
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java
index 60f7506..abaae9a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java
@@ -24,7 +24,7 @@
ASN1Sequence seq)
{
this.certId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
- this.certValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject();
+ this.certValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
}
public static CertBag getInstance(Object o)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java
index b3ee00e..a3ecffc 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.pkcs;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
@@ -25,7 +26,7 @@
{
protected CertificationRequestInfo reqInfo = null;
protected AlgorithmIdentifier sigAlgId = null;
- protected DERBitString sigBits = null;
+ protected ASN1BitString sigBits = null;
public static CertificationRequest getInstance(Object o)
{
@@ -49,7 +50,7 @@
public CertificationRequest(
CertificationRequestInfo requestInfo,
AlgorithmIdentifier algorithm,
- DERBitString signature)
+ ASN1BitString signature)
{
this.reqInfo = requestInfo;
this.sigAlgId = algorithm;
@@ -77,7 +78,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sigBits;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
index bce5f0e..0c140bc 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
@@ -99,10 +99,7 @@
this(X500Name.getInstance(subject.toASN1Primitive()), pkInfo, attributes);
}
- /**
- * @deprecated use getInstance().
- */
- public CertificationRequestInfo(
+ private CertificationRequestInfo(
ASN1Sequence seq)
{
version = (ASN1Integer)seq.getObjectAt(0);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java
index ed6988d..7ee5f3b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java
@@ -50,7 +50,7 @@
if (e.hasMoreElements())
{
- content = ((ASN1TaggedObject)e.nextElement()).getObject();
+ content = ((ASN1TaggedObject)e.nextElement()).getExplicitBaseObject();
}
isBer = seq instanceof BERSequence;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java
index 600b9d2..dc41097 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java
@@ -57,9 +57,8 @@
private EncryptedData(
ASN1Sequence seq)
{
- int version = ((ASN1Integer)seq.getObjectAt(0)).intValueExact();
-
- if (version != 0)
+ ASN1Integer version = (ASN1Integer)seq.getObjectAt(0);
+ if (!version.hasValue(0))
{
throw new IllegalArgumentException("sequence not version 0");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
index 47c6100..6507d4f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
@@ -11,6 +11,7 @@
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.util.Arrays;
/**
* @hide This class is not part of the Android public SDK API
@@ -35,7 +36,7 @@
byte[] encoding)
{
this.algId = algId;
- this.data = new DEROctetString(encoding);
+ this.data = new DEROctetString(Arrays.clone(encoding));
}
public static EncryptedPrivateKeyInfo getInstance(
@@ -60,7 +61,7 @@
public byte[] getEncryptedData()
{
- return data.getOctets();
+ return Arrays.clone(data.getOctets());
}
/**
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
index 82a22ec..c77a91e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
@@ -185,7 +185,7 @@
*/
public byte[] getSalt()
{
- return octStr.getOctets();
+ return Arrays.clone(octStr.getOctets());
}
/**
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBMAC1Params.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBMAC1Params.java
new file mode 100644
index 0000000..3927b45
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBMAC1Params.java
@@ -0,0 +1,90 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+
+/**
+ * From https://datatracker.ietf.org/doc/html/rfc8018
+ *
+ * <pre>
+ * PBMAC1-params ::= SEQUENCE {
+ * keyDerivationFunc AlgorithmIdentifier {{PBMAC1-KDFs}},
+ * messageAuthScheme AlgorithmIdentifier {{PBMAC1-MACs}} }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PBMAC1Params
+ extends ASN1Object
+ implements PKCSObjectIdentifiers
+{
+ private AlgorithmIdentifier func;
+ private AlgorithmIdentifier scheme;
+
+ public static PBMAC1Params getInstance(
+ Object obj)
+ {
+ if (obj instanceof PBMAC1Params)
+ {
+ return (PBMAC1Params)obj;
+ }
+ if (obj != null)
+ {
+ return new PBMAC1Params(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public PBMAC1Params(AlgorithmIdentifier keyDevFunc, AlgorithmIdentifier encScheme)
+ {
+ this.func = keyDevFunc;
+ this.scheme = encScheme;
+ }
+
+ private PBMAC1Params(
+ ASN1Sequence obj)
+ {
+ Enumeration e = obj.getObjects();
+ ASN1Sequence funcSeq = ASN1Sequence.getInstance(((ASN1Encodable)e.nextElement()).toASN1Primitive());
+
+ if (funcSeq.getObjectAt(0).equals(id_PBKDF2))
+ {
+ func = new AlgorithmIdentifier(id_PBKDF2, PBKDF2Params.getInstance(funcSeq.getObjectAt(1)));
+ }
+ else
+ {
+ func = AlgorithmIdentifier.getInstance(funcSeq);
+ }
+
+ scheme = AlgorithmIdentifier.getInstance(e.nextElement());
+ }
+
+ public AlgorithmIdentifier getKeyDerivationFunc()
+ {
+ return func;
+ }
+
+ public AlgorithmIdentifier getMessageAuthScheme()
+ {
+ return scheme;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(func);
+ v.add(scheme);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
index 040a1c2..8207102 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
@@ -78,10 +78,12 @@
ASN1ObjectIdentifier pbeWithSHA1AndDES_CBC = pkcs_5.branch("10");
/** PKCS#5: 1.2.840.113549.1.5.11 */
ASN1ObjectIdentifier pbeWithSHA1AndRC2_CBC = pkcs_5.branch("11");
- /** PKCS#5: 1.2.840.113549.1.5.13 */
- ASN1ObjectIdentifier id_PBES2 = pkcs_5.branch("13");
/** PKCS#5: 1.2.840.113549.1.5.12 */
ASN1ObjectIdentifier id_PBKDF2 = pkcs_5.branch("12");
+ /** PKCS#5: 1.2.840.113549.1.5.13 */
+ ASN1ObjectIdentifier id_PBES2 = pkcs_5.branch("13");
+ /** PKCS#5: 1.2.840.113549.1.5.14 */
+ ASN1ObjectIdentifier id_PBMAC1 = pkcs_5.branch("14");
//
// encryptionAlgorithm OBJECT IDENTIFIER ::= {
@@ -137,6 +139,10 @@
ASN1ObjectIdentifier id_hmacWithSHA384 = digestAlgorithm.branch("10").intern();
/** 1.2.840.113549.2.11 */
ASN1ObjectIdentifier id_hmacWithSHA512 = digestAlgorithm.branch("11").intern();
+ /** 1.2.840.113549.2.12 */
+ ASN1ObjectIdentifier id_hmacWithSHA512_224 = digestAlgorithm.branch("12").intern();
+ /** 1.2.840.113549.2.13 */
+ ASN1ObjectIdentifier id_hmacWithSHA512_256 = digestAlgorithm.branch("13").intern();
//
// pkcs-7 OBJECT IDENTIFIER ::= {
@@ -191,6 +197,8 @@
ASN1ObjectIdentifier pkcs_9_at_smimeCapabilities = pkcs_9.branch("15").intern();
/** PKCS#9: 1.2.840.113549.1.9.16 */
ASN1ObjectIdentifier id_smime = pkcs_9.branch("16").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.46 */
+ ASN1ObjectIdentifier pkcs_9_at_binarySigningTime = pkcs_9.branch("16.2.46").intern();
/** PKCS#9: 1.2.840.113549.1.9.20 */
ASN1ObjectIdentifier pkcs_9_at_friendlyName = pkcs_9.branch("20").intern();
@@ -249,8 +257,20 @@
/** S/MIME: Algorithm Identifiers ; 1.2.840.113549.1.9.16.3 */
ASN1ObjectIdentifier id_alg = id_smime.branch("3");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.5 */
+ ASN1ObjectIdentifier id_alg_ESDH = id_alg.branch("5");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.6 */
+ ASN1ObjectIdentifier id_alg_CMS3DESwrap = id_alg.branch("6");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.7 */
+ ASN1ObjectIdentifier id_alg_CMSRC2wrap = id_alg.branch("7");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.8 */
+ ASN1ObjectIdentifier id_alg_zlibCompress = id_alg.branch("8");
/** PKCS#9: 1.2.840.113549.1.9.16.3.9 */
- ASN1ObjectIdentifier id_alg_PWRI_KEK = id_alg.branch("9");
+ ASN1ObjectIdentifier id_alg_PWRI_KEK = id_alg.branch("9");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.10 */
+ ASN1ObjectIdentifier id_alg_SSDH = id_alg.branch("10");
+
/**
* <pre>
* -- RSA-KEM Key Transport Algorithm RFC 5990
@@ -468,14 +488,5 @@
* @deprecated use pbeWithSHAAnd40BitRC2_CBC
*/
ASN1ObjectIdentifier pbewithSHAAnd40BitRC2_CBC = pkcs_12PbeIds.branch("6");
-
- /** PKCS#9: 1.2.840.113549.1.9.16.3.6 */
- ASN1ObjectIdentifier id_alg_CMS3DESwrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.6");
- /** PKCS#9: 1.2.840.113549.1.9.16.3.7 */
- ASN1ObjectIdentifier id_alg_CMSRC2wrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.7");
- /** PKCS#9: 1.2.840.113549.1.9.16.3.5 */
- ASN1ObjectIdentifier id_alg_ESDH = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.5");
- /** PKCS#9: 1.2.840.113549.1.9.16.3.10 */
- ASN1ObjectIdentifier id_alg_SSDH = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.10");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java
index a782500..509dc17 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java
@@ -23,7 +23,7 @@
ASN1Sequence seq)
{
ASN1Integer version = ASN1Integer.getInstance(seq.getObjectAt(0));
- if (version.intValueExact() != 3)
+ if (!version.hasValue(3))
{
throw new IllegalArgumentException("wrong version for PFX PDU");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
index 9d8e99d..92e6162 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
@@ -166,7 +166,7 @@
throw new IllegalArgumentException("'publicKey' requires version v2(1) or later");
}
- this.publicKey = DERBitString.getInstance(tagged, false);
+ this.publicKey = ASN1BitString.getInstance(tagged, false);
break;
}
default:
@@ -197,6 +197,11 @@
return new DEROctetString(privateKey.getOctets());
}
+ public int getPrivateKeyLength()
+ {
+ return privateKey.getOctetsLength();
+ }
+
public ASN1Encodable parsePrivateKey()
throws IOException
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
index 6cd1615..b105459 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
@@ -62,11 +62,7 @@
this.pSourceAlgorithm = pSourceAlgorithm;
}
- /**
- * @deprecated use getInstance()
- * @param seq
- */
- public RSAESOAEPparams(
+ private RSAESOAEPparams(
ASN1Sequence seq)
{
hashAlgorithm = DEFAULT_HASH_ALGORITHM;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java
index 93fec39..6a3fb56 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java
@@ -61,7 +61,7 @@
ASN1Sequence seq)
{
this.bagId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
- this.bagValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject();
+ this.bagValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getExplicitBaseObject();
if (seq.size() == 3)
{
this.bagAttributes = (ASN1Set)seq.getObjectAt(2);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java
index e8b76a7..c0090ff 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java
@@ -4,6 +4,7 @@
import java.math.BigInteger;
import java.util.Enumeration;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
@@ -12,7 +13,7 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.BERTags;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
@@ -93,7 +94,7 @@
*/
public ECPrivateKey(
BigInteger key,
- DERBitString publicKey,
+ ASN1BitString publicKey,
ASN1Encodable parameters)
{
this(key.bitLength(), key, publicKey, parameters);
@@ -110,7 +111,7 @@
public ECPrivateKey(
int orderBitLength,
BigInteger key,
- DERBitString publicKey,
+ ASN1BitString publicKey,
ASN1Encodable parameters)
{
byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key);
@@ -139,18 +140,27 @@
return new BigInteger(1, octs.getOctets());
}
-
- public DERBitString getPublicKey()
+
+ public ASN1BitString getPublicKey()
{
- return (DERBitString)getObjectInTag(1);
+ return (ASN1BitString)getObjectInTag(1, BERTags.BIT_STRING);
}
+ /**
+ * @deprecated Use {@link #getParametersObject()} instead and getInstance
+ * methods or similar to get the object at the desired type.
+ */
public ASN1Primitive getParameters()
{
- return getObjectInTag(0);
+ return getParametersObject().toASN1Primitive();
}
- private ASN1Primitive getObjectInTag(int tagNo)
+ public ASN1Object getParametersObject()
+ {
+ return getObjectInTag(0, -1);
+ }
+
+ private ASN1Object getObjectInTag(int tagNo, int baseTagNo)
{
Enumeration e = seq.getObjects();
@@ -161,9 +171,11 @@
if (obj instanceof ASN1TaggedObject)
{
ASN1TaggedObject tag = (ASN1TaggedObject)obj;
- if (tag.getTagNo() == tagNo)
+ if (tag.hasContextTag(tagNo))
{
- return tag.getObject().toASN1Primitive();
+ return baseTagNo < 0
+ ? tag.getExplicitBaseObject().toASN1Primitive()
+ : tag.getBaseUniversal(true, baseTagNo);
}
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
index 4cb9eab..13edd6d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
@@ -4,6 +4,7 @@
import java.math.BigInteger;
import java.util.Enumeration;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
@@ -12,7 +13,6 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
@@ -56,7 +56,7 @@
public ECPrivateKeyStructure(
BigInteger key,
- DERBitString publicKey,
+ ASN1BitString publicKey,
ASN1Encodable parameters)
{
byte[] bytes = BigIntegers.asUnsignedByteArray(key);
@@ -86,9 +86,9 @@
return new BigInteger(1, octs.getOctets());
}
- public DERBitString getPublicKey()
+ public ASN1BitString getPublicKey()
{
- return (DERBitString)getObjectInTag(1);
+ return (ASN1BitString)getObjectInTag(1);
}
public ASN1Primitive getParameters()
@@ -109,7 +109,7 @@
ASN1TaggedObject tag = (ASN1TaggedObject)obj;
if (tag.getTagNo() == tagNo)
{
- return (ASN1Primitive)((ASN1Encodable)tag.getObject()).toASN1Primitive();
+ return (ASN1Primitive)((ASN1Encodable)tag.getExplicitBaseObject()).toASN1Primitive();
}
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java
index 31cbd7f..bc40585 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java
@@ -50,22 +50,27 @@
*/
static X9ECParametersHolder secp112r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = (2^128 - 3) / 76439
BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
BigInteger a = fromHex("DB7C2ABF62E35E668076BEAD2088");
BigInteger b = fromHex("659EF8BA043916EEDE8911702B22");
- byte[] S = Hex.decodeStrict("00F50B028E4D696E676875615175290472783FB1");
BigInteger n = fromHex("DB7C2ABF62E35E7628DFAC6561C5");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("00F50B028E4D696E676875615175290472783FB1");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -74,22 +79,27 @@
*/
static X9ECParametersHolder secp112r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = (2^128 - 3) / 76439
BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
BigInteger a = fromHex("6127C24C05F38A0AAAF65C0EF02C");
BigInteger b = fromHex("51DEF1815DB5ED74FCC34C85D709");
- byte[] S = Hex.decodeStrict("002757A1114D696E6768756151755316C05E0BD4");
BigInteger n = fromHex("36DF0AAFD8B8D7597CA10520D04B");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("002757A1114D696E6768756151755316C05E0BD4");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -98,22 +108,27 @@
*/
static X9ECParametersHolder secp128r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^128 - 2^97 - 1
BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("E87579C11079F43DD824993C2CEE5ED3");
- byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
BigInteger n = fromHex("FFFFFFFE0000000075A30D1B9038A115");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -122,22 +137,27 @@
*/
static X9ECParametersHolder secp128r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^128 - 2^97 - 1
BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("D6031998D1B3BBFEBF59CC9BBFF9AEE1");
BigInteger b = fromHex("5EEEFCA380D02919DC2C6558BB6D8A5D");
- byte[] S = Hex.decodeStrict("004D696E67687561517512D8F03431FCE63B88F4");
BigInteger n = fromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("004D696E67687561517512D8F03431FCE63B88F4");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -146,13 +166,12 @@
*/
static X9ECParametersHolder secp160k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(7);
- byte[] S = null;
BigInteger n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3");
BigInteger h = BigInteger.valueOf(1);
@@ -170,12 +189,18 @@
new BigInteger("96341f1138933bc2f503fd44", 16),
176));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -184,22 +209,27 @@
*/
static X9ECParametersHolder secp160r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^160 - 2^31 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC");
BigInteger b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45");
- byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
BigInteger n = fromHex("0100000000000000000001F4C8F927AED3CA752257");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -208,22 +238,27 @@
*/
static X9ECParametersHolder secp160r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70");
BigInteger b = fromHex("B4E134D3FB59EB8BAB57274904664D5AF50388BA");
- byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
BigInteger n = fromHex("0100000000000000000000351EE786A818F3A1A16B");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -232,13 +267,12 @@
*/
static X9ECParametersHolder secp192k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(3);
- byte[] S = null;
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D");
BigInteger h = BigInteger.valueOf(1);
@@ -256,12 +290,18 @@
new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
208));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -270,22 +310,27 @@
*/
static X9ECParametersHolder secp192r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^192 - 2^64 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1");
- byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -294,13 +339,12 @@
*/
static X9ECParametersHolder secp224k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(5);
- byte[] S = null;
BigInteger n = fromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
BigInteger h = BigInteger.valueOf(1);
@@ -318,12 +362,18 @@
new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
240));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -332,22 +382,27 @@
*/
static X9ECParametersHolder secp224r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^224 - 2^96 + 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE");
BigInteger b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4");
- byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -356,13 +411,12 @@
*/
static X9ECParametersHolder secp256k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(7);
- byte[] S = null;
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
BigInteger h = BigInteger.valueOf(1);
@@ -380,12 +434,18 @@
new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
272));
- ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+ return configureCurveGLV(new ECCurve.Fp(p, a, b, n, h, true), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -394,22 +454,27 @@
*/
static X9ECParametersHolder secp256r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1
BigInteger p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B");
- byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -418,23 +483,28 @@
*/
static X9ECParametersHolder secp384r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^384 - 2^128 - 2^96 + 2^32 - 1
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC");
BigInteger b = fromHex("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF");
- byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -443,23 +513,28 @@
*/
static X9ECParametersHolder secp521r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
// p = 2^521 - 1
BigInteger p = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00");
- byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+ return configureCurve(new ECCurve.Fp(p, a, b, n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
+ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -468,23 +543,28 @@
*/
static X9ECParametersHolder sect113r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 113;
int k = 9;
BigInteger a = fromHex("003088250CA6E7C7FE649CE85820F7");
BigInteger b = fromHex("00E8BEE4D3E2260744188BE0E9C723");
- byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
BigInteger n = fromHex("0100000000000000D9CCEC8A39E56F");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -493,23 +573,28 @@
*/
static X9ECParametersHolder sect113r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 113;
int k = 9;
BigInteger a = fromHex("00689918DBEC7E5A0DD6DFC0AA55C7");
BigInteger b = fromHex("0095E9A9EC9B297BD4BF36E059184F");
- byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
BigInteger n = fromHex("010000000000000108789B2496AF93");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -518,7 +603,7 @@
*/
static X9ECParametersHolder sect131r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 131;
int k1 = 2;
@@ -527,16 +612,21 @@
BigInteger a = fromHex("07A11B09A76B562144418FF3FF8C2570B8");
BigInteger b = fromHex("0217C05610884B63B9C6C7291678F9D341");
- byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
BigInteger n = fromHex("0400000000000000023123953A9464B54D");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -545,7 +635,7 @@
*/
static X9ECParametersHolder sect131r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 131;
int k1 = 2;
@@ -554,16 +644,21 @@
BigInteger a = fromHex("03E5A88919D7CAFCBF415F07C2176573B2");
BigInteger b = fromHex("04B8266A46C55657AC734CE38F018F2192");
- byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
BigInteger n = fromHex("0400000000000000016954A233049BA98F");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -572,7 +667,7 @@
*/
static X9ECParametersHolder sect163k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 163;
int k1 = 3;
@@ -581,16 +676,21 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("04000000000000000000020108A2E0CC0D99F8A5EF");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -599,7 +699,7 @@
*/
static X9ECParametersHolder sect163r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 163;
int k1 = 3;
@@ -608,16 +708,21 @@
BigInteger a = fromHex("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2");
BigInteger b = fromHex("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9");
- byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -626,7 +731,7 @@
*/
static X9ECParametersHolder sect163r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 163;
int k1 = 3;
@@ -635,16 +740,21 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("020A601907B8C953CA1481EB10512F78744A3205FD");
- byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
BigInteger n = fromHex("040000000000000000000292FE77E70C12A4234C33");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -653,23 +763,28 @@
*/
static X9ECParametersHolder sect193r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 193;
int k = 15;
BigInteger a = fromHex("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01");
BigInteger b = fromHex("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814");
- byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
BigInteger n = fromHex("01000000000000000000000000C7F34A778F443ACC920EBA49");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -678,23 +793,28 @@
*/
static X9ECParametersHolder sect193r2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 193;
int k = 15;
BigInteger a = fromHex("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B");
BigInteger b = fromHex("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE");
- byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
BigInteger n = fromHex("010000000000000000000000015AAB561B005413CCD4EE99D5");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -703,23 +823,28 @@
*/
static X9ECParametersHolder sect233k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 233;
int k = 74;
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -728,23 +853,28 @@
*/
static X9ECParametersHolder sect233r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 233;
int k = 74;
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD");
- byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
BigInteger n = fromHex("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -753,23 +883,28 @@
*/
static X9ECParametersHolder sect239k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 239;
int k = 158;
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -778,7 +913,7 @@
*/
static X9ECParametersHolder sect283k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 283;
int k1 = 5;
@@ -787,17 +922,22 @@
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
+ "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -806,7 +946,7 @@
*/
static X9ECParametersHolder sect283r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 283;
int k1 = 5;
@@ -815,17 +955,22 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5");
- byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
+ "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -834,24 +979,29 @@
*/
static X9ECParametersHolder sect409k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 409;
int k = 87;
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
+ "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -860,24 +1010,29 @@
*/
static X9ECParametersHolder sect409r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 409;
int k = 87;
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F");
- byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
BigInteger n = fromHex("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
+ "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -886,7 +1041,7 @@
*/
static X9ECParametersHolder sect571k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 571;
int k1 = 2;
@@ -895,17 +1050,22 @@
BigInteger a = ECConstants.ZERO;
BigInteger b = BigInteger.valueOf(1);
- byte[] S = null;
BigInteger n = fromHex("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
+ "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -914,7 +1074,7 @@
*/
static X9ECParametersHolder sect571r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
int m = 571;
int k1 = 2;
@@ -923,17 +1083,22 @@
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A");
- byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ return configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
+ "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
- return new X9ECParameters(curve, G, n, h, S);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -987,26 +1152,35 @@
defineCurve("sect571r1", SECObjectIdentifiers.sect571r1, sect571r1);
}
- public static X9ECParameters getByName(
- String name)
+ public static X9ECParameters getByName(String name)
{
ASN1ObjectIdentifier oid = getOID(name);
return oid == null ? null : getByOID(oid);
}
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOIDLazy(oid);
+ }
+
/**
* return the X9ECParameters object for the named curve represented by
* the passed in object identifier. Null if the curve isn't present.
*
* @param oid an object identifier representing a named curve, if present.
*/
- public static X9ECParameters getByOID(
- ASN1ObjectIdentifier oid)
+ public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid);
+ X9ECParametersHolder holder = getByOIDLazy(oid);
return holder == null ? null : holder.getParameters();
}
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return (X9ECParametersHolder)curves.get(oid);
+ }
+
/**
* return the object identifier signified by the passed in name. Null
* if there is no object identifier associated with name.
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java
index 786d484..99a0d76 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java
@@ -1,43 +1,42 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.util;
-import java.io.IOException;
-import java.util.Enumeration;
-
-import com.android.internal.org.bouncycastle.asn1.ASN1ApplicationSpecific;
+import com.android.internal.org.bouncycastle.asn1.ASN1BMPString;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Boolean;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
import com.android.internal.org.bouncycastle.asn1.ASN1External;
import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1GraphicString;
+import com.android.internal.org.bouncycastle.asn1.ASN1IA5String;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Null;
+import com.android.internal.org.bouncycastle.asn1.ASN1NumericString;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectDescriptor;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1PrintableString;
+import com.android.internal.org.bouncycastle.asn1.ASN1RelativeOID;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1T61String;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.internal.org.bouncycastle.asn1.ASN1UTCTime;
-import com.android.internal.org.bouncycastle.asn1.BERApplicationSpecific;
+import com.android.internal.org.bouncycastle.asn1.ASN1UTF8String;
+import com.android.internal.org.bouncycastle.asn1.ASN1Util;
+import com.android.internal.org.bouncycastle.asn1.ASN1VideotexString;
+import com.android.internal.org.bouncycastle.asn1.ASN1VisibleString;
import com.android.internal.org.bouncycastle.asn1.BEROctetString;
import com.android.internal.org.bouncycastle.asn1.BERSequence;
import com.android.internal.org.bouncycastle.asn1.BERSet;
import com.android.internal.org.bouncycastle.asn1.BERTaggedObject;
-import com.android.internal.org.bouncycastle.asn1.BERTags;
-import com.android.internal.org.bouncycastle.asn1.DERApplicationSpecific;
-import com.android.internal.org.bouncycastle.asn1.DERBMPString;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
-import com.android.internal.org.bouncycastle.asn1.DERGraphicString;
-import com.android.internal.org.bouncycastle.asn1.DERIA5String;
-import com.android.internal.org.bouncycastle.asn1.DERNull;
-import com.android.internal.org.bouncycastle.asn1.DERPrintableString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.DERSet;
-import com.android.internal.org.bouncycastle.asn1.DERT61String;
-import com.android.internal.org.bouncycastle.asn1.DERUTF8String;
-import com.android.internal.org.bouncycastle.asn1.DERVideotexString;
-import com.android.internal.org.bouncycastle.asn1.DERVisibleString;
-import com.android.internal.org.bouncycastle.asn1.DLApplicationSpecific;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DLBitString;
import com.android.internal.org.bouncycastle.util.Strings;
import com.android.internal.org.bouncycastle.util.encoders.Hex;
@@ -62,11 +61,14 @@
StringBuffer buf)
{
String nl = Strings.lineSeparator();
- if (obj instanceof ASN1Sequence)
+ if (obj instanceof ASN1Null)
{
- Enumeration e = ((ASN1Sequence)obj).getObjects();
- String tab = indent + TAB;
-
+ buf.append(indent);
+ buf.append("NULL");
+ buf.append(nl);
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
buf.append(indent);
if (obj instanceof BERSequence)
{
@@ -80,64 +82,19 @@
{
buf.append("Sequence");
}
-
buf.append(nl);
- while (e.hasMoreElements())
+ ASN1Sequence sequence = (ASN1Sequence)obj;
+ String elementsIndent = indent + TAB;
+
+ for (int i = 0, count = sequence.size(); i < count; ++i)
{
- Object o = e.nextElement();
-
- if (o == null || o.equals(DERNull.INSTANCE))
- {
- 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);
- }
+ _dumpAsString(elementsIndent, verbose, sequence.getObjectAt(i).toASN1Primitive(), buf);
}
}
- else if (obj instanceof ASN1TaggedObject)
- {
- String tab = indent + TAB;
-
- buf.append(indent);
- if (obj instanceof BERTaggedObject)
- {
- buf.append("BER Tagged [");
- }
- else
- {
- buf.append("Tagged [");
- }
-
- ASN1TaggedObject o = (ASN1TaggedObject)obj;
-
- buf.append(Integer.toString(o.getTagNo()));
- buf.append(']');
-
- if (!o.isExplicit())
- {
- buf.append(" IMPLICIT ");
- }
-
- buf.append(nl);
-
- _dumpAsString(tab, verbose, o.getObject(), buf);
- }
else if (obj instanceof ASN1Set)
{
- Enumeration e = ((ASN1Set)obj).getObjects();
- String tab = indent + TAB;
-
buf.append(indent);
-
if (obj instanceof BERSet)
{
buf.append("BER Set");
@@ -152,26 +109,45 @@
}
buf.append(nl);
- while (e.hasMoreElements())
- {
- Object o = e.nextElement();
+ ASN1Set set = (ASN1Set)obj;
+ String elementsIndent = indent + TAB;
- 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);
- }
+ for (int i = 0, count = set.size(); i < count; ++i)
+ {
+ _dumpAsString(elementsIndent, verbose, set.getObjectAt(i).toASN1Primitive(), buf);
}
}
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ buf.append(indent);
+ if (obj instanceof BERTaggedObject)
+ {
+ buf.append("BER Tagged ");
+ }
+ else if (obj instanceof DERTaggedObject)
+ {
+ buf.append("DER Tagged ");
+ }
+ else
+ {
+ buf.append("Tagged ");
+ }
+
+ ASN1TaggedObject o = (ASN1TaggedObject)obj;
+
+ buf.append(ASN1Util.getTagText(o));
+
+ if (!o.isExplicit())
+ {
+ buf.append(" IMPLICIT ");
+ }
+
+ buf.append(nl);
+
+ String baseIndent = indent + TAB;
+
+ _dumpAsString(baseIndent, verbose, o.getBaseObject().toASN1Primitive(), buf);
+ }
else if (obj instanceof ASN1OctetString)
{
ASN1OctetString oct = (ASN1OctetString)obj;
@@ -197,6 +173,10 @@
{
buf.append(indent + "ObjectIdentifier(" + ((ASN1ObjectIdentifier)obj).getId() + ")" + nl);
}
+ else if (obj instanceof ASN1RelativeOID)
+ {
+ buf.append(indent + "RelativeOID(" + ((ASN1RelativeOID)obj).getId() + ")" + nl);
+ }
else if (obj instanceof ASN1Boolean)
{
buf.append(indent + "Boolean(" + ((ASN1Boolean)obj).isTrue() + ")" + nl);
@@ -205,50 +185,70 @@
{
buf.append(indent + "Integer(" + ((ASN1Integer)obj).getValue() + ")" + nl);
}
- else if (obj instanceof DERBitString)
+ else if (obj instanceof ASN1BitString)
{
- DERBitString bt = (DERBitString)obj;
- buf.append(indent + "DER Bit String" + "[" + bt.getBytes().length + ", " + bt.getPadBits() + "] ");
+ ASN1BitString bitString = (ASN1BitString)obj;
+
+ byte[] bytes = bitString.getBytes();
+ int padBits = bitString.getPadBits();
+
+ if (bitString instanceof DERBitString)
+ {
+ buf.append(indent + "DER Bit String" + "[" + bytes.length + ", " + padBits + "] ");
+ }
+ else if (bitString instanceof DLBitString)
+ {
+ buf.append(indent + "DL Bit String" + "[" + bytes.length + ", " + padBits + "] ");
+ }
+ else
+ {
+ buf.append(indent + "BER Bit String" + "[" + bytes.length + ", " + padBits + "] ");
+ }
+
if (verbose)
{
- buf.append(dumpBinaryDataAsString(indent, bt.getBytes()));
+ buf.append(dumpBinaryDataAsString(indent, bytes));
}
else
{
buf.append(nl);
}
}
- else if (obj instanceof DERIA5String)
+ else if (obj instanceof ASN1IA5String)
{
- buf.append(indent + "IA5String(" + ((DERIA5String)obj).getString() + ") " + nl);
+ buf.append(indent + "IA5String(" + ((ASN1IA5String)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERUTF8String)
+ else if (obj instanceof ASN1UTF8String)
{
- buf.append(indent + "UTF8String(" + ((DERUTF8String)obj).getString() + ") " + nl);
+ buf.append(indent + "UTF8String(" + ((ASN1UTF8String)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERPrintableString)
+ else if (obj instanceof ASN1NumericString)
{
- buf.append(indent + "PrintableString(" + ((DERPrintableString)obj).getString() + ") " + nl);
+ buf.append(indent + "NumericString(" + ((ASN1NumericString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERVisibleString)
+ else if (obj instanceof ASN1PrintableString)
{
- buf.append(indent + "VisibleString(" + ((DERVisibleString)obj).getString() + ") " + nl);
+ buf.append(indent + "PrintableString(" + ((ASN1PrintableString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERBMPString)
+ else if (obj instanceof ASN1VisibleString)
{
- buf.append(indent + "BMPString(" + ((DERBMPString)obj).getString() + ") " + nl);
+ buf.append(indent + "VisibleString(" + ((ASN1VisibleString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERT61String)
+ else if (obj instanceof ASN1BMPString)
{
- buf.append(indent + "T61String(" + ((DERT61String)obj).getString() + ") " + nl);
+ buf.append(indent + "BMPString(" + ((ASN1BMPString)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERGraphicString)
+ else if (obj instanceof ASN1T61String)
{
- buf.append(indent + "GraphicString(" + ((DERGraphicString)obj).getString() + ") " + nl);
+ buf.append(indent + "T61String(" + ((ASN1T61String)obj).getString() + ") " + nl);
}
- else if (obj instanceof DERVideotexString)
+ else if (obj instanceof ASN1GraphicString)
{
- buf.append(indent + "VideotexString(" + ((DERVideotexString)obj).getString() + ") " + nl);
+ buf.append(indent + "GraphicString(" + ((ASN1GraphicString)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof ASN1VideotexString)
+ {
+ buf.append(indent + "VideotexString(" + ((ASN1VideotexString)obj).getString() + ") " + nl);
}
else if (obj instanceof ASN1UTCTime)
{
@@ -258,23 +258,16 @@
{
buf.append(indent + "GeneralizedTime(" + ((ASN1GeneralizedTime)obj).getTime() + ") " + nl);
}
- else if (obj instanceof BERApplicationSpecific)
- {
- buf.append(outputApplicationSpecific("BER", indent, verbose, obj, nl));
- }
- else if (obj instanceof DERApplicationSpecific)
- {
- buf.append(outputApplicationSpecific("DER", indent, verbose, obj, nl));
- }
- else if (obj instanceof DLApplicationSpecific)
- {
- buf.append(outputApplicationSpecific("", indent, verbose, obj, nl));
- }
else if (obj instanceof ASN1Enumerated)
{
ASN1Enumerated en = (ASN1Enumerated) obj;
buf.append(indent + "DER Enumerated(" + en.getValue() + ")" + nl);
}
+ else if (obj instanceof ASN1ObjectDescriptor)
+ {
+ ASN1ObjectDescriptor od = (ASN1ObjectDescriptor)obj;
+ buf.append(indent + "ObjectDescriptor(" + od.getBaseGraphicString().getString() + ") " + nl);
+ }
else if (obj instanceof ASN1External)
{
ASN1External ext = (ASN1External) obj;
@@ -300,32 +293,6 @@
buf.append(indent + obj.toString() + nl);
}
}
-
- private static String outputApplicationSpecific(String type, String indent, boolean verbose, ASN1Primitive obj, String nl)
- {
- ASN1ApplicationSpecific app = ASN1ApplicationSpecific.getInstance(obj);
- StringBuffer buf = new StringBuffer();
-
- if (app.isConstructed())
- {
- try
- {
- ASN1Sequence s = ASN1Sequence.getInstance(app.getObject(BERTags.SEQUENCE));
- buf.append(indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "]" + nl);
- for (Enumeration e = s.getObjects(); e.hasMoreElements();)
- {
- _dumpAsString(indent + TAB, verbose, (ASN1Primitive)e.nextElement(), buf);
- }
- }
- catch (IOException e)
- {
- buf.append(e);
- }
- return buf.toString();
- }
-
- return indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "] (" + Strings.fromByteArray(Hex.encode(app.getContents())) + ")" + nl;
- }
/**
* dump out a DER object as a formatted string, in non-verbose mode.
@@ -350,21 +317,22 @@
Object obj,
boolean verbose)
{
- StringBuffer buf = new StringBuffer();
-
+ ASN1Primitive primitive;
if (obj instanceof ASN1Primitive)
{
- _dumpAsString("", verbose, (ASN1Primitive)obj, buf);
+ primitive = (ASN1Primitive)obj;
}
else if (obj instanceof ASN1Encodable)
{
- _dumpAsString("", verbose, ((ASN1Encodable)obj).toASN1Primitive(), buf);
+ primitive = ((ASN1Encodable)obj).toASN1Primitive();
}
else
{
return "unknown object type " + obj.toString();
}
+ StringBuffer buf = new StringBuffer();
+ _dumpAsString("", verbose, primitive, buf);
return buf.toString();
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/DirectoryString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/DirectoryString.java
index d13ae8f..48e814d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/DirectoryString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/DirectoryString.java
@@ -1,17 +1,18 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x500;
+import com.android.internal.org.bouncycastle.asn1.ASN1BMPString;
import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1PrintableString;
import com.android.internal.org.bouncycastle.asn1.ASN1String;
+import com.android.internal.org.bouncycastle.asn1.ASN1T61String;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.internal.org.bouncycastle.asn1.DERBMPString;
-import com.android.internal.org.bouncycastle.asn1.DERPrintableString;
-import com.android.internal.org.bouncycastle.asn1.DERT61String;
+import com.android.internal.org.bouncycastle.asn1.ASN1UTF8String;
+import com.android.internal.org.bouncycastle.asn1.ASN1UniversalString;
import com.android.internal.org.bouncycastle.asn1.DERUTF8String;
-import com.android.internal.org.bouncycastle.asn1.DERUniversalString;
/**
* The DirectoryString CHOICE object.
@@ -30,29 +31,29 @@
return (DirectoryString)o;
}
- if (o instanceof DERT61String)
+ if (o instanceof ASN1T61String)
{
- return new DirectoryString((DERT61String)o);
+ return new DirectoryString((ASN1T61String)o);
}
- if (o instanceof DERPrintableString)
+ if (o instanceof ASN1PrintableString)
{
- return new DirectoryString((DERPrintableString)o);
+ return new DirectoryString((ASN1PrintableString)o);
}
- if (o instanceof DERUniversalString)
+ if (o instanceof ASN1UniversalString)
{
- return new DirectoryString((DERUniversalString)o);
+ return new DirectoryString((ASN1UniversalString)o);
}
- if (o instanceof DERUTF8String)
+ if (o instanceof ASN1UTF8String)
{
- return new DirectoryString((DERUTF8String)o);
+ return new DirectoryString((ASN1UTF8String)o);
}
- if (o instanceof DERBMPString)
+ if (o instanceof ASN1BMPString)
{
- return new DirectoryString((DERBMPString)o);
+ return new DirectoryString((ASN1BMPString)o);
}
throw new IllegalArgumentException("illegal object in getInstance: " + o.getClass().getName());
@@ -65,35 +66,35 @@
throw new IllegalArgumentException("choice item must be explicitly tagged");
}
- return getInstance(o.getObject());
+ return getInstance(o.getExplicitBaseObject());
}
private DirectoryString(
- DERT61String string)
+ ASN1T61String string)
{
this.string = string;
}
private DirectoryString(
- DERPrintableString string)
+ ASN1PrintableString string)
{
this.string = string;
}
private DirectoryString(
- DERUniversalString string)
+ ASN1UniversalString string)
{
this.string = string;
}
private DirectoryString(
- DERUTF8String string)
+ ASN1UTF8String string)
{
this.string = string;
}
private DirectoryString(
- DERBMPString string)
+ ASN1BMPString string)
{
this.string = string;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java
index fc07882..3cb1e00 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java
@@ -2,12 +2,11 @@
package com.android.internal.org.bouncycastle.asn1.x500;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
-import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Set;
-import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.internal.org.bouncycastle.asn1.DERSet;
/**
@@ -21,6 +20,7 @@
private RDN(ASN1Set values)
{
+ // TODO Require minimum size of 1?
this.values = values;
}
@@ -38,6 +38,11 @@
return null;
}
+ public static RDN getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit)
+ {
+ return new RDN(ASN1Set.getInstance(taggedObject, declaredExplicit));
+ }
+
/**
* Create a single valued RDN.
*
@@ -46,12 +51,7 @@
*/
public RDN(ASN1ObjectIdentifier oid, ASN1Encodable value)
{
- ASN1EncodableVector v = new ASN1EncodableVector(2);
-
- v.add(oid);
- v.add(value);
-
- this.values = new DERSet(new DERSequence(v));
+ this(new AttributeTypeAndValue(oid, value));
}
public RDN(AttributeTypeAndValue attrTAndV)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java
index ed3f378..d29fa9f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java
@@ -1,8 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x500;
-import java.util.Enumeration;
-
import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
@@ -113,18 +111,18 @@
X500NameStyle style,
ASN1Sequence seq)
{
+ int count = seq.size();
+
this.style = style;
- this.rdns = new RDN[seq.size()];
+ this.rdns = new RDN[count];
boolean inPlace = true;
-
- int index = 0;
- for (Enumeration e = seq.getObjects(); e.hasMoreElements();)
+ for (int index = 0; index < count; ++index)
{
- Object element = e.nextElement();
+ ASN1Encodable element = seq.getObjectAt(index);
RDN rdn = RDN.getInstance(element);
inPlace &= (rdn == element);
- rdns[index++] = rdn;
+ rdns[index] = rdn;
}
if (inPlace)
@@ -231,6 +229,11 @@
return res;
}
+ public int size()
+ {
+ return rdns.length;
+ }
+
public ASN1Primitive toASN1Primitive()
{
return rdnSeq;
@@ -267,14 +270,14 @@
ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive();
- if (this.toASN1Primitive().equals(derO))
+ if (toASN1Primitive().equals(derO))
{
return true;
}
try
{
- return style.areEqual(this, new X500Name(ASN1Sequence.getInstance(((ASN1Encodable)obj).toASN1Primitive())));
+ return style.areEqual(this, getInstance(obj));
}
catch (Exception e)
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
index 3580944..ae466ed 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
@@ -133,19 +133,22 @@
public boolean areEqual(X500Name name1, X500Name name2)
{
- RDN[] rdns1 = name1.getRDNs();
- RDN[] rdns2 = name2.getRDNs();
-
- if (rdns1.length != rdns2.length)
+ if (name1.size() != name2.size())
{
return false;
}
+ RDN[] rdns1 = name1.getRDNs();
+ RDN[] rdns2 = name2.getRDNs();
+
boolean reverse = false;
- if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null)
+ AttributeTypeAndValue first1 = rdns1[0].getFirst();
+ AttributeTypeAndValue first2 = rdns2[0].getFirst();
+
+ if (first1 != null && first2 != null)
{
- reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType()); // guess forward
+ reverse = !first1.getType().equals(first2.getType()); // guess forward
}
for (int i = 0; i != rdns1.length; i++)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStrictStyle.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStrictStyle.java
index 86f124f..030d643 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStrictStyle.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStrictStyle.java
@@ -17,14 +17,14 @@
public boolean areEqual(X500Name name1, X500Name name2)
{
- RDN[] rdns1 = name1.getRDNs();
- RDN[] rdns2 = name2.getRDNs();
-
- if (rdns1.length != rdns2.length)
+ if (name1.size() != name2.size())
{
return false;
}
+ RDN[] rdns1 = name1.getRDNs();
+ RDN[] rdns2 = name2.getRDNs();
+
for (int i = 0; i != rdns1.length; i++)
{
if (!rdnAreEqual(rdns1[i], rdns2[i]))
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java
index e320f82..81f5ea0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java
@@ -293,9 +293,9 @@
defaultLookUp = copyHashTable(DefaultLookUp);
}
- protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid,
- String value) {
- if (oid.equals(EmailAddress) || oid.equals(DC))
+ protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, String value)
+ {
+ if (oid.equals(EmailAddress) || oid.equals(DC))
{
return new DERIA5String(value);
}
@@ -303,18 +303,18 @@
{
return new ASN1GeneralizedTime(value);
}
- else if (oid.equals(C) || oid.equals(SN) || oid.equals(DN_QUALIFIER)
+ else if (oid.equals(C) || oid.equals(SERIALNUMBER) || oid.equals(DN_QUALIFIER)
|| oid.equals(TELEPHONE_NUMBER))
{
return new DERPrintableString(value);
}
-
- return super.encodeStringValue(oid, value);
+
+ return super.encodeStringValue(oid, value);
}
public String oidToDisplayName(ASN1ObjectIdentifier oid)
{
- return (String)DefaultSymbols.get(oid);
+ return (String)defaultSymbols.get(oid);
}
public String[] oidToAttrNames(ASN1ObjectIdentifier oid)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/IETFUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/IETFUtils.java
index 130a589..da849eb 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/IETFUtils.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/IETFUtils.java
@@ -11,7 +11,7 @@
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1String;
-import com.android.internal.org.bouncycastle.asn1.DERUniversalString;
+import com.android.internal.org.bouncycastle.asn1.ASN1UniversalString;
import com.android.internal.org.bouncycastle.asn1.x500.AttributeTypeAndValue;
import com.android.internal.org.bouncycastle.asn1.x500.RDN;
import com.android.internal.org.bouncycastle.asn1.x500.X500NameBuilder;
@@ -26,12 +26,15 @@
{
private static String unescape(String elt)
{
- if (elt.length() == 0 || (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0))
+ if (elt.length() == 0)
+ {
+ return elt;
+ }
+ if (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0)
{
return elt.trim();
}
- char[] elts = elt.toCharArray();
boolean escaped = false;
boolean quoted = false;
StringBuffer buf = new StringBuffer(elt.length());
@@ -39,9 +42,9 @@
// if it's an escaped hash string and not an actual encoding in string form
// we need to leave it escaped.
- if (elts[0] == '\\')
+ if (elt.charAt(0) == '\\')
{
- if (elts[1] == '#')
+ if (elt.charAt(1) == '#')
{
start = 2;
buf.append("\\#");
@@ -52,9 +55,9 @@
int lastEscaped = 0;
char hex1 = 0;
- for (int i = start; i != elts.length; i++)
+ for (int i = start; i != elt.length(); i++)
{
- char c = elts[i];
+ char c = elt.charAt(i);
if (c != ' ')
{
@@ -70,8 +73,8 @@
else
{
buf.append(c);
+ escaped = false;
}
- escaped = false;
}
else if (c == '\\' && !(escaped || quoted))
{
@@ -132,81 +135,93 @@
public static RDN[] rDNsFromString(String name, X500NameStyle x500Style)
{
- X500NameTokenizer nTok = new X500NameTokenizer(name);
+ X500NameTokenizer tokenizer = new X500NameTokenizer(name);
X500NameBuilder builder = new X500NameBuilder(x500Style);
- while (nTok.hasMoreTokens())
+ addRDNs(x500Style, builder, tokenizer);
+
+ // TODO There's an unnecessary clone of the RDNs array happening here
+ return builder.build().getRDNs();
+ }
+
+ private static void addRDNs(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer)
+ {
+ String token;
+ while ((token = tokenizer.nextToken()) != null)
{
- String token = nTok.nextToken();
-
- if (token.indexOf('+') > 0)
+ if (token.indexOf('+') >= 0)
{
- X500NameTokenizer pTok = new X500NameTokenizer(token, '+');
- X500NameTokenizer vTok = new X500NameTokenizer(pTok.nextToken(), '=');
-
- String attr = vTok.nextToken();
-
- if (!vTok.hasMoreTokens())
- {
- throw new IllegalArgumentException("badly formatted directory string");
- }
-
- String value = vTok.nextToken();
- ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim());
-
- if (pTok.hasMoreTokens())
- {
- Vector oids = new Vector();
- Vector values = new Vector();
-
- oids.addElement(oid);
- values.addElement(unescape(value));
-
- while (pTok.hasMoreTokens())
- {
- vTok = new X500NameTokenizer(pTok.nextToken(), '=');
-
- attr = vTok.nextToken();
-
- if (!vTok.hasMoreTokens())
- {
- throw new IllegalArgumentException("badly formatted directory string");
- }
-
- value = vTok.nextToken();
- oid = x500Style.attrNameToOID(attr.trim());
-
-
- oids.addElement(oid);
- values.addElement(unescape(value));
- }
-
- builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values));
- }
- else
- {
- builder.addRDN(oid, unescape(value));
- }
+ addMultiValuedRDN(style, builder, new X500NameTokenizer(token, '+'));
}
else
{
- X500NameTokenizer vTok = new X500NameTokenizer(token, '=');
-
- String attr = vTok.nextToken();
-
- if (!vTok.hasMoreTokens())
- {
- throw new IllegalArgumentException("badly formatted directory string");
- }
-
- String value = vTok.nextToken();
- ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim());
-
- builder.addRDN(oid, unescape(value));
+ addRDN(style, builder, token);
}
}
+ }
- return builder.build().getRDNs();
+ private static void addMultiValuedRDN(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer)
+ {
+ String token = tokenizer.nextToken();
+ if (token == null)
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
+
+ if (!tokenizer.hasMoreTokens())
+ {
+ addRDN(style, builder, token);
+ return;
+ }
+
+ Vector oids = new Vector();
+ Vector values = new Vector();
+
+ do
+ {
+ collectAttributeTypeAndValue(style, oids, values, token);
+ token = tokenizer.nextToken();
+ }
+ while (token != null);
+
+ builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values));
+ }
+
+ private static void addRDN(X500NameStyle style, X500NameBuilder builder, String token)
+ {
+ X500NameTokenizer tokenizer = new X500NameTokenizer(token, '=');
+
+ String typeToken = nextToken(tokenizer, true);
+ String valueToken = nextToken(tokenizer, false);
+
+ ASN1ObjectIdentifier oid = style.attrNameToOID(typeToken.trim());
+ String value = unescape(valueToken);
+
+ builder.addRDN(oid, value);
+ }
+
+ private static void collectAttributeTypeAndValue(X500NameStyle style, Vector oids, Vector values, String token)
+ {
+ X500NameTokenizer tokenizer = new X500NameTokenizer(token, '=');
+
+ String typeToken = nextToken(tokenizer, true);
+ String valueToken = nextToken(tokenizer, false);
+
+ ASN1ObjectIdentifier oid = style.attrNameToOID(typeToken.trim());
+ String value = unescape(valueToken);
+
+ oids.addElement(oid);
+ values.addElement(value);
+ }
+
+ private static String nextToken(X500NameTokenizer tokenizer, boolean expectMoreTokens)
+ {
+ String token = tokenizer.nextToken();
+ if (token == null || tokenizer.hasMoreTokens() != expectMoreTokens)
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
+ return token;
}
private static String[] toValueArray(Vector values)
@@ -358,7 +373,7 @@
{
StringBuffer vBuf = new StringBuffer();
- if (value instanceof ASN1String && !(value instanceof DERUniversalString))
+ if (value instanceof ASN1String && !(value instanceof ASN1UniversalString))
{
String v = ((ASN1String)value).getString();
if (v.length() > 0 && v.charAt(0) == '#')
@@ -373,6 +388,7 @@
try
{
vBuf.append('#');
+ // -DM Hex.toHexString
vBuf.append(Hex.toHexString(value.toASN1Primitive().getEncoded(ASN1Encoding.DER)));
}
catch (IOException e)
@@ -427,7 +443,7 @@
int endBuf = vBuf.length() - 1;
- while (endBuf >= 0 && vBuf.charAt(endBuf) == ' ')
+ while (endBuf >= start && vBuf.charAt(endBuf) == ' ')
{
vBuf.insert(endBuf, '\\');
endBuf--;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/RFC4519Style.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/RFC4519Style.java
index 7d8f676..5679f9d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/RFC4519Style.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/RFC4519Style.java
@@ -15,7 +15,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class RFC4519Style
- extends AbstractX500NameStyle
+ extends AbstractX500NameStyle
{
public static final ASN1ObjectIdentifier businessCategory = new ASN1ObjectIdentifier("2.5.4.15").intern();
public static final ASN1ObjectIdentifier c = new ASN1ObjectIdentifier("2.5.4.6").intern();
@@ -179,9 +179,9 @@
defaultLookUp = copyHashTable(DefaultLookUp);
}
- protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid,
- String value) {
- if (oid.equals(dc))
+ protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, String value)
+ {
+ if (oid.equals(dc))
{
return new DERIA5String(value);
}
@@ -191,12 +191,12 @@
return new DERPrintableString(value);
}
- return super.encodeStringValue(oid, value);
+ return super.encodeStringValue(oid, value);
}
public String oidToDisplayName(ASN1ObjectIdentifier oid)
{
- return (String)DefaultSymbols.get(oid);
+ return (String)defaultSymbols.get(oid);
}
public String[] oidToAttrNames(ASN1ObjectIdentifier oid)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java
index 6622550..a45f4a8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java
@@ -10,83 +10,78 @@
*/
public class X500NameTokenizer
{
- private String value;
- private int index;
- private char separator;
- private StringBuffer buf = new StringBuffer();
+ private final String value;
+ private final char separator;
- public X500NameTokenizer(
- String oid)
+ private int index;
+
+ public X500NameTokenizer(String oid)
{
this(oid, ',');
}
-
- public X500NameTokenizer(
- String oid,
- char separator)
+
+ public X500NameTokenizer(String oid, char separator)
{
+ if (oid == null)
+ {
+ throw new NullPointerException();
+ }
+ if (separator == '"' || separator == '\\')
+ {
+ throw new IllegalArgumentException("reserved separator character");
+ }
+
this.value = oid;
- this.index = -1;
this.separator = separator;
+ this.index = oid.length() < 1 ? 0 : -1;
}
public boolean hasMoreTokens()
{
- return (index != value.length());
+ return index < value.length();
}
public String nextToken()
{
- if (index == value.length())
+ if (index >= value.length())
{
return null;
}
- int end = index + 1;
boolean quoted = false;
boolean escaped = false;
- buf.setLength(0);
-
- while (end != value.length())
+ int beginIndex = index + 1;
+ while (++index < value.length())
{
- char c = value.charAt(end);
+ char c = value.charAt(index);
- if (c == '"')
+ if (escaped)
{
- if (!escaped)
- {
- quoted = !quoted;
- }
- buf.append(c);
escaped = false;
}
- else
+ else if (c == '"')
{
- if (escaped || quoted)
- {
- buf.append(c);
- escaped = false;
- }
- else if (c == '\\')
- {
- buf.append(c);
- escaped = true;
- }
- else if (c == separator)
- {
- break;
- }
- else
- {
- buf.append(c);
- }
+ quoted = !quoted;
}
- end++;
+ else if (quoted)
+ {
+ }
+ else if (c == '\\')
+ {
+ escaped = true;
+ }
+ else if (c == separator)
+ {
+ return value.substring(beginIndex, index);
+ }
}
- index = end;
+ if (escaped || quoted)
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
- return buf.toString();
+ return value.substring(beginIndex, index);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AltSignatureAlgorithm.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AltSignatureAlgorithm.java
new file mode 100644
index 0000000..429a072
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AltSignatureAlgorithm.java
@@ -0,0 +1,96 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+
+/**
+ * X.509 Section 9.8.3.
+ * <br/>
+ * This extension may be used as a public-key certificate extension, a CRL extension or an AVL extension. It shall contain
+ * the algorithm identifier for the alternative digital signature algorithm used by the signer when creating an alternative
+ * digital signature and by the relying party when validating the alternative digital signature.
+ * <pre>
+ * altSignatureAlgorithm EXTENSION ::= {
+ * SYNTAX AltSignatureAlgorithm
+ * IDENTIFIED BY id-ce-altSignatureAlgorithm }
+ *
+ * AltSignatureAlgorithm ::= AlgorithmIdentifier{{SupportedAlgorithms}}
+ * </pre>
+ * When the altSignatureAlgorithm extension is included in a particular value that is an instance of a data type that
+ * supports extensions, the altSignatureValue extension shall also be included.
+ * <br/>
+ * NOTE 1 – By having a separate altSignatureAlgorithm extension, instead of having it combined with the
+ * altSignatureValue extension, the alternative digital signature algorithm is protected by the alternative signature.
+ * This extension may be flagged either as critical or as non-critical.
+ * <br/>
+ * NOTE 2 – It is recommended that it be flagged as non-critical. Flagging it as critical would require all relying parties to understand
+ * the extension and the alternative public-key algorithms
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AltSignatureAlgorithm
+ extends ASN1Object
+{
+ private final AlgorithmIdentifier algorithm;
+
+ public static AltSignatureAlgorithm getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(AlgorithmIdentifier.getInstance(obj, explicit));
+ }
+
+ public static AltSignatureAlgorithm getInstance(
+ Object obj)
+ {
+ if (obj instanceof AltSignatureAlgorithm)
+ {
+ return (AltSignatureAlgorithm)obj;
+ }
+ else if (obj != null)
+ {
+ return new AltSignatureAlgorithm(AlgorithmIdentifier.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static AltSignatureAlgorithm fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.altSignatureAlgorithm));
+ }
+
+ public AltSignatureAlgorithm(AlgorithmIdentifier algorithm)
+ {
+ this.algorithm = algorithm;
+ }
+
+ public AltSignatureAlgorithm(ASN1ObjectIdentifier algorithm)
+ {
+ this(algorithm, null);
+ }
+
+ public AltSignatureAlgorithm(ASN1ObjectIdentifier algorithm, ASN1Encodable parameters)
+ {
+ this.algorithm = new AlgorithmIdentifier(algorithm, parameters);
+ }
+
+ /**
+ * Return the algorithm identifier representing the alternate signature algorithm
+ * used to generate the alternate signature algorithm value extension.
+ *
+ * @return alternate signature algorithm identifier.
+ */
+ public AlgorithmIdentifier getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return algorithm.toASN1Primitive();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AltSignatureValue.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AltSignatureValue.java
new file mode 100644
index 0000000..080cb14
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AltSignatureValue.java
@@ -0,0 +1,96 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+
+/**
+ * X.509 Section 9.8.4.
+ * <br/>
+ * This extension may be used as a public-key certificate extension, a CRL extension or an AVL extension.
+ * This alternative signature shall be created by the issuer using its alternative private key, and it shall be verified using the
+ * alternative public key of the issuer.
+ * <pre>
+ * altSignatureValue EXTENSION ::= {
+ * SYNTAX AltSignatureValue
+ * IDENTIFIED BY id-ce-altSignatureValue }
+ *
+ * AltSignatureValue ::= BIT STRING
+ * </pre>
+ * This extension can only be created by a signer holding a multiple cryptographic algorithms public-key certificate. When
+ * creating the alternative digital signature on an issued public-key certificate or CRL, the signer shall use its alternative
+ * private key.
+ * <br/>
+ * The procedures for creating and validating alternative digital signatures are specified in:
+ * <ul>
+ * <li>clause 7.2.2 for public-key certificates;</li>
+ * <li>clause 7.10.3 for CRLs: and</li>
+ * <li>clause 11.4 for AVLs.</li>
+ * </ul>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AltSignatureValue
+ extends ASN1Object
+{
+ private final ASN1BitString signature;
+
+ public static AltSignatureValue getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1BitString.getInstance(obj, explicit));
+ }
+
+ public static AltSignatureValue getInstance(
+ Object obj)
+ {
+ if (obj instanceof AltSignatureValue)
+ {
+ return (AltSignatureValue)obj;
+ }
+ else if (obj != null)
+ {
+ return new AltSignatureValue(ASN1BitString.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static AltSignatureValue fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.altSignatureValue));
+ }
+
+ private AltSignatureValue(ASN1BitString signature)
+ {
+ this.signature = signature;
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param signature a signature value, based on the enclosing certificate.
+ */
+ public AltSignatureValue(byte[] signature)
+ {
+ this.signature = new DERBitString(signature);
+ }
+
+ /**
+ * Return the alternate signature to verify the certificate.
+ *
+ * @return certificate's alternate signature.
+ */
+ public ASN1BitString getSignature()
+ {
+ return signature;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return signature;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertIssuer.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertIssuer.java
index ea2103f..acf96bb 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertIssuer.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertIssuer.java
@@ -50,7 +50,7 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ return getInstance(obj.getExplicitBaseObject()); // must be explicitly tagged
}
/**
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java
index 1148862..d0f07a6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x509;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
@@ -16,7 +17,7 @@
{
AttributeCertificateInfo acinfo;
AlgorithmIdentifier signatureAlgorithm;
- DERBitString signatureValue;
+ ASN1BitString signatureValue;
/**
* @param obj
@@ -39,28 +40,23 @@
public AttributeCertificate(
AttributeCertificateInfo acinfo,
AlgorithmIdentifier signatureAlgorithm,
- DERBitString signatureValue)
+ ASN1BitString signatureValue)
{
this.acinfo = acinfo;
this.signatureAlgorithm = signatureAlgorithm;
this.signatureValue = signatureValue;
}
- /**
- * @deprecated use getInstance() method.
- */
- public AttributeCertificate(
- ASN1Sequence seq)
+ private AttributeCertificate(ASN1Sequence seq)
{
if (seq.size() != 3)
{
- throw new IllegalArgumentException("Bad sequence size: "
- + seq.size());
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
}
this.acinfo = AttributeCertificateInfo.getInstance(seq.getObjectAt(0));
this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- this.signatureValue = DERBitString.getInstance(seq.getObjectAt(2));
+ this.signatureValue = ASN1BitString.getInstance(seq.getObjectAt(2));
}
public AttributeCertificateInfo getAcinfo()
@@ -73,7 +69,7 @@
return signatureAlgorithm;
}
- public DERBitString getSignatureValue()
+ public ASN1BitString getSignatureValue()
{
return signatureValue;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
index db94e6f..a631ea6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x509;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
@@ -8,7 +9,6 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
/**
@@ -21,10 +21,10 @@
private Holder holder;
private AttCertIssuer issuer;
private AlgorithmIdentifier signature;
- private ASN1Integer serialNumber;
+ private ASN1Integer serialNumber;
private AttCertValidityPeriod attrCertValidityPeriod;
private ASN1Sequence attributes;
- private DERBitString issuerUniqueID;
+ private ASN1BitString issuerUniqueID;
private Extensions extensions;
public static AttributeCertificateInfo getInstance(
@@ -80,9 +80,9 @@
{
ASN1Encodable obj = seq.getObjectAt(i);
- if (obj instanceof DERBitString)
+ if (obj instanceof ASN1BitString)
{
- this.issuerUniqueID = DERBitString.getInstance(seq.getObjectAt(i));
+ this.issuerUniqueID = ASN1BitString.getInstance(seq.getObjectAt(i));
}
else if (obj instanceof ASN1Sequence || obj instanceof Extensions)
{
@@ -126,7 +126,7 @@
return attributes;
}
- public DERBitString getIssuerUniqueID()
+ public ASN1BitString getIssuerUniqueID()
{
return issuerUniqueID;
}
@@ -158,7 +158,7 @@
{
ASN1EncodableVector v = new ASN1EncodableVector(9);
- if (version.intValueExact() != 0)
+ if (!version.hasValue(0))
{
v.add(version);
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
index 23ae0c7..400da2e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
@@ -18,6 +18,7 @@
// Android-changed: Use Android digests
// import org.bouncycastle.crypto.digests.SHA1Digest;
import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.internal.org.bouncycastle.util.Arrays;
import com.android.internal.org.bouncycastle.util.encoders.Hex;
/**
@@ -175,7 +176,7 @@
GeneralNames name,
BigInteger serialNumber)
{
- this.keyidentifier = (keyIdentifier != null) ? new DEROctetString(keyIdentifier) : null;
+ this.keyidentifier = (keyIdentifier != null) ? new DEROctetString(Arrays.clone(keyIdentifier)) : null;
this.certissuer = name;
this.certserno = (serialNumber != null) ? new ASN1Integer(serialNumber) : null;
}
@@ -232,6 +233,7 @@
public String toString()
{
+ // -DM Hex.toHexString
String keyID = (keyidentifier != null) ? Hex.toHexString(keyidentifier.getOctets()) : "null";
return "AuthorityKeyIdentifier: KeyID(" + keyID + ")";
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java
index 54cb6b7..538137c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java
@@ -126,6 +126,11 @@
return null;
}
+ public ASN1Integer getPathLenConstraintInteger()
+ {
+ return pathLenConstraint;
+ }
+
/**
* Produce an object suitable for an ASN1OutputStream.
* <pre>
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLNumber.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLNumber.java
index 291bf6c..dde27f2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLNumber.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLNumber.java
@@ -6,6 +6,7 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
/**
* The CRLNumber object.
@@ -22,6 +23,10 @@
public CRLNumber(
BigInteger number)
{
+ if (BigIntegers.ZERO.compareTo(number) > 0)
+ {
+ throw new IllegalArgumentException("Invalid CRL number : not in (0..MAX)");
+ }
this.number = number;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java
index 1055281..73b9f72 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java
@@ -53,7 +53,7 @@
/**
* @deprecated use lower case version
*/
- public static final int CESSATION_OF_OPERATION = 5;
+ public static final int CESSATION_OF_OPERATION = 5;
/**
* @deprecated use lower case version
*/
@@ -76,7 +76,7 @@
public static final int cACompromise = 2;
public static final int affiliationChanged = 3;
public static final int superseded = 4;
- public static final int cessationOfOperation = 5;
+ public static final int cessationOfOperation = 5;
public static final int certificateHold = 6;
// 7 -> unknown
public static final int removeFromCRL = 8;
@@ -84,11 +84,11 @@
public static final int aACompromise = 10;
private static final String[] reasonString =
- {
- "unspecified", "keyCompromise", "cACompromise", "affiliationChanged",
- "superseded", "cessationOfOperation", "certificateHold", "unknown",
- "removeFromCRL", "privilegeWithdrawn", "aACompromise"
- };
+ {
+ "unspecified", "keyCompromise", "cACompromise", "affiliationChanged",
+ "superseded", "cessationOfOperation", "certificateHold", "unknown",
+ "removeFromCRL", "privilegeWithdrawn", "aACompromise"
+ };
private static final Hashtable table = new Hashtable();
@@ -111,6 +111,10 @@
private CRLReason(
int reason)
{
+ if (reason < 0)
+ {
+ throw new IllegalArgumentException("Invalid CRL reason : not in (0..MAX)");
+ }
value = new ASN1Enumerated(reason);
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Certificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Certificate.java
index 667c834..308ed94 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Certificate.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Certificate.java
@@ -1,12 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x509;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
/**
@@ -26,7 +26,7 @@
ASN1Sequence seq;
TBSCertificate tbsCert;
AlgorithmIdentifier sigAlgId;
- DERBitString sig;
+ ASN1BitString sig;
public static Certificate getInstance(
ASN1TaggedObject obj,
@@ -63,7 +63,7 @@
tbsCert = TBSCertificate.getInstance(seq.getObjectAt(0));
sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- sig = DERBitString.getInstance(seq.getObjectAt(2));
+ sig = ASN1BitString.getInstance(seq.getObjectAt(2));
}
else
{
@@ -121,7 +121,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sig;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java
index 218a623..2e1e0ed 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java
@@ -4,6 +4,7 @@
import java.util.Enumeration;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
@@ -32,7 +33,7 @@
{
TBSCertList tbsCertList;
AlgorithmIdentifier sigAlgId;
- DERBitString sig;
+ ASN1BitString sig;
boolean isHashCodeSet = false;
int hashCodeValue;
@@ -58,18 +59,14 @@
return null;
}
- /**
- * @deprecated use getInstance() method.
- * @param seq
- */
- public CertificateList(
+ private CertificateList(
ASN1Sequence seq)
{
if (seq.size() == 3)
{
tbsCertList = TBSCertList.getInstance(seq.getObjectAt(0));
sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- sig = DERBitString.getInstance(seq.getObjectAt(2));
+ sig = ASN1BitString.getInstance(seq.getObjectAt(2));
}
else
{
@@ -97,7 +94,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sig;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java
new file mode 100644
index 0000000..459da2d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DeltaCertificateDescriptor.java
@@ -0,0 +1,276 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * <pre>
+ * DeltaCertificateDescriptor ::= SEQUENCE {
+ * serialNumber CertificateSerialNumber,
+ * signature [0] IMPLICIT AlgorithmIdentifier
+ * {SIGNATURE_ALGORITHM, {...}} OPTIONAL,
+ * issuer [1] IMPLICIT Name OPTIONAL,
+ * validity [2] IMPLICIT Validity OPTIONAL,
+ * subject [3] IMPLICIT Name OPTIONAL,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * extensions [4] IMPLICIT Extensions{CertExtensions}
+ * OPTIONAL,
+ * signatureValue BIT STRING
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DeltaCertificateDescriptor
+ extends ASN1Object
+{
+ private final ASN1Integer serialNumber;
+
+ private AlgorithmIdentifier signature;
+ private X500Name issuer;
+ private ASN1Sequence validity;
+ private X500Name subject;
+ private SubjectPublicKeyInfo subjectPublicKeyInfo;
+ private Extensions extensions;
+
+ private final ASN1BitString signatureValue;
+
+ public static DeltaCertificateDescriptor getInstance(
+ Object obj)
+ {
+ if (obj instanceof DeltaCertificateDescriptor)
+ {
+ return (DeltaCertificateDescriptor)obj;
+ }
+ else if (obj != null)
+ {
+ return new DeltaCertificateDescriptor(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieve a DeltaCertificateDescriptor for a passed in Extensions object, if present.
+ *
+ * @param extensions the extensions object to be examined.
+ * @return the DeltaCertificateDescriptor, null if the extension is not present.
+ */
+ public static DeltaCertificateDescriptor fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.deltaCertificateDescriptor));
+ }
+
+ private DeltaCertificateDescriptor(ASN1Sequence seq)
+ {
+ this.serialNumber = ASN1Integer.getInstance(seq.getObjectAt(0));
+
+ int idx = 1;
+ ASN1Encodable next = seq.getObjectAt(idx);
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ signature = AlgorithmIdentifier.getInstance(tagged, false);
+ break;
+ case 1:
+ issuer = X500Name.getInstance(tagged, true); // issuer
+ break;
+ case 2:
+ validity = ASN1Sequence.getInstance(tagged, false);
+ break;
+ case 3:
+ subject = X500Name.getInstance(tagged, true); // subject
+ break;
+ }
+ next = seq.getObjectAt(idx++);
+ }
+
+ subjectPublicKeyInfo = subjectPublicKeyInfo.getInstance(next);
+
+ next = seq.getObjectAt(idx);
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 4:
+ extensions = Extensions.getInstance(tagged, false);
+ break;
+ }
+ next = seq.getObjectAt(idx++);
+ }
+
+ signatureValue = ASN1BitString.getInstance(next);
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ public AlgorithmIdentifier getSignature()
+ {
+ return signature;
+ }
+
+ public X500Name getIssuer()
+ {
+ return issuer;
+ }
+
+ public ASN1Sequence getValidity()
+ {
+ return validity;
+ }
+
+ public X500Name getSubject()
+ {
+ return subject;
+ }
+
+ public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
+ {
+ return subjectPublicKeyInfo;
+ }
+
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+
+ public ASN1BitString getSignatureValue()
+ {
+ return signatureValue;
+ }
+
+ public DeltaCertificateDescriptor trimTo(TBSCertificate baseTbsCertificate, Extensions tbsExtensions)
+ {
+ AlgorithmIdentifier signature = baseTbsCertificate.signature;
+ X500Name issuer = baseTbsCertificate.issuer;
+ ASN1Sequence validity = new DERSequence(new ASN1Encodable[]
+ {
+ baseTbsCertificate.startDate, baseTbsCertificate.endDate
+ });
+ X500Name subject = baseTbsCertificate.subject;
+ ASN1Sequence s = ASN1Sequence.getInstance(toASN1Primitive());
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ Enumeration en = s.getObjects();
+ v.add((ASN1Encodable)en.nextElement());
+
+ ASN1Encodable next = (ASN1Encodable)en.nextElement();
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ AlgorithmIdentifier sig = AlgorithmIdentifier.getInstance(tagged, false);
+ if (!sig.equals(signature))
+ {
+ v.add(next);
+ }
+ break;
+ case 1:
+ X500Name iss = X500Name.getInstance(tagged, true); // issuer
+ if (!iss.equals(issuer))
+ {
+ v.add(next);
+ }
+ break;
+ case 2:
+ ASN1Sequence val = ASN1Sequence.getInstance(tagged, false);
+ if (!val.equals(validity))
+ {
+ v.add(next);
+ }
+ break;
+ case 3:
+ X500Name sub = X500Name.getInstance(tagged, true); // subject
+ if (!sub.equals(subject))
+ {
+ v.add(next);
+ }
+ break;
+ }
+ next = (ASN1Encodable)en.nextElement();
+ }
+
+ v.add(next);
+
+ next = (ASN1Encodable)en.nextElement();
+ while (next instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(next);
+ switch (tagged.getTagNo())
+ {
+ case 4:
+ Extensions deltaExts = Extensions.getInstance(tagged, false);
+ ExtensionsGenerator deltaExtGen = new ExtensionsGenerator();
+ for (Enumeration extEn = deltaExts.oids(); extEn.hasMoreElements(); )
+ {
+ Extension deltaExt = deltaExts.getExtension((ASN1ObjectIdentifier)extEn.nextElement());
+ Extension primaryExt = tbsExtensions.getExtension(deltaExt.getExtnId());
+
+ if (primaryExt != null)
+ {
+ if (!deltaExt.equals(primaryExt))
+ {
+ deltaExtGen.addExtension(deltaExt);
+ }
+ }
+ }
+
+ DeltaCertificateDescriptor trimmedDeltaCertDesc;
+ if (!deltaExtGen.isEmpty())
+ {
+ v.add(new DERTaggedObject(false, 4, deltaExtGen.generate()));
+ }
+ }
+ next = (ASN1Encodable)en.nextElement();
+ }
+
+ v.add(next);
+
+ return new DeltaCertificateDescriptor(new DERSequence(v));
+ }
+
+ private void addOptional(ASN1EncodableVector v, int tag, boolean explicit, ASN1Object obj)
+ {
+ if (obj != null)
+ {
+ v.add(new DERTaggedObject(explicit, tag, obj));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(7);
+
+ v.add(serialNumber);
+ addOptional(v, 0, false, signature);
+ addOptional(v, 1, true, issuer); // CHOICE
+ addOptional(v, 2, false, validity);
+ addOptional(v, 3, true, subject); // CHOICE
+ v.add(subjectPublicKeyInfo);
+ addOptional(v, 4, false, extensions);
+ v.add(signatureValue);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java
index 4d3b786..8e16403 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java
@@ -1,12 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x509;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
import com.android.internal.org.bouncycastle.util.Strings;
@@ -61,10 +61,11 @@
switch (t.getTagNo())
{
case 0:
+ // CHOICE so explicit
distributionPoint = DistributionPointName.getInstance(t, true);
break;
case 1:
- reasons = new ReasonFlags(DERBitString.getInstance(t, false));
+ reasons = new ReasonFlags(ASN1BitString.getInstance(t, false));
break;
case 2:
cRLIssuer = GeneralNames.getInstance(t, false);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java
index 548f930..487fc44 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java
@@ -13,6 +13,7 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Arrays;
/**
* an object for the elements in the X.509 V3 extension block.
@@ -181,6 +182,26 @@
*/
public static final ASN1ObjectIdentifier expiredCertsOnCRL = new ASN1ObjectIdentifier("2.5.29.60").intern();
+ /**
+ * the subject’s alternative public key information
+ */
+ public static final ASN1ObjectIdentifier subjectAltPublicKeyInfo = new ASN1ObjectIdentifier("2.5.29.72").intern();
+
+ /**
+ * the algorithm identifier for the alternative digital signature algorithm.
+ */
+ public static final ASN1ObjectIdentifier altSignatureAlgorithm = new ASN1ObjectIdentifier("2.5.29.73").intern();
+
+ /**
+ * alternative signature shall be created by the issuer using its alternative private key.
+ */
+ public static final ASN1ObjectIdentifier altSignatureValue = new ASN1ObjectIdentifier("2.5.29.74").intern();
+
+ /**
+ * delta certificate extension - prototype value will change!
+ */
+ public static final ASN1ObjectIdentifier deltaCertificateDescriptor = new ASN1ObjectIdentifier("2.16.840.1.114027.80.6.1");
+
private ASN1ObjectIdentifier extnId;
private boolean critical;
private ASN1OctetString value;
@@ -212,7 +233,7 @@
boolean critical,
byte[] value)
{
- this(extnId, critical, new DEROctetString(value));
+ this(extnId, critical, new DEROctetString(Arrays.clone(value)));
}
/**
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java
index 0d5cec1..f715156 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java
@@ -13,6 +13,7 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Properties;
/**
* <pre>
@@ -72,6 +73,11 @@
private Extensions(
ASN1Sequence seq)
{
+ if (seq.size() == 0)
+ {
+ throw new IllegalArgumentException("empty extension sequence found");
+ }
+
Enumeration e = seq.getObjects();
while (e.hasMoreElements())
@@ -80,7 +86,10 @@
if (extensions.containsKey(ext.getExtnId()))
{
- throw new IllegalArgumentException("repeated extension found: " + ext.getExtnId());
+ if (!Properties.isOverrideSet("com.android.internal.org.bouncycastle.x509.ignore_repeated_extensions"))
+ {
+ throw new IllegalArgumentException("repeated extension found: " + ext.getExtnId());
+ }
}
extensions.put(ext.getExtnId(), ext);
@@ -108,6 +117,11 @@
public Extensions(
Extension[] extensions)
{
+ if (extensions == null || extensions.length == 0)
+ {
+ throw new IllegalArgumentException("extension array cannot be null or empty");
+ }
+
for (int i = 0; i != extensions.length; i++)
{
Extension ext = extensions[i];
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
index 7f9db5f..27c261b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
@@ -2,13 +2,22 @@
package com.android.internal.org.bouncycastle.asn1.x509;
import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Set;
import java.util.Vector;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1ParsingException;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Arrays;
/**
* Generator for X.509 extensions
@@ -18,6 +27,18 @@
{
private Hashtable extensions = new Hashtable();
private Vector extOrdering = new Vector();
+ private static final Set dupsAllowed;
+
+
+ static
+ {
+ Set dups = new HashSet();
+ dups.add(Extension.subjectAlternativeName);
+ dups.add(Extension.issuerAlternativeName);
+ dups.add(Extension.subjectDirectoryAttributes);
+ dups.add(Extension.certificateIssuer);
+ dupsAllowed = Collections.unmodifiableSet(dups);
+ }
/**
* Reset the generator
@@ -32,14 +53,14 @@
* Add an extension with the given oid and the passed in value to be included
* in the OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
- * @param critical true if critical, false otherwise.
- * @param value the ASN.1 object to be included in the extension.
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the ASN.1 object to be included in the extension.
*/
public void addExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- ASN1Encodable value)
+ boolean critical,
+ ASN1Encodable value)
throws IOException
{
this.addExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER));
@@ -49,22 +70,52 @@
* Add an extension with the given oid and the passed in byte array to be wrapped in the
* OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
+ * @param oid OID for the extension.
* @param critical true if critical, false otherwise.
- * @param value the byte array to be wrapped.
+ * @param value the byte array to be wrapped.
*/
public void addExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- byte[] value)
+ boolean critical,
+ byte[] value)
{
if (extensions.containsKey(oid))
{
- throw new IllegalArgumentException("extension " + oid + " already added");
- }
+ if (dupsAllowed.contains(oid))
+ {
+ Extension existingExtension = (Extension)extensions.get(oid);
+ ASN1Sequence seq1 = ASN1Sequence.getInstance(DEROctetString.getInstance(existingExtension.getExtnValue()).getOctets());
+ ASN1Sequence seq2 = ASN1Sequence.getInstance(value);
- extOrdering.addElement(oid);
- extensions.put(oid, new Extension(oid, critical, new DEROctetString(value)));
+ ASN1EncodableVector items = new ASN1EncodableVector(seq1.size() + seq2.size());
+ for (Enumeration en = seq1.getObjects(); en.hasMoreElements();)
+ {
+ items.add((ASN1Encodable)en.nextElement());
+ }
+ for (Enumeration en = seq2.getObjects(); en.hasMoreElements();)
+ {
+ items.add((ASN1Encodable)en.nextElement());
+ }
+
+ try
+ {
+ extensions.put(oid, new Extension(oid, critical, new DERSequence(items).getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException(e.getMessage(), e);
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("extension " + oid + " already added");
+ }
+ }
+ else
+ {
+ extOrdering.addElement(oid);
+ extensions.put(oid, new Extension(oid, critical, new DEROctetString(Arrays.clone(value))));
+ }
}
/**
@@ -88,14 +139,14 @@
* Replace an extension with the given oid and the passed in value to be included
* in the OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
- * @param critical true if critical, false otherwise.
- * @param value the ASN.1 object to be included in the extension.
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the ASN.1 object to be included in the extension.
*/
public void replaceExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- ASN1Encodable value)
+ boolean critical,
+ ASN1Encodable value)
throws IOException
{
this.replaceExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER));
@@ -105,14 +156,14 @@
* Replace an extension with the given oid and the passed in byte array to be wrapped in the
* OCTET STRING associated with the extension.
*
- * @param oid OID for the extension.
+ * @param oid OID for the extension.
* @param critical true if critical, false otherwise.
- * @param value the byte array to be wrapped.
+ * @param value the byte array to be wrapped.
*/
public void replaceExtension(
ASN1ObjectIdentifier oid,
- boolean critical,
- byte[] value)
+ boolean critical,
+ byte[] value)
{
this.replaceExtension(new Extension(oid, critical, value));
}
@@ -158,7 +209,7 @@
*/
public boolean hasExtension(ASN1ObjectIdentifier oid)
{
- return extensions.containsKey(oid);
+ return extensions.containsKey(oid);
}
/**
@@ -169,7 +220,7 @@
*/
public Extension getExtension(ASN1ObjectIdentifier oid)
{
- return (Extension)extensions.get(oid);
+ return (Extension)extensions.get(oid);
}
/**
@@ -185,7 +236,7 @@
/**
* Generate an Extensions object based on the current state of the generator.
*
- * @return an X09Extensions object.
+ * @return an X09Extensions object.
*/
public Extensions generate()
{
@@ -198,4 +249,15 @@
return new Extensions(exts);
}
+
+ public void addExtension(Extensions extensions)
+ {
+ ASN1ObjectIdentifier[] oids = extensions.getExtensionOIDs();
+ for (int i = 0; i != oids.length; i++)
+ {
+ ASN1ObjectIdentifier ident = oids[i];
+ Extension ext = extensions.getExtension(ident);
+ addExtension(ASN1ObjectIdentifier.getInstance(ident), ext.isCritical(), ext.getExtnValue().getOctets());
+ }
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java
index 779009a..7ce143f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java
@@ -6,6 +6,7 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1IA5String;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
@@ -196,7 +197,7 @@
case dNSName:
case rfc822Name:
case uniformResourceIdentifier:
- return new GeneralName(tag, DERIA5String.getInstance(tagObj, false));
+ return new GeneralName(tag, ASN1IA5String.getInstance(tagObj, false));
case directoryName:
return new GeneralName(tag, X500Name.getInstance(tagObj, true));
@@ -229,6 +230,11 @@
ASN1TaggedObject tagObj,
boolean explicit)
{
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
return GeneralName.getInstance(ASN1TaggedObject.getInstance(tagObj, true));
}
@@ -253,7 +259,7 @@
case rfc822Name:
case dNSName:
case uniformResourceIdentifier:
- buf.append(DERIA5String.getInstance(obj).getString());
+ buf.append(ASN1IA5String.getInstance(obj).getString());
break;
case directoryName:
buf.append(X500Name.getInstance(obj).toString());
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java
index 64773c6..0c058ae 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java
@@ -205,7 +205,7 @@
v.add(base);
- if (minimum != null && !minimum.hasValue(ZERO))
+ if (minimum != null && !minimum.hasValue(0))
{
v.add(new DERTaggedObject(false, 0, minimum));
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java
index 9a4eed1..8bb4e32 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java
@@ -89,7 +89,7 @@
default:
throw new IllegalArgumentException("unknown tag in Holder");
}
- version = 0;
+ version = V1_CERTIFICATE_HOLDER;
}
/**
@@ -125,7 +125,7 @@
throw new IllegalArgumentException("unknown tag in Holder");
}
}
- version = 1;
+ version = V2_CERTIFICATE_HOLDER;
}
public Holder(IssuerSerial baseCertificateID)
@@ -211,7 +211,7 @@
public ASN1Primitive toASN1Primitive()
{
- if (version == 1)
+ if (version == V2_CERTIFICATE_HOLDER)
{
ASN1EncodableVector v = new ASN1EncodableVector(3);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java
index 0c5aba5..bc721d5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java
@@ -3,13 +3,13 @@
import java.math.BigInteger;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
@@ -19,9 +19,9 @@
public class IssuerSerial
extends ASN1Object
{
- GeneralNames issuer;
- ASN1Integer serial;
- DERBitString issuerUID;
+ GeneralNames issuer;
+ ASN1Integer serial;
+ ASN1BitString issuerUID;
public static IssuerSerial getInstance(
Object obj)
@@ -59,7 +59,7 @@
if (seq.size() == 3)
{
- issuerUID = DERBitString.getInstance(seq.getObjectAt(2));
+ issuerUID = ASN1BitString.getInstance(seq.getObjectAt(2));
}
}
@@ -95,7 +95,7 @@
return serial;
}
- public DERBitString getIssuerUID()
+ public ASN1BitString getIssuerUID()
{
return issuerUID;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
index 43d1c23..571f78e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x509;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Boolean;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
@@ -154,7 +155,7 @@
switch (o.getTagNo())
{
case 0:
- // CHOICE so explicit
+ // CHOICE so explicit
distributionPoint = DistributionPointName.getInstance(o, true);
break;
case 1:
@@ -164,7 +165,7 @@
onlyContainsCACerts = ASN1Boolean.getInstance(o, false).isTrue();
break;
case 3:
- onlySomeReasons = new ReasonFlags(ReasonFlags.getInstance(o, false));
+ onlySomeReasons = new ReasonFlags(ASN1BitString.getInstance(o, false));
break;
case 4:
indirectCRL = ASN1Boolean.getInstance(o, false).isTrue();
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java
index 0aac42b..ad1cf20 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java
@@ -109,6 +109,30 @@
*/
public static final KeyPurposeId id_kp_capwapWTP = new KeyPurposeId(id_kp.branch("19"));
+
+ /**
+ * id-kp-cmcCA OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) kp(3) 27 }
+ */
+ public static final KeyPurposeId id_kp_cmcCA = new KeyPurposeId(id_kp.branch("27"));
+
+ /**
+ * id-kp-cmcRA OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) kp(3) 28 }
+ */
+ public static final KeyPurposeId id_kp_cmcRA = new KeyPurposeId(id_kp.branch("28"));
+
+ /**
+ * id-kp-cmKGA OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) kp(3) 32 }
+ */
+ public static final KeyPurposeId id_kp_cmKGA = new KeyPurposeId(id_kp.branch("32"));
+
+
+
//
// microsoft key purpose ids
//
@@ -142,15 +166,6 @@
this.id = id;
}
- /**
- * @param id string representation of an OID.
- * @deprecated use getInstance and an OID or one of the constants above.
- */
- public KeyPurposeId(String id)
- {
- this(new ASN1ObjectIdentifier(id));
- }
-
public static KeyPurposeId getInstance(Object o)
{
if (o instanceof KeyPurposeId)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java
index 94433bf..aa7bfcd 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x509;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
@@ -36,7 +37,7 @@
public static final int encipherOnly = (1 << 0);
public static final int decipherOnly = (1 << 15);
- private DERBitString bitString;
+ private ASN1BitString bitString;
public static KeyUsage getInstance(Object obj) // needs to be DERBitString for other VMs
{
@@ -46,7 +47,7 @@
}
else if (obj != null)
{
- return new KeyUsage(DERBitString.getInstance(obj));
+ return new KeyUsage(ASN1BitString.getInstance(obj));
}
return null;
@@ -71,7 +72,7 @@
}
private KeyUsage(
- DERBitString bitString)
+ ASN1BitString bitString)
{
this.bitString = bitString;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
index e174f4c..4e8d9ef 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x509;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
@@ -56,7 +57,7 @@
AlgorithmIdentifier digestAlgorithm;
- DERBitString objectDigest;
+ ASN1BitString objectDigest;
public static ObjectDigestInfo getInstance(
Object obj)
@@ -131,7 +132,7 @@
digestAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1 + offset));
- objectDigest = DERBitString.getInstance(seq.getObjectAt(2 + offset));
+ objectDigest = ASN1BitString.getInstance(seq.getObjectAt(2 + offset));
}
public ASN1Enumerated getDigestedObjectType()
@@ -149,7 +150,7 @@
return digestAlgorithm;
}
- public DERBitString getObjectDigest()
+ public ASN1BitString getObjectDigest()
{
return objectDigest;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java
index 098b21f..5a45583 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java
@@ -69,7 +69,7 @@
private OtherName(ASN1Sequence seq)
{
this.typeID = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
- this.value = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject(); // explicitly tagged
+ this.value = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getExplicitBaseObject();
}
public ASN1ObjectIdentifier getTypeID()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
index 70c7a58..14e8434 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
@@ -10,9 +10,9 @@
import java.util.Map;
import java.util.Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1IA5String;
import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.internal.org.bouncycastle.asn1.DERIA5String;
import com.android.internal.org.bouncycastle.asn1.x500.RDN;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
import com.android.internal.org.bouncycastle.asn1.x500.style.IETFUtils;
@@ -1826,22 +1826,22 @@
private static String extractHostFromURL(String url)
{
// see RFC 1738
- // remove ':' after protocol, e.g. http:
+ // remove ':' after protocol, e.g. https:
String sub = url.substring(url.indexOf(':') + 1);
- // extract host from Common Internet Scheme Syntax, e.g. http://
+ // extract host from Common Internet Scheme Syntax, e.g. https://
if (sub.indexOf("//") != -1)
{
sub = sub.substring(sub.indexOf("//") + 2);
}
- // first remove port, e.g. http://test.com:21
+ // first remove port, e.g. https://test.com:21
if (sub.lastIndexOf(':') != -1)
{
sub = sub.substring(0, sub.lastIndexOf(':'));
}
- // remove user and password, e.g. http://john:[email protected]
+ // remove user and password, e.g. https://john:[email protected]
sub = sub.substring(sub.indexOf(':') + 1);
sub = sub.substring(sub.indexOf('@') + 1);
- // remove local parts, e.g. http://test.com/bla
+ // remove local parts, e.g. https://test.com/bla
if (sub.indexOf('/') != -1)
{
sub = sub.substring(0, sub.indexOf('/'));
@@ -1851,7 +1851,7 @@
private String extractNameAsString(GeneralName name)
{
- return DERIA5String.getInstance(name.getName()).getString();
+ return ASN1IA5String.getInstance(name.getName()).getString();
}
/**
@@ -2080,6 +2080,7 @@
temp.append(":");
try
{
+ // -DM Hex.toHexString
temp.append(Hex.toHexString(name.getValue().toASN1Primitive().getEncoded()));
}
catch (IOException e)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
index 8b3fda3..e51d504 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
@@ -116,4 +116,9 @@
return new DERSequence(dev);
}
+
+ public String toString()
+ {
+ return "PolicyQualifierInfo[" + policyQualifierId + ", " + qualifier + "]";
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ReasonFlags.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ReasonFlags.java
index ecb4416..f73a82e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ReasonFlags.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ReasonFlags.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x509;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
/**
@@ -80,7 +81,7 @@
}
public ReasonFlags(
- DERBitString reasons)
+ ASN1BitString reasons)
{
super(reasons.getBytes(), reasons.getPadBits());
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectAltPublicKeyInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectAltPublicKeyInfo.java
new file mode 100644
index 0000000..5c66d0d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectAltPublicKeyInfo.java
@@ -0,0 +1,110 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * X.509 Section 9.8.2.
+ * <br/>
+ * This public-key certificate extension, when present, shall contain the subject’s alternative public key information
+ * <pre>
+ * subjectAltPublicKeyInfo EXTENSION ::= {
+ * SYNTAX SubjectAltPublicKeyInfo
+ * IDENTIFIED BY id-ce-subjectAltPublicKeyInfo }
+ *
+ * SubjectAltPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier{{SupportedAlgorithms}},
+ * subjectAltPublicKey BIT STRING }
+ * </pre>
+ * The SubjectAltPublicKeyInfo data type has the following components:
+ * <ul>
+ * <li>the algorithm subcomponent, which shall hold the algorithm that this public key is an instance of</li>
+ * <li>the subjectAltPublicKey subcomponent, which shall hold the alternative public key</li>
+ * </ul>
+ * This extension may be flagged as critical or as non-critical.
+ * <br/>
+ * NOTE – It is recommended that it be flagged as non-critical. Flagging it as critical would require relying parties to understand this
+ * extension and the alternative public-key algorithm.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SubjectAltPublicKeyInfo
+ extends ASN1Object
+{
+ private AlgorithmIdentifier algorithm;
+ private ASN1BitString subjectAltPublicKey;
+
+ public static SubjectAltPublicKeyInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static SubjectAltPublicKeyInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof SubjectAltPublicKeyInfo)
+ {
+ return (SubjectAltPublicKeyInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new SubjectAltPublicKeyInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static SubjectAltPublicKeyInfo fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.subjectAltPublicKeyInfo));
+ }
+
+ private SubjectAltPublicKeyInfo(ASN1Sequence s)
+ {
+ if (s.size() != 2)
+ {
+ throw new IllegalArgumentException("extension should contain only 2 elements");
+ }
+ algorithm = AlgorithmIdentifier.getInstance(s.getObjectAt(0));
+ subjectAltPublicKey = ASN1BitString.getInstance(s.getObjectAt(1));
+ }
+
+ public SubjectAltPublicKeyInfo(AlgorithmIdentifier algorithm, ASN1BitString subjectAltPublicKey)
+ {
+ this.algorithm = algorithm;
+ this.subjectAltPublicKey = subjectAltPublicKey;
+ }
+
+ public SubjectAltPublicKeyInfo(SubjectPublicKeyInfo subjectPublicKeyInfo)
+ {
+ this.algorithm = subjectPublicKeyInfo.getAlgorithm();
+ this.subjectAltPublicKey = subjectPublicKeyInfo.getPublicKeyData();
+ }
+
+ public AlgorithmIdentifier getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public ASN1BitString getSubjectAltPublicKey()
+ {
+ return subjectAltPublicKey;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(algorithm);
+ v.add(subjectAltPublicKey);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
index d26ac7b..8d97bd2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
@@ -4,6 +4,7 @@
import java.io.IOException;
import java.util.Enumeration;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
@@ -24,7 +25,7 @@
extends ASN1Object
{
private AlgorithmIdentifier algId;
- private DERBitString keyData;
+ private ASN1BitString keyData;
public static SubjectPublicKeyInfo getInstance(
ASN1TaggedObject obj,
@@ -50,6 +51,14 @@
public SubjectPublicKeyInfo(
AlgorithmIdentifier algId,
+ ASN1BitString publicKey)
+ {
+ this.keyData = publicKey;
+ this.algId = algId;
+ }
+
+ public SubjectPublicKeyInfo(
+ AlgorithmIdentifier algId,
ASN1Encodable publicKey)
throws IOException
{
@@ -77,10 +86,10 @@
+ seq.size());
}
- Enumeration e = seq.getObjects();
+ Enumeration e = seq.getObjects();
this.algId = AlgorithmIdentifier.getInstance(e.nextElement());
- this.keyData = DERBitString.getInstance(e.nextElement());
+ this.keyData = ASN1BitString.getInstance(e.nextElement());
}
public AlgorithmIdentifier getAlgorithm()
@@ -131,7 +140,7 @@
*
* @return the public key as the raw bit string...
*/
- public DERBitString getPublicKeyData()
+ public ASN1BitString getPublicKeyData()
{
return keyData;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java
index 49e763f..bb95f43 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java
@@ -107,7 +107,7 @@
}
}
- private class RevokedCertificatesEnumeration
+ private static class RevokedCertificatesEnumeration
implements Enumeration
{
private final Enumeration en;
@@ -128,7 +128,7 @@
}
}
- private class EmptyEnumeration
+ private static class EmptyEnumeration
implements Enumeration
{
public boolean hasMoreElements()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java
index 74e2827..0c19019 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java
@@ -1,19 +1,16 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x509;
-import java.math.BigInteger;
-
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
-import com.android.internal.org.bouncycastle.util.BigIntegers;
import com.android.internal.org.bouncycastle.util.Properties;
/**
@@ -49,8 +46,8 @@
Time startDate, endDate;
X500Name subject;
SubjectPublicKeyInfo subjectPublicKeyInfo;
- DERBitString issuerUniqueId;
- DERBitString subjectUniqueId;
+ ASN1BitString issuerUniqueId;
+ ASN1BitString subjectUniqueId;
Extensions extensions;
public static TBSCertificate getInstance(
@@ -98,15 +95,15 @@
boolean isV1 = false;
boolean isV2 = false;
- if (version.hasValue(BigInteger.valueOf(0)))
+ if (version.hasValue(0))
{
isV1 = true;
}
- else if (version.hasValue(BigInteger.valueOf(1)))
+ else if (version.hasValue(1))
{
isV2 = true;
}
- else if (!version.hasValue(BigInteger.valueOf(2)))
+ else if (!version.hasValue(2))
{
throw new IllegalArgumentException("version number not recognised");
}
@@ -144,10 +141,10 @@
switch (extra.getTagNo())
{
case 1:
- issuerUniqueId = DERBitString.getInstance(extra, false);
+ issuerUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 2:
- subjectUniqueId = DERBitString.getInstance(extra, false);
+ subjectUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 3:
if (isV2)
@@ -208,12 +205,12 @@
return subjectPublicKeyInfo;
}
- public DERBitString getIssuerUniqueId()
+ public ASN1BitString getIssuerUniqueId()
{
return issuerUniqueId;
}
- public DERBitString getSubjectUniqueId()
+ public ASN1BitString getSubjectUniqueId()
{
return subjectUniqueId;
}
@@ -240,7 +237,7 @@
ASN1EncodableVector v = new ASN1EncodableVector();
// DEFAULT Zero
- if (!version.hasValue(BigIntegers.ZERO))
+ if (!version.hasValue(0))
{
v.add(new DERTaggedObject(true, 0, version));
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificateStructure.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
index 5ae69df..c010192 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
@@ -1,12 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x509;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
@@ -45,8 +45,8 @@
Time startDate, endDate;
X500Name subject;
SubjectPublicKeyInfo subjectPublicKeyInfo;
- DERBitString issuerUniqueId;
- DERBitString subjectUniqueId;
+ ASN1BitString issuerUniqueId;
+ ASN1BitString subjectUniqueId;
X509Extensions extensions;
public static TBSCertificateStructure getInstance(
@@ -118,10 +118,10 @@
switch (extra.getTagNo())
{
case 1:
- issuerUniqueId = DERBitString.getInstance(extra, false);
+ issuerUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 2:
- subjectUniqueId = DERBitString.getInstance(extra, false);
+ subjectUniqueId = ASN1BitString.getInstance(extra, false);
break;
case 3:
extensions = X509Extensions.getInstance(extra);
@@ -174,12 +174,12 @@
return subjectPublicKeyInfo;
}
- public DERBitString getIssuerUniqueId()
+ public ASN1BitString getIssuerUniqueId()
{
return issuerUniqueId;
}
- public DERBitString getSubjectUniqueId()
+ public ASN1BitString getSubjectUniqueId()
{
return subjectUniqueId;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Time.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Time.java
index eb98713..35d5c44 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Time.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Time.java
@@ -17,6 +17,7 @@
import com.android.internal.org.bouncycastle.asn1.ASN1UTCTime;
import com.android.internal.org.bouncycastle.asn1.DERGeneralizedTime;
import com.android.internal.org.bouncycastle.asn1.DERUTCTime;
+import com.android.internal.org.bouncycastle.asn1.LocaleUtil;
/**
* @hide This class is not part of the Android public SDK API
@@ -31,7 +32,12 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
+ return getInstance(obj.getExplicitBaseObject());
}
public Time(
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java
index 110b930..8d7d81f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java
@@ -71,10 +71,7 @@
this.objectDigestInfo = objectDigestInfo;
}
- /**
- * @deprecated use getInstance().
- */
- public V2Form(
+ private V2Form(
ASN1Sequence seq)
{
if (seq.size() > 3)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
index 2123bdc..ef6f55b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
@@ -3,6 +3,8 @@
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1UTCTime;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
@@ -157,20 +159,34 @@
}
}
- public TBSCertificate generateTBSCertificate()
+ public ASN1Sequence generatePreTBSCertificate()
{
- if ((serialNumber == null) || (signature == null)
+ if (signature != null)
+ {
+ throw new IllegalStateException("signature field should not be set in PreTBSCertificate");
+ }
+ if ((serialNumber == null)
|| (issuer == null) || (startDate == null) || (endDate == null)
|| (subject == null && !altNamePresentAndCritical) || (subjectPublicKeyInfo == null))
{
throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator");
}
+ return generateTBSStructure();
+ }
+
+ private ASN1Sequence generateTBSStructure()
+ {
ASN1EncodableVector v = new ASN1EncodableVector(10);
v.add(version);
v.add(serialNumber);
- v.add(signature);
+
+ if (signature != null)
+ {
+ v.add(signature);
+ }
+
v.add(issuer);
//
@@ -210,6 +226,18 @@
v.add(new DERTaggedObject(true, 3, extensions));
}
- return TBSCertificate.getInstance(new DERSequence(v));
+ return new DERSequence(v);
+ }
+
+ public TBSCertificate generateTBSCertificate()
+ {
+ if ((serialNumber == null) || (signature == null)
+ || (issuer == null) || (startDate == null) || (endDate == null)
+ || (subject == null && !altNamePresentAndCritical) || (subjectPublicKeyInfo == null))
+ {
+ throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator");
+ }
+
+ return TBSCertificate.getInstance(generateTBSStructure());
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509CertificateStructure.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509CertificateStructure.java
index 34afe36..cffec83 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509CertificateStructure.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509CertificateStructure.java
@@ -1,12 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x509;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
@@ -29,7 +29,7 @@
ASN1Sequence seq;
TBSCertificateStructure tbsCert;
AlgorithmIdentifier sigAlgId;
- DERBitString sig;
+ ASN1BitString sig;
public static X509CertificateStructure getInstance(
ASN1TaggedObject obj,
@@ -66,7 +66,7 @@
tbsCert = TBSCertificateStructure.getInstance(seq.getObjectAt(0));
sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
- sig = DERBitString.getInstance(seq.getObjectAt(2));
+ sig = ASN1BitString.getInstance(seq.getObjectAt(2));
}
else
{
@@ -119,7 +119,7 @@
return sigAlgId;
}
- public DERBitString getSignature()
+ public ASN1BitString getSignature()
{
return sig;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
index 582ebdd..e949d3e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
@@ -9,6 +9,7 @@
import com.android.internal.org.bouncycastle.asn1.DERIA5String;
import com.android.internal.org.bouncycastle.asn1.DERPrintableString;
import com.android.internal.org.bouncycastle.asn1.DERUTF8String;
+import com.android.internal.org.bouncycastle.asn1.x500.style.BCStyle;
/**
* The default converter for X509 DN entries when going from their
@@ -47,16 +48,16 @@
{
value = value.substring(1);
}
- if (oid.equals(X509Name.EmailAddress) || oid.equals(X509Name.DC))
+ if (oid.equals(BCStyle.EmailAddress) || oid.equals(BCStyle.DC))
{
return new DERIA5String(value);
}
- else if (oid.equals(X509Name.DATE_OF_BIRTH)) // accept time string as well as # (for compatibility)
+ else if (oid.equals(BCStyle.DATE_OF_BIRTH)) // accept time string as well as # (for compatibility)
{
return new DERGeneralizedTime(value);
}
- else if (oid.equals(X509Name.C) || oid.equals(X509Name.SN) || oid.equals(X509Name.DN_QUALIFIER)
- || oid.equals(X509Name.TELEPHONE_NUMBER))
+ else if (oid.equals(BCStyle.C) || oid.equals(BCStyle.SERIALNUMBER) || oid.equals(BCStyle.DN_QUALIFIER)
+ || oid.equals(BCStyle.TELEPHONE_NUMBER))
{
return new DERPrintableString(value);
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java
index 2f3fbef..90adcc4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java
@@ -13,10 +13,11 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.BERTags;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
/**
- * @deprecated use {@link Extensions}
+ * @deprecated use {@link Extension} and {@link Extensions}
* @hide This class is not part of the Android public SDK API
*/
public class X509Extensions
@@ -238,7 +239,9 @@
if (obj instanceof ASN1TaggedObject)
{
- return getInstance(((ASN1TaggedObject)obj).getObject());
+ ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC);
+
+ return getInstance(taggedObject.getBaseObject().toASN1Primitive());
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java
index 9065239..270577e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java
@@ -16,9 +16,9 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Set;
import com.android.internal.org.bouncycastle.asn1.ASN1String;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.ASN1UniversalString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.org.bouncycastle.asn1.DERSet;
-import com.android.internal.org.bouncycastle.asn1.DERUniversalString;
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
import com.android.internal.org.bouncycastle.util.Strings;
@@ -427,7 +427,7 @@
ordering.addElement(ASN1ObjectIdentifier.getInstance(s.getObjectAt(0)));
ASN1Encodable value = s.getObjectAt(1);
- if (value instanceof ASN1String && !(value instanceof DERUniversalString))
+ if (value instanceof ASN1String && !(value instanceof ASN1UniversalString))
{
String v = ((ASN1String)value).getString();
if (v.length() > 0 && v.charAt(0) == '#')
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
index 9329e67..80b071b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
@@ -5,7 +5,7 @@
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.internal.org.bouncycastle.asn1.DERPrintableString;
+import com.android.internal.org.bouncycastle.asn1.ASN1PrintableString;
import com.android.internal.org.bouncycastle.util.encoders.Hex;
/**
@@ -73,7 +73,7 @@
protected boolean canBePrintable(
String str)
{
- return DERPrintableString.isPrintableString(str);
+ return ASN1PrintableString.isPrintableString(str);
}
/**
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
index 89e8a56..80c6b6d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
@@ -111,4 +111,11 @@
static final ASN1ObjectIdentifier ocspAccessMethod = id_ad_ocsp;
/** OID for crl uri in AuthorityInformationAccess extension */
static final ASN1ObjectIdentifier crlAccessMethod = id_ad_caIssuers;
+
+
+ /**
+ * id-PasswordBasedMac OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) nt(113533) nsn(7) algorithms(66) 13 }
+ */
+ static final ASN1ObjectIdentifier id_PasswordBasedMac = new ASN1ObjectIdentifier("1.2.840.113533.7.66.13");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java
index a2d4c8a..5ca0dd6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java
@@ -1,13 +1,13 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x9;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
/**
@@ -16,7 +16,7 @@
*/
public class DHValidationParms extends ASN1Object
{
- private DERBitString seed;
+ private ASN1BitString seed;
private ASN1Integer pgenCounter;
public static DHValidationParms getInstance(ASN1TaggedObject obj, boolean explicit)
@@ -38,7 +38,7 @@
return null;
}
- public DHValidationParms(DERBitString seed, ASN1Integer pgenCounter)
+ public DHValidationParms(ASN1BitString seed, ASN1Integer pgenCounter)
{
if (seed == null)
{
@@ -60,11 +60,11 @@
throw new IllegalArgumentException("Bad sequence size: " + seq.size());
}
- this.seed = DERBitString.getInstance(seq.getObjectAt(0));
+ this.seed = ASN1BitString.getInstance(seq.getObjectAt(0));
this.pgenCounter = ASN1Integer.getInstance(seq.getObjectAt(1));
}
- public DERBitString getSeed()
+ public ASN1BitString getSeed()
{
return this.seed;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
index 08ada94..848834c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
@@ -71,6 +71,47 @@
return ecP;
}
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ X9ECParametersHolder holder = X962NamedCurves.getByNameLazy(name);
+
+ if (null == holder)
+ {
+ holder = SECNamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = NISTNamedCurves.getByNameLazy(name);
+ }
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ if (null == holder)
+ {
+ holder = TeleTrusTNamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = ANSSINamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = ECGOST3410NamedCurves.getByNameLazy(name);
+ }
+
+ if (null == holder)
+ {
+ holder = GMNamedCurves.getByNameLazy(name);
+ }
+ */
+ // END Android-removed: Unsupported curves
+
+ return holder;
+ }
+
/**
* return the object identifier signified by the passed in name. Null
* if there is no object identifier associated with name.
@@ -224,6 +265,44 @@
return ecP;
}
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ X9ECParametersHolder holder = X962NamedCurves.getByOIDLazy(oid);
+
+ if (null == holder)
+ {
+ holder = SECNamedCurves.getByOIDLazy(oid);
+ }
+
+ // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ if (null == holder)
+ {
+ holder = TeleTrusTNamedCurves.getByOIDLazy(oid);
+ }
+
+ if (null == holder)
+ {
+ holder = ANSSINamedCurves.getByOIDLazy(oid);
+ }
+
+ if (null == holder)
+ {
+ holder = ECGOST3410NamedCurves.getByOIDLazy(oid);
+ }
+
+ if (null == holder)
+ {
+ holder = GMNamedCurves.getByOIDLazy(oid);
+ }
+ */
+ // END Android-removed: Unsupported curves
+
+ return holder;
+ }
+
/**
* return an enumeration of the names of the available curves.
*
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java
index 0e2329c..29505b2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java
@@ -3,6 +3,7 @@
import java.math.BigInteger;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
@@ -25,7 +26,7 @@
public class ValidationParams
extends ASN1Object
{
- private DERBitString seed;
+ private ASN1BitString seed;
private ASN1Integer pgenCounter;
public static ValidationParams getInstance(ASN1TaggedObject obj, boolean explicit)
@@ -80,7 +81,7 @@
throw new IllegalArgumentException("Bad sequence size: " + seq.size());
}
- this.seed = DERBitString.getInstance(seq.getObjectAt(0));
+ this.seed = ASN1BitString.getInstance(seq.getObjectAt(0));
this.pgenCounter = ASN1Integer.getInstance(seq.getObjectAt(1));
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java
index 7b82cc0..b6046ea 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java
@@ -37,141 +37,183 @@
static X9ECParametersHolder prime192v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("ffffffffffffffffffffffff99def836146bc9b1b4d22831");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
fromHex("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("3045AE6FC8422f64ED579528D38120EAE12196D5");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("3045AE6FC8422f64ED579528D38120EAE12196D5"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime192v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
fromHex("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("31a92ee2029fd10d901b113e990710f0d21ac6b6");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("31a92ee2029fd10d901b113e990710f0d21ac6b6"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime192v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("ffffffffffffffffffffffff7a62d031c83f4294f640ec13");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
fromHex("22123dc2395a05caa7423daeccc94760a7d462256bd56916"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("c469684435deb378c4b65ca9591e2a5763059a2e");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"027d29778100c65a1da1783716588dce2b8b4aee8e228f1896");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c469684435deb378c4b65ca9591e2a5763059a2e"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime239v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
fromHex("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("e43bb460f0b80cc0c0b075798e948060f8321b7d");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e43bb460f0b80cc0c0b075798e948060f8321b7d"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime239v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
fromHex("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("e8b4011604095303ca3b8099982be09fcb9ae616");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e8b4011604095303ca3b8099982be09fcb9ae616"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime239v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
fromHex("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("7d7374168ffe3471b60a857686a19475d3bfa2ff");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("7d7374168ffe3471b60a857686a19475d3bfa2ff"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder prime256v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve curve = configureCurve(new ECCurve.Fp(
+ return configureCurve(new ECCurve.Fp(
new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"),
fromHex("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc"),
fromHex("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b"),
- n, h));
+ n, h, true));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("c49d360886e704936a6678e1139d26b7819f7e90");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c49d360886e704936a6678e1139d26b7819f7e90"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -180,337 +222,433 @@
*/
static X9ECParametersHolder c2pnb163v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0400000000000000000001E60FC8821CC74DAEAFC1");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
fromHex("072546B5435234A422E0789675F432C89435DE5242"),
fromHex("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("D2C0FB15760860DEF1EEF4D696E6768756151754");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0307AF69989546103D79329FCC3D74880F33BBE803CB");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("D2C0FB15760860DEF1EEF4D696E6768756151754"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb163v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
fromHex("0108B39E77C4B108BED981ED0E890E117C511CF072"),
fromHex("0667ACEB38AF4E488C407433FFAE4F1C811638DF20"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"030024266E4EB5106D0A964D92C4860E2671DB9B6CC5");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb163v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
fromHex("07A526C63D3E25A256A007699F5447E32AE456B50E"),
fromHex("03F7061798EB99E238FD6F1BF95B48FEEB4854252B"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb176w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("010092537397ECA4F6145799D62B0A19CE06FE26AD");
BigInteger h = BigInteger.valueOf(0xFF6E);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
176,
1, 2, 43,
fromHex("E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B"),
fromHex("5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"038D16C2866798B600F9F08BB4A8E860F3298CE04A5798");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb191v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("40000000000000000000000004A20E90C39067C893BBB9A5");
BigInteger h = BigInteger.valueOf(2);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
191,
9,
fromHex("2866537B676752636A68F56554E12640276B649EF7526267"),
fromHex("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("4E13CA542744D696E67687561517552F279A8C84");
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D");
- return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("4E13CA542744D696E67687561517552F279A8C84"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb191v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("20000000000000000000000050508CB89F652824E06B8173");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
191,
9,
fromHex("401028774D7777C7B7666D1366EA432071274F89FF01E718"),
fromHex("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb191v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("155555555555555555555555610C0B196812BFB6288A3EA3");
BigInteger h = BigInteger.valueOf(6);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
191,
9,
fromHex("6C01074756099122221056911C77D77E77A777E7E7E77FCB"),
fromHex("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"03375D4CE24FDE434489DE8746E71786015009E66E38A926DD");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb208w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D");
BigInteger h = BigInteger.valueOf(0xFE48);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
208,
1, 2, 83,
BigInteger.valueOf(0),
fromHex("C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb239v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447");
BigInteger h = BigInteger.valueOf(4);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
239,
36,
fromHex("32010857077C5431123A46B808906756F543423E8D27877578125778AC76"),
fromHex("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb239v2 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D");
BigInteger h = BigInteger.valueOf(6);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
239,
36,
fromHex("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F"),
fromHex("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb239v3 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF");
BigInteger h = BigInteger.valueOf(10);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
239,
36,
fromHex("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F"),
fromHex("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb272w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521");
BigInteger h = BigInteger.valueOf(0xFF06);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
272,
1, 3, 56,
fromHex("91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20"),
fromHex("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb304w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D");
BigInteger h = BigInteger.valueOf(0xFE2E);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
304,
1, 2, 11,
fromHex("FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681"),
fromHex("BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb359v1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B");
BigInteger h = BigInteger.valueOf(0x4C);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
359,
68,
fromHex("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557"),
fromHex("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2pnb368w1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967");
BigInteger h = BigInteger.valueOf(0xFF70);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
368,
1, 2, 85,
fromHex("E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D"),
fromHex("FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
static X9ECParametersHolder c2tnb431r1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
BigInteger n = fromHex("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91");
BigInteger h = BigInteger.valueOf(0x2760);
- ECCurve curve = configureCurve(new ECCurve.F2m(
+ return configureCurve(new ECCurve.F2m(
431,
120,
fromHex("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F"),
fromHex("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618"),
n, h));
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7");
- return new X9ECParameters(curve, G, n, h);
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -553,17 +691,16 @@
defineCurve("c2tnb431r1", X9ObjectIdentifiers.c2tnb431r1, c2tnb431r1);
}
- public static X9ECParameters getByName(
- String name)
+ public static X9ECParameters getByName(String name)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name));
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOID(oid);
+ }
- if (oid != null)
- {
- return getByOID(oid);
- }
-
- return null;
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOIDLazy(oid);
}
/**
@@ -572,17 +709,15 @@
*
* @param oid an object identifier representing a named curve, if present.
*/
- public static X9ECParameters getByOID(
- ASN1ObjectIdentifier oid)
+ public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid);
+ X9ECParametersHolder holder = getByOIDLazy(oid);
+ return holder == null ? null : holder.getParameters();
+ }
- if (holder != null)
- {
- return holder.getParameters();
- }
-
- return null;
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return (X9ECParametersHolder)curves.get(oid);
}
/**
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java
index 0780832..d8eac08 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java
@@ -50,7 +50,12 @@
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(obj.getObject()); // must be explicitly tagged
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
+ return getInstance(obj.getExplicitBaseObject());
}
public X962Parameters(
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java
index 58ca88b..edbefdb 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java
@@ -38,7 +38,7 @@
ASN1Sequence seq)
{
if (!(seq.getObjectAt(0) instanceof ASN1Integer)
- || !((ASN1Integer)seq.getObjectAt(0)).hasValue(ONE))
+ || !((ASN1Integer)seq.getObjectAt(0)).hasValue(1))
{
throw new IllegalArgumentException("bad version in X9ECParameters");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParametersHolder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
index 4db5dd1..b53213c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
@@ -1,14 +1,27 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x9;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+
/**
* A holding class that allows for X9ECParameters to be lazily constructed.
* @hide This class is not part of the Android public SDK API
*/
public abstract class X9ECParametersHolder
{
+ private ECCurve curve;
private X9ECParameters params;
+ public synchronized ECCurve getCurve()
+ {
+ if (curve == null)
+ {
+ curve = createCurve();
+ }
+
+ return curve;
+ }
+
public synchronized X9ECParameters getParameters()
{
if (params == null)
@@ -19,5 +32,10 @@
return params;
}
+ protected ECCurve createCurve()
+ {
+ return createParameters().getCurve();
+ }
+
protected abstract X9ECParameters createParameters();
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldElement.java
index e9124a2..a22b40b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldElement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldElement.java
@@ -1,10 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x9;
-import java.math.BigInteger;
-
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
-import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
@@ -25,22 +22,6 @@
this.f = f;
}
- /**
- * @deprecated Will be removed
- */
- public X9FieldElement(BigInteger p, ASN1OctetString s)
- {
- this(new ECFieldElement.Fp(p, new BigInteger(1, s.getOctets())));
- }
-
- /**
- * @deprecated Will be removed
- */
- public X9FieldElement(int m, int k1, int k2, int k3, ASN1OctetString s)
- {
- this(new ECFieldElement.F2m(m, k1, k2, k3, new BigInteger(1, s.getOctets())));
- }
-
public ECFieldElement getValue()
{
return f;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AlphabetMapper.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AlphabetMapper.java
new file mode 100644
index 0000000..53e0341
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AlphabetMapper.java
@@ -0,0 +1,34 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * Base interface for mapping from an alphabet to a set of indexes
+ * suitable for use with FPE.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface AlphabetMapper
+{
+ /**
+ * Return the number of characters in the alphabet.
+ *
+ * @return the radix for the alphabet.
+ */
+ int getRadix();
+
+ /**
+ * Return the passed in char[] as a byte array of indexes (indexes
+ * can be more than 1 byte)
+ *
+ * @param input characters to be mapped.
+ * @return an index array.
+ */
+ byte[] convertToIndexes(char[] input);
+
+ /**
+ * Return a char[] for this alphabet based on the indexes passed.
+ *
+ * @param input input array of indexes.
+ * @return an array of char corresponding to the index values.
+ */
+ char[] convertToChars(byte[] input);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BlockCipher.java
index 9fbfe10..3c8e44e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BlockCipher.java
@@ -38,16 +38,16 @@
* Process one block of input from the array in and write it to
* the out array.
*
- * @param in the array containing the input data.
+ * @param input the array containing the input data.
* @param inOff offset into the in array the data starts at.
- * @param out the array the output data will be copied into.
+ * @param output the array the output data will be copied into.
* @param outOff the offset into the out array the output will start at.
- * @exception DataLengthException if there isn't enough data in in, or
+ * @exception DataLengthException if there isn't enough data in input , or
* space in out.
* @exception IllegalStateException if the cipher isn't initialised.
* @return the number of bytes processed and produced.
*/
- public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
+ public int processBlock(byte[] input, int inOff, byte[] output, int outOff)
throws DataLengthException, IllegalStateException;
/**
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BufferedBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BufferedBlockCipher.java
index f9e8c6c..d0e6ad2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BufferedBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BufferedBlockCipher.java
@@ -16,8 +16,9 @@
protected byte[] buf;
protected int bufOff;
- protected boolean forEncryption;
- protected BlockCipher cipher;
+ protected boolean forEncryption;
+ protected BlockCipher cipher;
+ protected MultiBlockCipher mbCipher;
protected boolean partialBlockOkay;
protected boolean pgpCFB;
@@ -25,7 +26,7 @@
/**
* constructor for subclasses
*/
- protected BufferedBlockCipher()
+ BufferedBlockCipher()
{
}
@@ -33,13 +34,24 @@
* Create a buffered block cipher without padding.
*
* @param cipher the underlying block cipher this buffering object wraps.
+ * @deprecated use the constructor on DefaultBufferedBlockCipher.
*/
public BufferedBlockCipher(
BlockCipher cipher)
{
this.cipher = cipher;
- buf = new byte[cipher.getBlockSize()];
+ if (cipher instanceof MultiBlockCipher)
+ {
+ this.mbCipher = (MultiBlockCipher)cipher;
+ buf = new byte[mbCipher.getMultiBlockSize()];
+ }
+ else
+ {
+ this.mbCipher = null;
+ buf = new byte[cipher.getBlockSize()];
+ }
+
bufOff = 0;
//
@@ -145,6 +157,11 @@
public int getOutputSize(
int length)
{
+ if (pgpCFB && forEncryption)
+ {
+ return length + bufOff + (cipher.getBlockSize() + 2);
+ }
+
// Note: Can assume partialBlockOkay is true for purposes of this calculation
return length + bufOff;
}
@@ -227,12 +244,29 @@
len -= gapLen;
inOff += gapLen;
- while (len > buf.length)
+ if (mbCipher != null)
{
- resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen);
+ int blockCount = len / mbCipher.getMultiBlockSize();
- len -= blockSize;
- inOff += blockSize;
+ if (blockCount > 0)
+ {
+ resultLen += mbCipher.processBlocks(in, inOff, blockCount, out, outOff + resultLen);
+
+ int processed = blockCount * mbCipher.getMultiBlockSize();
+
+ len -= processed;
+ inOff += processed;
+ }
+ }
+ else
+ {
+ while (len > buf.length)
+ {
+ resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen);
+
+ len -= blockSize;
+ inOff += blockSize;
+ }
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherKeyGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherKeyGenerator.java
index 2b26db6..d5fca73 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherKeyGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherKeyGenerator.java
@@ -3,6 +3,8 @@
import java.security.SecureRandom;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+
/**
* The base class for symmetric, or secret, cipher key generators.
* @hide This class is not part of the Android public SDK API
@@ -22,6 +24,8 @@
{
this.random = param.getRandom();
this.strength = (param.getStrength() + 7) / 8;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("SymKeyGen", param.getStrength()));
}
/**
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServiceConstraintsException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServiceConstraintsException.java
new file mode 100644
index 0000000..9550f05
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServiceConstraintsException.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CryptoServiceConstraintsException
+ extends RuntimeException
+{
+ public CryptoServiceConstraintsException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServiceProperties.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServiceProperties.java
new file mode 100644
index 0000000..2e52488
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServiceProperties.java
@@ -0,0 +1,16 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CryptoServiceProperties
+{
+ int bitsOfSecurity();
+
+ String getServiceName();
+
+ CryptoServicePurpose getPurpose();
+
+ Object getParams();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicePurpose.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicePurpose.java
new file mode 100644
index 0000000..80dd1c2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicePurpose.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public enum CryptoServicePurpose
+{
+ AGREEMENT,
+ ENCRYPTION,
+ DECRYPTION,
+ KEYGEN,
+ SIGNING, // for signatures (and digests)
+ VERIFYING,
+ AUTHENTICATION, // for MACs (and digests)
+ VERIFICATION,
+ PRF,
+ ANY
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesConstraints.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesConstraints.java
new file mode 100644
index 0000000..da7f1ec
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesConstraints.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CryptoServicesConstraints
+{
+ void check(CryptoServiceProperties service);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesPermission.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesPermission.java
index 6c1f44a..c82d785 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesPermission.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesPermission.java
@@ -27,6 +27,11 @@
*/
public static final String DEFAULT_RANDOM = "defaultRandomConfig";
+ /**
+ * Enable the setting of the constraints.
+ */
+ public static final String CONSTRAINTS = "constraints";
+
private final Set<String> actions = new HashSet<String>();
public CryptoServicesPermission(String name)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java
index 7a337ce..daa59ef 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java
@@ -9,12 +9,16 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Logger;
import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
import com.android.internal.org.bouncycastle.crypto.params.DHValidationParameters;
import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
import com.android.internal.org.bouncycastle.crypto.params.DSAValidationParameters;
+import com.android.internal.org.bouncycastle.util.Properties;
+import com.android.internal.org.bouncycastle.util.Strings;
import com.android.internal.org.bouncycastle.util.encoders.Hex;
/**
@@ -23,15 +27,28 @@
*/
public final class CryptoServicesRegistrar
{
+ private static final Logger LOG = Logger.getLogger(CryptoServicesRegistrar.class.getName());
+
private static final Permission CanSetDefaultProperty = new CryptoServicesPermission(CryptoServicesPermission.GLOBAL_CONFIG);
private static final Permission CanSetThreadProperty = new CryptoServicesPermission(CryptoServicesPermission.THREAD_LOCAL_CONFIG);
private static final Permission CanSetDefaultRandom = new CryptoServicesPermission(CryptoServicesPermission.DEFAULT_RANDOM);
+ private static final Permission CanSetConstraints = new CryptoServicesPermission(CryptoServicesPermission.CONSTRAINTS);
private static final ThreadLocal<Map<String, Object[]>> threadProperties = new ThreadLocal<Map<String, Object[]>>();
private static final Map<String, Object[]> globalProperties = Collections.synchronizedMap(new HashMap<String, Object[]>());
+ private static final SecureRandomProvider defaultRandomProviderImpl = new ThreadLocalSecureRandomProvider();
- private static final Object cacheLock = new Object();
- private static SecureRandom defaultSecureRandom;
+ private static final CryptoServicesConstraints noConstraintsImpl = new CryptoServicesConstraints()
+ {
+ public void check(CryptoServiceProperties service)
+ {
+ // anything goes.
+ }
+ };
+
+ private static final AtomicReference<SecureRandomProvider> defaultSecureRandomProvider = new AtomicReference<SecureRandomProvider>();
+ private static final boolean preconfiguredConstraints;
+ private static final AtomicReference<CryptoServicesConstraints> servicesConstraints = new AtomicReference<CryptoServicesConstraints>();
static
{
@@ -45,56 +62,59 @@
DSAParameters def768Params = new DSAParameters(
new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5" +
- "d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a" +
- "22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45" +
- "ee3688c11a8c56ab127a3daf", 16),
+ "d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a" +
+ "22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45" +
+ "ee3688c11a8c56ab127a3daf", 16),
new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16),
new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7" +
- "a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d366844577" +
- "1f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a" +
- "7064f316933a346d3f529252", 16),
+ "a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d366844577" +
+ "1f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a" +
+ "7064f316933a346d3f529252", 16),
new DSAValidationParameters(Hex.decodeStrict("77d0f8c4dad15eb8c4f2f8d6726cefd96d5bb399"), 263));
DSAParameters def1024Params = new DSAParameters(
new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80" +
- "b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b" +
- "801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c6" +
- "1bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675" +
- "f3ae2b61d72aeff22203199dd14801c7", 16),
+ "b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b" +
+ "801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c6" +
+ "1bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675" +
+ "f3ae2b61d72aeff22203199dd14801c7", 16),
new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16),
new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b" +
- "3d0782675159578ebad4594fe67107108180b449167123e84c281613" +
- "b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f" +
- "0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06" +
- "928b665e807b552564014c3bfecf492a", 16),
+ "3d0782675159578ebad4594fe67107108180b449167123e84c281613" +
+ "b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f" +
+ "0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06" +
+ "928b665e807b552564014c3bfecf492a", 16),
new DSAValidationParameters(Hex.decodeStrict("8d5155894229d5e689ee01e6018a237e2cae64cd"), 92));
DSAParameters def2048Params = new DSAParameters(
new BigInteger("95475cf5d93e596c3fcd1d902add02f427f5f3c7210313bb45fb4d5b" +
- "b2e5fe1cbd678cd4bbdd84c9836be1f31c0777725aeb6c2fc38b85f4" +
- "8076fa76bcd8146cc89a6fb2f706dd719898c2083dc8d896f84062e2" +
- "c9c94d137b054a8d8096adb8d51952398eeca852a0af12df83e475aa" +
- "65d4ec0c38a9560d5661186ff98b9fc9eb60eee8b030376b236bc73b" +
- "e3acdbd74fd61c1d2475fa3077b8f080467881ff7e1ca56fee066d79" +
- "506ade51edbb5443a563927dbc4ba520086746175c8885925ebc64c6" +
- "147906773496990cb714ec667304e261faee33b3cbdf008e0c3fa906" +
- "50d97d3909c9275bf4ac86ffcb3d03e6dfc8ada5934242dd6d3bcca2" +
- "a406cb0b", 16),
+ "b2e5fe1cbd678cd4bbdd84c9836be1f31c0777725aeb6c2fc38b85f4" +
+ "8076fa76bcd8146cc89a6fb2f706dd719898c2083dc8d896f84062e2" +
+ "c9c94d137b054a8d8096adb8d51952398eeca852a0af12df83e475aa" +
+ "65d4ec0c38a9560d5661186ff98b9fc9eb60eee8b030376b236bc73b" +
+ "e3acdbd74fd61c1d2475fa3077b8f080467881ff7e1ca56fee066d79" +
+ "506ade51edbb5443a563927dbc4ba520086746175c8885925ebc64c6" +
+ "147906773496990cb714ec667304e261faee33b3cbdf008e0c3fa906" +
+ "50d97d3909c9275bf4ac86ffcb3d03e6dfc8ada5934242dd6d3bcca2" +
+ "a406cb0b", 16),
new BigInteger("f8183668ba5fc5bb06b5981e6d8b795d30b8978d43ca0ec572e37e09939a9773", 16),
new BigInteger("42debb9da5b3d88cc956e08787ec3f3a09bba5f48b889a74aaf53174" +
- "aa0fbe7e3c5b8fcd7a53bef563b0e98560328960a9517f4014d3325f" +
- "c7962bf1e049370d76d1314a76137e792f3f0db859d095e4a5b93202" +
- "4f079ecf2ef09c797452b0770e1350782ed57ddf794979dcef23cb96" +
- "f183061965c4ebc93c9c71c56b925955a75f94cccf1449ac43d586d0" +
- "beee43251b0b2287349d68de0d144403f13e802f4146d882e057af19" +
- "b6f6275c6676c8fa0e3ca2713a3257fd1b27d0639f695e347d8d1cf9" +
- "ac819a26ca9b04cb0eb9b7b035988d15bbac65212a55239cfc7e58fa" +
- "e38d7250ab9991ffbc97134025fe8ce04c4399ad96569be91a546f49" +
- "78693c7a", 16),
+ "aa0fbe7e3c5b8fcd7a53bef563b0e98560328960a9517f4014d3325f" +
+ "c7962bf1e049370d76d1314a76137e792f3f0db859d095e4a5b93202" +
+ "4f079ecf2ef09c797452b0770e1350782ed57ddf794979dcef23cb96" +
+ "f183061965c4ebc93c9c71c56b925955a75f94cccf1449ac43d586d0" +
+ "beee43251b0b2287349d68de0d144403f13e802f4146d882e057af19" +
+ "b6f6275c6676c8fa0e3ca2713a3257fd1b27d0639f695e347d8d1cf9" +
+ "ac819a26ca9b04cb0eb9b7b035988d15bbac65212a55239cfc7e58fa" +
+ "e38d7250ab9991ffbc97134025fe8ce04c4399ad96569be91a546f49" +
+ "78693c7a", 16),
new DSAValidationParameters(Hex.decodeStrict("b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536"), 497));
localSetGlobalProperty(Property.DSA_DEFAULT_PARAMS, def512Params, def768Params, def1024Params, def2048Params);
localSetGlobalProperty(Property.DH_DEFAULT_PARAMS, toDH(def512Params), toDH(def768Params), toDH(def1024Params), toDH(def2048Params));
+
+ servicesConstraints.set(getDefaultConstraints());
+ preconfiguredConstraints = (servicesConstraints.get() != noConstraintsImpl);
}
private CryptoServicesRegistrar()
@@ -109,25 +129,9 @@
*/
public static SecureRandom getSecureRandom()
{
- synchronized (cacheLock)
- {
- if (null != defaultSecureRandom)
- {
- return defaultSecureRandom;
- }
- }
+ defaultSecureRandomProvider.compareAndSet(null, defaultRandomProviderImpl);
- SecureRandom tmp = new SecureRandom();
-
- synchronized (cacheLock)
- {
- if (null == defaultSecureRandom)
- {
- defaultSecureRandom = tmp;
- }
-
- return defaultSecureRandom;
- }
+ return defaultSecureRandomProvider.get().get();
}
/**
@@ -146,13 +150,83 @@
*
* @param secureRandom the SecureRandom to use as the default.
*/
- public static void setSecureRandom(SecureRandom secureRandom)
+ public static void setSecureRandom(final SecureRandom secureRandom)
{
checkPermission(CanSetDefaultRandom);
- synchronized (cacheLock)
+ if (secureRandom == null)
{
- defaultSecureRandom = secureRandom;
+ defaultSecureRandomProvider.set(defaultRandomProviderImpl);
+ }
+ else
+ {
+ defaultSecureRandomProvider.set(new SecureRandomProvider()
+ {
+ public SecureRandom get()
+ {
+ return secureRandom;
+ }
+ });
+ }
+ }
+
+ /**
+ * Set a default secure random provider to be used where none is otherwise provided.
+ *
+ * @param secureRandomProvider a provider SecureRandom to use when a default SecureRandom is requested.
+ */
+ public static void setSecureRandomProvider(SecureRandomProvider secureRandomProvider)
+ {
+ checkPermission(CanSetDefaultRandom);
+
+ defaultSecureRandomProvider.set(secureRandomProvider);
+ }
+
+ /**
+ * Return the current algorithm/services constraints.
+ *
+ * @return the algorithm/services constraints.
+ */
+ public static CryptoServicesConstraints getServicesConstraints()
+ {
+ return servicesConstraints.get();
+ }
+
+ /**
+ * Check a service to make sure it meets the current constraints.
+ *
+ * @param cryptoService the service to be checked.
+ * @throws CryptoServiceConstraintsException if the service violates the current constraints.
+ */
+ public static void checkConstraints(CryptoServiceProperties cryptoService)
+ {
+ servicesConstraints.get().check(cryptoService);
+ }
+
+ /**
+ * Set the current algorithm constraints.
+ */
+ public static void setServicesConstraints(CryptoServicesConstraints constraints)
+ {
+ checkPermission(CanSetConstraints);
+
+ CryptoServicesConstraints newConstraints = (constraints == null) ? noConstraintsImpl : constraints;
+
+ if (preconfiguredConstraints)
+ {
+ if (Properties.isOverrideSet("com.android.internal.org.bouncycastle.constraints.allow_override"))
+ {
+ servicesConstraints.set(newConstraints);
+ }
+ else
+ {
+ LOG.warning("attempt to override pre-configured constraints ignored");
+ }
+ }
+ else
+ {
+ // TODO: should this only be allowed once?
+ servicesConstraints.set(newConstraints);
}
}
@@ -161,7 +235,7 @@
* configuration first and then on the global configuration in no local configuration exists.
*
* @param property the property to look up.
- * @param <T> the type to be returned
+ * @param <T> the type to be returned
* @return null if the property is not set, the default value otherwise,
*/
public static <T> T getProperty(Property property)
@@ -197,7 +271,7 @@
* DSA_DEFAULT_PARAMS.
*
* @param property the name of the property to look up.
- * @param <T> the base type of the array to be returned.
+ * @param <T> the base type of the array to be returned.
* @return null if the property is not set, an array of the current values otherwise.
*/
public static <T> T[] getSizedProperty(Property property)
@@ -217,8 +291,8 @@
* DSA_DEFAULT_PARAMS.
*
* @param property the name of the property to look up.
- * @param size the size (in bits) of the defining value in the property type.
- * @param <T> the type of the value to be returned.
+ * @param size the size (in bits) of the defining value in the property type.
+ * @param <T> the type of the value to be returned.
* @return the current value for the size, null if there is no value set,
*/
public static <T> T getSizedProperty(Property property, int size)
@@ -263,9 +337,9 @@
* one value can be passed in for a sized property. If more than one value is provided the
* first value in the argument list becomes the default value.
*
- * @param property the name of the property to set.
+ * @param property the name of the property to set.
* @param propertyValue the values to assign to the property.
- * @param <T> the base type of the property value.
+ * @param <T> the base type of the property value.
*/
public static <T> void setThreadProperty(Property property, T... propertyValue)
{
@@ -284,9 +358,9 @@
* one value can be passed in for a sized property. If more than one value is provided the
* first value in the argument list becomes the default value.
*
- * @param property the name of the property to set.
+ * @param property the name of the property to set.
* @param propertyValue the values to assign to the property.
- * @param <T> the base type of the property value.
+ * @param <T> the base type of the property value.
*/
public static <T> void setGlobalProperty(Property property, T... propertyValue)
{
@@ -325,7 +399,7 @@
* Clear the global value for the passed in property.
*
* @param property the property to be cleared.
- * @param <T> the base type of the property value
+ * @param <T> the base type of the property value
* @return an array of T if a value was previously set, null otherwise.
*/
public static <T> T[] clearGlobalProperty(Property property)
@@ -342,7 +416,7 @@
* Clear the thread local value for the passed in property.
*
* @param property the property to be cleared.
- * @param <T> the base type of the property value
+ * @param <T> the base type of the property value
* @return an array of T if a value was previously set, null otherwise.
*/
public static <T> T[] clearThreadProperty(Property property)
@@ -417,6 +491,13 @@
return m;
}
+ private static CryptoServicesConstraints getDefaultConstraints()
+ {
+ // TODO: return one based on system/security properties if set.
+
+ return noConstraintsImpl;
+ }
+
/**
* Available properties that can be set.
* @hide This class is not part of the Android public SDK API
@@ -430,11 +511,11 @@
/**
* The default parameters for a particular size of Diffie-Hellman key.This is a sized property.
*/
- public static final Property DH_DEFAULT_PARAMS= new Property("dhDefaultParams", DHParameters.class);
+ public static final Property DH_DEFAULT_PARAMS = new Property("dhDefaultParams", DHParameters.class);
/**
* The default parameters for a particular size of DSA key. This is a sized property.
*/
- public static final Property DSA_DEFAULT_PARAMS= new Property("dsaDefaultParams", DSAParameters.class);
+ public static final Property DSA_DEFAULT_PARAMS = new Property("dsaDefaultParams", DSAParameters.class);
private final String name;
private final Class type;
@@ -444,4 +525,20 @@
this.type = type;
}
}
+
+ private static class ThreadLocalSecureRandomProvider
+ implements SecureRandomProvider
+ {
+ final ThreadLocal<SecureRandom> defaultRandoms = new ThreadLocal<SecureRandom>();
+
+ public SecureRandom get()
+ {
+ if (defaultRandoms.get() == null)
+ {
+ defaultRandoms.set(new SecureRandom());
+ }
+
+ return defaultRandoms.get();
+ }
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java
new file mode 100644
index 0000000..6ff4992
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java
@@ -0,0 +1,358 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+
+/**
+ * A wrapper class that allows block ciphers to be used to process data in
+ * a piecemeal fashion. The BufferedBlockCipher outputs a block only when the
+ * buffer is full and more data is being added, or on a doFinal.
+ * <p>
+ * Note: in the case where the underlying cipher is either a CFB cipher or an
+ * OFB one the last block may not be a multiple of the block size. Use this class
+ * for construction rather than BufferedBlockCipher as BufferedBlockCipher will eventually
+ * turn into an interface.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultBufferedBlockCipher
+ extends BufferedBlockCipher
+{
+ protected byte[] buf;
+ protected int bufOff;
+
+ protected boolean forEncryption;
+ protected BlockCipher cipher;
+ protected MultiBlockCipher mbCipher;
+
+ protected boolean partialBlockOkay;
+ protected boolean pgpCFB;
+
+ /**
+ * constructor for subclasses
+ */
+ protected DefaultBufferedBlockCipher()
+ {
+ }
+
+ /**
+ * Create a buffered block cipher without padding.
+ *
+ * @param cipher the underlying block cipher this buffering object wraps.
+ */
+ public DefaultBufferedBlockCipher(
+ BlockCipher cipher)
+ {
+ this.cipher = cipher;
+
+ if (cipher instanceof MultiBlockCipher)
+ {
+ this.mbCipher = (MultiBlockCipher)cipher;
+ buf = new byte[mbCipher.getMultiBlockSize()];
+ }
+ else
+ {
+ this.mbCipher = null;
+ buf = new byte[cipher.getBlockSize()];
+ }
+
+ bufOff = 0;
+
+ //
+ // check if we can handle partial blocks on doFinal.
+ //
+ String name = cipher.getAlgorithmName();
+ int idx = name.indexOf('/') + 1;
+
+ pgpCFB = (idx > 0 && name.startsWith("PGP", idx));
+
+ if (pgpCFB || cipher instanceof StreamCipher)
+ {
+ partialBlockOkay = true;
+ }
+ else
+ {
+ partialBlockOkay = (idx > 0 && (name.startsWith("OpenPGP", idx)));
+ }
+ }
+
+ /**
+ * return the cipher this object wraps.
+ *
+ * @return the cipher this object wraps.
+ */
+ public BlockCipher getUnderlyingCipher()
+ {
+ return cipher;
+ }
+
+ /**
+ * initialise the cipher.
+ *
+ * @param forEncryption if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param params the key and other data required by the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters params)
+ throws IllegalArgumentException
+ {
+ this.forEncryption = forEncryption;
+
+ reset();
+
+ cipher.init(forEncryption, params);
+ }
+
+ /**
+ * return the blocksize for the underlying cipher.
+ *
+ * @return the blocksize for the underlying cipher.
+ */
+ public int getBlockSize()
+ {
+ return cipher.getBlockSize();
+ }
+
+ /**
+ * return the size of the output buffer required for an update
+ * an input of len bytes.
+ *
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to update
+ * with len bytes of input.
+ */
+ public int getUpdateOutputSize(
+ int len)
+ {
+ int total = len + bufOff;
+ int leftOver;
+
+ if (pgpCFB)
+ {
+ if (forEncryption)
+ {
+ leftOver = total % buf.length - (cipher.getBlockSize() + 2);
+ }
+ else
+ {
+ leftOver = total % buf.length;
+ }
+ }
+ else
+ {
+ leftOver = total % buf.length;
+ }
+
+ return total - leftOver;
+ }
+
+ /**
+ * return the size of the output buffer required for an update plus a
+ * doFinal with an input of 'length' bytes.
+ *
+ * @param length the length of the input.
+ * @return the space required to accommodate a call to update and doFinal
+ * with 'length' bytes of input.
+ */
+ public int getOutputSize(
+ int length)
+ {
+ if (pgpCFB && forEncryption)
+ {
+ return length + bufOff + (cipher.getBlockSize() + 2);
+ }
+
+ // Note: Can assume partialBlockOkay is true for purposes of this calculation
+ return length + bufOff;
+ }
+
+ /**
+ * process a single byte, producing an output block if necessary.
+ *
+ * @param in the input byte.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processByte(
+ byte in,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ int resultLen = 0;
+
+ buf[bufOff++] = in;
+
+ if (bufOff == buf.length)
+ {
+ resultLen = cipher.processBlock(buf, 0, out, outOff);
+ bufOff = 0;
+ }
+
+ return resultLen;
+ }
+
+ /**
+ * process an array of bytes, producing output if necessary.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset at which the input data starts.
+ * @param len the number of bytes to be copied out of the input array.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processBytes(
+ byte[] in,
+ int inOff,
+ int len,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Can't have a negative input length!");
+ }
+
+ int blockSize = getBlockSize();
+ int length = getUpdateOutputSize(len);
+
+ if (length > 0)
+ {
+ if ((outOff + length) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ }
+
+ int resultLen = 0;
+ int gapLen = buf.length - bufOff;
+
+ if (len > gapLen)
+ {
+ System.arraycopy(in, inOff, buf, bufOff, gapLen);
+
+ resultLen += cipher.processBlock(buf, 0, out, outOff);
+
+ bufOff = 0;
+ len -= gapLen;
+ inOff += gapLen;
+
+ if (mbCipher != null)
+ {
+ int blockCount = len / mbCipher.getMultiBlockSize();
+
+ if (blockCount > 0)
+ {
+ resultLen += mbCipher.processBlocks(in, inOff, blockCount, out, outOff + resultLen);
+
+ int processed = blockCount * mbCipher.getMultiBlockSize();
+
+ len -= processed;
+ inOff += processed;
+ }
+ }
+ else
+ {
+ while (len > buf.length)
+ {
+ resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen);
+
+ len -= blockSize;
+ inOff += blockSize;
+ }
+ }
+ }
+
+ System.arraycopy(in, inOff, buf, bufOff, len);
+
+ bufOff += len;
+
+ if (bufOff == buf.length)
+ {
+ resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen);
+ bufOff = 0;
+ }
+
+ return resultLen;
+ }
+
+ /**
+ * Process the last block in the buffer.
+ *
+ * @param out the array the block currently being held is copied into.
+ * @param outOff the offset at which the copying starts.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there is insufficient space in out for
+ * the output, or the input is not block size aligned and should be.
+ * @exception IllegalStateException if the underlying cipher is not
+ * initialised.
+ * @exception InvalidCipherTextException if padding is expected and not found.
+ * @exception DataLengthException if the input is not block size
+ * aligned.
+ */
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException, InvalidCipherTextException
+ {
+ try
+ {
+ int resultLen = 0;
+
+ if (outOff + bufOff > out.length)
+ {
+ throw new OutputLengthException("output buffer too short for doFinal()");
+ }
+
+ if (bufOff != 0)
+ {
+ if (!partialBlockOkay)
+ {
+ throw new DataLengthException("data not block size aligned");
+ }
+
+ cipher.processBlock(buf, 0, buf, 0);
+ resultLen = bufOff;
+ bufOff = 0;
+ System.arraycopy(buf, 0, out, outOff, resultLen);
+ }
+
+ return resultLen;
+ }
+ finally
+ {
+ reset();
+ }
+ }
+
+ /**
+ * Reset the buffer and cipher. After resetting the object is in the same
+ * state as it was after the last init (if there was one).
+ */
+ public void reset()
+ {
+ //
+ // clean the buffer.
+ //
+ for (int i = 0; i < buf.length; i++)
+ {
+ buf[i] = 0;
+ }
+
+ bufOff = 0;
+
+ //
+ // reset the underlying cipher.
+ //
+ cipher.reset();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DefaultMultiBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DefaultMultiBlockCipher.java
new file mode 100644
index 0000000..f1ca987
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DefaultMultiBlockCipher.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class DefaultMultiBlockCipher
+ implements MultiBlockCipher
+{
+ protected DefaultMultiBlockCipher()
+ {
+ }
+
+ public int getMultiBlockSize()
+ {
+ return this.getBlockSize();
+ }
+
+ public int processBlocks(byte[] in, int inOff, int blockCount, byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+
+ // TODO check if the underlying cipher supports the multiblock interface and call it directly?
+
+ int resultLen = 0;
+ int blockSize = this.getMultiBlockSize();
+
+ for (int i = 0; i != blockCount; i++)
+ {
+ resultLen += this.processBlock(in, inOff, out, outOff + resultLen);
+
+ inOff += blockSize;
+ }
+
+ return resultLen;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/EncapsulatedSecretExtractor.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/EncapsulatedSecretExtractor.java
new file mode 100644
index 0000000..16c1394
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/EncapsulatedSecretExtractor.java
@@ -0,0 +1,22 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface EncapsulatedSecretExtractor
+{
+ /**
+ * Extract the secret based on the recipient private key.
+ *
+ * @param encapsulation the encapsulated secret.
+ */
+ byte[] extractSecret(byte[] encapsulation);
+
+ /**
+ * Return the length in bytes of the encapsulation.
+ *
+ * @return length in bytes of an encapsulation for this parameter set.
+ */
+ int getEncapsulationLength();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/EncapsulatedSecretGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/EncapsulatedSecretGenerator.java
new file mode 100644
index 0000000..2b362ea
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/EncapsulatedSecretGenerator.java
@@ -0,0 +1,17 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface EncapsulatedSecretGenerator
+{
+ /**
+ * Generate secret/encapsulation based on the recipient public key.
+ *
+ * @return An SecretWithEncapsulation derived from the recipient public key.
+ */
+ SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/MultiBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/MultiBlockCipher.java
new file mode 100644
index 0000000..c0f386e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/MultiBlockCipher.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * Base interface for a cipher engine capable of processing multiple blocks at a time.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface MultiBlockCipher
+ extends BlockCipher
+{
+ /**
+ * Return the multi-block size for this cipher (in bytes).
+ *
+ * @return the multi-block size for this cipher in bytes.
+ */
+ int getMultiBlockSize();
+
+ /**
+ * Process blockCount blocks from input in offset inOff and place the output in
+ * out from offset outOff.
+ *
+ * @param in input data array.
+ * @param inOff start of input data in in.
+ * @param blockCount number of blocks to be processed.
+ * @param out output data array.
+ * @param outOff start position for output data.
+ * @return number of bytes written to out.
+ * @throws DataLengthException
+ * @throws IllegalStateException
+ */
+ int processBlocks(byte[] in, int inOff, int blockCount, byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SavableDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SavableDigest.java
new file mode 100644
index 0000000..f018b89
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SavableDigest.java
@@ -0,0 +1,15 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import com.android.internal.org.bouncycastle.crypto.digests.EncodableDigest;
+import com.android.internal.org.bouncycastle.util.Memoable;
+
+/**
+ * Extended digest which provides the ability to store state and
+ * provide an encoding.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface SavableDigest
+ extends ExtendedDigest, EncodableDigest, Memoable
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SecretWithEncapsulation.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SecretWithEncapsulation.java
new file mode 100644
index 0000000..ff512eb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SecretWithEncapsulation.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import javax.security.auth.Destroyable;
+
+/**
+ * Interface describing secret with encapsulation details.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface SecretWithEncapsulation
+ extends Destroyable
+{
+ /**
+ * Return the secret associated with the encapsulation.
+ *
+ * @return the secret the encapsulation is for.
+ */
+ byte[] getSecret();
+
+ /**
+ * Return the data that carries the secret in its encapsulated form.
+ *
+ * @return the encapsulation of the secret.
+ */
+ byte[] getEncapsulation();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SecureRandomProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SecureRandomProvider.java
new file mode 100644
index 0000000..5b7eb8a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SecureRandomProvider.java
@@ -0,0 +1,17 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import java.security.SecureRandom;
+
+/**
+ * Source provider for SecureRandom implementations.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface SecureRandomProvider
+{
+ /**
+ * Return a SecureRandom instance.
+ * @return a SecureRandom
+ */
+ SecureRandom get();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamBlockCipher.java
index b52b224..a3652a7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamBlockCipher.java
@@ -7,7 +7,8 @@
* @hide This class is not part of the Android public SDK API
*/
public abstract class StreamBlockCipher
- implements BlockCipher, StreamCipher
+ extends DefaultMultiBlockCipher
+ implements StreamCipher
{
private final BlockCipher cipher;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/DHBasicAgreement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
index 718e105..04d5351 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
@@ -5,6 +5,7 @@
import com.android.internal.org.bouncycastle.crypto.BasicAgreement;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
@@ -49,6 +50,8 @@
this.key = (DHPrivateKeyParameters)kParam;
this.dhParams = key.getParameters();
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("DHB", key));
}
public int getFieldSize()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
index 944a986..a0b2468 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
@@ -5,6 +5,7 @@
import com.android.internal.org.bouncycastle.crypto.BasicAgreement;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
@@ -36,6 +37,8 @@
CipherParameters key)
{
this.key = (ECPrivateKeyParameters)key;
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("ECDH", this.key));
}
public int getFieldSize()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/Utils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/Utils.java
new file mode 100644
index 0000000..a8bed7e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/Utils.java
@@ -0,0 +1,41 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.agreement;
+
+import com.android.internal.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.params.DHKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECKeyParameters;
+// Android-removed: unsupported algorithms
+// import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
+// import org.bouncycastle.crypto.params.X448PrivateKeyParameters;
+
+class Utils
+{
+ static CryptoServiceProperties getDefaultProperties(String algorithm, ECKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getCurve()), k, CryptoServicePurpose.AGREEMENT);
+ }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, DHKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getP()), k, CryptoServicePurpose.AGREEMENT);
+ }
+
+ // BEGIN Android-removed: unsupported algorithms
+ /*
+ static CryptoServiceProperties getDefaultProperties(String algorithm, X448PrivateKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, 224, k, CryptoServicePurpose.AGREEMENT);
+ }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, X25519PrivateKeyParameters k)
+ {
+ return new DefaultServiceProperties(algorithm, 128, k, CryptoServicePurpose.AGREEMENT);
+ }
+ */
+ // END Android-removed: unsupported algorithms
+}
+
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/constraints/ConstraintUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/constraints/ConstraintUtils.java
new file mode 100644
index 0000000..7fdf02d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/constraints/ConstraintUtils.java
@@ -0,0 +1,51 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.constraints;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ConstraintUtils
+{
+ /**
+ * Return the bits of security for the passed in RSA modulus or DH/DSA group value.
+ *
+ * @param p a modulus or group value
+ * @return the security strength in bits.
+ */
+ public static int bitsOfSecurityFor(BigInteger p)
+ {
+ return bitsOfSecurityForFF(p.bitLength());
+ }
+
+ /**
+ * Return the bits of security for the passed in Elliptic Curve.
+ *
+ * @param curve the ECCurve of interest.
+ * @return the security strength in bits.
+ */
+ public static int bitsOfSecurityFor(ECCurve curve)
+ {
+ int sBits = (curve.getFieldSize() + 1) / 2;
+
+ return (sBits > 256) ? 256 : sBits;
+ }
+
+ public static int bitsOfSecurityForFF(int strength)
+ {
+ if (strength >= 2048)
+ {
+ return (strength >= 3072) ?
+ ((strength >= 7680) ?
+ ((strength >= 15360) ? 256
+ : 192)
+ : 128)
+ : 112;
+ }
+
+ return (strength >= 1024) ? 80 : 20; // TODO: possibly a bit harsh...
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/constraints/DefaultServiceProperties.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/constraints/DefaultServiceProperties.java
new file mode 100644
index 0000000..e9003a8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/constraints/DefaultServiceProperties.java
@@ -0,0 +1,59 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.constraints;
+
+import com.android.internal.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultServiceProperties
+ implements CryptoServiceProperties
+{
+ private final String algorithm;
+ private final int bitsOfSecurity;
+ private final Object params;
+ private final CryptoServicePurpose purpose;
+
+ public DefaultServiceProperties(String algorithm, int bitsOfSecurity)
+ {
+ this(algorithm, bitsOfSecurity, null, CryptoServicePurpose.ANY);
+ }
+
+ public DefaultServiceProperties(String algorithm, int bitsOfSecurity, Object params)
+ {
+ this(algorithm, bitsOfSecurity, params, CryptoServicePurpose.ANY);
+ }
+
+ public DefaultServiceProperties(String algorithm, int bitsOfSecurity, Object params, CryptoServicePurpose purpose)
+ {
+ this.algorithm = algorithm;
+ this.bitsOfSecurity = bitsOfSecurity;
+ this.params = params;
+ if (params instanceof CryptoServicePurpose)
+ {
+ throw new IllegalArgumentException("params should not be CryptoServicePurpose");
+ }
+ this.purpose = purpose;
+ }
+
+ public int bitsOfSecurity()
+ {
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return algorithm;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return purpose;
+ }
+
+ public Object getParams()
+ {
+ return params;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AsconDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AsconDigest.java
new file mode 100644
index 0000000..32ae62e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AsconDigest.java
@@ -0,0 +1,222 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.ExtendedDigest;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+
+/* ASCON v1.2 Digest, https://ascon.iaik.tugraz.at/ .
+ * <p>
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf
+ * <p>
+ * ASCON v1.2 Digest with reference to C Reference Impl from: https://github.com/ascon/ascon-c .
+ */
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AsconDigest
+ implements ExtendedDigest
+{
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public enum AsconParameters
+ {
+ AsconHash,
+ AsconHashA,
+ }
+
+ AsconParameters asconParameters;
+
+ public AsconDigest(AsconParameters parameters)
+ {
+ this.asconParameters = parameters;
+ switch (parameters)
+ {
+ case AsconHash:
+ ASCON_PB_ROUNDS = 12;
+ algorithmName = "Ascon-Hash";
+ break;
+ case AsconHashA:
+ ASCON_PB_ROUNDS = 8;
+ algorithmName = "Ascon-HashA";
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid parameter settings for Ascon Hash");
+ }
+ reset();
+ }
+
+ private final String algorithmName;
+ private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ private long x0;
+ private long x1;
+ private long x2;
+ private long x3;
+ private long x4;
+ private final int CRYPTO_BYTES = 32;
+ private final int ASCON_PB_ROUNDS;
+
+ private long ROR(long x, int n)
+ {
+ return x >>> n | x << (64 - n);
+ }
+
+ private void ROUND(long C)
+ {
+ long t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
+ long t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
+ long t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
+ long t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
+ long t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
+ x0 = t0 ^ ROR(t0, 19) ^ ROR(t0, 28);
+ x1 = t1 ^ ROR(t1, 39) ^ ROR(t1, 61);
+ x2 = ~(t2 ^ ROR(t2, 1) ^ ROR(t2, 6));
+ x3 = t3 ^ ROR(t3, 10) ^ ROR(t3, 17);
+ x4 = t4 ^ ROR(t4, 7) ^ ROR(t4, 41);
+ }
+
+ private void P(int nr)
+ {
+ if (nr == 12)
+ {
+ ROUND(0xf0L);
+ ROUND(0xe1L);
+ ROUND(0xd2L);
+ ROUND(0xc3L);
+ }
+ if (nr >= 8)
+ {
+ ROUND(0xb4L);
+ ROUND(0xa5L);
+ }
+ ROUND(0x96L);
+ ROUND(0x87L);
+ ROUND(0x78L);
+ ROUND(0x69L);
+ ROUND(0x5aL);
+ ROUND(0x4bL);
+ }
+
+ private long PAD(int i)
+ {
+ return 0x80L << (56 - (i << 3));
+ }
+
+ private long LOADBYTES(final byte[] bytes, int inOff, int n)
+ {
+ long x = 0;
+ for (int i = 0; i < n; ++i)
+ {
+ x |= (bytes[i + inOff] & 0xFFL) << ((7 - i) << 3);
+ }
+ return x;
+ }
+
+ private void STOREBYTES(byte[] bytes, int inOff, long w, int n)
+ {
+ for (int i = 0; i < n; ++i)
+ {
+ bytes[i + inOff] = (byte)(w >>> ((7 - i) << 3));
+ }
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return algorithmName;
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return CRYPTO_BYTES;
+ }
+
+ @Override
+ public int getByteLength()
+ {
+ return 8;
+ }
+
+ @Override
+ public void update(byte in)
+ {
+ buffer.write(in);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+ }
+
+ @Override
+ public int doFinal(byte[] output, int outOff)
+ {
+ if (CRYPTO_BYTES + outOff > output.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ byte[] input = buffer.toByteArray();
+ int len = buffer.size();
+ int inOff = 0;
+ /* absorb full plaintext blocks */
+ int ASCON_HASH_RATE = 8;
+ while (len >= ASCON_HASH_RATE)
+ {
+ x0 ^= LOADBYTES(input, inOff, 8);
+ P(ASCON_PB_ROUNDS);
+ inOff += ASCON_HASH_RATE;
+ len -= ASCON_HASH_RATE;
+ }
+ /* absorb final plaintext block */
+ x0 ^= LOADBYTES(input, inOff, len);
+ x0 ^= PAD(len);
+ int ASCON_PA_ROUNDS = 12;
+ P(ASCON_PA_ROUNDS);
+ /* squeeze full output blocks */
+ len = CRYPTO_BYTES;
+ while (len > ASCON_HASH_RATE)
+ {
+ STOREBYTES(output, outOff, x0, 8);
+ P(ASCON_PB_ROUNDS);
+ outOff += ASCON_HASH_RATE;
+ len -= ASCON_HASH_RATE;
+ }
+ /* squeeze final output block */
+ STOREBYTES(output, outOff, x0, len);
+ reset();
+ return CRYPTO_BYTES;
+ }
+
+ @Override
+ public void reset()
+ {
+ buffer.reset();
+ /* initialize */
+ switch (asconParameters)
+ {
+ case AsconHashA:
+ x0 = 92044056785660070L;
+ x1 = 8326807761760157607L;
+ x2 = 3371194088139667532L;
+ x3 = -2956994353054992515L;
+ x4 = -6828509670848688761L;
+ break;
+ case AsconHash:
+ x0 = -1255492011513352131L;
+ x1 = -8380609354527731710L;
+ x2 = -5437372128236807582L;
+ x3 = 4834782570098516968L;
+ x4 = 3787428097924915520L;
+ break;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/GeneralDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/GeneralDigest.java
index 75038bd..f62783e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/GeneralDigest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/GeneralDigest.java
@@ -1,4 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: maintain old behaviour
package com.android.internal.org.bouncycastle.crypto.digests;
import com.android.internal.org.bouncycastle.crypto.ExtendedDigest;
@@ -160,3 +161,4 @@
protected abstract void processBlock();
}
+// END Android-changed: maintain old behaviour
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/Haraka256Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/Haraka256Digest.java
new file mode 100644
index 0000000..15000f5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/Haraka256Digest.java
@@ -0,0 +1,156 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Bytes;
+
+/**
+ * Haraka-256 v2, https://eprint.iacr.org/2016/098.pdf
+ * <p>
+ * Haraka256-256 with reference to Python Reference Impl from: https://github.com/kste/haraka
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Haraka256Digest
+ extends HarakaBase
+{
+ private void mix256(byte[][] s1, byte[][] s2)
+ {
+ System.arraycopy(s1[0], 0, s2[0], 0, 4);
+ System.arraycopy(s1[1], 0, s2[0], 4, 4);
+ System.arraycopy(s1[0], 4, s2[0], 8, 4);
+ System.arraycopy(s1[1], 4, s2[0], 12, 4);
+
+ System.arraycopy(s1[0], 8, s2[1], 0, 4);
+ System.arraycopy(s1[1], 8, s2[1], 4, 4);
+ System.arraycopy(s1[0], 12, s2[1], 8, 4);
+ System.arraycopy(s1[1], 12, s2[1], 12, 4);
+ }
+
+ private int haraka256256(byte[] msg, byte[] out, int outOff)
+ {
+ byte[][] s1 = new byte[2][16];
+ byte[][] s2 = new byte[2][16];
+
+ System.arraycopy(msg, 0, s1[0], 0, 16);
+ System.arraycopy(msg, 16, s1[1], 0, 16);
+
+ s1[0] = aesEnc(s1[0], RC[0]);
+ s1[1] = aesEnc(s1[1], RC[1]);
+ s1[0] = aesEnc(s1[0], RC[2]);
+ s1[1] = aesEnc(s1[1], RC[3]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[4]);
+ s1[1] = aesEnc(s2[1], RC[5]);
+ s1[0] = aesEnc(s1[0], RC[6]);
+ s1[1] = aesEnc(s1[1], RC[7]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[8]);
+ s1[1] = aesEnc(s2[1], RC[9]);
+ s1[0] = aesEnc(s1[0], RC[10]);
+ s1[1] = aesEnc(s1[1], RC[11]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[12]);
+ s1[1] = aesEnc(s2[1], RC[13]);
+ s1[0] = aesEnc(s1[0], RC[14]);
+ s1[1] = aesEnc(s1[1], RC[15]);
+ mix256(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[16]);
+ s1[1] = aesEnc(s2[1], RC[17]);
+ s1[0] = aesEnc(s1[0], RC[18]);
+ s1[1] = aesEnc(s1[1], RC[19]);
+ mix256(s1, s2);
+
+ Bytes.xor(16, s2[0], 0, msg, 0, out, outOff);
+ Bytes.xor(16, s2[1], 0, msg, 16, out, outOff + 16);
+
+ return DIGEST_SIZE;
+ }
+
+ private final byte[] buffer;
+ private int off;
+
+ private final CryptoServicePurpose purpose;
+
+
+ public Haraka256Digest()
+ {
+ this(CryptoServicePurpose.ANY);
+ }
+
+ public Haraka256Digest(CryptoServicePurpose purpose)
+ {
+ this.purpose = purpose;
+
+ this.buffer = new byte[32];
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties(this, getDigestSize()*4, purpose));
+ }
+
+ public Haraka256Digest(Haraka256Digest digest)
+ {
+ this.purpose = digest.purpose;
+
+ this.buffer = Arrays.clone(digest.buffer);
+ this.off = digest.off;
+
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties(this, getDigestSize()*4, purpose));
+ }
+
+ public String getAlgorithmName()
+ {
+ return "Haraka-256";
+ }
+
+ public void update(byte in)
+ {
+ if (off > 32 - 1)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 32 bytes");
+ }
+
+ buffer[off++] = in;
+ }
+
+ public void update(byte[] in, int inOff, int len)
+ {
+ if (off > 32 - len)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 32 bytes");
+ }
+
+ System.arraycopy(in, inOff, buffer, off, len);
+ off += len;
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ {
+ if (off != 32)
+ {
+ throw new IllegalStateException("input must be exactly 32 bytes");
+ }
+
+ if (out.length - outOff < 32)
+ {
+ throw new IllegalArgumentException("output too short to receive digest");
+ }
+
+ int rv = haraka256256(buffer, out, outOff);
+
+ reset();
+
+ return rv;
+ }
+
+ public void reset()
+ {
+ off = 0;
+ Arrays.clear(buffer);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/Haraka512Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/Haraka512Digest.java
new file mode 100644
index 0000000..69a8654
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/Haraka512Digest.java
@@ -0,0 +1,191 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Bytes;
+
+/**
+ * Haraka-512 v2, https://eprint.iacr.org/2016/098.pdf
+ * <p>
+ * Haraka512-256 with reference to Python Reference Impl from: https://github.com/kste/haraka
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Haraka512Digest
+ extends HarakaBase
+{
+ private final byte[] buffer;
+ private int off;
+
+ private final CryptoServicePurpose purpose;
+
+
+ public Haraka512Digest()
+ {
+ this(CryptoServicePurpose.ANY);
+ }
+ public Haraka512Digest(CryptoServicePurpose purpose)
+ {
+ this.purpose = purpose;
+
+ this.buffer = new byte[64];
+ }
+
+ public Haraka512Digest(Haraka512Digest digest)
+ {
+ this.purpose = digest.purpose;
+
+ this.buffer = Arrays.clone(digest.buffer);
+ this.off = digest.off;
+ }
+
+ private void mix512(byte[][] s1, byte[][] s2)
+ {
+ System.arraycopy(s1[0], 12, s2[0], 0, 4);
+ System.arraycopy(s1[2], 12, s2[0], 4, 4);
+ System.arraycopy(s1[1], 12, s2[0], 8, 4);
+ System.arraycopy(s1[3], 12, s2[0], 12, 4);
+
+ System.arraycopy(s1[2], 0, s2[1], 0, 4);
+ System.arraycopy(s1[0], 0, s2[1], 4, 4);
+ System.arraycopy(s1[3], 0, s2[1], 8, 4);
+ System.arraycopy(s1[1], 0, s2[1], 12, 4);
+
+ System.arraycopy(s1[2], 4, s2[2], 0, 4);
+ System.arraycopy(s1[0], 4, s2[2], 4, 4);
+ System.arraycopy(s1[3], 4, s2[2], 8, 4);
+ System.arraycopy(s1[1], 4, s2[2], 12, 4);
+
+ System.arraycopy(s1[0], 8, s2[3], 0, 4);
+ System.arraycopy(s1[2], 8, s2[3], 4, 4);
+ System.arraycopy(s1[1], 8, s2[3], 8, 4);
+ System.arraycopy(s1[3], 8, s2[3], 12, 4);
+ }
+
+ private int haraka512256(byte[] msg, byte[] out, int outOff)
+ {
+ byte[][] s1 = new byte[4][16];
+ byte[][] s2 = new byte[4][16];
+
+ //-- Unrolled version of above.
+
+ System.arraycopy(msg, 0, s1[0], 0, 16);
+ System.arraycopy(msg, 16, s1[1], 0, 16);
+ System.arraycopy(msg, 32, s1[2], 0, 16);
+ System.arraycopy(msg, 48, s1[3], 0, 16);
+
+ s1[0] = aesEnc(s1[0], RC[0]);
+ s1[1] = aesEnc(s1[1], RC[1]);
+ s1[2] = aesEnc(s1[2], RC[2]);
+ s1[3] = aesEnc(s1[3], RC[3]);
+ s1[0] = aesEnc(s1[0], RC[4]);
+ s1[1] = aesEnc(s1[1], RC[5]);
+ s1[2] = aesEnc(s1[2], RC[6]);
+ s1[3] = aesEnc(s1[3], RC[7]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[8]);
+ s1[1] = aesEnc(s2[1], RC[9]);
+ s1[2] = aesEnc(s2[2], RC[10]);
+ s1[3] = aesEnc(s2[3], RC[11]);
+ s1[0] = aesEnc(s1[0], RC[12]);
+ s1[1] = aesEnc(s1[1], RC[13]);
+ s1[2] = aesEnc(s1[2], RC[14]);
+ s1[3] = aesEnc(s1[3], RC[15]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[16]);
+ s1[1] = aesEnc(s2[1], RC[17]);
+ s1[2] = aesEnc(s2[2], RC[18]);
+ s1[3] = aesEnc(s2[3], RC[19]);
+ s1[0] = aesEnc(s1[0], RC[20]);
+ s1[1] = aesEnc(s1[1], RC[21]);
+ s1[2] = aesEnc(s1[2], RC[22]);
+ s1[3] = aesEnc(s1[3], RC[23]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[24]);
+ s1[1] = aesEnc(s2[1], RC[25]);
+ s1[2] = aesEnc(s2[2], RC[26]);
+ s1[3] = aesEnc(s2[3], RC[27]);
+ s1[0] = aesEnc(s1[0], RC[28]);
+ s1[1] = aesEnc(s1[1], RC[29]);
+ s1[2] = aesEnc(s1[2], RC[30]);
+ s1[3] = aesEnc(s1[3], RC[31]);
+ mix512(s1, s2);
+
+ s1[0] = aesEnc(s2[0], RC[32]);
+ s1[1] = aesEnc(s2[1], RC[33]);
+ s1[2] = aesEnc(s2[2], RC[34]);
+ s1[3] = aesEnc(s2[3], RC[35]);
+ s1[0] = aesEnc(s1[0], RC[36]);
+ s1[1] = aesEnc(s1[1], RC[37]);
+ s1[2] = aesEnc(s1[2], RC[38]);
+ s1[3] = aesEnc(s1[3], RC[39]);
+ mix512(s1, s2);
+
+ Bytes.xor(16, s2[0], 0, msg, 0, s1[0], 0);
+ Bytes.xor(16, s2[1], 0, msg, 16, s1[1], 0);
+ Bytes.xor(16, s2[2], 0, msg, 32, s1[2], 0);
+ Bytes.xor(16, s2[3], 0, msg, 48, s1[3], 0);
+
+ System.arraycopy(s1[0], 8, out, outOff, 8);
+ System.arraycopy(s1[1], 8, out, outOff + 8, 8);
+ System.arraycopy(s1[2], 0, out, outOff + 16, 8);
+ System.arraycopy(s1[3], 0, out, outOff + 24, 8);
+
+ return DIGEST_SIZE;
+ }
+
+ public String getAlgorithmName()
+ {
+ return "Haraka-512";
+ }
+
+ public void update(byte in)
+ {
+ if (off > 64 - 1)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 64 bytes");
+ }
+
+ buffer[off++] = in;
+ }
+
+ public void update(byte[] in, int inOff, int len)
+ {
+ if (off > 64 - len)
+ {
+ throw new IllegalArgumentException("total input cannot be more than 64 bytes");
+ }
+
+ System.arraycopy(in, inOff, buffer, off, len);
+ off += len;
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ {
+ if (off != 64)
+ {
+ throw new IllegalStateException("input must be exactly 64 bytes");
+ }
+
+ if (out.length - outOff < 32)
+ {
+ throw new IllegalArgumentException("output too short to receive digest");
+ }
+
+ int rv = haraka512256(buffer, out, outOff);
+
+ reset();
+
+ return rv;
+ }
+
+ public void reset()
+ {
+ off = 0;
+ Arrays.clear(buffer);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/HarakaBase.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/HarakaBase.java
new file mode 100644
index 0000000..785e60b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/HarakaBase.java
@@ -0,0 +1,149 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.util.Bytes;
+
+/**
+ * Base class for Haraka v2, https://eprint.iacr.org/2016/098.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class HarakaBase
+ implements Digest
+{
+ protected static final int DIGEST_SIZE = 32;
+
+ // Haraka round constants
+ static final byte[][] RC = new byte[][]
+ {
+ new byte[]{ (byte)0x9D, (byte)0x7B, (byte)0x81, (byte)0x75, (byte)0xF0, (byte)0xFE, (byte)0xC5, (byte)0xB2, (byte)0x0A, (byte)0xC0, (byte)0x20, (byte)0xE6, (byte)0x4C, (byte)0x70, (byte)0x84, (byte)0x06 },
+ new byte[]{ (byte)0x17, (byte)0xF7, (byte)0x08, (byte)0x2F, (byte)0xA4, (byte)0x6B, (byte)0x0F, (byte)0x64, (byte)0x6B, (byte)0xA0, (byte)0xF3, (byte)0x88, (byte)0xE1, (byte)0xB4, (byte)0x66, (byte)0x8B },
+ new byte[]{ (byte)0x14, (byte)0x91, (byte)0x02, (byte)0x9F, (byte)0x60, (byte)0x9D, (byte)0x02, (byte)0xCF, (byte)0x98, (byte)0x84, (byte)0xF2, (byte)0x53, (byte)0x2D, (byte)0xDE, (byte)0x02, (byte)0x34 },
+ new byte[]{ (byte)0x79, (byte)0x4F, (byte)0x5B, (byte)0xFD, (byte)0xAF, (byte)0xBC, (byte)0xF3, (byte)0xBB, (byte)0x08, (byte)0x4F, (byte)0x7B, (byte)0x2E, (byte)0xE6, (byte)0xEA, (byte)0xD6, (byte)0x0E },
+ new byte[]{ (byte)0x44, (byte)0x70, (byte)0x39, (byte)0xBE, (byte)0x1C, (byte)0xCD, (byte)0xEE, (byte)0x79, (byte)0x8B, (byte)0x44, (byte)0x72, (byte)0x48, (byte)0xCB, (byte)0xB0, (byte)0xCF, (byte)0xCB },
+ new byte[]{ (byte)0x7B, (byte)0x05, (byte)0x8A, (byte)0x2B, (byte)0xED, (byte)0x35, (byte)0x53, (byte)0x8D, (byte)0xB7, (byte)0x32, (byte)0x90, (byte)0x6E, (byte)0xEE, (byte)0xCD, (byte)0xEA, (byte)0x7E },
+ new byte[]{ (byte)0x1B, (byte)0xEF, (byte)0x4F, (byte)0xDA, (byte)0x61, (byte)0x27, (byte)0x41, (byte)0xE2, (byte)0xD0, (byte)0x7C, (byte)0x2E, (byte)0x5E, (byte)0x43, (byte)0x8F, (byte)0xC2, (byte)0x67 },
+ new byte[]{ (byte)0x3B, (byte)0x0B, (byte)0xC7, (byte)0x1F, (byte)0xE2, (byte)0xFD, (byte)0x5F, (byte)0x67, (byte)0x07, (byte)0xCC, (byte)0xCA, (byte)0xAF, (byte)0xB0, (byte)0xD9, (byte)0x24, (byte)0x29 },
+ new byte[]{ (byte)0xEE, (byte)0x65, (byte)0xD4, (byte)0xB9, (byte)0xCA, (byte)0x8F, (byte)0xDB, (byte)0xEC, (byte)0xE9, (byte)0x7F, (byte)0x86, (byte)0xE6, (byte)0xF1, (byte)0x63, (byte)0x4D, (byte)0xAB },
+ new byte[]{ (byte)0x33, (byte)0x7E, (byte)0x03, (byte)0xAD, (byte)0x4F, (byte)0x40, (byte)0x2A, (byte)0x5B, (byte)0x64, (byte)0xCD, (byte)0xB7, (byte)0xD4, (byte)0x84, (byte)0xBF, (byte)0x30, (byte)0x1C },
+ new byte[]{ (byte)0x00, (byte)0x98, (byte)0xF6, (byte)0x8D, (byte)0x2E, (byte)0x8B, (byte)0x02, (byte)0x69, (byte)0xBF, (byte)0x23, (byte)0x17, (byte)0x94, (byte)0xB9, (byte)0x0B, (byte)0xCC, (byte)0xB2 },
+ new byte[]{ (byte)0x8A, (byte)0x2D, (byte)0x9D, (byte)0x5C, (byte)0xC8, (byte)0x9E, (byte)0xAA, (byte)0x4A, (byte)0x72, (byte)0x55, (byte)0x6F, (byte)0xDE, (byte)0xA6, (byte)0x78, (byte)0x04, (byte)0xFA },
+ new byte[]{ (byte)0xD4, (byte)0x9F, (byte)0x12, (byte)0x29, (byte)0x2E, (byte)0x4F, (byte)0xFA, (byte)0x0E, (byte)0x12, (byte)0x2A, (byte)0x77, (byte)0x6B, (byte)0x2B, (byte)0x9F, (byte)0xB4, (byte)0xDF },
+ new byte[]{ (byte)0xEE, (byte)0x12, (byte)0x6A, (byte)0xBB, (byte)0xAE, (byte)0x11, (byte)0xD6, (byte)0x32, (byte)0x36, (byte)0xA2, (byte)0x49, (byte)0xF4, (byte)0x44, (byte)0x03, (byte)0xA1, (byte)0x1E },
+ new byte[]{ (byte)0xA6, (byte)0xEC, (byte)0xA8, (byte)0x9C, (byte)0xC9, (byte)0x00, (byte)0x96, (byte)0x5F, (byte)0x84, (byte)0x00, (byte)0x05, (byte)0x4B, (byte)0x88, (byte)0x49, (byte)0x04, (byte)0xAF },
+ new byte[]{ (byte)0xEC, (byte)0x93, (byte)0xE5, (byte)0x27, (byte)0xE3, (byte)0xC7, (byte)0xA2, (byte)0x78, (byte)0x4F, (byte)0x9C, (byte)0x19, (byte)0x9D, (byte)0xD8, (byte)0x5E, (byte)0x02, (byte)0x21 },
+ new byte[]{ (byte)0x73, (byte)0x01, (byte)0xD4, (byte)0x82, (byte)0xCD, (byte)0x2E, (byte)0x28, (byte)0xB9, (byte)0xB7, (byte)0xC9, (byte)0x59, (byte)0xA7, (byte)0xF8, (byte)0xAA, (byte)0x3A, (byte)0xBF },
+ new byte[]{ (byte)0x6B, (byte)0x7D, (byte)0x30, (byte)0x10, (byte)0xD9, (byte)0xEF, (byte)0xF2, (byte)0x37, (byte)0x17, (byte)0xB0, (byte)0x86, (byte)0x61, (byte)0x0D, (byte)0x70, (byte)0x60, (byte)0x62 },
+ new byte[]{ (byte)0xC6, (byte)0x9A, (byte)0xFC, (byte)0xF6, (byte)0x53, (byte)0x91, (byte)0xC2, (byte)0x81, (byte)0x43, (byte)0x04, (byte)0x30, (byte)0x21, (byte)0xC2, (byte)0x45, (byte)0xCA, (byte)0x5A },
+ new byte[]{ (byte)0x3A, (byte)0x94, (byte)0xD1, (byte)0x36, (byte)0xE8, (byte)0x92, (byte)0xAF, (byte)0x2C, (byte)0xBB, (byte)0x68, (byte)0x6B, (byte)0x22, (byte)0x3C, (byte)0x97, (byte)0x23, (byte)0x92 },
+ new byte[]{ (byte)0xB4, (byte)0x71, (byte)0x10, (byte)0xE5, (byte)0x58, (byte)0xB9, (byte)0xBA, (byte)0x6C, (byte)0xEB, (byte)0x86, (byte)0x58, (byte)0x22, (byte)0x38, (byte)0x92, (byte)0xBF, (byte)0xD3 },
+ new byte[]{ (byte)0x8D, (byte)0x12, (byte)0xE1, (byte)0x24, (byte)0xDD, (byte)0xFD, (byte)0x3D, (byte)0x93, (byte)0x77, (byte)0xC6, (byte)0xF0, (byte)0xAE, (byte)0xE5, (byte)0x3C, (byte)0x86, (byte)0xDB },
+ new byte[]{ (byte)0xB1, (byte)0x12, (byte)0x22, (byte)0xCB, (byte)0xE3, (byte)0x8D, (byte)0xE4, (byte)0x83, (byte)0x9C, (byte)0xA0, (byte)0xEB, (byte)0xFF, (byte)0x68, (byte)0x62, (byte)0x60, (byte)0xBB },
+ new byte[]{ (byte)0x7D, (byte)0xF7, (byte)0x2B, (byte)0xC7, (byte)0x4E, (byte)0x1A, (byte)0xB9, (byte)0x2D, (byte)0x9C, (byte)0xD1, (byte)0xE4, (byte)0xE2, (byte)0xDC, (byte)0xD3, (byte)0x4B, (byte)0x73 },
+ new byte[]{ (byte)0x4E, (byte)0x92, (byte)0xB3, (byte)0x2C, (byte)0xC4, (byte)0x15, (byte)0x14, (byte)0x4B, (byte)0x43, (byte)0x1B, (byte)0x30, (byte)0x61, (byte)0xC3, (byte)0x47, (byte)0xBB, (byte)0x43 },
+ new byte[]{ (byte)0x99, (byte)0x68, (byte)0xEB, (byte)0x16, (byte)0xDD, (byte)0x31, (byte)0xB2, (byte)0x03, (byte)0xF6, (byte)0xEF, (byte)0x07, (byte)0xE7, (byte)0xA8, (byte)0x75, (byte)0xA7, (byte)0xDB },
+ new byte[]{ (byte)0x2C, (byte)0x47, (byte)0xCA, (byte)0x7E, (byte)0x02, (byte)0x23, (byte)0x5E, (byte)0x8E, (byte)0x77, (byte)0x59, (byte)0x75, (byte)0x3C, (byte)0x4B, (byte)0x61, (byte)0xF3, (byte)0x6D },
+ new byte[]{ (byte)0xF9, (byte)0x17, (byte)0x86, (byte)0xB8, (byte)0xB9, (byte)0xE5, (byte)0x1B, (byte)0x6D, (byte)0x77, (byte)0x7D, (byte)0xDE, (byte)0xD6, (byte)0x17, (byte)0x5A, (byte)0xA7, (byte)0xCD },
+ new byte[]{ (byte)0x5D, (byte)0xEE, (byte)0x46, (byte)0xA9, (byte)0x9D, (byte)0x06, (byte)0x6C, (byte)0x9D, (byte)0xAA, (byte)0xE9, (byte)0xA8, (byte)0x6B, (byte)0xF0, (byte)0x43, (byte)0x6B, (byte)0xEC },
+ new byte[]{ (byte)0xC1, (byte)0x27, (byte)0xF3, (byte)0x3B, (byte)0x59, (byte)0x11, (byte)0x53, (byte)0xA2, (byte)0x2B, (byte)0x33, (byte)0x57, (byte)0xF9, (byte)0x50, (byte)0x69, (byte)0x1E, (byte)0xCB },
+ new byte[]{ (byte)0xD9, (byte)0xD0, (byte)0x0E, (byte)0x60, (byte)0x53, (byte)0x03, (byte)0xED, (byte)0xE4, (byte)0x9C, (byte)0x61, (byte)0xDA, (byte)0x00, (byte)0x75, (byte)0x0C, (byte)0xEE, (byte)0x2C },
+ new byte[]{ (byte)0x50, (byte)0xA3, (byte)0xA4, (byte)0x63, (byte)0xBC, (byte)0xBA, (byte)0xBB, (byte)0x80, (byte)0xAB, (byte)0x0C, (byte)0xE9, (byte)0x96, (byte)0xA1, (byte)0xA5, (byte)0xB1, (byte)0xF0 },
+ new byte[]{ (byte)0x39, (byte)0xCA, (byte)0x8D, (byte)0x93, (byte)0x30, (byte)0xDE, (byte)0x0D, (byte)0xAB, (byte)0x88, (byte)0x29, (byte)0x96, (byte)0x5E, (byte)0x02, (byte)0xB1, (byte)0x3D, (byte)0xAE },
+ new byte[]{ (byte)0x42, (byte)0xB4, (byte)0x75, (byte)0x2E, (byte)0xA8, (byte)0xF3, (byte)0x14, (byte)0x88, (byte)0x0B, (byte)0xA4, (byte)0x54, (byte)0xD5, (byte)0x38, (byte)0x8F, (byte)0xBB, (byte)0x17 },
+ new byte[]{ (byte)0xF6, (byte)0x16, (byte)0x0A, (byte)0x36, (byte)0x79, (byte)0xB7, (byte)0xB6, (byte)0xAE, (byte)0xD7, (byte)0x7F, (byte)0x42, (byte)0x5F, (byte)0x5B, (byte)0x8A, (byte)0xBB, (byte)0x34 },
+ new byte[]{ (byte)0xDE, (byte)0xAF, (byte)0xBA, (byte)0xFF, (byte)0x18, (byte)0x59, (byte)0xCE, (byte)0x43, (byte)0x38, (byte)0x54, (byte)0xE5, (byte)0xCB, (byte)0x41, (byte)0x52, (byte)0xF6, (byte)0x26 },
+ new byte[]{ (byte)0x78, (byte)0xC9, (byte)0x9E, (byte)0x83, (byte)0xF7, (byte)0x9C, (byte)0xCA, (byte)0xA2, (byte)0x6A, (byte)0x02, (byte)0xF3, (byte)0xB9, (byte)0x54, (byte)0x9A, (byte)0xE9, (byte)0x4C },
+ new byte[]{ (byte)0x35, (byte)0x12, (byte)0x90, (byte)0x22, (byte)0x28, (byte)0x6E, (byte)0xC0, (byte)0x40, (byte)0xBE, (byte)0xF7, (byte)0xDF, (byte)0x1B, (byte)0x1A, (byte)0xA5, (byte)0x51, (byte)0xAE },
+ new byte[]{ (byte)0xCF, (byte)0x59, (byte)0xA6, (byte)0x48, (byte)0x0F, (byte)0xBC, (byte)0x73, (byte)0xC1, (byte)0x2B, (byte)0xD2, (byte)0x7E, (byte)0xBA, (byte)0x3C, (byte)0x61, (byte)0xC1, (byte)0xA0 },
+ new byte[]{ (byte)0xA1, (byte)0x9D, (byte)0xC5, (byte)0xE9, (byte)0xFD, (byte)0xBD, (byte)0xD6, (byte)0x4A, (byte)0x88, (byte)0x82, (byte)0x28, (byte)0x02, (byte)0x03, (byte)0xCC, (byte)0x6A, (byte)0x75 },
+ };
+
+ private static final byte[][] S = new byte[][]{
+ { (byte)0x63, (byte)0x7C, (byte)0x77, (byte)0x7B, (byte)0xF2, (byte)0x6B, (byte)0x6F, (byte)0xC5, (byte)0x30, (byte)0x01, (byte)0x67, (byte)0x2B, (byte)0xFE, (byte)0xD7, (byte)0xAB, (byte)0x76 },
+ { (byte)0xCA, (byte)0x82, (byte)0xC9, (byte)0x7D, (byte)0xFA, (byte)0x59, (byte)0x47, (byte)0xF0, (byte)0xAD, (byte)0xD4, (byte)0xA2, (byte)0xAF, (byte)0x9C, (byte)0xA4, (byte)0x72, (byte)0xC0 },
+ { (byte)0xB7, (byte)0xFD, (byte)0x93, (byte)0x26, (byte)0x36, (byte)0x3F, (byte)0xF7, (byte)0xCC, (byte)0x34, (byte)0xA5, (byte)0xE5, (byte)0xF1, (byte)0x71, (byte)0xD8, (byte)0x31, (byte)0x15 },
+ { (byte)0x04, (byte)0xC7, (byte)0x23, (byte)0xC3, (byte)0x18, (byte)0x96, (byte)0x05, (byte)0x9A, (byte)0x07, (byte)0x12, (byte)0x80, (byte)0xE2, (byte)0xEB, (byte)0x27, (byte)0xB2, (byte)0x75 },
+ { (byte)0x09, (byte)0x83, (byte)0x2C, (byte)0x1A, (byte)0x1B, (byte)0x6E, (byte)0x5A, (byte)0xA0, (byte)0x52, (byte)0x3B, (byte)0xD6, (byte)0xB3, (byte)0x29, (byte)0xE3, (byte)0x2F, (byte)0x84 },
+ { (byte)0x53, (byte)0xD1, (byte)0x00, (byte)0xED, (byte)0x20, (byte)0xFC, (byte)0xB1, (byte)0x5B, (byte)0x6A, (byte)0xCB, (byte)0xBE, (byte)0x39, (byte)0x4A, (byte)0x4C, (byte)0x58, (byte)0xCF },
+ { (byte)0xD0, (byte)0xEF, (byte)0xAA, (byte)0xFB, (byte)0x43, (byte)0x4D, (byte)0x33, (byte)0x85, (byte)0x45, (byte)0xF9, (byte)0x02, (byte)0x7F, (byte)0x50, (byte)0x3C, (byte)0x9F, (byte)0xA8 },
+ { (byte)0x51, (byte)0xA3, (byte)0x40, (byte)0x8F, (byte)0x92, (byte)0x9D, (byte)0x38, (byte)0xF5, (byte)0xBC, (byte)0xB6, (byte)0xDA, (byte)0x21, (byte)0x10, (byte)0xFF, (byte)0xF3, (byte)0xD2 },
+ { (byte)0xCD, (byte)0x0C, (byte)0x13, (byte)0xEC, (byte)0x5F, (byte)0x97, (byte)0x44, (byte)0x17, (byte)0xC4, (byte)0xA7, (byte)0x7E, (byte)0x3D, (byte)0x64, (byte)0x5D, (byte)0x19, (byte)0x73 },
+ { (byte)0x60, (byte)0x81, (byte)0x4F, (byte)0xDC, (byte)0x22, (byte)0x2A, (byte)0x90, (byte)0x88, (byte)0x46, (byte)0xEE, (byte)0xB8, (byte)0x14, (byte)0xDE, (byte)0x5E, (byte)0x0B, (byte)0xDB },
+ { (byte)0xE0, (byte)0x32, (byte)0x3A, (byte)0x0A, (byte)0x49, (byte)0x06, (byte)0x24, (byte)0x5C, (byte)0xC2, (byte)0xD3, (byte)0xAC, (byte)0x62, (byte)0x91, (byte)0x95, (byte)0xE4, (byte)0x79 },
+ { (byte)0xE7, (byte)0xC8, (byte)0x37, (byte)0x6D, (byte)0x8D, (byte)0xD5, (byte)0x4E, (byte)0xA9, (byte)0x6C, (byte)0x56, (byte)0xF4, (byte)0xEA, (byte)0x65, (byte)0x7A, (byte)0xAE, (byte)0x08 },
+ { (byte)0xBA, (byte)0x78, (byte)0x25, (byte)0x2E, (byte)0x1C, (byte)0xA6, (byte)0xB4, (byte)0xC6, (byte)0xE8, (byte)0xDD, (byte)0x74, (byte)0x1F, (byte)0x4B, (byte)0xBD, (byte)0x8B, (byte)0x8A },
+ { (byte)0x70, (byte)0x3E, (byte)0xB5, (byte)0x66, (byte)0x48, (byte)0x03, (byte)0xF6, (byte)0x0E, (byte)0x61, (byte)0x35, (byte)0x57, (byte)0xB9, (byte)0x86, (byte)0xC1, (byte)0x1D, (byte)0x9E },
+ { (byte)0xE1, (byte)0xF8, (byte)0x98, (byte)0x11, (byte)0x69, (byte)0xD9, (byte)0x8E, (byte)0x94, (byte)0x9B, (byte)0x1E, (byte)0x87, (byte)0xE9, (byte)0xCE, (byte)0x55, (byte)0x28, (byte)0xDF },
+ { (byte)0x8C, (byte)0xA1, (byte)0x89, (byte)0x0D, (byte)0xBF, (byte)0xE6, (byte)0x42, (byte)0x68, (byte)0x41, (byte)0x99, (byte)0x2D, (byte)0x0F, (byte)0xB0, (byte)0x54, (byte)0xBB, (byte)0x16 },
+ };
+
+ static byte sBox(byte x)
+ {
+ return S[(((x & 0xFF) >>> 4))][x & 0xF];
+ }
+
+ static byte[] subBytes(byte[] s)
+ {
+ byte[] out = new byte[s.length];
+ out[0] = sBox(s[0]);
+ out[1] = sBox(s[1]);
+ out[2] = sBox(s[2]);
+ out[3] = sBox(s[3]);
+ out[4] = sBox(s[4]);
+ out[5] = sBox(s[5]);
+ out[6] = sBox(s[6]);
+ out[7] = sBox(s[7]);
+ out[8] = sBox(s[8]);
+ out[9] = sBox(s[9]);
+ out[10] = sBox(s[10]);
+ out[11] = sBox(s[11]);
+ out[12] = sBox(s[12]);
+ out[13] = sBox(s[13]);
+ out[14] = sBox(s[14]);
+ out[15] = sBox(s[15]);
+ return out;
+ }
+
+ static byte[] shiftRows(byte[] s)
+ {
+ return new byte[]{
+ s[0], s[5], s[10], s[15],
+ s[4], s[9], s[14], s[3],
+ s[8], s[13], s[2], s[7],
+ s[12], s[1], s[6], s[11]
+ };
+ }
+
+ static byte[] aesEnc(byte[] s, byte[] rk)
+ {
+ s = subBytes(s);
+ s = shiftRows(s);
+ s = mixColumns(s);
+ Bytes.xorTo(16, rk, s);
+ return s;
+ }
+
+ static byte mulX(byte p)
+ {
+ return (byte)(((p & 0x7F) << 1) ^ (((p & 0x80) >> 7) * 0x1B));
+ }
+
+ private static byte[] mixColumns(byte[] s)
+ {
+ byte[] out = new byte[s.length];
+ int j = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ out[j++] = (byte)(mulX(s[4 * i]) ^ mulX(s[4 * i + 1]) ^ s[4 * i + 1] ^ s[4 * i + 2] ^ s[4 * i + 3]);
+ out[j++] = (byte)(s[4 * i] ^ mulX(s[4 * i + 1]) ^ mulX(s[4 * i + 2]) ^ s[4 * i + 2] ^ s[4 * i + 3]);
+ out[j++] = (byte)(s[4 * i] ^ s[4 * i + 1] ^ mulX(s[4 * i + 2]) ^ mulX(s[4 * i + 3]) ^ s[4 * i + 3]);
+ out[j++] = (byte)(mulX(s[4 * i]) ^ s[4 * i] ^ s[4 * i + 1] ^ s[4 * i + 2] ^ mulX(s[4 * i + 3]));
+ }
+ return out;
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_SIZE;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/ISAPDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/ISAPDigest.java
new file mode 100644
index 0000000..1bcb481
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/ISAPDigest.java
@@ -0,0 +1,148 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * ISAP Hash v2, https://isap.iaik.tugraz.at/
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/isap-spec-final.pdf
+ * <p>
+ * ISAP Hash v2 with reference to C Reference Impl from: https://github.com/isap-lwc/isap-code-package
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+
+public class ISAPDigest
+ implements Digest
+{
+ private long x0, x1, x2, x3, x4;
+ private long t0, t1, t2, t3, t4;
+ private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+
+ private void ROUND(long C)
+ {
+ t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
+ t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
+ t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
+ t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
+ t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
+ x0 = t0 ^ ROTR(t0, 19) ^ ROTR(t0, 28);
+ x1 = t1 ^ ROTR(t1, 39) ^ ROTR(t1, 61);
+ x2 = ~(t2 ^ ROTR(t2, 1) ^ ROTR(t2, 6));
+ x3 = t3 ^ ROTR(t3, 10) ^ ROTR(t3, 17);
+ x4 = t4 ^ ROTR(t4, 7) ^ ROTR(t4, 41);
+ }
+
+ private void P12()
+ {
+ ROUND(0xf0);
+ ROUND(0xe1);
+ ROUND(0xd2);
+ ROUND(0xc3);
+ ROUND(0xb4);
+ ROUND(0xa5);
+ ROUND(0x96);
+ ROUND(0x87);
+ ROUND(0x78);
+ ROUND(0x69);
+ ROUND(0x5a);
+ ROUND(0x4b);
+ }
+
+ private long ROTR(long x, long n)
+ {
+ return (x >>> n) | (x << (64 - n));
+ }
+
+ protected long U64BIG(long x)
+ {
+ return ((ROTR(x, 8) & (0xFF000000FF000000L)) | (ROTR(x, 24) & (0x00FF000000FF0000L)) |
+ (ROTR(x, 40) & (0x0000FF000000FF00L)) | (ROTR(x, 56) & (0x000000FF000000FFL)));
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return "ISAP Hash";
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return 32;
+ }
+
+ @Override
+ public void update(byte input)
+ {
+ buffer.write(input);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+ }
+
+ @Override
+ public int doFinal(byte[] out, int outOff)
+ {
+ if (32 + outOff > out.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ t0 = t1 = t2 = t3 = t4 = 0;
+ /* init state */
+ x0 = -1255492011513352131L;
+ x1 = -8380609354527731710L;
+ x2 = -5437372128236807582L;
+ x3 = 4834782570098516968L;
+ x4 = 3787428097924915520L;
+ /* absorb */
+ byte[] input = buffer.toByteArray();
+ int len = input.length;
+ long[] in64 = new long[len >> 3];
+ Pack.littleEndianToLong(input, 0, in64, 0, in64.length);
+ int idx = 0;
+ while (len >= 8)
+ {
+ x0 ^= U64BIG(in64[idx++]);
+ P12();
+ len -= 8;
+ }
+ /* absorb final input block */
+ x0 ^= 0x80L << ((7 - len) << 3);
+ while (len > 0)
+ {
+ x0 ^= (input[(idx << 3) + --len] & 0xFFL) << ((7 - len) << 3);
+ }
+ P12();
+ // squeeze
+ long[] out64 = new long[4];
+ for (idx = 0; idx < 3; ++idx)
+ {
+ out64[idx] = U64BIG(x0);
+ P12();
+ }
+ /* squeeze final output block */
+ out64[idx] = U64BIG(x0);
+ Pack.longToLittleEndian(out64, out, outOff);
+ buffer.reset();
+ return 32;
+ }
+
+ @Override
+ public void reset()
+ {
+ buffer.reset();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/LongDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/LongDigest.java
index cc7411e..5346d09 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/LongDigest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/LongDigest.java
@@ -1,6 +1,8 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.digests;
+import com.android.internal.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
import com.android.internal.org.bouncycastle.crypto.ExtendedDigest;
import com.android.internal.org.bouncycastle.util.Memoable;
import com.android.internal.org.bouncycastle.util.Pack;
@@ -14,6 +16,8 @@
{
private static final int BYTE_LENGTH = 128;
+ protected final CryptoServicePurpose purpose;
+
private byte[] xBuf = new byte[8];
private int xBufOff;
@@ -30,6 +34,16 @@
*/
protected LongDigest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Constructor for variable length word
+ */
+ protected LongDigest(CryptoServicePurpose purpose)
+ {
+ this.purpose = purpose;
+
xBufOff = 0;
reset();
@@ -42,6 +56,8 @@
*/
protected LongDigest(LongDigest t)
{
+ this.purpose = t.purpose;
+
copyIn(t);
}
@@ -149,7 +165,7 @@
//
// process whole words.
//
- while (len > xBuf.length)
+ while (len >= xBuf.length)
{
processWord(in, inOff);
@@ -408,4 +424,5 @@
0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L
};
+ protected abstract CryptoServiceProperties cryptoServiceProperties();
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD4Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD4Digest.java
index 9b8176d..7b8508a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD4Digest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD4Digest.java
@@ -1,4 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: maintain old behaviour
package com.android.internal.org.bouncycastle.crypto.digests;
@@ -291,3 +292,4 @@
copyIn(d);
}
}
+// END Android-changed: maintain old behaviour
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD5Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD5Digest.java
index ba66202..0231c30 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD5Digest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD5Digest.java
@@ -1,4 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: maintain old behaviour
package com.android.internal.org.bouncycastle.crypto.digests;
@@ -361,3 +362,4 @@
return state;
}
}
+// END Android-changed: maintain old behaviour
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java
new file mode 100644
index 0000000..3487148
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/PhotonBeetleDigest.java
@@ -0,0 +1,221 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Bytes;
+
+/**
+ * Photon-Beetle, https://www.isical.ac.in/~lightweight/beetle/
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/photon-beetle-spec-final.pdf
+ * <p>
+ * Photon-Beetle with reference to C Reference Impl from: https://github.com/PHOTON-Beetle/Software
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PhotonBeetleDigest
+ implements Digest
+{
+ private byte[] state;
+ private byte[][] state_2d;
+ private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ private final int INITIAL_RATE_INBYTES = 16;
+ private int RATE_INBYTES = 4;
+ private int SQUEEZE_RATE_INBYTES = 16;
+ private int STATE_INBYTES = 32;
+ private int TAG_INBYTES = 32;
+ private int LAST_THREE_BITS_OFFSET = 5;
+ private int ROUND = 12;
+ private int D = 8;
+ private int Dq = 3;
+ private int Dr = 7;
+ private int DSquare = 64;
+ private int S = 4;
+ private int S_1 = 3;
+ private byte[][] RC = {//[D][12]
+ {1, 3, 7, 14, 13, 11, 6, 12, 9, 2, 5, 10},
+ {0, 2, 6, 15, 12, 10, 7, 13, 8, 3, 4, 11},
+ {2, 0, 4, 13, 14, 8, 5, 15, 10, 1, 6, 9},
+ {6, 4, 0, 9, 10, 12, 1, 11, 14, 5, 2, 13},
+ {14, 12, 8, 1, 2, 4, 9, 3, 6, 13, 10, 5},
+ {15, 13, 9, 0, 3, 5, 8, 2, 7, 12, 11, 4},
+ {13, 15, 11, 2, 1, 7, 10, 0, 5, 14, 9, 6},
+ {9, 11, 15, 6, 5, 3, 14, 4, 1, 10, 13, 2}
+ };
+ private byte[][] MixColMatrix = { //[D][D]
+ {2, 4, 2, 11, 2, 8, 5, 6},
+ {12, 9, 8, 13, 7, 7, 5, 2},
+ {4, 4, 13, 13, 9, 4, 13, 9},
+ {1, 6, 5, 1, 12, 13, 15, 14},
+ {15, 12, 9, 13, 14, 5, 14, 13},
+ {9, 14, 5, 15, 4, 12, 9, 6},
+ {12, 2, 2, 10, 3, 1, 1, 14},
+ {15, 1, 13, 10, 5, 10, 2, 3}
+ };
+
+ private byte[] sbox = {12, 5, 6, 11, 9, 0, 10, 13, 3, 14, 15, 8, 4, 7, 1, 2};
+
+ public PhotonBeetleDigest()
+ {
+ state = new byte[STATE_INBYTES];
+ state_2d = new byte[D][D];
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return "Photon-Beetle Hash";
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return TAG_INBYTES;
+ }
+
+ @Override
+ public void update(byte input)
+ {
+ buffer.write(input);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+ }
+
+ @Override
+ public int doFinal(byte[] output, int outOff)
+ {
+ if (32 + outOff > output.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ byte[] input = buffer.toByteArray();
+ int inlen = input.length;
+ if (inlen == 0)
+ {
+ state[STATE_INBYTES - 1] ^= 1 << LAST_THREE_BITS_OFFSET;
+ }
+ else if (inlen <= INITIAL_RATE_INBYTES)
+ {
+ System.arraycopy(input, 0, state, 0, inlen);
+ if (inlen < INITIAL_RATE_INBYTES)
+ {
+ state[inlen] ^= 0x01; // ozs
+ }
+ state[STATE_INBYTES - 1] ^= (inlen < INITIAL_RATE_INBYTES ? (byte)1 : (byte)2) << LAST_THREE_BITS_OFFSET;
+ }
+ else
+ {
+ System.arraycopy(input, 0, state, 0, INITIAL_RATE_INBYTES);
+ inlen -= INITIAL_RATE_INBYTES;
+ int Dlen_inblocks = (inlen + RATE_INBYTES - 1) / RATE_INBYTES;
+ int i, LastDBlocklen;
+ for (i = 0; i < Dlen_inblocks - 1; i++)
+ {
+ PHOTON_Permutation();
+ Bytes.xorTo(RATE_INBYTES, input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, state, 0);
+ }
+ PHOTON_Permutation();
+ LastDBlocklen = inlen - i * RATE_INBYTES;
+ Bytes.xorTo(LastDBlocklen, input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, state, 0);
+ if (LastDBlocklen < RATE_INBYTES)
+ {
+ state[LastDBlocklen] ^= 0x01; // ozs
+ }
+ state[STATE_INBYTES - 1] ^= (inlen % RATE_INBYTES == 0 ? (byte)1 : (byte)2) << LAST_THREE_BITS_OFFSET;
+ }
+ PHOTON_Permutation();
+ System.arraycopy(state, 0, output, outOff, SQUEEZE_RATE_INBYTES);
+ PHOTON_Permutation();
+ System.arraycopy(state, 0, output, outOff + SQUEEZE_RATE_INBYTES, TAG_INBYTES - SQUEEZE_RATE_INBYTES);
+ return TAG_INBYTES;
+ }
+
+ @Override
+ public void reset()
+ {
+ buffer.reset();
+ Arrays.fill(state, (byte)0);
+ }
+
+ void PHOTON_Permutation()
+ {
+ int i, j, k, l;
+ for (i = 0; i < DSquare; i++)
+ {
+ state_2d[i >>> Dq][i & Dr] = (byte)(((state[i >> 1] & 0xFF) >>> (4 * (i & 1))) & 0xf);
+ }
+ for (int round = 0; round < ROUND; round++)
+ {
+ //AddKey
+ for (i = 0; i < D; i++)
+ {
+ state_2d[i][0] ^= RC[i][round];
+ }
+ //SubCell
+ for (i = 0; i < D; i++)
+ {
+ for (j = 0; j < D; j++)
+ {
+ state_2d[i][j] = sbox[state_2d[i][j]];
+ }
+ }
+ //ShiftRow
+ for (i = 1; i < D; i++)
+ {
+ System.arraycopy(state_2d[i], 0, state, 0, D);
+ System.arraycopy(state, i, state_2d[i], 0, D - i);
+ System.arraycopy(state, 0, state_2d[i], D - i, i);
+ }
+ //MixColumn
+ for (j = 0; j < D; j++)
+ {
+ for (i = 0; i < D; i++)
+ {
+ byte sum = 0;
+ for (k = 0; k < D; k++)
+ {
+ int x = MixColMatrix[i][k], ret = 0, b = state_2d[k][j];
+ for (l = 0; l < S; l++)
+ {
+ if (((b >>> l) & 1) != 0)
+ {
+ ret ^= x;
+ }
+ if (((x >>> S_1) & 1) != 0)
+ {
+ x <<= 1;
+ x ^= 0x3;
+ }
+ else
+ {
+ x <<= 1;
+ }
+ }
+ sum ^= ret & 15;
+ }
+ state[i] = sum;
+ }
+ for (i = 0; i < D; i++)
+ {
+ state_2d[i][j] = state[i];
+ }
+ }
+ }
+ for (i = 0; i < DSquare; i += 2)
+ {
+ state[i >>> 1] = (byte)(((state_2d[i >>> Dq][i & Dr] & 0xf)) | ((state_2d[i >>> Dq][(i + 1) & Dr] & 0xf) << 4));
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA1Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA1Digest.java
index 12f82e5..b035ece 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA1Digest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA1Digest.java
@@ -1,4 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: maintain old behaviour
package com.android.internal.org.bouncycastle.crypto.digests;
import com.android.internal.org.bouncycastle.util.Memoable;
@@ -350,6 +351,4 @@
}
}
-
-
-
+// END Android-changed: maintain old behaviour
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA224Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA224Digest.java
index 8c3f9a4..82b6570 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA224Digest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA224Digest.java
@@ -1,4 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: maintain old behaviour
package com.android.internal.org.bouncycastle.crypto.digests;
@@ -360,4 +361,4 @@
return state;
}
}
-
+// END Android-changed: maintain old behaviour
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA256Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA256Digest.java
index 2626336..f7cd35e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA256Digest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA256Digest.java
@@ -1,7 +1,13 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN Android-changed: adapt to old version of GeneralDigest
package com.android.internal.org.bouncycastle.crypto.digests;
+import com.android.internal.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.SavableDigest;
import com.android.internal.org.bouncycastle.util.Memoable;
import com.android.internal.org.bouncycastle.util.Pack;
@@ -20,20 +26,60 @@
*/
public class SHA256Digest
extends GeneralDigest
- implements EncodableDigest
+ implements SavableDigest
{
private static final int DIGEST_LENGTH = 32;
+ protected final CryptoServicePurpose purpose;
private int H1, H2, H3, H4, H5, H6, H7, H8;
private int[] X = new int[64];
private int xOff;
+ public static SavableDigest newInstance()
+ {
+ return new SHA256Digest();
+ }
+
+ public static SavableDigest newInstance(CryptoServicePurpose purpose)
+ {
+ return new SHA256Digest(purpose);
+ }
+
+ public static SavableDigest newInstance(Digest digest)
+ {
+ if (digest instanceof SHA256Digest)
+ {
+ return new SHA256Digest((SHA256Digest) digest);
+ }
+
+ throw new IllegalArgumentException("receiver digest not available for input type " + (digest != null ? digest.getClass().getName() : "null"));
+ }
+
+ public static SavableDigest newInstance(byte[] encoded)
+ {
+ return new SHA256Digest(encoded);
+ }
+
/**
* Standard constructor
*/
public SHA256Digest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Standard constructor, with purpose
+ */
+ public SHA256Digest(CryptoServicePurpose purpose)
+ {
+ super();
+
+ this.purpose = purpose;
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
+
reset();
}
@@ -45,6 +91,8 @@
{
super(t);
+ this.purpose = CryptoServicePurpose.ANY;
+
copyIn(t);
}
@@ -74,6 +122,8 @@
{
super(encodedState);
+ this.purpose = CryptoServicePurpose.ANY;
+
H1 = Pack.bigEndianToInt(encodedState, 16);
H2 = Pack.bigEndianToInt(encodedState, 20);
H3 = Pack.bigEndianToInt(encodedState, 24);
@@ -105,13 +155,7 @@
byte[] in,
int inOff)
{
- // Note: Inlined for performance
-// X[xOff] = Pack.bigEndianToInt(in, inOff);
- int n = in[inOff] << 24;
- n |= (in[++inOff] & 0xff) << 16;
- n |= (in[++inOff] & 0xff) << 8;
- n |= (in[++inOff] & 0xff);
- X[xOff] = n;
+ X[xOff] = Pack.bigEndianToInt(in, inOff);
if (++xOff == 16)
{
@@ -131,9 +175,7 @@
X[15] = (int)(bitLength & 0xffffffff);
}
- public int doFinal(
- byte[] out,
- int outOff)
+ public int doFinal(byte[] out, int outOff)
{
finish();
@@ -201,7 +243,7 @@
int g = H7;
int h = H8;
- int t = 0;
+ int t = 0;
for(int i = 0; i < 8; i ++)
{
// t = 8 * i
@@ -334,7 +376,7 @@
public byte[] getEncodedState()
{
- byte[] state = new byte[52 + xOff * 4];
+ byte[] state = new byte[52 + xOff * 4 + 1];
super.populateState(state);
@@ -353,7 +395,14 @@
Pack.intToBigEndian(X[i], state, 52 + (i * 4));
}
+ state[state.length - 1] = (byte)purpose.ordinal();
+
return state;
}
-}
+ protected CryptoServiceProperties cryptoServiceProperties()
+ {
+ return Utils.getDefaultProperties(this, 256, purpose);
+ }
+}
+// END Android-changed: adapt to old version of GeneralDigest
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA384Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA384Digest.java
index 77a0db3..9eafed7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA384Digest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA384Digest.java
@@ -1,6 +1,9 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.digests;
+import com.android.internal.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.util.Memoable;
import com.android.internal.org.bouncycastle.util.Pack;
@@ -27,6 +30,19 @@
*/
public SHA384Digest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Standard constructor, with purpose
+ */
+ public SHA384Digest(CryptoServicePurpose purpose)
+ {
+ super(purpose);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
+
+ reset();
}
/**
@@ -36,6 +52,8 @@
public SHA384Digest(SHA384Digest t)
{
super(t);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
/**
@@ -45,7 +63,11 @@
*/
public SHA384Digest(byte[] encodedState)
{
+ super(CryptoServicePurpose.values()[encodedState[encodedState.length - 1]]);
+
restoreState(encodedState);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
public String getAlgorithmName()
@@ -111,8 +133,16 @@
public byte[] getEncodedState()
{
- byte[] encoded = new byte[getEncodedStateSize()];
+ byte[] encoded = new byte[getEncodedStateSize() + 1];
super.populateState(encoded);
+
+ encoded[encoded.length - 1] = (byte)purpose.ordinal();
+
return encoded;
}
+
+ protected CryptoServiceProperties cryptoServiceProperties()
+ {
+ return Utils.getDefaultProperties(this, 256, purpose);
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA512Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA512Digest.java
index 5a84732..e052a9e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA512Digest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA512Digest.java
@@ -1,6 +1,9 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.digests;
+import com.android.internal.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.util.Memoable;
import com.android.internal.org.bouncycastle.util.Pack;
@@ -27,6 +30,19 @@
*/
public SHA512Digest()
{
+ this(CryptoServicePurpose.ANY);
+ }
+
+ /**
+ * Standard constructor, with purpose
+ */
+ public SHA512Digest(CryptoServicePurpose purpose)
+ {
+ super(purpose);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
+
+ reset();
}
/**
@@ -36,6 +52,8 @@
public SHA512Digest(SHA512Digest t)
{
super(t);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
/**
@@ -45,7 +63,11 @@
*/
public SHA512Digest(byte[] encodedState)
{
+ super(CryptoServicePurpose.values()[encodedState[encodedState.length - 1]]);
+
restoreState(encodedState);
+
+ CryptoServicesRegistrar.checkConstraints(cryptoServiceProperties());
}
public String getAlgorithmName()
@@ -113,9 +135,17 @@
public byte[] getEncodedState()
{
- byte[] encoded = new byte[getEncodedStateSize()];
+ byte[] encoded = new byte[getEncodedStateSize() + 1];
super.populateState(encoded);
+
+ encoded[encoded.length - 1] = (byte)purpose.ordinal();
+
return encoded;
}
+
+ protected CryptoServiceProperties cryptoServiceProperties()
+ {
+ return Utils.getDefaultProperties(this, 256, purpose);
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/Utils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/Utils.java
new file mode 100644
index 0000000..a58cd6f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/Utils.java
@@ -0,0 +1,98 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+
+class Utils
+{
+ static CryptoServiceProperties getDefaultProperties(Digest digest, CryptoServicePurpose purpose)
+ {
+ return new DefaultProperties(digest.getDigestSize() * 4, digest.getAlgorithmName(), purpose);
+ }
+
+ static CryptoServiceProperties getDefaultProperties(Digest digest, int prfBitsOfSecurity, CryptoServicePurpose purpose)
+ {
+ return new DefaultPropertiesWithPRF(digest.getDigestSize() * 4, prfBitsOfSecurity, digest.getAlgorithmName(), purpose);
+ }
+
+ // Service Definitions
+ private static class DefaultPropertiesWithPRF
+ implements CryptoServiceProperties
+ {
+ private final int bitsOfSecurity;
+ private final int prfBitsOfSecurity;
+ private final String algorithmName;
+ private final CryptoServicePurpose purpose;
+
+ public DefaultPropertiesWithPRF(int bitsOfSecurity, int prfBitsOfSecurity, String algorithmName, CryptoServicePurpose purpose)
+ {
+ this.bitsOfSecurity = bitsOfSecurity;
+ this.prfBitsOfSecurity = prfBitsOfSecurity;
+ this.algorithmName = algorithmName;
+ this.purpose = purpose;
+ }
+
+ public int bitsOfSecurity()
+ {
+ if (purpose == CryptoServicePurpose.PRF)
+ {
+ return prfBitsOfSecurity;
+ }
+
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return algorithmName;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return purpose;
+ }
+
+ public Object getParams()
+ {
+ return null;
+ }
+ }
+
+ // Service Definitions
+ private static class DefaultProperties
+ implements CryptoServiceProperties
+ {
+ private final int bitsOfSecurity;
+ private final String algorithmName;
+ private final CryptoServicePurpose purpose;
+
+ public DefaultProperties(int bitsOfSecurity, String algorithmName, CryptoServicePurpose purpose)
+ {
+ this.bitsOfSecurity = bitsOfSecurity;
+ this.algorithmName = algorithmName;
+ this.purpose = purpose;
+ }
+
+ public int bitsOfSecurity()
+ {
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return algorithmName;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return purpose;
+ }
+
+ public Object getParams()
+ {
+ return null;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/XofUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/XofUtils.java
index 88c2a4a..ae45edd 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/XofUtils.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/XofUtils.java
@@ -1,6 +1,8 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.digests;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -8,24 +10,24 @@
{
public static byte[] leftEncode(long strLen)
{
- byte n = 1;
+ byte n = 1;
long v = strLen;
- while ((v >>= 8) != 0)
+ while ((v >>= 8) != 0)
{
- n++;
- }
+ n++;
+ }
byte[] b = new byte[n + 1];
- b[0] = n;
+ b[0] = n;
- for (int i = 1; i <= n; i++)
- {
- b[i] = (byte)(strLen >> (8 * (n - i)));
- }
+ for (int i = 1; i <= n; i++)
+ {
+ b[i] = (byte)(strLen >> (8 * (n - i)));
+ }
- return b;
+ return b;
}
public static byte[] rightEncode(long strLen)
@@ -49,4 +51,18 @@
return b;
}
+
+ static byte[] encode(byte X)
+ {
+ return Arrays.concatenate(XofUtils.leftEncode(8), new byte[] { X });
+ }
+
+ static byte[] encode(byte[] in, int inOff, int len)
+ {
+ if (in.length == len)
+ {
+ return Arrays.concatenate(XofUtils.leftEncode(len * 8), in);
+ }
+ return Arrays.concatenate(XofUtils.leftEncode(len * 8), Arrays.copyOfRange(in, inOff, inOff + len));
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/XoodyakDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/XoodyakDigest.java
new file mode 100644
index 0000000..3ec8de5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/XoodyakDigest.java
@@ -0,0 +1,208 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * Xoodyak v1, https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/xoodyak-spec-final.pdf
+ * <p>
+ * Xoodyak with reference to C Reference Impl from: https://github.com/XKCP/XKCP
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+
+public class XoodyakDigest
+ implements Digest
+{
+ private byte[] state;
+ private int phase;
+ private MODE mode;
+ private int Rabsorb;
+ private final int f_bPrime = 48;
+ private final int Rhash = 16;
+ private final int PhaseDown = 1;
+ private final int PhaseUp = 2;
+ private final int NLANES = 12;
+ private final int NROWS = 3;
+ private final int NCOLUMS = 4;
+ private final int MAXROUNDS = 12;
+ private final int TAGLEN = 16;
+ private final int[] RC = {0x00000058, 0x00000038, 0x000003C0, 0x000000D0, 0x00000120, 0x00000014, 0x00000060,
+ 0x0000002C, 0x00000380, 0x000000F0, 0x000001A0, 0x00000012};
+ private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+
+ enum MODE
+ {
+ ModeHash,
+ ModeKeyed
+ }
+
+ public XoodyakDigest()
+ {
+ state = new byte[48];
+ reset();
+ }
+
+ @Override
+ public String getAlgorithmName()
+ {
+ return "Xoodyak Hash";
+ }
+
+ @Override
+ public int getDigestSize()
+ {
+ return 32;
+ }
+
+ @Override
+ public void update(byte input)
+ {
+ buffer.write(input);
+ }
+
+ @Override
+ public void update(byte[] input, int inOff, int len)
+ {
+ if ((inOff + len) > input.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ buffer.write(input, inOff, len);
+
+ }
+
+ @Override
+ public int doFinal(byte[] output, int outOff)
+ {
+ if (32 + outOff > output.length)
+ {
+ throw new OutputLengthException("output buffer is too short");
+ }
+ byte[] input = buffer.toByteArray();
+ int inOff = 0;
+ int len = buffer.size();
+ int Cd = 0x03;
+ int splitLen;
+ do
+ {
+ if (phase != PhaseUp)
+ {
+ Up(null, 0, 0, 0);
+ }
+ splitLen = Math.min(len, Rabsorb);
+ Down(input, inOff, splitLen, Cd);
+ Cd = 0;
+ inOff += splitLen;
+ len -= splitLen;
+ }
+ while (len != 0);
+ Up(output, outOff, TAGLEN, 0x40);
+ Down(null, 0, 0, 0);
+ Up(output, outOff + TAGLEN, TAGLEN, 0);
+ return 32;
+ }
+
+ @Override
+ public void reset()
+ {
+ Arrays.fill(state, (byte)0);
+ phase = PhaseUp;
+ mode = MODE.ModeHash;
+ Rabsorb = Rhash;
+ buffer.reset();
+ }
+
+ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
+ {
+ if (mode != MODE.ModeHash)
+ {
+ state[f_bPrime - 1] ^= Cu;
+ }
+ int[] a = new int[NLANES];
+ Pack.littleEndianToInt(state, 0, a, 0, a.length);
+ int x, y;
+ int[] b = new int[NLANES];
+ int[] p = new int[NCOLUMS];
+ int[] e = new int[NCOLUMS];
+ for (int i = 0; i < MAXROUNDS; ++i)
+ {
+ /* Theta: Column Parity Mixer */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ p[x] = a[index(x, 0)] ^ a[index(x, 1)] ^ a[index(x, 2)];
+ }
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ y = p[(x + 3) & 3];
+ e[x] = ROTL32(y, 5) ^ ROTL32(y, 14);
+ }
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ for (y = 0; y < NROWS; ++y)
+ {
+ a[index(x, y)] ^= e[x];
+ }
+ }
+ /* Rho-west: plane shift */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ b[index(x, 0)] = a[index(x, 0)];
+ b[index(x, 1)] = a[index(x + 3, 1)];
+ b[index(x, 2)] = ROTL32(a[index(x, 2)], 11);
+ }
+ /* Iota: round ant */
+ b[0] ^= RC[i];
+ /* Chi: non linear layer */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ for (y = 0; y < NROWS; ++y)
+ {
+ a[index(x, y)] = b[index(x, y)] ^ (~b[index(x, y + 1)] & b[index(x, y + 2)]);
+ }
+ }
+ /* Rho-east: plane shift */
+ for (x = 0; x < NCOLUMS; ++x)
+ {
+ b[index(x, 0)] = a[index(x, 0)];
+ b[index(x, 1)] = ROTL32(a[index(x, 1)], 1);
+ b[index(x, 2)] = ROTL32(a[index(x + 2, 2)], 8);
+ }
+ System.arraycopy(b, 0, a, 0, NLANES);
+ }
+ Pack.intToLittleEndian(a, 0, a.length, state, 0);
+ phase = PhaseUp;
+ if (Yi != null)
+ {
+ System.arraycopy(state, 0, Yi, YiOff, YiLen);
+ }
+ }
+
+ void Down(byte[] Xi, int XiOff, int XiLen, int Cd)
+ {
+ for (int i = 0; i < XiLen; i++)
+ {
+ state[i] ^= Xi[XiOff++];
+ }
+ state[XiLen] ^= 0x01;
+ state[f_bPrime - 1] ^= (mode == MODE.ModeHash) ? (Cd & 0x01) : Cd;
+ phase = PhaseDown;
+ }
+
+ private int index(int x, int y)
+ {
+ return (((y % NROWS) * NCOLUMS) + ((x) % NCOLUMS));
+ }
+
+ private int ROTL32(int a, int offset)
+ {
+ return (a << (offset & 31)) ^ (a >>> ((32 - (offset)) & 31));
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ec/CustomNamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ec/CustomNamedCurves.java
index d2f0a3a..1eecf91 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ec/CustomNamedCurves.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ec/CustomNamedCurves.java
@@ -87,10 +87,15 @@
*
static X9ECParametersHolder curve25519 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new Curve25519());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new Curve25519());
+ ECCurve curve = getCurve();
/*
* NOTE: Curve25519 was specified in Montgomery form. Rewriting in Weierstrass form
@@ -113,10 +118,15 @@
*
static X9ECParametersHolder secp128r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP128R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
- ECCurve curve = configureCurve(new SecP128R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -128,9 +138,8 @@
*
static X9ECParametersHolder secp160k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
@@ -144,7 +153,13 @@
new BigInteger("9162fbe73984472a0a9d0590", 16),
new BigInteger("96341f1138933bc2f503fd44", 16),
176));
- ECCurve curve = configureCurveGLV(new SecP160K1Curve(), glv);
+ return configureCurveGLV(new SecP160K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -156,10 +171,15 @@
*
static X9ECParametersHolder secp160r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP160R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
- ECCurve curve = configureCurve(new SecP160R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -171,10 +191,15 @@
*
static X9ECParametersHolder secp160r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP160R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
- ECCurve curve = configureCurve(new SecP160R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -188,9 +213,8 @@
*/
static X9ECParametersHolder secp192k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
@@ -204,7 +228,13 @@
new BigInteger("71169be7330b3038edb025f1d0f9", 16),
new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
208));
- ECCurve curve = configureCurveGLV(new SecP192K1Curve(), glv);
+ return configureCurveGLV(new SecP192K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -216,10 +246,15 @@
*/
static X9ECParametersHolder secp192r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP192R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
- ECCurve curve = configureCurve(new SecP192R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -231,9 +266,8 @@
*/
static X9ECParametersHolder secp224k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
@@ -247,7 +281,13 @@
new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
240));
- ECCurve curve = configureCurveGLV(new SecP224K1Curve(), glv);
+ return configureCurveGLV(new SecP224K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -259,10 +299,15 @@
*/
static X9ECParametersHolder secp224r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP224R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
- ECCurve curve = configureCurve(new SecP224R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -274,9 +319,8 @@
*/
static X9ECParametersHolder secp256k1 = new X9ECParametersHolder()
{
- protected X9ECParameters createParameters()
+ protected ECCurve createCurve()
{
- byte[] S = null;
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
@@ -290,7 +334,13 @@
new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
272));
- ECCurve curve = configureCurveGLV(new SecP256K1Curve(), glv);
+ return configureCurveGLV(new SecP256K1Curve(), glv);
+ }
+
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -302,10 +352,15 @@
*/
static X9ECParametersHolder secp256r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP256R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
- ECCurve curve = configureCurve(new SecP256R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -317,10 +372,15 @@
*/
static X9ECParametersHolder secp384r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP384R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
- ECCurve curve = configureCurve(new SecP384R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
@@ -333,10 +393,15 @@
*/
static X9ECParametersHolder secp521r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecP521R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
- ECCurve curve = configureCurve(new SecP521R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
+ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
@@ -351,10 +416,15 @@
*
static X9ECParametersHolder sect113r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT113R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
- ECCurve curve = configureCurve(new SecT113R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -366,10 +436,15 @@
*
static X9ECParametersHolder sect113r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT113R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
- ECCurve curve = configureCurve(new SecT113R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -381,10 +456,15 @@
*
static X9ECParametersHolder sect131r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT131R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
- ECCurve curve = configureCurve(new SecT131R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -396,10 +476,15 @@
*
static X9ECParametersHolder sect131r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT131R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
- ECCurve curve = configureCurve(new SecT131R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -411,10 +496,15 @@
*
static X9ECParametersHolder sect163k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT163K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT163K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -426,10 +516,15 @@
*
static X9ECParametersHolder sect163r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT163R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
- ECCurve curve = configureCurve(new SecT163R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -441,10 +536,15 @@
*
static X9ECParametersHolder sect163r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT163R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
- ECCurve curve = configureCurve(new SecT163R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -456,10 +556,15 @@
*
static X9ECParametersHolder sect193r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT193R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
- ECCurve curve = configureCurve(new SecT193R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -471,10 +576,15 @@
*
static X9ECParametersHolder sect193r2 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT193R2Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
- ECCurve curve = configureCurve(new SecT193R2Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -486,10 +596,15 @@
*
static X9ECParametersHolder sect233k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT233K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT233K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -501,10 +616,15 @@
*
static X9ECParametersHolder sect233r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT233R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
- ECCurve curve = configureCurve(new SecT233R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -516,10 +636,15 @@
*
static X9ECParametersHolder sect239k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT239K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT239K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -531,10 +656,15 @@
*
static X9ECParametersHolder sect283k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT283K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT283K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
+ "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
@@ -547,10 +677,15 @@
*
static X9ECParametersHolder sect283r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT283R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
- ECCurve curve = configureCurve(new SecT283R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
+ "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
@@ -563,10 +698,15 @@
*
static X9ECParametersHolder sect409k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT409K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT409K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
+ "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
@@ -579,10 +719,15 @@
*
static X9ECParametersHolder sect409r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT409R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
- ECCurve curve = configureCurve(new SecT409R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
+ "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
@@ -595,10 +740,15 @@
*
static X9ECParametersHolder sect571k1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT571K1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SecT571K1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
+ "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
@@ -611,10 +761,15 @@
*
static X9ECParametersHolder sect571r1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SecT571R1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
- ECCurve curve = configureCurve(new SecT571R1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve, "04"
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
+ "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
@@ -627,10 +782,15 @@
*
static X9ECParametersHolder sm2p256v1 = new X9ECParametersHolder()
{
+ protected ECCurve createCurve()
+ {
+ return configureCurve(new SM2P256V1Curve());
+ }
+
protected X9ECParameters createParameters()
{
byte[] S = null;
- ECCurve curve = configureCurve(new SM2P256V1Curve());
+ ECCurve curve = getCurve();
X9ECPoint G = configureBasepoint(curve,
"0432C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -640,6 +800,7 @@
// END Android-removed: Unsupported curves
+
static final Hashtable nameToCurve = new Hashtable();
static final Hashtable nameToOID = new Hashtable();
static final Hashtable oidToCurve = new Hashtable();
@@ -746,10 +907,15 @@
public static X9ECParameters getByName(String name)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)nameToCurve.get(Strings.toLowerCase(name));
+ X9ECParametersHolder holder = getByNameLazy(name);
return holder == null ? null : holder.getParameters();
}
+ public static X9ECParametersHolder getByNameLazy(String name)
+ {
+ return (X9ECParametersHolder)nameToCurve.get(Strings.toLowerCase(name));
+ }
+
/**
* return the X9ECParameters object for the named curve represented by the passed in object
* identifier. Null if the curve isn't present.
@@ -759,10 +925,15 @@
*/
public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
{
- X9ECParametersHolder holder = (X9ECParametersHolder)oidToCurve.get(oid);
+ X9ECParametersHolder holder = getByOIDLazy(oid);
return holder == null ? null : holder.getParameters();
}
+ public static X9ECParametersHolder getByOIDLazy(ASN1ObjectIdentifier oid)
+ {
+ return (X9ECParametersHolder)oidToCurve.get(oid);
+ }
+
/**
* return the object identifier signified by the passed in name. Null if there is no object
* identifier associated with name.
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java
index 23fcdd6..bb835c7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java
@@ -14,6 +14,7 @@
// import org.bouncycastle.crypto.util.DigestFactory;
import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Pack;
/**
* Optimal Asymmetric Encryption Padding (OAEP) - see PKCS 1 V 2.
@@ -227,7 +228,9 @@
// on encryption, we need to make sure our decrypted block comes back
// the same size.
//
- boolean wrongData = (block.length < (2 * defHash.length) + 1);
+
+ // i.e. wrong when block.length < (2 * defHash.length) + 1
+ int wrongMask = (block.length - ((2 * defHash.length) + 1)) >> 31;
if (data.length <= block.length)
{
@@ -236,7 +239,7 @@
else
{
System.arraycopy(data, 0, block, 0, block.length);
- wrongData = true;
+ wrongMask |= 1;
}
//
@@ -264,39 +267,38 @@
// check the hash of the encoding params.
// long check to try to avoid this been a source of a timing attack.
//
- boolean defHashWrong = false;
-
for (int i = 0; i != defHash.length; i++)
{
- if (defHash[i] != block[defHash.length + i])
- {
- defHashWrong = true;
- }
+ wrongMask |= defHash[i] ^ block[defHash.length + i];
}
//
// find the data block
//
- int start = block.length;
+ int start = -1;
for (int index = 2 * defHash.length; index != block.length; index++)
{
- if (block[index] != 0 & start == block.length)
- {
- start = index;
- }
+ int octet = block[index] & 0xFF;
+
+ // i.e. mask will be 0xFFFFFFFF if octet is non-zero and start is (still) negative, else 0.
+ int shouldSetMask = (-octet & start) >> 31;
+
+ start += index & shouldSetMask;
}
- boolean dataStartWrong = (start > (block.length - 1) | block[start] != 1);
+ wrongMask |= start >> 31;
+ ++start;
+ wrongMask |= block[start] ^ 1;
- start++;
-
- if (defHashWrong | wrongData | dataStartWrong)
+ if (wrongMask != 0)
{
Arrays.fill(block, (byte)0);
throw new InvalidCipherTextException("data wrong");
}
+ ++start;
+
//
// extract the data block
//
@@ -309,19 +311,6 @@
}
/**
- * int to octet string.
- */
- private void ItoOSP(
- int i,
- byte[] sp)
- {
- sp[0] = (byte)(i >>> 24);
- sp[1] = (byte)(i >>> 16);
- sp[2] = (byte)(i >>> 8);
- sp[3] = (byte)(i >>> 0);
- }
-
- /**
* mask generator function, as described in PKCS1v2.
*/
private byte[] maskGeneratorFunction1(
@@ -339,7 +328,7 @@
while (counter < (length / hashBuf.length))
{
- ItoOSP(counter, C);
+ Pack.intToBigEndian(counter, C, 0);
mgf1Hash.update(Z, zOff, zLen);
mgf1Hash.update(C, 0, C.length);
@@ -352,7 +341,7 @@
if ((counter * hashBuf.length) < length)
{
- ItoOSP(counter, C);
+ Pack.intToBigEndian(counter, C, 0);
mgf1Hash.update(Z, zOff, zLen);
mgf1Hash.update(C, 0, C.length);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
index aafbf6e..d3b8c97 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
@@ -235,52 +235,86 @@
}
/**
- * Checks if the argument is a correctly PKCS#1.5 encoded Plaintext
- * for encryption.
- *
- * @param encoded The Plaintext.
- * @param pLen Expected length of the plaintext.
- * @return Either 0, if the encoding is correct, or -1, if it is incorrect.
+ * Check the argument is a valid encoding with type 1. Returns the plaintext length if valid, or -1 if invalid.
*/
- private static int checkPkcs1Encoding(byte[] encoded, int pLen)
+ private static int checkPkcs1Encoding1(byte[] buf)
{
- int correct = 0;
- /*
- * Check if the first two bytes are 0 2
- */
- correct |= (encoded[0] ^ 2);
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
- /*
- * Now the padding check, check for no 0 byte in the padding
- */
- int plen = encoded.length - (
- pLen /* Length of the PMS */
- + 1 /* Final 0-byte before PMS */
- );
+ // The first byte should be 0x01
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x01);
- for (int i = 1; i < plen; i++)
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
{
- int tmp = encoded[i];
- tmp |= tmp >> 1;
- tmp |= tmp >> 2;
- tmp |= tmp >> 4;
- correct |= (tmp & 1) - 1;
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ int is0xFFMask = ((padByte ^ 0xFF) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ badPadSign |= ~(foundZeroMask | is0xFFMask);
}
- /*
- * Make sure the padding ends with a 0 byte.
- */
- correct |= encoded[encoded.length - (pLen + 1)];
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
- /*
- * Return 0 or 1, depending on the result.
- */
- correct |= correct >> 1;
- correct |= correct >> 2;
- correct |= correct >> 4;
- return ~((correct & 1) - 1);
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
}
+ /**
+ * Check the argument is a valid encoding with type 2. Returns the plaintext length if valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding2(byte[] buf)
+ {
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
+
+ // The first byte should be 0x02
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x02);
+
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
+ {
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ }
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
+ }
+
+ /**
+ * Check the argument is a valid encoding with type 2 of a plaintext with the given length. Returns 0 if
+ * valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding2(byte[] buf, int plaintextLength)
+ {
+ // The first byte should be 0x02
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x02);
+
+ int lastPadPos = buf.length - 1 - plaintextLength;
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ // All pad bytes before the last one should be non-zero
+ for (int i = 1; i < lastPadPos; ++i)
+ {
+ badPadSign |= (buf[i] & 0xFF) - 1;
+ }
+
+ // Last pad byte should be zero
+ badPadSign |= -(buf[lastPadPos] & 0xFF);
+
+ return badPadSign >> 31;
+ }
/**
* Decode PKCS#1.5 encoding, and return a random value if the padding is not correct.
@@ -300,36 +334,43 @@
throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
}
- byte[] block = engine.processBlock(in, inOff, inLen);
- byte[] random;
- if (this.fallback == null)
+ int plaintextLength = this.pLen;
+
+ byte[] random = fallback;
+ if (fallback == null)
{
- random = new byte[this.pLen];
+ random = new byte[plaintextLength];
this.random.nextBytes(random);
}
- else
+
+ int badPadMask = 0;
+ int strictBlockSize = engine.getOutputBlockSize();
+ byte[] block = engine.processBlock(in, inOff, inLen);
+
+ byte[] data = block;
+ if (block.length != strictBlockSize)
{
- random = fallback;
+ if (useStrictLength || block.length < strictBlockSize)
+ {
+ data = blockBuffer;
+ }
}
- byte[] data = (useStrictLength & (block.length != engine.getOutputBlockSize())) ? blockBuffer : block;
+ badPadMask |= checkPkcs1Encoding2(data, plaintextLength);
- /*
- * Check the padding.
- */
- int correct = PKCS1Encoding.checkPkcs1Encoding(data, this.pLen);
-
- /*
- * Now, to a constant time constant memory copy of the decrypted value
- * or the random value, depending on the validity of the padding.
- */
- byte[] result = new byte[this.pLen];
- for (int i = 0; i < this.pLen; i++)
+ /*
+ * Now, to a constant time constant memory copy of the decrypted value
+ * or the random value, depending on the validity of the padding.
+ */
+ int dataOff = data.length - plaintextLength;
+ byte[] result = new byte[plaintextLength];
+ for (int i = 0; i < plaintextLength; ++i)
{
- result[i] = (byte)((data[i + (data.length - pLen)] & (~correct)) | (random[i] & correct));
+ result[i] = (byte)((data[dataOff + i] & ~badPadMask) | (random[i] & badPadMask));
}
- Arrays.fill(data, (byte)0);
+ Arrays.fill(block, (byte)0);
+ Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0);
return result;
}
@@ -337,95 +378,50 @@
/**
* @throws InvalidCipherTextException if the decrypted block is not in PKCS1 format.
*/
- private byte[] decodeBlock(
- byte[] in,
- int inOff,
- int inLen)
+ private byte[] decodeBlock(byte[] in, int inOff, int inLen)
throws InvalidCipherTextException
{
/*
* If the length of the expected plaintext is known, we use a constant-time decryption.
* If the decryption fails, we return a random value.
*/
- if (this.pLen != -1)
+ if (forPrivateKey && this.pLen != -1)
{
return this.decodeBlockOrRandom(in, inOff, inLen);
}
+ int strictBlockSize = engine.getOutputBlockSize();
byte[] block = engine.processBlock(in, inOff, inLen);
- boolean incorrectLength = (useStrictLength & (block.length != engine.getOutputBlockSize()));
- byte[] data;
- if (block.length < getOutputBlockSize())
+ boolean incorrectLength = useStrictLength & (block.length != strictBlockSize);
+
+ byte[] data = block;
+ if (block.length < strictBlockSize)
{
data = blockBuffer;
}
- else
+
+ int plaintextLength = forPrivateKey ? checkPkcs1Encoding2(data) : checkPkcs1Encoding1(data);
+
+ try
{
- data = block;
- }
-
- byte type = data[0];
-
- boolean badType;
- if (forPrivateKey)
- {
- badType = (type != 2);
- }
- else
- {
- badType = (type != 1);
- }
-
- //
- // find and extract the message block.
- //
- int start = findStart(type, data);
-
- start++; // data should start at the next byte
-
- if (badType | start < HEADER_LENGTH)
- {
- Arrays.fill(data, (byte)0);
- throw new InvalidCipherTextException("block incorrect");
- }
-
- // if we get this far, it's likely to be a genuine encoding error
- if (incorrectLength)
- {
- Arrays.fill(data, (byte)0);
- throw new InvalidCipherTextException("block incorrect size");
- }
-
- byte[] result = new byte[data.length - start];
-
- System.arraycopy(data, start, result, 0, result.length);
-
- return result;
- }
-
- private int findStart(byte type, byte[] block)
- throws InvalidCipherTextException
- {
- int start = -1;
- boolean padErr = false;
-
- for (int i = 1; i != block.length; i++)
- {
- byte pad = block[i];
-
- if (pad == 0 & start < 0)
+ if (plaintextLength < 0)
{
- start = i;
+ throw new InvalidCipherTextException("block incorrect");
}
- padErr |= (type == 1 & start < 0 & pad != (byte)0xff);
- }
+ if (incorrectLength)
+ {
+ throw new InvalidCipherTextException("block incorrect size");
+ }
- if (padErr)
+ byte[] result = new byte[plaintextLength];
+ System.arraycopy(data, data.length - plaintextLength, result, 0, plaintextLength);
+ return result;
+ }
+ finally
{
- return -1;
+ Arrays.fill(block, (byte)0);
+ Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0);
}
-
- return start;
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java
index 1ad46f6..513faf7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java
@@ -1,10 +1,13 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.engines;
-import com.android.internal.org.bouncycastle.crypto.BlockCipher;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.DefaultMultiBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.MultiBlockCipher;
import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
import com.android.internal.org.bouncycastle.util.Arrays;
import com.android.internal.org.bouncycastle.util.Pack;
@@ -15,7 +18,7 @@
* For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
- * <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
+ * <a href="https://fp.gladman.plus.com/cryptography_technology/rijndael/">https://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
*
* There are three levels of tradeoff of speed vs memory
* Because java has no preprocessor, they are written as three separate classes from which to choose
@@ -34,7 +37,7 @@
*
*/
public class AESEngine
- implements BlockCipher
+ extends DefaultMultiBlockCipher
{
// The S box
private static final byte[] S = {
@@ -414,7 +417,6 @@
private int ROUNDS;
private int[][] WorkingKey = null;
- private int C0, C1, C2, C3;
private boolean forEncryption;
private byte[] s;
@@ -422,10 +424,22 @@
private static final int BLOCK_SIZE = 16;
/**
+ * Return an AESEngine.
+ *
+ * @return an AES ECB mode cipher.
+ */
+ public static MultiBlockCipher newInstance()
+ {
+ return new AESEngine();
+ }
+
+ /**
* default constructor - 128 bit block size.
+ * @deprecated use AESEngine.newInstance()
*/
public AESEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 256));
}
/**
@@ -452,6 +466,9 @@
{
s = Arrays.clone(Si);
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, Utils.getPurpose(forEncryption)));
+
return;
}
@@ -468,38 +485,30 @@
return BLOCK_SIZE;
}
- public int processBlock(
- byte[] in,
- int inOff,
- byte[] out,
- int outOff)
+ public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
{
if (WorkingKey == null)
{
throw new IllegalStateException("AES engine not initialised");
}
- if ((inOff + (32 / 2)) > in.length)
+ if (inOff > (in.length - BLOCK_SIZE))
{
throw new DataLengthException("input buffer too short");
}
- if ((outOff + (32 / 2)) > out.length)
+ if (outOff > (out.length - BLOCK_SIZE))
{
throw new OutputLengthException("output buffer too short");
}
if (forEncryption)
{
- unpackBlock(in, inOff);
- encryptBlock(WorkingKey);
- packBlock(out, outOff);
+ encryptBlock(in, inOff, out, outOff, WorkingKey);
}
else
{
- unpackBlock(in, inOff);
- decryptBlock(WorkingKey);
- packBlock(out, outOff);
+ decryptBlock(in, inOff, out, outOff, WorkingKey);
}
return BLOCK_SIZE;
@@ -509,68 +518,18 @@
{
}
- private void unpackBlock(
- byte[] bytes,
- int off)
+ private void encryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- int index = off;
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- C0 = (bytes[index++] & 0xff);
- C0 |= (bytes[index++] & 0xff) << 8;
- C0 |= (bytes[index++] & 0xff) << 16;
- C0 |= bytes[index++] << 24;
+ int t0 = C0 ^ KW[0][0];
+ int t1 = C1 ^ KW[0][1];
+ int t2 = C2 ^ KW[0][2];
- C1 = (bytes[index++] & 0xff);
- C1 |= (bytes[index++] & 0xff) << 8;
- C1 |= (bytes[index++] & 0xff) << 16;
- C1 |= bytes[index++] << 24;
-
- C2 = (bytes[index++] & 0xff);
- C2 |= (bytes[index++] & 0xff) << 8;
- C2 |= (bytes[index++] & 0xff) << 16;
- C2 |= bytes[index++] << 24;
-
- C3 = (bytes[index++] & 0xff);
- C3 |= (bytes[index++] & 0xff) << 8;
- C3 |= (bytes[index++] & 0xff) << 16;
- C3 |= bytes[index++] << 24;
- }
-
- private void packBlock(
- byte[] bytes,
- int off)
- {
- int index = off;
-
- bytes[index++] = (byte)C0;
- bytes[index++] = (byte)(C0 >> 8);
- bytes[index++] = (byte)(C0 >> 16);
- bytes[index++] = (byte)(C0 >> 24);
-
- bytes[index++] = (byte)C1;
- bytes[index++] = (byte)(C1 >> 8);
- bytes[index++] = (byte)(C1 >> 16);
- bytes[index++] = (byte)(C1 >> 24);
-
- bytes[index++] = (byte)C2;
- bytes[index++] = (byte)(C2 >> 8);
- bytes[index++] = (byte)(C2 >> 16);
- bytes[index++] = (byte)(C2 >> 24);
-
- bytes[index++] = (byte)C3;
- bytes[index++] = (byte)(C3 >> 8);
- bytes[index++] = (byte)(C3 >> 16);
- bytes[index++] = (byte)(C3 >> 24);
- }
-
-
- private void encryptBlock(int[][] KW)
- {
- int t0 = this.C0 ^ KW[0][0];
- int t1 = this.C1 ^ KW[0][1];
- int t2 = this.C2 ^ KW[0][2];
-
- int r = 1, r0, r1, r2, r3 = this.C3 ^ KW[0][3];
+ int r = 1, r0, r1, r2, r3 = C3 ^ KW[0][3];
while (r < ROUNDS - 1)
{
r0 = T0[t0&255] ^ shift(T0[(t1>>8)&255], 24) ^ shift(T0[(t2>>16)&255], 16) ^ shift(T0[(r3>>24)&255], 8) ^ KW[r][0];
@@ -590,19 +549,29 @@
// the final round's table is a simple function of S so we don't use a whole other four tables for it
- this.C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[r][0];
- this.C1 = (s[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[r][1];
- this.C2 = (s[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2];
- this.C3 = (s[r3&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3];
+ C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[r][0];
+ C1 = (s[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[r][1];
+ C2 = (s[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2];
+ C3 = (s[r3&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
}
- private void decryptBlock(int[][] KW)
+ private void decryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- int t0 = this.C0 ^ KW[ROUNDS][0];
- int t1 = this.C1 ^ KW[ROUNDS][1];
- int t2 = this.C2 ^ KW[ROUNDS][2];
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- int r = ROUNDS - 1, r0, r1, r2, r3 = this.C3 ^ KW[ROUNDS][3];
+ int t0 = C0 ^ KW[ROUNDS][0];
+ int t1 = C1 ^ KW[ROUNDS][1];
+ int t2 = C2 ^ KW[ROUNDS][2];
+
+ int r = ROUNDS - 1, r0, r1, r2, r3 = C3 ^ KW[ROUNDS][3];
while (r > 1)
{
r0 = Tinv0[t0&255] ^ shift(Tinv0[(r3>>8)&255], 24) ^ shift(Tinv0[(t2>>16)&255], 16) ^ shift(Tinv0[(t1>>24)&255], 8) ^ KW[r][0];
@@ -622,9 +591,23 @@
// the final round's table is a simple function of Si so we don't use a whole other four tables for it
- this.C0 = (Si[r0&255]&255) ^ ((s[(r3>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0];
- this.C1 = (s[r1&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (s[(r2>>24)&255]<<24) ^ KW[0][1];
- this.C2 = (s[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[0][2];
- this.C3 = (Si[r3&255]&255) ^ ((s[(r2>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[0][3];
+ C0 = (Si[r0&255]&255) ^ ((s[(r3>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0];
+ C1 = (s[r1&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (s[(r2>>24)&255]<<24) ^ KW[0][1];
+ C2 = (s[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[0][2];
+ C3 = (Si[r3&255]&255) ^ ((s[(r2>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[0][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
+ }
+
+ private int bitsOfSecurity()
+ {
+ if (WorkingKey == null)
+ {
+ return 256;
+ }
+ return (WorkingKey.length - 7) << 5;
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java
index 71345c1..82cf0a6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java
@@ -3,8 +3,10 @@
import com.android.internal.org.bouncycastle.crypto.BlockCipher;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
import com.android.internal.org.bouncycastle.util.Pack;
@@ -14,7 +16,7 @@
* For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
- * <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
+ * <a href="https://fp.gladman.plus.com/cryptography_technology/rijndael/">https://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
*
* There are three levels of tradeoff of speed vs memory
* Because java has no preprocessor, they are written as three separate classes from which to choose
@@ -743,7 +745,6 @@
private int ROUNDS;
private int[][] WorkingKey = null;
- private int C0, C1, C2, C3;
private boolean forEncryption;
private static final int BLOCK_SIZE = 16;
@@ -753,6 +754,7 @@
*/
public AESFastEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 256));
}
/**
@@ -771,6 +773,7 @@
{
WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption);
this.forEncryption = forEncryption;
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, Utils.getPurpose(forEncryption)));
return;
}
@@ -787,40 +790,32 @@
return BLOCK_SIZE;
}
- public int processBlock(
- byte[] in,
- int inOff,
- byte[] out,
- int outOff)
+ public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
{
if (WorkingKey == null)
{
throw new IllegalStateException("AES engine not initialised");
}
- if ((inOff + (32 / 2)) > in.length)
+ if (inOff > (in.length - BLOCK_SIZE))
{
throw new DataLengthException("input buffer too short");
}
- if ((outOff + (32 / 2)) > out.length)
+ if (outOff > (out.length - BLOCK_SIZE))
{
throw new OutputLengthException("output buffer too short");
}
- unpackBlock(in, inOff);
-
if (forEncryption)
{
- encryptBlock(WorkingKey);
+ encryptBlock(in, inOff, out, outOff, WorkingKey);
}
else
{
- decryptBlock(WorkingKey);
+ decryptBlock(in, inOff, out, outOff, WorkingKey);
}
- packBlock(out, outOff);
-
return BLOCK_SIZE;
}
@@ -828,27 +823,16 @@
{
}
- private void unpackBlock(byte[] bytes, int off)
+ private void encryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- this.C0 = Pack.littleEndianToInt(bytes, off);
- this.C1 = Pack.littleEndianToInt(bytes, off + 4);
- this.C2 = Pack.littleEndianToInt(bytes, off + 8);
- this.C3 = Pack.littleEndianToInt(bytes, off + 12);
- }
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- private void packBlock(byte[] bytes, int off)
- {
- Pack.intToLittleEndian(this.C0, bytes, off);
- Pack.intToLittleEndian(this.C1, bytes, off + 4);
- Pack.intToLittleEndian(this.C2, bytes, off + 8);
- Pack.intToLittleEndian(this.C3, bytes, off + 12);
- }
-
- private void encryptBlock(int[][] KW)
- {
- int t0 = this.C0 ^ KW[0][0];
- int t1 = this.C1 ^ KW[0][1];
- int t2 = this.C2 ^ KW[0][2];
+ int t0 = C0 ^ KW[0][0];
+ int t1 = C1 ^ KW[0][1];
+ int t2 = C2 ^ KW[0][2];
/*
* Fast engine has precomputed rotr(T0, 8/16/24) tables T1/T2/T3.
@@ -857,7 +841,7 @@
* avoids additional array range checks on 3 more arrays (which on HotSpot are more
* expensive than the offset additions).
*/
- int r = 1, r0, r1, r2, r3 = this.C3 ^ KW[0][3];
+ int r = 1, r0, r1, r2, r3 = C3 ^ KW[0][3];
int i0, i1, i2, i3;
while (r < ROUNDS - 1)
@@ -915,28 +899,38 @@
i0 = r0; i1 = r1 >>> 8; i2 = r2 >>> 16; i3 = r3 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][0];
+ C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][0];
i0 = r1; i1 = r2 >>> 8; i2 = r3 >>> 16; i3 = r0 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][1];
+ C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][1];
i0 = r2; i1 = r3 >>> 8; i2 = r0 >>> 16; i3 = r1 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][2];
+ C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][2];
i0 = r3; i1 = r0 >>> 8; i2 = r1 >>> 16; i3 = r2 >>> 24;
i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
- this.C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][3];
+ C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
}
- private void decryptBlock(int[][] KW)
+ private void decryptBlock(byte[] in, int inOff, byte[] out, int outOff, int[][] KW)
{
- int t0 = this.C0 ^ KW[ROUNDS][0];
- int t1 = this.C1 ^ KW[ROUNDS][1];
- int t2 = this.C2 ^ KW[ROUNDS][2];
+ int C0 = Pack.littleEndianToInt(in, inOff + 0);
+ int C1 = Pack.littleEndianToInt(in, inOff + 4);
+ int C2 = Pack.littleEndianToInt(in, inOff + 8);
+ int C3 = Pack.littleEndianToInt(in, inOff + 12);
- int r = ROUNDS - 1, r0, r1, r2, r3 = this.C3 ^ KW[ROUNDS][3];
+ int t0 = C0 ^ KW[ROUNDS][0];
+ int t1 = C1 ^ KW[ROUNDS][1];
+ int t2 = C2 ^ KW[ROUNDS][2];
+
+ int r = ROUNDS - 1, r0, r1, r2, r3 = C3 ^ KW[ROUNDS][3];
int i0, i1, i2, i3;
while (r > 1)
@@ -994,18 +988,33 @@
i0 = r0; i1 = r3 >>> 8; i2 = r2 >>> 16; i3 = r1 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][0];
+ C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][0];
i0 = r1; i1 = r0 >>> 8; i2 = r3 >>> 16; i3 = r2 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][1];
+ C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][1];
i0 = r2; i1 = r1 >>> 8; i2 = r0 >>> 16; i3 = r3 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][2];
+ C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][2];
i0 = r3; i1 = r2 >>> 8; i2 = r1 >>> 16; i3 = r0 >>> 24;
i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
- this.C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][3];
+ C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][3];
+
+ Pack.intToLittleEndian(C0, out, outOff + 0);
+ Pack.intToLittleEndian(C1, out, outOff + 4);
+ Pack.intToLittleEndian(C2, out, outOff + 8);
+ Pack.intToLittleEndian(C3, out, outOff + 12);
+ }
+
+ // Service Definitions
+ private int bitsOfSecurity()
+ {
+ if (WorkingKey == null)
+ {
+ return 256;
+ }
+ return (WorkingKey.length - 7) << 5;
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java
index 2b45af8..1b921ee 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java
@@ -16,16 +16,16 @@
*/
public AESWrapEngine()
{
- super(new AESEngine());
+ super(AESEngine.newInstance());
}
/**
- * Create an AESWrapEngine where the underlying cipher is set to decrypt for wrapping, encrypt for unwrapping.
+ * Create an AESWrapEngine where the underlying cipher is (optionally) set to decrypt for wrapping, encrypt for unwrapping.
*
* @param useReverseDirection true if underlying cipher should be used in decryption mode, false otherwise.
*/
public AESWrapEngine(boolean useReverseDirection)
{
- super(new AESEngine(), useReverseDirection);
+ super(AESEngine.newInstance(), useReverseDirection);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AsconEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AsconEngine.java
new file mode 100644
index 0000000..1350758
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AsconEngine.java
@@ -0,0 +1,743 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.modes.AEADCipher;
+import com.android.internal.org.bouncycastle.crypto.params.AEADParameters;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Longs;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * ASCON AEAD v1.2, https://ascon.iaik.tugraz.at/
+ * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf
+ * <p>
+ * ASCON AEAD v1.2 with reference to C Reference Impl from: https://github.com/ascon/ascon-c
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AsconEngine
+ implements AEADCipher
+{
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public enum AsconParameters
+ {
+ ascon80pq,
+ ascon128a,
+ ascon128
+ }
+
+ private enum State
+ {
+ Uninitialized,
+ EncInit,
+ EncAad,
+ EncData,
+ EncFinal,
+ DecInit,
+ DecAad,
+ DecData,
+ DecFinal,
+ }
+
+ private final AsconParameters asconParameters;
+ private State m_state = State.Uninitialized;
+ private byte[] mac;
+ private byte[] initialAssociatedText;
+ private final String algorithmName;
+ private final int CRYPTO_KEYBYTES;
+ private final int CRYPTO_ABYTES;
+ private final int ASCON_AEAD_RATE;
+ private final int nr;
+ private long K0;
+ private long K1;
+ private long K2;
+ private long N0;
+ private long N1;
+ private final long ASCON_IV;
+ private long x0;
+ private long x1;
+ private long x2;
+ private long x3;
+ private long x4;
+ private final int m_bufferSizeDecrypt;
+ private final byte[] m_buf;
+ private int m_bufPos = 0;
+
+ public AsconEngine(AsconParameters asconParameters)
+ {
+ this.asconParameters = asconParameters;
+ switch (asconParameters)
+ {
+ case ascon80pq:
+ CRYPTO_KEYBYTES = 20;
+ CRYPTO_ABYTES = 16;
+ ASCON_AEAD_RATE = 8;
+ ASCON_IV = 0xa0400c0600000000L;
+ algorithmName = "Ascon-80pq AEAD";
+ break;
+ case ascon128a:
+ CRYPTO_KEYBYTES = 16;
+ CRYPTO_ABYTES = 16;
+ ASCON_AEAD_RATE = 16;
+ ASCON_IV = 0x80800c0800000000L;
+ algorithmName = "Ascon-128a AEAD";
+ break;
+ case ascon128:
+ CRYPTO_KEYBYTES = 16;
+ CRYPTO_ABYTES = 16;
+ ASCON_AEAD_RATE = 8;
+ ASCON_IV = 0x80400c0600000000L;
+ algorithmName = "Ascon-128 AEAD";
+ break;
+ default:
+ throw new IllegalArgumentException("invalid parameter setting for ASCON AEAD");
+ }
+ nr = (ASCON_AEAD_RATE == 8) ? 6 : 8;
+ m_bufferSizeDecrypt = ASCON_AEAD_RATE + CRYPTO_ABYTES;
+ m_buf = new byte[m_bufferSizeDecrypt];
+ }
+
+ private long PAD(int i)
+ {
+ return 0x80L << (56 - (i << 3));
+ }
+
+ private void ROUND(long C)
+ {
+ long t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
+ long t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
+ long t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
+ long t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
+ long t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
+ x0 = t0 ^ Longs.rotateRight(t0, 19) ^ Longs.rotateRight(t0, 28);
+ x1 = t1 ^ Longs.rotateRight(t1, 39) ^ Longs.rotateRight(t1, 61);
+ x2 = ~(t2 ^ Longs.rotateRight(t2, 1) ^ Longs.rotateRight(t2, 6));
+ x3 = t3 ^ Longs.rotateRight(t3, 10) ^ Longs.rotateRight(t3, 17);
+ x4 = t4 ^ Longs.rotateRight(t4, 7) ^ Longs.rotateRight(t4, 41);
+ }
+
+ private void P(int nr)
+ {
+ if (nr >= 8)
+ {
+ if (nr == 12)
+ {
+ ROUND(0xf0L);
+ ROUND(0xe1L);
+ ROUND(0xd2L);
+ ROUND(0xc3L);
+ }
+ ROUND(0xb4L);
+ ROUND(0xa5L);
+ }
+ ROUND(0x96L);
+ ROUND(0x87L);
+ ROUND(0x78L);
+ ROUND(0x69L);
+ ROUND(0x5aL);
+ ROUND(0x4bL);
+ }
+
+ private void ascon_aeadinit()
+ {
+ /* initialize */
+ x0 = ASCON_IV;
+ if (CRYPTO_KEYBYTES == 20)
+ {
+ x0 ^= K0;
+ }
+ x1 = K1;
+ x2 = K2;
+ x3 = N0;
+ x4 = N1;
+ P(12);
+ if (CRYPTO_KEYBYTES == 20)
+ {
+ x2 ^= K0;
+ }
+ x3 ^= K1;
+ x4 ^= K2;
+ }
+
+ private void checkAAD()
+ {
+ switch (m_state)
+ {
+ case DecInit:
+ m_state = State.DecAad;
+ break;
+ case EncInit:
+ m_state = State.EncAad;
+ break;
+ case DecAad:
+ case EncAad:
+ break;
+ case EncFinal:
+ throw new IllegalStateException(getAlgorithmName() + " cannot be reused for encryption");
+ default:
+ throw new IllegalStateException(getAlgorithmName() + " needs to be initialized");
+ }
+ }
+
+ private boolean checkData()
+ {
+ switch (m_state)
+ {
+ case DecInit:
+ case DecAad:
+ finishAAD(State.DecData);
+ return false;
+ case EncInit:
+ case EncAad:
+ finishAAD(State.EncData);
+ return true;
+ case DecData:
+ return false;
+ case EncData:
+ return true;
+ case EncFinal:
+ throw new IllegalStateException(getAlgorithmName() + " cannot be reused for encryption");
+ default:
+ throw new IllegalStateException(getAlgorithmName() + " needs to be initialized");
+ }
+ }
+
+ private void processBufferAAD(byte[] buffer, int inOff)
+ {
+ x0 ^= Pack.bigEndianToLong(buffer, inOff);
+ if (ASCON_AEAD_RATE == 16)
+ {
+ x1 ^= Pack.bigEndianToLong(buffer, 8 + inOff);
+ }
+ P(nr);
+ }
+
+ private void finishAAD(State nextState)
+ {
+ // State indicates whether we ever received AAD
+ switch (m_state)
+ {
+ case DecAad:
+ case EncAad:
+ m_buf[m_bufPos] = (byte)0x80;
+ if (m_bufPos >= 8) // ASCON_AEAD_RATE == 16 is implied
+ {
+ x0 ^= Pack.bigEndianToLong(m_buf, 0);
+ x1 ^= Pack.bigEndianToLong(m_buf, 8) & (-1L << (56 - ((m_bufPos - 8) << 3)));
+ }
+ else
+ {
+ x0 ^= Pack.bigEndianToLong(m_buf, 0) & (-1L << (56 - (m_bufPos << 3)));
+ }
+ P(nr);
+ break;
+ default:
+ break;
+ }
+ // domain separation
+ x4 ^= 1L;
+ m_bufPos = 0;
+ m_state = nextState;
+ }
+
+ private void processBufferDecrypt(byte[] buffer, int bufOff, byte[] output, int outOff)
+ {
+ if (outOff + ASCON_AEAD_RATE > output.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ long t0 = Pack.bigEndianToLong(buffer, bufOff);
+ Pack.longToBigEndian(x0 ^ t0, output, outOff);
+ x0 = t0;
+
+ if (ASCON_AEAD_RATE == 16)
+ {
+ long t1 = Pack.bigEndianToLong(buffer, bufOff + 8);
+ Pack.longToBigEndian(x1 ^ t1, output, outOff + 8);
+ x1 = t1;
+ }
+ P(nr);
+ }
+
+ private void processBufferEncrypt(byte[] buffer, int bufOff, byte[] output, int outOff)
+ {
+ if (outOff + ASCON_AEAD_RATE > output.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ x0 ^= Pack.bigEndianToLong(buffer, bufOff);
+ Pack.longToBigEndian(x0, output, outOff);
+
+ if (ASCON_AEAD_RATE == 16)
+ {
+ x1 ^= Pack.bigEndianToLong(buffer, bufOff + 8);
+ Pack.longToBigEndian(x1, output, outOff + 8);
+ }
+
+ P(nr);
+ }
+
+ private void processFinalDecrypt(byte[] input, int inOff, int inLen, byte[] output, int outOff)
+ {
+ if (inLen >= 8) // ASCON_AEAD_RATE == 16 is implied
+ {
+ long c0 = Pack.bigEndianToLong(input, inOff);
+ x0 ^= c0;
+ Pack.longToBigEndian(x0, output, outOff);
+ x0 = c0;
+ inOff += 8;
+ outOff += 8;
+ inLen -= 8;
+ x1 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ long c1 = Pack.littleEndianToLong_High(input, inOff, inLen);
+ x1 ^= c1;
+ Pack.longToLittleEndian_High(x1, output, outOff, inLen);
+ x1 &= -1L >>> (inLen << 3);
+ x1 ^= c1;
+ }
+ }
+ else
+ {
+ x0 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ long c0 = Pack.littleEndianToLong_High(input, inOff, inLen);
+ x0 ^= c0;
+ Pack.longToLittleEndian_High(x0, output, outOff, inLen);
+ x0 &= -1L >>> (inLen << 3);
+ x0 ^= c0;
+ }
+ }
+
+ finishData(State.DecFinal);
+ }
+
+ private void processFinalEncrypt(byte[] input, int inOff, int inLen, byte[] output, int outOff)
+ {
+ if (inLen >= 8) // ASCON_AEAD_RATE == 16 is implied
+ {
+ x0 ^= Pack.bigEndianToLong(input, inOff);
+ Pack.longToBigEndian(x0, output, outOff);
+ inOff += 8;
+ outOff += 8;
+ inLen -= 8;
+ x1 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ x1 ^= Pack.littleEndianToLong_High(input, inOff, inLen);
+ Pack.longToLittleEndian_High(x1, output, outOff, inLen);
+ }
+ }
+ else
+ {
+ x0 ^= PAD(inLen);
+ if (inLen != 0)
+ {
+ x0 ^= Pack.littleEndianToLong_High(input, inOff, inLen);
+ Pack.longToLittleEndian_High(x0, output, outOff, inLen);
+ }
+ }
+ finishData(State.EncFinal);
+ }
+
+ private void finishData(State nextState)
+ {
+ switch (asconParameters)
+ {
+ case ascon128:
+ x1 ^= K1;
+ x2 ^= K2;
+ break;
+ case ascon128a:
+ x2 ^= K1;
+ x3 ^= K2;
+ break;
+ case ascon80pq:
+ x1 ^= (K0 << 32 | K1 >> 32);
+ x2 ^= (K1 << 32 | K2 >> 32);
+ x3 ^= K2 << 32;
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ P(12);
+ x3 ^= K1;
+ x4 ^= K2;
+
+ m_state = nextState;
+ }
+
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException
+ {
+ KeyParameter key;
+ byte[] npub;
+ if (params instanceof AEADParameters)
+ {
+ AEADParameters aeadParameters = (AEADParameters)params;
+ key = aeadParameters.getKey();
+ npub = aeadParameters.getNonce();
+ initialAssociatedText = aeadParameters.getAssociatedText();
+
+ int macSizeBits = aeadParameters.getMacSize();
+ if (macSizeBits != CRYPTO_ABYTES * 8)
+ {
+ throw new IllegalArgumentException("Invalid value for MAC size: " + macSizeBits);
+ }
+ }
+ else if (params instanceof ParametersWithIV)
+ {
+ ParametersWithIV withIV = (ParametersWithIV)params;
+ key = (KeyParameter)withIV.getParameters();
+ npub = withIV.getIV();
+ initialAssociatedText = null;
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid parameters passed to Ascon");
+ }
+
+ if (key == null)
+ {
+ throw new IllegalArgumentException("Ascon Init parameters must include a key");
+ }
+ if (npub == null || npub.length != CRYPTO_ABYTES)
+ {
+ throw new IllegalArgumentException(asconParameters + " requires exactly " + CRYPTO_ABYTES + " bytes of IV");
+ }
+
+ byte[] k = key.getKey();
+ if (k.length != CRYPTO_KEYBYTES)
+ {
+ throw new IllegalArgumentException(asconParameters + " key must be " + CRYPTO_KEYBYTES + " bytes long");
+ }
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(
+ this.getAlgorithmName(), 128, params, Utils.getPurpose(forEncryption)));
+ N0 = Pack.bigEndianToLong(npub, 0);
+ N1 = Pack.bigEndianToLong(npub, 8);
+ if (CRYPTO_KEYBYTES == 16)
+ {
+ K1 = Pack.bigEndianToLong(k, 0);
+ K2 = Pack.bigEndianToLong(k, 8);
+ }
+ else if (CRYPTO_KEYBYTES == 20)
+ {
+ K0 = Pack.bigEndianToInt(k, 0);
+ K1 = Pack.bigEndianToLong(k, 4);
+ K2 = Pack.bigEndianToLong(k, 12);
+ }
+ else
+ {
+ throw new IllegalStateException();
+ }
+
+ m_state = forEncryption ? State.EncInit : State.DecInit;
+
+ reset(true);
+ }
+
+ public String getAlgorithmName()
+ {
+ return algorithmName;
+ }
+
+ public String getAlgorithmVersion()
+ {
+ return "v1.2";
+ }
+
+ public void processAADByte(byte in)
+ {
+ checkAAD();
+ m_buf[m_bufPos] = in;
+ if (++m_bufPos == ASCON_AEAD_RATE)
+ {
+ processBufferAAD(m_buf, 0);
+ }
+ }
+
+ public void processAADBytes(byte[] inBytes, int inOff, int len)
+ {
+ if ((inOff + len) > inBytes.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ // Don't enter AAD state until we actually get input
+ if (len <= 0)
+ {
+ return;
+ }
+ checkAAD();
+ if (m_bufPos > 0)
+ {
+ int available = ASCON_AEAD_RATE - m_bufPos;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return;
+ }
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, available);
+ inOff += available;
+ len -= available;
+ processBufferAAD(m_buf, 0);
+ //m_bufPos = 0;
+ }
+ while (len >= ASCON_AEAD_RATE)
+ {
+ processBufferAAD(inBytes, inOff);
+ inOff += ASCON_AEAD_RATE;
+ len -= ASCON_AEAD_RATE;
+ }
+ System.arraycopy(inBytes, inOff, m_buf, 0, len);
+ m_bufPos = len;
+ }
+
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ return processBytes(new byte[]{in}, 0, 1, out, outOff);
+ }
+
+ public int processBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff)
+ throws DataLengthException
+ {
+ if ((inOff + len) > inBytes.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ boolean forEncryption = checkData();
+ int resultLength = 0;
+
+ if (forEncryption)
+ {
+ if (m_bufPos > 0)
+ {
+ int available = ASCON_AEAD_RATE - m_bufPos;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return 0;
+ }
+
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, available);
+ inOff += available;
+ len -= available;
+
+ processBufferEncrypt(m_buf, 0, outBytes, outOff);
+ resultLength = ASCON_AEAD_RATE;
+ //m_bufPos = 0;
+ }
+
+ while (len >= ASCON_AEAD_RATE)
+ {
+ processBufferEncrypt(inBytes, inOff, outBytes, outOff + resultLength);
+ inOff += ASCON_AEAD_RATE;
+ len -= ASCON_AEAD_RATE;
+ resultLength += ASCON_AEAD_RATE;
+ }
+ }
+ else
+ {
+ int available = m_bufferSizeDecrypt - m_bufPos;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return 0;
+ }
+
+ // NOTE: Need 'while' here because ASCON_AEAD_RATE < CRYPTO_ABYTES in some parameter sets
+ while (m_bufPos >= ASCON_AEAD_RATE)
+ {
+ processBufferDecrypt(m_buf, 0, outBytes, outOff + resultLength);
+ m_bufPos -= ASCON_AEAD_RATE;
+ System.arraycopy(m_buf, ASCON_AEAD_RATE, m_buf, 0, m_bufPos);
+ resultLength += ASCON_AEAD_RATE;
+
+ available += ASCON_AEAD_RATE;
+ if (len < available)
+ {
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, len);
+ m_bufPos += len;
+ return resultLength;
+ }
+ }
+
+ available = ASCON_AEAD_RATE - m_bufPos;
+ System.arraycopy(inBytes, inOff, m_buf, m_bufPos, available);
+ inOff += available;
+ len -= available;
+ processBufferDecrypt(m_buf, 0, outBytes, outOff + resultLength);
+ resultLength += ASCON_AEAD_RATE;
+ //m_bufPos = 0;
+
+ while (len >= m_bufferSizeDecrypt)
+ {
+ processBufferDecrypt(inBytes, inOff, outBytes, outOff + resultLength);
+ inOff += ASCON_AEAD_RATE;
+ len -= ASCON_AEAD_RATE;
+ resultLength += ASCON_AEAD_RATE;
+ }
+ }
+
+ System.arraycopy(inBytes, inOff, m_buf, 0, len);
+ m_bufPos = len;
+
+ return resultLength;
+ }
+
+ public int doFinal(byte[] outBytes, int outOff)
+ throws IllegalStateException, InvalidCipherTextException, DataLengthException
+ {
+ boolean forEncryption = checkData();
+ int resultLength;
+ if (forEncryption)
+ {
+ resultLength = m_bufPos + CRYPTO_ABYTES;
+ if (outOff + resultLength > outBytes.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ processFinalEncrypt(m_buf, 0, m_bufPos, outBytes, outOff);
+ mac = new byte[CRYPTO_ABYTES];
+ Pack.longToBigEndian(x3, mac, 0);
+ Pack.longToBigEndian(x4, mac, 8);
+ System.arraycopy(mac, 0, outBytes, outOff + m_bufPos, CRYPTO_ABYTES);
+ reset(false);
+ }
+ else
+ {
+ if (m_bufPos < CRYPTO_ABYTES)
+ {
+ throw new InvalidCipherTextException("data too short");
+ }
+ m_bufPos -= CRYPTO_ABYTES;
+ resultLength = m_bufPos;
+ if (outOff + resultLength > outBytes.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ processFinalDecrypt(m_buf, 0, m_bufPos, outBytes, outOff);
+ x3 ^= Pack.bigEndianToLong(m_buf, m_bufPos);
+ x4 ^= Pack.bigEndianToLong(m_buf, m_bufPos + 8);
+ if ((x3 | x4) != 0L)
+ {
+ throw new InvalidCipherTextException("mac check in " + getAlgorithmName() + " failed");
+ }
+ reset(true);
+ }
+ return resultLength;
+ }
+
+ public byte[] getMac()
+ {
+ return mac;
+ }
+
+ public int getUpdateOutputSize(int len)
+ {
+ int total = Math.max(0, len);
+ switch (m_state)
+ {
+ case DecInit:
+ case DecAad:
+ total = Math.max(0, total - CRYPTO_ABYTES);
+ break;
+ case DecData:
+ case DecFinal:
+ total = Math.max(0, total + m_bufPos - CRYPTO_ABYTES);
+ break;
+ case EncData:
+ case EncFinal:
+ total += m_bufPos;
+ break;
+ default:
+ break;
+ }
+ return total - total % ASCON_AEAD_RATE;
+ }
+
+ public int getOutputSize(int len)
+ {
+ int total = Math.max(0, len);
+
+ switch (m_state)
+ {
+ case DecInit:
+ case DecAad:
+ return Math.max(0, total - CRYPTO_ABYTES);
+ case DecData:
+ case DecFinal:
+ return Math.max(0, total + m_bufPos - CRYPTO_ABYTES);
+ case EncData:
+ case EncFinal:
+ return total + m_bufPos + CRYPTO_ABYTES;
+ default:
+ return total + CRYPTO_ABYTES;
+ }
+ }
+
+ public void reset()
+ {
+ reset(true);
+ }
+
+ private void reset(boolean clearMac)
+ {
+ if (clearMac)
+ {
+ mac = null;
+ }
+ Arrays.clear(m_buf);
+ m_bufPos = 0;
+
+ switch (m_state)
+ {
+ case DecInit:
+ case EncInit:
+ break;
+ case DecAad:
+ case DecData:
+ case DecFinal:
+ m_state = State.DecInit;
+ break;
+ case EncAad:
+ case EncData:
+ case EncFinal:
+ m_state = State.EncFinal;
+ return;
+ default:
+ throw new IllegalStateException(getAlgorithmName() + " needs to be initialized");
+ }
+ ascon_aeadinit();
+ if (initialAssociatedText != null)
+ {
+ processAADBytes(initialAssociatedText, 0, initialAssociatedText.length);
+ }
+ }
+
+ public int getKeyBytesSize()
+ {
+ return CRYPTO_KEYBYTES;
+ }
+
+ public int getIVBytesSize()
+ {
+ return CRYPTO_ABYTES;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java
index adbb0d3..b4dec74 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java
@@ -3,8 +3,11 @@
import com.android.internal.org.bouncycastle.crypto.BlockCipher;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
/**
@@ -317,6 +320,7 @@
S2 = new int[SBOX_SK];
S3 = new int[SBOX_SK];
P = new int[P_SZ];
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity()));
}
/**
@@ -337,6 +341,7 @@
this.workingKey = ((KeyParameter)params).getKey();
setKey(this.workingKey);
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, getPurpose()));
return;
}
@@ -433,6 +438,11 @@
private void setKey(byte[] key)
{
+ if (key.length < 4 || key.length > 56)
+ {
+ throw new IllegalArgumentException("key length must be in range 32 to 448 bits");
+ }
+
/*
* - comments are from _Applied Crypto_, Schneier, p338
* please be careful comparing the two, AC numbers the
@@ -577,4 +587,22 @@
b[offset + 1] = (byte)(in >> 16);
b[offset] = (byte)(in >> 24);
}
+
+ private int bitsOfSecurity()
+ {
+ if (workingKey == null)
+ {
+ return 256;
+ }
+ return (workingKey.length > 32) ? 256 : workingKey.length * 8;
+ }
+
+ private CryptoServicePurpose getPurpose()
+ {
+ if (workingKey == null)
+ {
+ return CryptoServicePurpose.ANY;
+ }
+ return encrypting ? CryptoServicePurpose.ENCRYPTION : CryptoServicePurpose.DECRYPTION;
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESBase.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESBase.java
new file mode 100644
index 0000000..9d50163
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESBase.java
@@ -0,0 +1,408 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * a class that provides a basic DES engine.
+ */
+class DESBase
+{
+ protected static final int BLOCK_SIZE = 8;
+
+ /**
+ * standard constructor.
+ */
+ public DESBase()
+ {
+ }
+
+ /**
+ * what follows is mainly taken from "Applied Cryptography", by
+ * Bruce Schneier, however it also bears great resemblance to Richard
+ * Outerbridge's D3DES...
+ */
+
+// private static final short[] Df_Key =
+// {
+// 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+// 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+// 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
+// };
+
+ private static final short[] bytebit =
+ {
+ 0200, 0100, 040, 020, 010, 04, 02, 01
+ };
+
+ private static final int[] bigbyte =
+ {
+ 0x800000, 0x400000, 0x200000, 0x100000,
+ 0x80000, 0x40000, 0x20000, 0x10000,
+ 0x8000, 0x4000, 0x2000, 0x1000,
+ 0x800, 0x400, 0x200, 0x100,
+ 0x80, 0x40, 0x20, 0x10,
+ 0x8, 0x4, 0x2, 0x1
+ };
+
+ /*
+ * Use the key schedule specified in the Standard (ANSI X3.92-1981).
+ */
+
+ private static final byte[] pc1 =
+ {
+ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
+ 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
+ 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
+ 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
+ };
+
+ private static final byte[] totrot =
+ {
+ 1, 2, 4, 6, 8, 10, 12, 14,
+ 15, 17, 19, 21, 23, 25, 27, 28
+ };
+
+ private static final byte[] pc2 =
+ {
+ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
+ 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
+ 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
+ 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
+ };
+
+ private static final int[] SP1 = {
+ 0x01010400, 0x00000000, 0x00010000, 0x01010404,
+ 0x01010004, 0x00010404, 0x00000004, 0x00010000,
+ 0x00000400, 0x01010400, 0x01010404, 0x00000400,
+ 0x01000404, 0x01010004, 0x01000000, 0x00000004,
+ 0x00000404, 0x01000400, 0x01000400, 0x00010400,
+ 0x00010400, 0x01010000, 0x01010000, 0x01000404,
+ 0x00010004, 0x01000004, 0x01000004, 0x00010004,
+ 0x00000000, 0x00000404, 0x00010404, 0x01000000,
+ 0x00010000, 0x01010404, 0x00000004, 0x01010000,
+ 0x01010400, 0x01000000, 0x01000000, 0x00000400,
+ 0x01010004, 0x00010000, 0x00010400, 0x01000004,
+ 0x00000400, 0x00000004, 0x01000404, 0x00010404,
+ 0x01010404, 0x00010004, 0x01010000, 0x01000404,
+ 0x01000004, 0x00000404, 0x00010404, 0x01010400,
+ 0x00000404, 0x01000400, 0x01000400, 0x00000000,
+ 0x00010004, 0x00010400, 0x00000000, 0x01010004
+ };
+
+ private static final int[] SP2 = {
+ 0x80108020, 0x80008000, 0x00008000, 0x00108020,
+ 0x00100000, 0x00000020, 0x80100020, 0x80008020,
+ 0x80000020, 0x80108020, 0x80108000, 0x80000000,
+ 0x80008000, 0x00100000, 0x00000020, 0x80100020,
+ 0x00108000, 0x00100020, 0x80008020, 0x00000000,
+ 0x80000000, 0x00008000, 0x00108020, 0x80100000,
+ 0x00100020, 0x80000020, 0x00000000, 0x00108000,
+ 0x00008020, 0x80108000, 0x80100000, 0x00008020,
+ 0x00000000, 0x00108020, 0x80100020, 0x00100000,
+ 0x80008020, 0x80100000, 0x80108000, 0x00008000,
+ 0x80100000, 0x80008000, 0x00000020, 0x80108020,
+ 0x00108020, 0x00000020, 0x00008000, 0x80000000,
+ 0x00008020, 0x80108000, 0x00100000, 0x80000020,
+ 0x00100020, 0x80008020, 0x80000020, 0x00100020,
+ 0x00108000, 0x00000000, 0x80008000, 0x00008020,
+ 0x80000000, 0x80100020, 0x80108020, 0x00108000
+ };
+
+ private static final int[] SP3 = {
+ 0x00000208, 0x08020200, 0x00000000, 0x08020008,
+ 0x08000200, 0x00000000, 0x00020208, 0x08000200,
+ 0x00020008, 0x08000008, 0x08000008, 0x00020000,
+ 0x08020208, 0x00020008, 0x08020000, 0x00000208,
+ 0x08000000, 0x00000008, 0x08020200, 0x00000200,
+ 0x00020200, 0x08020000, 0x08020008, 0x00020208,
+ 0x08000208, 0x00020200, 0x00020000, 0x08000208,
+ 0x00000008, 0x08020208, 0x00000200, 0x08000000,
+ 0x08020200, 0x08000000, 0x00020008, 0x00000208,
+ 0x00020000, 0x08020200, 0x08000200, 0x00000000,
+ 0x00000200, 0x00020008, 0x08020208, 0x08000200,
+ 0x08000008, 0x00000200, 0x00000000, 0x08020008,
+ 0x08000208, 0x00020000, 0x08000000, 0x08020208,
+ 0x00000008, 0x00020208, 0x00020200, 0x08000008,
+ 0x08020000, 0x08000208, 0x00000208, 0x08020000,
+ 0x00020208, 0x00000008, 0x08020008, 0x00020200
+ };
+
+ private static final int[] SP4 = {
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802080, 0x00800081, 0x00800001, 0x00002001,
+ 0x00000000, 0x00802000, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00800080, 0x00800001,
+ 0x00000001, 0x00002000, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002001, 0x00002080,
+ 0x00800081, 0x00000001, 0x00002080, 0x00800080,
+ 0x00002000, 0x00802080, 0x00802081, 0x00000081,
+ 0x00800080, 0x00800001, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00000000, 0x00802000,
+ 0x00002080, 0x00800080, 0x00800081, 0x00000001,
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802081, 0x00000081, 0x00000001, 0x00002000,
+ 0x00800001, 0x00002001, 0x00802080, 0x00800081,
+ 0x00002001, 0x00002080, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002000, 0x00802080
+ };
+
+ private static final int[] SP5 = {
+ 0x00000100, 0x02080100, 0x02080000, 0x42000100,
+ 0x00080000, 0x00000100, 0x40000000, 0x02080000,
+ 0x40080100, 0x00080000, 0x02000100, 0x40080100,
+ 0x42000100, 0x42080000, 0x00080100, 0x40000000,
+ 0x02000000, 0x40080000, 0x40080000, 0x00000000,
+ 0x40000100, 0x42080100, 0x42080100, 0x02000100,
+ 0x42080000, 0x40000100, 0x00000000, 0x42000000,
+ 0x02080100, 0x02000000, 0x42000000, 0x00080100,
+ 0x00080000, 0x42000100, 0x00000100, 0x02000000,
+ 0x40000000, 0x02080000, 0x42000100, 0x40080100,
+ 0x02000100, 0x40000000, 0x42080000, 0x02080100,
+ 0x40080100, 0x00000100, 0x02000000, 0x42080000,
+ 0x42080100, 0x00080100, 0x42000000, 0x42080100,
+ 0x02080000, 0x00000000, 0x40080000, 0x42000000,
+ 0x00080100, 0x02000100, 0x40000100, 0x00080000,
+ 0x00000000, 0x40080000, 0x02080100, 0x40000100
+ };
+
+ private static final int[] SP6 = {
+ 0x20000010, 0x20400000, 0x00004000, 0x20404010,
+ 0x20400000, 0x00000010, 0x20404010, 0x00400000,
+ 0x20004000, 0x00404010, 0x00400000, 0x20000010,
+ 0x00400010, 0x20004000, 0x20000000, 0x00004010,
+ 0x00000000, 0x00400010, 0x20004010, 0x00004000,
+ 0x00404000, 0x20004010, 0x00000010, 0x20400010,
+ 0x20400010, 0x00000000, 0x00404010, 0x20404000,
+ 0x00004010, 0x00404000, 0x20404000, 0x20000000,
+ 0x20004000, 0x00000010, 0x20400010, 0x00404000,
+ 0x20404010, 0x00400000, 0x00004010, 0x20000010,
+ 0x00400000, 0x20004000, 0x20000000, 0x00004010,
+ 0x20000010, 0x20404010, 0x00404000, 0x20400000,
+ 0x00404010, 0x20404000, 0x00000000, 0x20400010,
+ 0x00000010, 0x00004000, 0x20400000, 0x00404010,
+ 0x00004000, 0x00400010, 0x20004010, 0x00000000,
+ 0x20404000, 0x20000000, 0x00400010, 0x20004010
+ };
+
+ private static final int[] SP7 = {
+ 0x00200000, 0x04200002, 0x04000802, 0x00000000,
+ 0x00000800, 0x04000802, 0x00200802, 0x04200800,
+ 0x04200802, 0x00200000, 0x00000000, 0x04000002,
+ 0x00000002, 0x04000000, 0x04200002, 0x00000802,
+ 0x04000800, 0x00200802, 0x00200002, 0x04000800,
+ 0x04000002, 0x04200000, 0x04200800, 0x00200002,
+ 0x04200000, 0x00000800, 0x00000802, 0x04200802,
+ 0x00200800, 0x00000002, 0x04000000, 0x00200800,
+ 0x04000000, 0x00200800, 0x00200000, 0x04000802,
+ 0x04000802, 0x04200002, 0x04200002, 0x00000002,
+ 0x00200002, 0x04000000, 0x04000800, 0x00200000,
+ 0x04200800, 0x00000802, 0x00200802, 0x04200800,
+ 0x00000802, 0x04000002, 0x04200802, 0x04200000,
+ 0x00200800, 0x00000000, 0x00000002, 0x04200802,
+ 0x00000000, 0x00200802, 0x04200000, 0x00000800,
+ 0x04000002, 0x04000800, 0x00000800, 0x00200002
+ };
+
+ private static final int[] SP8 = {
+ 0x10001040, 0x00001000, 0x00040000, 0x10041040,
+ 0x10000000, 0x10001040, 0x00000040, 0x10000000,
+ 0x00040040, 0x10040000, 0x10041040, 0x00041000,
+ 0x10041000, 0x00041040, 0x00001000, 0x00000040,
+ 0x10040000, 0x10000040, 0x10001000, 0x00001040,
+ 0x00041000, 0x00040040, 0x10040040, 0x10041000,
+ 0x00001040, 0x00000000, 0x00000000, 0x10040040,
+ 0x10000040, 0x10001000, 0x00041040, 0x00040000,
+ 0x00041040, 0x00040000, 0x10041000, 0x00001000,
+ 0x00000040, 0x10040040, 0x00001000, 0x00041040,
+ 0x10001000, 0x00000040, 0x10000040, 0x10040000,
+ 0x10040040, 0x10000000, 0x00040000, 0x10001040,
+ 0x00000000, 0x10041040, 0x00040040, 0x10000040,
+ 0x10040000, 0x10001000, 0x10001040, 0x00000000,
+ 0x10041040, 0x00041000, 0x00041000, 0x00001040,
+ 0x00001040, 0x00040040, 0x10000000, 0x10041000
+ };
+
+ /**
+ * generate an integer based working key based on our secret key
+ * and what we processing we are planning to do.
+ *
+ * Acknowledgements for this routine go to James Gillogly & Phil Karn.
+ * (whoever, and wherever they are!).
+ */
+ protected int[] generateWorkingKey(
+ boolean encrypting,
+ byte[] key)
+ {
+ int[] newKey = new int[32];
+ boolean[] pc1m = new boolean[56],
+ pcr = new boolean[56];
+
+ for (int j = 0; j < 56; j++)
+ {
+ int l = pc1[j];
+
+ pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0);
+ }
+
+ for (int i = 0; i < 16; i++)
+ {
+ int l, m, n;
+
+ if (encrypting)
+ {
+ m = i << 1;
+ }
+ else
+ {
+ m = (15 - i) << 1;
+ }
+
+ n = m + 1;
+ newKey[m] = newKey[n] = 0;
+
+ for (int j = 0; j < 28; j++)
+ {
+ l = j + totrot[i];
+ if (l < 28)
+ {
+ pcr[j] = pc1m[l];
+ }
+ else
+ {
+ pcr[j] = pc1m[l - 28];
+ }
+ }
+
+ for (int j = 28; j < 56; j++)
+ {
+ l = j + totrot[i];
+ if (l < 56)
+ {
+ pcr[j] = pc1m[l];
+ }
+ else
+ {
+ pcr[j] = pc1m[l - 28];
+ }
+ }
+
+ for (int j = 0; j < 24; j++)
+ {
+ if (pcr[pc2[j]])
+ {
+ newKey[m] |= bigbyte[j];
+ }
+
+ if (pcr[pc2[j + 24]])
+ {
+ newKey[n] |= bigbyte[j];
+ }
+ }
+ }
+
+ //
+ // store the processed key
+ //
+ for (int i = 0; i != 32; i += 2)
+ {
+ int i1, i2;
+
+ i1 = newKey[i];
+ i2 = newKey[i + 1];
+
+ newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10)
+ | ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6);
+
+ newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16)
+ | ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f);
+ }
+
+ return newKey;
+ }
+
+ /**
+ * the DES engine.
+ */
+ protected void desFunc(
+ int[] wKey,
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ int work, right, left;
+
+ left = Pack.bigEndianToInt(in, inOff);
+ right = Pack.bigEndianToInt(in, inOff + 4);
+
+ work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
+ right ^= work;
+ left ^= (work << 4);
+ work = ((left >>> 16) ^ right) & 0x0000ffff;
+ right ^= work;
+ left ^= (work << 16);
+ work = ((right >>> 2) ^ left) & 0x33333333;
+ left ^= work;
+ right ^= (work << 2);
+ work = ((right >>> 8) ^ left) & 0x00ff00ff;
+ left ^= work;
+ right ^= (work << 8);
+ right = (right << 1) | (right >>> 31);
+ work = (left ^ right) & 0xaaaaaaaa;
+ left ^= work;
+ right ^= work;
+ left = (left << 1) | (left >>> 31);
+
+ for (int round = 0; round < 8; round++)
+ {
+ int fval;
+
+ work = (right << 28) | (right >>> 4);
+ work ^= wKey[round * 4 + 0];
+ fval = SP7[ work & 0x3f];
+ fval |= SP5[(work >>> 8) & 0x3f];
+ fval |= SP3[(work >>> 16) & 0x3f];
+ fval |= SP1[(work >>> 24) & 0x3f];
+ work = right ^ wKey[round * 4 + 1];
+ fval |= SP8[ work & 0x3f];
+ fval |= SP6[(work >>> 8) & 0x3f];
+ fval |= SP4[(work >>> 16) & 0x3f];
+ fval |= SP2[(work >>> 24) & 0x3f];
+ left ^= fval;
+ work = (left << 28) | (left >>> 4);
+ work ^= wKey[round * 4 + 2];
+ fval = SP7[ work & 0x3f];
+ fval |= SP5[(work >>> 8) & 0x3f];
+ fval |= SP3[(work >>> 16) & 0x3f];
+ fval |= SP1[(work >>> 24) & 0x3f];
+ work = left ^ wKey[round * 4 + 3];
+ fval |= SP8[ work & 0x3f];
+ fval |= SP6[(work >>> 8) & 0x3f];
+ fval |= SP4[(work >>> 16) & 0x3f];
+ fval |= SP2[(work >>> 24) & 0x3f];
+ right ^= fval;
+ }
+
+ right = (right << 31) | (right >>> 1);
+ work = (left ^ right) & 0xaaaaaaaa;
+ left ^= work;
+ right ^= work;
+ left = (left << 31) | (left >>> 1);
+ work = ((left >>> 8) ^ right) & 0x00ff00ff;
+ right ^= work;
+ left ^= (work << 8);
+ work = ((left >>> 2) ^ right) & 0x33333333;
+ right ^= work;
+ left ^= (work << 2);
+ work = ((right >>> 16) ^ left) & 0x0000ffff;
+ left ^= work;
+ right ^= (work << 16);
+ work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
+ left ^= work;
+ right ^= (work << 4);
+
+ Pack.intToBigEndian(right, out, outOff);
+ Pack.intToBigEndian(left, out, outOff + 4);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESEngine.java
index dbef671..48996c0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESEngine.java
@@ -3,8 +3,10 @@
import com.android.internal.org.bouncycastle.crypto.BlockCipher;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
import com.android.internal.org.bouncycastle.util.Pack;
@@ -13,10 +15,12 @@
* @hide This class is not part of the Android public SDK API
*/
public class DESEngine
+ extends DESBase
implements BlockCipher
{
protected static final int BLOCK_SIZE = 8;
+ private boolean forEncryption;
private int[] workingKey = null;
/**
@@ -24,6 +28,7 @@
*/
public DESEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 56));
}
/**
@@ -40,14 +45,17 @@
{
if (params instanceof KeyParameter)
{
- if (((KeyParameter)params).getKey().length > 8)
+ if (((KeyParameter)params).getKeyLength() > 8)
{
throw new IllegalArgumentException("DES key too long - should be 8 bytes");
}
-
+
+ forEncryption = encrypting;
workingKey = generateWorkingKey(encrypting,
((KeyParameter)params).getKey());
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 56, params, Utils.getPurpose(forEncryption)));
+
return;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeEngine.java
index 7fa0b9f..115102a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeEngine.java
@@ -1,9 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.engines;
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
/**
@@ -11,34 +14,36 @@
* @hide This class is not part of the Android public SDK API
*/
public class DESedeEngine
- extends DESEngine
+ extends DESBase
+ implements BlockCipher
{
- protected static final int BLOCK_SIZE = 8;
+ protected static final int BLOCK_SIZE = 8;
- private int[] workingKey1 = null;
- private int[] workingKey2 = null;
- private int[] workingKey3 = null;
+ private int[] workingKey1 = null;
+ private int[] workingKey2 = null;
+ private int[] workingKey3 = null;
- private boolean forEncryption;
+ private boolean forEncryption;
/**
* standard constructor.
*/
public DESedeEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity()));
}
/**
* initialise a DESede cipher.
*
* @param encrypting whether or not we are for encryption.
- * @param params the parameters required to set up the cipher.
- * @exception IllegalArgumentException if the params argument is
- * inappropriate.
+ * @param params the parameters required to set up the cipher.
+ * @throws IllegalArgumentException if the params argument is
+ * inappropriate.
*/
public void init(
- boolean encrypting,
- CipherParameters params)
+ boolean encrypting,
+ CipherParameters params)
{
if (!(params instanceof KeyParameter))
{
@@ -72,6 +77,8 @@
{
workingKey3 = workingKey1;
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), bitsOfSecurity(), params, Utils.getPurpose(forEncryption)));
}
public String getAlgorithmName()
@@ -126,4 +133,14 @@
public void reset()
{
}
+
+ // Service Definitions
+ private int bitsOfSecurity()
+ {
+ if (workingKey1 != null && workingKey1 == workingKey3)
+ {
+ return 80;
+ }
+ return 112;
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
index d3ee6ca..8f1a4d4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
@@ -184,8 +184,8 @@
System.arraycopy(this.iv, 0, TEMP2, 0, this.iv.length);
System.arraycopy(TEMP1, 0, TEMP2, this.iv.length, TEMP1.length);
- // Reverse the order of the octets in TEMP2 and call the result TEMP3.
- byte[] TEMP3 = reverse(TEMP2);
+ // Reverse the order of the octets in TEMP2.
+ Arrays.reverseInPlace(TEMP2);
// Encrypt TEMP3 in CBC mode using the KEK and an initialization vector
// of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired
@@ -194,12 +194,12 @@
this.engine.init(true, param2);
- for (int currentBytePos = 0; currentBytePos != TEMP3.length; currentBytePos += blockSize)
+ for (int currentBytePos = 0; currentBytePos != TEMP2.length; currentBytePos += blockSize)
{
- engine.processBlock(TEMP3, currentBytePos, TEMP3, currentBytePos);
+ engine.processBlock(TEMP2, currentBytePos, TEMP2, currentBytePos);
}
- return TEMP3;
+ return TEMP2;
}
/**
@@ -252,15 +252,15 @@
this.engine.init(false, param2);
- byte TEMP3[] = new byte[inLen];
+ byte TEMP2[] = new byte[inLen];
for (int currentBytePos = 0; currentBytePos != inLen; currentBytePos += blockSize)
{
- engine.processBlock(in, inOff + currentBytePos, TEMP3, currentBytePos);
+ engine.processBlock(in, inOff + currentBytePos, TEMP2, currentBytePos);
}
- // Reverse the order of the octets in TEMP3 and call the result TEMP2.
- byte[] TEMP2 = reverse(TEMP3);
+ // Reverse the order of the octets in TEMP2.
+ Arrays.reverseInPlace(TEMP2);
// Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets.
this.iv = new byte[8];
@@ -343,14 +343,4 @@
{
return Arrays.constantTimeAreEqual(calculateCMSKeyChecksum(key), checksum);
}
-
- private static byte[] reverse(byte[] bs)
- {
- byte[] result = new byte[bs.length];
- for (int i = 0; i < bs.length; i++)
- {
- result[i] = bs[bs.length - (i + 1)];
- }
- return result;
- }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC2Engine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC2Engine.java
index 997f854..4caeaf0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC2Engine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC2Engine.java
@@ -1,10 +1,8 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.engines;
-import com.android.internal.org.bouncycastle.crypto.BlockCipher;
-import com.android.internal.org.bouncycastle.crypto.CipherParameters;
-import com.android.internal.org.bouncycastle.crypto.DataLengthException;
-import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.*;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
import com.android.internal.org.bouncycastle.crypto.params.RC2Parameters;
@@ -124,17 +122,18 @@
CipherParameters params)
{
this.encrypting = encrypting;
-
+ byte[] key;
if (params instanceof RC2Parameters)
{
RC2Parameters param = (RC2Parameters)params;
workingKey = generateWorkingKey(param.getKey(),
param.getEffectiveKeyBits());
+ key = param.getKey();
}
else if (params instanceof KeyParameter)
{
- byte[] key = ((KeyParameter)params).getKey();
+ key = ((KeyParameter)params).getKey();
workingKey = generateWorkingKey(key, key.length * 8);
}
@@ -143,6 +142,7 @@
throw new IllegalArgumentException("invalid parameter passed to RC2 init - " + params.getClass().getName());
}
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), key.length * 8, params, Utils.getPurpose(encrypting)));
}
public void reset()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC4Engine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC4Engine.java
index 02c138c..d49a920 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC4Engine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC4Engine.java
@@ -2,15 +2,18 @@
package com.android.internal.org.bouncycastle.crypto.engines;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
import com.android.internal.org.bouncycastle.crypto.StreamCipher;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
/**
* @hide This class is not part of the Android public SDK API
*/
-public class RC4Engine implements StreamCipher
+public class RC4Engine
+ implements StreamCipher
{
private final static int STATE_LENGTH = 256;
@@ -23,6 +26,12 @@
private int x = 0;
private int y = 0;
private byte[] workingKey = null;
+ private boolean forEncryption;
+
+ public RC4Engine()
+ {
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 20));
+ }
/**
* initialise a RC4 cipher.
@@ -34,8 +43,7 @@
*/
public void init(
boolean forEncryption,
- CipherParameters params
- )
+ CipherParameters params)
{
if (params instanceof KeyParameter)
{
@@ -44,9 +52,12 @@
* symmetrical, so the 'forEncryption' is
* irrelevant.
*/
- workingKey = ((KeyParameter)params).getKey();
+ this.workingKey = ((KeyParameter)params).getKey();
+ this.forEncryption = forEncryption;
setKey(workingKey);
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 20, params, Utils.getPurpose(forEncryption)));
+
return;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
index ed18b61..40b01b6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
@@ -22,14 +22,15 @@
public class RFC3394WrapEngine
implements Wrapper
{
- private BlockCipher engine;
- private boolean wrapCipherMode;
- private KeyParameter param;
- private boolean forWrapping;
+ private static final byte[] DEFAULT_IV = { (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6,
+ (byte)0xa6, (byte)0xa6 };
- private byte[] iv = {
- (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6,
- (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6 };
+ private final BlockCipher engine;
+ private final boolean wrapCipherMode;
+ private final byte[] iv = new byte[8];
+
+ private KeyParameter param = null;
+ private boolean forWrapping = true;
/**
* Create a RFC 3394 WrapEngine specifying the encrypt for wrapping, decrypt for unwrapping.
@@ -50,7 +51,7 @@
public RFC3394WrapEngine(BlockCipher engine, boolean useReverseDirection)
{
this.engine = engine;
- this.wrapCipherMode = (useReverseDirection) ? false : true;
+ this.wrapCipherMode = !useReverseDirection;
}
public void init(
@@ -67,15 +68,24 @@
if (param instanceof KeyParameter)
{
this.param = (KeyParameter)param;
+ System.arraycopy(DEFAULT_IV, 0, iv, 0, 8);
}
else if (param instanceof ParametersWithIV)
{
- this.iv = ((ParametersWithIV)param).getIV();
- this.param = (KeyParameter)((ParametersWithIV) param).getParameters();
- if (this.iv.length != 8)
+ ParametersWithIV withIV = (ParametersWithIV)param;
+
+ byte[] iv = withIV.getIV();
+ if (iv.length != 8)
{
throw new IllegalArgumentException("IV not equal to 8");
}
+
+ this.param = (KeyParameter)withIV.getParameters();
+ System.arraycopy(iv, 0, this.iv, 0, 8);
+ }
+ else
+ {
+ // TODO Throw an exception for bad parameters?
}
}
@@ -93,6 +103,10 @@
{
throw new IllegalStateException("not set for wrapping");
}
+ if (inLen < 8)
+ {
+ throw new DataLengthException("wrap data must be at least 8 bytes");
+ }
int n = inLen / 8;
@@ -101,34 +115,41 @@
throw new DataLengthException("wrap data must be a multiple of 8 bytes");
}
- byte[] block = new byte[inLen + iv.length];
- byte[] buf = new byte[8 + iv.length];
+ engine.init(wrapCipherMode, param);
+ byte[] block = new byte[inLen + iv.length];
System.arraycopy(iv, 0, block, 0, iv.length);
System.arraycopy(in, inOff, block, iv.length, inLen);
- engine.init(wrapCipherMode, param);
-
- for (int j = 0; j != 6; j++)
+ if (n == 1)
{
- for (int i = 1; i <= n; i++)
+ engine.processBlock(block, 0, block, 0);
+ }
+ else
+ {
+ byte[] buf = new byte[8 + iv.length];
+
+ for (int j = 0; j != 6; j++)
{
- System.arraycopy(block, 0, buf, 0, iv.length);
- System.arraycopy(block, 8 * i, buf, iv.length, 8);
- engine.processBlock(buf, 0, buf, 0);
-
- int t = n * j + i;
- for (int k = 1; t != 0; k++)
+ for (int i = 1; i <= n; i++)
{
- byte v = (byte)t;
+ System.arraycopy(block, 0, buf, 0, iv.length);
+ System.arraycopy(block, 8 * i, buf, iv.length, 8);
+ engine.processBlock(buf, 0, buf, 0);
- buf[iv.length - k] ^= v;
+ int t = n * j + i;
+ for (int k = 1; t != 0; k++)
+ {
+ byte v = (byte)t;
- t >>>= 8;
+ buf[iv.length - k] ^= v;
+
+ t >>>= 8;
+ }
+
+ System.arraycopy(buf, 0, block, 0, 8);
+ System.arraycopy(buf, 8, block, 8 * i, 8);
}
-
- System.arraycopy(buf, 0, block, 0, 8);
- System.arraycopy(buf, 8, block, 8 * i, 8);
}
}
@@ -145,6 +166,10 @@
{
throw new IllegalStateException("not set for unwrapping");
}
+ if (inLen < 16)
+ {
+ throw new InvalidCipherTextException("unwrap data too short");
+ }
int n = inLen / 8;
@@ -153,43 +178,89 @@
throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes");
}
- byte[] block = new byte[inLen - iv.length];
- byte[] a = new byte[iv.length];
- byte[] buf = new byte[8 + iv.length];
-
- System.arraycopy(in, inOff, a, 0, iv.length);
- System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length);
-
engine.init(!wrapCipherMode, param);
+ byte[] block = new byte[inLen - iv.length];
+ byte[] a = new byte[iv.length];
+ byte[] buf = new byte[8 + iv.length];
+
n = n - 1;
- for (int j = 5; j >= 0; j--)
+ if (n == 1)
{
- for (int i = n; i >= 1; i--)
+ engine.processBlock(in, inOff, buf, 0);
+ System.arraycopy(buf, 0, a, 0, iv.length);
+ System.arraycopy(buf, iv.length, block, 0, 8);
+ }
+ else
+ {
+ System.arraycopy(in, inOff, a, 0, iv.length);
+ System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length);
+
+ for (int j = 5; j >= 0; j--)
{
- System.arraycopy(a, 0, buf, 0, iv.length);
- System.arraycopy(block, 8 * (i - 1), buf, iv.length, 8);
-
- int t = n * j + i;
- for (int k = 1; t != 0; k++)
+ for (int i = n; i >= 1; i--)
{
- byte v = (byte)t;
-
- buf[iv.length - k] ^= v;
-
- t >>>= 8;
+ System.arraycopy(a, 0, buf, 0, iv.length);
+ System.arraycopy(block, 8 * (i - 1), buf, iv.length, 8);
+
+ int t = n * j + i;
+ for (int k = 1; t != 0; k++)
+ {
+ byte v = (byte)t;
+
+ buf[iv.length - k] ^= v;
+
+ t >>>= 8;
+ }
+
+ engine.processBlock(buf, 0, buf, 0);
+ System.arraycopy(buf, 0, a, 0, 8);
+ System.arraycopy(buf, 8, block, 8 * (i - 1), 8);
}
-
- engine.processBlock(buf, 0, buf, 0);
- System.arraycopy(buf, 0, a, 0, 8);
- System.arraycopy(buf, 8, block, 8 * (i - 1), 8);
}
}
- if (!Arrays.constantTimeAreEqual(a, iv))
+ if (n != 1)
{
- throw new InvalidCipherTextException("checksum failed");
+ if (!Arrays.constantTimeAreEqual(a, iv))
+ {
+ throw new InvalidCipherTextException("checksum failed");
+ }
+ }
+ else
+ {
+ // TODO: old (incorrect) backwards compatible unwrap - will be removed.
+ if (!Arrays.constantTimeAreEqual(a, iv))
+ {
+ System.arraycopy(in, inOff, a, 0, iv.length);
+ System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length);
+
+ for (int j = 5; j >= 0; j--)
+ {
+ System.arraycopy(a, 0, buf, 0, iv.length);
+ System.arraycopy(block, 0, buf, iv.length, 8);
+
+ int t = n * j + 1;
+ for (int k = 1; t != 0; k++)
+ {
+ byte v = (byte)t;
+
+ buf[iv.length - k] ^= v;
+
+ t >>>= 8;
+ }
+
+ engine.processBlock(buf, 0, buf, 0);
+ System.arraycopy(buf, 0, a, 0, 8);
+ System.arraycopy(buf, 8, block, 0, 8);
+ }
+
+ if (!Arrays.constantTimeAreEqual(a, iv))
+ {
+ throw new InvalidCipherTextException("checksum failed");
+ }
+ }
}
return block;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java
index 14f6c2f..c595f19 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java
@@ -112,39 +112,31 @@
}
BigInteger input = core.convertInput(in, inOff, inLen);
+ BigInteger result = processInput(input);
+ return core.convertOutput(result);
+ }
- BigInteger result;
+ private BigInteger processInput(BigInteger input)
+ {
if (key instanceof RSAPrivateCrtKeyParameters)
{
- RSAPrivateCrtKeyParameters k = (RSAPrivateCrtKeyParameters)key;
+ RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)key;
- BigInteger e = k.getPublicExponent();
+ BigInteger e = crtKey.getPublicExponent();
if (e != null) // can't do blinding without a public exponent
{
- BigInteger m = k.getModulus();
+ BigInteger m = crtKey.getModulus();
+
BigInteger r = BigIntegers.createRandomInRange(ONE, m.subtract(ONE), random);
+ BigInteger blind = r.modPow(e, m);
+ BigInteger unblind = BigIntegers.modOddInverse(m, r);
- BigInteger blindedInput = r.modPow(e, m).multiply(input).mod(m);
+ BigInteger blindedInput = blind.multiply(input).mod(m);
BigInteger blindedResult = core.processBlock(blindedInput);
-
- BigInteger rInv = BigIntegers.modOddInverse(m, r);
- result = blindedResult.multiply(rInv).mod(m);
- // defence against Arjen Lenstra’s CRT attack
- if (!input.equals(result.modPow(e, m)))
- {
- throw new IllegalStateException("RSA engine faulty decryption/signing detected");
- }
- }
- else
- {
- result = core.processBlock(input);
+ return unblind.multiply(blindedResult).mod(m);
}
}
- else
- {
- result = core.processBlock(input);
- }
- return core.convertOutput(result);
+ return core.processBlock(input);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSACoreEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSACoreEngine.java
index 7ab640d..5cf3657 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSACoreEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSACoreEngine.java
@@ -4,7 +4,11 @@
import java.math.BigInteger;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
import com.android.internal.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
@@ -16,21 +20,21 @@
class RSACoreEngine
{
private RSAKeyParameters key;
- private boolean forEncryption;
+ private boolean forEncryption;
/**
* initialise the RSA engine.
*
* @param forEncryption true if we are encrypting, false otherwise.
- * @param param the necessary RSA key parameters.
+ * @param param the necessary RSA key parameters.
*/
public void init(
- boolean forEncryption,
+ boolean forEncryption,
CipherParameters param)
{
if (param instanceof ParametersWithRandom)
{
- ParametersWithRandom rParam = (ParametersWithRandom)param;
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
key = (RSAKeyParameters)rParam.getParameters();
}
@@ -40,6 +44,8 @@
}
this.forEncryption = forEncryption;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("RSA", ConstraintUtils.bitsOfSecurityFor(key.getModulus()), key, getPurpose(key.isPrivate(), forEncryption)));
}
/**
@@ -51,7 +57,7 @@
*/
public int getInputBlockSize()
{
- int bitSize = key.getModulus().bitLength();
+ int bitSize = key.getModulus().bitLength();
if (forEncryption)
{
@@ -72,7 +78,7 @@
*/
public int getOutputBlockSize()
{
- int bitSize = key.getModulus().bitLength();
+ int bitSize = key.getModulus().bitLength();
if (forEncryption)
{
@@ -85,9 +91,9 @@
}
public BigInteger convertInput(
- byte[] in,
- int inOff,
- int inLen)
+ byte[] in,
+ int inOff,
+ int inLen)
{
if (inLen > (getInputBlockSize() + 1))
{
@@ -98,7 +104,7 @@
throw new DataLengthException("input too large for RSA cipher.");
}
- byte[] block;
+ byte[] block;
if (inOff != 0 || inLen != in.length)
{
@@ -123,13 +129,13 @@
public byte[] convertOutput(
BigInteger result)
{
- byte[] output = result.toByteArray();
+ byte[] output = result.toByteArray();
if (forEncryption)
{
if (output[0] == 0 && output.length > getOutputBlockSize()) // have ended up with an extra zero byte, copy down.
{
- byte[] tmp = new byte[output.length - 1];
+ byte[] tmp = new byte[output.length - 1];
System.arraycopy(output, 1, tmp, 0, tmp.length);
@@ -138,7 +144,7 @@
if (output.length < getOutputBlockSize()) // have ended up with less bytes than normal, lengthen
{
- byte[] tmp = new byte[getOutputBlockSize()];
+ byte[] tmp = new byte[getOutputBlockSize()];
System.arraycopy(output, 0, tmp, tmp.length - output.length, output.length);
@@ -149,7 +155,7 @@
}
else
{
- byte[] rv;
+ byte[] rv;
if (output[0] == 0) // have ended up with an extra zero byte, copy down.
{
rv = new byte[output.length - 1];
@@ -180,35 +186,64 @@
//
RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)key;
- BigInteger p = crtKey.getP();
- BigInteger q = crtKey.getQ();
- BigInteger dP = crtKey.getDP();
- BigInteger dQ = crtKey.getDQ();
- BigInteger qInv = crtKey.getQInv();
+ BigInteger e = crtKey.getPublicExponent();
+ if (e != null) // can't apply fault-attack countermeasure without public exponent
+ {
+ BigInteger p = crtKey.getP();
+ BigInteger q = crtKey.getQ();
+ BigInteger dP = crtKey.getDP();
+ BigInteger dQ = crtKey.getDQ();
+ BigInteger qInv = crtKey.getQInv();
- BigInteger mP, mQ, h, m;
+ BigInteger mP, mQ, h, m;
- // mP = ((input mod p) ^ dP)) mod p
- mP = (input.remainder(p)).modPow(dP, p);
+ // mP = ((input mod p) ^ dP)) mod p
+ mP = (input.remainder(p)).modPow(dP, p);
- // mQ = ((input mod q) ^ dQ)) mod q
- mQ = (input.remainder(q)).modPow(dQ, q);
+ // mQ = ((input mod q) ^ dQ)) mod q
+ mQ = (input.remainder(q)).modPow(dQ, q);
- // h = qInv * (mP - mQ) mod p
- h = mP.subtract(mQ);
- h = h.multiply(qInv);
- h = h.mod(p); // mod (in Java) returns the positive residual
+ // h = qInv * (mP - mQ) mod p
+ h = mP.subtract(mQ);
+ h = h.multiply(qInv);
+ h = h.mod(p); // mod (in Java) returns the positive residual
- // m = h * q + mQ
- m = h.multiply(q);
- m = m.add(mQ);
+ // m = h * q + mQ
+ m = h.multiply(q).add(mQ);
- return m;
+ // defence against Arjen Lenstra’s CRT attack
+ BigInteger check = m.modPow(e, crtKey.getModulus());
+ if (!check.equals(input))
+ {
+ throw new IllegalStateException("RSA engine faulty decryption/signing detected");
+ }
+
+ return m;
+ }
}
- else
+
+ return input.modPow(key.getExponent(), key.getModulus());
+ }
+
+ private CryptoServicePurpose getPurpose(boolean isPrivate, boolean forEncryption)
+ {
+ boolean isSigning = isPrivate && forEncryption;
+ boolean isEncryption = !isPrivate && forEncryption;
+ boolean isVerifying = !isPrivate && !forEncryption;
+
+ if (isSigning)
{
- return input.modPow(
- key.getExponent(), key.getModulus());
+ return CryptoServicePurpose.SIGNING;
}
+ if (isEncryption)
+ {
+ return CryptoServicePurpose.ENCRYPTION;
+ }
+ if (isVerifying)
+ {
+ return CryptoServicePurpose.VERIFYING;
+ }
+
+ return CryptoServicePurpose.DECRYPTION;
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/TwofishEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/TwofishEngine.java
index e7ba6de..e0d9669 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/TwofishEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/TwofishEngine.java
@@ -3,9 +3,13 @@
import com.android.internal.org.bouncycastle.crypto.BlockCipher;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.util.Integers;
+import com.android.internal.org.bouncycastle.util.Pack;
/**
* A class that provides Twofish encryption operations.
@@ -226,6 +230,8 @@
public TwofishEngine()
{
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), 256));
+
// calculate the MDS matrix
int[] m1 = new int[2];
int[] mX = new int[2];
@@ -274,7 +280,21 @@
{
this.encrypting = encrypting;
this.workingKey = ((KeyParameter)params).getKey();
- this.k64Cnt = (this.workingKey.length / 8); // pre-padded ?
+
+ int keyBits = this.workingKey.length * 8;
+ switch (keyBits)
+ {
+ case 128:
+ case 192:
+ case 256:
+ break;
+ default:
+ throw new IllegalArgumentException("Key length not 128/192/256 bits.");
+ }
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), keyBits, params, Utils.getPurpose(encrypting)));
+
+ this.k64Cnt = this.workingKey.length / 8;
setKey(this.workingKey);
return;
@@ -346,28 +366,16 @@
int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4
gSubKeys = new int[TOTAL_SUBKEYS];
- if (k64Cnt < 1)
- {
- throw new IllegalArgumentException("Key size less than 64 bits");
- }
-
- if (k64Cnt > 4)
- {
- throw new IllegalArgumentException("Key size larger than 256 bits");
- }
-
/*
- * k64Cnt is the number of 8 byte blocks (64 chunks)
- * that are in the input key. The input key is a
- * maximum of 32 bytes (256 bits), so the range
- * for k64Cnt is 1..4
+ * k64Cnt is the number of 8 byte blocks (64 chunks) that are in the input key.
+ * The input key is 16, 24 or 32 bytes, so the range for k64Cnt is 2..4
*/
for (int i=0; i<k64Cnt ; i++)
{
int p = i* 8;
- k32e[i] = BytesTo32Bits(key, p);
- k32o[i] = BytesTo32Bits(key, p+4);
+ k32e[i] = Pack.littleEndianToInt(key, p);
+ k32o[i] = Pack.littleEndianToInt(key, p + 4);
sBoxKeys[k64Cnt-1-i] = RS_MDS_Encode(k32e[i], k32o[i]);
}
@@ -378,7 +386,7 @@
q = i*SK_STEP;
A = F32(q, k32e);
B = F32(q+SK_BUMP, k32o);
- B = B << 8 | B >>> 24;
+ B = Integers.rotateLeft(B, 8);
A += B;
gSubKeys[i*2] = A;
A += B;
@@ -450,10 +458,10 @@
byte[] dst,
int dstIndex)
{
- int x0 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[INPUT_WHITEN];
- int x1 = BytesTo32Bits(src, srcIndex + 4) ^ gSubKeys[INPUT_WHITEN + 1];
- int x2 = BytesTo32Bits(src, srcIndex + 8) ^ gSubKeys[INPUT_WHITEN + 2];
- int x3 = BytesTo32Bits(src, srcIndex + 12) ^ gSubKeys[INPUT_WHITEN + 3];
+ int x0 = Pack.littleEndianToInt(src, srcIndex) ^ gSubKeys[INPUT_WHITEN];
+ int x1 = Pack.littleEndianToInt(src, srcIndex + 4) ^ gSubKeys[INPUT_WHITEN + 1];
+ int x2 = Pack.littleEndianToInt(src, srcIndex + 8) ^ gSubKeys[INPUT_WHITEN + 2];
+ int x3 = Pack.littleEndianToInt(src, srcIndex + 12) ^ gSubKeys[INPUT_WHITEN + 3];
int k = ROUND_SUBKEYS;
int t0, t1;
@@ -462,20 +470,20 @@
t0 = Fe32_0(x0);
t1 = Fe32_3(x1);
x2 ^= t0 + t1 + gSubKeys[k++];
- x2 = x2 >>>1 | x2 << 31;
- x3 = (x3 << 1 | x3 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
+ x2 = Integers.rotateRight(x2, 1);
+ x3 = Integers.rotateLeft(x3, 1) ^ (t0 + 2*t1 + gSubKeys[k++]);
t0 = Fe32_0(x2);
t1 = Fe32_3(x3);
x0 ^= t0 + t1 + gSubKeys[k++];
- x0 = x0 >>>1 | x0 << 31;
- x1 = (x1 << 1 | x1 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
+ x0 = Integers.rotateRight(x0, 1);
+ x1 = Integers.rotateLeft(x1, 1) ^ (t0 + 2*t1 + gSubKeys[k++]);
}
- Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex);
- Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4);
- Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8);
- Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12);
+ Pack.intToLittleEndian(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex);
+ Pack.intToLittleEndian(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4);
+ Pack.intToLittleEndian(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8);
+ Pack.intToLittleEndian(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12);
}
/**
@@ -489,10 +497,10 @@
byte[] dst,
int dstIndex)
{
- int x2 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN];
- int x3 = BytesTo32Bits(src, srcIndex+4) ^ gSubKeys[OUTPUT_WHITEN + 1];
- int x0 = BytesTo32Bits(src, srcIndex+8) ^ gSubKeys[OUTPUT_WHITEN + 2];
- int x1 = BytesTo32Bits(src, srcIndex+12) ^ gSubKeys[OUTPUT_WHITEN + 3];
+ int x2 = Pack.littleEndianToInt(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN];
+ int x3 = Pack.littleEndianToInt(src, srcIndex + 4) ^ gSubKeys[OUTPUT_WHITEN + 1];
+ int x0 = Pack.littleEndianToInt(src, srcIndex + 8) ^ gSubKeys[OUTPUT_WHITEN + 2];
+ int x1 = Pack.littleEndianToInt(src, srcIndex + 12) ^ gSubKeys[OUTPUT_WHITEN + 3];
int k = ROUND_SUBKEYS + 2 * ROUNDS -1 ;
int t0, t1;
@@ -501,20 +509,20 @@
t0 = Fe32_0(x2);
t1 = Fe32_3(x3);
x1 ^= t0 + 2*t1 + gSubKeys[k--];
- x0 = (x0 << 1 | x0 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
- x1 = x1 >>>1 | x1 << 31;
+ x0 = Integers.rotateLeft(x0, 1) ^ (t0 + t1 + gSubKeys[k--]);
+ x1 = Integers.rotateRight(x1, 1);
t0 = Fe32_0(x0);
t1 = Fe32_3(x1);
x3 ^= t0 + 2*t1 + gSubKeys[k--];
- x2 = (x2 << 1 | x2 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
- x3 = x3 >>>1 | x3 << 31;
+ x2 = Integers.rotateLeft(x2, 1) ^ (t0 + t1 + gSubKeys[k--]);
+ x3 = Integers.rotateRight(x3, 1);
}
- Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex);
- Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4);
- Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8);
- Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12);
+ Pack.intToLittleEndian(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex);
+ Pack.intToLittleEndian(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4);
+ Pack.intToLittleEndian(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8);
+ Pack.intToLittleEndian(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12);
}
/*
@@ -663,20 +671,4 @@
gSBox[ 0x200 + 2*((x >>> 8) & 0xff) ] ^
gSBox[ 0x201 + 2*((x >>> 16) & 0xff) ];
}
-
- private int BytesTo32Bits(byte[] b, int p)
- {
- return ((b[p] & 0xff)) |
- ((b[p+1] & 0xff) << 8) |
- ((b[p+2] & 0xff) << 16) |
- ((b[p+3] & 0xff) << 24);
- }
-
- private void Bits32ToBytes(int in, byte[] b, int offset)
- {
- b[offset] = (byte)in;
- b[offset + 1] = (byte)(in >> 8);
- b[offset + 2] = (byte)(in >> 16);
- b[offset + 3] = (byte)(in >> 24);
- }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Utils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Utils.java
new file mode 100644
index 0000000..65d6c47
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Utils.java
@@ -0,0 +1,12 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+
+class Utils
+{
+ static CryptoServicePurpose getPurpose(boolean forEncryption)
+ {
+ return forEncryption ? CryptoServicePurpose.ENCRYPTION : CryptoServicePurpose.DECRYPTION;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Zuc128CoreEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Zuc128CoreEngine.java
new file mode 100644
index 0000000..c591818
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Zuc128CoreEngine.java
@@ -0,0 +1,577 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.StreamCipher;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.util.Memoable;
+
+/**
+ * Zuc128Engine implementation.
+ * Based on https://www.gsma.com/aboutus/wp-content/uploads/2014/12/eea3eia3zucv16.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Zuc128CoreEngine
+ implements StreamCipher, Memoable
+{
+ /* the s-boxes */
+ private static final byte[] S0 = new byte[]{
+ (byte)0x3e, (byte)0x72, (byte)0x5b, (byte)0x47, (byte)0xca, (byte)0xe0, (byte)0x00, (byte)0x33, (byte)0x04, (byte)0xd1, (byte)0x54, (byte)0x98, (byte)0x09, (byte)0xb9, (byte)0x6d, (byte)0xcb,
+ (byte)0x7b, (byte)0x1b, (byte)0xf9, (byte)0x32, (byte)0xaf, (byte)0x9d, (byte)0x6a, (byte)0xa5, (byte)0xb8, (byte)0x2d, (byte)0xfc, (byte)0x1d, (byte)0x08, (byte)0x53, (byte)0x03, (byte)0x90,
+ (byte)0x4d, (byte)0x4e, (byte)0x84, (byte)0x99, (byte)0xe4, (byte)0xce, (byte)0xd9, (byte)0x91, (byte)0xdd, (byte)0xb6, (byte)0x85, (byte)0x48, (byte)0x8b, (byte)0x29, (byte)0x6e, (byte)0xac,
+ (byte)0xcd, (byte)0xc1, (byte)0xf8, (byte)0x1e, (byte)0x73, (byte)0x43, (byte)0x69, (byte)0xc6, (byte)0xb5, (byte)0xbd, (byte)0xfd, (byte)0x39, (byte)0x63, (byte)0x20, (byte)0xd4, (byte)0x38,
+ (byte)0x76, (byte)0x7d, (byte)0xb2, (byte)0xa7, (byte)0xcf, (byte)0xed, (byte)0x57, (byte)0xc5, (byte)0xf3, (byte)0x2c, (byte)0xbb, (byte)0x14, (byte)0x21, (byte)0x06, (byte)0x55, (byte)0x9b,
+ (byte)0xe3, (byte)0xef, (byte)0x5e, (byte)0x31, (byte)0x4f, (byte)0x7f, (byte)0x5a, (byte)0xa4, (byte)0x0d, (byte)0x82, (byte)0x51, (byte)0x49, (byte)0x5f, (byte)0xba, (byte)0x58, (byte)0x1c,
+ (byte)0x4a, (byte)0x16, (byte)0xd5, (byte)0x17, (byte)0xa8, (byte)0x92, (byte)0x24, (byte)0x1f, (byte)0x8c, (byte)0xff, (byte)0xd8, (byte)0xae, (byte)0x2e, (byte)0x01, (byte)0xd3, (byte)0xad,
+ (byte)0x3b, (byte)0x4b, (byte)0xda, (byte)0x46, (byte)0xeb, (byte)0xc9, (byte)0xde, (byte)0x9a, (byte)0x8f, (byte)0x87, (byte)0xd7, (byte)0x3a, (byte)0x80, (byte)0x6f, (byte)0x2f, (byte)0xc8,
+ (byte)0xb1, (byte)0xb4, (byte)0x37, (byte)0xf7, (byte)0x0a, (byte)0x22, (byte)0x13, (byte)0x28, (byte)0x7c, (byte)0xcc, (byte)0x3c, (byte)0x89, (byte)0xc7, (byte)0xc3, (byte)0x96, (byte)0x56,
+ (byte)0x07, (byte)0xbf, (byte)0x7e, (byte)0xf0, (byte)0x0b, (byte)0x2b, (byte)0x97, (byte)0x52, (byte)0x35, (byte)0x41, (byte)0x79, (byte)0x61, (byte)0xa6, (byte)0x4c, (byte)0x10, (byte)0xfe,
+ (byte)0xbc, (byte)0x26, (byte)0x95, (byte)0x88, (byte)0x8a, (byte)0xb0, (byte)0xa3, (byte)0xfb, (byte)0xc0, (byte)0x18, (byte)0x94, (byte)0xf2, (byte)0xe1, (byte)0xe5, (byte)0xe9, (byte)0x5d,
+ (byte)0xd0, (byte)0xdc, (byte)0x11, (byte)0x66, (byte)0x64, (byte)0x5c, (byte)0xec, (byte)0x59, (byte)0x42, (byte)0x75, (byte)0x12, (byte)0xf5, (byte)0x74, (byte)0x9c, (byte)0xaa, (byte)0x23,
+ (byte)0x0e, (byte)0x86, (byte)0xab, (byte)0xbe, (byte)0x2a, (byte)0x02, (byte)0xe7, (byte)0x67, (byte)0xe6, (byte)0x44, (byte)0xa2, (byte)0x6c, (byte)0xc2, (byte)0x93, (byte)0x9f, (byte)0xf1,
+ (byte)0xf6, (byte)0xfa, (byte)0x36, (byte)0xd2, (byte)0x50, (byte)0x68, (byte)0x9e, (byte)0x62, (byte)0x71, (byte)0x15, (byte)0x3d, (byte)0xd6, (byte)0x40, (byte)0xc4, (byte)0xe2, (byte)0x0f,
+ (byte)0x8e, (byte)0x83, (byte)0x77, (byte)0x6b, (byte)0x25, (byte)0x05, (byte)0x3f, (byte)0x0c, (byte)0x30, (byte)0xea, (byte)0x70, (byte)0xb7, (byte)0xa1, (byte)0xe8, (byte)0xa9, (byte)0x65,
+ (byte)0x8d, (byte)0x27, (byte)0x1a, (byte)0xdb, (byte)0x81, (byte)0xb3, (byte)0xa0, (byte)0xf4, (byte)0x45, (byte)0x7a, (byte)0x19, (byte)0xdf, (byte)0xee, (byte)0x78, (byte)0x34, (byte)0x60
+ };
+
+ private static final byte[] S1 = new byte[]{
+ (byte)0x55, (byte)0xc2, (byte)0x63, (byte)0x71, (byte)0x3b, (byte)0xc8, (byte)0x47, (byte)0x86, (byte)0x9f, (byte)0x3c, (byte)0xda, (byte)0x5b, (byte)0x29, (byte)0xaa, (byte)0xfd, (byte)0x77,
+ (byte)0x8c, (byte)0xc5, (byte)0x94, (byte)0x0c, (byte)0xa6, (byte)0x1a, (byte)0x13, (byte)0x00, (byte)0xe3, (byte)0xa8, (byte)0x16, (byte)0x72, (byte)0x40, (byte)0xf9, (byte)0xf8, (byte)0x42,
+ (byte)0x44, (byte)0x26, (byte)0x68, (byte)0x96, (byte)0x81, (byte)0xd9, (byte)0x45, (byte)0x3e, (byte)0x10, (byte)0x76, (byte)0xc6, (byte)0xa7, (byte)0x8b, (byte)0x39, (byte)0x43, (byte)0xe1,
+ (byte)0x3a, (byte)0xb5, (byte)0x56, (byte)0x2a, (byte)0xc0, (byte)0x6d, (byte)0xb3, (byte)0x05, (byte)0x22, (byte)0x66, (byte)0xbf, (byte)0xdc, (byte)0x0b, (byte)0xfa, (byte)0x62, (byte)0x48,
+ (byte)0xdd, (byte)0x20, (byte)0x11, (byte)0x06, (byte)0x36, (byte)0xc9, (byte)0xc1, (byte)0xcf, (byte)0xf6, (byte)0x27, (byte)0x52, (byte)0xbb, (byte)0x69, (byte)0xf5, (byte)0xd4, (byte)0x87,
+ (byte)0x7f, (byte)0x84, (byte)0x4c, (byte)0xd2, (byte)0x9c, (byte)0x57, (byte)0xa4, (byte)0xbc, (byte)0x4f, (byte)0x9a, (byte)0xdf, (byte)0xfe, (byte)0xd6, (byte)0x8d, (byte)0x7a, (byte)0xeb,
+ (byte)0x2b, (byte)0x53, (byte)0xd8, (byte)0x5c, (byte)0xa1, (byte)0x14, (byte)0x17, (byte)0xfb, (byte)0x23, (byte)0xd5, (byte)0x7d, (byte)0x30, (byte)0x67, (byte)0x73, (byte)0x08, (byte)0x09,
+ (byte)0xee, (byte)0xb7, (byte)0x70, (byte)0x3f, (byte)0x61, (byte)0xb2, (byte)0x19, (byte)0x8e, (byte)0x4e, (byte)0xe5, (byte)0x4b, (byte)0x93, (byte)0x8f, (byte)0x5d, (byte)0xdb, (byte)0xa9,
+ (byte)0xad, (byte)0xf1, (byte)0xae, (byte)0x2e, (byte)0xcb, (byte)0x0d, (byte)0xfc, (byte)0xf4, (byte)0x2d, (byte)0x46, (byte)0x6e, (byte)0x1d, (byte)0x97, (byte)0xe8, (byte)0xd1, (byte)0xe9,
+ (byte)0x4d, (byte)0x37, (byte)0xa5, (byte)0x75, (byte)0x5e, (byte)0x83, (byte)0x9e, (byte)0xab, (byte)0x82, (byte)0x9d, (byte)0xb9, (byte)0x1c, (byte)0xe0, (byte)0xcd, (byte)0x49, (byte)0x89,
+ (byte)0x01, (byte)0xb6, (byte)0xbd, (byte)0x58, (byte)0x24, (byte)0xa2, (byte)0x5f, (byte)0x38, (byte)0x78, (byte)0x99, (byte)0x15, (byte)0x90, (byte)0x50, (byte)0xb8, (byte)0x95, (byte)0xe4,
+ (byte)0xd0, (byte)0x91, (byte)0xc7, (byte)0xce, (byte)0xed, (byte)0x0f, (byte)0xb4, (byte)0x6f, (byte)0xa0, (byte)0xcc, (byte)0xf0, (byte)0x02, (byte)0x4a, (byte)0x79, (byte)0xc3, (byte)0xde,
+ (byte)0xa3, (byte)0xef, (byte)0xea, (byte)0x51, (byte)0xe6, (byte)0x6b, (byte)0x18, (byte)0xec, (byte)0x1b, (byte)0x2c, (byte)0x80, (byte)0xf7, (byte)0x74, (byte)0xe7, (byte)0xff, (byte)0x21,
+ (byte)0x5a, (byte)0x6a, (byte)0x54, (byte)0x1e, (byte)0x41, (byte)0x31, (byte)0x92, (byte)0x35, (byte)0xc4, (byte)0x33, (byte)0x07, (byte)0x0a, (byte)0xba, (byte)0x7e, (byte)0x0e, (byte)0x34,
+ (byte)0x88, (byte)0xb1, (byte)0x98, (byte)0x7c, (byte)0xf3, (byte)0x3d, (byte)0x60, (byte)0x6c, (byte)0x7b, (byte)0xca, (byte)0xd3, (byte)0x1f, (byte)0x32, (byte)0x65, (byte)0x04, (byte)0x28,
+ (byte)0x64, (byte)0xbe, (byte)0x85, (byte)0x9b, (byte)0x2f, (byte)0x59, (byte)0x8a, (byte)0xd7, (byte)0xb0, (byte)0x25, (byte)0xac, (byte)0xaf, (byte)0x12, (byte)0x03, (byte)0xe2, (byte)0xf2
+ };
+
+ /* the constants D */
+ private static final short[] EK_d = new short[]{
+ 0x44D7, 0x26BC, 0x626B, 0x135E, 0x5789, 0x35E2, 0x7135, 0x09AF,
+ 0x4D78, 0x2F13, 0x6BC4, 0x1AF1, 0x5E26, 0x3C4D, 0x789A, 0x47AC
+ };
+
+ /**
+ * State.
+ */
+ private final int[] LFSR = new int[16];
+ private final int[] F = new int[2];
+ private final int[] BRC = new int[4];
+
+ /**
+ * index of next byte in keyStream.
+ */
+ private int theIndex;
+
+ /**
+ * Advanced stream.
+ */
+ private final byte[] keyStream = new byte[4]; // Integer.BYTES
+
+ /**
+ * The iterations.
+ */
+ private int theIterations;
+
+ /**
+ * Reset state.
+ */
+ private Zuc128CoreEngine theResetState;
+
+ /**
+ * Constructor.
+ */
+ protected Zuc128CoreEngine()
+ {
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param pSource the source engine
+ */
+ protected Zuc128CoreEngine(final Zuc128CoreEngine pSource)
+ {
+ reset(pSource);
+ }
+
+ /**
+ * initialise a Snow3G cipher.
+ *
+ * @param forEncryption whether or not we are for encryption.
+ * @param params the parameters required to set up the cipher.
+ * @throws IllegalArgumentException if the params argument is inappropriate.
+ */
+ public void init(final boolean forEncryption,
+ final CipherParameters params)
+ {
+ /*
+ * encryption and decryption is completely symmetrical.
+ */
+
+ /* Determine parameters */
+ CipherParameters myParams = params;
+ byte[] newKey = null;
+ byte[] newIV = null;
+ if ((myParams instanceof ParametersWithIV))
+ {
+ final ParametersWithIV ivParams = (ParametersWithIV)myParams;
+ newIV = ivParams.getIV();
+ myParams = ivParams.getParameters();
+ }
+ if (myParams instanceof KeyParameter)
+ {
+ final KeyParameter keyParam = (KeyParameter)myParams;
+ newKey = keyParam.getKey();
+ }
+
+ /* Initialise engine and mark as initialised */
+ theIndex = 0;
+ theIterations = 0;
+ setKeyAndIV(newKey, newIV);
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(getAlgorithmName(), newKey.length * 8,
+ params, forEncryption ? CryptoServicePurpose.ENCRYPTION : CryptoServicePurpose.DECRYPTION));
+
+ /* Save reset state */
+ theResetState = (Zuc128CoreEngine)copy();
+ }
+
+ /**
+ * Obtain Max iterations.
+ *
+ * @return the maximum iterations
+ */
+ protected int getMaxIterations()
+ {
+ return 2047;
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc-128";
+ }
+
+ /**
+ * Process bytes.
+ *
+ * @param in the input buffer
+ * @param inOff the starting offset in the input buffer
+ * @param len the length of data in the input buffer
+ * @param out the output buffer
+ * @param outOff the starting offset in the output buffer
+ * @return the number of bytes returned in the output buffer
+ */
+ public int processBytes(final byte[] in,
+ final int inOff,
+ final int len,
+ final byte[] out,
+ final int outOff)
+ {
+ /* Check for errors */
+ if (theResetState == null)
+ {
+ throw new IllegalStateException(getAlgorithmName() + " not initialised");
+ }
+ if ((inOff + len) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+ if ((outOff + len) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ /* Loop through the input bytes */
+ for (int i = 0; i < len; i++)
+ {
+ out[i + outOff] = returnByte(in[i + inOff]);
+ }
+ return len;
+ }
+
+ /**
+ * Reset the engine.
+ */
+ public void reset()
+ {
+ if (theResetState != null)
+ {
+ reset(theResetState);
+ }
+ }
+
+ /**
+ * Process single byte.
+ *
+ * @param in the input byte
+ * @return the output byte
+ */
+ public byte returnByte(final byte in)
+ {
+ /* Make the keyStream if required */
+ if (theIndex == 0)
+ {
+ makeKeyStream();
+ }
+
+ /* Map the next byte and adjust index */
+ final byte out = (byte)(keyStream[theIndex] ^ in);
+ theIndex = (theIndex + 1) % 4; // Integer.BYTES
+
+ /* Return the mapped character */
+ return out;
+ }
+
+ /**
+ * Encode a 32-bit value into a buffer (little-endian).
+ *
+ * @param val the value to encode
+ * @param buf the output buffer
+ * @param off the output offset
+ */
+ public static void encode32be(int val, byte[] buf, int off)
+ {
+ buf[off] = (byte)(val >> 24);
+ buf[off + 1] = (byte)(val >> 16);
+ buf[off + 2] = (byte)(val >> 8);
+ buf[off + 3] = (byte)val;
+ }
+
+ /* ����������������������- */
+
+ /**
+ * Modular add c = a + b mod (2^31 � 1).
+ *
+ * @param a value A
+ * @param b value B
+ * @return the result
+ */
+ private int AddM(final int a, final int b)
+ {
+ final int c = a + b;
+ return (c & 0x7FFFFFFF) + (c >>> 31);
+ }
+
+ /**
+ * Multiply by power of two.
+ *
+ * @param x input value
+ * @param k the power of two
+ * @return the result
+ */
+ private static int MulByPow2(final int x, final int k)
+ {
+ return ((((x) << k) | ((x) >>> (31 - k))) & 0x7FFFFFFF);
+ }
+
+ /**
+ * LFSR with initialisation mode.
+ *
+ * @param u
+ */
+ private void LFSRWithInitialisationMode(final int u)
+ {
+ int f = LFSR[0];
+ int v = MulByPow2(LFSR[0], 8);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[4], 20);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[10], 21);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[13], 17);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[15], 15);
+ f = AddM(f, v);
+ f = AddM(f, u);
+
+ /* update the state */
+ LFSR[0] = LFSR[1];
+ LFSR[1] = LFSR[2];
+ LFSR[2] = LFSR[3];
+ LFSR[3] = LFSR[4];
+ LFSR[4] = LFSR[5];
+ LFSR[5] = LFSR[6];
+ LFSR[6] = LFSR[7];
+ LFSR[7] = LFSR[8];
+ LFSR[8] = LFSR[9];
+ LFSR[9] = LFSR[10];
+ LFSR[10] = LFSR[11];
+ LFSR[11] = LFSR[12];
+ LFSR[12] = LFSR[13];
+ LFSR[13] = LFSR[14];
+ LFSR[14] = LFSR[15];
+ LFSR[15] = f;
+ }
+
+ /**
+ * LFSR with work mode.
+ */
+ private void LFSRWithWorkMode()
+ {
+ int f, v;
+ f = LFSR[0];
+ v = MulByPow2(LFSR[0], 8);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[4], 20);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[10], 21);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[13], 17);
+ f = AddM(f, v);
+ v = MulByPow2(LFSR[15], 15);
+ f = AddM(f, v);
+
+ /* update the state */
+ LFSR[0] = LFSR[1];
+ LFSR[1] = LFSR[2];
+ LFSR[2] = LFSR[3];
+ LFSR[3] = LFSR[4];
+ LFSR[4] = LFSR[5];
+ LFSR[5] = LFSR[6];
+ LFSR[6] = LFSR[7];
+ LFSR[7] = LFSR[8];
+ LFSR[8] = LFSR[9];
+ LFSR[9] = LFSR[10];
+ LFSR[10] = LFSR[11];
+ LFSR[11] = LFSR[12];
+ LFSR[12] = LFSR[13];
+ LFSR[13] = LFSR[14];
+ LFSR[14] = LFSR[15];
+ LFSR[15] = f;
+ }
+
+ /**
+ * BitReorganization.
+ */
+ private void BitReorganization()
+ {
+ BRC[0] = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
+ BRC[1] = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
+ BRC[2] = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
+ BRC[3] = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >>> 15);
+ }
+
+ /**
+ * Rotate integer.
+ *
+ * @param a the integer
+ * @param k the shift
+ * @return the result
+ */
+ static int ROT(int a, int k)
+ {
+ return (((a) << k) | ((a) >>> (32 - k)));
+ }
+
+ /**
+ * L1.
+ *
+ * @param X the input integer.
+ * @return the result
+ */
+ private static int L1(final int X)
+ {
+ return (X ^ ROT(X, 2) ^ ROT(X, 10) ^ ROT(X, 18) ^ ROT(X, 24));
+ }
+
+ /**
+ * L2.
+ *
+ * @param X the input integer.
+ * @return the result
+ */
+ private static int L2(final int X)
+ {
+ return (X ^ ROT(X, 8) ^ ROT(X, 14) ^ ROT(X, 22) ^ ROT(X, 30));
+ }
+
+ /**
+ * Build a 32-bit integer from constituent parts.
+ *
+ * @param a part A
+ * @param b part B
+ * @param c part C
+ * @param d part D
+ * @return the built integer
+ */
+ private static int MAKEU32(final byte a,
+ final byte b,
+ final byte c,
+ final byte d)
+ {
+ return (((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF)));
+ }
+
+ /**
+ * F.
+ */
+ int F()
+ {
+ int W, W1, W2, u, v;
+ W = (BRC[0] ^ F[0]) + F[1];
+ W1 = F[0] + BRC[1];
+ W2 = F[1] ^ BRC[2];
+ u = L1((W1 << 16) | (W2 >>> 16));
+ v = L2((W2 << 16) | (W1 >>> 16));
+ F[0] = MAKEU32(S0[u >>> 24], S1[(u >>> 16) & 0xFF],
+ S0[(u >>> 8) & 0xFF], S1[u & 0xFF]);
+ F[1] = MAKEU32(S0[v >>> 24], S1[(v >>> 16) & 0xFF],
+ S0[(v >>> 8) & 0xFF], S1[v & 0xFF]);
+ return W;
+ }
+
+ /**
+ * Build a 31-bit integer from constituent parts.
+ *
+ * @param a part A
+ * @param b part B
+ * @param c part C
+ * @return the built integer
+ */
+ private static int MAKEU31(final byte a,
+ final short b,
+ final byte c)
+ {
+ return (((a & 0xFF) << 23) | ((b & 0xFFFF) << 8) | (c & 0xFF));
+ }
+
+ /**
+ * Process key and IV into LFSR.
+ *
+ * @param pLFSR the LFSR
+ * @param k the key
+ * @param iv the iv
+ */
+ protected void setKeyAndIV(final int[] pLFSR,
+ final byte[] k,
+ final byte[] iv)
+ {
+ /* Check lengths */
+ if (k == null || k.length != 16)
+ {
+ throw new IllegalArgumentException("A key of 16 bytes is needed");
+ }
+ if (iv == null || iv.length != 16)
+ {
+ throw new IllegalArgumentException("An IV of 16 bytes is needed");
+ }
+
+ /* expand key */
+ LFSR[0] = MAKEU31(k[0], EK_d[0], iv[0]);
+ LFSR[1] = MAKEU31(k[1], EK_d[1], iv[1]);
+ LFSR[2] = MAKEU31(k[2], EK_d[2], iv[2]);
+ LFSR[3] = MAKEU31(k[3], EK_d[3], iv[3]);
+ LFSR[4] = MAKEU31(k[4], EK_d[4], iv[4]);
+ LFSR[5] = MAKEU31(k[5], EK_d[5], iv[5]);
+ LFSR[6] = MAKEU31(k[6], EK_d[6], iv[6]);
+ LFSR[7] = MAKEU31(k[7], EK_d[7], iv[7]);
+ LFSR[8] = MAKEU31(k[8], EK_d[8], iv[8]);
+ LFSR[9] = MAKEU31(k[9], EK_d[9], iv[9]);
+ LFSR[10] = MAKEU31(k[10], EK_d[10], iv[10]);
+ LFSR[11] = MAKEU31(k[11], EK_d[11], iv[11]);
+ LFSR[12] = MAKEU31(k[12], EK_d[12], iv[12]);
+ LFSR[13] = MAKEU31(k[13], EK_d[13], iv[13]);
+ LFSR[14] = MAKEU31(k[14], EK_d[14], iv[14]);
+ LFSR[15] = MAKEU31(k[15], EK_d[15], iv[15]);
+ }
+
+ /**
+ * Process key and IV.
+ *
+ * @param k the key
+ * @param iv the IV
+ */
+ private void setKeyAndIV(final byte[] k,
+ final byte[] iv)
+ {
+ /* Initialise LFSR */
+ setKeyAndIV(LFSR, k, iv);
+
+ /* set F_R1 and F_R2 to zero */
+ F[0] = 0;
+ F[1] = 0;
+ int nCount = 32;
+ while (nCount > 0)
+ {
+ BitReorganization();
+ final int w = F();
+ LFSRWithInitialisationMode(w >>> 1);
+ nCount--;
+ }
+ BitReorganization();
+ F(); /* discard the output of F */
+ LFSRWithWorkMode();
+ }
+
+ /**
+ * Create the next byte keyStream.
+ */
+ private void makeKeyStream()
+ {
+ encode32be(makeKeyStreamWord(), keyStream, 0);
+ }
+
+ /**
+ * Create the next keyStream word.
+ *
+ * @return the next word
+ */
+ protected int makeKeyStreamWord()
+ {
+ if (theIterations++ >= getMaxIterations())
+ {
+ throw new IllegalStateException("Too much data processed by singleKey/IV");
+ }
+ BitReorganization();
+ final int result = F() ^ BRC[3];
+ LFSRWithWorkMode();
+ return result;
+ }
+
+ /**
+ * Create a copy of the engine.
+ *
+ * @return the copy
+ */
+ public Memoable copy()
+ {
+ return new Zuc128CoreEngine(this);
+ }
+
+ /**
+ * Reset from saved engine state.
+ *
+ * @param pState the state to restore
+ */
+ public void reset(final Memoable pState)
+ {
+ final Zuc128CoreEngine e = (Zuc128CoreEngine)pState;
+ System.arraycopy(e.LFSR, 0, LFSR, 0, LFSR.length);
+ System.arraycopy(e.F, 0, F, 0, F.length);
+ System.arraycopy(e.BRC, 0, BRC, 0, BRC.length);
+ System.arraycopy(e.keyStream, 0, keyStream, 0, keyStream.length);
+ theIndex = e.theIndex;
+ theIterations = e.theIterations;
+ theResetState = e;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Zuc256CoreEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Zuc256CoreEngine.java
new file mode 100644
index 0000000..a9fdeb1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Zuc256CoreEngine.java
@@ -0,0 +1,183 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.util.Memoable;
+
+/**
+ * Zuc256 implementation.
+ * Based on https://www.is.cas.cn/ztzl2016/zouchongzhi/201801/W020180126529970733243.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Zuc256CoreEngine
+ extends Zuc128CoreEngine
+{
+ /* the constants D */
+ private static final byte[] EK_d = new byte[]{
+ 0x22, 0x2f, 0x24, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100010, 0b0101111, 0b0100100, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /* the constants D for 32 bit Mac*/
+ private static final byte[] EK_d32 = new byte[]{
+ 0x22, 0x2f, 0x25, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100010, 0b0101111, 0b0100101, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /* the constants D for 64 bit Mac */
+ private static final byte[] EK_d64 = new byte[]{
+ 0x23, 0x2f, 0x24, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100011, 0b0101111, 0b0100100, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /* the constants D for 128 bit Mac */
+ private static final byte[] EK_d128 = new byte[]{
+ 0x23, 0x2f, 0x25, 0x2a, 0x6d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x52, 0x10, 0x30
+// 0b0100011, 0b0101111, 0b0100101, 0b0101010, 0b1101101, 0b1000000, 0b1000000, 0b1000000,
+// 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1000000, 0b1010010, 0b0010000, 0b0110000
+ };
+
+ /**
+ * The selected D constants.
+ */
+ private byte[] theD;
+
+ /**
+ * Constructor for streamCipher.
+ */
+ protected Zuc256CoreEngine()
+ {
+ theD = EK_d;
+ }
+
+ /**
+ * Constructor for Mac.
+ *
+ * @param pLength the Mac length
+ */
+ protected Zuc256CoreEngine(final int pLength)
+ {
+ switch (pLength)
+ {
+ case 32:
+ theD = EK_d32;
+ break;
+ case 64:
+ theD = EK_d64;
+ break;
+ case 128:
+ theD = EK_d128;
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported length: " + pLength);
+ }
+ }
+
+ /**
+ * Constructor for Memoable.
+ *
+ * @param pSource the source engine
+ */
+ protected Zuc256CoreEngine(final Zuc256CoreEngine pSource)
+ {
+ super(pSource);
+ }
+
+ /**
+ * Obtain Max iterations.
+ *
+ * @return the maximum iterations
+ */
+ protected int getMaxIterations()
+ {
+ return 625;
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc-256";
+ }
+
+ /**
+ * Build a 31-bit integer from constituent parts.
+ *
+ * @param a part A
+ * @param b part B
+ * @param c part C
+ * @param d part D
+ * @return the built integer
+ */
+ private static int MAKEU31(byte a, byte b, byte c, byte d)
+ {
+ return (((a & 0xFF) << 23) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | (d & 0xFF));
+ }
+
+ /**
+ * Process key and IV into LFSR.
+ *
+ * @param pLFSR the LFSR
+ * @param k the key
+ * @param iv the iv
+ */
+ protected void setKeyAndIV(final int[] pLFSR,
+ final byte[] k,
+ final byte[] iv)
+ {
+ /* Check lengths */
+ if (k == null || k.length != 32)
+ {
+ throw new IllegalArgumentException("A key of 32 bytes is needed");
+ }
+ if (iv == null || iv.length != 25)
+ {
+ throw new IllegalArgumentException("An IV of 25 bytes is needed");
+ }
+
+ /* expand key and IV */
+ pLFSR[0] = MAKEU31(k[0], theD[0], k[21], k[16]);
+ pLFSR[1] = MAKEU31(k[1], theD[1], k[22], k[17]);
+ pLFSR[2] = MAKEU31(k[2], theD[2], k[23], k[18]);
+ pLFSR[3] = MAKEU31(k[3], theD[3], k[24], k[19]);
+ pLFSR[4] = MAKEU31(k[4], theD[4], k[25], k[20]);
+ pLFSR[5] = MAKEU31(iv[0], (byte)(theD[5] | (iv[17] & 0x3F)), k[5], k[26]);
+ pLFSR[6] = MAKEU31(iv[1], (byte)(theD[6] | (iv[18] & 0x3F)), k[6], k[27]);
+ pLFSR[7] = MAKEU31(iv[10], (byte)(theD[7] | (iv[19] & 0x3F)), k[7], iv[2]);
+ pLFSR[8] = MAKEU31(k[8], (byte)(theD[8] | (iv[20] & 0x3F)), iv[3], iv[11]);
+ pLFSR[9] = MAKEU31(k[9], (byte)(theD[9] | (iv[21] & 0x3F)), iv[12], iv[4]);
+ pLFSR[10] = MAKEU31(iv[5], (byte)(theD[10] | (iv[22] & 0x3F)), k[10], k[28]);
+ pLFSR[11] = MAKEU31(k[11], (byte)(theD[11] | (iv[23] & 0x3F)), iv[6], iv[13]);
+ pLFSR[12] = MAKEU31(k[12], (byte)(theD[12] | (iv[24] & 0x3F)), iv[7], iv[14]);
+ pLFSR[13] = MAKEU31(k[13], theD[13], iv[15], iv[8]);
+ pLFSR[14] = MAKEU31(k[14], (byte)(theD[14] | ((k[31] >>> 4) & 0xF)), iv[16], iv[9]);
+ pLFSR[15] = MAKEU31(k[15], (byte)(theD[15] | (k[31] & 0xF)), k[30], k[29]);
+ }
+
+ /**
+ * Create a copy of the engine.
+ *
+ * @return the copy
+ */
+ public Memoable copy()
+ {
+ return new Zuc256CoreEngine(this);
+ }
+
+ /**
+ * Reset from saved engine state.
+ *
+ * @param pState the state to restore
+ */
+ public void reset(final Memoable pState)
+ {
+ final Zuc256CoreEngine e = (Zuc256CoreEngine)pState;
+ super.reset(pState);
+ theD = e.theD;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Zuc256Engine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Zuc256Engine.java
new file mode 100644
index 0000000..5b58ec5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/Zuc256Engine.java
@@ -0,0 +1,51 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.util.Memoable;
+
+/**
+ * Zuc256 implementation.
+ * Based on https://www.is.cas.cn/ztzl2016/zouchongzhi/201801/W020180126529970733243.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Zuc256Engine
+ extends Zuc256CoreEngine
+{
+ /**
+ * Constructor for streamCipher.
+ */
+ public Zuc256Engine()
+ {
+ super();
+ }
+
+ /**
+ * Constructor for Mac.
+ *
+ * @param pLength the Mac length
+ */
+ public Zuc256Engine(final int pLength)
+ {
+ super(pLength);
+ }
+
+ /**
+ * Constructor for Memoable.
+ *
+ * @param pSource the source engine
+ */
+ private Zuc256Engine(final Zuc256Engine pSource)
+ {
+ super(pSource);
+ }
+
+ /**
+ * Create a copy of the engine.
+ *
+ * @return the copy
+ */
+ public Memoable copy()
+ {
+ return new Zuc256Engine(this);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESKeyGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESKeyGenerator.java
index 3a5090a..2b2c1a3 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESKeyGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESKeyGenerator.java
@@ -2,7 +2,10 @@
package com.android.internal.org.bouncycastle.crypto.generators;
import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.DESParameters;
/**
@@ -33,6 +36,8 @@
+ (DESParameters.DES_KEY_LENGTH * 8)
+ " bits long.");
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DESKeyGen", 56, null, CryptoServicePurpose.KEYGEN));
}
public byte[] generateKey()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
index c718a7d..836e2aa 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
@@ -1,7 +1,10 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.generators;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.DESedeParameters;
/**
@@ -43,6 +46,8 @@
+ (2 * 8 * DESedeParameters.DES_KEY_LENGTH)
+ " bits long.");
}
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DESedeKeyGen", 112, null, CryptoServicePurpose.KEYGEN));
}
public byte[] generateKey()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java
index 75d1e3c..ee4c402 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java
@@ -1,16 +1,20 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.generators;
+import java.math.BigInteger;
+
import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.DHKeyGenerationParameters;
import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
import com.android.internal.org.bouncycastle.crypto.params.DHPublicKeyParameters;
-import java.math.BigInteger;
-
/**
* a basic Diffie-Hellman key pair generator.
*
@@ -27,6 +31,8 @@
KeyGenerationParameters param)
{
this.param = (DHKeyGenerationParameters)param;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DHBasicKeyGen", ConstraintUtils.bitsOfSecurityFor(this.param.getParameters().getP()), this.param.getParameters(), CryptoServicePurpose.KEYGEN));
}
public AsymmetricCipherKeyPair generateKeyPair()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java
index 570d45a..5f10d67 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java
@@ -6,7 +6,11 @@
import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.DSAKeyGenerationParameters;
import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
import com.android.internal.org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
@@ -32,6 +36,8 @@
KeyGenerationParameters param)
{
this.param = (DSAKeyGenerationParameters)param;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("DSAKeyGen", ConstraintUtils.bitsOfSecurityFor(this.param.getParameters().getP()), this.param.getParameters(), CryptoServicePurpose.KEYGEN));
}
public AsymmetricCipherKeyPair generateKeyPair()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
index 1b649eb..79d16ef 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
@@ -6,7 +6,11 @@
import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
import com.android.internal.org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
@@ -24,9 +28,20 @@
public class ECKeyPairGenerator
implements AsymmetricCipherKeyPairGenerator, ECConstants
{
+ private final String name;
ECDomainParameters params;
SecureRandom random;
+ public ECKeyPairGenerator()
+ {
+ this("ECKeyGen");
+ }
+
+ protected ECKeyPairGenerator(String name)
+ {
+ this.name = name;
+ }
+
public void init(
KeyGenerationParameters param)
{
@@ -34,6 +49,8 @@
this.random = ecP.getRandom();
this.params = ecP.getDomainParameters();
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(name, ConstraintUtils.bitsOfSecurityFor(this.params.getCurve()), ecP.getDomainParameters(), CryptoServicePurpose.KEYGEN));
}
/**
@@ -51,7 +68,7 @@
{
d = BigIntegers.createRandomBigInteger(nBitLength, random);
- if (d.compareTo(ONE) < 0 || (d.compareTo(n) >= 0))
+ if (isOutOfRangeD(d, n))
{
continue;
}
@@ -71,6 +88,11 @@
new ECPrivateKeyParameters(d, params));
}
+ protected boolean isOutOfRangeD(BigInteger d, BigInteger n)
+ {
+ return d.compareTo(ONE) < 0 || (d.compareTo(n) >= 0);
+ }
+
protected ECMultiplier createBasePointMultiplier()
{
return new FixedPointCombMultiplier();
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
index 43b5b5c..c336379 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
@@ -13,8 +13,9 @@
/**
* Generator for PBE derived keys and ivs as usd by OpenSSL.
* <p>
- * The scheme is a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an
- * iteration count of 1.
+ * Originally this scheme was a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an
+ * iteration count of 1. The default digest was changed to SHA-256 with OpenSSL 1.1.0. This
+ * implementation still defaults to MD5, but the digest can now be set.
* <p>
* @hide This class is not part of the Android public SDK API
*/
@@ -26,7 +27,7 @@
private Digest digest = AndroidDigestFactory.getMD5();
/**
- * Construct a OpenSSL Parameters generator.
+ * Construct a OpenSSL Parameters generator.
*/
public OpenSSLPBEParametersGenerator()
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
index 86a62fe..9552ffe 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
@@ -5,7 +5,11 @@
import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import com.android.internal.org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
import com.android.internal.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
@@ -27,6 +31,8 @@
public void init(KeyGenerationParameters param)
{
this.param = (RSAKeyGenerationParameters)param;
+
+ CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("RSAKeyGen", ConstraintUtils.bitsOfSecurityForFF(param.getStrength()), null, CryptoServicePurpose.KEYGEN));
}
public AsymmetricCipherKeyPair generateKeyPair()
@@ -93,12 +99,12 @@
continue;
}
- /*
+ /*
* Require a minimum weight of the NAF representation, since low-weight composites may
- * be weak against a version of the number-field-sieve for factoring.
- *
- * See "The number field sieve for integers of low weight", Oliver Schirokauer.
- */
+ * be weak against a version of the number-field-sieve for factoring.
+ *
+ * See "The number field sieve for integers of low weight", Oliver Schirokauer.
+ */
if (WNafUtil.getNafWeight(n) < minWeight)
{
p = chooseRandomPrime(pbitlength, e, squaredBound);
@@ -144,8 +150,8 @@
qInv = BigIntegers.modOddInverse(p, q);
result = new AsymmetricCipherKeyPair(
- new RSAKeyParameters(false, n, e),
- new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv));
+ new RSAKeyParameters(false, n, e, true),
+ new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv, true));
}
return result;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/SM2KeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/SM2KeyPairGenerator.java
new file mode 100644
index 0000000..35815e2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/SM2KeyPairGenerator.java
@@ -0,0 +1,40 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECKeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECMultiplier;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.ec.FixedPointCombMultiplier;
+import com.android.internal.org.bouncycastle.math.ec.WNafUtil;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SM2KeyPairGenerator
+ extends ECKeyPairGenerator
+{
+ public SM2KeyPairGenerator()
+ {
+ super("SM2KeyGen");
+ }
+
+ protected boolean isOutOfRangeD(BigInteger d, BigInteger n)
+ {
+ return d.compareTo(ONE) < 0 || (d.compareTo(n.subtract(BigIntegers.ONE)) >= 0);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java
index 38efe5c..5b83b75 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java
@@ -94,7 +94,7 @@
throw new IllegalArgumentException("MAC size must be multiple of 8");
}
- this.cipher = new CBCBlockCipher(cipher);
+ this.cipher = CBCBlockCipher.newInstance(cipher);
this.padding = padding;
this.macSize = macSizeInBits / 8;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/HMac.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/HMac.java
index c88919b..0f5ff11 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/HMac.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/HMac.java
@@ -218,15 +218,15 @@
*/
public void reset()
{
- /*
- * reset the underlying digest.
- */
- digest.reset();
-
- /*
- * reinitialize the digest.
- */
- digest.update(inputPad, 0, inputPad.length);
+ if (ipadState != null)
+ {
+ ((Memoable)digest).reset(ipadState);
+ }
+ else
+ {
+ digest.reset();
+ digest.update(inputPad, 0, inputPad.length);
+ }
}
private static void xorPad(byte[] pad, int len, byte n)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/Zuc128Mac.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/Zuc128Mac.java
new file mode 100644
index 0000000..64fee91
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/Zuc128Mac.java
@@ -0,0 +1,247 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.macs;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.Mac;
+import com.android.internal.org.bouncycastle.crypto.engines.Zuc128CoreEngine;
+
+/**
+ * Zuc128 Mac implementation.
+ * Based on https://www.qtc.jp/3GPP/Specs/eea3eia3specificationv16.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Zuc128Mac
+ implements Mac
+{
+ /**
+ * The Maximum Bit Mask.
+ */
+ private static final int TOPBIT = 0x80;
+
+ /**
+ * The Zuc128 Engine.
+ */
+ private final InternalZuc128Engine theEngine;
+
+ /**
+ * The calculated Mac in words.
+ */
+ private int theMac;
+
+ /**
+ * The active keyStream.
+ */
+ private final int[] theKeyStream;
+
+ /**
+ * The initialised state.
+ */
+ private Zuc128CoreEngine theState;
+
+ /**
+ * The current word index.
+ */
+ private int theWordIndex;
+
+ /**
+ * The current byte index.
+ */
+ private int theByteIndex;
+
+ /**
+ * Constructor.
+ */
+ public Zuc128Mac()
+ {
+ theEngine = new InternalZuc128Engine();
+ theKeyStream = new int[2];
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc128Mac";
+ }
+
+ /**
+ * Obtain Mac Size.
+ *
+ * @return the size in Bytes
+ */
+ public int getMacSize()
+ {
+ return 4; // Integer.Bytes
+ }
+
+ /**
+ * Initialise the Mac.
+ *
+ * @param pParams the parameters
+ */
+ public void init(final CipherParameters pParams)
+ {
+ /* Initialise the engine */
+ theEngine.init(true, pParams);
+ theState = (Zuc128CoreEngine)theEngine.copy();
+ initKeyStream();
+ }
+
+ /**
+ * Initialise the keyStream.
+ */
+ private void initKeyStream()
+ {
+ /* Initialise the Mac */
+ theMac = 0;
+
+ /* Initialise the KeyStream */
+ for (int i = 0; i < theKeyStream.length - 1; i++)
+ {
+ theKeyStream[i] = theEngine.createKeyStreamWord();
+ }
+ theWordIndex = theKeyStream.length - 1;
+ theByteIndex = 3; //Integer.BYTES - 1;
+ }
+
+ /**
+ * Update the mac with a single byte.
+ *
+ * @param in the byte to update with
+ */
+ public void update(final byte in)
+ {
+ /* shift for next byte */
+ shift4NextByte();
+
+ /* Loop through the bits */
+ final int bitBase = theByteIndex * 8; //Byte.SIZE;
+ for (int bitMask = TOPBIT, bitNo = 0; bitMask > 0; bitMask >>= 1, bitNo++)
+ {
+ /* If the bit is set */
+ if ((in & bitMask) != 0)
+ {
+ /* update theMac */
+ updateMac(bitBase + bitNo);
+ }
+ }
+ }
+
+ /**
+ * Shift for next byte.
+ */
+ private void shift4NextByte()
+ {
+ /* Adjust the byte index */
+ theByteIndex = (theByteIndex + 1) % 4; //Integer.BYTES;
+
+ /* Adjust keyStream if required */
+ if (theByteIndex == 0)
+ {
+ theKeyStream[theWordIndex] = theEngine.createKeyStreamWord();
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ }
+ }
+
+ /**
+ * Update the Mac.
+ *
+ * @param bitNo the bit number
+ */
+ private void updateMac(final int bitNo)
+ {
+ /* Update the Mac */
+ theMac ^= getKeyStreamWord(bitNo);
+ }
+
+ /**
+ * Obtain the keyStreamWord.
+ *
+ * @param bitNo the bitNumber
+ * @return the word
+ */
+ private int getKeyStreamWord(final int bitNo)
+ {
+ /* Access the first word and return it if this is bit 0 */
+ final int myFirst = theKeyStream[theWordIndex];
+ if (bitNo == 0)
+ {
+ return myFirst;
+ }
+
+ /* Access the second word */
+ final int mySecond = theKeyStream[(theWordIndex + 1) % theKeyStream.length];
+ return (myFirst << bitNo) | (mySecond >>> (32 - bitNo)); // Integer.SIZE - bitNo
+ }
+
+ /**
+ * Update the mac.
+ *
+ * @param in the input buffer
+ * @param inOff the starting offset in the input buffer
+ * @param len the length of data to process
+ */
+ public void update(final byte[] in, final int inOff, final int len)
+ {
+ for (int byteNo = 0; byteNo < len; byteNo++)
+ {
+ update(in[inOff + byteNo]);
+ }
+ }
+
+ /**
+ * Obtain the final word.
+ *
+ * @return the final word
+ */
+ private int getFinalWord()
+ {
+ if (theByteIndex != 0)
+ {
+ return theEngine.createKeyStreamWord();
+ }
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ return theKeyStream[theWordIndex];
+ }
+
+ /**
+ * Finalize the mac.
+ *
+ * @param out the output buffer
+ * @param outOff the starting offset in the input buffer
+ * @return the size of the mac
+ */
+ public int doFinal(final byte[] out, final int outOff)
+ {
+ /* Finish the Mac and output it */
+ shift4NextByte();
+ theMac ^= getKeyStreamWord(theByteIndex * 8); //Byte.SIZE
+ theMac ^= getFinalWord();
+ Zuc128CoreEngine.encode32be(theMac, out, outOff);
+
+ /* Reset the Mac */
+ reset();
+ return getMacSize();
+ }
+
+ public void reset()
+ {
+ if (theState != null)
+ {
+ theEngine.reset(theState);
+ }
+ initKeyStream();
+ }
+
+ private static class InternalZuc128Engine
+ extends Zuc128CoreEngine
+ {
+ int createKeyStreamWord()
+ {
+ return super.makeKeyStreamWord();
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/Zuc256Mac.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/Zuc256Mac.java
new file mode 100644
index 0000000..afd00f5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/Zuc256Mac.java
@@ -0,0 +1,276 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.macs;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.Mac;
+import com.android.internal.org.bouncycastle.crypto.engines.Zuc256CoreEngine;
+
+/**
+ * Zuc256 Mac implementation.
+ * Based on https://www.is.cas.cn/ztzl2016/zouchongzhi/201801/W020180126529970733243.pdf
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Zuc256Mac
+ implements Mac
+{
+ /**
+ * The Maximum Bit Mask.
+ */
+ private static final int TOPBIT = 0x80;
+
+ /**
+ * The Zuc256 Engine.
+ */
+ private final InternalZuc256Engine theEngine;
+
+ /**
+ * The mac length.
+ */
+ private final int theMacLength;
+
+ /**
+ * The calculated Mac in words.
+ */
+ private final int[] theMac;
+
+ /**
+ * The active keyStream.
+ */
+ private final int[] theKeyStream;
+
+ /**
+ * The initialised state.
+ */
+ private Zuc256CoreEngine theState;
+
+ /**
+ * The current word index.
+ */
+ private int theWordIndex;
+
+ /**
+ * The current byte index.
+ */
+ private int theByteIndex;
+
+ /**
+ * Constructor.
+ *
+ * @param pLength the bit length of the Mac
+ */
+ public Zuc256Mac(final int pLength)
+ {
+ theEngine = new InternalZuc256Engine(pLength);
+ theMacLength = pLength;
+ final int numWords = pLength / 32; // Integer.SIZE
+ theMac = new int[numWords];
+ theKeyStream = new int[numWords + 1];
+ }
+
+ /**
+ * Obtain Algorithm Name.
+ *
+ * @return the name
+ */
+ public String getAlgorithmName()
+ {
+ return "Zuc256Mac-" + theMacLength;
+ }
+
+ /**
+ * Obtain Mac Size.
+ *
+ * @return the size in Bytes
+ */
+ public int getMacSize()
+ {
+ return theMacLength / 8; //Byte.SIZE
+ }
+
+ /**
+ * Initialise the Mac.
+ *
+ * @param pParams the parameters
+ */
+ public void init(final CipherParameters pParams)
+ {
+ /* Initialise the engine */
+ theEngine.init(true, pParams);
+ theState = (Zuc256CoreEngine)theEngine.copy();
+ initKeyStream();
+ }
+
+ /**
+ * Initialise the keyStream.
+ */
+ private void initKeyStream()
+ {
+ /* Initialise the Mac */
+ for (int i = 0; i < theMac.length; i++)
+ {
+ theMac[i] = theEngine.createKeyStreamWord();
+ }
+
+ /* Initialise the KeyStream */
+ for (int i = 0; i < theKeyStream.length - 1; i++)
+ {
+ theKeyStream[i] = theEngine.createKeyStreamWord();
+ }
+ theWordIndex = theKeyStream.length - 1;
+ theByteIndex = 4 - 1; // Integer.SIZE
+ }
+
+ /**
+ * Update the mac with a single byte.
+ *
+ * @param in the byte to update with
+ */
+ public void update(final byte in)
+ {
+ /* shift for next byte */
+ shift4NextByte();
+
+ /* Loop through the bits */
+ final int bitBase = theByteIndex * 8; //Byte.SIZE;
+ for (int bitMask = TOPBIT, bitNo = 0; bitMask > 0; bitMask >>= 1, bitNo++)
+ {
+ /* If the bit is set */
+ if ((in & bitMask) != 0)
+ {
+ /* update theMac */
+ updateMac(bitBase + bitNo);
+ }
+ }
+ }
+
+ /**
+ * Shift for next byte.
+ */
+ private void shift4NextByte()
+ {
+ /* Adjust the byte index */
+ theByteIndex = (theByteIndex + 1) % 4; //Integer.BYTES
+
+ /* Adjust keyStream if required */
+ if (theByteIndex == 0)
+ {
+ theKeyStream[theWordIndex] = theEngine.createKeyStreamWord();
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ }
+ }
+
+ /**
+ * Shift for final update.
+ */
+ private void shift4Final()
+ {
+ /* Adjust the byte index */
+ theByteIndex = (theByteIndex + 1) % 4; //Integer.BYTES
+
+ /* No need to read another word to the keyStream */
+ if (theByteIndex == 0)
+ {
+ theWordIndex = (theWordIndex + 1) % theKeyStream.length;
+ }
+ }
+
+ /**
+ * Update the Mac.
+ *
+ * @param bitNo the bit number
+ */
+ private void updateMac(final int bitNo)
+ {
+ /* Loop through the Mac */
+ for (int wordNo = 0; wordNo < theMac.length; wordNo++)
+ {
+ theMac[wordNo] ^= getKeyStreamWord(wordNo, bitNo);
+ }
+ }
+
+ /**
+ * Obtain the keyStreamWord.
+ *
+ * @param wordNo the wordNumber
+ * @param bitNo the bitNumber
+ * @return the word
+ */
+ private int getKeyStreamWord(final int wordNo, final int bitNo)
+ {
+ /* Access the first word and return it if this is bit 0 */
+ final int myFirst = theKeyStream[(theWordIndex + wordNo) % theKeyStream.length];
+ if (bitNo == 0)
+ {
+ return myFirst;
+ }
+
+ /* Access the second word */
+ final int mySecond = theKeyStream[(theWordIndex + wordNo + 1) % theKeyStream.length];
+ return (myFirst << bitNo) | (mySecond >>> (32 - bitNo)); //Integer.SIZE - bitNo
+ }
+
+ /**
+ * Update the mac.
+ *
+ * @param in the input buffer
+ * @param inOff the starting offset in the input buffer
+ * @param len the length of data to process
+ */
+ public void update(final byte[] in, final int inOff, final int len)
+ {
+ for (int byteNo = 0; byteNo < len; byteNo++)
+ {
+ update(in[inOff + byteNo]);
+ }
+ }
+
+ /**
+ * Finalize the mac.
+ *
+ * @param out the output buffer
+ * @param outOff the starting offset in the output buffer
+ * @return the size of the mac
+ */
+ public int doFinal(final byte[] out, final int outOff)
+ {
+ /* shift for final update */
+ shift4Final();
+
+ /* Finish the Mac and output it */
+ updateMac(theByteIndex * 8); //Byte.SIZE)
+ for (int i = 0; i < theMac.length; i++)
+ {
+ Zuc256CoreEngine.encode32be(theMac[i], out, outOff + i * 4); //Integer.BYTES)
+ }
+
+ /* Reset the Mac */
+ reset();
+ return getMacSize();
+ }
+
+ /**
+ * Reset the Mac.
+ */
+ public void reset()
+ {
+ if (theState != null)
+ {
+ theEngine.reset(theState);
+ }
+ initKeyStream();
+ }
+
+ private static class InternalZuc256Engine
+ extends Zuc256CoreEngine
+ {
+ public InternalZuc256Engine(int pLength)
+ {
+ super(pLength);
+ }
+
+ int createKeyStreamWord()
+ {
+ return super.makeKeyStreamWord();
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CBCBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CBCBlockCipher.java
index d767a6a..4c6aa12 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CBCBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CBCBlockCipher.java
@@ -4,6 +4,7 @@
import com.android.internal.org.bouncycastle.crypto.BlockCipher;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.DefaultMultiBlockCipher;
import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
import com.android.internal.org.bouncycastle.util.Arrays;
@@ -12,7 +13,8 @@
* @hide This class is not part of the Android public SDK API
*/
public class CBCBlockCipher
- implements BlockCipher
+ extends DefaultMultiBlockCipher
+ implements CBCModeCipher
{
private byte[] IV;
private byte[] cbcV;
@@ -23,9 +25,20 @@
private boolean encrypting;
/**
+ * Return a new CBC mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the CBC mode.
+ */
+ public static CBCModeCipher newInstance(BlockCipher cipher)
+ {
+ return new CBCBlockCipher(cipher);
+ }
+
+ /**
* Basic constructor.
*
* @param cipher the block cipher to be used as the basis of chaining.
+ * @deprecated use the CBCBlockCipher.newInstance() static method.
*/
public CBCBlockCipher(
BlockCipher cipher)
@@ -79,31 +92,23 @@
System.arraycopy(iv, 0, IV, 0, iv.length);
- reset();
-
- // if null it's an IV changed only.
- if (ivParam.getParameters() != null)
- {
- cipher.init(encrypting, ivParam.getParameters());
- }
- else if (oldEncrypting != encrypting)
- {
- throw new IllegalArgumentException("cannot change encrypting state without providing key.");
- }
+ params = ivParam.getParameters();
}
else
{
- reset();
+ Arrays.fill(IV, (byte)0);
+ }
- // if it's null, key is to be reused.
- if (params != null)
- {
- cipher.init(encrypting, params);
- }
- else if (oldEncrypting != encrypting)
- {
- throw new IllegalArgumentException("cannot change encrypting state without providing key.");
- }
+ reset();
+
+ // if null it's an IV changed only (key is to be reused).
+ if (params != null)
+ {
+ cipher.init(encrypting, params);
+ }
+ else if (oldEncrypting != encrypting)
+ {
+ throw new IllegalArgumentException("cannot change encrypting state without providing key.");
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CBCModeCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CBCModeCipher.java
new file mode 100644
index 0000000..d88d300
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CBCModeCipher.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.MultiBlockCipher;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CBCModeCipher
+ extends MultiBlockCipher
+{
+ /**
+ * return the underlying block cipher that we are wrapping.
+ *
+ * @return the underlying block cipher that we are wrapping.
+ */
+ BlockCipher getUnderlyingCipher();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMBlockCipher.java
index f93c727..affcb17 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMBlockCipher.java
@@ -22,7 +22,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class CCMBlockCipher
- implements AEADBlockCipher
+ implements CCMModeCipher
{
private BlockCipher cipher;
private int blockSize;
@@ -36,9 +36,20 @@
private ExposedByteArrayOutputStream data = new ExposedByteArrayOutputStream();
/**
+ * Return a new CCM mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the CCM mode.
+ */
+ public static CCMModeCipher newInstance(BlockCipher cipher)
+ {
+ return new CCMBlockCipher(cipher);
+ }
+
+ /**
* Basic constructor.
*
* @param c the block cipher to be used.
+ * @deprecated use the CCMBlockCipher.newInstance() static method.
*/
public CCMBlockCipher(BlockCipher c)
{
@@ -262,7 +273,7 @@
iv[0] = (byte)((q - 1) & 0x7);
System.arraycopy(nonce, 0, iv, 1, nonce.length);
- BlockCipher ctrCipher = new SICBlockCipher(cipher);
+ BlockCipher ctrCipher = SICBlockCipher.newInstance(cipher);
ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv));
int outputLen;
@@ -456,7 +467,7 @@
return getAssociatedTextLength() > 0;
}
- private class ExposedByteArrayOutputStream
+ private static class ExposedByteArrayOutputStream
extends ByteArrayOutputStream
{
public ExposedByteArrayOutputStream()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMModeCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMModeCipher.java
new file mode 100644
index 0000000..ebdcb7e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMModeCipher.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CCMModeCipher
+ extends AEADBlockCipher
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java
index d8f51e3..61f3652 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java
@@ -14,6 +14,7 @@
*/
public class CFBBlockCipher
extends StreamBlockCipher
+ implements CFBModeCipher
{
private byte[] IV;
private byte[] cfbV;
@@ -26,11 +27,23 @@
private int byteCount;
/**
+ * Return a new CFB mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the CFB mode.
+ * @param blockSize the block size (in bits) used for the CFB mode.
+ */
+ public static CFBModeCipher newInstance(BlockCipher cipher, int blockSize)
+ {
+ return new CFBBlockCipher(cipher, blockSize);
+ }
+
+ /**
* Basic constructor.
*
* @param cipher the block cipher to be used as the basis of the
* feedback mode.
* @param bitBlockSize the block size in bits (note: a multiple of 8)
+ * @deprecated use the equivalent CFBBlockCipher.newInstance() static method.
*/
public CFBBlockCipher(
BlockCipher cipher,
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBModeCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBModeCipher.java
new file mode 100644
index 0000000..23a16c8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBModeCipher.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import com.android.internal.org.bouncycastle.crypto.MultiBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.StreamCipher;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CFBModeCipher
+ extends MultiBlockCipher, StreamCipher
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CTRModeCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CTRModeCipher.java
new file mode 100644
index 0000000..21b766f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CTRModeCipher.java
@@ -0,0 +1,20 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.MultiBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.SkippingStreamCipher;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CTRModeCipher
+ extends MultiBlockCipher, SkippingStreamCipher
+{
+ /**
+ * return the underlying block cipher that we are wrapping.
+ *
+ * @return the underlying block cipher that we are wrapping.
+ */
+ BlockCipher getUnderlyingCipher();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CTSBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CTSBlockCipher.java
index a277ae2..3fc15c0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CTSBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CTSBlockCipher.java
@@ -2,8 +2,8 @@
package com.android.internal.org.bouncycastle.crypto.modes;
import com.android.internal.org.bouncycastle.crypto.BlockCipher;
-import com.android.internal.org.bouncycastle.crypto.BufferedBlockCipher;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
import com.android.internal.org.bouncycastle.crypto.StreamBlockCipher;
@@ -14,7 +14,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class CTSBlockCipher
- extends BufferedBlockCipher
+ extends DefaultBufferedBlockCipher
{
private int blockSize;
@@ -223,9 +223,9 @@
buf[i] ^= block[i - blockSize];
}
- if (cipher instanceof CBCBlockCipher)
+ if (cipher instanceof CBCModeCipher)
{
- BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher();
+ BlockCipher c = ((CBCModeCipher)cipher).getUnderlyingCipher();
c.processBlock(buf, blockSize, out, outOff);
}
@@ -252,9 +252,9 @@
if (bufOff > blockSize)
{
- if (cipher instanceof CBCBlockCipher)
+ if (cipher instanceof CBCModeCipher)
{
- BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher();
+ BlockCipher c = ((CBCModeCipher)cipher).getUnderlyingCipher();
c.processBlock(buf, 0, block, 0);
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMBlockCipher.java
index e74dd6b..fdf8cf9 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMBlockCipher.java
@@ -23,7 +23,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class GCMBlockCipher
- implements AEADBlockCipher
+ implements GCMModeCipher
{
private static final int BLOCK_SIZE = 16;
// BEGIN Android-added: Max input size limitation from NIST.
@@ -60,11 +60,45 @@
private long atLength;
private long atLengthPre;
+ /**
+ * Return a new GCM mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the GCM mode.
+ */
+ public static GCMModeCipher newInstance(BlockCipher cipher)
+ {
+ return new GCMBlockCipher(cipher);
+ }
+
+ /**
+ * Return a new GCM mode cipher based on the passed in base cipher and multiplier.
+ *
+ * @param cipher the base cipher for the GCM mode.
+ * @param m the GCM multiplier to use.
+ */
+ public static GCMModeCipher newInstance(BlockCipher cipher, GCMMultiplier m)
+ {
+ return new GCMBlockCipher(cipher, m);
+ }
+
+ /**
+ * Base constructor - GCM mode over base cipher c.
+ *
+ * @param c the base cipher.
+ * @deprecated use the GCMBlockCipher.newInstance() static method.
+ */
public GCMBlockCipher(BlockCipher c)
{
this(c, null);
}
+ /**
+ * Base constructor - GCM mode over base cipher c over base multiplier m.
+ *
+ * @param c the base cipher.
+ * @param m the GCM multiplier to use.
+ * @deprecated use the CBCBlockCipher.newInstance() static method.
+ */
public GCMBlockCipher(BlockCipher c, GCMMultiplier m)
{
if (c.getBlockSize() != BLOCK_SIZE)
@@ -289,17 +323,35 @@
}
// END Android-added: Max input size limitation from NIST.
- for (int i = 0; i < len; ++i)
+ if (atBlockPos > 0)
{
- atBlock[atBlockPos] = in[inOff + i];
- if (++atBlockPos == BLOCK_SIZE)
+ int available = BLOCK_SIZE - atBlockPos;
+ if (len < available)
{
- // Hash each block as it fills
- gHASHBlock(S_at, atBlock);
- atBlockPos = 0;
- atLength += BLOCK_SIZE;
+ System.arraycopy(in, inOff, atBlock, atBlockPos, len);
+ atBlockPos += len;
+ return;
}
+
+ System.arraycopy(in, inOff, atBlock, atBlockPos, available);
+ gHASHBlock(S_at, atBlock);
+ atLength += BLOCK_SIZE;
+ inOff += available;
+ len -= available;
+ //atBlockPos = 0;
}
+
+ int inLimit = inOff + len - BLOCK_SIZE;
+
+ while (inOff <= inLimit)
+ {
+ gHASHBlock(S_at, in, inOff);
+ atLength += BLOCK_SIZE;
+ inOff += BLOCK_SIZE;
+ }
+
+ atBlockPos = BLOCK_SIZE + inLimit - inOff;
+ System.arraycopy(in, inOff, atBlock, 0, atBlockPos);
}
private void initCipher()
@@ -336,13 +388,14 @@
bufBlock[bufOff] = in;
if (++bufOff == bufBlock.length)
{
- processBlock(bufBlock, 0, out, outOff);
if (forEncryption)
{
+ encryptBlock(bufBlock, 0, out, outOff);
bufOff = 0;
}
else
{
+ decryptBlock(bufBlock, 0, out, outOff);
System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize);
bufOff = macSize;
}
@@ -370,49 +423,79 @@
if (forEncryption)
{
- if (bufOff != 0)
+ if (bufOff > 0)
{
- while (len > 0)
+ int available = BLOCK_SIZE - bufOff;
+ if (len < available)
{
- --len;
- bufBlock[bufOff] = in[inOff++];
- if (++bufOff == BLOCK_SIZE)
- {
- processBlock(bufBlock, 0, out, outOff);
- bufOff = 0;
- resultLen += BLOCK_SIZE;
- break;
- }
+ System.arraycopy(in, inOff, bufBlock, bufOff, len);
+ bufOff += len;
+ return 0;
}
+
+ System.arraycopy(in, inOff, bufBlock, bufOff, available);
+ encryptBlock(bufBlock, 0, out, outOff);
+ inOff += available;
+ len -= available;
+ resultLen = BLOCK_SIZE;
+ //bufOff = 0;
}
- while (len >= BLOCK_SIZE)
+ int inLimit = inOff + len - BLOCK_SIZE;
+
+ while (inOff <= inLimit)
{
- processBlock(in, inOff, out, outOff + resultLen);
+ encryptBlock(in, inOff, out, outOff + resultLen);
inOff += BLOCK_SIZE;
- len -= BLOCK_SIZE;
resultLen += BLOCK_SIZE;
}
- if (len > 0)
- {
- System.arraycopy(in, inOff, bufBlock, 0, len);
- bufOff = len;
- }
+ bufOff = BLOCK_SIZE + inLimit - inOff;
+ System.arraycopy(in, inOff, bufBlock, 0, bufOff);
}
else
{
- for (int i = 0; i < len; ++i)
+ int available = bufBlock.length - bufOff;
+ if (len < available)
{
- bufBlock[bufOff] = in[inOff + i];
- if (++bufOff == bufBlock.length)
+ System.arraycopy(in, inOff, bufBlock, bufOff, len);
+ bufOff += len;
+ return 0;
+ }
+
+ if (bufOff >= BLOCK_SIZE)
+ {
+ decryptBlock(bufBlock, 0, out, outOff);
+ System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, bufOff -= BLOCK_SIZE);
+ resultLen = BLOCK_SIZE;
+
+ available += BLOCK_SIZE;
+ if (len < available)
{
- processBlock(bufBlock, 0, out, outOff + resultLen);
- System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize);
- bufOff = macSize;
- resultLen += BLOCK_SIZE;
+ System.arraycopy(in, inOff, bufBlock, bufOff, len);
+ bufOff += len;
+ return resultLen;
}
}
+
+ int inLimit = inOff + len - bufBlock.length;
+
+ available = BLOCK_SIZE - bufOff;
+ System.arraycopy(in, inOff, bufBlock, bufOff, available);
+ decryptBlock(bufBlock, 0, out, outOff + resultLen);
+ inOff += available;
+ resultLen += BLOCK_SIZE;
+ //bufOff = 0;
+
+ while (inOff <= inLimit)
+ {
+ decryptBlock(in, inOff, out, outOff + resultLen);
+ inOff += BLOCK_SIZE;
+ resultLen += BLOCK_SIZE;
+ }
+
+ bufOff = bufBlock.length + inLimit - inOff;
+ System.arraycopy(in, inOff, bufBlock, 0, bufOff);
}
return resultLen;
@@ -585,7 +668,7 @@
}
}
- private void processBlock(byte[] buf, int bufOff, byte[] out, int outOff)
+ private void decryptBlock(byte[] buf, int bufOff, byte[] out, int outOff)
{
if ((out.length - outOff) < BLOCK_SIZE)
{
@@ -599,18 +682,30 @@
byte[] ctrBlock = new byte[BLOCK_SIZE];
getNextCTRBlock(ctrBlock);
- if (forEncryption)
+ gHASHBlock(S, buf, bufOff);
+ GCMUtil.xor(ctrBlock, 0, buf, bufOff, out, outOff);
+
+ totalLength += BLOCK_SIZE;
+ }
+
+ private void encryptBlock(byte[] buf, int bufOff, byte[] out, int outOff)
+ {
+ if ((out.length - outOff) < BLOCK_SIZE)
{
- GCMUtil.xor(ctrBlock, buf, bufOff);
- gHASHBlock(S, ctrBlock);
- System.arraycopy(ctrBlock, 0, out, outOff, BLOCK_SIZE);
+ throw new OutputLengthException("Output buffer too short");
}
- else
+ if (totalLength == 0)
{
- gHASHBlock(S, buf, bufOff);
- GCMUtil.xor(ctrBlock, 0, buf, bufOff, out, outOff);
+ initCipher();
}
+ byte[] ctrBlock = new byte[BLOCK_SIZE];
+
+ getNextCTRBlock(ctrBlock);
+ GCMUtil.xor(ctrBlock, buf, bufOff);
+ gHASHBlock(S, ctrBlock);
+ System.arraycopy(ctrBlock, 0, out, outOff, BLOCK_SIZE);
+
totalLength += BLOCK_SIZE;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMModeCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMModeCipher.java
new file mode 100644
index 0000000..13b5f18
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMModeCipher.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface GCMModeCipher
+ extends AEADBlockCipher
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java
new file mode 100644
index 0000000..6faf7a8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMSIVBlockCipher.java
@@ -0,0 +1,973 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.engines.AESEngine;
+import com.android.internal.org.bouncycastle.crypto.modes.gcm.GCMMultiplier;
+import com.android.internal.org.bouncycastle.crypto.modes.gcm.Tables4kGCMMultiplier;
+import com.android.internal.org.bouncycastle.crypto.params.AEADParameters;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Bytes;
+import com.android.internal.org.bouncycastle.util.Integers;
+import com.android.internal.org.bouncycastle.util.Longs;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * GCM-SIV Mode.
+ * <p>It should be noted that the specified limit of 2<sup>36</sup> bytes is not supported. This is because all bytes are
+ * cached in a <b>ByteArrayOutputStream</b> object (which has a limit of a little less than 2<sup>31</sup> bytes),
+ * and are output on the <b>doFinal</b>() call (which can only process a maximum of 2<sup>31</sup> bytes).</p>
+ * <p>The practical limit of 2<sup>31</sup> - 24 bytes is policed, and attempts to breach the limit will be rejected</p>
+ * <p>In order to properly support the higher limit, an extended form of <b>ByteArrayOutputStream</b> would be needed
+ * which would use multiple arrays to store the data. In addition, a new <b>doOutput</b> method would be required (similar
+ * to that in <b>XOF</b> digests), which would allow the data to be output over multiple calls. Alternatively an extended
+ * form of <b>ByteArrayInputStream</b> could be used to deliver the data.</p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GCMSIVBlockCipher
+ implements AEADBlockCipher
+{
+ /**
+ * The buffer length.
+ */
+ private static final int BUFLEN = 16;
+
+ /**
+ * The halfBuffer length.
+ */
+ private static final int HALFBUFLEN = BUFLEN >> 1;
+
+ /**
+ * The nonce length.
+ */
+ private static final int NONCELEN = 12;
+
+ /**
+ * The maximum data length (AEAD/PlainText). Due to implementation constraints this is restricted to the maximum
+ * array length (https://programming.guide/java/array-maximum-length.html) minus the BUFLEN to allow for the MAC
+ */
+ private static final int MAX_DATALEN = Integer.MAX_VALUE - 8 - BUFLEN;
+
+ /**
+ * The top bit mask.
+ */
+ private static final byte MASK = (byte) 0x80;
+
+ /**
+ * The addition constant.
+ */
+ private static final byte ADD = (byte) 0xE1;
+
+ /**
+ * The initialisation flag.
+ */
+ private static final int INIT = 1;
+
+ /**
+ * The aeadComplete flag.
+ */
+ private static final int AEAD_COMPLETE = 2;
+
+ /**
+ * The cipher.
+ */
+ private final BlockCipher theCipher;
+
+ /**
+ * The multiplier.
+ */
+ private final GCMMultiplier theMultiplier;
+
+ /**
+ * The gHash buffer.
+ */
+ private final byte[] theGHash = new byte[BUFLEN];
+
+ /**
+ * The reverse buffer.
+ */
+ private final byte[] theReverse = new byte[BUFLEN];
+
+ /**
+ * The aeadHasher.
+ */
+ private final GCMSIVHasher theAEADHasher;
+
+ /**
+ * The dataHasher.
+ */
+ private final GCMSIVHasher theDataHasher;
+
+ /**
+ * The plainDataStream.
+ */
+ private GCMSIVCache thePlain;
+
+ /**
+ * The encryptedDataStream (decryption only).
+ */
+ private GCMSIVCache theEncData;
+
+ /**
+ * Are we encrypting?
+ */
+ private boolean forEncryption;
+
+ /**
+ * The initialAEAD.
+ */
+ private byte[] theInitialAEAD;
+
+ /**
+ * The nonce.
+ */
+ private byte[] theNonce;
+
+ /**
+ * The flags.
+ */
+ private int theFlags;
+
+ // defined fixed
+ private byte[] macBlock = new byte[16];
+
+ /**
+ * Constructor.
+ */
+ public GCMSIVBlockCipher()
+ {
+ this(AESEngine.newInstance());
+ }
+
+ /**
+ * Constructor.
+ * @param pCipher the underlying cipher
+ */
+ public GCMSIVBlockCipher(final BlockCipher pCipher)
+ {
+ this(pCipher, new Tables4kGCMMultiplier());
+ }
+
+ /**
+ * Constructor.
+ * @param pCipher the underlying cipher
+ * @param pMultiplier the multiplier
+ */
+ public GCMSIVBlockCipher(final BlockCipher pCipher,
+ final GCMMultiplier pMultiplier)
+ {
+ /* Ensure that the cipher is the correct size */
+ if (pCipher.getBlockSize() != BUFLEN)
+ {
+ throw new IllegalArgumentException("Cipher required with a block size of " + BUFLEN + ".");
+ }
+
+ /* Store parameters */
+ theCipher = pCipher;
+ theMultiplier = pMultiplier;
+
+ /* Create the hashers */
+ theAEADHasher = new GCMSIVHasher();
+ theDataHasher = new GCMSIVHasher();
+ }
+
+ public BlockCipher getUnderlyingCipher()
+ {
+ return theCipher;
+ }
+
+ public void init(final boolean pEncrypt,
+ final CipherParameters cipherParameters) throws IllegalArgumentException
+ {
+ /* Set defaults */
+ byte[] myInitialAEAD = null;
+ byte[] myNonce = null;
+ KeyParameter myKey = null;
+
+ /* Access parameters */
+ if (cipherParameters instanceof AEADParameters)
+ {
+ final AEADParameters myAEAD = (AEADParameters) cipherParameters;
+ myInitialAEAD = myAEAD.getAssociatedText();
+ myNonce = myAEAD.getNonce();
+ myKey = myAEAD.getKey();
+ }
+ else if (cipherParameters instanceof ParametersWithIV)
+ {
+ final ParametersWithIV myParms = (ParametersWithIV) cipherParameters;
+ myNonce = myParms.getIV();
+ myKey = (KeyParameter) myParms.getParameters();
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid parameters passed to GCM-SIV");
+ }
+
+ /* Check nonceSize */
+ if (myNonce == null || myNonce.length != NONCELEN)
+ {
+ throw new IllegalArgumentException("Invalid nonce");
+ }
+
+ /* Check keysize */
+ if (myKey == null
+ || (myKey.getKeyLength() != BUFLEN
+ && myKey.getKeyLength() != (BUFLEN << 1)))
+ {
+ throw new IllegalArgumentException("Invalid key");
+ }
+
+ /* Reset details */
+ forEncryption = pEncrypt;
+ theInitialAEAD = myInitialAEAD;
+ theNonce = myNonce;
+
+ /* Initialise the keys */
+ deriveKeys(myKey);
+ resetStreams();
+ }
+
+ public String getAlgorithmName()
+ {
+ return theCipher.getAlgorithmName() + "-GCM-SIV";
+ }
+
+ /**
+ * check AEAD status.
+ * @param pLen the aeadLength
+ */
+ private void checkAEADStatus(final int pLen)
+ {
+ /* Check we are initialised */
+ if ((theFlags & INIT) == 0)
+ {
+ throw new IllegalStateException("Cipher is not initialised");
+ }
+
+ /* Check AAD is allowed */
+ if ((theFlags & AEAD_COMPLETE) != 0)
+ {
+ throw new IllegalStateException("AEAD data cannot be processed after ordinary data");
+ }
+
+ /* Make sure that we haven't breached AEAD data limit */
+ if (theAEADHasher.getBytesProcessed() + Long.MIN_VALUE
+ > (MAX_DATALEN - pLen) + Long.MIN_VALUE)
+ {
+ throw new IllegalStateException("AEAD byte count exceeded");
+ }
+ }
+
+ /**
+ * check status.
+ * @param pLen the dataLength
+ */
+ private void checkStatus(final int pLen)
+ {
+ /* Check we are initialised */
+ if ((theFlags & INIT) == 0)
+ {
+ throw new IllegalStateException("Cipher is not initialised");
+ }
+
+ /* Complete the AEAD section if this is the first data */
+ if ((theFlags & AEAD_COMPLETE) == 0)
+ {
+ theAEADHasher.completeHash();
+ theFlags |= AEAD_COMPLETE;
+ }
+
+ /* Make sure that we haven't breached data limit */
+ long dataLimit = MAX_DATALEN;
+ long currBytes = thePlain.size();
+ if (!forEncryption)
+ {
+ dataLimit += BUFLEN;
+ currBytes = theEncData.size();
+ }
+ if (currBytes + Long.MIN_VALUE
+ > (dataLimit - pLen) + Long.MIN_VALUE)
+ {
+ throw new IllegalStateException("byte count exceeded");
+ }
+ }
+
+ public void processAADByte(final byte pByte)
+ {
+ /* Check that we can supply AEAD */
+ checkAEADStatus(1);
+
+ /* Process the aead */
+ theAEADHasher.updateHash(pByte);
+ }
+
+ public void processAADBytes(final byte[] pData,
+ final int pOffset,
+ final int pLen)
+ {
+ /* Check that we can supply AEAD */
+ checkAEADStatus(pLen);
+
+ /* Check input buffer */
+ checkBuffer(pData, pOffset, pLen, false);
+
+ /* Process the aead */
+ theAEADHasher.updateHash(pData, pOffset, pLen);
+ }
+
+ public int processByte(final byte pByte,
+ final byte[] pOutput,
+ final int pOutOffset) throws DataLengthException
+ {
+ /* Check that we have initialised */
+ checkStatus(1);
+
+ /* Store the data */
+ if (forEncryption)
+ {
+ thePlain.write(pByte);
+ theDataHasher.updateHash(pByte);
+ }
+ else
+ {
+ theEncData.write(pByte);
+ }
+
+ /* No data returned */
+ return 0;
+ }
+
+ public int processBytes(final byte[] pData,
+ final int pOffset,
+ final int pLen,
+ final byte[] pOutput,
+ final int pOutOffset) throws DataLengthException
+ {
+ /* Check that we have initialised */
+ checkStatus(pLen);
+
+ /* Check input buffer */
+ checkBuffer(pData, pOffset, pLen, false);
+
+ /* Store the data */
+ if (forEncryption)
+ {
+ thePlain.write(pData, pOffset, pLen);
+ theDataHasher.updateHash(pData, pOffset, pLen);
+ }
+ else
+ {
+ theEncData.write(pData, pOffset, pLen);
+ }
+
+ /* No data returned */
+ return 0;
+ }
+
+ public int doFinal(final byte[] pOutput,
+ final int pOffset) throws IllegalStateException, InvalidCipherTextException
+ {
+ /* Check that we have initialised */
+ checkStatus(0);
+
+ /* Check output buffer */
+ checkBuffer(pOutput, pOffset, getOutputSize(0), true);
+
+ /* If we are encrypting */
+ if (forEncryption)
+ {
+ /* Derive the tag */
+ final byte[] myTag = calculateTag();
+
+ /* encrypt the plain text */
+ final int myDataLen = BUFLEN + encryptPlain(myTag, pOutput, pOffset);
+
+ /* Add the tag to the output */
+ System.arraycopy(myTag, 0, pOutput, pOffset + thePlain.size(), BUFLEN);
+
+ System.arraycopy(myTag, 0, macBlock, 0, macBlock.length);
+
+ /* Reset the streams */
+ resetStreams();
+ return myDataLen;
+
+ /* else we are decrypting */
+ }
+ else
+ {
+ /* decrypt to plain text */
+ decryptPlain();
+
+ /* Release plain text */
+ final int myDataLen = thePlain.size();
+ final byte[] mySrc = thePlain.getBuffer();
+ System.arraycopy(mySrc, 0, pOutput, pOffset, myDataLen);
+
+ /* Reset the streams */
+ resetStreams();
+ return myDataLen;
+ }
+ }
+
+ public byte[] getMac()
+ {
+ return Arrays.clone(macBlock);
+ }
+
+ public int getUpdateOutputSize(final int pLen)
+ {
+ return 0;
+ }
+
+ public int getOutputSize(final int pLen)
+ {
+ if (forEncryption)
+ {
+ return pLen + thePlain.size() + BUFLEN;
+ }
+ final int myCurr = pLen + theEncData.size();
+ return myCurr > BUFLEN ? myCurr - BUFLEN : 0;
+ }
+
+ public void reset()
+ {
+ resetStreams();
+ }
+
+ /**
+ * Reset Streams.
+ */
+ private void resetStreams()
+ {
+ /* Clear the plainText buffer */
+ if (thePlain != null)
+ {
+ thePlain.clearBuffer();
+ }
+
+ /* Reset hashers */
+ theAEADHasher.reset();
+ theDataHasher.reset();
+
+ /* Recreate streams (to release memory) */
+ thePlain = new GCMSIVCache();
+ theEncData = forEncryption ? null : new GCMSIVCache();
+
+ /* Initialise AEAD if required */
+ theFlags &= ~AEAD_COMPLETE;
+ Arrays.fill(theGHash, (byte) 0);
+ if (theInitialAEAD != null)
+ {
+ theAEADHasher.updateHash(theInitialAEAD, 0, theInitialAEAD.length);
+ }
+ }
+
+ /**
+ * Obtain buffer length (allowing for null).
+ * @param pBuffer the buffere
+ * @return the length
+ */
+ private static int bufLength(final byte[] pBuffer)
+ {
+ return pBuffer == null ? 0 : pBuffer.length;
+ }
+
+ /**
+ * Check buffer.
+ * @param pBuffer the buffer
+ * @param pOffset the offset
+ * @param pLen the length
+ * @param pOutput is this an output buffer?
+ */
+ private static void checkBuffer(final byte[] pBuffer,
+ final int pOffset,
+ final int pLen,
+ final boolean pOutput)
+ {
+ /* Access lengths */
+ final int myBufLen = bufLength(pBuffer);
+ final int myLast = pOffset + pLen;
+
+ /* Check for negative values and buffer overflow */
+ final boolean badLen = pLen < 0 || pOffset < 0 || myLast < 0;
+ if (badLen || myLast > myBufLen)
+ {
+ throw pOutput
+ ? new OutputLengthException("Output buffer too short.")
+ : new DataLengthException("Input buffer too short.");
+ }
+ }
+
+ /**
+ * encrypt data stream.
+ * @param pCounter the counter
+ * @param pTarget the target buffer
+ * @param pOffset the target offset
+ * @return the length of data encrypted
+ */
+ private int encryptPlain(final byte[] pCounter,
+ final byte[] pTarget,
+ final int pOffset)
+ {
+ /* Access buffer and length */
+ final byte[] mySrc = thePlain.getBuffer();
+ final byte[] myCounter = Arrays.clone(pCounter);
+ myCounter[BUFLEN - 1] |= MASK;
+ final byte[] myMask = new byte[BUFLEN];
+ int myRemaining = thePlain.size();
+ int myOff = 0;
+
+ /* While we have data to process */
+ while (myRemaining > 0)
+ {
+ /* Generate the next mask */
+ theCipher.processBlock(myCounter, 0, myMask, 0);
+
+ /* Xor data into mask */
+ final int myLen = Math.min(BUFLEN, myRemaining);
+ xorBlock(myMask, mySrc, myOff, myLen);
+
+ /* Copy encrypted data to output */
+ System.arraycopy(myMask, 0, pTarget, pOffset + myOff, myLen);
+
+ /* Adjust counters */
+ myRemaining -= myLen;
+ myOff += myLen;
+ incrementCounter(myCounter);
+ }
+
+ /* Return the amount of data processed */
+ return thePlain.size();
+ }
+
+ /**
+ * decrypt data stream.
+ * @throws InvalidCipherTextException on data too short or mac check failed
+ */
+ private void decryptPlain() throws InvalidCipherTextException
+ {
+ /* Access buffer and length */
+ final byte[] mySrc = theEncData.getBuffer();
+ int myRemaining = theEncData.size() - BUFLEN;
+
+ /* Check for insufficient data */
+ if (myRemaining < 0)
+ {
+ throw new InvalidCipherTextException("Data too short");
+ }
+
+ /* Access counter */
+ final byte[] myExpected = Arrays.copyOfRange(mySrc, myRemaining, myRemaining + BUFLEN);
+ final byte[] myCounter = Arrays.clone(myExpected);
+ myCounter[BUFLEN - 1] |= MASK;
+ final byte[] myMask = new byte[BUFLEN];
+ int myOff = 0;
+
+ /* While we have data to process */
+ while (myRemaining > 0)
+ {
+ /* Generate the next mask */
+ theCipher.processBlock(myCounter, 0, myMask, 0);
+
+ /* Xor data into mask */
+ final int myLen = Math.min(BUFLEN, myRemaining);
+ xorBlock(myMask, mySrc, myOff, myLen);
+
+ /* Write data to plain dataStream */
+ thePlain.write(myMask, 0, myLen);
+ theDataHasher.updateHash(myMask, 0, myLen);
+
+ /* Adjust counters */
+ myRemaining -= myLen;
+ myOff += myLen;
+ incrementCounter(myCounter);
+ }
+
+ /* Derive and check the tag */
+ final byte[] myTag = calculateTag();
+ if (!Arrays.constantTimeAreEqual(myTag, myExpected))
+ {
+ reset();
+ throw new InvalidCipherTextException("mac check failed");
+ }
+
+ System.arraycopy(myTag, 0, macBlock, 0, macBlock.length);
+ }
+
+ /**
+ * calculate tag.
+ * @return the calculated tag
+ */
+ private byte[] calculateTag()
+ {
+ /* Complete the hash */
+ theDataHasher.completeHash();
+ final byte[] myPolyVal = completePolyVal();
+
+ /* calculate polyVal */
+ final byte[] myResult = new byte[BUFLEN];
+
+ /* Fold in the nonce */
+ for (int i = 0; i < NONCELEN; i++)
+ {
+ myPolyVal[i] ^= theNonce[i];
+ }
+
+ /* Clear top bit */
+ myPolyVal[BUFLEN - 1] &= (MASK - 1);
+
+ /* Calculate tag and return it */
+ theCipher.processBlock(myPolyVal, 0, myResult, 0);
+ return myResult;
+ }
+
+ /**
+ * complete polyVAL.
+ * @return the calculated value
+ */
+ private byte[] completePolyVal()
+ {
+ /* Build the polyVal result */
+ final byte[] myResult = new byte[BUFLEN];
+ gHashLengths();
+ fillReverse(theGHash, 0, BUFLEN, myResult);
+ return myResult;
+ }
+
+ /**
+ * process lengths.
+ */
+ private void gHashLengths()
+ {
+ /* Create reversed bigEndian buffer to keep it simple */
+ final byte[] myIn = new byte[BUFLEN];
+ Pack.longToBigEndian(Bytes.SIZE * theDataHasher.getBytesProcessed(), myIn, 0);
+ Pack.longToBigEndian(Bytes.SIZE * theAEADHasher.getBytesProcessed(), myIn, Longs.BYTES);
+
+ /* hash value */
+ gHASH(myIn);
+ }
+
+ /**
+ * perform the next GHASH step.
+ * @param pNext the next value
+ */
+ private void gHASH(final byte[] pNext)
+ {
+ xorBlock(theGHash, pNext);
+ theMultiplier.multiplyH(theGHash);
+ }
+
+ /**
+ * Byte reverse a buffer.
+ * @param pInput the input buffer
+ * @param pOffset the offset
+ * @param pLength the length of data (<= BUFLEN)
+ * @param pOutput the output buffer
+ */
+ private static void fillReverse(final byte[] pInput,
+ final int pOffset,
+ final int pLength,
+ final byte[] pOutput)
+ {
+ /* Loop through the buffer */
+ for (int i = 0, j = BUFLEN - 1; i < pLength; i++, j--)
+ {
+ /* Copy byte */
+ pOutput[j] = pInput[pOffset + i];
+ }
+ }
+
+ /**
+ * xor a full block buffer.
+ * @param pLeft the left operand and result
+ * @param pRight the right operand
+ */
+ private static void xorBlock(final byte[] pLeft,
+ final byte[] pRight)
+ {
+ /* Loop through the bytes */
+ for (int i = 0; i < BUFLEN; i++)
+ {
+ pLeft[i] ^= pRight[i];
+ }
+ }
+
+ /**
+ * xor a partial block buffer.
+ * @param pLeft the left operand and result
+ * @param pRight the right operand
+ * @param pOffset the offset in the right operand
+ * @param pLength the length of data in the right operand
+ */
+ private static void xorBlock(final byte[] pLeft,
+ final byte[] pRight,
+ final int pOffset,
+ final int pLength)
+ {
+ /* Loop through the bytes */
+ for (int i = 0; i < pLength; i++)
+ {
+ pLeft[i] ^= pRight[i + pOffset];
+ }
+ }
+
+ /**
+ * increment the counter.
+ * @param pCounter the counter to increment
+ */
+ private static void incrementCounter(final byte[] pCounter)
+ {
+ /* Loop through the bytes incrementing counter */
+ for (int i = 0; i < Integers.BYTES; i++)
+ {
+ if (++pCounter[i] != 0)
+ {
+ break;
+ }
+ }
+ }
+
+ /**
+ * multiply by X.
+ * @param pValue the value to adjust
+ */
+ private static void mulX(final byte[] pValue)
+ {
+ /* Loop through the bytes */
+ byte myMask = (byte) 0;
+ for (int i = 0; i < BUFLEN; i++)
+ {
+ final byte myValue = pValue[i];
+ pValue[i] = (byte) (((myValue >> 1) & ~MASK) | myMask);
+ myMask = (myValue & 1) == 0 ? 0 : MASK;
+ }
+
+ /* Xor in addition if last bit was set */
+ if (myMask != 0)
+ {
+ pValue[0] ^= ADD;
+ }
+ }
+
+ /**
+ * Derive Keys.
+ * @param pKey the keyGeneration key
+ */
+ private void deriveKeys(final KeyParameter pKey)
+ {
+ /* Create the buffers */
+ final byte[] myIn = new byte[BUFLEN];
+ final byte[] myOut = new byte[BUFLEN];
+ final byte[] myResult = new byte[BUFLEN];
+ final byte[] myEncKey = new byte[pKey.getKeyLength()];
+
+ /* Prepare for encryption */
+ System.arraycopy(theNonce, 0, myIn, BUFLEN - NONCELEN, NONCELEN);
+ theCipher.init(true, pKey);
+
+ /* Derive authentication key */
+ int myOff = 0;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myResult, myOff, HALFBUFLEN);
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myResult, myOff, HALFBUFLEN);
+
+ /* Derive encryption key */
+ myIn[0]++;
+ myOff = 0;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+
+ /* If we have a 32byte key */
+ if (myEncKey.length == BUFLEN << 1)
+ {
+ /* Derive remainder of encryption key */
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+ myIn[0]++;
+ myOff += HALFBUFLEN;
+ theCipher.processBlock(myIn, 0, myOut, 0);
+ System.arraycopy(myOut, 0, myEncKey, myOff, HALFBUFLEN);
+ }
+
+ /* Initialise the Cipher */
+ theCipher.init(true, new KeyParameter(myEncKey));
+
+ /* Initialise the multiplier */
+ fillReverse(myResult, 0, BUFLEN, myOut);
+ mulX(myOut);
+ theMultiplier.init(myOut);
+ theFlags |= INIT;
+ }
+
+ /**
+ * GCMSIVCache.
+ */
+ private static class GCMSIVCache
+ extends ByteArrayOutputStream
+ {
+ /**
+ * Constructor.
+ */
+ GCMSIVCache()
+ {
+ }
+
+ /**
+ * Obtain the buffer.
+ * @return the buffer
+ */
+ byte[] getBuffer()
+ {
+ return this.buf;
+ }
+
+ /**
+ * Clear the buffer.
+ */
+ void clearBuffer()
+ {
+ Arrays.fill(getBuffer(), (byte) 0);
+ }
+ }
+
+ /**
+ * Hash Control.
+ */
+ private class GCMSIVHasher
+ {
+ /**
+ * Cache.
+ */
+ private final byte[] theBuffer = new byte[BUFLEN];
+
+ /**
+ * Single byte cache.
+ */
+ private final byte[] theByte = new byte[1];
+
+ /**
+ * Count of active bytes in cache.
+ */
+ private int numActive;
+
+ /**
+ * Count of hashed bytes.
+ */
+ private long numHashed;
+
+ /**
+ * Obtain the count of bytes hashed.
+ * @return the count
+ */
+ long getBytesProcessed()
+ {
+ return numHashed;
+ }
+
+ /**
+ * Reset the hasher.
+ */
+ void reset()
+ {
+ numActive = 0;
+ numHashed = 0;
+ }
+
+ /**
+ * update hash.
+ * @param pByte the byte
+ */
+ void updateHash(final byte pByte)
+ {
+ theByte[0] = pByte;
+ updateHash(theByte, 0, 1);
+ }
+
+ /**
+ * update hash.
+ * @param pBuffer the buffer
+ * @param pOffset the offset within the buffer
+ * @param pLen the length of data
+ */
+ void updateHash(final byte[] pBuffer,
+ final int pOffset,
+ final int pLen)
+ {
+ /* If we should process the cache */
+ final int mySpace = BUFLEN - numActive;
+ int numProcessed = 0;
+ int myRemaining = pLen;
+ if (numActive > 0
+ && pLen >= mySpace)
+ {
+ /* Copy data into the cache and hash it */
+ System.arraycopy(pBuffer, pOffset, theBuffer, numActive, mySpace);
+ fillReverse(theBuffer, 0, BUFLEN, theReverse);
+ gHASH(theReverse);
+
+ /* Adjust counters */
+ numProcessed += mySpace;
+ myRemaining -= mySpace;
+ numActive = 0;
+ }
+
+ /* While we have full blocks */
+ while (myRemaining >= BUFLEN)
+ {
+ /* Access the next data */
+ fillReverse(pBuffer, pOffset + numProcessed, BUFLEN, theReverse);
+ gHASH(theReverse);
+
+ /* Adjust counters */
+ numProcessed += BUFLEN;
+ myRemaining -= BUFLEN;
+ }
+
+ /* If we have remaining data */
+ if (myRemaining > 0)
+ {
+ /* Copy data into the cache */
+ System.arraycopy(pBuffer, pOffset + numProcessed, theBuffer, numActive, myRemaining);
+ numActive += myRemaining;
+ }
+
+ /* Adjust the number of bytes processed */
+ numHashed += pLen;
+ }
+
+ /**
+ * complete hash.
+ */
+ void completeHash()
+ {
+ /* If we have remaining data */
+ if (numActive > 0)
+ {
+ /* Access the next data */
+ Arrays.fill(theReverse, (byte) 0);
+ fillReverse(theBuffer, 0, numActive, theReverse);
+
+ /* hash value */
+ gHASH(theReverse);
+ }
+ }
+ }
+ }
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/SICBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/SICBlockCipher.java
index b4121be..cd7031c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/SICBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/SICBlockCipher.java
@@ -4,7 +4,7 @@
import com.android.internal.org.bouncycastle.crypto.BlockCipher;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
-import com.android.internal.org.bouncycastle.crypto.SkippingStreamCipher;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
import com.android.internal.org.bouncycastle.crypto.StreamBlockCipher;
import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
import com.android.internal.org.bouncycastle.util.Arrays;
@@ -17,7 +17,7 @@
*/
public class SICBlockCipher
extends StreamBlockCipher
- implements SkippingStreamCipher
+ implements CTRModeCipher
{
private final BlockCipher cipher;
private final int blockSize;
@@ -28,9 +28,20 @@
private int byteCount;
/**
+ * Return a new SIC/CTR mode cipher based on the passed in base cipher
+ *
+ * @param cipher the base cipher for the SIC/CTR mode.
+ */
+ public static CTRModeCipher newInstance(BlockCipher cipher)
+ {
+ return new SICBlockCipher(cipher);
+ }
+
+ /**
* Basic constructor.
*
* @param c the block cipher to be used.
+ * @deprecated use newInstance() method.
*/
public SICBlockCipher(BlockCipher c)
{
@@ -93,16 +104,75 @@
public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
throws DataLengthException, IllegalStateException
{
- processBytes(in, inOff, blockSize, out, outOff);
+ if (byteCount != 0)
+ {
+ processBytes(in, inOff, blockSize, out, outOff);
+ return blockSize;
+ }
+ if (inOff + blockSize > in.length)
+ {
+ throw new DataLengthException("input buffer too small");
+ }
+ if (outOff + blockSize > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ cipher.processBlock(counter, 0, counterOut, 0);
+ for (int i = 0; i < blockSize; ++i)
+ {
+ out[outOff + i] = (byte)(in[inOff + i] ^ counterOut[i]);
+ }
+ incrementCounter();
return blockSize;
}
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ if (inOff + len > in.length)
+ {
+ throw new DataLengthException("input buffer too small");
+ }
+ if (outOff + len > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ for (int i = 0; i < len; ++i)
+ {
+ byte next;
+
+ if (byteCount == 0)
+ {
+ checkLastIncrement();
+
+ cipher.processBlock(counter, 0, counterOut, 0);
+ next = (byte)(in[inOff + i] ^ counterOut[byteCount++]);
+ }
+ else
+ {
+ next = (byte)(in[inOff + i] ^ counterOut[byteCount++]);
+ if (byteCount == counter.length)
+ {
+ byteCount = 0;
+ incrementCounter();
+ }
+ }
+ out[outOff + i] = next;
+ }
+
+ return len;
+ }
+
protected byte calculateByte(byte in)
throws DataLengthException, IllegalStateException
{
if (byteCount == 0)
{
+ checkLastIncrement();
+
cipher.processBlock(counter, 0, counterOut, 0);
return (byte)(counterOut[byteCount++] ^ in);
@@ -113,10 +183,7 @@
if (byteCount == counter.length)
{
byteCount = 0;
-
- incrementCounterAt(0);
-
- checkCounter();
+ incrementCounter();
}
return rv;
@@ -127,7 +194,7 @@
// if the IV is the same as the blocksize we assume the user knows what they are doing
if (IV.length < blockSize)
{
- for (int i = 0; i != IV.length; i++)
+ for (int i = IV.length - 1; i >= 0; i--)
{
if (counter[i] != IV[i])
{
@@ -137,6 +204,30 @@
}
}
+ private void checkLastIncrement()
+ {
+ // if the IV is the same as the blocksize we assume the user knows what they are doing
+ if (IV.length < blockSize)
+ {
+ if (counter[IV.length - 1] != IV[IV.length - 1])
+ {
+ throw new IllegalStateException("Counter in CTR/SIC mode out of range.");
+ }
+ }
+ }
+
+ private void incrementCounter()
+ {
+ int i = counter.length;
+ while (--i >= 0)
+ {
+ if (++counter[i] != 0)
+ {
+ break;
+ }
+ }
+ }
+
private void incrementCounterAt(int pos)
{
int i = counter.length - pos;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java
index 2d317ff..fe86002 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java
@@ -1,8 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.modes.gcm;
-import com.android.internal.org.bouncycastle.util.Arrays;
-
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -23,7 +21,9 @@
if (pow > 0)
{
- long[] powX = Arrays.clone(x);
+ long[] powX = new long[GCMUtil.SIZE_LONGS];
+ GCMUtil.copy(x, powX);
+
do
{
if ((pow & 1L) != 0)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
index 0797bca..1dc1d48 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
@@ -10,76 +10,119 @@
*/
public abstract class GCMUtil
{
+ public static final int SIZE_BYTES = 16;
+ public static final int SIZE_INTS = 4;
+ public static final int SIZE_LONGS = 2;
+
private static final int E1 = 0xe1000000;
private static final long E1L = (E1 & 0xFFFFFFFFL) << 32;
public static byte[] oneAsBytes()
{
- byte[] tmp = new byte[16];
+ byte[] tmp = new byte[SIZE_BYTES];
tmp[0] = (byte)0x80;
return tmp;
}
public static int[] oneAsInts()
{
- int[] tmp = new int[4];
+ int[] tmp = new int[SIZE_INTS];
tmp[0] = 1 << 31;
return tmp;
}
public static long[] oneAsLongs()
{
- long[] tmp = new long[2];
+ long[] tmp = new long[SIZE_LONGS];
tmp[0] = 1L << 63;
return tmp;
}
+ public static byte areEqual(byte[] x, byte[] y)
+ {
+ int d = 0;
+ for (int i = 0; i < SIZE_BYTES; ++i)
+ {
+ d |= x[i] ^ y[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (byte)((d - 1) >> 31);
+ }
+
+ public static int areEqual(int[] x, int[] y)
+ {
+ int d = 0;
+ d |= x[0] ^ y[0];
+ d |= x[1] ^ y[1];
+ d |= x[2] ^ y[2];
+ d |= x[3] ^ y[3];
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static long areEqual(long[] x, long[] y)
+ {
+ long d = 0L;
+ d |= x[0] ^ y[0];
+ d |= x[1] ^ y[1];
+ d = (d >>> 1) | (d & 1L);
+ return (d - 1L) >> 63;
+ }
+
public static byte[] asBytes(int[] x)
{
- byte[] z = new byte[16];
- Pack.intToBigEndian(x, z, 0);
+ byte[] z = new byte[SIZE_BYTES];
+ Pack.intToBigEndian(x, 0, SIZE_INTS, z, 0);
return z;
}
public static void asBytes(int[] x, byte[] z)
{
- Pack.intToBigEndian(x, z, 0);
+ Pack.intToBigEndian(x, 0, SIZE_INTS, z, 0);
}
public static byte[] asBytes(long[] x)
{
- byte[] z = new byte[16];
- Pack.longToBigEndian(x, z, 0);
+ byte[] z = new byte[SIZE_BYTES];
+ Pack.longToBigEndian(x, 0, SIZE_LONGS, z, 0);
return z;
}
public static void asBytes(long[] x, byte[] z)
{
- Pack.longToBigEndian(x, z, 0);
+ Pack.longToBigEndian(x, 0, SIZE_LONGS, z, 0);
}
public static int[] asInts(byte[] x)
{
- int[] z = new int[4];
- Pack.bigEndianToInt(x, 0, z);
+ int[] z = new int[SIZE_INTS];
+ Pack.bigEndianToInt(x, 0, z, 0, SIZE_INTS);
return z;
}
public static void asInts(byte[] x, int[] z)
{
- Pack.bigEndianToInt(x, 0, z);
+ Pack.bigEndianToInt(x, 0, z, 0, SIZE_INTS);
}
public static long[] asLongs(byte[] x)
{
- long[] z = new long[2];
- Pack.bigEndianToLong(x, 0, z);
+ long[] z = new long[SIZE_LONGS];
+ Pack.bigEndianToLong(x, 0, z, 0, SIZE_LONGS);
return z;
}
public static void asLongs(byte[] x, long[] z)
{
- Pack.bigEndianToLong(x, 0, z);
+ Pack.bigEndianToLong(x, 0, z, 0, SIZE_LONGS);
+ }
+
+ public static void copy(byte[] x, byte[] z)
+ {
+ for (int i = 0; i < SIZE_BYTES; ++i)
+ {
+ z[i] = x[i];
+ }
}
public static void copy(int[] x, int[] z)
@@ -107,10 +150,48 @@
public static void multiply(byte[] x, byte[] y)
{
- long[] t1 = GCMUtil.asLongs(x);
- long[] t2 = GCMUtil.asLongs(y);
- GCMUtil.multiply(t1, t2);
- GCMUtil.asBytes(t1, x);
+ long[] t1 = asLongs(x);
+ long[] t2 = asLongs(y);
+ multiply(t1, t2);
+ asBytes(t1, x);
+ }
+
+ static void multiply(byte[] x, long[] y)
+ {
+ /*
+ * "Three-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
+ *
+ * Without access to the high part of a 64x64 product x * y, we use a bit reversal to calculate it:
+ * rev(x) * rev(y) == rev((x * y) << 1)
+ */
+
+ long x0 = Pack.bigEndianToLong(x, 0);
+ long x1 = Pack.bigEndianToLong(x, 8);
+ long y0 = y[0], y1 = y[1];
+ long x0r = Longs.reverse(x0), x1r = Longs.reverse(x1);
+ long y0r = Longs.reverse(y0), y1r = Longs.reverse(y1);
+
+ long h0 = Longs.reverse(implMul64(x0r, y0r));
+ long h1 = implMul64(x0, y0) << 1;
+ long h2 = Longs.reverse(implMul64(x1r, y1r));
+ long h3 = implMul64(x1, y1) << 1;
+ long h4 = Longs.reverse(implMul64(x0r ^ x1r, y0r ^ y1r));
+ long h5 = implMul64(x0 ^ x1, y0 ^ y1) << 1;
+
+ long z0 = h0;
+ long z1 = h1 ^ h0 ^ h2 ^ h4;
+ long z2 = h2 ^ h1 ^ h3 ^ h5;
+ long z3 = h3;
+
+ z1 ^= z3 ^ (z3 >>> 1) ^ (z3 >>> 2) ^ (z3 >>> 7);
+// z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57);
+ z2 ^= (z3 << 62) ^ (z3 << 57);
+
+ z0 ^= z2 ^ (z2 >>> 1) ^ (z2 >>> 2) ^ (z2 >>> 7);
+ z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
+
+ Pack.longToBigEndian(z0, x, 0);
+ Pack.longToBigEndian(z1, x, 8);
}
public static void multiply(int[] x, int[] y)
@@ -118,7 +199,7 @@
int y0 = y[0], y1 = y[1], y2 = y[2], y3 = y[3];
int z0 = 0, z1 = 0, z2 = 0, z3 = 0;
- for (int i = 0; i < 4; ++i)
+ for (int i = 0; i < SIZE_INTS; ++i)
{
int bits = x[i];
for (int j = 0; j < 32; ++j)
@@ -301,16 +382,24 @@
y[1] = (x1 >>> 8) | (x0 << 56);
}
+ public static void multiplyP16(long[] x)
+ {
+ long x0 = x[0], x1 = x[1];
+ long c = x1 << 48;
+ x[0] = (x0 >>> 16) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
+ x[1] = (x1 >>> 16) | (x0 << 48);
+ }
+
public static long[] pAsLongs()
{
- long[] tmp = new long[2];
+ long[] tmp = new long[SIZE_LONGS];
tmp[0] = 1L << 62;
return tmp;
}
public static void square(long[] x, long[] z)
{
- long[] t = new long[4];
+ long[] t = new long[SIZE_LONGS * 2];
Interleave.expand64To128Rev(x[0], t, 0);
Interleave.expand64To128Rev(x[1], t, 2);
@@ -336,7 +425,7 @@
x[i] ^= y[i]; ++i;
x[i] ^= y[i]; ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(byte[] x, byte[] y, int yOff)
@@ -349,7 +438,7 @@
x[i] ^= y[yOff + i]; ++i;
x[i] ^= y[yOff + i]; ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff)
@@ -362,7 +451,7 @@
z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(byte[] x, byte[] y, int yOff, int yLen)
@@ -391,7 +480,7 @@
z[i] = (byte)(x[i] ^ y[i]); ++i;
z[i] = (byte)(x[i] ^ y[i]); ++i;
}
- while (i < 16);
+ while (i < SIZE_BYTES);
}
public static void xor(int[] x, int[] y)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java
index 7689396..ae466a0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java
@@ -1,9 +1,8 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.modes.gcm;
-import java.util.Vector;
-
-import com.android.internal.org.bouncycastle.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
/**
* @hide This class is not part of the Android public SDK API
@@ -13,18 +12,18 @@
{
// A lookup table of the power-of-two powers of 'x'
// - lookupPowX2[i] = x^(2^i)
- private Vector lookupPowX2;
+ private List lookupPowX2;
public void init(byte[] x)
{
long[] y = GCMUtil.asLongs(x);
- if (lookupPowX2 != null && Arrays.areEqual(y, (long[])lookupPowX2.elementAt(0)))
+ if (lookupPowX2 != null && 0L != GCMUtil.areEqual(y, (long[])lookupPowX2.get(0)))
{
return;
}
- lookupPowX2 = new Vector(8);
- lookupPowX2.addElement(y);
+ lookupPowX2 = new ArrayList(8);
+ lookupPowX2.add(y);
}
public void exponentiateX(long pow, byte[] output)
@@ -35,8 +34,7 @@
{
if ((pow & 1L) != 0)
{
- ensureAvailable(bit);
- GCMUtil.multiply(y, (long[])lookupPowX2.elementAt(bit));
+ GCMUtil.multiply(y, getPowX2(bit));
}
++bit;
pow >>>= 1;
@@ -45,19 +43,22 @@
GCMUtil.asBytes(y, output);
}
- private void ensureAvailable(int bit)
+ private long[] getPowX2(int bit)
{
- int count = lookupPowX2.size();
- if (count <= bit)
+ int last = lookupPowX2.size() - 1;
+ if (last < bit)
{
- long[] tmp = (long[])lookupPowX2.elementAt(count - 1);
+ long[] prev = (long[])lookupPowX2.get(last);
do
{
- tmp = Arrays.clone(tmp);
- GCMUtil.square(tmp, tmp);
- lookupPowX2.addElement(tmp);
+ long[] next = new long[GCMUtil.SIZE_LONGS];
+ GCMUtil.square(prev, next);
+ lookupPowX2.add(next);
+ prev = next;
}
- while (++count <= bit);
+ while (++last < bit);
}
+
+ return (long[])lookupPowX2.get(bit);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java
index 30f2af6..8909017 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.modes.gcm;
-import com.android.internal.org.bouncycastle.util.Arrays;
import com.android.internal.org.bouncycastle.util.Pack;
/**
@@ -19,12 +18,13 @@
{
T = new long[256][2];
}
- else if (Arrays.areEqual(this.H, H))
+ else if (0 != GCMUtil.areEqual(this.H, H))
{
return;
}
- this.H = Arrays.clone(H);
+ this.H = new byte[GCMUtil.SIZE_BYTES];
+ GCMUtil.copy(H, this.H);
// T[0] = 0
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java
index 3b92541..793b271 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.modes.gcm;
-import com.android.internal.org.bouncycastle.util.Arrays;
import com.android.internal.org.bouncycastle.util.Pack;
/**
@@ -17,16 +16,17 @@
{
if (T == null)
{
- T = new long[32][16][2];
+ T = new long[2][256][2];
}
- else if (Arrays.areEqual(this.H, H))
+ else if (0 != GCMUtil.areEqual(this.H, H))
{
return;
}
- this.H = Arrays.clone(H);
+ this.H = new byte[GCMUtil.SIZE_BYTES];
+ GCMUtil.copy(H, this.H);
- for (int i = 0; i < 32; ++i)
+ for (int i = 0; i < 2; ++i)
{
long[][] t = T[i];
@@ -34,17 +34,17 @@
if (i == 0)
{
- // t[1] = H.p^3
+ // t[1] = H.p^7
GCMUtil.asLongs(this.H, t[1]);
- GCMUtil.multiplyP3(t[1], t[1]);
+ GCMUtil.multiplyP7(t[1], t[1]);
}
else
{
- // t[1] = T[i-1][1].p^4
- GCMUtil.multiplyP4(T[i - 1][1], t[1]);
+ // t[1] = T[i-1][1].p^8
+ GCMUtil.multiplyP8(T[i - 1][1], t[1]);
}
- for (int n = 2; n < 16; n += 2)
+ for (int n = 2; n < 256; n += 2)
{
// t[2.n] = t[n].p^-1
GCMUtil.divideP(t[n >> 1], t[n]);
@@ -53,28 +53,33 @@
GCMUtil.xor(t[n], t[1], t[n + 1]);
}
}
-
}
public void multiplyH(byte[] x)
{
+ long[][] T0 = T[0], T1 = T[1];
+
// long[] z = new long[2];
-// for (int i = 15; i >= 0; --i)
+// for (int i = 14; i >= 0; i -= 2)
// {
-// GCMUtil.xor(z, T[i + i + 1][(x[i] & 0x0F)]);
-// GCMUtil.xor(z, T[i + i ][(x[i] & 0xF0) >>> 4]);
+// GCMUtil.multiplyP16(z);
+// GCMUtil.xor(z, T0[x[i] & 0xFF]);
+// GCMUtil.xor(z, T1[x[i + 1] & 0xFF]);
// }
// Pack.longToBigEndian(z, x, 0);
- long z0 = 0, z1 = 0;
+ long[] u = T0[x[14] & 0xFF];
+ long[] v = T1[x[15] & 0xFF];
+ long z0 = u[0] ^ v[0], z1 = u[1] ^ v[1];
- for (int i = 15; i >= 0; --i)
+ for (int i = 12; i >= 0; i -= 2)
{
- long[] u = T[i + i + 1][(x[i] & 0x0F)];
- long[] v = T[i + i ][(x[i] & 0xF0) >>> 4];
+ u = T0[x[i] & 0xFF];
+ v = T1[x[i + 1] & 0xFF];
- z0 ^= u[0] ^ v[0];
- z1 ^= u[1] ^ v[1];
+ long c = z1 << 48;
+ z1 = u[1] ^ v[1] ^ ((z1 >>> 16) | (z0 << 48));
+ z0 = u[0] ^ v[0] ^ (z0 >>> 16) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
}
Pack.longToBigEndian(z0, x, 0);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
index 14c634a..7392808 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
@@ -63,9 +63,11 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in[in.length - 1] & 0xff;
+ int count = in[in.length - 1] & 0xFF;
+ int position = in.length - count;
- if (count > in.length)
+ int failed = (position | (count - 1)) >> 31;
+ if (failed != 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java
index 9b20044..84b9d2d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java
@@ -62,18 +62,20 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in.length - 1;
-
- while (count > 0 && in[count] == 0)
+ int position = -1, still00Mask = -1;
+ int i = in.length;
+ while (--i >= 0)
{
- count--;
+ int next = in[i] & 0xFF;
+ int match00Mask = ((next ^ 0x00) - 1) >> 31;
+ int match80Mask = ((next ^ 0x80) - 1) >> 31;
+ position ^= (i ^ position) & (still00Mask & match80Mask);
+ still00Mask &= match00Mask;
}
-
- if (in[count] != (byte)0x80)
+ if (position < 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
-
- return in.length - count;
+ return in.length - position;
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PKCS7Padding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PKCS7Padding.java
index f96d4b8..4058b56 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PKCS7Padding.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PKCS7Padding.java
@@ -58,18 +58,16 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in[in.length - 1] & 0xff;
- byte countAsbyte = (byte)count;
+ byte countAsByte = in[in.length - 1];
+ int count = countAsByte & 0xFF;
+ int position = in.length - count;
- // constant time version
- boolean failed = (count > in.length | count == 0);
-
- for (int i = 0; i < in.length; i++)
+ int failed = (position | (count - 1)) >> 31;
+ for (int i = 0; i < in.length; ++i)
{
- failed |= (in.length - i <= count) & (in[i] != countAsbyte);
+ failed |= (in[i] ^ countAsByte) & ~((i - position) >> 31);
}
-
- if (failed)
+ if (failed != 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java
index f75ef53..732c2e8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java
@@ -2,9 +2,9 @@
package com.android.internal.org.bouncycastle.crypto.paddings;
import com.android.internal.org.bouncycastle.crypto.BlockCipher;
-import com.android.internal.org.bouncycastle.crypto.BufferedBlockCipher;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
@@ -18,7 +18,7 @@
* @hide This class is not part of the Android public SDK API
*/
public class PaddedBufferedBlockCipher
- extends BufferedBlockCipher
+ extends DefaultBufferedBlockCipher
{
BlockCipherPadding padding;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/TBCPadding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/TBCPadding.java
index fbaa0f3..1040137 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/TBCPadding.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/TBCPadding.java
@@ -78,14 +78,15 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- byte code = in[in.length - 1];
-
- int index = in.length - 1;
- while (index > 0 && in[index - 1] == code)
+ int i = in.length;
+ int code = in[--i] & 0xFF, count = 1, countingMask = -1;
+ while (--i >= 0)
{
- index--;
+ int next = in[i] & 0xFF;
+ int matchMask = ((next ^ code) - 1) >> 31;
+ countingMask &= matchMask;
+ count -= countingMask;
}
-
- return in.length - index;
+ return count;
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/X923Padding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/X923Padding.java
index ca24e81..23b6cdb 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/X923Padding.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/X923Padding.java
@@ -70,9 +70,11 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in[in.length - 1] & 0xff;
+ int count = in[in.length - 1] & 0xFF;
+ int position = in.length - count;
- if (count > in.length)
+ int failed = (position | (count - 1)) >> 31;
+ if (failed != 0)
{
throw new InvalidCipherTextException("pad block corrupted");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ZeroBytePadding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ZeroBytePadding.java
index 9553137..c796e03 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ZeroBytePadding.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ZeroBytePadding.java
@@ -58,18 +58,15 @@
public int padCount(byte[] in)
throws InvalidCipherTextException
{
- int count = in.length;
-
- while (count > 0)
+ int count = 0, still00Mask = -1;
+ int i = in.length;
+ while (--i >= 0)
{
- if (in[count - 1] != 0)
- {
- break;
- }
-
- count--;
+ int next = in[i] & 0xFF;
+ int match00Mask = ((next ^ 0x00) - 1) >> 31;
+ still00Mask &= match00Mask;
+ count -= still00Mask;
}
-
- return in.length - count;
+ return count;
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/Blake3Parameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/Blake3Parameters.java
new file mode 100644
index 0000000..576967c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/Blake3Parameters.java
@@ -0,0 +1,86 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Blake3 Parameters.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Blake3Parameters
+ implements CipherParameters
+{
+ /**
+ * The key length.
+ */
+ private static final int KEYLEN = 32;
+
+ /**
+ * The key.
+ */
+ private byte[] theKey;
+
+ /**
+ * The context.
+ */
+ private byte[] theContext;
+
+ /**
+ * Create a key parameter.
+ * @param pContext the context
+ * @return the parameter
+ */
+ public static Blake3Parameters context(final byte[] pContext)
+ {
+ if (pContext == null)
+ {
+ throw new IllegalArgumentException("Invalid context");
+ }
+ final Blake3Parameters myParams = new Blake3Parameters();
+ myParams.theContext = Arrays.clone(pContext);
+ return myParams;
+ }
+
+ /**
+ * Create a key parameter.
+ * @param pKey the key
+ * @return the parameter
+ */
+ public static Blake3Parameters key(final byte[] pKey)
+ {
+ if (pKey == null || pKey.length != KEYLEN)
+ {
+ throw new IllegalArgumentException("Invalid keyLength");
+ }
+ final Blake3Parameters myParams = new Blake3Parameters();
+ myParams.theKey = Arrays.clone(pKey);
+ return myParams;
+ }
+
+ /**
+ * Obtain the key.
+ * @return the key
+ */
+ public byte[] getKey()
+ {
+ return Arrays.clone(theKey);
+ }
+
+ /**
+ * Clear the key bytes.
+ */
+ public void clearKey()
+ {
+ Arrays.fill(theKey, (byte) 0);
+ }
+
+ /**
+ * Obtain the salt.
+ * @return the salt
+ */
+ public byte[] getContext()
+ {
+ return Arrays.clone(theContext);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/FPEParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/FPEParameters.java
new file mode 100644
index 0000000..91b8dea
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/FPEParameters.java
@@ -0,0 +1,61 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.util.RadixConverter;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class FPEParameters
+ implements CipherParameters
+{
+ private final KeyParameter key;
+ private final RadixConverter radixConverter;
+ private final byte[] tweak;
+ private final boolean useInverse;
+
+ public FPEParameters(KeyParameter key, int radix, byte[] tweak)
+ {
+ this(key, radix, tweak, false);
+ }
+
+ public FPEParameters(KeyParameter key, int radix, byte[] tweak, boolean useInverse)
+ {
+ this(key, new RadixConverter(radix), tweak, useInverse);
+ }
+
+ public FPEParameters(KeyParameter key, RadixConverter radixConverter, byte[] tweak, boolean useInverse)
+ {
+ this.key = key;
+ this.radixConverter = radixConverter;
+ this.tweak = Arrays.clone(tweak);
+ this.useInverse = useInverse;
+ }
+
+ public KeyParameter getKey()
+ {
+ return key;
+ }
+
+ public int getRadix()
+ {
+ return radixConverter.getRadix();
+ }
+
+ public RadixConverter getRadixConverter()
+ {
+ return radixConverter;
+ }
+
+ public byte[] getTweak()
+ {
+ return Arrays.clone(tweak);
+ }
+
+ public boolean isUsingInverseFunction()
+ {
+ return useInverse;
+ }
+}
\ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KeyParameter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KeyParameter.java
index 210e7d6..aebfacd 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KeyParameter.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KeyParameter.java
@@ -2,6 +2,7 @@
package com.android.internal.org.bouncycastle.crypto.params;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.util.Arrays;
/**
* @hide This class is not part of the Android public SDK API
@@ -22,13 +23,38 @@
int keyOff,
int keyLen)
{
- this.key = new byte[keyLen];
+ this(keyLen);
System.arraycopy(key, keyOff, this.key, 0, keyLen);
}
+ private KeyParameter(int length)
+ {
+ this.key = new byte[length];
+ }
+
+ public void copyTo(byte[] buf, int off, int len)
+ {
+ if (key.length != len)
+ throw new IllegalArgumentException("len");
+
+ System.arraycopy(key, 0, buf, off, len);
+ }
+
public byte[] getKey()
{
return key;
}
+
+ public int getKeyLength()
+ {
+ return key.length;
+ }
+
+ public KeyParameter reverse()
+ {
+ KeyParameter reversed = new KeyParameter(key.length);
+ Arrays.reverse(this.key, reversed.key);
+ return reversed;
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java
index c23d9f5..4f76182 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java
@@ -3,6 +3,9 @@
import java.math.BigInteger;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.math.Primes;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
import com.android.internal.org.bouncycastle.util.Properties;
/**
@@ -11,6 +14,8 @@
public class RSAKeyParameters
extends AsymmetricKeyParameter
{
+ private static final BigIntegers.Cache validated = new BigIntegers.Cache();
+
// Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
"8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
@@ -29,6 +34,15 @@
BigInteger modulus,
BigInteger exponent)
{
+ this(isPrivate, modulus, exponent, false);
+ }
+
+ public RSAKeyParameters(
+ boolean isPrivate,
+ BigInteger modulus,
+ BigInteger exponent,
+ boolean isInternal)
+ {
super(isPrivate);
if (!isPrivate)
@@ -38,13 +52,20 @@
throw new IllegalArgumentException("RSA publicExponent is even");
}
}
-
- this.modulus = validate(modulus);
+
+ this.modulus = validated.contains(modulus) ? modulus : validate(modulus, isInternal);
this.exponent = exponent;
- }
+ }
- private BigInteger validate(BigInteger modulus)
+ private BigInteger validate(BigInteger modulus, boolean isInternal)
{
+ if (isInternal)
+ {
+ validated.add(modulus);
+
+ return modulus;
+ }
+
if ((modulus.intValue() & 1) == 0)
{
throw new IllegalArgumentException("RSA modulus is even");
@@ -57,16 +78,45 @@
return modulus;
}
+ int maxBitLength = Properties.asInteger("com.android.internal.org.bouncycastle.rsa.max_size", 15360);
+
+ int modBitLength = modulus.bitLength();
+ if (maxBitLength < modBitLength)
+ {
+ throw new IllegalArgumentException("modulus value out of range");
+ }
+
if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE))
{
throw new IllegalArgumentException("RSA modulus has a small prime factor");
}
- // TODO: add additional primePower/Composite test - expensive!!
+ int bits = modulus.bitLength() / 2;
+ int iterations = Properties.asInteger("com.android.internal.org.bouncycastle.rsa.max_mr_tests", getMRIterations(bits));
+ if (iterations > 0)
+ {
+ Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, CryptoServicesRegistrar.getSecureRandom(), iterations);
+ if (!mr.isProvablyComposite())
+ {
+ throw new IllegalArgumentException("RSA modulus is not composite");
+ }
+ }
+
+ validated.add(modulus);
+
return modulus;
}
+ private static int getMRIterations(int bits)
+ {
+ int iterations = bits >= 1536 ? 3
+ : bits >= 1024 ? 4
+ : bits >= 512 ? 7
+ : 50;
+ return iterations;
+ }
+
public BigInteger getModulus()
{
return modulus;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java
index 1fc5f05..f69b232 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java
@@ -20,6 +20,19 @@
*
*/
public RSAPrivateCrtKeyParameters(
+ BigInteger modulus,
+ BigInteger publicExponent,
+ BigInteger privateExponent,
+ BigInteger p,
+ BigInteger q,
+ BigInteger dP,
+ BigInteger dQ,
+ BigInteger qInv)
+ {
+ this(modulus, publicExponent, privateExponent, p, q, dP, dQ, qInv, false);
+ }
+
+ public RSAPrivateCrtKeyParameters(
BigInteger modulus,
BigInteger publicExponent,
BigInteger privateExponent,
@@ -27,9 +40,10 @@
BigInteger q,
BigInteger dP,
BigInteger dQ,
- BigInteger qInv)
+ BigInteger qInv,
+ boolean isInternal)
{
- super(true, modulus, privateExponent);
+ super(true, modulus, privateExponent, isInternal);
this.e = publicExponent;
this.p = p;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java
index 0be6a4a..a0de433 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java
@@ -70,6 +70,8 @@
this.key = (DSAPublicKeyParameters)param;
}
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("DSA", key, forSigning));
+
this.random = initSecureRandom(forSigning && !kCalculator.isDeterministic(), providedRandom);
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java
index 0216020..d854536 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java
@@ -76,6 +76,8 @@
this.key = (ECPublicKeyParameters)param;
}
+ CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties("ECDSA", key, forSigning));
+
this.random = initSecureRandom(forSigning && !kCalculator.isDeterministic(), providedRandom);
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/Utils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/Utils.java
new file mode 100644
index 0000000..8f969c5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/Utils.java
@@ -0,0 +1,41 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.signers;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.constraints.ConstraintUtils;
+import com.android.internal.org.bouncycastle.crypto.constraints.DefaultServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.params.DSAKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECKeyParameters;
+// Android-removed: unsupported algorithm
+// import org.bouncycastle.crypto.params.GOST3410KeyParameters;
+
+class Utils
+{
+ static CryptoServiceProperties getDefaultProperties(String algorithm, DSAKeyParameters k, boolean forSigning)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getP()), k, getPurpose(forSigning));
+ }
+
+ // Android-removed: unsupported algorithm
+ // static CryptoServiceProperties getDefaultProperties(String algorithm, GOST3410KeyParameters k, boolean forSigning)
+ // {
+ // return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getP()), k, getPurpose(forSigning));
+ // }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, ECKeyParameters k, boolean forSigning)
+ {
+ return new DefaultServiceProperties(algorithm, ConstraintUtils.bitsOfSecurityFor(k.getParameters().getCurve()), k, getPurpose(forSigning));
+ }
+
+ static CryptoServiceProperties getDefaultProperties(String algorithm, int bitsOfSecurity, CipherParameters k, boolean forSigning)
+ {
+ return new DefaultServiceProperties(algorithm, bitsOfSecurity, k, getPurpose(forSigning));
+ }
+
+ static CryptoServicePurpose getPurpose(boolean forSigning)
+ {
+ return forSigning ? CryptoServicePurpose.SIGNING : CryptoServicePurpose.VERIFYING;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/BasicAlphabetMapper.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/BasicAlphabetMapper.java
new file mode 100644
index 0000000..1e077c0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/BasicAlphabetMapper.java
@@ -0,0 +1,107 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.crypto.AlphabetMapper;
+
+/**
+ * A basic alphabet mapper that just creates a mapper based on the
+ * passed in array of characters.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BasicAlphabetMapper
+ implements AlphabetMapper
+{
+ private Map<Character, Integer> indexMap = new HashMap<Character, Integer>();
+ private Map<Integer, Character> charMap = new HashMap<Integer, Character>();
+
+ /**
+ * Base constructor.
+ *
+ * @param alphabet a String of characters making up the alphabet.
+ */
+ public BasicAlphabetMapper(String alphabet)
+ {
+ this(alphabet.toCharArray());
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param alphabet an array of characters making up the alphabet.
+ */
+ public BasicAlphabetMapper(char[] alphabet)
+ {
+ for (int i = 0; i != alphabet.length; i++)
+ {
+ if (indexMap.containsKey(alphabet[i]))
+ {
+ throw new IllegalArgumentException("duplicate key detected in alphabet: " + alphabet[i]);
+ }
+ indexMap.put(alphabet[i], i);
+ charMap.put(i, alphabet[i]);
+ }
+ }
+
+ public int getRadix()
+ {
+ return indexMap.size();
+ }
+
+ public byte[] convertToIndexes(char[] input)
+ {
+ byte[] out;
+
+ if (indexMap.size() <= 256)
+ {
+ out = new byte[input.length];
+ for (int i = 0; i != input.length; i++)
+ {
+ out[i] = indexMap.get(input[i]).byteValue();
+ }
+ }
+ else
+ {
+ out = new byte[input.length * 2];
+ for (int i = 0; i != input.length; i++)
+ {
+ int idx = indexMap.get(input[i]);
+ out[i * 2] = (byte)((idx >> 8) & 0xff);
+ out[i * 2 + 1] = (byte)(idx & 0xff);
+ }
+ }
+
+ return out;
+ }
+
+ public char[] convertToChars(byte[] input)
+ {
+ char[] out;
+
+ if (charMap.size() <= 256)
+ {
+ out = new char[input.length];
+ for (int i = 0; i != input.length; i++)
+ {
+ out[i] = charMap.get(input[i] & 0xff);
+ }
+ }
+ else
+ {
+ if ((input.length & 0x1) != 0)
+ {
+ throw new IllegalArgumentException("two byte radix and input string odd length");
+ }
+
+ out = new char[input.length / 2];
+ for (int i = 0; i != input.length; i += 2)
+ {
+ out[i / 2] = charMap.get(((input[i] << 8) & 0xff00) | (input[i + 1] & 0xff));
+ }
+ }
+
+ return out;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java
index 323d2c5..0a296f9 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java
@@ -70,6 +70,14 @@
public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData)
throws IOException
{
+ if (privateKeyInfoData == null)
+ {
+ throw new IllegalArgumentException("privateKeyInfoData array null");
+ }
+ if (privateKeyInfoData.length == 0)
+ {
+ throw new IllegalArgumentException("privateKeyInfoData array empty");
+ }
return createKey(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(privateKeyInfoData)));
}
@@ -97,6 +105,11 @@
public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo)
throws IOException
{
+ if (keyInfo == null)
+ {
+ throw new IllegalArgumentException("keyInfo argument null");
+ }
+
AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm();
ASN1ObjectIdentifier algOID = algId.getAlgorithm();
@@ -139,12 +152,12 @@
else if (algOID.equals(X9ObjectIdentifiers.id_dsa))
{
ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
- ASN1Encodable de = algId.getParameters();
+ ASN1Encodable algParameters = algId.getParameters();
DSAParameters parameters = null;
- if (de != null)
+ if (algParameters != null)
{
- DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive());
+ DSAParameter params = DSAParameter.getInstance(algParameters.toASN1Primitive());
parameters = new DSAParameters(params.getP(), params.getQ(), params.getG());
}
@@ -184,32 +197,44 @@
/*
else if (algOID.equals(EdECObjectIdentifiers.id_X25519))
{
- return new X25519PrivateKeyParameters(getRawKey(keyInfo, X25519PrivateKeyParameters.KEY_SIZE), 0);
+ // Java 11 bug: exact length of X25519/X448 secret used in Java 11
+ if (X25519PrivateKeyParameters.KEY_SIZE == keyInfo.getPrivateKeyLength())
+ {
+ return new X25519PrivateKeyParameters(keyInfo.getPrivateKey().getOctets());
+ }
+
+ return new X25519PrivateKeyParameters(getRawKey(keyInfo));
}
else if (algOID.equals(EdECObjectIdentifiers.id_X448))
{
- return new X448PrivateKeyParameters(getRawKey(keyInfo, X448PrivateKeyParameters.KEY_SIZE), 0);
+ // Java 11 bug: exact length of X25519/X448 secret used in Java 11
+ if (X448PrivateKeyParameters.KEY_SIZE == keyInfo.getPrivateKeyLength())
+ {
+ return new X448PrivateKeyParameters(keyInfo.getPrivateKey().getOctets());
+ }
+
+ return new X448PrivateKeyParameters(getRawKey(keyInfo));
}
else if (algOID.equals(EdECObjectIdentifiers.id_Ed25519))
{
- return new Ed25519PrivateKeyParameters(getRawKey(keyInfo, Ed25519PrivateKeyParameters.KEY_SIZE), 0);
+ return new Ed25519PrivateKeyParameters(getRawKey(keyInfo));
}
else if (algOID.equals(EdECObjectIdentifiers.id_Ed448))
{
- return new Ed448PrivateKeyParameters(getRawKey(keyInfo, Ed448PrivateKeyParameters.KEY_SIZE), 0);
+ return new Ed448PrivateKeyParameters(getRawKey(keyInfo));
}
else if (
algOID.equals(CryptoProObjectIdentifiers.gostR3410_2001) ||
algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) ||
algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256))
{
- GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters());
+ ASN1Encodable algParameters = algId.getParameters();
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(algParameters);
ECGOST3410Parameters ecSpec = null;
BigInteger d = null;
- ASN1Primitive p = keyInfo.getPrivateKeyAlgorithm().getParameters().toASN1Primitive();
+ ASN1Primitive p = algParameters.toASN1Primitive();
if (p instanceof ASN1Sequence && (ASN1Sequence.getInstance(p).size() == 2 || ASN1Sequence.getInstance(p).size() == 3))
{
-
X9ECParameters ecP = ECGOST3410NamedCurves.getByOIDX9(gostParams.getPublicKeyParamSet());
ecSpec = new ECGOST3410Parameters(
@@ -218,11 +243,12 @@
gostParams.getPublicKeyParamSet(),
gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet());
- ASN1OctetString privEnc = keyInfo.getPrivateKey();
- if (privEnc.getOctets().length == 32 || privEnc.getOctets().length == 64)
+ int privateKeyLength = keyInfo.getPrivateKeyLength();
+
+ if (privateKeyLength == 32 || privateKeyLength == 64)
{
- d = new BigInteger(1, Arrays.reverse(privEnc.getOctets()));
+ d = new BigInteger(1, Arrays.reverse(keyInfo.getPrivateKey().getOctets()));
}
else
{
@@ -240,7 +266,7 @@
}
else
{
- X962Parameters params = X962Parameters.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters());
+ X962Parameters params = X962Parameters.getInstance(algId.getParameters());
if (params.isNamedCurve())
{
@@ -296,14 +322,8 @@
}
}
- private static byte[] getRawKey(PrivateKeyInfo keyInfo, int expectedSize)
- throws IOException
+ private static byte[] getRawKey(PrivateKeyInfo keyInfo) throws IOException
{
- byte[] result = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets();
- if (expectedSize != result.length)
- {
- throw new RuntimeException("private key encoding has incorrect length");
- }
- return result;
+ return ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets();
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java
index 9e1f295..1b44a17 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java
@@ -7,13 +7,13 @@
import java.util.HashMap;
import java.util.Map;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
@@ -115,6 +115,14 @@
public static AsymmetricKeyParameter createKey(byte[] keyInfoData)
throws IOException
{
+ if (keyInfoData == null)
+ {
+ throw new IllegalArgumentException("keyInfoData array null");
+ }
+ if (keyInfoData.length == 0)
+ {
+ throw new IllegalArgumentException("keyInfoData array empty");
+ }
return createKey(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(keyInfoData)));
}
@@ -141,6 +149,10 @@
public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo)
throws IOException
{
+ if (keyInfo == null)
+ {
+ throw new IllegalArgumentException("keyInfo argument null");
+ }
return createKey(keyInfo, null);
}
@@ -155,6 +167,11 @@
public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Object defaultParams)
throws IOException
{
+ if (keyInfo == null)
+ {
+ throw new IllegalArgumentException("keyInfo argument null");
+ }
+
AlgorithmIdentifier algID = keyInfo.getAlgorithm();
SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algID.getAlgorithm());
@@ -306,7 +323,7 @@
dParams = new ECDomainParameters(x9);
}
- DERBitString bits = keyInfo.getPublicKeyData();
+ ASN1BitString bits = keyInfo.getPublicKeyData();
byte[] data = bits.getBytes();
ASN1OctetString key = new DEROctetString(data);
@@ -483,7 +500,7 @@
}
BigInteger b = new BigInteger(1, b_bytes);
DSTU4145BinaryField field = binary.getField();
- ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), b);
+ ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), b, null, null);
byte[] g_bytes = binary.getG();
if (algOid.equals(UAObjectIdentifiers.dstu4145le))
{
@@ -516,7 +533,7 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new X25519PublicKeyParameters(getRawKey(keyInfo, defaultParams, X25519PublicKeyParameters.KEY_SIZE), 0);
+ return new X25519PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
@@ -525,7 +542,7 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new X448PublicKeyParameters(getRawKey(keyInfo, defaultParams, X448PublicKeyParameters.KEY_SIZE), 0);
+ return new X448PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
@@ -534,7 +551,7 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new Ed25519PublicKeyParameters(getRawKey(keyInfo, defaultParams, Ed25519PublicKeyParameters.KEY_SIZE), 0);
+ return new Ed25519PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
@@ -543,24 +560,19 @@
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- return new Ed448PublicKeyParameters(getRawKey(keyInfo, defaultParams, Ed448PublicKeyParameters.KEY_SIZE), 0);
+ return new Ed448PublicKeyParameters(getRawKey(keyInfo, defaultParams));
}
}
*/
// END Android-removed: Unsupported algorithms
- private static byte[] getRawKey(SubjectPublicKeyInfo keyInfo, Object defaultParams, int expectedSize)
+ private static byte[] getRawKey(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
/*
* TODO[RFC 8422]
* - Require defaultParams == null?
* - Require keyInfo.getAlgorithm().getParameters() == null?
*/
- byte[] result = keyInfo.getPublicKeyData().getOctets();
- if (expectedSize != result.length)
- {
- throw new RuntimeException("public key encoding has incorrect length");
- }
- return result;
+ return keyInfo.getPublicKeyData().getOctets();
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/RadixConverter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/RadixConverter.java
new file mode 100644
index 0000000..dc8492e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/RadixConverter.java
@@ -0,0 +1,190 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.util;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * Utility class to convert decimal numbers (BigInteger) into a number in the base provided and the other way round.
+ * <p>For an application of this see the FPE parameter classes.</p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RadixConverter
+{
+
+ /*
+ The conversions in this class are more complex than the standard ways of converting between basis because we want to improve the performance by limiting the
+ operations on BigInteger which are not very efficient.
+ The general idea is to perform math operations on primitive long as much as we can and just work with BigInteger when necessary.
+ Converting between basis uses the fact that a number in base 'B' have a unique representation in polynomial form.
+
+ num = ... + r8B^8 + r7B^7 + r6B^6 + r5B^5 + r4B^4 + r3B^3 + r2B^2 + r1B + r0
+
+ We can compute how many digits in base 'B' can fit in a long. For example, for a radix R=2^16 the number of digits 'n' that we can fit into a long is the
+ max 'n' that still satisfies: R^n < Long.MAX_VALUE (i.e. 2^63 -1). In this case 'n' is 3. To convert 'num' from its decimal representation to base 'B'
+ representation we can write down 'num' in a polynomial form of B^3:
+
+ num = (((...)B^3 + r8B^2 + r7B + r6)B^3 + r5B^2 + r4B + r3)B^3 + (r2B^2 + r1B + r0)
+
+ B^3 would be our intermediate base. We can convert numbers in base B^3 while operating on primitive long.
+ To convert a decimal num to its representation in base B we can first build its B^3 representation and then figure out the digits in base B from the single
+ digit in base B^3. num % B^3 gives us a single digit in base B^3 which corresponds to a group of 3 digits in base B.
+
+ An equivalent way of writing the polynomial form of num would be:
+
+ num = (...)B^9 + (r8B^8 + r7B^7 + r6B^6)B^6 + (r5B^5 + r4B^4 + r3)B^3 + (r2B^2 + r1B + r0)
+
+ In this form it becomes clear that to obtain 'num' from a sequence of digits, one can group the digits in group of 3 and compute the corresponding decimal
+ number for the group in base B. We can then multiply the decimal numbers by the corresponding power of B^3 and sum up the result to obtain the decimal
+ representation of num in base B,
+ */
+ private static final double LOG_LONG_MAX_VALUE = Math.log(Long.MAX_VALUE);
+ private static final int DEFAULT_POWERS_TO_CACHE = 10;
+ // the max number of digits in base 'radix' that fits in a long
+ private final int digitsGroupLength;
+ // the total number of digits combination in a group. radix ^ digitsGroupLength
+ private final BigInteger digitsGroupSpaceSize;
+ private final int radix;
+ private final BigInteger[] digitsGroupSpacePowers;
+
+ /**
+ * @param radix the radix to use for base conversions
+ * @param numberOfCachedPowers number of intermediate base powers to precompute and cache.
+ */
+ public RadixConverter(int radix, int numberOfCachedPowers)
+ {
+ this.radix = radix;
+ // solves radix^n < Long.MAX_VALUE to find n (maxDigitsFitsInLong)
+ this.digitsGroupLength = (int)Math.floor(LOG_LONG_MAX_VALUE / Math.log(radix));
+ this.digitsGroupSpaceSize = BigInteger.valueOf(radix).pow(digitsGroupLength);
+ this.digitsGroupSpacePowers = precomputeDigitsGroupPowers(numberOfCachedPowers, digitsGroupSpaceSize);
+ }
+
+ /**
+ * @param radix the radix to use for base conversions.
+ */
+ public RadixConverter(int radix)
+ {
+ this(radix, DEFAULT_POWERS_TO_CACHE);
+ }
+
+ public int getRadix()
+ {
+ return radix;
+ }
+
+ public void toEncoding(BigInteger number, int messageLength, short[] out)
+ {
+ if (number.signum() < 0)
+ {
+ throw new IllegalArgumentException();
+ }
+ // convert number into its representation in base 'radix'.
+ // writes leading '0' if the messageLength is greater than the number of digits required to encode in base 'radix'
+ int digitIndex = messageLength - 1;
+ do
+ {
+ if (number.equals(BigInteger.ZERO))
+ {
+ out[digitIndex--] = 0;
+ continue;
+ }
+ BigInteger[] quotientAndRemainder = number.divideAndRemainder(digitsGroupSpaceSize);
+ number = quotientAndRemainder[0];
+ digitIndex = toEncoding(quotientAndRemainder[1].longValue(), digitIndex, out);
+ }
+ while (digitIndex >= 0);
+ if (number.signum() != 0)
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private int toEncoding(long number, int digitIndex, short[] out)
+ {
+ for (int i = 0; i < digitsGroupLength && digitIndex >= 0; i++)
+ {
+ if (number == 0)
+ {
+ out[digitIndex--] = 0;
+ continue;
+ }
+ out[digitIndex--] = (short)(number % radix);
+ number = number / radix;
+ }
+ if (number != 0)
+ {
+ throw new IllegalStateException("Failed to convert decimal number");
+ }
+ return digitIndex;
+ }
+
+ public BigInteger fromEncoding(short[] digits)
+ {
+ // from a sequence of digits in base 'radix' to a decimal number
+ // iterate through groups of digits right to left
+ // digitsGroupLength = 2; digits: [22, 45, 11, 31, 24]
+ // groups are, in order of iteration: [31, 24], [45, 11], [22]
+ BigInteger currentGroupCardinality = BigIntegers.ONE;
+ BigInteger res = null;
+ int indexGroup = 0;
+ int numberOfDigits = digits.length;
+ for (int groupStartDigitIndex = numberOfDigits - digitsGroupLength;
+ groupStartDigitIndex > -digitsGroupLength;
+ groupStartDigitIndex = groupStartDigitIndex - digitsGroupLength)
+ {
+ int actualDigitsInGroup = digitsGroupLength;
+ if (groupStartDigitIndex < 0)
+ {
+ // last group might contain fewer digits so adjust offsets
+ actualDigitsInGroup = digitsGroupLength + groupStartDigitIndex;
+ groupStartDigitIndex = 0;
+ }
+ int groupEndDigitIndex = Math.min(groupStartDigitIndex + actualDigitsInGroup, numberOfDigits);
+ long groupInBaseRadix = fromEncoding(groupStartDigitIndex, groupEndDigitIndex, digits);
+ BigInteger bigInteger = BigInteger.valueOf(groupInBaseRadix);
+ if (indexGroup == 0)
+ {
+ res = bigInteger;
+ }
+ else
+ {
+ currentGroupCardinality =
+ indexGroup <= digitsGroupSpacePowers.length
+ ? digitsGroupSpacePowers[indexGroup - 1]
+ : currentGroupCardinality.multiply(digitsGroupSpaceSize);
+ res = res.add(bigInteger.multiply(currentGroupCardinality));
+ }
+ indexGroup++;
+ }
+ return res;
+ }
+
+ public int getDigitsGroupLength()
+ {
+ return digitsGroupLength;
+ }
+
+ private long fromEncoding(int groupStartDigitIndex, int groupEndDigitIndex, short[] digits)
+ {
+ long decimalNumber = 0;
+ for (int digitIndex = groupStartDigitIndex; digitIndex < groupEndDigitIndex; digitIndex++)
+ {
+ decimalNumber = (decimalNumber * radix) + (digits[digitIndex] & 0xFFFF);
+ }
+ return decimalNumber;
+ }
+
+ private BigInteger[] precomputeDigitsGroupPowers(int numberOfCachedPowers, BigInteger digitsGroupSpaceSize)
+ {
+ BigInteger[] cachedPowers = new BigInteger[numberOfCachedPowers];
+ BigInteger currentPower = digitsGroupSpaceSize;
+ for (int i = 0; i < numberOfCachedPowers; i++)
+ {
+ cachedPowers[i] = currentPower;
+ currentPower = currentPower.multiply(digitsGroupSpaceSize);
+ }
+ return cachedPowers;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/SSHNamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/SSHNamedCurves.java
index 9853bf2..9498637 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/SSHNamedCurves.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/SSHNamedCurves.java
@@ -73,8 +73,8 @@
while (e.hasMoreElements())
{
String name = (String)e.nextElement();
- X9ECParameters parameters = CustomNamedCurves.getByName(name);
- put(parameters.getCurve(), name);
+ ECCurve curve = CustomNamedCurves.getByNameLazy(name).getCurve();
+ put(curve, name);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/GCMParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/internal/asn1/cms/GCMParameters.java
similarity index 89%
rename from repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/GCMParameters.java
rename to repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/internal/asn1/cms/GCMParameters.java
index e08c5a2..3bc6dd9 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/GCMParameters.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/internal/asn1/cms/GCMParameters.java
@@ -1,5 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1.cms;
+package com.android.internal.org.bouncycastle.internal.asn1.cms;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
@@ -33,8 +33,8 @@
* Accepted inputs:
* <ul>
* <li> null → null
- * <li> {@link com.android.internal.org.bouncycastle.asn1.cms.GCMParameters} object
- * <li> {@link com.android.internal.org.bouncycastle.asn1.ASN1Sequence#getInstance(Object) ASN1Sequence} input formats with GCMParameters structure inside
+ * <li> {@link GCMParameters} object
+ * <li> {@link ASN1Sequence#getInstance(Object) ASN1Sequence} input formats with GCMParameters structure inside
* </ul>
*
* @param obj the object we want converted.
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java
similarity index 94%
rename from repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java
rename to repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java
index 9bfcbfc..3ef4699 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/internal/asn1/isismtt/ISISMTTObjectIdentifiers.java
@@ -1,5 +1,5 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.asn1.isismtt;
+package com.android.internal.org.bouncycastle.internal.asn1.isismtt;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -105,8 +105,6 @@
* </pre>
* <p>
* OID: 1.3.36.8.3.8
- *
- * @see com.android.internal.org.bouncycastle.asn1.isismtt.x509.Restriction
*/
static final ASN1ObjectIdentifier id_isismtt_at_restriction = id_isismtt_at.branch("8");
@@ -131,8 +129,6 @@
* returned in this extension.
* <p>
* OID: 1.3.36.8.3.10
- *
- * @see com.android.internal.org.bouncycastle.asn1.isismtt.ocsp.RequestedCertificate
*/
static final ASN1ObjectIdentifier id_isismtt_at_requestedCertificate = id_isismtt_at.branch("10");
@@ -161,8 +157,7 @@
* Hash of a certificate in OCSP.
* <p>
* OID: 1.3.36.8.3.13
- *
- * @see com.android.internal.org.bouncycastle.asn1.isismtt.ocsp.CertHash
+ *
*/
static final ASN1ObjectIdentifier id_isismtt_at_certHash = id_isismtt_at.branch("13");
@@ -188,8 +183,7 @@
* </pre>
* <p>
* OID: 1.3.36.8.3.15
- *
- * @see com.android.internal.org.bouncycastle.asn1.isismtt.x509.AdditionalInformationSyntax
+ *
*/
static final ASN1ObjectIdentifier id_isismtt_at_additionalInformation = id_isismtt_at.branch("15");
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EndEntityType.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EndEntityType.java
deleted file mode 100644
index dac4a9e..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EndEntityType.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.its.asn1;
-
-import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
-import com.android.internal.org.bouncycastle.asn1.ASN1Object;
-import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
-
-/**
- * <pre>
- * EndEntityType ::= BIT STRING { app(0), enrol(1) } (SIZE (8)) (ALL EXCEPT ())
- * </pre>
- * @hide This class is not part of the Android public SDK API
- */
-public class EndEntityType
- extends ASN1Object
-{
- public static final int app = (1 << 7);
- public static final int enrol = (1 << 6);
-
- private final ASN1BitString type;
-
- public EndEntityType(int type)
- {
- if (type != app && type != enrol)
- {
- throw new IllegalArgumentException("value out of range");
- }
-
- this.type = new DERBitString(type);
- }
-
- private EndEntityType(DERBitString str)
- {
- this.type = str;
- }
-
- public static EndEntityType getInstance(Object src)
- {
- if (src instanceof EndEntityType)
- {
- return (EndEntityType)src;
- }
- else if (src != null)
- {
- return new EndEntityType(DERBitString.getInstance(src));
- }
-
- return null;
- }
-
- public ASN1Primitive toASN1Primitive()
- {
- return type;
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PsidGroupPermissions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PsidGroupPermissions.java
deleted file mode 100644
index 72173fc..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PsidGroupPermissions.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.its.asn1;
-
-import java.math.BigInteger;
-
-import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
-import com.android.internal.org.bouncycastle.asn1.ASN1Object;
-import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
-
-/**
- * <pre>
- * PsidGroupPermissions ::= SEQUENCE {
- * subjectPermissions SubjectPermissions,
- * minChainLength INTEGER DEFAULT 1,
- * chainLengthRange INTEGER DEFAULT 0,
- * eeType EndEntityType DEFAULT (app)
- * }
- * </pre>
- * @hide This class is not part of the Android public SDK API
- */
-public class PsidGroupPermissions
- extends ASN1Object
-{
- private final SubjectPermissions subjectPermissions;
- private final BigInteger minChainLength;
- private final BigInteger chainLengthRange;
- private final Object eeType;
-
- private PsidGroupPermissions(ASN1Sequence seq)
- {
- if (seq.size() != 2)
- {
- throw new IllegalArgumentException("sequence not length 2");
- }
-
- this.subjectPermissions = SubjectPermissions.getInstance(seq.getObjectAt(0));
- this.minChainLength = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue();
- this.chainLengthRange = ASN1Integer.getInstance(seq.getObjectAt(2)).getValue();
- this.eeType = EndEntityType.getInstance(seq.getObjectAt(3));
- }
-
- public static PsidGroupPermissions getInstance(Object src)
- {
- if (src instanceof PsidGroupPermissions)
- {
- return (PsidGroupPermissions)src;
- }
- else if (src != null)
- {
- return new PsidGroupPermissions(ASN1Sequence.getInstance(src));
- }
-
- return null;
- }
-
- public ASN1Primitive toASN1Primitive()
- {
- return null;
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/BCLoadStoreParameter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/BCLoadStoreParameter.java
new file mode 100644
index 0000000..da84300
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/BCLoadStoreParameter.java
@@ -0,0 +1,75 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCLoadStoreParameter
+ implements KeyStore.LoadStoreParameter
+{
+ private final InputStream in;
+ private final OutputStream out;
+ private final KeyStore.ProtectionParameter protectionParameter;
+
+ /**
+ * Base constructor for
+ *
+ * @param out
+ * @param password
+ */
+ public BCLoadStoreParameter(OutputStream out, char[] password)
+ {
+ this(out, new KeyStore.PasswordProtection(password));
+ }
+
+ public BCLoadStoreParameter(InputStream in, char[] password)
+ {
+ this(in, new KeyStore.PasswordProtection(password));
+ }
+
+ public BCLoadStoreParameter(InputStream in, KeyStore.ProtectionParameter protectionParameter)
+ {
+ this(in, null, protectionParameter);
+ }
+
+ public BCLoadStoreParameter(OutputStream out, KeyStore.ProtectionParameter protectionParameter)
+ {
+ this(null, out, protectionParameter);
+ }
+
+ BCLoadStoreParameter(InputStream in, OutputStream out, KeyStore.ProtectionParameter protectionParameter)
+ {
+ this.in = in;
+ this.out = out;
+ this.protectionParameter = protectionParameter;
+ }
+
+ public KeyStore.ProtectionParameter getProtectionParameter()
+ {
+ return protectionParameter;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ if (out == null)
+ {
+ throw new UnsupportedOperationException("parameter not configured for storage - no OutputStream");
+ }
+
+ return out;
+ }
+
+ public InputStream getInputStream()
+ {
+ if (out != null)
+ {
+ throw new UnsupportedOperationException("parameter configured for storage OutputStream present");
+ }
+
+ return in;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePrivateKey.java
index 594a05b..06a247b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePrivateKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePrivateKey.java
@@ -75,7 +75,7 @@
try
{
return new PrivateKeyInfo(
- new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_composite_key), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
}
catch (IOException e)
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePublicKey.java
index e9af6e5..1f73e33 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePublicKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePublicKey.java
@@ -75,7 +75,7 @@
try
{
return new SubjectPublicKeyInfo(
- new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_composite_key), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
}
catch (IOException e)
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/ExternalPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/ExternalPublicKey.java
new file mode 100644
index 0000000..03f56fe
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/ExternalPublicKey.java
@@ -0,0 +1,105 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.bc.BCObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.bc.ExternalValue;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.jcajce.util.MessageDigestUtils;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Wrapper class which returns an "ExternalValue" for the public key encoding. In this case
+ * the key encoding is a hash and the actual key needs to be looked up somewhere else. Useful
+ * for where the public keys are really large but it's required to keep certificates small.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExternalPublicKey
+ implements PublicKey
+{
+ private final GeneralName location;
+ private final AlgorithmIdentifier digestAlg;
+ private final byte[] digest;
+
+ /**
+ * Base constructor with fundamental contents.
+ *
+ * @param location location URI for the actual public key.
+ * @param digestAlg hashing algorithm used to hash the actual public key encoding.
+ * @param digest digest of the actual public key.
+ */
+ public ExternalPublicKey(GeneralName location, AlgorithmIdentifier digestAlg, byte[] digest)
+ {
+ this.location = location;
+ this.digestAlg = digestAlg;
+ this.digest = Arrays.clone(digest);
+ }
+
+ /**
+ * Helper constructor with JCA contents.
+ *
+ * @param key the public key we are externalising.
+ * @param location location URI for the actual public key.
+ * @param digest digest to use for hashing the key.
+ */
+ // Android-removed: unsupported
+ // public ExternalPublicKey(PublicKey key, GeneralName location, MessageDigest digest)
+ // {
+ // this(location, MessageDigestUtils.getDigestAlgID(digest.getAlgorithm()), digest.digest(key.getEncoded()));
+ // }
+
+ /**
+ * Base constructor with ASN.1 structure.
+ *
+ * @param extKey structure with location, hashing algorithm and hash for the public key.
+ */
+ public ExternalPublicKey(ExternalValue extKey)
+ {
+ this(extKey.getLocation(), extKey.getHashAlg(), extKey.getHashValue());
+ }
+
+ /**
+ * Return "ExternalKey"
+ *
+ * @return "ExternalKey"
+ */
+ public String getAlgorithm()
+ {
+ return "ExternalKey";
+ }
+
+ /**
+ * Return "X.509" (DER encoded SubjectPublicKeyInfo)
+ *
+ * @return "X.509"
+ */
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ /**
+ * Return a SubjectPublicKeyInfo structure containing an ExternalValue encoding for the key.
+ *
+ * @return a DER encoding of SubjectPublicKeyInfo containing an ExternalValue structure.
+ */
+ public byte[] getEncoded()
+ {
+ try
+ {
+ return new SubjectPublicKeyInfo(
+ new AlgorithmIdentifier(BCObjectIdentifiers.external_value),
+ new ExternalValue(location, digestAlg, digest)).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode composite key: " + e.getMessage());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/SecretKeyWithEncapsulation.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/SecretKeyWithEncapsulation.java
new file mode 100644
index 0000000..edcd039
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/SecretKeyWithEncapsulation.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import javax.crypto.SecretKey;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Carrier class for a KEM/KTS secret key plus its encapsulation.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class SecretKeyWithEncapsulation
+ implements SecretKey
+{
+ private final SecretKey secretKey;
+ private final byte[] encapsulation;
+
+ /**
+ * Basic constructor.
+ *
+ * @param secretKey the secret key that was arrived at.
+ * @param encapsulation the encapsulation the key data was carried in.
+ */
+ public SecretKeyWithEncapsulation(SecretKey secretKey, byte[] encapsulation)
+ {
+ this.secretKey = secretKey;
+ this.encapsulation = Arrays.clone(encapsulation);
+ }
+
+ /**
+ * Return the algorithm for the agreed secret key.
+ *
+ * @return the secret key value.
+ */
+ public String getAlgorithm()
+ {
+ return secretKey.getAlgorithm();
+ }
+
+ /**
+ * Return the format for the agreed secret key.
+ *
+ * @return the secret key format.
+ */
+ public String getFormat()
+ {
+ return secretKey.getFormat();
+ }
+
+ /**
+ * Return the encoding of the agreed secret key.
+ *
+ * @return the secret key encoding.
+ */
+ public byte[] getEncoded()
+ {
+ return secretKey.getEncoded();
+ }
+
+ /**
+ * Return the encapsulation that carried the key material used in creating the agreed secret key.
+ *
+ * @return the encrypted encapsulation of the agreed secret key.
+ */
+ public byte[] getEncapsulation()
+ {
+ return Arrays.clone(encapsulation);
+ }
+
+ public boolean equals(Object o)
+ {
+ return secretKey.equals(o);
+ }
+
+ public int hashCode()
+ {
+ return secretKey.hashCode();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java
index 8127e4d..2c288d5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java
@@ -6,6 +6,8 @@
import java.security.Signature;
import java.security.SignatureException;
+import com.android.internal.org.bouncycastle.util.Exceptions;
+
class SignatureUpdatingOutputStream
extends OutputStream
{
@@ -25,7 +27,7 @@
}
catch (SignatureException e)
{
- throw new IOException(e.getMessage());
+ throw Exceptions.ioException(e.getMessage(), e);
}
}
@@ -38,7 +40,7 @@
}
catch (SignatureException e)
{
- throw new IOException(e.getMessage());
+ throw Exceptions.ioException(e.getMessage(), e);
}
}
@@ -51,7 +53,7 @@
}
catch (SignatureException e)
{
- throw new IOException(e.getMessage());
+ throw Exceptions.ioException(e.getMessage(), e);
}
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java
new file mode 100644
index 0000000..0826695
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/COMPOSITE.java
@@ -0,0 +1,149 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.jcajce.CompositePrivateKey;
+import com.android.internal.org.bouncycastle.jcajce.CompositePublicKey;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class COMPOSITE
+{
+ private static final String PREFIX = "com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.COMPOSITE";
+
+ private static final Map<String, String> compositeAttributes = new HashMap<String, String>();
+
+ static
+ {
+ compositeAttributes.put("SupportedKeyClasses", "com.android.internal.org.bouncycastle.jcajce.CompositePublicKey|com.android.internal.org.bouncycastle.jcajce.CompositePrivateKey");
+ compositeAttributes.put("SupportedKeyFormats", "PKCS#8|X.509");
+ }
+
+ private static AsymmetricKeyInfoConverter baseConverter;
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyFactory
+ extends BaseKeyFactorySpi
+ {
+ protected Key engineTranslateKey(Key key)
+ throws InvalidKeyException
+ {
+ try
+ {
+ if (key instanceof PrivateKey)
+ {
+ return generatePrivate(PrivateKeyInfo.getInstance(key.getEncoded()));
+ }
+ else if (key instanceof PublicKey)
+ {
+ return generatePublic(SubjectPublicKeyInfo.getInstance(key.getEncoded()));
+ }
+ }
+ catch (IOException e)
+ {
+ throw new InvalidKeyException("key could not be parsed: " + e.getMessage());
+ }
+
+ throw new InvalidKeyException("key not recognized");
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePrivate(keyInfo);
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePublic(keyInfo);
+ }
+ }
+
+ private static class CompositeKeyInfoConverter
+ implements AsymmetricKeyInfoConverter
+ {
+ private final ConfigurableProvider provider;
+
+ public CompositeKeyInfoConverter(ConfigurableProvider provider)
+ {
+ this.provider = provider;
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(keyInfo.parsePrivateKey());
+ PrivateKey[] privKeys = new PrivateKey[keySeq.size()];
+
+ for (int i = 0; i != keySeq.size(); i++)
+ {
+ PrivateKeyInfo privInfo = PrivateKeyInfo.getInstance(keySeq.getObjectAt(i));
+
+ privKeys[i] = provider.getKeyInfoConverter(
+ privInfo.getPrivateKeyAlgorithm().getAlgorithm()).generatePrivate(privInfo);
+ }
+
+ return new CompositePrivateKey(privKeys);
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(keyInfo.getPublicKeyData().getBytes());
+ PublicKey[] pubKeys = new PublicKey[keySeq.size()];
+
+ for (int i = 0; i != keySeq.size(); i++)
+ {
+ SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(keySeq.getObjectAt(i));
+
+ pubKeys[i] = provider.getKeyInfoConverter((pubInfo.getAlgorithm().getAlgorithm())).generatePublic(pubInfo);
+ }
+
+ return new CompositePublicKey(pubKeys);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyFactory.COMPOSITE", PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory." + MiscObjectIdentifiers.id_alg_composite, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory.OID." + MiscObjectIdentifiers.id_alg_composite, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory." + MiscObjectIdentifiers.id_composite_key, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory.OID." + MiscObjectIdentifiers.id_composite_key, PREFIX + "$KeyFactory");
+
+ baseConverter = new CompositeKeyInfoConverter(provider);
+
+ provider.addKeyInfoConverter(MiscObjectIdentifiers.id_alg_composite, baseConverter);
+ provider.addKeyInfoConverter(MiscObjectIdentifiers.id_composite_key, baseConverter);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DSA.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
index 869ed54..aa19a8a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
@@ -24,7 +24,7 @@
public Mappings()
{
}
-
+
public void configure(ConfigurableProvider provider)
{
provider.addAlgorithm("AlgorithmParameters.DSA", PREFIX + "AlgorithmParametersSpi");
@@ -91,6 +91,8 @@
provider.addAlgorithm("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA");
// END Android-changed: Change primary ID from DSA to SHA1withDSA
+ // addSignatureAlgorithm(provider, "RIPEMD160", "DSA", PREFIX + "DSASigner$dsaRMD160");
+
AsymmetricKeyInfoConverter keyFact = new KeyFactorySpi();
for (int i = 0; i != DSAUtil.dsaOids.length; i++)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/EC.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/EC.java
index fa92c48..d9ae497 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/EC.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/EC.java
@@ -12,6 +12,9 @@
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
// END Android-removed: Unsupported algorithms
import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.cms.CMSObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.eac.EACObjectIdentifiers;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi;
import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
@@ -50,77 +53,73 @@
/*
provider.addAlgorithm("AlgorithmParameters.EC", PREFIX + "AlgorithmParametersSpi");
- provider.addAttributes("KeyAgreement.ECDH", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH");
- provider.addAttributes("KeyAgreement.ECDHC", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHC", PREFIX + "KeyAgreementSpi$DHC");
- provider.addAttributes("KeyAgreement.ECCDH", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDH", PREFIX + "KeyAgreementSpi$DHC");
+ provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECDHC", PREFIX + "KeyAgreementSpi$DHC", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDH", PREFIX + "KeyAgreementSpi$DHC", generalEcAttributes);
+
+ provider.addAlgorithm("KeyAgreement.ECCDHU", PREFIX + "KeyAgreementSpi$DHUC", generalEcAttributes);
- provider.addAttributes("KeyAgreement.ECCDHU", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHU", PREFIX + "KeyAgreementSpi$DHUC");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA1CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA256CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA384CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA512CKDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA1CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA256CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA384CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA512CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512CKDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384CKDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512KDF");
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA1KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA224KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA256KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA384KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA512KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA1KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA224KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA256KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA384KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA512KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF");
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA1, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA224, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA256, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA384, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA512, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA1, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA224, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA256, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA384, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA512, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF");
-
- provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_RIPEMD160, PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
- provider.addAlgorithm("KeyAgreement.ECKAEGWITHRIPEMD160KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_RIPEMD160, PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHRIPEMD160KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF", generalEcAttributes);
registerOid(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC", new KeyFactorySpi.EC());
@@ -158,25 +157,25 @@
if (!Properties.isOverrideSet("org.bouncycastle.ec.disable_mqv"))
{
- provider.addAlgorithm("KeyAgreement.ECMQV", PREFIX + "KeyAgreementSpi$MQV");
+ provider.addAlgorithm("KeyAgreement.ECMQV", PREFIX + "KeyAgreementSpi$MQV", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384CKDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512CKDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384CKDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512CKDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384KDF");
- provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512KDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384KDF", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512KDF", generalEcAttributes);
- provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA1KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA224KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA256KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA384KDFAndSharedInfo");
- provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA512KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA1KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA224KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA256KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA384KDFAndSharedInfo", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA512KDFAndSharedInfo", generalEcAttributes);
registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
@@ -210,17 +209,42 @@
provider.addAlgorithm("KeyPairGenerator.ECDHC", PREFIX + "KeyPairGeneratorSpi$ECDHC");
provider.addAlgorithm("KeyPairGenerator.ECIES", PREFIX + "KeyPairGeneratorSpi$ECDH");
- provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES");
+ provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA1", PREFIX + "IESCipher$ECIES", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA1", PREFIX + "IESCipher$ECIES", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA256", PREFIX + "IESCipher$ECIESwithSHA256", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA256", PREFIX + "IESCipher$ECIESwithSHA256", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA384", PREFIX + "IESCipher$ECIESwithSHA384", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA384", PREFIX + "IESCipher$ECIESwithSHA384", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA512", PREFIX + "IESCipher$ECIESwithSHA512", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA512", PREFIX + "IESCipher$ECIESwithSHA512", generalEcAttributes);
- provider.addAlgorithm("Cipher.ECIESwithAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC");
- provider.addAlgorithm("Cipher.ECIESWITHAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC");
- provider.addAlgorithm("Cipher.ECIESwithDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
- provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
+ provider.addAlgorithm("Cipher.ECIESwithAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA1andAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA1ANDAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA256andAES-CBC", PREFIX + "IESCipher$ECIESwithSHA256andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA256ANDAES-CBC", PREFIX + "IESCipher$ECIESwithSHA256andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA384andAES-CBC", PREFIX + "IESCipher$ECIESwithSHA384andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA384ANDAES-CBC", PREFIX + "IESCipher$ECIESwithSHA384andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA512andAES-CBC", PREFIX + "IESCipher$ECIESwithSHA512andAESCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA512ANDAES-CBC", PREFIX + "IESCipher$ECIESwithSHA512andAESCBC", generalEcAttributes);
- provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA");
+ provider.addAlgorithm("Cipher.ECIESwithDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA1andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA1ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA256andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA256andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA256ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA256andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA384andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA384andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA384ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA384andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESwithSHA512andDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA512andDESedeCBC", generalEcAttributes);
+ provider.addAlgorithm("Cipher.ECIESWITHSHA512ANDDESEDE-CBC", PREFIX + "IESCipher$ECIESwithSHA512andDESedeCBC", generalEcAttributes);
- provider.addAlgorithm("Signature.SHA1withECDSA", PREFIX + "SignatureSpi$ecDSA");
- provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone");
+ provider.addAlgorithm("Cipher.ETSIKEMWITHSHA256", PREFIX + "IESKEMCipher$KEMwithSHA256", generalEcAttributes);
+
+ provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA", generalEcAttributes);
+ provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone", generalEcAttributes);
provider.addAlgorithm("Alg.Alias.Signature.ECDSA", "SHA1withECDSA");
provider.addAlgorithm("Alg.Alias.Signature.ECDSAwithSHA1", "SHA1withECDSA");
@@ -231,16 +255,16 @@
provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
provider.addAlgorithm("Alg.Alias.Signature." + TeleTrusTObjectIdentifiers.ecSignWithSha1, "ECDSA");
- provider.addAlgorithm("Signature.ECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
- provider.addAlgorithm("Signature.SHA1WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
- provider.addAlgorithm("Signature.SHA224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA224");
- provider.addAlgorithm("Signature.SHA256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA256");
- provider.addAlgorithm("Signature.SHA384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA384");
- provider.addAlgorithm("Signature.SHA512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512");
- provider.addAlgorithm("Signature.SHA3-224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_224");
- provider.addAlgorithm("Signature.SHA3-256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_256");
- provider.addAlgorithm("Signature.SHA3-384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_384");
- provider.addAlgorithm("Signature.SHA3-512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_512");
+ provider.addAlgorithm("Signature.ECDDSA", PREFIX + "SignatureSpi$ecDetDSA", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA1WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA224", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA256", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA384", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_224", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_256", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_384", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA3-512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_512", generalEcAttributes);
provider.addAlgorithm("Alg.Alias.Signature.DETECDSA", "ECDDSA");
provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHDETECDSA", "SHA1WITHECDDSA");
@@ -249,22 +273,29 @@
provider.addAlgorithm("Alg.Alias.Signature.SHA384WITHDETECDSA", "SHA384WITHECDDSA");
provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHDETECDSA", "SHA512WITHECDDSA");
- addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224);
- addSignatureAlgorithm(provider, "SHA256", "ECDSA", PREFIX + "SignatureSpi$ecDSA256", X9ObjectIdentifiers.ecdsa_with_SHA256);
- addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384);
- addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512);
- addSignatureAlgorithm(provider, "SHA3-224", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_224", NISTObjectIdentifiers.id_ecdsa_with_sha3_224);
- addSignatureAlgorithm(provider, "SHA3-256", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_256", NISTObjectIdentifiers.id_ecdsa_with_sha3_256);
- addSignatureAlgorithm(provider, "SHA3-384", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_384", NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
- addSignatureAlgorithm(provider, "SHA3-512", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_512", NISTObjectIdentifiers.id_ecdsa_with_sha3_512);
+ addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA256", "ECDSA", PREFIX + "SignatureSpi$ecDSA256", X9ObjectIdentifiers.ecdsa_with_SHA256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-224", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_224", NISTObjectIdentifiers.id_ecdsa_with_sha3_224, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-256", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_256", NISTObjectIdentifiers.id_ecdsa_with_sha3_256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-384", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_384", NISTObjectIdentifiers.id_ecdsa_with_sha3_384, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA3-512", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_512", NISTObjectIdentifiers.id_ecdsa_with_sha3_512, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHAKE128", "ECDSA", PREFIX + "SignatureSpi$ecDSAShake128", CMSObjectIdentifiers.id_ecdsa_with_shake128, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHAKE256", "ECDSA", PREFIX + "SignatureSpi$ecDSAShake256", CMSObjectIdentifiers.id_ecdsa_with_shake256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "RIPEMD160", "ECDSA", PREFIX + "SignatureSpi$ecDSARipeMD160",TeleTrusTObjectIdentifiers.ecSignWithRipemd160, generalEcAttributes);
- addSignatureAlgorithm(provider, "RIPEMD160", "ECDSA", PREFIX + "SignatureSpi$ecDSARipeMD160",TeleTrusTObjectIdentifiers.ecSignWithRipemd160);
+ provider.addAlgorithm("Signature.SHA1WITHECNR", PREFIX + "SignatureSpi$ecNR", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA224WITHECNR", PREFIX + "SignatureSpi$ecNR224", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA256WITHECNR", PREFIX + "SignatureSpi$ecNR256", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA384WITHECNR", PREFIX + "SignatureSpi$ecNR384", generalEcAttributes);
+ provider.addAlgorithm("Signature.SHA512WITHECNR", PREFIX + "SignatureSpi$ecNR512", generalEcAttributes);
- provider.addAlgorithm("Signature.SHA1WITHECNR", PREFIX + "SignatureSpi$ecNR");
- provider.addAlgorithm("Signature.SHA224WITHECNR", PREFIX + "SignatureSpi$ecNR224");
- provider.addAlgorithm("Signature.SHA256WITHECNR", PREFIX + "SignatureSpi$ecNR256");
- provider.addAlgorithm("Signature.SHA384WITHECNR", PREFIX + "SignatureSpi$ecNR384");
- provider.addAlgorithm("Signature.SHA512WITHECNR", PREFIX + "SignatureSpi$ecNR512");
+ addSignatureAlgorithm(provider, "SHA1", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA224", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA224", EACObjectIdentifiers.id_TA_ECDSA_SHA_224, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA256", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA256", EACObjectIdentifiers.id_TA_ECDSA_SHA_256, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA384", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA384", EACObjectIdentifiers.id_TA_ECDSA_SHA_384, generalEcAttributes);
+ addSignatureAlgorithm(provider, "SHA512", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA512", EACObjectIdentifiers.id_TA_ECDSA_SHA_512, generalEcAttributes);
addSignatureAlgorithm(provider, "SHA1", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1);
addSignatureAlgorithm(provider, "SHA224", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA224", EACObjectIdentifiers.id_TA_ECDSA_SHA_224);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/EXTERNAL.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/EXTERNAL.java
new file mode 100644
index 0000000..277ada3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/EXTERNAL.java
@@ -0,0 +1,128 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.bc.BCObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.bc.ExternalValue;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.jcajce.ExternalPublicKey;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EXTERNAL
+{
+ private static final String PREFIX = "com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.EXTERNAL";
+
+ private static final Map<String, String> externalAttributes = new HashMap<String, String>();
+
+ static
+ {
+ externalAttributes.put("SupportedKeyClasses", "com.android.internal.org.bouncycastle.jcajce.ExternalPublicKey");
+ externalAttributes.put("SupportedKeyFormats", "X.509");
+ }
+
+ private static AsymmetricKeyInfoConverter baseConverter;
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyFactory
+ extends BaseKeyFactorySpi
+ {
+ protected Key engineTranslateKey(Key key)
+ throws InvalidKeyException
+ {
+ try
+ {
+ if (key instanceof PrivateKey)
+ {
+ return generatePrivate(PrivateKeyInfo.getInstance(key.getEncoded()));
+ }
+ else if (key instanceof PublicKey)
+ {
+ return generatePublic(SubjectPublicKeyInfo.getInstance(key.getEncoded()));
+ }
+ }
+ catch (IOException e)
+ {
+ throw new InvalidKeyException("key could not be parsed: " + e.getMessage());
+ }
+
+ throw new InvalidKeyException("key not recognized");
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePrivate(keyInfo);
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ return baseConverter.generatePublic(keyInfo);
+ }
+ }
+
+ private static class ExternalKeyInfoConverter
+ implements AsymmetricKeyInfoConverter
+ {
+ private final ConfigurableProvider provider;
+
+ public ExternalKeyInfoConverter(ConfigurableProvider provider)
+ {
+ this.provider = provider;
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ throw new UnsupportedOperationException("no support for private key");
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ ExternalValue extKey = ExternalValue.getInstance(keyInfo.parsePublicKey());
+
+ // TODO: maybe implement some sort of cache lookup?
+
+ return new ExternalPublicKey(extKey);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyFactory.EXTERNAL", PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory." + BCObjectIdentifiers.external_value, PREFIX + "$KeyFactory");
+ provider.addAlgorithm("KeyFactory.OID." + BCObjectIdentifiers.external_value, PREFIX + "$KeyFactory");
+
+ baseConverter = new ExternalKeyInfoConverter(provider);
+
+ provider.addKeyInfoConverter(BCObjectIdentifiers.external_value, baseConverter);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/LMS.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/LMS.java
new file mode 100644
index 0000000..0f3eece
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/LMS.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class LMS
+{
+ private static final String PREFIX = "com.android.internal.org.bouncycastle.pqc.jcajce.provider" + ".lms.";
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyFactory.LMS", PREFIX + "LMSKeyFactorySpi");
+ provider.addAlgorithm("Alg.Alias.KeyFactory." + PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, "LMS");
+
+ provider.addAlgorithm("KeyPairGenerator.LMS", PREFIX + "LMSKeyPairGeneratorSpi");
+ provider.addAlgorithm("Alg.Alias.KeyPairGenerator." + PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, "LMS");
+
+ provider.addAlgorithm("Signature.LMS", PREFIX + "LMSSignatureSpi$generic");
+ provider.addAlgorithm("Alg.Alias.Signature." + PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, "LMS");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/RSA.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
index 40c585e..4ea65a1 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
@@ -11,6 +11,7 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+// import org.bouncycastle.internal.asn1.cms.CMSObjectIdentifiers;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi;
import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
@@ -27,7 +28,7 @@
static
{
- generalRsaAttributes.put("SupportedKeyClasses", "javax.crypto.interfaces.RSAPublicKey|javax.crypto.interfaces.RSAPrivateKey");
+ generalRsaAttributes.put("SupportedKeyClasses", "java.security.interfaces.RSAPublicKey|java.security.interfaces.RSAPrivateKey");
generalRsaAttributes.put("SupportedKeyFormats", "PKCS#8|X.509");
}
@@ -80,8 +81,8 @@
// BEGIN Android-removed: Unsupported algorithms
/*
provider.addAlgorithm("Cipher.RSA/PKCS1", PREFIX + "CipherSpi$PKCS1v1_5Padding");
- provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.rsaEncryption, PREFIX + "CipherSpi$PKCS1v1_5Padding");
- provider.addAlgorithm("Cipher", X509ObjectIdentifiers.id_ea_rsa, PREFIX + "CipherSpi$PKCS1v1_5Padding");
+ provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.rsaEncryption, PREFIX + "CipherSpi$PKCS1v1_5Padding", generalRsaAttributes);
+ provider.addAlgorithm("Cipher", X509ObjectIdentifiers.id_ea_rsa, PREFIX + "CipherSpi$PKCS1v1_5Padding", generalRsaAttributes);
provider.addAlgorithm("Cipher.RSA/1", PREFIX + "CipherSpi$PKCS1v1_5Padding_PrivateOnly");
provider.addAlgorithm("Cipher.RSA/2", PREFIX + "CipherSpi$PKCS1v1_5Padding_PublicOnly");
provider.addAlgorithm("Cipher.RSA/OAEP", PREFIX + "CipherSpi$OAEPPadding");
@@ -122,12 +123,12 @@
registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSAES_OAEP, "OAEP");
registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSASSA_PSS, "PSS");
- provider.addAlgorithm("Signature.RSASSA-PSS", PREFIX + "PSSSignatureSpi$PSSwithRSA");
- provider.addAlgorithm("Signature." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA");
- provider.addAlgorithm("Signature.OID." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA");
+ provider.addAlgorithm("Signature.RSASSA-PSS", PREFIX + "PSSSignatureSpi$PSSwithRSA", generalRsaAttributes);
+ provider.addAlgorithm("Alg.Alias.Signature." + PKCSObjectIdentifiers.id_RSASSA_PSS, "RSASSA-PSS");
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + PKCSObjectIdentifiers.id_RSASSA_PSS, "RSASSA-PSS");
- provider.addAlgorithm("Signature.RSA", PREFIX + "DigestSignatureSpi$noneRSA");
- provider.addAlgorithm("Signature.RAWRSASSA-PSS", PREFIX + "PSSSignatureSpi$nonePSS");
+ provider.addAlgorithm("Signature.RSA", PREFIX + "DigestSignatureSpi$noneRSA", generalRsaAttributes);
+ provider.addAlgorithm("Signature.RAWRSASSA-PSS", PREFIX + "PSSSignatureSpi$nonePSS", generalRsaAttributes);
provider.addAlgorithm("Alg.Alias.Signature.RAWRSA", "RSA");
provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSA", "RSA");
@@ -137,17 +138,43 @@
provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSAANDMGF1", "RAWRSASSA-PSS");
provider.addAlgorithm("Alg.Alias.Signature.RSAPSS", "RSASSA-PSS");
- addPSSSignature(provider, "SHA224", PREFIX + "PSSSignatureSpi$SHA224withRSA");
- addPSSSignature(provider, "SHA256", PREFIX + "PSSSignatureSpi$SHA256withRSA");
- addPSSSignature(provider, "SHA384", PREFIX + "PSSSignatureSpi$SHA384withRSA");
- addPSSSignature(provider, "SHA512", PREFIX + "PSSSignatureSpi$SHA512withRSA");
- addPSSSignature(provider, "SHA512(224)", PREFIX + "PSSSignatureSpi$SHA512_224withRSA");
- addPSSSignature(provider, "SHA512(256)", PREFIX + "PSSSignatureSpi$SHA512_256withRSA");
+ addPSSSignature(provider, "SHA224", "MGF1", PREFIX + "PSSSignatureSpi$SHA224withRSA");
+ addPSSSignature(provider, "SHA256", "MGF1", PREFIX + "PSSSignatureSpi$SHA256withRSA");
+ addPSSSignature(provider, "SHA384", "MGF1", PREFIX + "PSSSignatureSpi$SHA384withRSA");
+ addPSSSignature(provider, "SHA512", "MGF1", PREFIX + "PSSSignatureSpi$SHA512withRSA");
+ addPSSSignature(provider, "SHA512(224)", "MGF1", PREFIX + "PSSSignatureSpi$SHA512_224withRSA");
+ addPSSSignature(provider, "SHA512(256)", "MGF1", PREFIX + "PSSSignatureSpi$SHA512_256withRSA");
- addPSSSignature(provider, "SHA3-224", PREFIX + "PSSSignatureSpi$SHA3_224withRSA");
- addPSSSignature(provider, "SHA3-256", PREFIX + "PSSSignatureSpi$SHA3_256withRSA");
- addPSSSignature(provider, "SHA3-384", PREFIX + "PSSSignatureSpi$SHA3_384withRSA");
- addPSSSignature(provider, "SHA3-512", PREFIX + "PSSSignatureSpi$SHA3_512withRSA");
+ addPSSSignature(provider, "SHA3-224", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_224withRSA");
+ addPSSSignature(provider, "SHA3-256", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_256withRSA");
+ addPSSSignature(provider, "SHA3-384", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_384withRSA");
+ addPSSSignature(provider, "SHA3-512", "MGF1", PREFIX + "PSSSignatureSpi$SHA3_512withRSA");
+ addPSSSignature(provider, "SHAKE128", PREFIX + "PSSSignatureSpi$SHAKE128WithRSAPSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128);
+ addPSSSignature(provider, "SHAKE256", PREFIX + "PSSSignatureSpi$SHAKE256WithRSAPSS", CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256);
+
+ addPSSSignature(provider, "SHA224", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA224withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA256", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA256withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA384", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA384withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA512", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA512withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA512(224)", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA512_224withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA512(256)", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA512_256withRSAandSHAKE128");
+
+ addPSSSignature(provider, "SHA224", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA224withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA256", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA256withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA384", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA384withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA512", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA512withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA512(224)", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA512_224withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA512(256)", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA512_256withRSAandSHAKE256");
+
+ addPSSSignature(provider, "SHA3-224", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_224withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA3-256", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_256withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA3-384", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_384withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA3-512", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA3_512withRSAandSHAKE128");
+
+ addPSSSignature(provider, "SHA3-224", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_224withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA3-256", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_256withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA3-384", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_384withRSAandSHAKE256");
+ addPSSSignature(provider, "SHA3-512", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA3_512withRSAandSHAKE256");
if (provider.hasAlgorithm("MessageDigest", "MD2"))
{
@@ -170,7 +197,9 @@
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1withRSA/PSS", "PSS");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1WITHRSAANDMGF1", "PSS");
- addPSSSignature(provider, "SHA1", PREFIX + "PSSSignatureSpi$SHA1withRSA");
+ addPSSSignature(provider, "SHA1", "MGF1", PREFIX + "PSSSignatureSpi$SHA1withRSA");
+ addPSSSignature(provider, "SHA1", "SHAKE128", PREFIX + "PSSSignatureSpi$SHA1withRSAandSHAKE128");
+ addPSSSignature(provider, "SHA1", "SHAKE256", PREFIX + "PSSSignatureSpi$SHA1withRSAandSHAKE256");
addDigestSignature(provider, "SHA1", PREFIX + "DigestSignatureSpi$SHA1", PKCSObjectIdentifiers.sha1WithRSAEncryption);
addISO9796Signature(provider, "SHA1", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption");
@@ -270,6 +299,7 @@
provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
}
+ provider.addAttributes("Signature." + mainName, generalRsaAttributes);
}
private void addISO9796Signature(
@@ -280,12 +310,37 @@
provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/ISO9796-2", digest + "WITHRSA/ISO9796-2");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/ISO9796-2", digest + "WITHRSA/ISO9796-2");
provider.addAlgorithm("Signature." + digest + "WITHRSA/ISO9796-2", className);
+ provider.addAttributes("Signature." + digest + "WITHRSA/ISO9796-2", generalRsaAttributes);
+ }
+
+ private void addPSSSignature(
+ ConfigurableProvider provider,
+ String digest, String mgf,
+ String className)
+ {
+ String stem = "WITHRSAAND" + mgf;
+ if (mgf.equals("MGF1"))
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WITHRSA/PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSASSA-PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSASSA-PSS", digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WITHRSASSA-PSS", digest + stem);
+ }
+
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSAand" + mgf, digest + stem);
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSAAnd" + mgf, digest + stem);
+
+ provider.addAlgorithm("Signature." + digest + "WITHRSAAND" + mgf, className);
+ provider.addAttributes("Signature." + digest + "WITHRSAAND" + mgf, generalRsaAttributes);
}
private void addPSSSignature(
ConfigurableProvider provider,
String digest,
- String className)
+ String className,
+ ASN1ObjectIdentifier sigOid)
{
provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/PSS", digest + "WITHRSAANDMGF1");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/PSS", digest + "WITHRSAANDMGF1");
@@ -306,6 +361,7 @@
provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/X9.31", digest + "WITHRSA/X9.31");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/X9.31", digest + "WITHRSA/X9.31");
provider.addAlgorithm("Signature." + digest + "WITHRSA/X9.31", className);
+ provider.addAttributes("Signature." + digest + "WITHRSA/X9.31", generalRsaAttributes);
}
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
index 97a1e6c..f88a335 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
@@ -41,6 +41,7 @@
// import org.bouncycastle.jcajce.spec.DHUParameterSpec;
// import org.bouncycastle.jcajce.spec.MQVParameterSpec;
import com.android.internal.org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
/**
* Diffie-Hellman key agreement. There's actually a better way of doing this
@@ -117,30 +118,9 @@
//
int expectedLength = (p.bitLength() + 7) / 8;
- byte[] tmp = r.toByteArray();
-
- if (tmp.length == expectedLength)
- {
- return tmp;
- }
-
- if (tmp[0] == 0 && tmp.length == expectedLength + 1)
- {
- byte[] rv = new byte[tmp.length - 1];
-
- System.arraycopy(tmp, 1, rv, 0, rv.length);
- return rv;
- }
-
- // tmp must be shorter than expectedLength
- // pad to the left with zeros.
- byte[] rv = new byte[expectedLength];
-
- System.arraycopy(tmp, 0, rv, rv.length - tmp.length, tmp.length);
-
- return rv;
+ return BigIntegers.asUnsignedByteArray(expectedLength, r);
}
-
+
protected Key engineDoPhase(
Key key,
boolean lastPhase)
@@ -268,7 +248,7 @@
return super.engineGenerateSecret(algorithm);
}
- protected void engineInit(
+ protected void doInitFromKey(
Key key,
AlgorithmParameterSpec params,
SecureRandom random)
@@ -387,7 +367,7 @@
this.result = bigIntToBytes(x);
}
- protected byte[] calcSecret()
+ protected byte[] doCalcSecret()
{
return result;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java
index e8a2fb1..f8ddbf4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java
@@ -71,7 +71,7 @@
}
else
{
- pGen = new DSAParametersGenerator(new SHA256Digest());
+ pGen = new DSAParametersGenerator(SHA256Digest.newInstance());
}
if (random == null)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
index cc30d17..9601735 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
@@ -1,6 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa;
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
@@ -10,7 +10,6 @@
import java.security.SignatureException;
import java.security.SignatureSpi;
import java.security.spec.AlgorithmParameterSpec;
-
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
@@ -29,7 +28,6 @@
// import org.bouncycastle.crypto.util.DigestFactory;
import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
import com.android.internal.org.bouncycastle.util.Arrays;
-
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -41,7 +39,6 @@
private DSAExt signer;
private DSAEncoding encoding = StandardDSAEncoding.INSTANCE;
private SecureRandom random;
-
protected DSASigner(
Digest digest,
DSAExt signer)
@@ -49,17 +46,14 @@
this.digest = digest;
this.signer = signer;
}
-
protected void engineInitVerify(
PublicKey publicKey)
throws InvalidKeyException
{
CipherParameters param = DSAUtil.generatePublicKeyParameter(publicKey);
-
digest.reset();
signer.init(false, param);
}
-
protected void engineInitSign(
PrivateKey privateKey,
SecureRandom random)
@@ -68,53 +62,43 @@
this.random = random;
engineInitSign(privateKey);
}
-
protected void engineInitSign(
PrivateKey privateKey)
throws InvalidKeyException
{
CipherParameters param = DSAUtil.generatePrivateKeyParameter(privateKey);
-
// Android-added: Check DSA keys when generated
DSAParameters dsaParam = ((DSAKeyParameters) param).getParameters();
checkKey(dsaParam);
-
if (random != null)
{
param = new ParametersWithRandom(param, random);
}
-
digest.reset();
signer.init(true, param);
}
-
protected void engineUpdate(
byte b)
throws SignatureException
{
digest.update(b);
}
-
protected void engineUpdate(
byte[] b,
int off,
- int len)
+ int len)
throws SignatureException
{
digest.update(b, off, len);
}
-
protected byte[] engineSign()
throws SignatureException
{
byte[] hash = new byte[digest.getDigestSize()];
-
digest.doFinal(hash, 0);
-
try
{
BigInteger[] sig = signer.generateSignature(hash);
-
return encoding.encode(signer.getOrder(), sig[0], sig[1]);
}
catch (Exception e)
@@ -122,17 +106,13 @@
throw new SignatureException(e.toString());
}
}
-
protected boolean engineVerify(
- byte[] sigBytes)
+ byte[] sigBytes)
throws SignatureException
{
byte[] hash = new byte[digest.getDigestSize()];
-
digest.doFinal(hash, 0);
-
BigInteger[] sig;
-
try
{
sig = encoding.decode(signer.getOrder(), sigBytes);
@@ -141,27 +121,22 @@
{
throw new SignatureException("error decoding signature bytes.");
}
-
return signer.verifySignature(hash, sig[0], sig[1]);
}
-
protected AlgorithmParameters engineGetParameters()
{
return null;
}
-
protected void engineSetParameter(
AlgorithmParameterSpec params)
{
throw new UnsupportedOperationException("engineSetParameter unsupported");
}
-
// BEGIN Android-added: Check DSA keys when generated
protected void checkKey(DSAParameters params) throws InvalidKeyException {
int valueL = params.getP().bitLength();
int valueN = params.getQ().bitLength();
int digestSize = digest.getDigestSize();
-
// The checks are consistent with DSAParametersGenerator's init method.
if ((valueL < 1024 || valueL > 3072) || valueL % 1024 != 0) {
throw new InvalidKeyException("valueL values must be between 1024 and 3072 and a multiple of 1024");
@@ -176,7 +151,6 @@
throw new InvalidKeyException("Key is too strong for this signature algorithm");
}
}
-
// END Android-added: Check DSA keys when generated
/**
* @deprecated replaced with #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
@@ -187,7 +161,6 @@
{
throw new UnsupportedOperationException("engineSetParameter unsupported");
}
-
/**
* @deprecated
*/
@@ -196,7 +169,6 @@
{
throw new UnsupportedOperationException("engineGetParameter unsupported");
}
-
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -210,7 +182,6 @@
super(AndroidDigestFactory.getSHA1(), new com.android.internal.org.bouncycastle.crypto.signers.DSASigner());
}
}
-
// BEGIN Android-removed: Unsupported algorithm
/*
static public class detDSA
@@ -221,6 +192,14 @@
super(DigestFactory.createSHA1(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA1())));
}
}
+ static public class dsaRMD160
+ extends DSASigner
+ {
+ public dsaRMD160()
+ {
+ super(new RIPEMD160Digest(), new org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
*/
// END Android-removed: Unsupported algorithm
@@ -237,7 +216,6 @@
super(AndroidDigestFactory.getSHA224(), new com.android.internal.org.bouncycastle.crypto.signers.DSASigner());
}
}
-
// BEGIN Android-removed: Unsupported algorithm
/*
static public class detDSA224
@@ -250,7 +228,6 @@
}
*/
// END Android-removed: Unsupported algorithm
-
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -264,7 +241,6 @@
super(AndroidDigestFactory.getSHA256(), new com.android.internal.org.bouncycastle.crypto.signers.DSASigner());
}
}
-
// BEGIN Android-removed: Unsupported algorithms
/*
static public class detDSA256
@@ -275,7 +251,6 @@
super(DigestFactory.createSHA256(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA256())));
}
}
-
static public class dsa384
extends DSASigner
{
@@ -284,7 +259,6 @@
super(DigestFactory.createSHA384(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSA384
extends DSASigner
{
@@ -293,7 +267,6 @@
super(DigestFactory.createSHA384(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA384())));
}
}
-
static public class dsa512
extends DSASigner
{
@@ -302,7 +275,6 @@
super(DigestFactory.createSHA512(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSA512
extends DSASigner
{
@@ -311,7 +283,6 @@
super(DigestFactory.createSHA512(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA512())));
}
}
-
static public class dsaSha3_224
extends DSASigner
{
@@ -320,7 +291,6 @@
super(DigestFactory.createSHA3_224(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_224
extends DSASigner
{
@@ -329,7 +299,6 @@
super(DigestFactory.createSHA3_224(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_224())));
}
}
-
static public class dsaSha3_256
extends DSASigner
{
@@ -338,7 +307,6 @@
super(DigestFactory.createSHA3_256(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_256
extends DSASigner
{
@@ -347,7 +315,6 @@
super(DigestFactory.createSHA3_256(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_256())));
}
}
-
static public class dsaSha3_384
extends DSASigner
{
@@ -356,7 +323,6 @@
super(DigestFactory.createSHA3_384(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_384
extends DSASigner
{
@@ -365,7 +331,6 @@
super(DigestFactory.createSHA3_384(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_384())));
}
}
-
static public class dsaSha3_512
extends DSASigner
{
@@ -374,7 +339,6 @@
super(DigestFactory.createSHA3_512(), new org.bouncycastle.crypto.signers.DSASigner());
}
}
-
static public class detDSASha3_512
extends DSASigner
{
@@ -385,7 +349,6 @@
}
*/
// END Android-removed: Unsupported algorithms
-
/**
* @hide This class is not part of the Android public SDK API
*/
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
index 5541f66..996c7be 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
@@ -152,7 +152,7 @@
else if (strength > 1024)
{
dsaParams = new DSAParameterGenerationParameters(strength, 256, certainty, random);
- pGen = new DSAParametersGenerator(new SHA256Digest());
+ pGen = new DSAParametersGenerator(SHA256Digest.newInstance());
pGen.init(dsaParams);
}
else
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
index e9fe33f..3b6ecea 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
@@ -16,6 +16,7 @@
import com.android.internal.org.bouncycastle.asn1.x9.X9ECPoint;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveSpec;
import com.android.internal.org.bouncycastle.math.ec.ECCurve;
@@ -41,12 +42,14 @@
if (algorithmParameterSpec instanceof ECGenParameterSpec)
{
ECGenParameterSpec ecGenParameterSpec = (ECGenParameterSpec)algorithmParameterSpec;
- X9ECParameters params = ECUtils.getDomainParametersFromGenSpec(ecGenParameterSpec);
+ ProviderConfiguration configuration = BouncyCastleProvider.CONFIGURATION;
- if (params == null)
+ X9ECParameters params = ECUtils.getDomainParametersFromGenSpec(ecGenParameterSpec, configuration);
+ if (null == params)
{
throw new InvalidParameterSpecException("EC curve name not recognized: " + ecGenParameterSpec.getName());
}
+
curveName = ecGenParameterSpec.getName();
ECParameterSpec baseSpec = EC5Util.convertToSpec(params);
ecParameterSpec = new ECNamedCurveSpec(curveName,
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
index 051e0b6..f08909a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
@@ -11,18 +11,20 @@
import java.security.spec.EllipticCurve;
import java.util.Enumeration;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable;
import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECNamedDomainParameters;
import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
@@ -31,7 +33,9 @@
import com.android.internal.org.bouncycastle.jce.interfaces.ECPointEncoder;
import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.util.Arrays;
/**
* @hide This class is not part of the Android public SDK API
@@ -41,16 +45,20 @@
{
static final long serialVersionUID = 994553197664784084L;
- private String algorithm = "EC";
- private boolean withCompression;
+ private String algorithm = "EC";
+ private boolean withCompression;
- private transient BigInteger d;
- private transient ECParameterSpec ecSpec;
- private transient ProviderConfiguration configuration;
- private transient DERBitString publicKey;
+ private transient BigInteger d;
+ private transient ECParameterSpec ecSpec;
+ private transient ProviderConfiguration configuration;
+ private transient ASN1BitString publicKey;
+ private transient PrivateKeyInfo privateKeyInfo;
+ private transient byte[] encoding;
+ private transient ECPrivateKeyParameters baseKey;
private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
protected BCECPrivateKey()
{
}
@@ -63,6 +71,7 @@
this.algorithm = key.getAlgorithm();
this.ecSpec = key.getParams();
this.configuration = configuration;
+ this.baseKey = convertToBaseKey(this);
}
public BCECPrivateKey(
@@ -88,6 +97,7 @@
}
this.configuration = configuration;
+ this.baseKey = convertToBaseKey(this);
}
@@ -100,6 +110,7 @@
this.d = spec.getS();
this.ecSpec = spec.getParams();
this.configuration = configuration;
+ this.baseKey = convertToBaseKey(this);
}
public BCECPrivateKey(
@@ -113,6 +124,7 @@
this.attrCarrier = key.attrCarrier;
this.publicKey = key.publicKey;
this.configuration = key.configuration;
+ this.baseKey = key.baseKey;
}
public BCECPrivateKey(
@@ -125,6 +137,7 @@
this.algorithm = algorithm;
this.d = params.getD();
this.configuration = configuration;
+ this.baseKey = params;
if (spec == null)
{
@@ -155,6 +168,7 @@
this.algorithm = algorithm;
this.d = params.getD();
this.configuration = configuration;
+ this.baseKey = params;
if (spec == null)
{
@@ -193,10 +207,11 @@
this.d = params.getD();
this.ecSpec = null;
this.configuration = configuration;
+ this.baseKey = params;
}
BCECPrivateKey(
- String algorithm,
+ String algorithm,
PrivateKeyInfo info,
ProviderConfiguration configuration)
throws IOException
@@ -217,7 +232,7 @@
ASN1Encodable privKey = info.parsePrivateKey();
if (privKey instanceof ASN1Integer)
{
- ASN1Integer derD = ASN1Integer.getInstance(privKey);
+ ASN1Integer derD = ASN1Integer.getInstance(privKey);
this.d = derD.getValue();
}
@@ -228,6 +243,7 @@
this.d = ec.getKey();
this.publicKey = ec.getPublicKey();
}
+ this.baseKey = convertToBaseKey(this);
}
public String getAlgorithm()
@@ -253,40 +269,71 @@
*/
public byte[] getEncoded()
{
- X962Parameters params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
+ if (encoding == null)
+ {
+ PrivateKeyInfo info = getPrivateKeyInfo();
- int orderBitLength;
- if (ecSpec == null)
- {
- orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS());
- }
- else
- {
- orderBitLength = ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS());
- }
-
- PrivateKeyInfo info;
- com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
+ if (info == null)
+ {
+ return null;
+ }
- if (publicKey != null)
- {
- keyStructure = new com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params);
- }
- else
- {
- keyStructure = new com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
+ try
+ {
+ encoding = info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
}
- try
- {
- info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure);
+ return Arrays.clone(encoding);
+ }
- return info.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
+ private PrivateKeyInfo getPrivateKeyInfo()
+ {
+ if (privateKeyInfo == null)
{
- return null;
+ X962Parameters params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
+
+ int orderBitLength;
+ if (ecSpec == null)
+ {
+ orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS());
+ }
+ else
+ {
+ orderBitLength = ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS());
+ }
+
+ com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
+
+ if (publicKey != null)
+ {
+ keyStructure = new com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params);
+ }
+ else
+ {
+ keyStructure = new com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
+ }
+
+ try
+ {
+ privateKeyInfo = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
}
+
+ return privateKeyInfo;
+ }
+
+ public ECPrivateKeyParameters engineGetKeyParameters()
+ {
+ return baseKey;
}
public ECParameterSpec getParams()
@@ -300,7 +347,6 @@
{
return null;
}
-
return EC5Util.convertSpec(ecSpec);
}
@@ -323,10 +369,10 @@
{
return d;
}
-
+
public void setBagAttribute(
ASN1ObjectIdentifier oid,
- ASN1Encodable attribute)
+ ASN1Encodable attribute)
{
attrCarrier.setBagAttribute(oid, attribute);
}
@@ -344,19 +390,37 @@
public void setPointFormat(String style)
{
- withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
}
public boolean equals(Object o)
{
- if (!(o instanceof BCECPrivateKey))
+ if (o instanceof ECPrivateKey)
{
- return false;
+ ECPrivateKey other = (ECPrivateKey)o;
+
+ PrivateKeyInfo info = this.getPrivateKeyInfo();
+ PrivateKeyInfo otherInfo = (other instanceof BCECPrivateKey) ? ((BCECPrivateKey)other).getPrivateKeyInfo() : PrivateKeyInfo.getInstance(other.getEncoded());
+
+ if (info == null || otherInfo == null)
+ {
+ return false;
+ }
+
+ try
+ {
+ boolean algEquals = Arrays.constantTimeAreEqual(info.getPrivateKeyAlgorithm().getEncoded(), otherInfo.getPrivateKeyAlgorithm().getEncoded());
+ boolean keyEquals = Arrays.constantTimeAreEqual(this.getS().toByteArray(), other.getS().toByteArray());
+
+ return algEquals & keyEquals;
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
}
- BCECPrivateKey other = (BCECPrivateKey)o;
-
- return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec()));
+ return false;
}
public int hashCode()
@@ -369,7 +433,7 @@
return ECUtil.privateKeyToString("EC", d, engineGetSpec());
}
- private DERBitString getPublicKeyDetails(BCECPublicKey pub)
+ private ASN1BitString getPublicKeyDetails(BCECPublicKey pub)
{
try
{
@@ -406,4 +470,31 @@
out.writeObject(this.getEncoded());
}
+
+ private static ECPrivateKeyParameters convertToBaseKey(BCECPrivateKey key)
+ {
+ com.android.internal.org.bouncycastle.jce.interfaces.ECPrivateKey k = (com.android.internal.org.bouncycastle.jce.interfaces.ECPrivateKey)key;
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec s = k.getParameters();
+
+ if (s == null)
+ {
+ s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+ }
+
+ if (k.getParameters() instanceof ECNamedCurveParameterSpec)
+ {
+ String name = ((ECNamedCurveParameterSpec)k.getParameters()).getName();
+ if (name != null)
+ {
+ return new ECPrivateKeyParameters(
+ k.getD(),
+ new ECNamedDomainParameters(ECNamedCurveTable.getOID(name),
+ s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
+ }
+ }
+
+ return new ECPrivateKeyParameters(
+ k.getD(),
+ new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
index 13e42f8..3d5d552 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
@@ -10,9 +10,9 @@
import java.security.spec.ECPublicKeySpec;
import java.security.spec.EllipticCurve;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
@@ -29,6 +29,7 @@
import com.android.internal.org.bouncycastle.jce.interfaces.ECPointEncoder;
import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.util.Arrays;
import com.android.internal.org.bouncycastle.util.Properties;
/**
@@ -45,6 +46,8 @@
private transient ECPublicKeyParameters ecPublicKey;
private transient ECParameterSpec ecSpec;
private transient ProviderConfiguration configuration;
+ private transient byte[] encoding;
+ private transient boolean oldPcSet;
public BCECPublicKey(
String algorithm,
@@ -197,7 +200,7 @@
ECCurve curve = EC5Util.getCurve(configuration, params);
ecSpec = EC5Util.convertToSpec(params, curve);
- DERBitString bits = info.getPublicKeyData();
+ ASN1BitString bits = info.getPublicKeyData();
byte[] data = bits.getBytes();
ASN1OctetString key = new DEROctetString(data);
@@ -239,16 +242,23 @@
public byte[] getEncoded()
{
- boolean compress = withCompression || Properties.isOverrideSet("com.android.internal.org.bouncycastle.ec.enable_pc");
+ boolean pcSet = Properties.isOverrideSet("com.android.internal.org.bouncycastle.ec.enable_pc");
+ if (encoding == null || oldPcSet != pcSet)
+ {
+ boolean compress = withCompression || pcSet;
- AlgorithmIdentifier algId = new AlgorithmIdentifier(
- X9ObjectIdentifiers.id_ecPublicKey,
- ECUtils.getDomainParametersFromName(ecSpec, compress));
+ AlgorithmIdentifier algId = new AlgorithmIdentifier(
+ X9ObjectIdentifiers.id_ecPublicKey,
+ ECUtils.getDomainParametersFromName(ecSpec, compress));
- byte[] pubKeyOctets = ecPublicKey.getQ().getEncoded(compress);
+ byte[] pubKeyOctets = ecPublicKey.getQ().getEncoded(compress);
- // stored curve is null if ImplicitlyCa
- return KeyUtil.getEncodedSubjectPublicKeyInfo(algId, pubKeyOctets);
+ // stored curve is null if ImplicitlyCa
+ encoding = KeyUtil.getEncodedSubjectPublicKeyInfo(algId, pubKeyOctets);
+ oldPcSet = pcSet;
+ }
+
+ return Arrays.clone(encoding);
}
public ECParameterSpec getParams()
@@ -306,18 +316,26 @@
public void setPointFormat(String style)
{
withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ encoding = null;
}
public boolean equals(Object o)
{
- if (!(o instanceof BCECPublicKey))
+ if (o instanceof BCECPublicKey)
{
- return false;
+ BCECPublicKey other = (BCECPublicKey)o;
+
+ return ecPublicKey.getQ().equals(other.ecPublicKey.getQ()) && (engineGetSpec().equals(other.engineGetSpec()));
}
- BCECPublicKey other = (BCECPublicKey)o;
+ if (o instanceof ECPublicKey)
+ {
+ ECPublicKey other = (ECPublicKey)o;
- return ecPublicKey.getQ().equals(other.ecPublicKey.getQ()) && (engineGetSpec().equals(other.engineGetSpec()));
+ return Arrays.areEqual(getEncoded(), other.getEncoded());
+ }
+
+ return false;
}
public int hashCode()
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
index d07bebf..f06afa2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
@@ -3,9 +3,11 @@
import java.math.BigInteger;
import java.security.InvalidKeyException;
+import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
+import java.util.Map;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.DERNull;
@@ -15,6 +17,7 @@
import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveSpec;
import com.android.internal.org.bouncycastle.math.ec.ECCurve;
@@ -27,39 +30,49 @@
return (key instanceof BCECPublicKey) ? ((BCECPublicKey)key).engineGetKeyParameters() : ECUtil.generatePublicKeyParameter(key);
}
- static X9ECParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec)
+ static AsymmetricKeyParameter generatePrivateKeyParameter(
+ PrivateKey key)
+ throws InvalidKeyException
{
- return getDomainParametersFromName(genSpec.getName());
+ return (key instanceof BCECPrivateKey) ? ((BCECPrivateKey)key).engineGetKeyParameters() : ECUtil.generatePrivateKeyParameter(key);
}
- static X9ECParameters getDomainParametersFromName(String curveName)
+ static X9ECParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec, ProviderConfiguration configuration)
{
- X9ECParameters domainParameters;
- try
+ return getDomainParametersFromName(genSpec.getName(), configuration);
+ }
+
+ static X9ECParameters getDomainParametersFromName(String curveName, ProviderConfiguration configuration)
+ {
+ if (null == curveName || curveName.length() < 1)
{
- if (curveName.charAt(0) >= '0' && curveName.charAt(0) <= '2')
+ return null;
+ }
+
+ int spacePos = curveName.indexOf(' ');
+ if (spacePos > 0)
+ {
+ curveName = curveName.substring(spacePos + 1);
+ }
+
+ ASN1ObjectIdentifier oid = getOID(curveName);
+ if (null == oid)
+ {
+ return ECUtil.getNamedCurveByName(curveName);
+ }
+
+ X9ECParameters x9 = ECUtil.getNamedCurveByOid(oid);
+ if (null == x9)
+ {
+ if (null != configuration)
{
- ASN1ObjectIdentifier oidID = new ASN1ObjectIdentifier(curveName);
- domainParameters = ECUtil.getNamedCurveByOid(oidID);
- }
- else
- {
- if (curveName.indexOf(' ') > 0)
- {
- curveName = curveName.substring(curveName.indexOf(' ') + 1);
- domainParameters = ECUtil.getNamedCurveByName(curveName);
- }
- else
- {
- domainParameters = ECUtil.getNamedCurveByName(curveName);
- }
+ Map extraCurves = configuration.getAdditionalECParameters();
+
+ x9 = (X9ECParameters)extraCurves.get(oid);
}
}
- catch (IllegalArgumentException ex)
- {
- domainParameters = ECUtil.getNamedCurveByName(curveName);
- }
- return domainParameters;
+
+ return x9;
}
static X962Parameters getDomainParametersFromName(ECParameterSpec ecSpec, boolean withCompression)
@@ -95,4 +108,20 @@
return params;
}
+
+ private static ASN1ObjectIdentifier getOID(String curveName)
+ {
+ char firstChar = curveName.charAt(0);
+ if (firstChar >= '0' && firstChar <= '2')
+ {
+ try
+ {
+ return new ASN1ObjectIdentifier(curveName);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ return null;
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java
new file mode 100644
index 0000000..fdde6c2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java
@@ -0,0 +1,259 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.generators.ECKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECKeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveSpec;
+import com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class GMKeyPairGeneratorSpi
+ extends java.security.KeyPairGenerator
+{
+ public GMKeyPairGeneratorSpi(String algorithmName)
+ {
+ super(algorithmName);
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class BaseSM2
+ extends GMKeyPairGeneratorSpi
+ {
+ ECKeyGenerationParameters param;
+ ECKeyPairGenerator engine = new ECKeyPairGenerator();
+ Object ecParams = null;
+ int strength = 239;
+ SecureRandom random = CryptoServicesRegistrar.getSecureRandom();
+ boolean initialised = false;
+ String algorithm;
+ ProviderConfiguration configuration;
+
+ static private Hashtable ecParameters;
+
+ static
+ {
+ ecParameters = new Hashtable();
+
+ ecParameters.put(Integers.valueOf(192), new ECNamedCurveGenParameterSpec("prime192v1")); // a.k.a P-192
+ ecParameters.put(Integers.valueOf(239), new ECNamedCurveGenParameterSpec("prime239v1"));
+ ecParameters.put(Integers.valueOf(256), new ECNamedCurveGenParameterSpec("prime256v1")); // a.k.a P-256
+
+ ecParameters.put(Integers.valueOf(224), new ECNamedCurveGenParameterSpec("P-224"));
+ ecParameters.put(Integers.valueOf(384), new ECNamedCurveGenParameterSpec("P-384"));
+ ecParameters.put(Integers.valueOf(521), new ECNamedCurveGenParameterSpec("P-521"));
+ }
+
+ public BaseSM2()
+ {
+ super("EC");
+ this.algorithm = "EC";
+ this.configuration = BouncyCastleProvider.CONFIGURATION;
+ }
+
+ public BaseSM2(
+ String algorithm,
+ ProviderConfiguration configuration)
+ {
+ super(algorithm);
+ this.algorithm = algorithm;
+ this.configuration = configuration;
+ }
+
+ public void initialize(
+ int strength,
+ SecureRandom random)
+ {
+ this.strength = strength;
+ this.random = random;
+
+ ECNamedCurveGenParameterSpec ecParams = (ECNamedCurveGenParameterSpec)ecParameters.get(Integers.valueOf(strength));
+ if (ecParams == null)
+ {
+ throw new InvalidParameterException("unknown key size.");
+ }
+
+ try
+ {
+ initialize(ecParams, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ throw new InvalidParameterException("key size not configurable.");
+ }
+ }
+
+ public void initialize(
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ if (params == null)
+ {
+ ECParameterSpec implicitCA = configuration.getEcImplicitlyCa();
+ if (implicitCA == null)
+ {
+ throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set");
+ }
+
+ this.ecParams = null;
+ this.param = createKeyGenParamsBC(implicitCA, random);
+ }
+ else if (params instanceof ECParameterSpec)
+ {
+ this.ecParams = params;
+ this.param = createKeyGenParamsBC((ECParameterSpec)params, random);
+ }
+ else if (params instanceof java.security.spec.ECParameterSpec)
+ {
+ this.ecParams = params;
+ this.param = createKeyGenParamsJCE((java.security.spec.ECParameterSpec)params, random);
+ }
+ else if (params instanceof ECGenParameterSpec)
+ {
+ initializeNamedCurve(((ECGenParameterSpec)params).getName(), random);
+ }
+ else if (params instanceof ECNamedCurveGenParameterSpec)
+ {
+ initializeNamedCurve(((ECNamedCurveGenParameterSpec)params).getName(), random);
+ }
+ else
+ {
+ String name = ECUtil.getNameFrom(params);
+
+ if (name != null)
+ {
+ initializeNamedCurve(name, random);
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("invalid parameterSpec: " + params);
+ }
+ }
+
+ engine.init(param);
+ initialised = true;
+ }
+
+ public KeyPair generateKeyPair()
+ {
+ if (!initialised)
+ {
+ initialize(strength, new SecureRandom());
+ }
+
+ AsymmetricCipherKeyPair pair = engine.generateKeyPair();
+ ECPublicKeyParameters pub = (ECPublicKeyParameters)pair.getPublic();
+ ECPrivateKeyParameters priv = (ECPrivateKeyParameters)pair.getPrivate();
+
+ if (ecParams instanceof ECParameterSpec)
+ {
+ ECParameterSpec p = (ECParameterSpec)ecParams;
+
+ BCECPublicKey pubKey = new BCECPublicKey(algorithm, pub, p, configuration);
+ return new KeyPair(pubKey,
+ new BCECPrivateKey(algorithm, priv, pubKey, p, configuration));
+ }
+ else if (ecParams == null)
+ {
+ return new KeyPair(new BCECPublicKey(algorithm, pub, configuration),
+ new BCECPrivateKey(algorithm, priv, configuration));
+ }
+ else
+ {
+ java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams;
+
+ BCECPublicKey pubKey = new BCECPublicKey(algorithm, pub, p, configuration);
+
+ return new KeyPair(pubKey, new BCECPrivateKey(algorithm, priv, pubKey, p, configuration));
+ }
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsBC(ECParameterSpec p, SecureRandom r)
+ {
+ return new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH()), r);
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsJCE(java.security.spec.ECParameterSpec p, SecureRandom r)
+ {
+ if (p instanceof ECNamedCurveSpec)
+ {
+ String curveName = ((ECNamedCurveSpec)p).getName();
+
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null != x9)
+ {
+ return createKeyGenParamsJCE(x9, r);
+ }
+ }
+
+ ECCurve curve = EC5Util.convertCurve(p.getCurve());
+ ECPoint g = EC5Util.convertPoint(curve, p.getGenerator());
+ BigInteger n = p.getOrder();
+ BigInteger h = BigInteger.valueOf(p.getCofactor());
+ ECDomainParameters dp = new ECDomainParameters(curve, g, n, h);
+ return new ECKeyGenerationParameters(dp, r);
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsJCE(X9ECParameters x9, SecureRandom r)
+ {
+ ECDomainParameters dp = new ECDomainParameters(x9.getCurve(), x9.getG(), x9.getN(), x9.getH());
+
+ return new ECKeyGenerationParameters(dp, r);
+ }
+
+ protected void initializeNamedCurve(String curveName, SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null == x9)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
+ }
+
+ // Work-around for JDK bug -- it won't look up named curves properly if seed is present
+ byte[] seed = null; //p.getSeed();
+
+ this.ecParams = new ECNamedCurveSpec(curveName, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), seed);
+ this.param = createKeyGenParamsJCE(x9, random);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class SM2
+ extends BaseSM2
+ {
+ public SM2()
+ {
+ super("SM2", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+}
\ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
index 324623c..b981962 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
@@ -197,21 +197,18 @@
return null;
}
- protected void engineInit(
- Key key,
- AlgorithmParameterSpec params,
- SecureRandom random)
+ protected void doInitFromKey(Key key, AlgorithmParameterSpec parameterSpec, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
// Android-removed: Unsupported algorithms
- // if (params != null &&
- // !(params instanceof MQVParameterSpec || params instanceof UserKeyingMaterialSpec || params instanceof DHUParameterSpec))
- if (params != null && !(params instanceof UserKeyingMaterialSpec))
+ // if (parameterSpec != null &&
+ // !(parameterSpec instanceof MQVParameterSpec || parameterSpec instanceof UserKeyingMaterialSpec || params instanceof DHUParameterSpec))
+ if (parameterSpec != null && !(parameterSpec instanceof UserKeyingMaterialSpec))
{
throw new InvalidAlgorithmParameterException("No algorithm parameters supported");
}
- initFromKey(key, params);
+ initFromKey(key, parameterSpec);
}
protected void engineInit(
@@ -251,9 +248,9 @@
{
MQVPrivateKey mqvPrivKey = (MQVPrivateKey)key;
staticPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey());
+ ECUtils.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey());
ephemPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey());
+ ECUtils.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey());
ephemPubKey = null;
if (mqvPrivKey.getEphemeralPublicKey() != null)
@@ -267,9 +264,9 @@
MQVParameterSpec mqvParameterSpec = (MQVParameterSpec)parameterSpec;
staticPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ ECUtils.generatePrivateKeyParameter((PrivateKey)key);
ephemPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(mqvParameterSpec.getEphemeralPrivateKey());
+ ECUtils.generatePrivateKeyParameter(mqvParameterSpec.getEphemeralPrivateKey());
ephemPubKey = null;
if (mqvParameterSpec.getEphemeralPublicKey() != null)
@@ -301,9 +298,9 @@
ECPublicKeyParameters ephemPubKey;
staticPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ ECUtils.generatePrivateKeyParameter((PrivateKey)key);
ephemPrivKey = (ECPrivateKeyParameters)
- ECUtil.generatePrivateKeyParameter(dheParameterSpec.getEphemeralPrivateKey());
+ ECUtils.generatePrivateKeyParameter(dheParameterSpec.getEphemeralPrivateKey());
ephemPubKey = null;
if (dheParameterSpec.getEphemeralPublicKey() != null)
@@ -332,7 +329,7 @@
{
throw new InvalidAlgorithmParameterException("no KDF specified for UserKeyingMaterialSpec");
}
- ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtils.generatePrivateKeyParameter((PrivateKey)key);
this.parameters = privKey.getParameters();
ukmParameters = (parameterSpec instanceof UserKeyingMaterialSpec) ? ((UserKeyingMaterialSpec)parameterSpec).getUserKeyingMaterial() : null;
((BasicAgreement)agreement).init(privKey);
@@ -346,7 +343,7 @@
return fullName.substring(fullName.lastIndexOf('.') + 1);
}
- protected byte[] calcSecret()
+ protected byte[] doCalcSecret()
{
return Arrays.clone(result);
}
@@ -762,8 +759,8 @@
{
super("ECKAEGwithSHA1KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA1()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -775,8 +772,8 @@
{
super("ECKAEGwithRIPEMD160KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(new RIPEMD160Digest()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -788,8 +785,8 @@
{
super("ECKAEGwithSHA224KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA224()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -801,8 +798,8 @@
{
super("ECKAEGwithSHA256KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA256()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
@@ -814,8 +811,8 @@
{
super("ECKAEGwithSHA384KDF", new ECDHBasicAgreement(),
new KDF2BytesGenerator(DigestFactory.createSHA384()));
- }
- }
+ }
+ }
/**
* KeyAgreement according to BSI TR-03111 chapter 4.3.1
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
index 87ea479..b2fdef1 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
@@ -241,7 +241,11 @@
try
{
- return new BCECPrivateKey(algorithm, new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ecKey.getParameters()), ecKey), configuration);
+ return new BCECPrivateKey(algorithm,
+ new PrivateKeyInfo(
+ new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ecKey.getParametersObject()),
+ ecKey),
+ configuration);
}
catch (IOException e)
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
index 0892390..f024d75 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
@@ -9,10 +9,7 @@
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.util.Hashtable;
-import java.util.Map;
-import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable;
import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
@@ -63,7 +60,8 @@
static private Hashtable ecParameters;
- static {
+ static
+ {
ecParameters = new Hashtable();
ecParameters.put(Integers.valueOf(192), new ECGenParameterSpec("prime192v1")); // a.k.a P-192
@@ -220,13 +218,12 @@
{
if (p instanceof ECNamedCurveSpec)
{
- X9ECParameters x9P = ECUtils.getDomainParametersFromName(((ECNamedCurveSpec)p).getName());
+ String curveName = ((ECNamedCurveSpec)p).getName();
- if (x9P != null)
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null != x9)
{
- ECDomainParameters dp = new ECDomainParameters(x9P.getCurve(), x9P.getG(), x9P.getN(), x9P.getH());
-
- return new ECKeyGenerationParameters(dp, r);
+ return createKeyGenParamsJCE(x9, r);
}
}
@@ -238,48 +235,27 @@
return new ECKeyGenerationParameters(dp, r);
}
- protected ECNamedCurveSpec createNamedCurveSpec(String curveName)
- throws InvalidAlgorithmParameterException
+ protected ECKeyGenerationParameters createKeyGenParamsJCE(X9ECParameters x9, SecureRandom r)
{
- // NOTE: Don't bother with custom curves here as the curve will be converted to JCE type shortly
+ ECDomainParameters dp = new ECDomainParameters(x9.getCurve(), x9.getG(), x9.getN(), x9.getH());
- X9ECParameters p = ECUtils.getDomainParametersFromName(curveName);
- if (p == null)
- {
- try
- {
- // Check whether it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug)
- p = ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(curveName));
- if (p == null)
- {
- Map extraCurves = configuration.getAdditionalECParameters();
-
- p = (X9ECParameters)extraCurves.get(new ASN1ObjectIdentifier(curveName));
-
- if (p == null)
- {
- throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName);
- }
- }
- }
- catch (IllegalArgumentException ex)
- {
- throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
- }
- }
-
- // Work-around for JDK bug -- it won't look up named curves properly if seed is present
- byte[] seed = null; //p.getSeed();
-
- return new ECNamedCurveSpec(curveName, p.getCurve(), p.getG(), p.getN(), p.getH(), seed);
+ return new ECKeyGenerationParameters(dp, r);
}
protected void initializeNamedCurve(String curveName, SecureRandom random)
throws InvalidAlgorithmParameterException
{
- ECNamedCurveSpec namedCurve = createNamedCurveSpec(curveName);
- this.ecParams = namedCurve;
- this.param = createKeyGenParamsJCE(namedCurve, random);
+ X9ECParameters x9 = ECUtils.getDomainParametersFromName(curveName, configuration);
+ if (null == x9)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
+ }
+
+ // Work-around for JDK bug -- it won't look up named curves properly if seed is present
+ byte[] seed = null; //p.getSeed();
+
+ this.ecParams = new ECNamedCurveSpec(curveName, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), seed);
+ this.param = createKeyGenParamsJCE(x9, random);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
index 87ad765..50ce091 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
@@ -12,6 +12,7 @@
import com.android.internal.org.bouncycastle.crypto.digests.NullDigest;
// BEGIN Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
+// import org.bouncycastle.crypto.digests.SHAKEDigest;
// END Android-removed: Unsupported algorithms
import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
import com.android.internal.org.bouncycastle.crypto.signers.DSAEncoding;
@@ -26,7 +27,6 @@
// import org.bouncycastle.crypto.util.DigestFactory;
import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.DSABase;
-import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
/**
* @hide This class is not part of the Android public SDK API
@@ -52,7 +52,7 @@
PrivateKey privateKey)
throws InvalidKeyException
{
- CipherParameters param = ECUtil.generatePrivateKeyParameter(privateKey);
+ CipherParameters param = ECUtils.generatePrivateKeyParameter(privateKey);
digest.reset();
@@ -297,6 +297,26 @@
}
}
+ static public class ecDSAShake128
+ extends SignatureSpi
+ {
+ public ecDSAShake128()
+ {
+ // RFC 8702 specifies deterministic DSA
+ super(new SHAKEDigest(128), new ECDSASigner(new HMacDSAKCalculator(new SHAKEDigest(128))), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDSAShake256
+ extends SignatureSpi
+ {
+ public ecDSAShake256()
+ {
+ // RFC 8702 specifies deterministic DSA
+ super(new SHAKEDigest(256), new ECDSASigner(new HMacDSAKCalculator(new SHAKEDigest(256))), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
static public class ecNR
extends SignatureSpi
{
@@ -395,6 +415,41 @@
super(new RIPEMD160Digest(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
}
}
+ static public class ecCVCDSA3_224
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_224()
+ {
+ super(DigestFactory.createSHA3_224(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA3_256
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_256()
+ {
+ super(DigestFactory.createSHA3_256(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA3_384
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_384()
+ {
+ super(DigestFactory.createSHA3_384(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA3_512
+ extends SignatureSpi
+ {
+ public ecCVCDSA3_512()
+ {
+ super(DigestFactory.createSHA3_512(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
index 8381d95..4420aea 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
@@ -12,9 +12,11 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
import com.android.internal.org.bouncycastle.asn1.DERNull;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
import com.android.internal.org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
@@ -184,16 +186,36 @@
throws IOException
{
PSSParameterSpec pssSpec = currentSpec;
- AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(
- DigestFactory.getOID(pssSpec.getDigestAlgorithm()),
- DERNull.INSTANCE);
- MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters();
- AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
- PKCSObjectIdentifiers.id_mgf1,
- new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
- RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField()));
+ ASN1ObjectIdentifier digOid = DigestFactory.getOID(pssSpec.getDigestAlgorithm());
+ AlgorithmIdentifier hashAlgorithm;
+ // RFC 8072
+ if (NISTObjectIdentifiers.id_shake128.equals(digOid) || NISTObjectIdentifiers.id_shake256.equals(digOid))
+ {
+ hashAlgorithm = new AlgorithmIdentifier(digOid);
+ }
+ else
+ {
+ hashAlgorithm = new AlgorithmIdentifier(digOid, DERNull.INSTANCE);
+ }
- return pssP.getEncoded("DER");
+ MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters();
+ if (mgfSpec != null)
+ {
+ AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
+ PKCSObjectIdentifiers.id_mgf1,
+ new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
+ RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField()));
+
+ return pssP.getEncoded("DER");
+ }
+ else
+ {
+ AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
+ pssSpec.getMGFAlgorithm().equals("SHAKE128") ? NISTObjectIdentifiers.id_shake128 : NISTObjectIdentifiers.id_shake256);
+ RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField()));
+
+ return pssP.getEncoded("DER");
+ }
}
protected byte[] engineGetEncoded(
@@ -241,17 +263,29 @@
{
RSASSAPSSparams pssP = RSASSAPSSparams.getInstance(params);
- if (!pssP.getMaskGenAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1))
+ ASN1ObjectIdentifier mgfOid = pssP.getMaskGenAlgorithm().getAlgorithm();
+ if (mgfOid.equals(PKCSObjectIdentifiers.id_mgf1))
+ {
+ currentSpec = new PSSParameterSpec(
+ MessageDigestUtils.getDigestName(pssP.getHashAlgorithm().getAlgorithm()),
+ PSSParameterSpec.DEFAULT.getMGFAlgorithm(),
+ new MGF1ParameterSpec(MessageDigestUtils.getDigestName(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getAlgorithm())),
+ pssP.getSaltLength().intValue(),
+ pssP.getTrailerField().intValue());
+ }
+ else if (mgfOid.equals(NISTObjectIdentifiers.id_shake128) || mgfOid.equals(NISTObjectIdentifiers.id_shake256))
+ {
+ currentSpec = new PSSParameterSpec(
+ MessageDigestUtils.getDigestName(pssP.getHashAlgorithm().getAlgorithm()),
+ mgfOid.equals(NISTObjectIdentifiers.id_shake128) ? "SHAKE128" : "SHAKE256",
+ null,
+ pssP.getSaltLength().intValue(),
+ pssP.getTrailerField().intValue());
+ }
+ else
{
throw new IOException("unknown mask generation function: " + pssP.getMaskGenAlgorithm().getAlgorithm());
}
-
- currentSpec = new PSSParameterSpec(
- MessageDigestUtils.getDigestName(pssP.getHashAlgorithm().getAlgorithm()),
- PSSParameterSpec.DEFAULT.getMGFAlgorithm(),
- new MGF1ParameterSpec(MessageDigestUtils.getDigestName(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getAlgorithm())),
- pssP.getSaltLength().intValue(),
- pssP.getTrailerField().intValue());
}
catch (ClassCastException e)
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
index 8a9a86c..f6d0b00 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
@@ -31,7 +31,6 @@
// Android-removed: Unsupported algorithm
// import org.bouncycastle.crypto.encodings.ISO9796d1Encoding;
import com.android.internal.org.bouncycastle.crypto.encodings.OAEPEncoding;
-import com.android.internal.org.bouncycastle.crypto.encodings.PKCS1Encoding;
import com.android.internal.org.bouncycastle.crypto.engines.RSABlindedEngine;
import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi;
@@ -209,7 +208,7 @@
}
else if (pad.equals("PKCS1PADDING"))
{
- cipher = new PKCS1Encoding(new RSABlindedEngine());
+ cipher = new CustomPKCS1Encoding(new RSABlindedEngine());
}
// BEGIN Android-removed: Unsupported algorithm
// else if (pad.equals("ISO9796-1PADDING"))
@@ -546,15 +545,26 @@
{
try
{
- return cipher.processBlock(bOut.getBuf(), 0, bOut.size());
- }
- catch (InvalidCipherTextException e)
- {
- throw new BadBlockException("unable to decrypt block", e);
- }
- catch (ArrayIndexOutOfBoundsException e)
- {
- throw new BadBlockException("unable to decrypt block", e);
+ byte[] output;
+ try
+ {
+ output = cipher.processBlock(bOut.getBuf(), 0, bOut.size());
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new BadBlockException("unable to decrypt block", e);
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ throw new BadBlockException("unable to decrypt block", e);
+ }
+
+ if (output == null)
+ {
+ throw new BadBlockException("unable to decrypt block", null);
+ }
+
+ return output;
}
finally
{
@@ -583,7 +593,7 @@
{
public PKCS1v1_5Padding()
{
- super(new PKCS1Encoding(new RSABlindedEngine()));
+ super(new CustomPKCS1Encoding(new RSABlindedEngine()));
}
}
@@ -592,7 +602,7 @@
{
public PKCS1v1_5Padding_PrivateOnly()
{
- super(false, true, new PKCS1Encoding(new RSABlindedEngine()));
+ super(false, true, new CustomPKCS1Encoding(new RSABlindedEngine()));
}
}
@@ -601,7 +611,7 @@
{
public PKCS1v1_5Padding_PublicOnly()
{
- super(true, false, new PKCS1Encoding(new RSABlindedEngine()));
+ super(true, false, new CustomPKCS1Encoding(new RSABlindedEngine()));
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java
new file mode 100644
index 0000000..371dd19
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/CustomPkcs1Encoding.java
@@ -0,0 +1,264 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.AsymmetricBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.encodings.PKCS1Encoding;
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Properties;
+
+/**
+ * this does your basic PKCS 1 v1.5 padding - whether or not you should be using this
+ * depends on your application - see PKCS1 Version 2 for details.
+ */
+class CustomPKCS1Encoding
+ implements AsymmetricBlockCipher
+{
+ private static final int HEADER_LENGTH = 10;
+
+ private SecureRandom random;
+ private AsymmetricBlockCipher engine;
+ private boolean forEncryption;
+ private boolean forPrivateKey;
+ private boolean useStrictLength;
+ private byte[] blockBuffer;
+
+ /**
+ * Basic constructor.
+ *
+ * @param cipher
+ */
+ CustomPKCS1Encoding(AsymmetricBlockCipher cipher)
+ {
+ this.engine = cipher;
+ this.useStrictLength = useStrict();
+ }
+
+ //
+ // for J2ME compatibility
+ //
+ private boolean useStrict()
+ {
+ if (Properties.isOverrideSetTo(PKCS1Encoding.NOT_STRICT_LENGTH_ENABLED_PROPERTY, true))
+ {
+ return false;
+ }
+
+ return !Properties.isOverrideSetTo(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY, false);
+ }
+
+ public AsymmetricBlockCipher getUnderlyingCipher()
+ {
+ return engine;
+ }
+
+ public void init(boolean forEncryption, CipherParameters param)
+ {
+ AsymmetricKeyParameter kParam;
+
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+ this.random = rParam.getRandom();
+ kParam = (AsymmetricKeyParameter)rParam.getParameters();
+ }
+ else
+ {
+ kParam = (AsymmetricKeyParameter)param;
+ if (!kParam.isPrivate() && forEncryption)
+ {
+ this.random = CryptoServicesRegistrar.getSecureRandom();
+ }
+ }
+
+ engine.init(forEncryption, param);
+
+ this.forPrivateKey = kParam.isPrivate();
+ this.forEncryption = forEncryption;
+ this.blockBuffer = new byte[engine.getOutputBlockSize()];
+ }
+
+ public int getInputBlockSize()
+ {
+ int baseBlockSize = engine.getInputBlockSize();
+
+ if (forEncryption)
+ {
+ return baseBlockSize - HEADER_LENGTH;
+ }
+ else
+ {
+ return baseBlockSize;
+ }
+ }
+
+ public int getOutputBlockSize()
+ {
+ int baseBlockSize = engine.getOutputBlockSize();
+
+ if (forEncryption)
+ {
+ return baseBlockSize;
+ }
+ else
+ {
+ return baseBlockSize - HEADER_LENGTH;
+ }
+ }
+
+ public byte[] processBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException
+ {
+ if (forEncryption)
+ {
+ return encodeBlock(in, inOff, inLen);
+ }
+ else
+ {
+ return decodeBlock(in, inOff, inLen);
+ }
+ }
+
+ private byte[] encodeBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException
+ {
+ if (inLen > getInputBlockSize())
+ {
+ throw new IllegalArgumentException("input data too large");
+ }
+
+ byte[] block = new byte[engine.getInputBlockSize()];
+
+ if (forPrivateKey)
+ {
+ block[0] = 0x01; // type code 1
+
+ for (int i = 1; i != block.length - inLen - 1; i++)
+ {
+ block[i] = (byte)0xFF;
+ }
+ }
+ else
+ {
+ random.nextBytes(block); // random fill
+
+ block[0] = 0x02; // type code 2
+
+ //
+ // a zero byte marks the end of the padding, so all
+ // the pad bytes must be non-zero.
+ //
+ for (int i = 1; i != block.length - inLen - 1; i++)
+ {
+ while (block[i] == 0)
+ {
+ block[i] = (byte)random.nextInt();
+ }
+ }
+ }
+
+ block[block.length - inLen - 1] = 0x00; // mark the end of the padding
+ System.arraycopy(in, inOff, block, block.length - inLen, inLen);
+
+ return engine.processBlock(block, 0, block.length);
+ }
+
+ /**
+ * Check the argument is a valid encoding with type 1. Returns the plaintext length if valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding1(byte[] buf)
+ {
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
+
+ // The first byte should be 0x01
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x01);
+
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
+ {
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ int is0xFFMask = ((padByte ^ 0xFF) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ badPadSign |= ~(foundZeroMask | is0xFFMask);
+ }
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
+ }
+
+ /**
+ * Check the argument is a valid encoding with type 2. Returns the plaintext length if valid, or -1 if invalid.
+ */
+ private static int checkPkcs1Encoding2(byte[] buf)
+ {
+ int foundZeroMask = 0;
+ int lastPadPos = 0;
+
+ // The first byte should be 0x02
+ int badPadSign = -((buf[0] & 0xFF) ^ 0x02);
+
+ // There must be a zero terminator for the padding somewhere
+ for (int i = 1; i < buf.length; ++i)
+ {
+ int padByte = buf[i] & 0xFF;
+ int is0x00Mask = ((padByte ^ 0x00) - 1) >> 31;
+ lastPadPos ^= i & ~foundZeroMask & is0x00Mask;
+ foundZeroMask |= is0x00Mask;
+ }
+
+ // The header should be at least 10 bytes
+ badPadSign |= lastPadPos - 9;
+
+ int plaintextLength = buf.length - 1 - lastPadPos;
+ return plaintextLength | badPadSign >> 31;
+ }
+
+ /**
+ * @throws InvalidCipherTextException if the decrypted block is not in PKCS1 format.
+ */
+ private byte[] decodeBlock(byte[] in, int inOff, int inLen)
+ throws InvalidCipherTextException
+ {
+ int strictBlockSize = engine.getOutputBlockSize();
+ byte[] block = engine.processBlock(in, inOff, inLen);
+
+ boolean incorrectLength = useStrictLength & (block.length != strictBlockSize);
+
+ byte[] data = block;
+ if (block.length < strictBlockSize)
+ {
+ data = blockBuffer;
+ }
+
+ int plaintextLength = forPrivateKey ? checkPkcs1Encoding2(data) : checkPkcs1Encoding1(data);
+
+ try
+ {
+ if (plaintextLength < 0 | incorrectLength)
+ {
+ // Special behaviour to avoid throw/catch/throw in CipherSpi
+ return null;
+ }
+
+ byte[] result = new byte[plaintextLength];
+ System.arraycopy(data, data.length - plaintextLength, result, 0, plaintextLength);
+ return result;
+ }
+ finally
+ {
+ Arrays.fill(block, (byte)0);
+ Arrays.fill(blockBuffer, 0, Math.max(0, blockBuffer.length - block.length), (byte)0);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
index b89cd73..9f0afce 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
@@ -1,7 +1,12 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
@@ -27,6 +32,7 @@
// import org.bouncycastle.crypto.agreement.kdf.DHKEKGenerator;
import com.android.internal.org.bouncycastle.crypto.params.DESParameters;
import com.android.internal.org.bouncycastle.crypto.params.KDFParameters;
+import com.android.internal.org.bouncycastle.jcajce.spec.HybridValueParameterSpec;
import com.android.internal.org.bouncycastle.util.Arrays;
import com.android.internal.org.bouncycastle.util.Integers;
import com.android.internal.org.bouncycastle.util.Strings;
@@ -152,6 +158,7 @@
protected final DerivationFunction kdf;
protected byte[] ukmParameters;
+ private HybridValueParameterSpec hybridSpec;
public BaseAgreementSpi(String kaAlgorithm, DerivationFunction kdf)
{
@@ -225,6 +232,40 @@
}
}
+ protected void engineInit(
+ Key key,
+ SecureRandom random)
+ throws InvalidKeyException
+ {
+ try
+ {
+ doInitFromKey(key, null, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ // this should never occur.
+ throw new InvalidKeyException(e.getMessage());
+ }
+ }
+
+ protected void engineInit(
+ Key key,
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ if (params instanceof HybridValueParameterSpec)
+ {
+ this.hybridSpec = (HybridValueParameterSpec)params;
+ doInitFromKey(key, hybridSpec.getBaseParameterSpec(), random);
+ }
+ else
+ {
+ this.hybridSpec = null;
+ doInitFromKey(key, params, random);
+ }
+ }
+
protected byte[] engineGenerateSecret()
throws IllegalStateException
{
@@ -351,5 +392,26 @@
}
}
- protected abstract byte[] calcSecret();
+ private byte[] calcSecret()
+ {
+ if (hybridSpec != null)
+ {
+ // Set Z' to Z || T
+ byte[] s = doCalcSecret();
+ byte[] sec = Arrays.concatenate(s, hybridSpec.getT());
+
+ Arrays.clear(s);
+
+ return sec;
+ }
+ else
+ {
+ return doCalcSecret();
+ }
+ }
+
+ protected abstract byte[] doCalcSecret();
+
+ protected abstract void doInitFromKey(Key key, AlgorithmParameterSpec parameterSpec, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
index 7eaea81..3beccd4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
@@ -20,6 +20,7 @@
import com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable;
import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParametersHolder;
import com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves;
import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
@@ -39,20 +40,41 @@
*/
public class EC5Util
{
- private static Map customCurves = new HashMap();
-
- static
+ private static class CustomCurves
{
- Enumeration e = CustomNamedCurves.getNames();
- while (e.hasMoreElements())
- {
- String name = (String)e.nextElement();
+ private static Map CURVE_MAP = createCurveMap();
- X9ECParameters curveParams = ECNamedCurveTable.getByName(name);
- if (curveParams != null) // there may not be a regular curve, may just be a custom curve.
+ private static Map createCurveMap()
+ {
+ Map map = new HashMap();
+
+ Enumeration e = CustomNamedCurves.getNames();
+ while (e.hasMoreElements())
{
- customCurves.put(curveParams.getCurve(), CustomNamedCurves.getByName(name).getCurve());
+ String name = (String)e.nextElement();
+
+ X9ECParametersHolder curveParams = ECNamedCurveTable.getByNameLazy(name);
+ if (curveParams != null) // there may not be a regular curve, may just be a custom curve.
+ {
+ ECCurve curve = curveParams.getCurve();
+ if (ECAlgorithms.isFpCurve(curve))
+ {
+ map.put(curve, CustomNamedCurves.getByNameLazy(name).getCurve());
+ }
+ }
}
+
+ ECCurve c_25519 = CustomNamedCurves.getByNameLazy("Curve25519").getCurve();
+
+ map.put(new ECCurve.Fp(
+ c_25519.getField().getCharacteristic(),
+ c_25519.getA().toBigInteger(),
+ c_25519.getB().toBigInteger(),
+ c_25519.getOrder(),
+ c_25519.getCofactor(),
+ true), c_25519);
+
+ return map;
}
// BEGIN Android-removed: Unsupported curves
@@ -69,6 +91,11 @@
), c_25519);
*/
// END Android-removed: Unsupported curves
+ static ECCurve substitute(ECCurve c)
+ {
+ ECCurve custom = (ECCurve)CURVE_MAP.get(c);
+ return null != custom ? custom : c;
+ }
}
public static ECCurve getCurve(
@@ -280,21 +307,14 @@
if (field instanceof ECFieldFp)
{
- ECCurve.Fp curve = new ECCurve.Fp(((ECFieldFp)field).getP(), a, b);
-
- if (customCurves.containsKey(curve))
- {
- return (ECCurve)customCurves.get(curve);
- }
-
- return curve;
+ return CustomCurves.substitute(new ECCurve.Fp(((ECFieldFp)field).getP(), a, b, null, null));
}
else
{
ECFieldF2m fieldF2m = (ECFieldF2m)field;
int m = fieldF2m.getM();
int ks[] = ECUtil.convertMidTerms(fieldF2m.getMidTermsOfReductionPolynomial());
- return new ECCurve.F2m(m, ks[0], ks[1], ks[2], a, b);
+ return new ECCurve.F2m(m, ks[0], ks[1], ks[2], a, b, null, null);
}
}
@@ -308,7 +328,7 @@
{
Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
int[] exponents = poly.getExponentsPresent();
- int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
+ int[] ks = Arrays.reverseInPlace(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
return new ECFieldF2m(poly.getDegree(), ks);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
index 5d0ebfe..75f275f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
@@ -293,6 +293,11 @@
{
if (order == null) // implicitly CA
{
+ if (configuration == null)
+ {
+ return privateValue.bitLength(); // a guess but better than an exception!
+ }
+
ECParameterSpec implicitCA = configuration.getEcImplicitlyCa();
if (implicitCA == null)
@@ -311,26 +316,24 @@
public static ASN1ObjectIdentifier getNamedCurveOid(
String curveName)
{
- String name = curveName;
+ if (null == curveName || curveName.length() < 1)
+ {
+ return null;
+ }
- int spacePos = name.indexOf(' ');
+ int spacePos = curveName.indexOf(' ');
if (spacePos > 0)
{
- name = name.substring(spacePos + 1);
+ curveName = curveName.substring(spacePos + 1);
}
- try
+ ASN1ObjectIdentifier oid = getOID(curveName);
+ if (null != oid)
{
- if (name.charAt(0) >= '0' && name.charAt(0) <= '2')
- {
- return new ASN1ObjectIdentifier(name);
- }
- }
- catch (IllegalArgumentException ex)
- {
+ return oid;
}
- return ECNamedCurveTable.getOID(name);
+ return ECNamedCurveTable.getOID(curveName);
}
public static ASN1ObjectIdentifier getNamedCurveOid(
@@ -448,4 +451,20 @@
}
});
}
+
+ private static ASN1ObjectIdentifier getOID(String curveName)
+ {
+ char firstChar = curveName.charAt(0);
+ if (firstChar >= '0' && firstChar <= '2')
+ {
+ try
+ {
+ return new ASN1ObjectIdentifier(curveName);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ return null;
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
index 1de0527..3b3db1a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
@@ -65,10 +65,11 @@
}
private java.security.cert.Certificate readPEMCertificate(
- InputStream in)
+ InputStream in,
+ boolean isFirst)
throws IOException, CertificateParsingException
{
- return getCertificate(PEM_CERT_PARSER.readPEMObject(in));
+ return getCertificate(PEM_CERT_PARSER.readPEMObject(in, isFirst));
}
private java.security.cert.Certificate getCertificate(ASN1Sequence seq)
@@ -123,10 +124,11 @@
}
private CRL readPEMCRL(
- InputStream in)
+ InputStream in,
+ boolean isFirst)
throws IOException, CRLException
{
- return getCRL(PEM_CRL_PARSER.readPEMObject(in));
+ return getCRL(PEM_CRL_PARSER.readPEMObject(in, isFirst));
}
private CRL readDERCRL(
@@ -181,6 +183,14 @@
InputStream in)
throws CertificateException
{
+ return doGenerateCertificate(in, true);
+ }
+
+ private java.security.cert.Certificate doGenerateCertificate(
+ InputStream in,
+ boolean isFirst)
+ throws CertificateException
+ {
if (currentStream == null)
{
currentStream = in;
@@ -254,7 +264,7 @@
if (tag != 0x30) // assume ascii PEM encoded.
{
- return readPEMCertificate(pis);
+ return readPEMCertificate(pis, isFirst);
}
else
{
@@ -286,7 +296,8 @@
// Android-changed: Read from original stream
// while ((cert = engineGenerateCertificate(in)) != null)
- while ((cert = engineGenerateCertificate(inStream)) != null)
+ // if we do read some certificates we'll return them even if junk at end of file
+ while ((cert = doGenerateCertificate(inStream, certs.isEmpty())) != null)
{
certs.add(cert);
}
@@ -302,6 +313,18 @@
InputStream in)
throws CRLException
{
+ return doGenerateCRL(in, true);
+ }
+
+ /**
+ * Generates a certificate revocation list (CRL) object and initializes
+ * it with the data read from the input stream inStream.
+ */
+ private CRL doGenerateCRL(
+ InputStream in,
+ boolean isFirst)
+ throws CRLException
+ {
if (currentCrlStream == null)
{
currentCrlStream = in;
@@ -353,7 +376,7 @@
pis.reset();
if (tag != 0x30) // assume ascii PEM encoded.
{
- return readPEMCRL(pis);
+ return readPEMCRL(pis, isFirst);
}
else
{ // lazy evaluate to help processing of large CRLs
@@ -387,7 +410,8 @@
List crls = new ArrayList();
BufferedInputStream in = new BufferedInputStream(inStream);
- while ((crl = engineGenerateCRL(in)) != null)
+ // if we do read some certificates we'll return them even if junk at end of file
+ while ((crl = doGenerateCRL(in, crls.isEmpty())) != null)
{
crls.add(crl);
}
@@ -435,7 +459,7 @@
return new PKIXCertPath(certificates);
}
- private class ExCertificateException
+ private static class ExCertificateException
extends CertificateException
{
private Throwable cause;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
index 25c4230..12ee916 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
@@ -14,7 +14,7 @@
* current PEM object.
*
*/
- private class Boundaries
+ private static class Boundaries
{
private final String _header;
private final String _footer;
@@ -113,7 +113,8 @@
}
ASN1Sequence readPEMObject(
- InputStream in)
+ InputStream in,
+ boolean isFirst)
throws IOException
{
String line;
@@ -132,6 +133,11 @@
if (header == null)
{
+ if (!isFirst)
+ {
+ // just ignore the data
+ return null;
+ }
throw new IOException("malformed PEM data: no header found");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
index 755d869..cdec618 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
@@ -29,6 +29,7 @@
import javax.security.auth.x500.X500Principal;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
@@ -37,7 +38,6 @@
import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.util.ASN1Dump;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
@@ -159,19 +159,6 @@
return null;
}
- public byte[] getEncoded()
- throws CRLException
- {
- try
- {
- return c.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- throw new CRLException(e.toString());
- }
- }
-
public void verify(PublicKey key)
throws CRLException, NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException, SignatureException
@@ -256,7 +243,7 @@
{
List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != pubKeys.size(); i++)
@@ -278,7 +265,7 @@
checkSignature(
(PublicKey)pubKeys.get(i), signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
catch (SignatureException e)
@@ -300,7 +287,7 @@
else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
{
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != sigSeq.size(); i++)
@@ -317,7 +304,7 @@
checkSignature(
key, signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
index a3a5fed..23fbc55 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
@@ -6,25 +6,42 @@
import com.android.internal.org.bouncycastle.asn1.x509.CertificateList;
import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+/**
+ * This class exists to let {@link #equals(Object)} and {@link #hashCode()} methods be delegated efficiently
+ * to the platform default implementations (especially important for compatibility of {@link #hashCode()}
+ * calculations). Those methods fall back to calling {@link #getEncoded()} for third-party subclasses, and
+ * this class allows us to avoid cloning the return value of {@link #getEncoded()} for those callers.
+ */
class X509CRLInternal extends X509CRLImpl
{
private final byte[] encoding;
+ private final CRLException exception;
X509CRLInternal(JcaJceHelper bcHelper, CertificateList c, String sigAlgName, byte[] sigAlgParams, boolean isIndirect,
- byte[] encoding)
+ byte[] encoding, CRLException exception)
{
super(bcHelper, c, sigAlgName, sigAlgParams, isIndirect);
this.encoding = encoding;
+ this.exception = exception;
}
public byte[] getEncoded() throws CRLException
{
+ if (null != exception)
+ {
+ throw exception;
+ }
+
if (null == encoding)
{
throw new CRLException();
}
+ /*
+ * NOTE: Don't clone this return value. See class javadoc for details. Any necessary cloning is
+ * handled by the X509CRLObject that is holding this instance.
+ */
return encoding;
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
index 1eb9d66..f094cde 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+import java.io.IOException;
import java.security.cert.CRLException;
import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
@@ -10,6 +11,7 @@
import com.android.internal.org.bouncycastle.asn1.x509.Extension;
import com.android.internal.org.bouncycastle.asn1.x509.IssuingDistributionPoint;
import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.util.Arrays;
class X509CRLObject
extends X509CRLImpl
@@ -25,6 +27,11 @@
super(bcHelper, c, createSigAlgName(c), createSigAlgParams(c), isIndirectCRL(c));
}
+ public byte[] getEncoded() throws CRLException
+ {
+ return Arrays.clone(getInternalCRL().getEncoded());
+ }
+
public boolean equals(Object other)
{
if (this == other)
@@ -51,6 +58,8 @@
return false;
}
}
+
+ return getInternalCRL().equals(otherBC.getInternalCRL());
}
return getInternalCRL().equals(other);
@@ -77,17 +86,19 @@
}
}
- byte[] encoding;
+ byte[] encoding = null;
+ CRLException exception = null;
try
{
- encoding = getEncoded();
+ encoding = c.getEncoded(ASN1Encoding.DER);
}
- catch (CRLException e)
+ catch (IOException e)
{
- encoding = null;
+ exception = new X509CRLException(e);
}
- X509CRLInternal temp = new X509CRLInternal(bcHelper, c, sigAlgName,sigAlgParams, isIndirect, encoding);
+ X509CRLInternal temp = new X509CRLInternal(bcHelper, c, sigAlgName,sigAlgParams, isIndirect, encoding,
+ exception);
synchronized (cacheLock)
{
@@ -108,7 +119,7 @@
}
catch (Exception e)
{
- throw new CRLException("CRL contents invalid: " + e);
+ throw new X509CRLException("CRL contents invalid: " + e.getMessage(), e);
}
}
@@ -147,4 +158,26 @@
throw new ExtCRLException("Exception reading IssuingDistributionPoint", e);
}
}
+
+ private static class X509CRLException
+ extends CRLException
+ {
+ private final Throwable cause;
+
+ X509CRLException(String msg, Throwable cause)
+ {
+ super(msg);
+ this.cause = cause;
+ }
+
+ X509CRLException(Throwable cause)
+ {
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
index 920186c..5819f16 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
@@ -32,16 +32,17 @@
import javax.security.auth.x500.X500Principal;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1IA5String;
import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1String;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
-import com.android.internal.org.bouncycastle.asn1.DERIA5String;
import com.android.internal.org.bouncycastle.asn1.DERNull;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
@@ -65,6 +66,7 @@
import com.android.internal.org.bouncycastle.jce.X509Principal;
import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Exceptions;
import com.android.internal.org.bouncycastle.util.Integers;
import com.android.internal.org.bouncycastle.util.Properties;
import com.android.internal.org.bouncycastle.util.Strings;
@@ -79,7 +81,6 @@
protected boolean[] keyUsage;
protected String sigAlgName;
protected byte[] sigAlgParams;
-
X509CertificateImpl(JcaJceHelper bcHelper, com.android.internal.org.bouncycastle.asn1.x509.Certificate c,
BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams)
{
@@ -230,7 +231,7 @@
public boolean[] getIssuerUniqueID()
{
- DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getIssuerUniqueId();
if (id != null)
{
@@ -250,7 +251,7 @@
public boolean[] getSubjectUniqueID()
{
- DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getSubjectUniqueId();
if (id != null)
{
@@ -298,29 +299,21 @@
throw new CertificateParsingException("error processing extended key usage extension");
}
}
-
+
public int getBasicConstraints()
{
- if (basicConstraints != null)
+ if (basicConstraints == null || !basicConstraints.isCA())
{
- if (basicConstraints.isCA())
- {
- if (basicConstraints.getPathLenConstraint() == null)
- {
- return Integer.MAX_VALUE;
- }
- else
- {
- return basicConstraints.getPathLenConstraint().intValue();
- }
- }
- else
- {
- return -1;
- }
+ return -1;
}
- return -1;
+ ASN1Integer pathLenConstraint = basicConstraints.getPathLenConstraintInteger();
+ if (pathLenConstraint == null)
+ {
+ return Integer.MAX_VALUE;
+ }
+
+ return pathLenConstraint.intPositiveValueExact();
}
public Collection getSubjectAlternativeNames()
@@ -375,7 +368,7 @@
}
catch (Exception e)
{
- throw new IllegalStateException("error parsing " + e.toString());
+ throw Exceptions.illegalStateException("error parsing " + e.getMessage(), e);
}
}
@@ -461,20 +454,7 @@
}
catch (IOException e)
{
- return null; // should never happen...
- }
- }
-
- public byte[] getEncoded()
- throws CertificateEncodingException
- {
- try
- {
- return c.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- throw new CertificateEncodingException(e.toString());
+ throw Exceptions.illegalStateException("failed to recover public key: " + e.getMessage(), e);
}
}
@@ -527,15 +507,15 @@
}
else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
{
- buf.append(new NetscapeCertType(DERBitString.getInstance(dIn.readObject()))).append(nl);
+ buf.append(new NetscapeCertType(ASN1BitString.getInstance(dIn.readObject()))).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
{
- buf.append(new NetscapeRevocationURL(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ buf.append(new NetscapeRevocationURL(ASN1IA5String.getInstance(dIn.readObject()))).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
{
- buf.append(new VerisignCzagExtension(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ buf.append(new VerisignCzagExtension(ASN1IA5String.getInstance(dIn.readObject()))).append(nl);
}
else
{
@@ -647,7 +627,7 @@
{
List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != pubKeys.size(); i++)
@@ -668,7 +648,7 @@
checkSignature(
(PublicKey)pubKeys.get(i), signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
catch (SignatureException e)
@@ -690,7 +670,7 @@
else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
{
ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
- ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(ASN1BitString.getInstance(c.getSignature()).getBytes());
boolean success = false;
for (int i = 0; i != sigSeq.size(); i++)
@@ -707,7 +687,7 @@
checkSignature(
key, signature,
sigAlg.getParameters(),
- DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ ASN1BitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
success = true;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
index 6ff5ac1..7c345b6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
@@ -6,25 +6,43 @@
import com.android.internal.org.bouncycastle.asn1.x509.BasicConstraints;
import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+/**
+ * This class exists to let {@link #equals(Object)} and {@link #hashCode()} methods be delegated efficiently
+ * to the platform default implementations (especially important for compatibility of {@link #hashCode()}
+ * calculations). Those methods fall back to calling {@link #getEncoded()} for third-party subclasses, and
+ * this class allows us to avoid cloning the return value of {@link #getEncoded()} for those callers.
+ */
class X509CertificateInternal extends X509CertificateImpl
{
private final byte[] encoding;
+ private final CertificateEncodingException exception;
X509CertificateInternal(JcaJceHelper bcHelper, com.android.internal.org.bouncycastle.asn1.x509.Certificate c,
- BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams, byte[] encoding)
+ BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams, byte[] encoding,
+ CertificateEncodingException exception)
{
super(bcHelper, c, basicConstraints, keyUsage, sigAlgName, sigAlgParams);
this.encoding = encoding;
+ this.exception = exception;
}
public byte[] getEncoded() throws CertificateEncodingException
{
+ if (null != exception)
+ {
+ throw exception;
+ }
+
if (null == encoding)
{
throw new CertificateEncodingException();
}
+ /*
+ * NOTE: Don't clone this return value. See class javadoc for details. Any necessary cloning is
+ * handled by the X509CertificateObject that is holding this instance.
+ */
return encoding;
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
index 39f0ff1..b69b46e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
@@ -1,57 +1,22 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
-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;
-import java.security.Principal;
-import java.security.Provider;
import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
import javax.security.auth.x500.X500Principal;
import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
-import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import com.android.internal.org.bouncycastle.asn1.ASN1OutputStream;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.internal.org.bouncycastle.asn1.ASN1String;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
-import com.android.internal.org.bouncycastle.asn1.DERIA5String;
-import com.android.internal.org.bouncycastle.asn1.DERNull;
-import com.android.internal.org.bouncycastle.asn1.DEROctetString;
-import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
-import com.android.internal.org.bouncycastle.asn1.misc.NetscapeCertType;
-import com.android.internal.org.bouncycastle.asn1.misc.NetscapeRevocationURL;
-import com.android.internal.org.bouncycastle.asn1.misc.VerisignCzagExtension;
-import com.android.internal.org.bouncycastle.asn1.util.ASN1Dump;
-import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
-import com.android.internal.org.bouncycastle.asn1.x500.style.RFC4519Style;
-import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.BasicConstraints;
import com.android.internal.org.bouncycastle.asn1.x509.Extension;
import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
@@ -62,12 +27,8 @@
// END Android-added: Unknown reason
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
-import com.android.internal.org.bouncycastle.jce.X509Principal;
import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
-import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
-import com.android.internal.org.bouncycastle.util.Integers;
-import com.android.internal.org.bouncycastle.util.Strings;
-import com.android.internal.org.bouncycastle.util.encoders.Hex;
+import com.android.internal.org.bouncycastle.util.Arrays;
class X509CertificateObject
extends X509CertificateImpl
@@ -254,6 +215,8 @@
return false;
}
}
+
+ return getInternalCertificate().equals(otherBC.getInternalCertificate());
}
return getInternalCertificate().equals(other);
@@ -318,18 +281,19 @@
}
}
- byte[] encoding;
+ byte[] encoding = null;
+ CertificateEncodingException exception = null;
try
{
- encoding = getEncoded();
+ encoding = c.getEncoded(ASN1Encoding.DER);
}
- catch (CertificateEncodingException e)
+ catch (IOException e)
{
- encoding = null;
+ exception = new X509CertificateEncodingException(e);
}
X509CertificateInternal temp = new X509CertificateInternal(bcHelper, c, basicConstraints, keyUsage, sigAlgName,
- sigAlgParams, encoding);
+ sigAlgParams, encoding, exception);
synchronized (cacheLock)
{
@@ -371,7 +335,7 @@
return null;
}
- ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(extOctets));
+ ASN1BitString bits = ASN1BitString.getInstance(ASN1Primitive.fromByteArray(extOctets));
byte[] bytes = bits.getBytes();
int length = (bytes.length * 8) - bits.getPadBits();
@@ -420,4 +384,20 @@
throw new CertificateParsingException("cannot construct SigAlgParams: " + e);
}
}
+
+ private static class X509CertificateEncodingException
+ extends CertificateEncodingException
+ {
+ private final Throwable cause;
+
+ X509CertificateEncodingException(Throwable cause)
+ {
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
index bcf9fb5..7265c3f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
@@ -181,6 +181,11 @@
static void prettyPrintSignature(byte[] sig, StringBuffer buf, String nl)
{
+ // -DM Hex.toHexString
+ // -DM Hex.toHexString
+ // -DM Hex.toHexString
+ // -DM Hex.toHexString
+
if (sig.length > 20)
{
buf.append(" Signature: ").append(Hex.toHexString(sig, 0, 20)).append(nl);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
index cd76b86..d24420a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
@@ -47,8 +47,12 @@
void addAlgorithm(String key, String value);
+ void addAlgorithm(String key, String value, Map<String, String> attributes);
+
void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className);
+ void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className, Map<String, String> attributes);
+
boolean hasAlgorithm(String type, String name);
void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
index da100c1..70f37e6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.jcajce.provider.digest;
+import java.security.DigestException;
import java.security.MessageDigest;
import com.android.internal.org.bouncycastle.crypto.Digest;
@@ -69,4 +70,16 @@
return digestBytes;
}
+
+ public int engineDigest(byte[] buf, int off, int len) throws DigestException
+ {
+ if (len < digestSize)
+ throw new DigestException("partial digests not returned");
+ if (buf.length - off < digestSize)
+ throw new DigestException("insufficient space in the output buffer to store the digest");
+
+ digest.doFinal(buf, off);
+
+ return digestSize;
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java
index b89a44e..89d02b7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java
@@ -24,6 +24,19 @@
provider.addAlgorithm("Alg.Alias.KeyGenerator.HMAC/" + algorithm, mainName);
}
+ protected void addKMACAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String algorithmClassName,
+ String keyGeneratorClassName)
+ {
+ String mainName = "KMAC" + algorithm;
+
+ provider.addAlgorithm("Mac." + mainName, algorithmClassName);
+ provider.addAlgorithm("KeyGenerator." + mainName, keyGeneratorClassName);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.KMAC" + algorithm, mainName);
+ }
+
protected void addHMACAlias(
ConfigurableProvider provider,
String algorithm,
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/Haraka.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/Haraka.java
new file mode 100644
index 0000000..e281654
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/Haraka.java
@@ -0,0 +1,80 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.digest;
+
+import com.android.internal.org.bouncycastle.crypto.digests.Haraka256Digest;
+import com.android.internal.org.bouncycastle.crypto.digests.Haraka512Digest;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Haraka
+{
+ private Haraka()
+ {
+
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class Digest256
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest256()
+ {
+ super(new Haraka256Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest256 d = (Digest256)super.clone();
+ d.digest = new Haraka256Digest((Haraka256Digest)digest);
+
+ return d;
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class Digest512
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest512()
+ {
+ super(new Haraka512Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest512 d = (Digest512)super.clone();
+ d.digest = new Haraka512Digest((Haraka512Digest)digest);
+
+ return d;
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends DigestAlgorithmProvider
+ {
+ private static final String PREFIX = Haraka.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("MessageDigest.HARAKA-256", PREFIX + "$Digest256");
+ provider.addAlgorithm("MessageDigest.HARAKA-512", PREFIX + "$Digest512");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA256.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA256.java
index a7ab409..c4a06ef 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA256.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA256.java
@@ -30,14 +30,14 @@
{
public Digest()
{
- super(new SHA256Digest());
+ super(SHA256Digest.newInstance());
}
public Object clone()
throws CloneNotSupportedException
{
Digest d = (Digest)super.clone();
- d.digest = new SHA256Digest((SHA256Digest)digest);
+ d.digest = SHA256Digest.newInstance(digest);
return d;
}
@@ -51,7 +51,7 @@
{
public HashMac()
{
- super(new HMac(new SHA256Digest()));
+ super(new HMac(SHA256Digest.newInstance()));
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA512.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA512.java
index 243a306..d9844d7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA512.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA512.java
@@ -190,10 +190,16 @@
provider.addAlgorithm("MessageDigest.SHA-512/224", PREFIX + "$DigestT224");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512/224", "SHA-512/224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512224", "SHA-512/224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA-512(224)", "SHA-512/224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512(224)", "SHA-512/224");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_224, "SHA-512/224");
provider.addAlgorithm("MessageDigest.SHA-512/256", PREFIX + "$DigestT256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512/256", "SHA-512/256");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512256", "SHA-512/256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA-512(256)", "SHA-512/256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512(256)", "SHA-512/256");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_256, "SHA-512/256");
provider.addAlgorithm("Mac.OLDHMACSHA512", PREFIX + "$OldSHA512");
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/drbg/EntropyDaemon.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/drbg/EntropyDaemon.java
new file mode 100644
index 0000000..1e16d0c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/drbg/EntropyDaemon.java
@@ -0,0 +1,66 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.drbg;
+
+import java.util.LinkedList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+class EntropyDaemon
+ implements Runnable
+{
+ private static final Logger LOG = Logger.getLogger(EntropyDaemon.class.getName());
+
+ private final LinkedList<Runnable> tasks = new LinkedList<Runnable>();
+
+ public EntropyDaemon()
+ {
+ }
+
+ void addTask(Runnable task)
+ {
+ synchronized (tasks)
+ {
+ tasks.add(task);
+ }
+ }
+
+ public void run()
+ {
+ while (!Thread.currentThread().isInterrupted())
+ {
+ Runnable task;
+ synchronized (tasks)
+ {
+ task = tasks.poll();
+ }
+
+ if (task != null)
+ {
+ try
+ {
+ task.run();
+ }
+ catch (Throwable e)
+ {
+ // ignore
+ }
+ }
+ else
+ {
+ try
+ {
+ Thread.sleep(5000);
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ if (LOG.isLoggable(Level.FINE))
+ {
+ LOG.fine("entropy thread interrupted - exiting");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/BC.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/BC.java
index 1cfc616..0480ac2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/BC.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/BC.java
@@ -3,6 +3,7 @@
import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+import com.android.internal.org.bouncycastle.util.Properties;
/**
* @hide This class is not part of the Android public SDK API
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
index 6c2c25b..a699cb2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
@@ -58,6 +58,7 @@
import com.android.internal.org.bouncycastle.jce.interfaces.BCKeyStore;
import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Properties;
import com.android.internal.org.bouncycastle.util.io.Streams;
import com.android.internal.org.bouncycastle.util.io.TeeOutputStream;
@@ -398,6 +399,11 @@
{
byte[] enc = key.getEncoded();
+ if (enc == null)
+ {
+ throw new IOException("unable to store encoding of protected key");
+ }
+
if (key instanceof PrivateKey)
{
dOut.write(KEY_PRIVATE);
@@ -676,9 +682,18 @@
Certificate[] chain)
throws KeyStoreException
{
- if ((key instanceof PrivateKey) && (chain == null))
+ if ((key instanceof PrivateKey))
{
- throw new KeyStoreException("no certificate chain for private key");
+ if (chain == null)
+ {
+ throw new KeyStoreException("no certificate chain for private key");
+ }
+ if (key.getEncoded() == null)
+ {
+ // we ingore the password as the key is already protected.
+ table.put(alias, new StoreEntry(alias, new Date(), KEY, key, chain));
+ return;
+ }
}
try
@@ -1129,6 +1144,10 @@
public Version1()
{
super(1);
+ if (!Properties.isOverrideSet("com.android.internal.org.bouncycastle.bks.enable_v1"))
+ {
+ throw new IllegalStateException("BKS-V1 not enabled");
+ }
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
index 745534d..23031b0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
@@ -3,6 +3,7 @@
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
+import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -47,6 +48,7 @@
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
+import com.android.internal.org.bouncycastle.asn1.ASN1BMPString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
@@ -66,6 +68,7 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.GOST28147Parameters;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
// import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
@@ -84,9 +87,13 @@
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.DigestInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.KeyPurposeId;
import com.android.internal.org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertificate;
import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.Digest;
@@ -97,6 +104,9 @@
import com.android.internal.org.bouncycastle.jcajce.PKCS12StoreParameter;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
+// import org.bouncycastle.jcajce.BCLoadStoreParameter;
+import com.android.internal.org.bouncycastle.jcajce.provider.keystore.util.AdaptingKeyStoreSpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.keystore.util.ParameterUtil;
import com.android.internal.org.bouncycastle.jcajce.spec.PBKDF2KeySpec;
import com.android.internal.org.bouncycastle.jcajce.util.BCJcaJceHelper;
import com.android.internal.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
@@ -133,7 +143,7 @@
private static final DefaultSecretKeyProvider keySizeProvider = new DefaultSecretKeyProvider();
private IgnoresCaseHashtable keys = new IgnoresCaseHashtable();
- private Hashtable localIds = new Hashtable();
+ private IgnoresCaseHashtable localIds = new IgnoresCaseHashtable();
private IgnoresCaseHashtable certs = new IgnoresCaseHashtable();
private Hashtable chainCerts = new Hashtable();
private Hashtable keyCerts = new Hashtable();
@@ -257,6 +267,12 @@
this.random = rand;
}
+ public boolean engineProbe(InputStream stream)
+ throws IOException
+ {
+ return false;
+ }
+
public Enumeration engineAliases()
{
Hashtable tab = new Hashtable();
@@ -295,25 +311,23 @@
String alias)
throws KeyStoreException
{
- Key k = (Key)keys.remove(alias);
-
- Certificate c = (Certificate)certs.remove(alias);
-
- if (c != null)
+ Certificate cert = (Certificate)certs.remove(alias);
+ if (cert != null)
{
- chainCerts.remove(new CertId(c.getPublicKey()));
+ chainCerts.remove(new CertId(cert.getPublicKey()));
}
- if (k != null)
+ Key key = (Key)keys.remove(alias);
+ if (key != null)
{
String id = (String)localIds.remove(alias);
if (id != null)
{
- c = (Certificate)keyCerts.remove(id);
- }
- if (c != null)
- {
- chainCerts.remove(new CertId(c.getPublicKey()));
+ Certificate keyCert = (Certificate)keyCerts.remove(id);
+ if (keyCert != null)
+ {
+ chainCerts.remove(new CertId(keyCert.getPublicKey()));
+ }
}
}
}
@@ -658,7 +672,7 @@
try
{
- SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm);
+ SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm);
PBEParameterSpec defParams = new PBEParameterSpec(
pbeParams.getIV(),
pbeParams.getIterations().intValue());
@@ -708,7 +722,7 @@
throw new IOException("exception decrypting data - " + e.toString());
}
}
- else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2))
+ else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2))
{
try
{
@@ -771,6 +785,31 @@
return cipher;
}
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public void engineLoad(KeyStore.LoadStoreParameter loadStoreParameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (loadStoreParameter == null)
+ {
+ engineLoad(null, null);
+ }
+ else if (loadStoreParameter instanceof BCLoadStoreParameter)
+ {
+ BCLoadStoreParameter bcParam = (BCLoadStoreParameter)loadStoreParameter;
+
+ engineLoad(bcParam.getInputStream(), ParameterUtil.extractPassword(loadStoreParameter));
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "no support for 'param' of type " + loadStoreParameter.getClass().getName());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
public void engineLoad(
InputStream stream,
char[] password)
@@ -786,7 +825,10 @@
bufIn.mark(10);
int head = bufIn.read();
-
+ if (head < 0)
+ {
+ throw new EOFException("no data in keystore stream");
+ }
if (head != 0x30)
{
throw new IOException("stream does not represent a PKCS12 key store");
@@ -795,7 +837,7 @@
bufIn.reset();
ASN1InputStream bIn = new ASN1InputStream(bufIn);
-
+
Pfx bag;
try
{
@@ -872,7 +914,7 @@
// END Android-removed: keep v1.61 behaviour to keep backwards-compatibility
keys = new IgnoresCaseHashtable();
- localIds = new Hashtable();
+ localIds = new IgnoresCaseHashtable();
if (info.getContentType().equals(data))
{
@@ -892,86 +934,19 @@
SafeBag b = SafeBag.getInstance(seq.getObjectAt(j));
if (b.getBagId().equals(pkcs8ShroudedKeyBag))
{
- com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
- PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
-
- //
- // set the attributes on the key
- //
- String alias = null;
- ASN1OctetString localId = null;
-
- if (b.getBagAttributes() != null)
- {
- Enumeration e = b.getBagAttributes().getObjects();
- while (e.hasMoreElements())
- {
- ASN1Sequence sq = (ASN1Sequence)e.nextElement();
- ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0);
- ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
- ASN1Primitive attr = null;
-
- if (attrSet.size() > 0)
- {
- attr = (ASN1Primitive)attrSet.getObjectAt(0);
-
- if (privKey instanceof PKCS12BagAttributeCarrier)
- {
- PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
- ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
- if (existing != null)
- {
- // OK, but the value has to be the same
- if (!existing.toASN1Primitive().equals(attr))
- {
- throw new IOException(
- "attempt to add existing attribute with different value");
- }
- }
- else
- {
- bagAttr.setBagAttribute(aOid, attr);
- }
- }
- }
-
- if (aOid.equals(pkcs_9_at_friendlyName))
- {
- alias = ((DERBMPString)attr).getString();
- keys.put(alias, privKey);
- }
- else if (aOid.equals(pkcs_9_at_localKeyId))
- {
- localId = (ASN1OctetString)attr;
- }
- }
- }
-
- if (localId != null)
- {
- String name = new String(Hex.encode(localId.getOctets()));
-
- if (alias == null)
- {
- keys.put(name, privKey);
- }
- else
- {
- localIds.put(alias, name);
- }
- }
- else
- {
- unmarkedKey = true;
- keys.put("unmarked", privKey);
- }
+ unmarkedKey = processShroudedKeyBag(b, password, wrongPKCS12Zero);
}
else if (b.getBagId().equals(certBag))
{
chain.addElement(b);
}
+ else if (b.getBagId().equals(keyBag))
+ {
+ processKeyBag(b);
+ }
else
{
+ // -DM 2 System.out.println
System.out.println("extra in data " + b.getBagId());
System.out.println(ASN1Dump.dumpAsString(b));
}
@@ -987,137 +962,21 @@
for (int j = 0; j != seq.size(); j++)
{
SafeBag b = SafeBag.getInstance(seq.getObjectAt(j));
-
if (b.getBagId().equals(certBag))
{
chain.addElement(b);
}
else if (b.getBagId().equals(pkcs8ShroudedKeyBag))
{
- com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
- PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
-
- //
- // set the attributes on the key
- //
- PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
- String alias = null;
- ASN1OctetString localId = null;
-
- Enumeration e = b.getBagAttributes().getObjects();
- while (e.hasMoreElements())
- {
- ASN1Sequence sq = (ASN1Sequence)e.nextElement();
- ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0);
- ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
- ASN1Primitive attr = null;
-
- if (attrSet.size() > 0)
- {
- attr = (ASN1Primitive)attrSet.getObjectAt(0);
-
- ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
- if (existing != null)
- {
- // OK, but the value has to be the same
- if (!existing.toASN1Primitive().equals(attr))
- {
- throw new IOException(
- "attempt to add existing attribute with different value");
- }
- }
- else
- {
- bagAttr.setBagAttribute(aOid, attr);
- }
- }
-
- if (aOid.equals(pkcs_9_at_friendlyName))
- {
- alias = ((DERBMPString)attr).getString();
- keys.put(alias, privKey);
- }
- else if (aOid.equals(pkcs_9_at_localKeyId))
- {
- localId = (ASN1OctetString)attr;
- }
- }
-
- String name = new String(Hex.encode(localId.getOctets()));
-
- if (alias == null)
- {
- keys.put(name, privKey);
- }
- else
- {
- localIds.put(alias, name);
- }
+ unmarkedKey = processShroudedKeyBag(b, password, wrongPKCS12Zero);
}
else if (b.getBagId().equals(keyBag))
{
- com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue());
- PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo);
-
- //
- // set the attributes on the key
- //
- PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
- String alias = null;
- ASN1OctetString localId = null;
-
- Enumeration e = b.getBagAttributes().getObjects();
- while (e.hasMoreElements())
- {
- ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement());
- ASN1ObjectIdentifier aOid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0));
- ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1));
- ASN1Primitive attr = null;
-
- if (attrSet.size() > 0)
- {
- attr = (ASN1Primitive)attrSet.getObjectAt(0);
-
- ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
- if (existing != null)
- {
- // OK, but the value has to be the same
- if (!existing.toASN1Primitive().equals(attr))
- {
- throw new IOException(
- "attempt to add existing attribute with different value");
- }
- }
- else
- {
- bagAttr.setBagAttribute(aOid, attr);
- }
-
- if (aOid.equals(pkcs_9_at_friendlyName))
- {
- alias = ((DERBMPString)attr).getString();
- keys.put(alias, privKey);
- }
- else if (aOid.equals(pkcs_9_at_localKeyId))
- {
- localId = (ASN1OctetString)attr;
- }
- }
- }
-
- String name = new String(Hex.encode(localId.getOctets()));
-
- if (alias == null)
- {
- keys.put(name, privKey);
- }
- else
- {
- localIds.put(alias, name);
- }
+ processKeyBag(b);
}
else
{
+ // -DM 2 System.out.println
System.out.println("extra in encryptedData " + b.getBagId());
System.out.println(ASN1Dump.dumpAsString(b));
}
@@ -1125,6 +984,7 @@
}
else
{
+ // -DM 2 System.out.println
System.out.println("extra " + c[i].getContentType().getId());
System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent()));
}
@@ -1185,6 +1045,17 @@
ASN1Encodable existing = bagAttr.getBagAttribute(oid);
if (existing != null)
{
+ // we've found more than one - one might be incorrect
+ if (oid.equals(pkcs_9_at_localKeyId))
+ {
+ // -DM Hex.toHexString
+ String id = Hex.toHexString(((ASN1OctetString)attr).getOctets());
+ if (!(keys.keys.containsKey(id) || localIds.keys.containsKey(id)))
+ {
+ continue; // ignore this one - it's not valid
+ }
+ }
+
// OK, but the value has to be the same
if (!existing.toASN1Primitive().equals(attr))
{
@@ -1194,13 +1065,20 @@
}
else
{
- bagAttr.setBagAttribute(oid, attr);
+ if (attrSet.size() > 1)
+ {
+ bagAttr.setBagAttribute(oid, attrSet);
+ }
+ else
+ {
+ bagAttr.setBagAttribute(oid, attr);
+ }
}
}
if (oid.equals(pkcs_9_at_friendlyName))
{
- alias = ((DERBMPString)attr).getString();
+ alias = ((ASN1BMPString)attr).getString();
}
else if (oid.equals(pkcs_9_at_localKeyId))
{
@@ -1241,6 +1119,149 @@
}
}
+ private boolean processShroudedKeyBag(SafeBag b, char[] password, boolean wrongPKCS12Zero)
+ throws IOException
+ {
+ com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
+ PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
+
+ //
+ // set the attributes on the key
+ //
+ String alias = null;
+ ASN1OctetString localId = null;
+
+ if (b.getBagAttributes() != null)
+ {
+ Enumeration e = b.getBagAttributes().getObjects();
+ while (e.hasMoreElements())
+ {
+ ASN1Sequence sq = (ASN1Sequence)e.nextElement();
+ ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0);
+ ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
+ ASN1Primitive attr = null;
+
+ if (attrSet.size() > 0)
+ {
+ attr = (ASN1Primitive)attrSet.getObjectAt(0);
+
+ if (privKey instanceof PKCS12BagAttributeCarrier)
+ {
+ PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
+ ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
+ if (existing != null)
+ {
+ // OK, but the value has to be the same
+ if (!existing.toASN1Primitive().equals(attr))
+ {
+ throw new IOException(
+ "attempt to add existing attribute with different value");
+ }
+ }
+ else
+ {
+ bagAttr.setBagAttribute(aOid, attr);
+ }
+ }
+ }
+
+ if (aOid.equals(pkcs_9_at_friendlyName))
+ {
+ alias = ((ASN1BMPString)attr).getString();
+ keys.put(alias, privKey);
+ }
+ else if (aOid.equals(pkcs_9_at_localKeyId))
+ {
+ localId = (ASN1OctetString)attr;
+ }
+ }
+ }
+
+ if (localId != null)
+ {
+ String name = new String(Hex.encode(localId.getOctets()));
+
+ if (alias == null)
+ {
+ keys.put(name, privKey);
+ }
+ else
+ {
+ localIds.put(alias, name);
+ }
+ return false; // key properly marked
+ }
+ else
+ {
+ keys.put("unmarked", privKey);
+ return true; // key properly marked
+ }
+ }
+
+ private void processKeyBag(SafeBag b)
+ throws IOException
+ {
+ com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue());
+ PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo);
+
+ //
+ // set the attributes on the key
+ //
+ PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
+ String alias = null;
+ ASN1OctetString localId = null;
+
+ Enumeration e = b.getBagAttributes().getObjects();
+ while (e.hasMoreElements())
+ {
+ ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement());
+ ASN1ObjectIdentifier aOid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0));
+ ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1));
+ ASN1Primitive attr = null;
+
+ if (attrSet.size() > 0)
+ {
+ attr = (ASN1Primitive)attrSet.getObjectAt(0);
+
+ ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
+ if (existing != null)
+ {
+ // OK, but the value has to be the same
+ if (!existing.toASN1Primitive().equals(attr))
+ {
+ throw new IOException(
+ "attempt to add existing attribute with different value");
+ }
+ }
+ else
+ {
+ bagAttr.setBagAttribute(aOid, attr);
+ }
+
+ if (aOid.equals(pkcs_9_at_friendlyName))
+ {
+ alias = ((ASN1BMPString)attr).getString();
+ keys.put(alias, privKey);
+ }
+ else if (aOid.equals(pkcs_9_at_localKeyId))
+ {
+ localId = (ASN1OctetString)attr;
+ }
+ }
+ }
+
+ String name = new String(Hex.encode(localId.getOctets()));
+
+ if (alias == null)
+ {
+ keys.put(name, privKey);
+ }
+ else
+ {
+ localIds.put(alias, name);
+ }
+ }
+
private int validateIterationCount(BigInteger i)
{
int count = i.intValue();
@@ -1322,7 +1343,55 @@
// See CtsKeystoreTestCases:android.keystore.cts.KeyStoreTest
if (password == null)
{
- throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
+ if (password == null)
+ {
+ Enumeration cs = certs.keys();
+
+ ASN1EncodableVector certSeq = new ASN1EncodableVector();
+
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ String certId = (String)cs.nextElement();
+ Certificate cert = (Certificate)certs.get(certId);
+
+ SafeBag sBag = createSafeBag(certId, cert);
+
+ certSeq.add(sBag);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ if (useDEREncoding)
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.DER);
+ }
+ else
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.BER);
+ }
+
+ return;
+ }
+ }
+ else
+ {
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied for PKCS#12 KeyStore");
+ }
}
/*
if (keys.size() == 0)
@@ -1409,7 +1478,7 @@
//
// make sure we are using the local alias on store
//
- DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ ASN1BMPString nm = (ASN1BMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(name))
{
bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name));
@@ -1500,7 +1569,7 @@
//
// make sure we are using the local alias on store
//
- DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ ASN1BMPString nm = (ASN1BMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(name))
{
bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name));
@@ -1633,6 +1702,7 @@
}
}
+
SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
certSeq.add(sBag);
@@ -1706,7 +1776,7 @@
//
// make sure we are using the local alias on store
//
- DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ ASN1BMPString nm = (ASN1BMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(certId))
{
if (certId != null)
@@ -1750,6 +1820,43 @@
fName.add(new DERSequence(fSeq));
}
+ // Android-removed: unsupported
+ // add the trusted usage attribute - needed for Oracle key stores
+ // if (cert instanceof X509Certificate)
+ // {
+ // TBSCertificate tbsCert = TBSCertificate.getInstance(((X509Certificate)cert).getTBSCertificate());
+ // Extensions exts = tbsCert.getExtensions();
+ // if (exts != null)
+ // {
+ // Extension extUsage = exts.getExtension(Extension.extendedKeyUsage);
+ // if (extUsage != null)
+ // {
+ // ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ // // oracle trusted key usage OID.
+ // fSeq.add(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage);
+ // fSeq.add(new DERSet(ExtendedKeyUsage.getInstance(extUsage.getParsedValue()).getUsages()));
+ // fName.add(new DERSequence(fSeq));
+ // }
+ // else
+ // {
+ // ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ // fSeq.add(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage);
+ // fSeq.add(new DERSet(KeyPurposeId.anyExtendedKeyUsage));
+ // fName.add(new DERSequence(fSeq));
+ // }
+ // }
+ // else
+ // {
+ // ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ // fSeq.add(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage);
+ // fSeq.add(new DERSet(KeyPurposeId.anyExtendedKeyUsage));
+ // fName.add(new DERSequence(fSeq));
+ // }
+ // }
+
return new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
}
@@ -1757,19 +1864,19 @@
{
Set usedSet = new HashSet();
- for (Enumeration en = keys.keys(); en.hasMoreElements();)
+ for (Enumeration en = keys.keys(); en.hasMoreElements(); )
{
String alias = (String)en.nextElement();
- Certificate[] certs = engineGetCertificateChain(alias);
+ Certificate[] certs = engineGetCertificateChain(alias);
- for (int i = 0; i != certs.length; i++)
- {
- usedSet.add(certs[i]);
- }
+ for (int i = 0; i != certs.length; i++)
+ {
+ usedSet.add(certs[i]);
+ }
}
- for (Enumeration en = certs.keys(); en.hasMoreElements();)
+ for (Enumeration en = certs.keys(); en.hasMoreElements(); )
{
String alias = (String)en.nextElement();
@@ -1801,6 +1908,7 @@
return mac.doFinal();
}
+ // Android-changed: Use default provider for JCA algorithms instead of BC
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -1810,7 +1918,7 @@
public BCPKCS12KeyStore()
{
// Android-changed: Use default provider for JCA algorithms instead of BC
- // Was: super(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
+ // Was: super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC));
super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
}
}
@@ -1818,29 +1926,29 @@
// BEGIN Android-removed: Unsupported algorithms
/*
public static class BCPKCS12KeyStore3DES
- extends PKCS12KeyStoreSpi
+ extends AdaptingKeyStoreSpi
{
public BCPKCS12KeyStore3DES()
{
- super(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC);
+ super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC));
}
}
public static class DefPKCS12KeyStore
- extends PKCS12KeyStoreSpi
+ extends AdaptingKeyStoreSpi
{
public DefPKCS12KeyStore()
{
- super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
+ super(new DefaultJcaJceHelper(), new PKCS12KeyStoreSpi(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC));
}
}
public static class DefPKCS12KeyStore3DES
- extends PKCS12KeyStoreSpi
+ extends AdaptingKeyStoreSpi
{
public DefPKCS12KeyStore3DES()
{
- super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC);
+ super(new DefaultJcaJceHelper(), new PKCS12KeyStoreSpi(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC));
}
}
*/
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/util/AdaptingKeyStoreSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/util/AdaptingKeyStoreSpi.java
new file mode 100644
index 0000000..63dd613
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/util/AdaptingKeyStoreSpi.java
@@ -0,0 +1,186 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.keystore.util;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.util.Properties;
+
+/**
+ * Implements a certificate only JKS key store.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AdaptingKeyStoreSpi
+ extends KeyStoreSpi
+{
+ public static final String COMPAT_OVERRIDE = "keystore.type.compat";
+
+ private final JKSKeyStoreSpi jksStore;
+ private final KeyStoreSpi primaryStore;
+
+ private KeyStoreSpi keyStoreSpi;
+
+ public AdaptingKeyStoreSpi(JcaJceHelper helper, KeyStoreSpi primaryStore)
+ {
+ this.jksStore = new JKSKeyStoreSpi(helper);
+ this.primaryStore = primaryStore;
+ this.keyStoreSpi = primaryStore;
+ }
+
+ public boolean engineProbe(InputStream stream)
+ throws IOException
+ {
+ if (keyStoreSpi instanceof PKCS12KeyStoreSpi)
+ {
+ return ((PKCS12KeyStoreSpi)keyStoreSpi).engineProbe(stream);
+ }
+ return false;
+ }
+
+ public Key engineGetKey(String alias, char[] password)
+ throws NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ return keyStoreSpi.engineGetKey(alias, password);
+ }
+
+ public Certificate[] engineGetCertificateChain(String alias)
+ {
+ return keyStoreSpi.engineGetCertificateChain(alias);
+ }
+
+ public Certificate engineGetCertificate(String alias)
+ {
+ return keyStoreSpi.engineGetCertificate(alias);
+ }
+
+ public Date engineGetCreationDate(String alias)
+ {
+ return keyStoreSpi.engineGetCreationDate(alias);
+ }
+
+ public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
+ }
+
+ public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineSetKeyEntry(alias, key, chain);
+ }
+
+ public void engineSetCertificateEntry(String alias, Certificate cert)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineSetCertificateEntry(alias, cert);
+ }
+
+ public void engineDeleteEntry(String alias)
+ throws KeyStoreException
+ {
+ keyStoreSpi.engineDeleteEntry(alias);
+ }
+
+ public Enumeration<String> engineAliases()
+ {
+ return keyStoreSpi.engineAliases();
+ }
+
+ public boolean engineContainsAlias(String alias)
+ {
+ return keyStoreSpi.engineContainsAlias(alias);
+ }
+
+ public int engineSize()
+ {
+ return keyStoreSpi.engineSize();
+ }
+
+ public boolean engineIsKeyEntry(String alias)
+ {
+ return keyStoreSpi.engineIsKeyEntry(alias);
+ }
+
+ public boolean engineIsCertificateEntry(String alias)
+ {
+ return keyStoreSpi.engineIsCertificateEntry(alias);
+ }
+
+ public String engineGetCertificateAlias(Certificate cert)
+ {
+ return keyStoreSpi.engineGetCertificateAlias(cert);
+ }
+
+ public void engineStore(OutputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ keyStoreSpi.engineStore(stream, password);
+ }
+
+ public void engineStore(KeyStore.LoadStoreParameter parameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ keyStoreSpi.engineStore(parameter);
+ }
+
+ public void engineLoad(InputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (stream == null)
+ {
+ keyStoreSpi = primaryStore;
+ keyStoreSpi.engineLoad(null, password);
+ }
+ else
+ {
+ // the FIPS BCFKS/JKS compatibility is explicit and doesn't use the override.
+ if (Properties.isOverrideSet(COMPAT_OVERRIDE) || !(primaryStore instanceof PKCS12KeyStoreSpi))
+ {
+ if (!stream.markSupported())
+ {
+ stream = new BufferedInputStream(stream);
+ }
+
+ stream.mark(8);
+ if (jksStore.engineProbe(stream))
+ {
+ keyStoreSpi = jksStore;
+ }
+ else
+ {
+ keyStoreSpi = primaryStore;
+ }
+
+ stream.reset();
+ }
+ else
+ {
+ keyStoreSpi = primaryStore;
+ }
+
+ keyStoreSpi.engineLoad(stream, password);
+ }
+ }
+
+ public void engineLoad(KeyStore.LoadStoreParameter parameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ keyStoreSpi.engineLoad(parameter);
+ }
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/util/JKSKeyStoreSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/util/JKSKeyStoreSpi.java
new file mode 100644
index 0000000..a188742
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/util/JKSKeyStoreSpi.java
@@ -0,0 +1,428 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.keystore.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.jcajce.BCLoadStoreParameter;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.DigestFactory;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.io.Streams;
+
+/**
+ * Implements a certificate only JKS key store.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JKSKeyStoreSpi
+ extends KeyStoreSpi
+{
+ private static final String NOT_IMPLEMENTED_MESSAGE = "BC JKS store is read-only and only supports certificate entries";
+
+ private final Hashtable<String, BCJKSTrustedCertEntry> certificateEntries = new Hashtable<String, BCJKSTrustedCertEntry>();
+ private final JcaJceHelper helper;
+
+ public JKSKeyStoreSpi(JcaJceHelper helper)
+ {
+ this.helper = helper;
+ }
+
+ public boolean engineProbe(InputStream stream)
+ throws IOException
+ {
+ DataInputStream storeStream;
+ if (stream instanceof DataInputStream)
+ {
+ storeStream = (DataInputStream)stream;
+ }
+ else
+ {
+ storeStream = new DataInputStream(stream);
+ }
+
+ int magic = storeStream.readInt();
+ int storeVersion = storeStream.readInt();
+ return magic == (int)0x0000feedfeedL && (storeVersion == 1 || storeVersion == 2);
+ }
+
+ public Key engineGetKey(String alias, char[] password)
+ throws NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ return null; // by definition
+ }
+
+ public Certificate[] engineGetCertificateChain(String alias)
+ {
+ return null; // by definition
+ }
+
+ public Certificate engineGetCertificate(String alias)
+ {
+ synchronized (certificateEntries)
+ {
+ BCJKSTrustedCertEntry ent = certificateEntries.get(alias);
+ if (ent != null)
+ {
+ return ent.cert;
+ }
+ }
+ return null;
+ }
+
+ public Date engineGetCreationDate(String alias)
+ {
+ synchronized (certificateEntries)
+ {
+ BCJKSTrustedCertEntry ent = certificateEntries.get(alias);
+ if (ent != null)
+ {
+ return ent.date;
+ }
+ }
+ return null;
+ }
+
+ public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineSetCertificateEntry(String alias, Certificate cert)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineDeleteEntry(String alias)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public Enumeration<String> engineAliases()
+ {
+ synchronized (certificateEntries)
+ {
+ return certificateEntries.keys();
+ }
+ }
+
+ public boolean engineContainsAlias(String alias)
+ {
+ if (alias == null)
+ {
+ throw new NullPointerException("alias value is null");
+ }
+
+ synchronized (certificateEntries)
+ {
+ return certificateEntries.containsKey(alias);
+ }
+ }
+
+ public int engineSize()
+ {
+ return certificateEntries.size();
+ }
+
+ public boolean engineIsKeyEntry(String alias)
+ {
+ return false; // by definition
+ }
+
+ public boolean engineIsCertificateEntry(String alias)
+ {
+ synchronized (certificateEntries)
+ {
+ return certificateEntries.containsKey(alias);
+ }
+ }
+
+ public String engineGetCertificateAlias(Certificate cert)
+ {
+ synchronized (certificateEntries)
+ {
+ for (Iterator<Map.Entry<String, BCJKSTrustedCertEntry>> it = certificateEntries.entrySet().iterator(); it.hasNext(); )
+ {
+ Map.Entry<String, BCJKSTrustedCertEntry> entry = it.next();
+ if (entry.getValue().cert.equals(cert))
+ {
+ return entry.getKey();
+ }
+ }
+ return null;
+ }
+ }
+
+ public void engineStore(OutputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ throw new IOException(NOT_IMPLEMENTED_MESSAGE);
+ }
+
+ public void engineLoad(KeyStore.LoadStoreParameter loadStoreParameter)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (loadStoreParameter == null)
+ {
+ engineLoad(null, null);
+ }
+ else if (loadStoreParameter instanceof BCLoadStoreParameter)
+ {
+ BCLoadStoreParameter bcParam = (BCLoadStoreParameter)loadStoreParameter;
+
+ engineLoad(bcParam.getInputStream(), ParameterUtil.extractPassword(loadStoreParameter));
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "no support for 'param' of type " + loadStoreParameter.getClass().getName());
+ }
+ }
+
+ public void engineLoad(InputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ if (stream == null)
+ {
+ return;
+ }
+
+ ErasableByteStream storeStream = validateStream(stream, password);
+
+ synchronized (certificateEntries)
+ {
+ try
+ {
+ DataInputStream dIn = new DataInputStream(storeStream);
+
+ int magic = dIn.readInt();
+ int storeVersion = dIn.readInt();
+ if (magic == (int)0x0000feedfeedL)
+ {
+ CertificateFactory certFact = null;
+ Hashtable certFactories = null;
+
+ switch (storeVersion)
+ {
+ case 1: // all certs X.509
+ certFact = createCertFactory("X.509");
+ break;
+ case 2: // provision for format in store.
+ certFactories = new Hashtable();
+ break;
+ default:
+ throw new IllegalStateException("unable to discern store version");
+ }
+
+ int numEntries = dIn.readInt();
+ for (int t = 0; t < numEntries; t++)
+ {
+ int tag = dIn.readInt();
+ switch (tag)
+ {
+ case 1: // we can't process keys
+ throw new IOException(NOT_IMPLEMENTED_MESSAGE);
+ case 2: // certificate
+ String alias = dIn.readUTF();
+ Date date = new Date(dIn.readLong());
+
+ if (storeVersion == 2)
+ {
+ String certFormat = dIn.readUTF();
+ if (certFactories.containsKey(certFormat))
+ {
+ certFact = (CertificateFactory)certFactories.get(certFormat);
+ }
+ else
+ {
+ certFact = createCertFactory(certFormat);
+ certFactories.put(certFormat, certFact);
+ }
+ }
+
+ int l = dIn.readInt();
+ byte[] certData = new byte[l];
+ dIn.readFully(certData);
+
+ ErasableByteStream certStream = new ErasableByteStream(certData, 0, certData.length);
+ Certificate cert;
+ try
+ {
+ cert = certFact.generateCertificate(certStream);
+
+ if (certStream.available() != 0)
+ {
+ throw new IOException("password incorrect or store tampered with");
+ }
+ }
+ finally
+ {
+ certStream.erase();
+ }
+
+ certificateEntries.put(alias, new BCJKSTrustedCertEntry(date, cert));
+ break;
+ default:
+ throw new IllegalStateException("unable to discern entry type");
+ }
+ }
+ }
+
+ if (storeStream.available() != 0)
+ {
+ throw new IOException("password incorrect or store tampered with");
+ }
+ }
+ finally
+ {
+ storeStream.erase();
+ }
+ }
+ }
+
+ private CertificateFactory createCertFactory(String certFormat)
+ throws CertificateException
+ {
+ if (helper != null)
+ {
+ try
+ {
+ return helper.createCertificateFactory(certFormat);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new CertificateException(e.toString());
+ }
+ }
+ else
+ {
+ return CertificateFactory.getInstance(certFormat);
+ }
+ }
+
+ /**
+ * Process password updates the digest with the password.
+ *
+ * @param digest The digest instance.
+ * @param password The password.
+ */
+ private void addPassword(Digest digest, char[] password)
+ throws IOException
+ {
+ for (int i = 0; i < password.length; ++i)
+ {
+ digest.update((byte)(password[i] >> 8));
+ digest.update((byte)password[i]);
+ }
+
+ //
+ // This "Mighty Aphrodite" string goes all the way back to the
+ // first java betas in the mid 90's, why who knows? But see
+ // https://cryptosense.com/mighty-aphrodite-dark-secrets-of-the-java-keystore/
+ //
+ digest.update(Strings.toByteArray("Mighty Aphrodite"), 0, 16);
+ }
+
+ /**
+ * Validate password takes the checksum of the store and will either.
+ * 1. If password is null, load the store into memory, return the result.
+ * 2. If password is not null, load the store into memory, test the checksum, and if successful return
+ * a new input stream instance of the store.
+ * 3. Fail if there is a password and an invalid checksum.
+ *
+ * @param inputStream The input stream.
+ * @param password the password.
+ * @return Either the passed in input stream or a new input stream.
+ * @throws IOException
+ */
+ private ErasableByteStream validateStream(InputStream inputStream, char[] password)
+ throws IOException
+ {
+ Digest checksumCalculator = DigestFactory.getDigest("SHA-1");
+ byte[] rawStore = Streams.readAll(inputStream);
+
+ if (password != null)
+ {
+ addPassword(checksumCalculator, password);
+ checksumCalculator.update(rawStore, 0, rawStore.length - checksumCalculator.getDigestSize());
+
+ byte[] checksum = new byte[checksumCalculator.getDigestSize()];
+
+ checksumCalculator.doFinal(checksum, 0);
+
+ byte[] streamChecksum = new byte[checksum.length];
+ System.arraycopy(rawStore, rawStore.length - checksum.length, streamChecksum, 0, checksum.length);
+
+ if (!Arrays.constantTimeAreEqual(checksum, streamChecksum))
+ {
+ Arrays.fill(rawStore, (byte)0);
+ throw new IOException("password incorrect or store tampered with");
+ }
+
+ return new ErasableByteStream(rawStore, 0, rawStore.length - checksum.length);
+ }
+
+ return new ErasableByteStream(rawStore, 0, rawStore.length - checksumCalculator.getDigestSize());
+ }
+
+ /**
+ * BCJKSTrustedCertEntry is a internal container for the certificate entry.
+ */
+ private static final class BCJKSTrustedCertEntry
+ {
+ final Date date;
+ final Certificate cert;
+
+ public BCJKSTrustedCertEntry(Date date, Certificate cert)
+ {
+ this.date = date;
+ this.cert = cert;
+ }
+ }
+
+ private static final class ErasableByteStream
+ extends ByteArrayInputStream
+ {
+ public ErasableByteStream(byte[] buf, int offSet, int length)
+ {
+ super(buf, offSet, length);
+ }
+
+ public void erase()
+ {
+ // this will also erase the checksum from memory.
+ Arrays.fill(buf, (byte)0);
+ }
+ }
+
+
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/util/ParameterUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/util/ParameterUtil.java
new file mode 100644
index 0000000..f2a20c9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/util/ParameterUtil.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.keystore.util;
+
+import java.io.IOException;
+import java.security.KeyStore;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ParameterUtil
+{
+ public static char[] extractPassword(KeyStore.LoadStoreParameter bcParam)
+ throws IOException
+ {
+ KeyStore.ProtectionParameter protParam = bcParam.getProtectionParameter();
+
+ if (protParam == null)
+ {
+ return null;
+ }
+ else if (protParam instanceof KeyStore.PasswordProtection)
+ {
+ return ((KeyStore.PasswordProtection)protParam).getPassword();
+ }
+ else if (protParam instanceof KeyStore.CallbackHandlerProtection)
+ {
+ CallbackHandler handler = ((KeyStore.CallbackHandlerProtection)protParam).getCallbackHandler();
+
+ PasswordCallback passwordCallback = new PasswordCallback("password: ", false);
+
+ try
+ {
+ handler.handle(new Callback[]{passwordCallback});
+
+ return passwordCallback.getPassword();
+ }
+ catch (UnsupportedCallbackException e)
+ {
+ throw new IllegalArgumentException("PasswordCallback not recognised: " + e.getMessage(), e);
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "no support for protection parameter of type " + protParam.getClass().getName());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java
index 056faae..7daa5d2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java
@@ -19,16 +19,13 @@
import javax.crypto.NoSuchPaddingException;
// END Android-added: Needed for setting padding with GCM
import com.android.internal.org.bouncycastle.asn1.bc.BCObjectIdentifiers;
-// Android-removed: Unsupported algorithms
-// import org.bouncycastle.asn1.cms.CCMParameters;
-import com.android.internal.org.bouncycastle.asn1.cms.GCMParameters;
import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import com.android.internal.org.bouncycastle.crypto.BlockCipher;
-import com.android.internal.org.bouncycastle.crypto.BufferedBlockCipher;
import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
import com.android.internal.org.bouncycastle.crypto.Mac;
import com.android.internal.org.bouncycastle.crypto.engines.AESEngine;
@@ -43,9 +40,13 @@
import com.android.internal.org.bouncycastle.crypto.modes.CBCBlockCipher;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.modes.CCMBlockCipher;
+// import org.bouncycastle.crypto.modes.CCMModeCipher;
import com.android.internal.org.bouncycastle.crypto.modes.CFBBlockCipher;
import com.android.internal.org.bouncycastle.crypto.modes.GCMBlockCipher;
import com.android.internal.org.bouncycastle.crypto.modes.OFBBlockCipher;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.internal.asn1.cms.CCMParameters;
+import com.android.internal.org.bouncycastle.internal.asn1.cms.GCMParameters;
import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator;
@@ -78,7 +79,7 @@
private AES()
{
}
-
+
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -91,7 +92,7 @@
{
public BlockCipher get()
{
- return new AESEngine();
+ return AESEngine.newInstance();
}
});
}
@@ -101,11 +102,11 @@
* @hide This class is not part of the Android public SDK API
*/
public static class CBC
- extends BaseBlockCipher
+ extends BaseBlockCipher
{
public CBC()
{
- super(new CBCBlockCipher(new AESEngine()), 128);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), 128);
}
}
@@ -117,7 +118,7 @@
{
public CFB()
{
- super(new BufferedBlockCipher(new CFBBlockCipher(new AESEngine(), 128)), 128);
+ super(new DefaultBufferedBlockCipher(CFBBlockCipher.newInstance(AESEngine.newInstance(), 128)), 128);
}
}
@@ -129,7 +130,7 @@
{
public OFB()
{
- super(new BufferedBlockCipher(new OFBBlockCipher(new AESEngine(), 128)), 128);
+ super(new DefaultBufferedBlockCipher(new OFBBlockCipher(AESEngine.newInstance(), 128)), 128);
}
}
@@ -161,7 +162,7 @@
{
public CCM()
{
- super(new CCMBlockCipher(new AESEngine()), false, 12);
+ super(CCMBlockCipher.newInstance(AESEngine.newInstance()), false, 12);
}
}
@@ -170,7 +171,7 @@
{
public AESCMAC()
{
- super(new CMac(new AESEngine()));
+ super(new CMac(AESEngine.newInstance()));
}
}
@@ -179,7 +180,7 @@
{
public AESGMAC()
{
- super(new GMac(new GCMBlockCipher(new AESEngine())));
+ super(new GMac(GCMBlockCipher.newInstance(AESEngine.newInstance())));
}
}
@@ -194,7 +195,7 @@
private static class CCMMac
implements Mac
{
- private final CCMBlockCipher ccm = new CCMBlockCipher(new AESEngine());
+ private final CCMModeCipher ccm = CCMBlockCipher.newInstance(AESEngine.newInstance());
private int macLength = 8;
@@ -249,7 +250,7 @@
}
static public class KeyFactory
- extends BaseSecretKeyFactory
+ extends BaseSecretKeyFactory
{
public KeyFactory()
{
@@ -262,7 +263,7 @@
{
public Poly1305()
{
- super(new org.bouncycastle.crypto.macs.Poly1305(new AESEngine()));
+ super(new org.bouncycastle.crypto.macs.Poly1305(AESEngine.newInstance()));
}
}
@@ -305,7 +306,7 @@
{
public RFC3211Wrap()
{
- super(new RFC3211WrapEngine(new AESEngine()), 16);
+ super(new RFC3211WrapEngine(AESEngine.newInstance()), 16);
}
}
@@ -314,7 +315,7 @@
{
public RFC5649Wrap()
{
- super(new RFC5649WrapEngine(new AESEngine()));
+ super(new RFC5649WrapEngine(AESEngine.newInstance()));
}
}
*/
@@ -329,7 +330,7 @@
{
public PBEWithAESCBC()
{
- super(new CBCBlockCipher(new AESEngine()));
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()));
}
}
@@ -342,7 +343,7 @@
{
public PBEWithSHA1AESCBC128()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 128, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 128, 16);
}
}
@@ -354,7 +355,7 @@
{
public PBEWithSHA1AESCBC192()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 192, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 192, 16);
}
}
@@ -366,7 +367,7 @@
{
public PBEWithSHA1AESCBC256()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 256, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA1, 256, 16);
}
}
@@ -379,7 +380,7 @@
{
public PBEWithSHA256AESCBC128()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 128, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 128, 16);
}
}
@@ -391,7 +392,7 @@
{
public PBEWithSHA256AESCBC192()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 192, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 192, 16);
}
}
@@ -403,7 +404,7 @@
{
public PBEWithSHA256AESCBC256()
{
- super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 256, 16);
+ super(CBCBlockCipher.newInstance(AESEngine.newInstance()), PKCS12, SHA256, 256, 16);
}
}
@@ -472,7 +473,7 @@
super("PBEWithSHA1And128BitAES-CBC-BC", null, true, PKCS12, SHA1, 128, 128);
}
}
-
+
/**
* PBEWithSHA1And192BitAES-BC
* @hide This class is not part of the Android public SDK API
@@ -485,7 +486,7 @@
super("PBEWithSHA1And192BitAES-CBC-BC", null, true, PKCS12, SHA1, 192, 128);
}
}
-
+
/**
* PBEWithSHA1And256BitAES-BC
* @hide This class is not part of the Android public SDK API
@@ -498,7 +499,7 @@
super("PBEWithSHA1And256BitAES-CBC-BC", null, true, PKCS12, SHA1, 256, 128);
}
}
-
+
/**
* PBEWithSHA256And128BitAES-BC
* @hide This class is not part of the Android public SDK API
@@ -511,7 +512,7 @@
super("PBEWithSHA256And128BitAES-CBC-BC", null, true, PKCS12, SHA256, 128, 128);
}
}
-
+
/**
* PBEWithSHA256And192BitAES-BC
* @hide This class is not part of the Android public SDK API
@@ -524,7 +525,7 @@
super("PBEWithSHA256And192BitAES-CBC-BC", null, true, PKCS12, SHA256, 192, 128);
}
}
-
+
/**
* PBEWithSHA256And256BitAES-BC
* @hide This class is not part of the Android public SDK API
@@ -537,7 +538,7 @@
super("PBEWithSHA256And256BitAES-CBC-BC", null, true, PKCS12, SHA256, 256, 128);
}
}
-
+
/**
* PBEWithMD5And128BitAES-OpenSSL
* @hide This class is not part of the Android public SDK API
@@ -550,7 +551,7 @@
super("PBEWithMD5And128BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 128, 128);
}
}
-
+
/**
* PBEWithMD5And192BitAES-OpenSSL
* @hide This class is not part of the Android public SDK API
@@ -563,7 +564,7 @@
super("PBEWithMD5And192BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 192, 128);
}
}
-
+
/**
* PBEWithMD5And256BitAES-OpenSSL
* @hide This class is not part of the Android public SDK API
@@ -592,7 +593,7 @@
protected AlgorithmParameters engineGenerateParameters()
{
- byte[] iv = new byte[16];
+ byte[] iv = new byte[16];
if (random == null)
{
@@ -631,7 +632,7 @@
protected AlgorithmParameters engineGenerateParameters()
{
- byte[] iv = new byte[12];
+ byte[] iv = new byte[12];
if (random == null)
{
@@ -670,7 +671,7 @@
protected AlgorithmParameters engineGenerateParameters()
{
- byte[] nonce = new byte[12];
+ byte[] nonce = new byte[12];
if (random == null)
{
@@ -778,7 +779,7 @@
{
if (paramSpec == AlgorithmParameterSpec.class || GcmSpecUtil.isGcmSpec(paramSpec))
{
- if (GcmSpecUtil.gcmSpecExists())
+ if (GcmSpecUtil.gcmSpecExtractable())
{
return GcmSpecUtil.extractGcmSpec(gcmParams.toASN1Primitive());
}
@@ -865,7 +866,7 @@
{
if (paramSpec == AlgorithmParameterSpec.class || GcmSpecUtil.isGcmSpec(paramSpec))
{
- if (GcmSpecUtil.gcmSpecExists())
+ if (GcmSpecUtil.gcmSpecExtractable())
{
return GcmSpecUtil.extractGcmSpec(ccmParams.toASN1Primitive());
}
@@ -893,7 +894,7 @@
extends SymmetricAlgorithmProvider
{
private static final String PREFIX = AES.class.getName();
-
+
/**
* These three got introduced in some messages as a result of a typo in an
* early document. We don't produce anything using these OID values, but we'll
@@ -1055,31 +1056,31 @@
provider.addAlgorithm("Cipher.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC128");
provider.addAlgorithm("Cipher.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC192");
provider.addAlgorithm("Cipher.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC256");
-
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
provider.addAlgorithm("Cipher.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
provider.addAlgorithm("Cipher.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
@@ -1093,48 +1094,48 @@
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And128BitAESCBCOpenSSL");
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And192BitAESCBCOpenSSL");
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND256BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And256BitAESCBCOpenSSL");
-
+
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND128BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd128BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND192BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd192BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND256BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd256BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And128BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And192BitAESBC");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And256BitAESBC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-BC", "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-BC", "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-BC", "PBEWITHSHA256AND256BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc, "PBEWITHSHAAND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc, "PBEWITHSHAAND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc, "PBEWITHSHAAND256BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc, "PBEWITHSHA256AND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc, "PBEWITHSHA256AND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc, "PBEWITHSHA256AND256BITAES-CBC-BC");
-
+
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND192BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND256BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND128BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND192BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND256BITAES-CBC-BC", "PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND128BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND192BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND256BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND128BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND192BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND256BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC","PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC","PKCS12PBE");
-
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND128BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND192BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND256BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND128BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND192BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND256BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC", "PKCS12PBE");
+
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), "PKCS12PBE");
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java
deleted file mode 100644
index 55feea6..0000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
-
-import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.internal.org.bouncycastle.asn1.cms.GCMParameters;
-import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil;
-import com.android.internal.org.bouncycastle.util.Integers;
-
-class GcmSpecUtil
-{
- static final Class gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
-
- static boolean gcmSpecExists()
- {
- return gcmSpecClass != null;
- }
-
- static boolean isGcmSpec(AlgorithmParameterSpec paramSpec)
- {
- return gcmSpecClass != null && gcmSpecClass.isInstance(paramSpec);
- }
-
- static boolean isGcmSpec(Class paramSpecClass)
- {
- return gcmSpecClass == paramSpecClass;
- }
-
- static AlgorithmParameterSpec extractGcmSpec(ASN1Primitive spec)
- throws InvalidParameterSpecException
- {
- try
- {
- GCMParameters gcmParams = GCMParameters.getInstance(spec);
- Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
-
- return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() });
- }
- catch (NoSuchMethodException e)
- {
- throw new InvalidParameterSpecException("No constructor found!"); // should never happen
- }
- catch (Exception e)
- {
- throw new InvalidParameterSpecException("Construction failed: " + e.getMessage()); // should never happen
- }
- }
-
- static GCMParameters extractGcmParameters(AlgorithmParameterSpec paramSpec)
- throws InvalidParameterSpecException
- {
- try
- {
- Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
- Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
-
- return new GCMParameters((byte[])iv.invoke(paramSpec, new Object[0]), ((Integer)tLen.invoke(paramSpec, new Object[0])).intValue() / 8);
- }
- catch (Exception e)
- {
- throw new InvalidParameterSpecException("Cannot process GCMParameterSpec");
- }
- }
-}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
index 63824db..904febf 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
@@ -621,6 +621,15 @@
super("PBKDF2", PKCS5S2_UTF8, SM3);
}
}
+
+ public static class PBKDF2withSM3
+ extends BasePBKDF2
+ {
+ public PBKDF2withSM3()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, SM3);
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
index de35216..f7c0889 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
@@ -73,19 +73,23 @@
public String getAlgorithm()
{
+ String rv = this.algorithm;
+
checkDestroyed(this);
- return algorithm;
+ return rv;
}
public String getFormat()
{
+ checkDestroyed(this);
+
return "RAW";
}
public byte[] getEncoded()
{
- checkDestroyed(this);
+ byte[] enc;
if (param != null)
{
@@ -100,58 +104,72 @@
kParam = (KeyParameter)param;
}
- return kParam.getKey();
+ enc = kParam.getKey();
}
else
{
if (type == PBE.PKCS12)
{
- return PBEParametersGenerator.PKCS12PasswordToBytes(password);
+ enc = PBEParametersGenerator.PKCS12PasswordToBytes(password);
}
else if (type == PBE.PKCS5S2_UTF8)
{
- return PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password);
+ enc = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password);
}
else
{
- return PBEParametersGenerator.PKCS5PasswordToBytes(password);
+ enc = PBEParametersGenerator.PKCS5PasswordToBytes(password);
}
}
+
+ checkDestroyed(this);
+
+ return enc;
}
int getType()
{
+ int rv = type;
+
checkDestroyed(this);
- return type;
+ return rv;
}
int getDigest()
{
+ int rv = digest;
+
checkDestroyed(this);
- return digest;
+ return rv;
}
int getKeySize()
{
+ int rv = keySize;
+
checkDestroyed(this);
- return keySize;
+ return rv;
}
public int getIvSize()
{
+ int rv = ivSize;
+
checkDestroyed(this);
- return ivSize;
+ return rv;
}
public CipherParameters getParam()
{
+ CipherParameters rv = param;
+
checkDestroyed(this);
- return param;
+ return rv;
}
/* (non-Javadoc)
@@ -159,14 +177,16 @@
*/
public char[] getPassword()
{
+ char[] clone = Arrays.clone(password);
+
checkDestroyed(this);
- if (password == null)
+ if (clone == null)
{
throw new IllegalStateException("no password available");
}
- return Arrays.clone(password);
+ return clone;
}
/* (non-Javadoc)
@@ -174,9 +194,11 @@
*/
public byte[] getSalt()
{
+ byte[] clone = Arrays.clone(salt);
+
checkDestroyed(this);
- return Arrays.clone(salt);
+ return clone;
}
/* (non-Javadoc)
@@ -184,16 +206,20 @@
*/
public int getIterationCount()
{
+ int rv = iterationCount;
+
checkDestroyed(this);
- return iterationCount;
+ return rv;
}
public ASN1ObjectIdentifier getOID()
{
+ ASN1ObjectIdentifier rv = oid;
+
checkDestroyed(this);
- return oid;
+ return rv;
}
public void setTryWrongPKCS12Zero(boolean tryWrong)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
index 50417c7..c3d967a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
@@ -29,17 +29,20 @@
// import javax.crypto.spec.RC5ParameterSpec;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
-import com.android.internal.org.bouncycastle.asn1.cms.GCMParameters;
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.internal.org.bouncycastle.crypto.BlockCipher;
import com.android.internal.org.bouncycastle.crypto.BufferedBlockCipher;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.engines.DSTU7624Engine;
+// import org.bouncycastle.crypto.fpe.FPEEngine;
+// import org.bouncycastle.crypto.fpe.FPEFF1Engine;
+// import org.bouncycastle.crypto.fpe.FPEFF3_1Engine;
import com.android.internal.org.bouncycastle.crypto.modes.AEADBlockCipher;
import com.android.internal.org.bouncycastle.crypto.modes.AEADCipher;
import com.android.internal.org.bouncycastle.crypto.modes.CBCBlockCipher;
@@ -51,6 +54,7 @@
// import org.bouncycastle.crypto.modes.GCFBBlockCipher;
import com.android.internal.org.bouncycastle.crypto.modes.GCMBlockCipher;
// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.modes.GCMSIVBlockCipher;
// import org.bouncycastle.crypto.modes.GOFBBlockCipher;
// import org.bouncycastle.crypto.modes.KCCMBlockCipher;
// import org.bouncycastle.crypto.modes.KCTRBlockCipher;
@@ -60,6 +64,8 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher;
// import org.bouncycastle.crypto.modes.PGPCFBBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.paddings.PKCS7Padding;
+// import org.bouncycastle.crypto.params.FPEParameters;
import com.android.internal.org.bouncycastle.crypto.modes.SICBlockCipher;
import com.android.internal.org.bouncycastle.crypto.paddings.BlockCipherPadding;
import com.android.internal.org.bouncycastle.crypto.paddings.ISO10126d2Padding;
@@ -85,6 +91,8 @@
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
// import org.bouncycastle.jcajce.spec.RepeatedSecretKeySpec;
+import com.android.internal.org.bouncycastle.internal.asn1.cms.GCMParameters;
+// import org.bouncycastle.jcajce.spec.FPEParameterSpec;
import com.android.internal.org.bouncycastle.util.Arrays;
import com.android.internal.org.bouncycastle.util.Strings;
@@ -96,7 +104,6 @@
implements PBE
{
private static final int BUF_SIZE = 512;
- private static final Class gcmSpecClass = ClassUtil.loadClass(BaseBlockCipher.class, "javax.crypto.spec.GCMParameterSpec");
//
// specs we can handle.
@@ -106,7 +113,7 @@
// Android-removed: Unsupported alhorithms
// RC2ParameterSpec.class,
// RC5ParameterSpec.class,
- gcmSpecClass,
+ GcmSpecUtil.gcmSpecClass,
// Android-removed: unsupported algorithms
// GOST28147ParameterSpec.class,
IvParameterSpec.class,
@@ -170,7 +177,14 @@
AEADBlockCipher engine)
{
this.baseEngine = engine.getUnderlyingCipher();
- this.ivLength = baseEngine.getBlockSize();
+ if (engine.getAlgorithmName().indexOf("GCM") >= 0)
+ {
+ this.ivLength = 12;
+ }
+ else
+ {
+ this.ivLength = baseEngine.getBlockSize();
+ }
this.cipher = new AEADGenericBlockCipher(engine);
}
@@ -352,7 +366,7 @@
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(
- new CBCBlockCipher(baseEngine));
+ CBCBlockCipher.newInstance(baseEngine));
}
else if (modeName.startsWith("OFB"))
{
@@ -378,12 +392,12 @@
int wordSize = Integer.parseInt(modeName.substring(3));
cipher = new BufferedGenericBlockCipher(
- new CFBBlockCipher(baseEngine, wordSize));
+ CFBBlockCipher.newInstance(baseEngine, wordSize));
}
else
{
cipher = new BufferedGenericBlockCipher(
- new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
+ CFBBlockCipher.newInstance(baseEngine, 8 * baseEngine.getBlockSize()));
}
}
// BEGIN Android-removed: Unsupported modes
@@ -407,6 +421,18 @@
cipher = new BufferedGenericBlockCipher(
new OpenPGPCFBBlockCipher(baseEngine));
}
+ else if (modeName.equals("FF1"))
+ {
+ ivLength = 0;
+ cipher = new BufferedFPEBlockCipher(
+ new FPEFF1Engine(baseEngine));
+ }
+ else if (modeName.equals("FF3-1"))
+ {
+ ivLength = 0;
+ cipher = new BufferedFPEBlockCipher(
+ new FPEFF3_1Engine(baseEngine));
+ }
else if (modeName.equals("SIC"))
{
ivLength = baseEngine.getBlockSize();
@@ -415,8 +441,8 @@
throw new IllegalArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
}
fixedIv = false;
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new SICBlockCipher(baseEngine)));
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
+ SICBlockCipher.newInstance(baseEngine)));
}
*/
// END Android-removed: Unsupported modes
@@ -428,14 +454,14 @@
/*
if (baseEngine instanceof DSTU7624Engine)
{
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
new KCTRBlockCipher(baseEngine)));
}
else
{
*/
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new SICBlockCipher(baseEngine)));
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
+ SICBlockCipher.newInstance(baseEngine)));
/*
}
*/
@@ -445,13 +471,13 @@
else if (modeName.equals("GOFB"))
{
ivLength = baseEngine.getBlockSize();
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
new GOFBBlockCipher(baseEngine)));
}
else if (modeName.equals("GCFB"))
{
ivLength = baseEngine.getBlockSize();
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(
new GCFBBlockCipher(baseEngine)));
}
*/
@@ -459,7 +485,7 @@
else if (modeName.equals("CTS"))
{
ivLength = baseEngine.getBlockSize();
- cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(new CBCBlockCipher(baseEngine)));
+ cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(CBCBlockCipher.newInstance(baseEngine)));
}
else if (modeName.equals("CCM"))
{
@@ -473,7 +499,7 @@
else
{
*/
- cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine));
+ cipher = new AEADGenericBlockCipher(CCMBlockCipher.newInstance(baseEngine));
/*
}
*/
@@ -509,12 +535,13 @@
/*
if (baseEngine instanceof DSTU7624Engine)
{
+ ivLength = baseEngine.getBlockSize();
cipher = new AEADGenericBlockCipher(new KGCMBlockCipher(baseEngine));
}
else
{
*/
- cipher = new AEADGenericBlockCipher(new GCMBlockCipher(baseEngine));
+ cipher = new AEADGenericBlockCipher(GCMBlockCipher.newInstance(baseEngine));
/*
}
*/
@@ -540,7 +567,7 @@
{
if (cipher.wrapOnNoPadding())
{
- cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(cipher.getUnderlyingCipher()));
+ cipher = new BufferedGenericBlockCipher(new DefaultBufferedBlockCipher(cipher.getUnderlyingCipher()));
}
}
else if (paddingName.equals("WITHCTS") || paddingName.equals("CTSPADDING") || paddingName.equals("CS3PADDING"))
@@ -849,7 +876,7 @@
GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
param = new ParametersWithSBox(
- new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox());
+ new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSBox());
if (gost28147Param.getIV() != null && ivLength != 0)
{
@@ -922,9 +949,15 @@
ivParam = (ParametersWithIV)param;
}
}
+ else if (params instanceof FPEParameterSpec)
+ {
+ FPEParameterSpec spec = (FPEParameterSpec)params;
+
+ param = new FPEParameters((KeyParameter)param, spec.getRadixConverter(), spec.getTweak(), spec.isUsingInverseFunction());
+ }
*/
// END Android-removed: Unsupported algorithms
- else if (gcmSpecClass != null && gcmSpecClass.isInstance(params))
+ else if (GcmSpecUtil.isGcmSpec(params))
{
if (!isAEADModeName(modeName) && !(cipher instanceof AEADGenericBlockCipher))
{
@@ -1048,7 +1081,7 @@
// need to pick up IV and SBox.
GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
- param = new ParametersWithSBox(param, gost28147Param.getSbox());
+ param = new ParametersWithSBox(param, gost28147Param.getSBox());
if (gost28147Param.getIV() != null && ivLength != 0)
{
@@ -1075,7 +1108,7 @@
// need to pick up IV and SBox.
GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
- param = new ParametersWithSBox(param, gost28147Param.getSbox());
+ param = new ParametersWithSBox(param, gost28147Param.getSBox());
if (gost28147Param.getIV() != null && ivLength != 0)
{
@@ -1351,7 +1384,7 @@
BufferedGenericBlockCipher(com.android.internal.org.bouncycastle.crypto.BlockCipher cipher)
{
- this.cipher = new PaddedBufferedBlockCipher(cipher);
+ this(cipher, new PKCS7Padding());
}
BufferedGenericBlockCipher(com.android.internal.org.bouncycastle.crypto.BlockCipher cipher, BlockCipherPadding padding)
@@ -1421,6 +1454,85 @@
}
}
+ // BEGIN Android-removed: unsupported
+ // private static class BufferedFPEBlockCipher
+ // implements GenericBlockCipher
+ // {
+ // private FPEEngine cipher;
+ // private ErasableOutputStream eOut = new ErasableOutputStream();
+
+ // BufferedFPEBlockCipher(FPEEngine cipher)
+ // {
+ // this.cipher = cipher;
+ // }
+
+ // public void init(boolean forEncryption, CipherParameters params)
+ // throws IllegalArgumentException
+ // {
+ // cipher.init(forEncryption, params);
+ // }
+
+ // public boolean wrapOnNoPadding()
+ // {
+ // return false;
+ // }
+
+ // public String getAlgorithmName()
+ // {
+ // return cipher.getAlgorithmName();
+ // }
+
+ // public org.bouncycastle.crypto.BlockCipher getUnderlyingCipher()
+ // {
+ // throw new IllegalStateException("not applicable for FPE");
+ // }
+
+ // public int getOutputSize(int len)
+ // {
+ // return eOut.size() + len;
+ // }
+
+ // public int getUpdateOutputSize(int len)
+ // {
+ // return 0;
+ // }
+
+ // public void updateAAD(byte[] input, int offset, int length)
+ // {
+ // throw new UnsupportedOperationException("AAD is not supported in the current mode.");
+ // }
+
+ // public int processByte(byte in, byte[] out, int outOff)
+ // throws DataLengthException
+ // {
+ // eOut.write(in);
+
+ // return 0;
+ // }
+
+ // public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ // throws DataLengthException
+ // {
+ // eOut.write(in, inOff, len);
+
+ // return 0;
+ // }
+
+ // public int doFinal(byte[] out, int outOff)
+ // throws IllegalStateException, BadPaddingException
+ // {
+ // try
+ // {
+ // return cipher.processBlock(eOut.getBuf(), 0, eOut.size(), out, outOff);
+ // }
+ // finally
+ // {
+ // eOut.erase();
+ // }
+ // }
+ // }
+ // END Android-removed: unsupported
+
private static class AEADGenericBlockCipher
implements GenericBlockCipher
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
index c142c38..d6f08e4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
@@ -36,8 +36,6 @@
public class BaseMac
extends MacSpi implements PBE
{
- private static final Class gcmSpecClass = ClassUtil.loadClass(BaseMac.class, "javax.crypto.spec.GCMParameterSpec");
-
private Mac macEngine;
private int scheme = PKCS12;
@@ -215,7 +213,7 @@
{
param = new KeyParameter(key.getEncoded());
}
- else if (gcmSpecClass != null && gcmSpecClass.isAssignableFrom(params.getClass()))
+ else if (GcmSpecUtil.isGcmSpec(params))
{
param = GcmSpecUtil.extractAeadParameters(keyParam, params);
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java
index 5582be7..d205733 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java
@@ -27,7 +27,9 @@
{
try
{
- return Class.forName(className);
+ ClassLoader classLoader = ClassLoader.getSystemClassLoader();
+
+ return classLoader.loadClass(className);
}
catch (Exception e)
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
index 242306b..9bd37f5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
@@ -11,9 +11,9 @@
import java.security.spec.InvalidParameterSpecException;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.internal.org.bouncycastle.asn1.cms.GCMParameters;
import com.android.internal.org.bouncycastle.crypto.params.AEADParameters;
import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.internal.asn1.cms.GCMParameters;
import com.android.internal.org.bouncycastle.util.Integers;
/**
@@ -21,25 +21,48 @@
*/
public class GcmSpecUtil
{
- static final Class gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
-
- static final Method tLen;
- static final Method iv;
+ static final Class gcmSpecClass;
+ private static final Constructor constructor;
+ private static final Method tLen;
+ private static final Method iv;
static
{
+ gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
+
if (gcmSpecClass != null)
{
+ constructor = extractConstructor();
tLen = extractMethod("getTLen");
iv = extractMethod("getIV");
}
else
{
+ constructor = null;
tLen = null;
iv = null;
}
}
+ private static Constructor extractConstructor()
+ {
+ try
+ {
+ return (Constructor)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return gcmSpecClass.getConstructor(new Class[]{ Integer.TYPE, byte[].class });
+ }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ return null;
+ }
+ }
+
private static Method extractMethod(final String name)
{
try
@@ -64,6 +87,11 @@
return gcmSpecClass != null;
}
+ public static boolean gcmSpecExtractable()
+ {
+ return constructor != null;
+ }
+
public static boolean isGcmSpec(AlgorithmParameterSpec paramSpec)
{
return gcmSpecClass != null && gcmSpecClass.isInstance(paramSpec);
@@ -80,14 +108,9 @@
try
{
GCMParameters gcmParams = GCMParameters.getInstance(spec);
- Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() });
}
- catch (NoSuchMethodException e)
- {
- throw new InvalidParameterSpecException("No constructor found!"); // should never happen
- }
catch (Exception e)
{
throw new InvalidParameterSpecException("Construction failed: " + e.getMessage()); // should never happen
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
index 5255765..b93d0ca 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
@@ -15,6 +15,7 @@
import javax.crypto.spec.PBEParameterSpec;
import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
import com.android.internal.org.bouncycastle.crypto.PBEParametersGenerator;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.digests.GOST3411Digest;
@@ -107,25 +108,25 @@
{
// Android-removed: Unsupported algorithms
// case MD2:
- // generator = new PKCS5S2ParametersGenerator(new MD2Digest());
+ // generator = new PKCS5S2ParametersGenerator(new MD2Digest(CryptoServicePurpose.PRF));
// break;
case MD5:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createMD5());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createMD5PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getMD5());
break;
case SHA1:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA1());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA1PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA1());
break;
// BEGIN Android-removed: Unsupported algorithms
/*
case RIPEMD160:
- generator = new PKCS5S2ParametersGenerator(new RIPEMD160Digest());
+ generator = new PKCS5S2ParametersGenerator(new RIPEMD160Digest(CryptoServicePurpose.PRF));
break;
case TIGER:
- generator = new PKCS5S2ParametersGenerator(new TigerDigest());
+ generator = new PKCS5S2ParametersGenerator(new TigerDigest(CryptoServicePurpose.PRF));
break;
*/
// END Android-removed: Unsupported algorithms
@@ -136,36 +137,43 @@
break;
// Android-removed: Unsupported algorithms
// case GOST3411:
+ // generator = new PKCS5S2ParametersGenerator(new GOST3411Digest(CryptoServicePurpose.PRF));
+ // break;
+ // Android-removed: Unsupported algorithms
+ // case GOST3411:
// generator = new PKCS5S2ParametersGenerator(new GOST3411Digest());
// break;
case SHA224:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA224());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA224PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA224());
break;
case SHA384:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA384());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA384PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA384());
break;
case SHA512:
// Android-changed: Use Android digests
- // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA512());
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA512PRF());
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA512());
break;
// BEGIN Android-removed: Unsupported algorithms
/*
case SHA3_224:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_224());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_224PRF());
break;
case SHA3_256:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_256());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_256PRF());
break;
case SHA3_384:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_384());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_384PRF());
break;
case SHA3_512:
- generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_512());
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_512PRF());
+ break;
+ case SM3:
+ generator = new PKCS5S2ParametersGenerator(new SM3Digest(CryptoServicePurpose.PRF));
break;
case SM3:
generator = new PKCS5S2ParametersGenerator(new SM3Digest());
@@ -182,50 +190,54 @@
{
// Android-removed: Unsupported algorithms
// case MD2:
- // generator = new PKCS12ParametersGenerator(new MD2Digest());
+ // generator = new PKCS12ParametersGenerator(new MD2Digest(CryptoServicePurpose.PRF));
// break;
case MD5:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createMD5());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createMD5PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getMD5());
break;
case SHA1:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA1());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA1PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA1());
break;
// BEGIN Android-removed: Unsupported algorithms
/*
case RIPEMD160:
- generator = new PKCS12ParametersGenerator(new RIPEMD160Digest());
+ generator = new PKCS12ParametersGenerator(new RIPEMD160Digest(CryptoServicePurpose.PRF));
break;
case TIGER:
- generator = new PKCS12ParametersGenerator(new TigerDigest());
+ generator = new PKCS12ParametersGenerator(new TigerDigest(CryptoServicePurpose.PRF));
break;
*/
// END Android-removed: Unsupported algorithms
case SHA256:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA256());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA256PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA256());
break;
// Android-removed: Unsupported algorithms
// case GOST3411:
+ // generator = new PKCS12ParametersGenerator(new GOST3411Digest(CryptoServicePurpose.PRF));
+ // break;
+ // Android-removed: Unsupported algorithms
+ // case GOST3411:
// generator = new PKCS12ParametersGenerator(new GOST3411Digest());
// break;
case SHA224:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA224());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA224PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA224());
break;
case SHA384:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA384());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA384PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA384());
break;
case SHA512:
// Android-changed: Use Android digests
- // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA512());
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA512PRF());
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA512());
break;
default:
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java
index f602b3d..47ad788 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java
@@ -1,6 +1,8 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.jcajce.provider.util;
+import java.util.Map;
+
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
@@ -21,6 +23,24 @@
provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, algorithm);
}
+ protected void addSignatureAlias(
+ ConfigurableProvider provider,
+ String algorithm,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, algorithm);
+ }
+
+ protected void addSignatureAlgorithm(
+ ConfigurableProvider provider,
+ String digest,
+ String algorithm,
+ String className)
+ {
+ addSignatureAlgorithm(provider, digest, algorithm, className, null);
+ }
+
protected void addSignatureAlgorithm(
ConfigurableProvider provider,
String digest,
@@ -37,8 +57,103 @@
provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation1, mainName);
provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation2, mainName);
provider.addAlgorithm("Alg.Alias.Signature." + alias, mainName);
- provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
- provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
+ }
+ }
+
+ protected void addSignatureAlgorithm(
+ ConfigurableProvider provider,
+ String digest,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid,
+ Map<String, String> attributes)
+ {
+ String mainName = digest + "WITH" + algorithm;
+ String jdk11Variation1 = digest + "with" + algorithm;
+ String jdk11Variation2 = digest + "With" + algorithm;
+ String alias = digest + "/" + algorithm;
+
+ provider.addAlgorithm("Signature." + mainName, className);
+ provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation1, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation2, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + alias, mainName);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
+ }
+ provider.addAttributes("Signature." + mainName, attributes);
+ }
+
+ protected void addKeyPairGeneratorAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("KeyPairGenerator." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyPairGenerator." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.KeyPairGenerator.OID." + oid, algorithm);
+ }
+ }
+
+ protected void addKeyFactoryAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid,
+ AsymmetricKeyInfoConverter keyInfoConverter)
+ {
+ provider.addAlgorithm("KeyFactory." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyFactory." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.KeyFactory.OID." + oid, algorithm);
+
+ provider.addKeyInfoConverter(oid, keyInfoConverter);
+ }
+ }
+
+ protected void addKeyGeneratorAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("KeyGenerator." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyGenerator." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.OID." + oid, algorithm);
+ }
+ }
+
+ protected void addCipherAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("Cipher." + algorithm, className);
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.Cipher." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.Cipher.OID." + oid, algorithm);
+ }
+ }
+
+ protected void registerKeyFactoryOid(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name, AsymmetricKeyInfoConverter keyFactory)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyFactory." + oid, name);
+ provider.addAlgorithm("Alg.Alias.KeyFactory.OID." + oid, name);
+
+ provider.addKeyInfoConverter(oid, keyFactory);
}
protected void registerOid(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name, AsymmetricKeyInfoConverter keyFactory)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/DigestFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/DigestFactory.java
index 0a431a3..47499bf 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/DigestFactory.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/DigestFactory.java
@@ -35,6 +35,8 @@
private static Set sha3_256 = new HashSet();
private static Set sha3_384 = new HashSet();
private static Set sha3_512 = new HashSet();
+ private static Set shake128 = new HashSet();
+ private static Set shake256 = new HashSet();
*/
// END Android-removed: Unsupported algorithms
@@ -86,6 +88,18 @@
sha3_512.add("SHA3-512");
sha3_512.add(NISTObjectIdentifiers.id_sha3_512.getId());
+
+ shake128.add("SHAKE128");
+ shake128.add(NISTObjectIdentifiers.id_shake128.getId());
+
+ shake256.add("SHAKE256");
+ shake256.add(NISTObjectIdentifiers.id_shake256.getId());
+
+ oids.put("SHAKE128", NISTObjectIdentifiers.id_shake128);
+ oids.put(NISTObjectIdentifiers.id_shake128.getId(), NISTObjectIdentifiers.id_shake128);
+
+ oids.put("SHAKE256", NISTObjectIdentifiers.id_shake256);
+ oids.put(NISTObjectIdentifiers.id_shake256.getId(), NISTObjectIdentifiers.id_shake256);
*/
// END Android-removed: Unsupported algorithms
@@ -202,6 +216,14 @@
{
return org.bouncycastle.crypto.util.DigestFactory.createSHA3_512();
}
+ if (shake128.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHAKE128();
+ }
+ if (shake256.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHAKE256();
+ }
*/
// END Android-removed: Unsupported algorithms
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/FPEParameterSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/FPEParameterSpec.java
new file mode 100644
index 0000000..3aed568
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/FPEParameterSpec.java
@@ -0,0 +1,55 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.android.internal.org.bouncycastle.crypto.util.RadixConverter;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class FPEParameterSpec
+ implements AlgorithmParameterSpec
+{
+ private final RadixConverter radixConverter;
+ private final byte[] tweak;
+ private final boolean useInverse;
+
+ public FPEParameterSpec(int radix, byte[] tweak)
+ {
+ this(radix, tweak, false);
+ }
+
+ public FPEParameterSpec(int radix, byte[] tweak, boolean useInverse)
+ {
+ this(new RadixConverter(radix), tweak, useInverse);
+ }
+
+ public FPEParameterSpec(RadixConverter radixConverter, byte[] tweak, boolean useInverse)
+ {
+ this.radixConverter = radixConverter;
+ this.tweak = Arrays.clone(tweak);
+ this.useInverse = useInverse;
+ }
+
+ public int getRadix()
+ {
+ return radixConverter.getRadix();
+ }
+
+ public RadixConverter getRadixConverter()
+ {
+ return radixConverter;
+ }
+
+ public byte[] getTweak()
+ {
+ return Arrays.clone(tweak);
+ }
+
+ public boolean isUsingInverseFunction()
+ {
+ return useInverse;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java
new file mode 100644
index 0000000..3bf9bda
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/HybridValueParameterSpec.java
@@ -0,0 +1,99 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.security.auth.Destroyable;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * SP 800-56C Hybrid Value spec, to allow the secret in a key agreement to be
+ * created as "Z | T" where T is some other secret value as described in Section 2.
+ * <p>
+ * Get methods throw IllegalStateException if destroy() is called.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HybridValueParameterSpec
+ implements AlgorithmParameterSpec, Destroyable
+{
+ private final AtomicBoolean hasBeenDestroyed = new AtomicBoolean(false);
+
+ private volatile byte[] t;
+ private volatile AlgorithmParameterSpec baseSpec;
+
+ /**
+ * Create a spec with T set to t and the spec for the KDF in the agreement to baseSpec.
+ * Note: the t value is not copied.
+ *
+ * @param t a shared secret to be concatenated with the agreement's Z value.
+ * @param baseSpec the base spec for the agreements KDF.
+ */
+ public HybridValueParameterSpec(byte[] t, AlgorithmParameterSpec baseSpec)
+ {
+ this.t = t;
+ this.baseSpec = baseSpec;
+ }
+
+ /**
+ * Return a reference to the T value.
+ *
+ * @return a reference to T.
+ */
+ public byte[] getT()
+ {
+ byte[] tVal = t;
+
+ checkDestroyed();
+
+ return tVal;
+ }
+
+ /**
+ * Return the base parameter spec.
+ *
+ * @return base spec to be applied to the KDF.
+ */
+ public AlgorithmParameterSpec getBaseParameterSpec()
+ {
+ AlgorithmParameterSpec rv = this.baseSpec;
+
+ checkDestroyed();
+
+ return rv;
+ }
+
+ /**
+ * Return true if the destroy() method is called and the contents are
+ * erased.
+ *
+ * @return true if destroyed, false otherwise.
+ */
+ public boolean isDestroyed()
+ {
+ return this.hasBeenDestroyed.get();
+ }
+
+ /**
+ * Destroy this parameter spec, explicitly erasing its contents.
+ */
+ public void destroy()
+ {
+ if (!hasBeenDestroyed.getAndSet(true))
+ {
+ Arrays.clear(t);
+ this.t = null;
+ this.baseSpec = null;
+ }
+ }
+
+ private void checkDestroyed()
+ {
+ if (isDestroyed())
+ {
+ throw new IllegalStateException("spec has been destroyed");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/IESKEMParameterSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/IESKEMParameterSpec.java
new file mode 100644
index 0000000..94cf47f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/IESKEMParameterSpec.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Parameter spec for an integrated encryptor KEM, as in IEEE_Std_1609_2
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IESKEMParameterSpec
+ implements AlgorithmParameterSpec
+{
+ private final byte[] recipientInfo;
+ private final boolean usePointCompression;
+
+
+ /**
+ * Set the IESKEM parameters.
+ *
+ * @param recipientInfo recipient data.
+ */
+ public IESKEMParameterSpec(
+ byte[] recipientInfo)
+ {
+ this(recipientInfo, false);
+ }
+
+ /**
+ * Set the IESKEM parameters - specifying point compression.
+ *
+ * @param recipientInfo recipient data.
+ * @param usePointCompression use point compression on output (ignored on input).
+ */
+ public IESKEMParameterSpec(
+ byte[] recipientInfo,
+ boolean usePointCompression)
+ {
+ this.recipientInfo = Arrays.clone(recipientInfo);
+ this.usePointCompression = usePointCompression;
+ }
+
+ public byte[] getRecipientInfo()
+ {
+ return Arrays.clone(recipientInfo);
+ }
+
+ public boolean hasUsePointCompression()
+ {
+ return usePointCompression;
+ }
+}
\ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/KEMExtractSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/KEMExtractSpec.java
new file mode 100644
index 0000000..277d4e8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/KEMExtractSpec.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.security.PrivateKey;
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KEMExtractSpec
+ implements AlgorithmParameterSpec
+{
+ private final PrivateKey privateKey;
+ private final byte[] encapsulation;
+ private final String keyAlgorithmName;
+ private final int keySizeInBits;
+
+ public KEMExtractSpec(PrivateKey privateKey, byte[] encapsulation, String keyAlgorithmName)
+ {
+ this(privateKey, encapsulation, keyAlgorithmName, 256);
+ }
+
+ public KEMExtractSpec(PrivateKey privateKey, byte[] encapsulation, String keyAlgorithmName, int keySizeInBits)
+ {
+ this.privateKey = privateKey;
+ this.encapsulation = Arrays.clone(encapsulation);
+ this.keyAlgorithmName = keyAlgorithmName;
+ this.keySizeInBits = keySizeInBits;
+ }
+
+ public byte[] getEncapsulation()
+ {
+ return Arrays.clone(encapsulation);
+ }
+
+ public PrivateKey getPrivateKey()
+ {
+ return privateKey;
+ }
+
+ public String getKeyAlgorithmName()
+ {
+ return keyAlgorithmName;
+ }
+
+ public int getKeySize()
+ {
+ return keySizeInBits;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java
new file mode 100644
index 0000000..24b6693
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/KEMGenerateSpec.java
@@ -0,0 +1,43 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.security.PublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KEMGenerateSpec
+ implements AlgorithmParameterSpec
+{
+ private final PublicKey publicKey;
+ private final String keyAlgorithmName;
+ private final int keySizeInBits;
+
+ public KEMGenerateSpec(PublicKey publicKey, String keyAlgorithmName)
+ {
+ this(publicKey, keyAlgorithmName, 256);
+ }
+
+ public KEMGenerateSpec(PublicKey publicKey, String keyAlgorithmName, int keySizeInBits)
+ {
+ this.publicKey = publicKey;
+ this.keyAlgorithmName = keyAlgorithmName;
+ this.keySizeInBits = keySizeInBits;
+ }
+
+ public PublicKey getPublicKey()
+ {
+ return publicKey;
+ }
+
+ public String getKeyAlgorithmName()
+ {
+ return keyAlgorithmName;
+ }
+
+ public int getKeySize()
+ {
+ return keySizeInBits;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/RawEncodedKeySpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/RawEncodedKeySpec.java
new file mode 100644
index 0000000..c20bbd9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/RawEncodedKeySpec.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.EncodedKeySpec;
+
+/**
+ * An encoded key spec that just wraps the minimal data for a public/private key representation.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RawEncodedKeySpec
+ extends EncodedKeySpec
+{
+ /**
+ * Base constructor - just the minimal data.
+ *
+ * @param bytes the public/private key data.
+ */
+ public RawEncodedKeySpec(byte[] bytes)
+ {
+ super(bytes);
+ }
+
+ public String getFormat()
+ {
+ return "RAW";
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
index 1e37d43..c99e3be 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
@@ -12,14 +12,47 @@
implements AlgorithmParameterSpec
{
private final byte[] userKeyingMaterial;
+ private final byte[] salt;
+ /**
+ * Base constructor.
+ *
+ * @param userKeyingMaterial the bytes to be mixed in to the key agreement's KDF.
+ */
public UserKeyingMaterialSpec(byte[] userKeyingMaterial)
{
- this.userKeyingMaterial = Arrays.clone(userKeyingMaterial);
+ this(userKeyingMaterial, null);
}
+ /**
+ * Base constructor.
+ *
+ * @param userKeyingMaterial the bytes to be mixed in to the key agreement's KDF.
+ * @param salt the salt to use with the underlying KDF.
+ */
+ public UserKeyingMaterialSpec(byte[] userKeyingMaterial, byte[] salt)
+ {
+ this.userKeyingMaterial = Arrays.clone(userKeyingMaterial);
+ this.salt = Arrays.clone(salt);
+ }
+
+ /**
+ * Return a copy of the key material in this object.
+ *
+ * @return the user keying material.
+ */
public byte[] getUserKeyingMaterial()
{
return Arrays.clone(userKeyingMaterial);
}
+
+ /**
+ * Return a copy of the salt in this object.
+ *
+ * @return the KDF salt.
+ */
+ public byte[] getSalt()
+ {
+ return Arrays.clone(salt);
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ECKeyUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ECKeyUtil.java
index 4fc2ca1..c584f1b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ECKeyUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ECKeyUtil.java
@@ -12,6 +12,7 @@
import com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable;
import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParametersHolder;
import com.android.internal.org.bouncycastle.asn1.x9.X9ECPoint;
import com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves;
@@ -70,10 +71,10 @@
{
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
- X9ECParameters x9 = CustomNamedCurves.getByOID(oid);
+ X9ECParametersHolder x9 = CustomNamedCurves.getByOIDLazy(oid);
if (x9 == null)
{
- x9 = ECNamedCurveTable.getByOID(oid);
+ x9 = ECNamedCurveTable.getByOIDLazy(oid);
}
curve = x9.getCurve();
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/MessageDigestUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/MessageDigestUtils.java
index a8fe3e7..1343075 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/MessageDigestUtils.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/MessageDigestUtils.java
@@ -15,6 +15,9 @@
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+// import org.bouncycastle.asn1.DERNull;
+// import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+// import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
/**
* @hide This class is not part of the Android public SDK API
@@ -23,6 +26,9 @@
{
private static Map<ASN1ObjectIdentifier, String> digestOidMap = new HashMap<ASN1ObjectIdentifier, String>();
+ // Android-removed: Unsupported algorithms
+ // private static Map<String, AlgorithmIdentifier> digestAlgIdMap = new HashMap<String, AlgorithmIdentifier>();
+
static
{
// BEGIN Android-removed: Unsupported algorithms
@@ -37,6 +43,8 @@
digestOidMap.put(NISTObjectIdentifiers.id_sha512, "SHA-512");
// BEGIN Android-removed: Unsupported algorithms
/*
+ digestOidMap.put(NISTObjectIdentifiers.id_sha512_224, "SHA-512(224)");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha512_256, "SHA-512(256)");
digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD-128");
digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD-160");
digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD-128");
@@ -49,11 +57,51 @@
digestOidMap.put(NISTObjectIdentifiers.id_sha3_256, "SHA3-256");
digestOidMap.put(NISTObjectIdentifiers.id_sha3_384, "SHA3-384");
digestOidMap.put(NISTObjectIdentifiers.id_sha3_512, "SHA3-512");
+ digestOidMap.put(NISTObjectIdentifiers.id_shake128, "SHAKE128");
+ digestOidMap.put(NISTObjectIdentifiers.id_shake256, "SHAKE256");
digestOidMap.put(GMObjectIdentifiers.sm3, "SM3");
+ digestOidMap.put(MiscObjectIdentifiers.blake3_256, "BLAKE3-256");
+
+ digestAlgIdMap.put("SHA-1", new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE));
+ digestAlgIdMap.put("SHA-224", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224));
+ digestAlgIdMap.put("SHA224", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224));
+ digestAlgIdMap.put("SHA-256", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256));
+ digestAlgIdMap.put("SHA256", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256));
+ digestAlgIdMap.put("SHA-384", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384));
+ digestAlgIdMap.put("SHA384", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384));
+ digestAlgIdMap.put("SHA-512", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512));
+ digestAlgIdMap.put("SHA512", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512));
+ digestAlgIdMap.put("SHA3-224", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_224));
+ digestAlgIdMap.put("SHA3-256", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256));
+ digestAlgIdMap.put("SHA3-384", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_384));
+ digestAlgIdMap.put("SHA3-512", new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_512));
+ digestAlgIdMap.put("BLAKE3-256", new AlgorithmIdentifier(MiscObjectIdentifiers.blake3_256));
*/
// END Android-removed: Unsupported algorithms
}
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ * Attempt to find a standard JCA name for the digest represented by the passed in OID.
+ *
+ * @param digestName name of the digest algorithm of interest.
+ * @return an algorithm identifier representing the digest.
+ public static AlgorithmIdentifier getDigestAlgID(String digestName)
+ {
+ if (digestAlgIdMap.containsKey(digestName))
+ {
+ return (AlgorithmIdentifier)digestAlgIdMap.get(digestName);
+ }
+ throw new IllegalArgumentException("unknown digest: " + digestName);
+ }
+
+ public static AlgorithmIdentifier getDigestAlgID(String digestName)
+ {
+ throw new IllegalArgumentException("unknown digest: " + digestName);
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
/**
* Attempt to find a standard JCA name for the digest represented by the passed in OID.
*
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/ECNamedCurveTable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/ECNamedCurveTable.java
index aabfac9..9b7b7ba 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/ECNamedCurveTable.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/ECNamedCurveTable.java
@@ -23,32 +23,35 @@
public static ECNamedCurveParameterSpec getParameterSpec(
String name)
{
- X9ECParameters ecP = com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves.getByName(name);
+ ASN1ObjectIdentifier oid;
+ try
+ {
+ oid = possibleOID(name) ? new ASN1ObjectIdentifier(name) : null;
+ }
+ catch (IllegalArgumentException e)
+ {
+ oid = null;
+ }
+
+ X9ECParameters ecP;
+ if (oid != null)
+ {
+ ecP = com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves.getByOID(oid);
+ }
+ else
+ {
+ ecP = com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves.getByName(name);
+ }
+
if (ecP == null)
{
- try
+ if (oid != null)
{
- ecP = com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves.getByOID(new ASN1ObjectIdentifier(name));
+ ecP = com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable.getByOID(oid);
}
- catch (IllegalArgumentException e)
- {
- // ignore - not an oid
- }
-
- if (ecP == null)
+ else
{
ecP = com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable.getByName(name);
- if (ecP == null)
- {
- try
- {
- ecP = com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(name));
- }
- catch (IllegalArgumentException e)
- {
- // ignore - not an oid
- }
- }
}
}
@@ -75,4 +78,21 @@
{
return com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable.getNames();
}
+
+ private static boolean possibleOID(
+ String identifier)
+ {
+ if (identifier.length() < 3 || identifier.charAt(1) != '.')
+ {
+ return false;
+ }
+
+ char first = identifier.charAt(0);
+ if (first < '0' || first > '2')
+ {
+ return false;
+ }
+
+ return true;
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/netscape/NetscapeCertRequest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
index a77431f..0a06f6d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
@@ -18,6 +18,7 @@
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1IA5String;
import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
import com.android.internal.org.bouncycastle.asn1.ASN1Object;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
@@ -105,7 +106,7 @@
+ pkac.size());
}
- challenge = ((DERIA5String)pkac.getObjectAt(1)).getString();
+ challenge = ((ASN1IA5String)pkac.getObjectAt(1)).getString();
//this could be dangerous, as ASN.1 decoding/encoding
//could potentially alter the bytes
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java
index 2689da8..7b4d904 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java
@@ -13,12 +13,20 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
// import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.crypto.CryptoServiceConstraintsException;
+import com.android.internal.org.bouncycastle.crypto.CryptoServiceProperties;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicePurpose;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil;
@@ -35,6 +43,16 @@
// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSKeyFactorySpi;
// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSMTKeyFactorySpi;
// import org.bouncycastle.pqc.jcajce.provider.lms.LMSKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.bike.BIKEKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.cmce.CMCEKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.dilithium.DilithiumKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.falcon.FalconKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.hqc.HQCKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.kyber.KyberKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.ntru.NTRUKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.picnic.PicnicKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.sphincsplus.SPHINCSPlusKeyFactorySpi;
+import com.android.internal.org.bouncycastle.util.Strings;
/**
* To add the provider at runtime use:
@@ -64,7 +82,9 @@
public final class BouncyCastleProvider extends Provider
implements ConfigurableProvider
{
- private static String info = "BouncyCastle Security Provider v1.68";
+ private static final Logger LOG = Logger.getLogger(BouncyCastleProvider.class.getName());
+
+ private static String info = "BouncyCastle Security Provider v1.77";
public static final String PROVIDER_NAME = "BC";
@@ -89,17 +109,27 @@
private static final String[] SYMMETRIC_MACS =
{
// Android-removed: Unsupported algorithms
- // "SipHash", "Poly1305"
+ // "SipHash", "SipHash128", "Poly1305"
};
- private static final String[] SYMMETRIC_CIPHERS =
+ private static final CryptoServiceProperties[] SYMMETRIC_CIPHERS =
{
// Android-changed: Unsupported algorithms
- // "AES", "ARC4", "ARIA", "Blowfish", "Camellia", "CAST5", "CAST6", "ChaCha", "DES", "DESede",
- // "GOST28147", "Grainv1", "Grain128", "HC128", "HC256", "IDEA", "Noekeon", "RC2", "RC5",
- // "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Shacal2", "Skipjack", "SM4", "TEA", "Twofish", "Threefish",
- // "VMPC", "VMPCKSA3", "XTEA", "XSalsa20", "OpenSSLPBKDF", "DSTU7624", "GOST3412_2015"
- "AES", "ARC4", "Blowfish", "DES", "DESede", "RC2", "Twofish",
+ // TODO: these numbers need a bit more work, we cap at 256 bits.
+ // service("ARIA", 256), service("Camellia", 256), service("CAST5", 128),
+ // service("CAST6", 256), service("ChaCha", 128), service("GOST28147", 128),
+ // service("Grainv1", 128), service("Grain128", 128), service("HC128", 128),
+ // service("HC256", 256), service("IDEA", 128), service("Noekeon", 128),
+ // service("RC6", 256), service("Rijndael", 256), service("Salsa20", 128),
+ // service("SEED", 128), service("Serpent", 256), service("Shacal2", 128),
+ // service("Skipjack", 80), service("SM4", 128), service("TEA", 128),
+ // service("RC5", 128), service("Threefish", 128), service("VMPC", 128),
+ // service("VMPCKSA3", 128), service("XTEA", 128), service("XSalsa20", 128),
+ // service("OpenSSLPBKDF", 128), service("DSTU7624", 256), service("GOST3412_2015", 256),
+ // service("Zuc", 128)
+ service("AES", 256), service("ARC4", 20), service("Blowfish", 128),
+ service("DES", 56), service("DESede", 112), service("RC2", 128),
+ service("Twofish", 256)
};
/*
@@ -112,14 +142,14 @@
private static final String[] ASYMMETRIC_GENERIC =
{
// Android-changed: Unsupported algorithms
- // "X509", "IES", "COMPOSITE"
+ // "X509", "IES", "COMPOSITE", "EXTERNAL"
"X509"
};
private static final String[] ASYMMETRIC_CIPHERS =
{
// Android-changed: Unsupported algorithms
- // "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC"
+ // "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC", "LMS", "SPHINCSPlus", "Dilithium", "Falcon", "NTRU"
"DSA", "DH", "EC", "RSA",
};
@@ -155,6 +185,8 @@
// "DRBG"
// };
+ private Map<String, Service> serviceMap = new ConcurrentHashMap<String, Service>();
+
/**
* Construct a new provider. This should only be required when
* using runtime registration of the provider using the
@@ -162,7 +194,7 @@
*/
public BouncyCastleProvider()
{
- super(PROVIDER_NAME, 1.68, info);
+ super(PROVIDER_NAME, 1.77, info);
AccessController.doPrivileged(new PrivilegedAction()
{
@@ -228,13 +260,9 @@
put("Cipher.OLDPBEWITHSHAANDTWOFISH-CBC", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$OldPBEWithSHAAndTwofish");
// Certification Path API
- put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi");
- put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
- put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
- put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
-
if (revChkClass != null)
{
+ put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi");
put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi_8");
put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi_8");
@@ -261,33 +289,149 @@
// put("CertStore.Multi", "org.bouncycastle.jce.provider.MultiCertStoreSpi");
// put("Alg.Alias.CertStore.X509LDAP", "LDAP");
// END Android-removed: Unsupported algorithms
+
+ getService("SecureRandom", "DEFAULT"); // prime for new SecureRandom() on 1.8 JVMs.
+ }
+
+ public final Service getService(final String type, final String algorithm)
+ {
+ String upperCaseAlgName = Strings.toUpperCase(algorithm);
+ final String key = type + "." + upperCaseAlgName;
+
+ Service service = serviceMap.get(key);
+
+ if (service == null)
+ {
+ synchronized (this)
+ {
+ if (!serviceMap.containsKey(key))
+ {
+ service = AccessController.doPrivileged(new PrivilegedAction<Service>()
+ {
+ @Override
+ public Service run()
+ {
+ Service service = BouncyCastleProvider.super.getService(type, algorithm);
+ if (service == null)
+ {
+ return null;
+ }
+ serviceMap.put(key, service);
+ // remove legacy entry and swap to service entry
+ BouncyCastleProvider.super.remove(service.getType() + "." + service.getAlgorithm());
+ BouncyCastleProvider.super.putService(service);
+
+ return service;
+ }
+ });
+ }
+ else
+ {
+ service = serviceMap.get(key);
+ }
+ }
+ }
+
+ return service;
}
private void loadAlgorithms(String packageName, String[] names)
{
for (int i = 0; i != names.length; i++)
{
- Class clazz = ClassUtil.loadClass(BouncyCastleProvider.class, packageName + names[i] + "$Mappings");
+ loadServiceClass(packageName, names[i]);
+ }
+ }
- if (clazz != null)
+ private void loadAlgorithms(String packageName, CryptoServiceProperties[] services)
+ {
+ for (int i = 0; i != services.length; i++)
+ {
+ CryptoServiceProperties service = services[i];
+ try
{
- try
+ CryptoServicesRegistrar.checkConstraints(service);
+
+ loadServiceClass(packageName, service.getServiceName());
+ }
+ catch (CryptoServiceConstraintsException e)
+ {
+ if (LOG.isLoggable(Level.FINE))
{
- ((AlgorithmProvider)clazz.newInstance()).configure(this);
- }
- catch (Exception e)
- { // this should never ever happen!!
- throw new InternalError("cannot create instance of "
- + packageName + names[i] + "$Mappings : " + e);
+ LOG.fine("service for " + service.getServiceName() + " ignored due to constraints");
}
}
}
}
+ private void loadServiceClass(String packageName, String serviceName)
+ {
+ Class clazz = ClassUtil.loadClass(BouncyCastleProvider.class, packageName + serviceName + "$Mappings");
+
+ if (clazz != null)
+ {
+ try
+ {
+ ((AlgorithmProvider)clazz.newInstance()).configure(this);
+ }
+ catch (Exception e)
+ { // this should never ever happen!!
+ throw new InternalError("cannot create instance of "
+ + packageName + serviceName + "$Mappings : " + e);
+ }
+ }
+ }
// BEGIN Android-removed: Unsupported algorithms
/*
+
private void loadPQCKeys()
{
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple, new SPHINCSPlusKeyFactorySpi());
+
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_128s, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_192s, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_sha2_256s, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(new ASN1ObjectIdentifier("1.3.9999.6.4.10"), new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_128f, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_192f, new SPHINCSPlusKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.sphincsPlus_shake_256f, new SPHINCSPlusKeyFactorySpi());
+
addKeyInfoConverter(PQCObjectIdentifiers.sphincs256, new Sphincs256KeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.newHope, new NHKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.xmss, new XMSSKeyFactorySpi());
@@ -300,6 +444,37 @@
addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_I, new QTESLAKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_III, new QTESLAKeyFactorySpi());
addKeyInfoConverter(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, new LMSKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.picnic_key, new PicnicKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.falcon_512, new FalconKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.falcon_1024, new FalconKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium2, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium3, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium5, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium2_aes, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium3_aes, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.dilithium5_aes, new DilithiumKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber512, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber768, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber1024, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece348864_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece460896_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece6688128_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece6960119_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.mceliece8192128_r3, new CMCEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.bike128, new BIKEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.bike192, new BIKEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.bike256, new BIKEKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.hqc128, new HQCKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.hqc192, new HQCKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.hqc256, new HQCKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber1024, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber512_aes, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber768_aes, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.kyber1024_aes, new KyberKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhps2048509, new NTRUKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhps2048677, new NTRUKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhps4096821, new NTRUKeyFactorySpi());
+ addKeyInfoConverter(BCObjectIdentifiers.ntruhrss701, new NTRUKeyFactorySpi());
}
*/
// END Android-removed: Unsupported algorithms
@@ -327,12 +502,25 @@
put(key, value);
}
+ public void addAlgorithm(String key, String value, Map<String, String> attributes)
+ {
+ addAlgorithm(key, value);
+ addAttributes(key, attributes);
+ }
+
public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className)
{
addAlgorithm(type + "." + oid, className);
addAlgorithm(type + ".OID." + oid, className);
}
+ public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className, Map<String, String> attributes)
+ {
+ addAlgorithm(type, oid, className);
+ addAttributes(type + "." + oid, attributes);
+ addAttributes(type + ".OID." + oid, attributes);
+ }
+
public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter)
{
synchronized (keyInfoConverters)
@@ -348,6 +536,8 @@
public void addAttributes(String key, Map<String, String> attributeMap)
{
+ put(key + " ImplementedIn", "Software");
+
for (Iterator it = attributeMap.keySet().iterator(); it.hasNext();)
{
String attributeName = (String)it.next();
@@ -388,6 +578,11 @@
}
// Android-removed: see above
/*
+ if (publicKeyInfo.getAlgorithm().getAlgorithm().on(BCObjectIdentifiers.picnic_key))
+ {
+ return new PicnicKeyFactorySpi().generatePublic(publicKeyInfo);
+ }
+
AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(publicKeyInfo.getAlgorithm().getAlgorithm());
if (converter == null)
@@ -461,4 +656,42 @@
return privateProvider;
}
// END Android-added: Allow algorithms to be provided privately for BC internals.
+ private static CryptoServiceProperties service(String name, int bitsOfSecurity)
+ {
+ return new JcaCryptoService(name, bitsOfSecurity);
+ }
+
+ private static class JcaCryptoService
+ implements CryptoServiceProperties
+ {
+
+ private final String name;
+ private final int bitsOfSecurity;
+
+ JcaCryptoService(String name, int bitsOfSecurity)
+ {
+ this.name = name;
+ this.bitsOfSecurity = bitsOfSecurity;
+ }
+
+ public int bitsOfSecurity()
+ {
+ return bitsOfSecurity;
+ }
+
+ public String getServiceName()
+ {
+ return name;
+ }
+
+ public CryptoServicePurpose getPurpose()
+ {
+ return CryptoServicePurpose.ANY;
+ }
+
+ public Object getParams()
+ {
+ return null;
+ }
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
index e6aa307..931487f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
@@ -45,7 +45,6 @@
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
-import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
@@ -55,7 +54,6 @@
import com.android.internal.org.bouncycastle.asn1.ASN1String;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
-import com.android.internal.org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
import com.android.internal.org.bouncycastle.asn1.x500.style.RFC4519Style;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
@@ -69,6 +67,7 @@
import com.android.internal.org.bouncycastle.asn1.x509.GeneralNames;
import com.android.internal.org.bouncycastle.asn1.x509.PolicyInformation;
import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.internal.asn1.isismtt.ISISMTTObjectIdentifiers;
import com.android.internal.org.bouncycastle.jcajce.PKIXCRLStore;
import com.android.internal.org.bouncycastle.jcajce.PKIXCRLStoreSelector;
import com.android.internal.org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
@@ -84,7 +83,6 @@
import com.android.internal.org.bouncycastle.util.Store;
import com.android.internal.org.bouncycastle.util.StoreException;
import com.android.internal.org.bouncycastle.x509.X509AttributeCertificate;
-import com.android.internal.org.bouncycastle.x509.extension.X509ExtensionUtil;
class CertPathValidatorUtilities
{
@@ -777,7 +775,7 @@
for (int j = 0; j < genNames.length; j++)
{
- GeneralName name = genNames[i];
+ GeneralName name = genNames[j];
if (name.getTagNo() == GeneralName.uniformResourceIdentifier)
{
try
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPrivateKey.java
index 18c6e32..04f6f90 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPrivateKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPrivateKey.java
@@ -20,7 +20,7 @@
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import com.android.internal.org.bouncycastle.asn1.x9.DHDomainParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.DomainParameters;
import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
@@ -85,9 +85,9 @@
}
else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
{
- DHDomainParameters params = DHDomainParameters.getInstance(seq);
+ DomainParameters params = DomainParameters.getInstance(seq);
- this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue());
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
}
else
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPublicKey.java
index f15f091..2859a58 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPublicKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPublicKey.java
@@ -17,7 +17,7 @@
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import com.android.internal.org.bouncycastle.asn1.x9.DHDomainParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.DomainParameters;
import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import com.android.internal.org.bouncycastle.crypto.params.DHPublicKeyParameters;
import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
@@ -80,8 +80,8 @@
this.y = derY.getValue();
- ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithmId().getParameters());
- ASN1ObjectIdentifier id = info.getAlgorithmId().getAlgorithm();
+ ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithm().getParameters());
+ ASN1ObjectIdentifier id = info.getAlgorithm().getAlgorithm();
// we need the PKCS check to handle older keys marked with the X9 oid.
if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement) || isPKCSParam(seq))
@@ -99,9 +99,9 @@
}
else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
{
- DHDomainParameters params = DHDomainParameters.getInstance(seq);
+ DomainParameters params = DomainParameters.getInstance(seq);
- this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue());
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
}
else
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java
index fd3fd5c..abbe4a9 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java
@@ -7,24 +7,21 @@
import java.math.BigInteger;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.EllipticCurve;
import java.util.Enumeration;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DERNull;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
-import com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKeyStructure;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
@@ -53,7 +50,7 @@
private ECParameterSpec ecSpec;
private boolean withCompression;
- private DERBitString publicKey;
+ private ASN1BitString publicKey;
private PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
@@ -218,6 +215,7 @@
else
*/
// END Android-removed: Unsupported algorithms
+ if (ecP != null)
{
EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed());
@@ -254,7 +252,7 @@
}
else
{
- ECPrivateKeyStructure ec = new ECPrivateKeyStructure((ASN1Sequence)privKey);
+ com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey ec = com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(privKey);
this.d = ec.getKey();
this.publicKey = ec.getPublicKey();
@@ -314,15 +312,25 @@
}
PrivateKeyInfo info;
- ECPrivateKeyStructure keyStructure;
+ com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
- if (publicKey != null)
+ int orderBitLength;
+ if (ecSpec == null)
{
- keyStructure = new ECPrivateKeyStructure(this.getS(), publicKey, params);
+ orderBitLength = ECUtil.getOrderBitLength(null, null, this.getS());
}
else
{
- keyStructure = new ECPrivateKeyStructure(this.getS(), params);
+ orderBitLength = ECUtil.getOrderBitLength(null, ecSpec.getOrder(), this.getS());
+ }
+
+ if (publicKey != null)
+ {
+ keyStructure = new com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params);
+ }
+ else
+ {
+ keyStructure = new com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
}
try
@@ -434,7 +442,7 @@
}
- private DERBitString getPublicKeyDetails(JCEECPublicKey pub)
+ private ASN1BitString getPublicKeyDetails(JCEECPublicKey pub)
{
try
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java
index 46cd235..6ef9017 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java
@@ -11,11 +11,11 @@
import java.security.spec.ECPublicKeySpec;
import java.security.spec.EllipticCurve;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DERNull;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
// Android-removed: Unsupported algorithms
@@ -192,7 +192,7 @@
if (algID.getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001))
{
- DERBitString bits = info.getPublicKeyData();
+ ASN1BitString bits = info.getPublicKeyData();
ASN1OctetString key;
this.algorithm = "ECGOST3410";
@@ -273,7 +273,7 @@
ecP.getH().intValue());
}
- DERBitString bits = info.getPublicKeyData();
+ ASN1BitString bits = info.getPublicKeyData();
byte[] data = bits.getBytes();
ASN1OctetString key = new DEROctetString(data);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java
index c5fec2b..15bd316 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java
@@ -41,8 +41,9 @@
for (Iterator it = initialSet.iterator(); it.hasNext();)
{
X509CRL crl = (X509CRL)it.next();
-
- if (crl.getNextUpdate().after(validityDate))
+
+ Date nextUpdate = crl.getNextUpdate();
+ if (nextUpdate == null || nextUpdate.after(validityDate))
{
X509Certificate cert = crlselect.getCertificateChecking();
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
index 64da571..69bf752 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
@@ -2,7 +2,6 @@
package com.android.internal.org.bouncycastle.jce.provider;
import java.io.IOException;
-import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.security.cert.CertPath;
@@ -2099,18 +2098,12 @@
throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
index);
}
- if (bc != null)
+ if (bc != null && bc.isCA()) // if there is a path len constraint and we're not a CA, ignore it! (yes, it happens).
{
- BigInteger _pathLengthConstraint = bc.getPathLenConstraint();
-
- if (_pathLengthConstraint != null)
+ ASN1Integer pathLenConstraint = bc.getPathLenConstraintInteger();
+ if (pathLenConstraint != null)
{
- int _plc = _pathLengthConstraint.intValue();
-
- if (_plc < maxPathLength)
- {
- return _plc;
- }
+ maxPathLength = Math.min(maxPathLength, pathLenConstraint.intPositiveValueExact());
}
}
return maxPathLength;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLEntryObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLEntryObject.java
index 0efb820..23c975d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLEntryObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLEntryObject.java
@@ -24,7 +24,6 @@
import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
import com.android.internal.org.bouncycastle.asn1.x509.GeneralNames;
import com.android.internal.org.bouncycastle.asn1.x509.TBSCertList;
-import com.android.internal.org.bouncycastle.asn1.x509.X509Extension;
import com.android.internal.org.bouncycastle.util.Strings;
/**
@@ -288,11 +287,11 @@
buf.append(" critical(").append(ext.isCritical()).append(") ");
try
{
- if (oid.equals(X509Extension.reasonCode))
+ if (oid.equals(Extension.reasonCode))
{
buf.append(CRLReason.getInstance(ASN1Enumerated.getInstance(dIn.readObject()))).append(nl);
}
- else if (oid.equals(X509Extension.certificateIssuer))
+ else if (oid.equals(Extension.certificateIssuer))
{
buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl);
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java
index 10c90b7..d5a7949 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java
@@ -35,13 +35,13 @@
import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1IA5String;
import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1String;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
-import com.android.internal.org.bouncycastle.asn1.DERIA5String;
import com.android.internal.org.bouncycastle.asn1.DERNull;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
@@ -109,7 +109,7 @@
byte[] bytes = this.getExtensionBytes("2.5.29.15");
if (bytes != null)
{
- ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes));
+ ASN1BitString bits = ASN1BitString.getInstance(ASN1Primitive.fromByteArray(bytes));
bytes = bits.getBytes();
int length = (bytes.length * 8) - bits.getPadBits();
@@ -292,7 +292,7 @@
public boolean[] getIssuerUniqueID()
{
- DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getIssuerUniqueId();
if (id != null)
{
@@ -312,7 +312,7 @@
public boolean[] getSubjectUniqueID()
{
- DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
+ ASN1BitString id = c.getTBSCertificate().getSubjectUniqueId();
if (id != null)
{
@@ -366,26 +366,18 @@
public int getBasicConstraints()
{
- if (basicConstraints != null)
+ if (basicConstraints == null || !basicConstraints.isCA())
{
- if (basicConstraints.isCA())
- {
- if (basicConstraints.getPathLenConstraint() == null)
- {
- return Integer.MAX_VALUE;
- }
- else
- {
- return basicConstraints.getPathLenConstraint().intValue();
- }
- }
- else
- {
- return -1;
- }
+ return -1;
}
- return -1;
+ ASN1Integer pathLenConstraint = basicConstraints.getPathLenConstraintInteger();
+ if (pathLenConstraint == null)
+ {
+ return Integer.MAX_VALUE;
+ }
+
+ return pathLenConstraint.intPositiveValueExact();
}
public Collection getSubjectAlternativeNames()
@@ -711,15 +703,15 @@
}
else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
{
- buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl);
+ buf.append(new NetscapeCertType((ASN1BitString)dIn.readObject())).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
{
- buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl);
+ buf.append(new NetscapeRevocationURL((ASN1IA5String)dIn.readObject())).append(nl);
}
else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
{
- buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl);
+ buf.append(new VerisignCzagExtension((ASN1IA5String)dIn.readObject())).append(nl);
}
else
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
index 401ef67..432f5e6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
@@ -45,7 +45,7 @@
{
Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
int[] exponents = poly.getExponentsPresent();
- int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
+ int[] ks = Arrays.reverseInPlace(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
return new ECFieldF2m(poly.getDegree(), ks);
}
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java
index d936d10..8a702bb 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java
@@ -3,9 +3,14 @@
import java.math.BigInteger;
import java.security.SecureRandom;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.Random;
+import java.util.Set;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.math.Primes;
import com.android.internal.org.bouncycastle.math.ec.endo.ECEndomorphism;
import com.android.internal.org.bouncycastle.math.ec.endo.GLVEndomorphism;
import com.android.internal.org.bouncycastle.math.field.FiniteField;
@@ -13,6 +18,7 @@
import com.android.internal.org.bouncycastle.math.raw.Nat;
import com.android.internal.org.bouncycastle.util.BigIntegers;
import com.android.internal.org.bouncycastle.util.Integers;
+import com.android.internal.org.bouncycastle.util.Properties;
/**
* base class for an elliptic curve
@@ -677,6 +683,8 @@
public static class Fp extends AbstractFp
{
private static final int FP_DEFAULT_COORDS = ECCurve.COORD_JACOBIAN_MODIFIED;
+ private static final Set<BigInteger> knownQs = Collections.synchronizedSet(new HashSet<BigInteger>());
+ private static final BigIntegers.Cache validatedQs = new BigIntegers.Cache();
BigInteger q, r;
ECPoint.Fp infinity;
@@ -691,9 +699,44 @@
public Fp(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor)
{
+ this(q, a, b, order, cofactor, false);
+ }
+
+ public Fp(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor, boolean isInternal)
+ {
super(q);
- this.q = q;
+ if (isInternal)
+ {
+ this.q = q;
+ knownQs.add(q);
+ }
+ else if (knownQs.contains(q) || validatedQs.contains(q))
+ {
+ this.q = q;
+ }
+ else
+ {
+ int maxBitLength = Properties.asInteger("com.android.internal.org.bouncycastle.ec.fp_max_size", 1042); // 2 * 521
+ int certainty = Properties.asInteger("com.android.internal.org.bouncycastle.ec.fp_certainty", 100);
+
+ int qBitLength = q.bitLength();
+ if (maxBitLength < qBitLength)
+ {
+ throw new IllegalArgumentException("Fp q value out of range");
+ }
+
+ if (Primes.hasAnySmallFactors(q) || !Primes.isMRProbablePrime(
+ q, CryptoServicesRegistrar.getSecureRandom(), getNumberOfIterations(qBitLength, certainty)))
+ {
+ throw new IllegalArgumentException("Fp q value not prime");
+ }
+
+ validatedQs.add(q);
+
+ this.q = q;
+ }
+
this.r = ECFieldElement.Fp.calculateResidue(q);
this.infinity = new ECPoint.Fp(this, null, null);
@@ -750,6 +793,11 @@
public ECFieldElement fromBigInteger(BigInteger x)
{
+ if (x == null || x.signum() < 0 || x.compareTo(q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for Fp field element");
+ }
+
return new ECFieldElement.Fp(this.q, this.r, x);
}
@@ -809,32 +857,11 @@
private static FiniteField buildField(int m, int k1, int k2, int k3)
{
- if (k1 == 0)
- {
- throw new IllegalArgumentException("k1 must be > 0");
- }
+ int[] exponents = (k2 | k3) == 0
+ ? new int[]{ 0, k1, m }
+ : new int[]{ 0, k1, k2, k3, m };
- if (k2 == 0)
- {
- if (k3 != 0)
- {
- throw new IllegalArgumentException("k3 must be 0 if k2 == 0");
- }
-
- return FiniteFields.getBinaryExtensionField(new int[]{ 0, k1, m });
- }
-
- if (k2 <= k1)
- {
- throw new IllegalArgumentException("k2 must be > k1");
- }
-
- if (k3 <= k2)
- {
- throw new IllegalArgumentException("k3 must be > k2");
- }
-
- return FiniteFields.getBinaryExtensionField(new int[]{ 0, k1, k2, k3, m });
+ return FiniteFields.getBinaryExtensionField(exponents);
}
protected AbstractF2m(int m, int k1, int k2, int k3)
@@ -927,7 +954,7 @@
y = this.getB().sqrt();
}
else
- {
+ {
ECFieldElement beta = x.square().invert().multiply(this.getB()).add(this.getA()).add(x);
ECFieldElement z = solveQuadraticEquation(beta);
if (z != null)
@@ -1288,7 +1315,16 @@
public ECFieldElement fromBigInteger(BigInteger x)
{
- return new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, x);
+ if (x == null || x.signum() < 0 || x.bitLength() > m)
+ {
+ throw new IllegalArgumentException("x value invalid in F2m field element");
+ }
+
+ int[] ks = (k2 | k3) == 0
+ ? new int[]{ k1 }
+ : new int[]{ k1, k2, k3 };
+
+ return new ECFieldElement.F2m(m, ks, new LongArray(x));
}
protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
@@ -1403,4 +1439,36 @@
};
}
}
+
+ private static int getNumberOfIterations(int bits, int certainty)
+ {
+ /*
+ * NOTE: We enforce a minimum 'certainty' of 100 for bits >= 1024 (else 80). Where the
+ * certainty is higher than the FIPS 186-4 tables (C.2/C.3) cater to, extra iterations
+ * are added at the "worst case rate" for the excess.
+ */
+ if (bits >= 1536)
+ {
+ return certainty <= 100 ? 3
+ : certainty <= 128 ? 4
+ : 4 + (certainty - 128 + 1) / 2;
+ }
+ else if (bits >= 1024)
+ {
+ return certainty <= 100 ? 4
+ : certainty <= 112 ? 5
+ : 5 + (certainty - 112 + 1) / 2;
+ }
+ else if (bits >= 512)
+ {
+ return certainty <= 80 ? 5
+ : certainty <= 100 ? 7
+ : 7 + (certainty - 100 + 1) / 2;
+ }
+ else
+ {
+ return certainty <= 80 ? 40
+ : 40 + (certainty - 80 + 1) / 2;
+ }
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java
index 7e612ec..50080f8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java
@@ -120,21 +120,8 @@
return null;
}
- /**
- * @deprecated Use ECCurve.fromBigInteger to construct field elements
- */
- public Fp(BigInteger q, BigInteger x)
- {
- this(q, calculateResidue(q), x);
- }
-
Fp(BigInteger q, BigInteger r, BigInteger x)
{
- if (x == null || x.signum() < 0 || x.compareTo(q) >= 0)
- {
- throw new IllegalArgumentException("x value invalid in Fp field element");
- }
-
this.q = q;
this.r = r;
this.x = x;
@@ -626,59 +613,6 @@
*/
LongArray x;
- /**
- * Constructor for PPB.
- * @param m The exponent <code>m</code> of
- * <code>F<sub>2<sup>m</sup></sub></code>.
- * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> +
- * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
- * represents the reduction polynomial <code>f(z)</code>.
- * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> +
- * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
- * represents the reduction polynomial <code>f(z)</code>.
- * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> +
- * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
- * represents the reduction polynomial <code>f(z)</code>.
- * @param x The BigInteger representing the value of the field element.
- * @deprecated Use ECCurve.fromBigInteger to construct field elements
- */
- public F2m(
- int m,
- int k1,
- int k2,
- int k3,
- BigInteger x)
- {
- if (x == null || x.signum() < 0 || x.bitLength() > m)
- {
- throw new IllegalArgumentException("x value invalid in F2m field element");
- }
-
- if ((k2 == 0) && (k3 == 0))
- {
- this.representation = TPB;
- this.ks = new int[]{ k1 };
- }
- else
- {
- if (k2 >= k3)
- {
- throw new IllegalArgumentException(
- "k2 must be smaller than k3");
- }
- if (k2 <= 0)
- {
- throw new IllegalArgumentException(
- "k2 must be larger than 0");
- }
- this.representation = PPB;
- this.ks = new int[]{ k1, k2, k3 };
- }
-
- this.m = m;
- this.x = new LongArray(x);
- }
-
F2m(int m, int[] ks, LongArray x)
{
this.m = m;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/Tnaf.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/Tnaf.java
index f326608..95a342b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/Tnaf.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/Tnaf.java
@@ -3,6 +3,8 @@
import java.math.BigInteger;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
/**
* Class holding methods for point multiplication based on the window
* τ-adic nonadjacent form (WTNAF). The algorithms are based on the
@@ -29,20 +31,19 @@
public static final byte WIDTH = 4;
/**
- * 2<sup>4</sup>
- */
- public static final byte POW_2_WIDTH = 16;
-
- /**
* The <code>α<sub>u</sub></code>'s for <code>a=0</code> as an array
* of <code>ZTauElement</code>s.
*/
- public static final ZTauElement[] alpha0 = {
- null,
- new ZTauElement(ECConstants.ONE, ECConstants.ZERO), null,
- new ZTauElement(MINUS_THREE, MINUS_ONE), null,
- new ZTauElement(MINUS_ONE, MINUS_ONE), null,
- new ZTauElement(ECConstants.ONE, MINUS_ONE), null
+ public static final ZTauElement[] alpha0 =
+ {
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ZERO),
+ null, new ZTauElement(MINUS_THREE, MINUS_ONE),
+ null, new ZTauElement(MINUS_ONE, MINUS_ONE),
+ null, new ZTauElement(ECConstants.ONE, MINUS_ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ONE),
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ONE),
+ null, new ZTauElement(ECConstants.THREE, ECConstants.ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ZERO),
};
/**
@@ -57,11 +58,16 @@
* The <code>α<sub>u</sub></code>'s for <code>a=1</code> as an array
* of <code>ZTauElement</code>s.
*/
- public static final ZTauElement[] alpha1 = {null,
- new ZTauElement(ECConstants.ONE, ECConstants.ZERO), null,
- new ZTauElement(MINUS_THREE, ECConstants.ONE), null,
- new ZTauElement(MINUS_ONE, ECConstants.ONE), null,
- new ZTauElement(ECConstants.ONE, ECConstants.ONE), null
+ public static final ZTauElement[] alpha1 =
+ {
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ZERO),
+ null, new ZTauElement(MINUS_THREE, ECConstants.ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ONE),
+ null, new ZTauElement(ECConstants.ONE, ECConstants.ONE),
+ null, new ZTauElement(MINUS_ONE, MINUS_ONE),
+ null, new ZTauElement(ECConstants.ONE, MINUS_ONE),
+ null, new ZTauElement(ECConstants.THREE, MINUS_ONE),
+ null, new ZTauElement(MINUS_ONE, ECConstants.ZERO),
};
/**
@@ -82,31 +88,29 @@
*/
public static BigInteger norm(final byte mu, ZTauElement lambda)
{
- BigInteger norm;
-
// s1 = u^2
BigInteger s1 = lambda.u.multiply(lambda.u);
// s2 = u * v
- BigInteger s2 = lambda.u.multiply(lambda.v);
+// BigInteger s2 = lambda.u.multiply(lambda.v);
// s3 = 2 * v^2
- BigInteger s3 = lambda.v.multiply(lambda.v).shiftLeft(1);
+// BigInteger s3 = lambda.v.multiply(lambda.v).shiftLeft(1);
if (mu == 1)
{
- norm = s1.add(s2).add(s3);
+// return s1.add(s2).add(s3);
+ return lambda.v.shiftLeft(1).add(lambda.u).multiply(lambda.v).add(s1);
}
else if (mu == -1)
{
- norm = s1.subtract(s2).add(s3);
+// return s1.subtract(s2).add(s3);
+ return lambda.v.shiftLeft(1).subtract(lambda.u).multiply(lambda.v).add(s1);
}
else
{
throw new IllegalArgumentException("mu must be 1 or -1");
}
-
- return norm;
}
/**
@@ -452,10 +456,7 @@
throw new IllegalArgumentException("mu must be 1 or -1");
}
- BigInteger u0;
- BigInteger u1;
- BigInteger u2;
-
+ BigInteger u0, u1, u2;
if (doV)
{
u0 = ECConstants.TWO;
@@ -470,26 +471,18 @@
for (int i = 1; i < k; i++)
{
// u2 = mu*u1 - 2*u0;
- BigInteger s = null;
- if (mu == 1)
+ BigInteger s = u1;
+ if (mu < 0)
{
- s = u1;
+ s = s.negate();
}
- else
- {
- // mu == -1
- s = u1.negate();
- }
-
+
u2 = s.subtract(u0.shiftLeft(1));
u0 = u1;
u1 = u2;
-// System.out.println(i + ": " + u2);
-// System.out.println();
}
- BigInteger[] retVal = {u0, u1};
- return retVal;
+ return new BigInteger[]{ u0, u1 };
}
/**
@@ -520,11 +513,7 @@
BigInteger[] us = getLucas(mu, w, false);
BigInteger twoToW = ECConstants.ZERO.setBit(w);
BigInteger u1invert = us[1].modInverse(twoToW);
- BigInteger tw;
- tw = ECConstants.TWO.multiply(us[0]).multiply(u1invert).mod(twoToW);
-// System.out.println("mu = " + mu);
-// System.out.println("tw = " + tw);
- return tw;
+ return us[0].shiftLeft(1).multiply(u1invert).mod(twoToW);
}
}
@@ -543,22 +532,7 @@
throw new IllegalArgumentException("si is defined for Koblitz curves only");
}
- int m = curve.getFieldSize();
- int a = curve.getA().toBigInteger().intValue();
- byte mu = getMu(a);
- int shifts = getShiftsForCofactor(curve.getCofactor());
- int index = m + 3 - a;
- BigInteger[] ui = getLucas(mu, index, false);
- if (mu == 1)
- {
- ui[0] = ui[0].negate();
- ui[1] = ui[1].negate();
- }
-
- BigInteger dividend0 = ECConstants.ONE.add(ui[1]).shiftRight(shifts);
- BigInteger dividend1 = ECConstants.ONE.add(ui[0]).shiftRight(shifts).negate();
-
- return new BigInteger[] { dividend0, dividend1 };
+ return getSi(curve.getFieldSize(), curve.getA().toBigInteger().intValue(), curve.getCofactor());
}
public static BigInteger[] getSi(int fieldSize, int curveA, BigInteger cofactor)
@@ -609,9 +583,11 @@
* modular reduction.
* @return <code>ρ := k partmod (τ<sup>m</sup> - 1)/(τ - 1)</code>
*/
- public static ZTauElement partModReduction(BigInteger k, int m, byte a,
- BigInteger[] s, byte mu, byte c)
+ public static ZTauElement partModReduction(ECCurve.AbstractF2m curve, BigInteger k, byte a, byte mu, byte c)
{
+ int m = curve.getFieldSize();
+ BigInteger[] s = curve.getSi();
+
// d0 = s[0] + mu*s[1]; mu is either 1 or -1
BigInteger d0;
if (mu == 1)
@@ -623,20 +599,29 @@
d0 = s[0].subtract(s[1]);
}
- BigInteger[] v = getLucas(mu, m, true);
- BigInteger vm = v[1];
+ BigInteger vm;
+ if (curve.isKoblitz())
+ {
+ /*
+ * Jerome A. Solinas, "Improved Algorithms for Arithmetic on Anomalous Binary Curves", (21).
+ */
+ vm = ECConstants.ONE.shiftLeft(m).add(ECConstants.ONE).subtract(
+ curve.getOrder().multiply(curve.getCofactor()));
+ }
+ else
+ {
+ BigInteger[] v = getLucas(mu, m, true);
+ vm = v[1];
+ }
- SimpleBigDecimal lambda0 = approximateDivisionByN(
- k, s[0], vm, a, m, c);
-
- SimpleBigDecimal lambda1 = approximateDivisionByN(
- k, s[1], vm, a, m, c);
+ SimpleBigDecimal lambda0 = approximateDivisionByN(k, s[0], vm, a, m, c);
+ SimpleBigDecimal lambda1 = approximateDivisionByN(k, s[1], vm, a, m, c);
ZTauElement q = round(lambda0, lambda1, mu);
// r0 = n - d0*q0 - 2*s1*q1
BigInteger r0 = k.subtract(d0.multiply(q.u)).subtract(
- BigInteger.valueOf(2).multiply(s[1]).multiply(q.v));
+ s[1].multiply(q.v).shiftLeft(1));
// r1 = s1*q0 - s0*q1
BigInteger r1 = s[1].multiply(q.u).subtract(s[0].multiply(q.v));
@@ -655,11 +640,10 @@
public static ECPoint.AbstractF2m multiplyRTnaf(ECPoint.AbstractF2m p, BigInteger k)
{
ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m) p.getCurve();
- int m = curve.getFieldSize();
int a = curve.getA().toBigInteger().intValue();
byte mu = getMu(a);
- BigInteger[] s = curve.getSi();
- ZTauElement rho = partModReduction(k, m, (byte)a, s, mu, (byte)10);
+
+ ZTauElement rho = partModReduction(curve, k, (byte)a, mu, (byte)10);
return multiplyTnaf(p, rho);
}
@@ -676,12 +660,11 @@
public static ECPoint.AbstractF2m multiplyTnaf(ECPoint.AbstractF2m p, ZTauElement lambda)
{
ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
+ ECPoint.AbstractF2m pNeg = (ECPoint.AbstractF2m)p.negate();
byte mu = getMu(curve.getA());
byte[] u = tauAdicNaf(mu, lambda);
- ECPoint.AbstractF2m q = multiplyFromTnaf(p, u);
-
- return q;
+ return multiplyFromTnaf(p, pNeg, u);
}
/**
@@ -693,11 +676,10 @@
* @param u The the TNAF of <code>λ</code>..
* @return <code>λ * p</code>
*/
- public static ECPoint.AbstractF2m multiplyFromTnaf(ECPoint.AbstractF2m p, byte[] u)
+ public static ECPoint.AbstractF2m multiplyFromTnaf(ECPoint.AbstractF2m p, ECPoint.AbstractF2m pNeg, byte[] u)
{
ECCurve curve = p.getCurve();
ECPoint.AbstractF2m q = (ECPoint.AbstractF2m)curve.getInfinity();
- ECPoint.AbstractF2m pNeg = (ECPoint.AbstractF2m)p.negate();
int tauCount = 0;
for (int i = u.length - 1; i >= 0; i--)
{
@@ -733,10 +715,9 @@
* @return The <code>[τ]</code>-adic window NAF of
* <code>λ</code>.
*/
- public static byte[] tauAdicWNaf(byte mu, ZTauElement lambda,
- byte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha)
+ public static byte[] tauAdicWNaf(byte mu, ZTauElement lambda, int width, int tw, ZTauElement[] alpha)
{
- if (!((mu == 1) || (mu == -1)))
+ if (!(mu == 1 || mu == -1))
{
throw new IllegalArgumentException("mu must be 1 or -1");
}
@@ -752,75 +733,72 @@
// The array holding the TNAF
byte[] u = new byte[maxLength];
- // 2^(width - 1)
- BigInteger pow2wMin1 = pow2w.shiftRight(1);
+ int pow2Width = 1 << width;
+ int pow2Mask = pow2Width - 1;
+ int s = 32 - width;
// Split lambda into two BigIntegers to simplify calculations
- BigInteger r0 = lambda.u;
- BigInteger r1 = lambda.v;
- int i = 0;
+ BigInteger R0 = lambda.u;
+ BigInteger R1 = lambda.v;
+ int uPos = 0;
// while lambda <> (0, 0)
- while (!((r0.equals(ECConstants.ZERO))&&(r1.equals(ECConstants.ZERO))))
+ while (R0.bitLength() > 62 || R1.bitLength() > 62)
{
- // if r0 is odd
- if (r0.testBit(0))
+ if (R0.testBit(0))
{
- // uUnMod = r0 + r1*tw mod 2^width
- BigInteger uUnMod
- = r0.add(r1.multiply(tw)).mod(pow2w);
-
- byte uLocal;
- // if uUnMod >= 2^(width - 1)
- if (uUnMod.compareTo(pow2wMin1) >= 0)
- {
- uLocal = (byte) uUnMod.subtract(pow2w).intValue();
- }
- else
- {
- uLocal = (byte) uUnMod.intValue();
- }
- // uLocal is now in [-2^(width-1), 2^(width-1)-1]
+ int uVal = R0.intValue() + (R1.intValue() * tw);
+ int alphaPos = uVal & pow2Mask;
- u[i] = uLocal;
- boolean s = true;
- if (uLocal < 0)
- {
- s = false;
- uLocal = (byte)-uLocal;
- }
- // uLocal is now >= 0
-
- if (s)
- {
- r0 = r0.subtract(alpha[uLocal].u);
- r1 = r1.subtract(alpha[uLocal].v);
- }
- else
- {
- r0 = r0.add(alpha[uLocal].u);
- r1 = r1.add(alpha[uLocal].v);
- }
- }
- else
- {
- u[i] = 0;
+ u[uPos] = (byte)((uVal << s) >> s);
+ R0 = R0.subtract(alpha[alphaPos].u);
+ R1 = R1.subtract(alpha[alphaPos].v);
}
- BigInteger t = r0;
+ ++uPos;
+ BigInteger t = R0.shiftRight(1);
if (mu == 1)
{
- r0 = r1.add(r0.shiftRight(1));
+ R0 = R1.add(t);
}
- else
+ else // mu == -1
{
- // mu == -1
- r0 = r1.subtract(r0.shiftRight(1));
+ R0 = R1.subtract(t);
}
- r1 = t.shiftRight(1).negate();
- i++;
+ R1 = t.negate();
}
+
+ long r0_64 = BigIntegers.longValueExact(R0);
+ long r1_64 = BigIntegers.longValueExact(R1);
+
+ // while lambda <> (0, 0)
+ while ((r0_64 | r1_64) != 0L)
+ {
+ if ((r0_64 & 1L) != 0L)
+ {
+ int uVal = (int)r0_64 + ((int)r1_64 * tw);
+ int alphaPos = uVal & pow2Mask;
+
+ u[uPos] = (byte)((uVal << s) >> s);
+ r0_64 -= alpha[alphaPos].u.intValue();
+ r1_64 -= alpha[alphaPos].v.intValue();
+ }
+
+ ++uPos;
+
+ long t_64 = r0_64 >> 1;
+ if (mu == 1)
+ {
+ r0_64 = r1_64 + t_64;
+ }
+ else // mu == -1
+ {
+ r0_64 = r1_64 - t_64;
+ }
+ r1_64 = -t_64;
+ }
+
return u;
}
@@ -832,6 +810,7 @@
*/
public static ECPoint.AbstractF2m[] getPreComp(ECPoint.AbstractF2m p, byte a)
{
+ ECPoint.AbstractF2m pNeg = (ECPoint.AbstractF2m)p.negate();
byte[][] alphaTnaf = (a == 0) ? Tnaf.alpha0Tnaf : Tnaf.alpha1Tnaf;
ECPoint.AbstractF2m[] pu = new ECPoint.AbstractF2m[(alphaTnaf.length + 1) >>> 1];
@@ -840,7 +819,7 @@
int precompLen = alphaTnaf.length;
for (int i = 3; i < precompLen; i += 2)
{
- pu[i >>> 1] = Tnaf.multiplyFromTnaf(p, alphaTnaf[i]);
+ pu[i >>> 1] = Tnaf.multiplyFromTnaf(p, pNeg, alphaTnaf[i]);
}
p.getCurve().normalizeAll(pu);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafMultiplier.java
index 43308b1..0494130 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafMultiplier.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafMultiplier.java
@@ -31,12 +31,10 @@
ECPoint.AbstractF2m p = (ECPoint.AbstractF2m)point;
ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
- int m = curve.getFieldSize();
byte a = curve.getA().toBigInteger().byteValue();
byte mu = Tnaf.getMu(a);
- BigInteger[] s = curve.getSi();
- ZTauElement rho = Tnaf.partModReduction(k, m, a, s, mu, (byte)10);
+ ZTauElement rho = Tnaf.partModReduction(curve, k, a, mu, (byte)10);
return multiplyWTnaf(p, rho, a, mu);
}
@@ -57,8 +55,7 @@
BigInteger tw = Tnaf.getTw(mu, Tnaf.WIDTH);
- byte[]u = Tnaf.tauAdicWNaf(mu, lambda, Tnaf.WIDTH,
- BigInteger.valueOf(Tnaf.POW_2_WIDTH), tw, alpha);
+ byte[] u = Tnaf.tauAdicWNaf(mu, lambda, Tnaf.WIDTH, tw.intValue(), alpha);
return multiplyFromWTnaf(p, u);
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
index fd47d21..a013a24 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
@@ -102,6 +102,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ Nat256.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
{
int c = Nat256.mulAddTo(x, y, zz);
@@ -175,6 +181,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ Nat256.square(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -190,6 +202,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ Nat256.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat256.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat256.sub(x, y, z);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
index 0821894..8be290d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
@@ -150,49 +150,51 @@
return this;
}
+ int[] tt0 = Nat256.createExt();
+
int[] x2 = Nat256.create();
- SecP256K1Field.square(x1, x2);
- SecP256K1Field.multiply(x2, x1, x2);
+ SecP256K1Field.square(x1, x2, tt0);
+ SecP256K1Field.multiply(x2, x1, x2, tt0);
int[] x3 = Nat256.create();
- SecP256K1Field.square(x2, x3);
- SecP256K1Field.multiply(x3, x1, x3);
+ SecP256K1Field.square(x2, x3, tt0);
+ SecP256K1Field.multiply(x3, x1, x3, tt0);
int[] x6 = Nat256.create();
- SecP256K1Field.squareN(x3, 3, x6);
- SecP256K1Field.multiply(x6, x3, x6);
+ SecP256K1Field.squareN(x3, 3, x6, tt0);
+ SecP256K1Field.multiply(x6, x3, x6, tt0);
int[] x9 = x6;
- SecP256K1Field.squareN(x6, 3, x9);
- SecP256K1Field.multiply(x9, x3, x9);
+ SecP256K1Field.squareN(x6, 3, x9, tt0);
+ SecP256K1Field.multiply(x9, x3, x9, tt0);
int[] x11 = x9;
- SecP256K1Field.squareN(x9, 2, x11);
- SecP256K1Field.multiply(x11, x2, x11);
+ SecP256K1Field.squareN(x9, 2, x11, tt0);
+ SecP256K1Field.multiply(x11, x2, x11, tt0);
int[] x22 = Nat256.create();
- SecP256K1Field.squareN(x11, 11, x22);
- SecP256K1Field.multiply(x22, x11, x22);
+ SecP256K1Field.squareN(x11, 11, x22, tt0);
+ SecP256K1Field.multiply(x22, x11, x22, tt0);
int[] x44 = x11;
- SecP256K1Field.squareN(x22, 22, x44);
- SecP256K1Field.multiply(x44, x22, x44);
+ SecP256K1Field.squareN(x22, 22, x44, tt0);
+ SecP256K1Field.multiply(x44, x22, x44, tt0);
int[] x88 = Nat256.create();
- SecP256K1Field.squareN(x44, 44, x88);
- SecP256K1Field.multiply(x88, x44, x88);
+ SecP256K1Field.squareN(x44, 44, x88, tt0);
+ SecP256K1Field.multiply(x88, x44, x88, tt0);
int[] x176 = Nat256.create();
- SecP256K1Field.squareN(x88, 88, x176);
- SecP256K1Field.multiply(x176, x88, x176);
+ SecP256K1Field.squareN(x88, 88, x176, tt0);
+ SecP256K1Field.multiply(x176, x88, x176, tt0);
int[] x220 = x88;
- SecP256K1Field.squareN(x176, 44, x220);
- SecP256K1Field.multiply(x220, x44, x220);
+ SecP256K1Field.squareN(x176, 44, x220, tt0);
+ SecP256K1Field.multiply(x220, x44, x220, tt0);
int[] x223 = x44;
- SecP256K1Field.squareN(x220, 3, x223);
- SecP256K1Field.multiply(x223, x3, x223);
+ SecP256K1Field.squareN(x220, 3, x223, tt0);
+ SecP256K1Field.multiply(x223, x3, x223, tt0);
int[] t1 = x223;
- SecP256K1Field.squareN(t1, 23, t1);
- SecP256K1Field.multiply(t1, x22, t1);
- SecP256K1Field.squareN(t1, 6, t1);
- SecP256K1Field.multiply(t1, x2, t1);
- SecP256K1Field.squareN(t1, 2, t1);
+ SecP256K1Field.squareN(t1, 23, t1, tt0);
+ SecP256K1Field.multiply(t1, x22, t1, tt0);
+ SecP256K1Field.squareN(t1, 6, t1, tt0);
+ SecP256K1Field.multiply(t1, x2, t1, tt0);
+ SecP256K1Field.squareN(t1, 2, t1, tt0);
int[] t2 = x2;
- SecP256K1Field.square(t1, t2);
+ SecP256K1Field.square(t1, t2, tt0);
return Nat256.eq(x1, t2) ? new SecP256K1FieldElement(t1) : null;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
index 283554e..f5140d1 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
@@ -52,6 +52,7 @@
SecP256K1FieldElement Z2 = (SecP256K1FieldElement)b.getZCoord(0);
int c;
+ int[] tt0 = Nat256.createExt();
int[] tt1 = Nat256.createExt();
int[] t2 = Nat256.create();
int[] t3 = Nat256.create();
@@ -67,13 +68,13 @@
else
{
S2 = t3;
- SecP256K1Field.square(Z1.x, S2);
+ SecP256K1Field.square(Z1.x, S2, tt0);
U2 = t2;
- SecP256K1Field.multiply(S2, X2.x, U2);
+ SecP256K1Field.multiply(S2, X2.x, U2, tt0);
- SecP256K1Field.multiply(S2, Z1.x, S2);
- SecP256K1Field.multiply(S2, Y2.x, S2);
+ SecP256K1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP256K1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -86,13 +87,13 @@
else
{
S1 = t4;
- SecP256K1Field.square(Z2.x, S1);
+ SecP256K1Field.square(Z2.x, S1, tt0);
U1 = tt1;
- SecP256K1Field.multiply(S1, X1.x, U1);
+ SecP256K1Field.multiply(S1, X1.x, U1, tt0);
- SecP256K1Field.multiply(S1, Z2.x, S1);
- SecP256K1Field.multiply(S1, Y1.x, S1);
+ SecP256K1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP256K1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat256.create();
@@ -115,13 +116,13 @@
}
int[] HSquared = t3;
- SecP256K1Field.square(H, HSquared);
+ SecP256K1Field.square(H, HSquared, tt0);
int[] G = Nat256.create();
- SecP256K1Field.multiply(HSquared, H, G);
+ SecP256K1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP256K1Field.multiply(HSquared, U1, V);
+ SecP256K1Field.multiply(HSquared, U1, V, tt0);
SecP256K1Field.negate(G, G);
Nat256.mul(S1, G, tt1);
@@ -130,7 +131,7 @@
SecP256K1Field.reduce32(c, G);
SecP256K1FieldElement X3 = new SecP256K1FieldElement(t4);
- SecP256K1Field.square(R, X3.x);
+ SecP256K1Field.square(R, X3.x, tt0);
SecP256K1Field.subtract(X3.x, G, X3.x);
SecP256K1FieldElement Y3 = new SecP256K1FieldElement(G);
@@ -141,11 +142,11 @@
SecP256K1FieldElement Z3 = new SecP256K1FieldElement(H);
if (!Z1IsOne)
{
- SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP256K1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP256K1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
@@ -172,20 +173,21 @@
SecP256K1FieldElement X1 = (SecP256K1FieldElement)this.x, Z1 = (SecP256K1FieldElement)this.zs[0];
int c;
+ int[] tt0 = Nat256.createExt();
int[] Y1Squared = Nat256.create();
- SecP256K1Field.square(Y1.x, Y1Squared);
+ SecP256K1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat256.create();
- SecP256K1Field.square(Y1Squared, T);
+ SecP256K1Field.square(Y1Squared, T, tt0);
int[] M = Nat256.create();
- SecP256K1Field.square(X1.x, M);
+ SecP256K1Field.square(X1.x, M, tt0);
c = Nat256.addBothTo(M, M, M);
SecP256K1Field.reduce32(c, M);
int[] S = Y1Squared;
- SecP256K1Field.multiply(Y1Squared, X1.x, S);
+ SecP256K1Field.multiply(Y1Squared, X1.x, S, tt0);
c = Nat.shiftUpBits(8, S, 2, 0);
SecP256K1Field.reduce32(c, S);
@@ -194,20 +196,20 @@
SecP256K1Field.reduce32(c, t1);
SecP256K1FieldElement X3 = new SecP256K1FieldElement(T);
- SecP256K1Field.square(M, X3.x);
+ SecP256K1Field.square(M, X3.x, tt0);
SecP256K1Field.subtract(X3.x, S, X3.x);
SecP256K1Field.subtract(X3.x, S, X3.x);
SecP256K1FieldElement Y3 = new SecP256K1FieldElement(S);
SecP256K1Field.subtract(S, X3.x, Y3.x);
- SecP256K1Field.multiply(Y3.x, M, Y3.x);
+ SecP256K1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP256K1Field.subtract(Y3.x, t1, Y3.x);
SecP256K1FieldElement Z3 = new SecP256K1FieldElement(M);
SecP256K1Field.twice(Y1.x, Z3.x);
if (!Z1.isOne())
{
- SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP256K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
index b9cea7a..290420d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
@@ -98,6 +98,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ Nat256.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
{
int c = Nat256.mulAddTo(x, y, zz);
@@ -244,6 +250,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ Nat256.square(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -259,6 +271,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ Nat256.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat256.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat256.sub(x, y, z);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
index 3cfbea6..990a86a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
@@ -141,32 +141,33 @@
return this;
}
+ int[] tt0 = Nat256.createExt();
int[] t1 = Nat256.create();
int[] t2 = Nat256.create();
- SecP256R1Field.square(x1, t1);
- SecP256R1Field.multiply(t1, x1, t1);
+ SecP256R1Field.square(x1, t1, tt0);
+ SecP256R1Field.multiply(t1, x1, t1, tt0);
- SecP256R1Field.squareN(t1, 2, t2);
- SecP256R1Field.multiply(t2, t1, t2);
+ SecP256R1Field.squareN(t1, 2, t2, tt0);
+ SecP256R1Field.multiply(t2, t1, t2, tt0);
- SecP256R1Field.squareN(t2, 4, t1);
- SecP256R1Field.multiply(t1, t2, t1);
+ SecP256R1Field.squareN(t2, 4, t1, tt0);
+ SecP256R1Field.multiply(t1, t2, t1, tt0);
- SecP256R1Field.squareN(t1, 8, t2);
- SecP256R1Field.multiply(t2, t1, t2);
+ SecP256R1Field.squareN(t1, 8, t2, tt0);
+ SecP256R1Field.multiply(t2, t1, t2, tt0);
- SecP256R1Field.squareN(t2, 16, t1);
- SecP256R1Field.multiply(t1, t2, t1);
+ SecP256R1Field.squareN(t2, 16, t1, tt0);
+ SecP256R1Field.multiply(t1, t2, t1, tt0);
- SecP256R1Field.squareN(t1, 32, t1);
- SecP256R1Field.multiply(t1, x1, t1);
+ SecP256R1Field.squareN(t1, 32, t1, tt0);
+ SecP256R1Field.multiply(t1, x1, t1, tt0);
- SecP256R1Field.squareN(t1, 96, t1);
- SecP256R1Field.multiply(t1, x1, t1);
+ SecP256R1Field.squareN(t1, 96, t1, tt0);
+ SecP256R1Field.multiply(t1, x1, t1, tt0);
- SecP256R1Field.squareN(t1, 94, t1);
- SecP256R1Field.square(t1, t2);
+ SecP256R1Field.squareN(t1, 94, t1, tt0);
+ SecP256R1Field.square(t1, t2, tt0);
return Nat256.eq(x1, t2) ? new SecP256R1FieldElement(t1) : null;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
index 475624a..990a0ba 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
@@ -51,6 +51,7 @@
SecP256R1FieldElement Z2 = (SecP256R1FieldElement)b.getZCoord(0);
int c;
+ int[] tt0 = Nat256.createExt();
int[] tt1 = Nat256.createExt();
int[] t2 = Nat256.create();
int[] t3 = Nat256.create();
@@ -66,13 +67,13 @@
else
{
S2 = t3;
- SecP256R1Field.square(Z1.x, S2);
+ SecP256R1Field.square(Z1.x, S2, tt0);
U2 = t2;
- SecP256R1Field.multiply(S2, X2.x, U2);
+ SecP256R1Field.multiply(S2, X2.x, U2, tt0);
- SecP256R1Field.multiply(S2, Z1.x, S2);
- SecP256R1Field.multiply(S2, Y2.x, S2);
+ SecP256R1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP256R1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -85,13 +86,13 @@
else
{
S1 = t4;
- SecP256R1Field.square(Z2.x, S1);
+ SecP256R1Field.square(Z2.x, S1, tt0);
U1 = tt1;
- SecP256R1Field.multiply(S1, X1.x, U1);
+ SecP256R1Field.multiply(S1, X1.x, U1, tt0);
- SecP256R1Field.multiply(S1, Z2.x, S1);
- SecP256R1Field.multiply(S1, Y1.x, S1);
+ SecP256R1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP256R1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat256.create();
@@ -114,13 +115,13 @@
}
int[] HSquared = t3;
- SecP256R1Field.square(H, HSquared);
+ SecP256R1Field.square(H, HSquared, tt0);
int[] G = Nat256.create();
- SecP256R1Field.multiply(HSquared, H, G);
+ SecP256R1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP256R1Field.multiply(HSquared, U1, V);
+ SecP256R1Field.multiply(HSquared, U1, V, tt0);
SecP256R1Field.negate(G, G);
Nat256.mul(S1, G, tt1);
@@ -129,7 +130,7 @@
SecP256R1Field.reduce32(c, G);
SecP256R1FieldElement X3 = new SecP256R1FieldElement(t4);
- SecP256R1Field.square(R, X3.x);
+ SecP256R1Field.square(R, X3.x, tt0);
SecP256R1Field.subtract(X3.x, G, X3.x);
SecP256R1FieldElement Y3 = new SecP256R1FieldElement(G);
@@ -140,11 +141,11 @@
SecP256R1FieldElement Z3 = new SecP256R1FieldElement(H);
if (!Z1IsOne)
{
- SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP256R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP256R1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
@@ -170,14 +171,15 @@
SecP256R1FieldElement X1 = (SecP256R1FieldElement)this.x, Z1 = (SecP256R1FieldElement)this.zs[0];
int c;
+ int[] tt0 = Nat256.createExt();
int[] t1 = Nat256.create();
int[] t2 = Nat256.create();
int[] Y1Squared = Nat256.create();
- SecP256R1Field.square(Y1.x, Y1Squared);
+ SecP256R1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat256.create();
- SecP256R1Field.square(Y1Squared, T);
+ SecP256R1Field.square(Y1Squared, T, tt0);
boolean Z1IsOne = Z1.isOne();
@@ -185,19 +187,19 @@
if (!Z1IsOne)
{
Z1Squared = t2;
- SecP256R1Field.square(Z1.x, Z1Squared);
+ SecP256R1Field.square(Z1.x, Z1Squared, tt0);
}
SecP256R1Field.subtract(X1.x, Z1Squared, t1);
int[] M = t2;
SecP256R1Field.add(X1.x, Z1Squared, M);
- SecP256R1Field.multiply(M, t1, M);
+ SecP256R1Field.multiply(M, t1, M, tt0);
c = Nat256.addBothTo(M, M, M);
SecP256R1Field.reduce32(c, M);
int[] S = Y1Squared;
- SecP256R1Field.multiply(Y1Squared, X1.x, S);
+ SecP256R1Field.multiply(Y1Squared, X1.x, S, tt0);
c = Nat.shiftUpBits(8, S, 2, 0);
SecP256R1Field.reduce32(c, S);
@@ -205,20 +207,20 @@
SecP256R1Field.reduce32(c, t1);
SecP256R1FieldElement X3 = new SecP256R1FieldElement(T);
- SecP256R1Field.square(M, X3.x);
+ SecP256R1Field.square(M, X3.x, tt0);
SecP256R1Field.subtract(X3.x, S, X3.x);
SecP256R1Field.subtract(X3.x, S, X3.x);
SecP256R1FieldElement Y3 = new SecP256R1FieldElement(S);
SecP256R1Field.subtract(S, X3.x, Y3.x);
- SecP256R1Field.multiply(Y3.x, M, Y3.x);
+ SecP256R1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP256R1Field.subtract(Y3.x, t1, Y3.x);
SecP256R1FieldElement Z3 = new SecP256R1FieldElement(M);
SecP256R1Field.twice(Y1.x, Z3.x);
if (!Z1IsOne)
{
- SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP256R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
index c95f759..25e40ab 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
@@ -104,6 +104,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ Nat384.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void negate(int[] x, int[] z)
{
if (0 != isZero(x))
@@ -240,6 +246,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ Nat384.square(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -255,6 +267,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ Nat384.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat384.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat.sub(12, x, y, z);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
index a2791d4..5520ffc 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
@@ -141,54 +141,55 @@
return this;
}
+ int[] tt0 = Nat.create(24);
int[] t1 = Nat.create(12);
int[] t2 = Nat.create(12);
int[] t3 = Nat.create(12);
int[] t4 = Nat.create(12);
- SecP384R1Field.square(x1, t1);
- SecP384R1Field.multiply(t1, x1, t1);
+ SecP384R1Field.square(x1, t1, tt0);
+ SecP384R1Field.multiply(t1, x1, t1, tt0);
- SecP384R1Field.squareN(t1, 2, t2);
- SecP384R1Field.multiply(t2, t1, t2);
+ SecP384R1Field.squareN(t1, 2, t2, tt0);
+ SecP384R1Field.multiply(t2, t1, t2, tt0);
- SecP384R1Field.square(t2, t2);
- SecP384R1Field.multiply(t2, x1, t2);
+ SecP384R1Field.square(t2, t2, tt0);
+ SecP384R1Field.multiply(t2, x1, t2, tt0);
- SecP384R1Field.squareN(t2, 5, t3);
- SecP384R1Field.multiply(t3, t2, t3);
+ SecP384R1Field.squareN(t2, 5, t3, tt0);
+ SecP384R1Field.multiply(t3, t2, t3, tt0);
- SecP384R1Field.squareN(t3, 5, t4);
- SecP384R1Field.multiply(t4, t2, t4);
+ SecP384R1Field.squareN(t3, 5, t4, tt0);
+ SecP384R1Field.multiply(t4, t2, t4, tt0);
- SecP384R1Field.squareN(t4, 15, t2);
- SecP384R1Field.multiply(t2, t4, t2);
+ SecP384R1Field.squareN(t4, 15, t2, tt0);
+ SecP384R1Field.multiply(t2, t4, t2, tt0);
- SecP384R1Field.squareN(t2, 2, t3);
- SecP384R1Field.multiply(t1, t3, t1);
+ SecP384R1Field.squareN(t2, 2, t3, tt0);
+ SecP384R1Field.multiply(t1, t3, t1, tt0);
- SecP384R1Field.squareN(t3, 28, t3);
- SecP384R1Field.multiply(t2, t3, t2);
+ SecP384R1Field.squareN(t3, 28, t3, tt0);
+ SecP384R1Field.multiply(t2, t3, t2, tt0);
- SecP384R1Field.squareN(t2, 60, t3);
- SecP384R1Field.multiply(t3, t2, t3);
+ SecP384R1Field.squareN(t2, 60, t3, tt0);
+ SecP384R1Field.multiply(t3, t2, t3, tt0);
int[] r = t2;
- SecP384R1Field.squareN(t3, 120, r);
- SecP384R1Field.multiply(r, t3, r);
+ SecP384R1Field.squareN(t3, 120, r, tt0);
+ SecP384R1Field.multiply(r, t3, r, tt0);
- SecP384R1Field.squareN(r, 15, r);
- SecP384R1Field.multiply(r, t4, r);
+ SecP384R1Field.squareN(r, 15, r, tt0);
+ SecP384R1Field.multiply(r, t4, r, tt0);
- SecP384R1Field.squareN(r, 33, r);
- SecP384R1Field.multiply(r, t1, r);
+ SecP384R1Field.squareN(r, 33, r, tt0);
+ SecP384R1Field.multiply(r, t1, r, tt0);
- SecP384R1Field.squareN(r, 64, r);
- SecP384R1Field.multiply(r, x1, r);
+ SecP384R1Field.squareN(r, 64, r, tt0);
+ SecP384R1Field.multiply(r, x1, r, tt0);
- SecP384R1Field.squareN(r, 30, t1);
- SecP384R1Field.square(t1, t2);
+ SecP384R1Field.squareN(r, 30, t1, tt0);
+ SecP384R1Field.square(t1, t2, tt0);
return Nat.eq(12, x1, t2) ? new SecP384R1FieldElement(t1) : null;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
index 27b6aa5..5787a5f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
@@ -51,6 +51,7 @@
SecP384R1FieldElement Z2 = (SecP384R1FieldElement)b.getZCoord(0);
int c;
+ int[] tt0 = Nat.create(24);
int[] tt1 = Nat.create(24);
int[] tt2 = Nat.create(24);
int[] t3 = Nat.create(12);
@@ -66,13 +67,13 @@
else
{
S2 = t3;
- SecP384R1Field.square(Z1.x, S2);
+ SecP384R1Field.square(Z1.x, S2, tt0);
U2 = tt2;
- SecP384R1Field.multiply(S2, X2.x, U2);
+ SecP384R1Field.multiply(S2, X2.x, U2, tt0);
- SecP384R1Field.multiply(S2, Z1.x, S2);
- SecP384R1Field.multiply(S2, Y2.x, S2);
+ SecP384R1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP384R1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -85,13 +86,13 @@
else
{
S1 = t4;
- SecP384R1Field.square(Z2.x, S1);
+ SecP384R1Field.square(Z2.x, S1, tt0);
U1 = tt1;
- SecP384R1Field.multiply(S1, X1.x, U1);
+ SecP384R1Field.multiply(S1, X1.x, U1, tt0);
- SecP384R1Field.multiply(S1, Z2.x, S1);
- SecP384R1Field.multiply(S1, Y1.x, S1);
+ SecP384R1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP384R1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat.create(12);
@@ -114,13 +115,13 @@
}
int[] HSquared = t3;
- SecP384R1Field.square(H, HSquared);
+ SecP384R1Field.square(H, HSquared, tt0);
int[] G = Nat.create(12);
- SecP384R1Field.multiply(HSquared, H, G);
+ SecP384R1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP384R1Field.multiply(HSquared, U1, V);
+ SecP384R1Field.multiply(HSquared, U1, V, tt0);
SecP384R1Field.negate(G, G);
Nat384.mul(S1, G, tt1);
@@ -129,7 +130,7 @@
SecP384R1Field.reduce32(c, G);
SecP384R1FieldElement X3 = new SecP384R1FieldElement(t4);
- SecP384R1Field.square(R, X3.x);
+ SecP384R1Field.square(R, X3.x, tt0);
SecP384R1Field.subtract(X3.x, G, X3.x);
SecP384R1FieldElement Y3 = new SecP384R1FieldElement(G);
@@ -141,11 +142,11 @@
SecP384R1FieldElement Z3 = new SecP384R1FieldElement(H);
if (!Z1IsOne)
{
- SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP384R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP384R1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
@@ -171,14 +172,15 @@
SecP384R1FieldElement X1 = (SecP384R1FieldElement)this.x, Z1 = (SecP384R1FieldElement)this.zs[0];
int c;
+ int[] tt0 = Nat.create(24);
int[] t1 = Nat.create(12);
int[] t2 = Nat.create(12);
int[] Y1Squared = Nat.create(12);
- SecP384R1Field.square(Y1.x, Y1Squared);
+ SecP384R1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat.create(12);
- SecP384R1Field.square(Y1Squared, T);
+ SecP384R1Field.square(Y1Squared, T, tt0);
boolean Z1IsOne = Z1.isOne();
@@ -186,19 +188,19 @@
if (!Z1IsOne)
{
Z1Squared = t2;
- SecP384R1Field.square(Z1.x, Z1Squared);
+ SecP384R1Field.square(Z1.x, Z1Squared, tt0);
}
SecP384R1Field.subtract(X1.x, Z1Squared, t1);
int[] M = t2;
SecP384R1Field.add(X1.x, Z1Squared, M);
- SecP384R1Field.multiply(M, t1, M);
+ SecP384R1Field.multiply(M, t1, M, tt0);
c = Nat.addBothTo(12, M, M, M);
SecP384R1Field.reduce32(c, M);
int[] S = Y1Squared;
- SecP384R1Field.multiply(Y1Squared, X1.x, S);
+ SecP384R1Field.multiply(Y1Squared, X1.x, S, tt0);
c = Nat.shiftUpBits(12, S, 2, 0);
SecP384R1Field.reduce32(c, S);
@@ -206,20 +208,20 @@
SecP384R1Field.reduce32(c, t1);
SecP384R1FieldElement X3 = new SecP384R1FieldElement(T);
- SecP384R1Field.square(M, X3.x);
+ SecP384R1Field.square(M, X3.x, tt0);
SecP384R1Field.subtract(X3.x, S, X3.x);
SecP384R1Field.subtract(X3.x, S, X3.x);
SecP384R1FieldElement Y3 = new SecP384R1FieldElement(S);
SecP384R1Field.subtract(S, X3.x, Y3.x);
- SecP384R1Field.multiply(Y3.x, M, Y3.x);
+ SecP384R1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP384R1Field.subtract(Y3.x, t1, Y3.x);
SecP384R1FieldElement Z3 = new SecP384R1FieldElement(M);
SecP384R1Field.twice(Y1.x, Z3.x);
if (!Z1IsOne)
{
- SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP384R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
index d4780f3..1f3ca22 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
@@ -81,6 +81,12 @@
reduce(tt, z);
}
+ public static void multiply(int[] x, int[] y, int[] z, int[] tt)
+ {
+ implMultiply(x, y, tt);
+ reduce(tt, z);
+ }
+
public static void negate(int[] x, int[] z)
{
if (0 != isZero(x))
@@ -149,6 +155,12 @@
reduce(tt, z);
}
+ public static void square(int[] x, int[] z, int[] tt)
+ {
+ implSquare(x, tt);
+ reduce(tt, z);
+ }
+
public static void squareN(int[] x, int n, int[] z)
{
// assert n > 0;
@@ -164,6 +176,20 @@
}
}
+ public static void squareN(int[] x, int n, int[] z, int[] tt)
+ {
+// assert n > 0;
+
+ implSquare(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ implSquare(z, tt);
+ reduce(tt, z);
+ }
+ }
+
public static void subtract(int[] x, int[] y, int[] z)
{
int c = Nat.sub(16, x, y, z) + x[16] - y[16];
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
index 4e52472..c7bd309 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
@@ -142,11 +142,12 @@
return this;
}
+ int[] tt0 = Nat.create(33);
int[] t1 = Nat.create(17);
int[] t2 = Nat.create(17);
- SecP521R1Field.squareN(x1, 519, t1);
- SecP521R1Field.square(t1, t2);
+ SecP521R1Field.squareN(x1, 519, t1, tt0);
+ SecP521R1Field.square(t1, t2, tt0);
return Nat.eq(17, x1, t2) ? new SecP521R1FieldElement(t1) : null;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
index 3bb4f69..e9e31ad 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
@@ -49,6 +49,7 @@
SecP521R1FieldElement Z1 = (SecP521R1FieldElement)this.zs[0];
SecP521R1FieldElement Z2 = (SecP521R1FieldElement)b.getZCoord(0);
+ int[] tt0 = Nat.create(33);
int[] t1 = Nat.create(17);
int[] t2 = Nat.create(17);
int[] t3 = Nat.create(17);
@@ -64,13 +65,13 @@
else
{
S2 = t3;
- SecP521R1Field.square(Z1.x, S2);
+ SecP521R1Field.square(Z1.x, S2, tt0);
U2 = t2;
- SecP521R1Field.multiply(S2, X2.x, U2);
+ SecP521R1Field.multiply(S2, X2.x, U2, tt0);
- SecP521R1Field.multiply(S2, Z1.x, S2);
- SecP521R1Field.multiply(S2, Y2.x, S2);
+ SecP521R1Field.multiply(S2, Z1.x, S2, tt0);
+ SecP521R1Field.multiply(S2, Y2.x, S2, tt0);
}
boolean Z2IsOne = Z2.isOne();
@@ -83,13 +84,13 @@
else
{
S1 = t4;
- SecP521R1Field.square(Z2.x, S1);
+ SecP521R1Field.square(Z2.x, S1, tt0);
U1 = t1;
- SecP521R1Field.multiply(S1, X1.x, U1);
+ SecP521R1Field.multiply(S1, X1.x, U1, tt0);
- SecP521R1Field.multiply(S1, Z2.x, S1);
- SecP521R1Field.multiply(S1, Y1.x, S1);
+ SecP521R1Field.multiply(S1, Z2.x, S1, tt0);
+ SecP521R1Field.multiply(S1, Y1.x, S1, tt0);
}
int[] H = Nat.create(17);
@@ -112,35 +113,35 @@
}
int[] HSquared = t3;
- SecP521R1Field.square(H, HSquared);
+ SecP521R1Field.square(H, HSquared, tt0);
int[] G = Nat.create(17);
- SecP521R1Field.multiply(HSquared, H, G);
+ SecP521R1Field.multiply(HSquared, H, G, tt0);
int[] V = t3;
- SecP521R1Field.multiply(HSquared, U1, V);
+ SecP521R1Field.multiply(HSquared, U1, V, tt0);
- SecP521R1Field.multiply(S1, G, t1);
+ SecP521R1Field.multiply(S1, G, t1, tt0);
SecP521R1FieldElement X3 = new SecP521R1FieldElement(t4);
- SecP521R1Field.square(R, X3.x);
+ SecP521R1Field.square(R, X3.x, tt0);
SecP521R1Field.add(X3.x, G, X3.x);
SecP521R1Field.subtract(X3.x, V, X3.x);
SecP521R1Field.subtract(X3.x, V, X3.x);
SecP521R1FieldElement Y3 = new SecP521R1FieldElement(G);
SecP521R1Field.subtract(V, X3.x, Y3.x);
- SecP521R1Field.multiply(Y3.x, R, t2);
+ SecP521R1Field.multiply(Y3.x, R, t2, tt0);
SecP521R1Field.subtract(t2, t1, Y3.x);
SecP521R1FieldElement Z3 = new SecP521R1FieldElement(H);
if (!Z1IsOne)
{
- SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
if (!Z2IsOne)
{
- SecP521R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ SecP521R1Field.multiply(Z3.x, Z2.x, Z3.x, tt0);
}
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
@@ -165,14 +166,15 @@
SecP521R1FieldElement X1 = (SecP521R1FieldElement)this.x, Z1 = (SecP521R1FieldElement)this.zs[0];
+ int[] tt0 = Nat.create(33);
int[] t1 = Nat.create(17);
int[] t2 = Nat.create(17);
int[] Y1Squared = Nat.create(17);
- SecP521R1Field.square(Y1.x, Y1Squared);
+ SecP521R1Field.square(Y1.x, Y1Squared, tt0);
int[] T = Nat.create(17);
- SecP521R1Field.square(Y1Squared, T);
+ SecP521R1Field.square(Y1Squared, T, tt0);
boolean Z1IsOne = Z1.isOne();
@@ -180,19 +182,19 @@
if (!Z1IsOne)
{
Z1Squared = t2;
- SecP521R1Field.square(Z1.x, Z1Squared);
+ SecP521R1Field.square(Z1.x, Z1Squared, tt0);
}
SecP521R1Field.subtract(X1.x, Z1Squared, t1);
int[] M = t2;
SecP521R1Field.add(X1.x, Z1Squared, M);
- SecP521R1Field.multiply(M, t1, M);
+ SecP521R1Field.multiply(M, t1, M, tt0);
Nat.addBothTo(17, M, M, M);
SecP521R1Field.reduce23(M);
int[] S = Y1Squared;
- SecP521R1Field.multiply(Y1Squared, X1.x, S);
+ SecP521R1Field.multiply(Y1Squared, X1.x, S, tt0);
Nat.shiftUpBits(17, S, 2, 0);
SecP521R1Field.reduce23(S);
@@ -200,20 +202,20 @@
SecP521R1Field.reduce23(t1);
SecP521R1FieldElement X3 = new SecP521R1FieldElement(T);
- SecP521R1Field.square(M, X3.x);
+ SecP521R1Field.square(M, X3.x, tt0);
SecP521R1Field.subtract(X3.x, S, X3.x);
SecP521R1Field.subtract(X3.x, S, X3.x);
SecP521R1FieldElement Y3 = new SecP521R1FieldElement(S);
SecP521R1Field.subtract(S, X3.x, Y3.x);
- SecP521R1Field.multiply(Y3.x, M, Y3.x);
+ SecP521R1Field.multiply(Y3.x, M, Y3.x, tt0);
SecP521R1Field.subtract(Y3.x, t1, Y3.x);
SecP521R1FieldElement Z3 = new SecP521R1FieldElement(M);
SecP521R1Field.twice(Y1.x, Z3.x);
if (!Z1IsOne)
{
- SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x, tt0);
}
return new SecP521R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
index 94dd7fa..f6272a4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
@@ -11,17 +11,6 @@
protected final BigInteger beta, lambda;
protected final ScalarSplitParameters splitParams;
- /**
- * @deprecated Use constructor taking a {@link ScalarSplitParameters} instead.
- */
- public GLVTypeBParameters(BigInteger beta, BigInteger lambda, BigInteger[] v1, BigInteger[] v2, BigInteger g1,
- BigInteger g2, int bits)
- {
- this.beta = beta;
- this.lambda = lambda;
- this.splitParams = new ScalarSplitParameters(v1, v2, g1, g2, bits);
- }
-
public GLVTypeBParameters(BigInteger beta, BigInteger lambda, ScalarSplitParameters splitParams)
{
this.beta = beta;
@@ -43,60 +32,4 @@
{
return splitParams;
}
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV1A()
- {
- return getSplitParams().getV1A();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV1B()
- {
- return getSplitParams().getV1B();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV2A()
- {
- return getSplitParams().getV2A();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getV2B()
- {
- return getSplitParams().getV2B();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getG1()
- {
- return getSplitParams().getG1();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public BigInteger getG2()
- {
- return getSplitParams().getG2();
- }
-
- /**
- * @deprecated Access via {@link #getSplitParams()} instead.
- */
- public int getBits()
- {
- return getSplitParams().getBits();
- }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteFields.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteFields.java
index 45cc70f..d736859 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteFields.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteFields.java
@@ -3,6 +3,8 @@
import java.math.BigInteger;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -43,7 +45,7 @@
if (bitLength < 3)
{
- switch (characteristic.intValue())
+ switch (BigIntegers.intValueExact(characteristic))
{
case 2:
return GF_2;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java
index c6d6bec..88ac856 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java
@@ -18,17 +18,6 @@
private static final int M30 = 0x3FFFFFFF;
private static final long M32L = 0xFFFFFFFFL;
- /** @deprecated Will be removed. */
- public static void add(int[] p, int[] x, int[] y, int[] z)
- {
- int len = p.length;
- int c = Nat.add(len, x, y, z);
- if (c != 0)
- {
- Nat.subFrom(len, p, z);
- }
- }
-
public static void checkedModOddInverse(int[] m, int[] x, int[] z)
{
if (0 == modOddInverse(m, x, z))
@@ -58,12 +47,6 @@
return x;
}
- /** @deprecated Use {@link #checkedModOddInverseVar(int[], int[], int[])} instead. */
- public static void invert(int[] m, int[] x, int[] z)
- {
- checkedModOddInverseVar(m, x, z);
- }
-
public static int modOddInverse(int[] m, int[] x, int[] z)
{
int len32 = m.length;
@@ -86,13 +69,13 @@
encode30(bits, m, 0, M, 0);
System.arraycopy(M, 0, F, 0, len30);
- int eta = -1;
+ int delta = 0;
int m0Inv32 = inverse32(M[0]);
int maxDivsteps = getMaximumDivsteps(bits);
for (int divSteps = 0; divSteps < maxDivsteps; divSteps += 30)
{
- eta = divsteps30(eta, F[0], G[0], t);
+ delta = divsteps30(delta, F[0], G[0], t);
updateDE30(len30, D, E, t, m0Inv32, M);
updateFG30(len30, F, G, t);
}
@@ -232,17 +215,6 @@
return s;
}
- /** @deprecated Will be removed. */
- public static void subtract(int[] p, int[] x, int[] y, int[] z)
- {
- int len = p.length;
- int c = Nat.sub(len, x, y, z);
- if (c != 0)
- {
- Nat.addTo(len, p, z);
- }
- }
-
private static int add30(int len30, int[] D, int[] M)
{
// assert len30 > 0;
@@ -280,7 +252,6 @@
// assert len30 > 0;
// assert D.length >= len30;
// assert M.length >= len30;
-
int last = len30 - 1;
{
@@ -335,38 +306,38 @@
}
}
- private static int divsteps30(int eta, int f0, int g0, int[] t)
+ private static int divsteps30(int delta, int f0, int g0, int[] t)
{
- int u = 1, v = 0, q = 0, r = 1;
+ int u = 1 << 30, v = 0, q = 0, r = 1 << 30;
int f = f0, g = g0;
for (int i = 0; i < 30; ++i)
{
// assert (f & 1) == 1;
-// assert (u * f0 + v * g0) == f << i;
-// assert (q * f0 + r * g0) == g << i;
+// assert ((u >> (30 - i)) * f0 + (v >> (30 - i)) * g0) == f << i;
+// assert ((q >> (30 - i)) * f0 + (r >> (30 - i)) * g0) == g << i;
- int c1 = eta >> 31;
+ int c1 = delta >> 31;
int c2 = -(g & 1);
- int x = (f ^ c1) - c1;
- int y = (u ^ c1) - c1;
- int z = (v ^ c1) - c1;
+ int x = f ^ c1;
+ int y = u ^ c1;
+ int z = v ^ c1;
- g += x & c2;
- q += y & c2;
- r += z & c2;
+ g -= x & c2;
+ q -= y & c2;
+ r -= z & c2;
- c1 &= c2;
- eta = (eta ^ c1) - (c1 + 1);
+ c2 &= ~c1;
+ delta = (delta ^ c2) - (c2 - 1);
- f += g & c1;
- u += q & c1;
- v += r & c1;
+ f += g & c2;
+ u += q & c2;
+ v += r & c2;
g >>= 1;
- u <<= 1;
- v <<= 1;
+ q >>= 1;
+ r >>= 1;
}
t[0] = u;
@@ -374,7 +345,7 @@
t[2] = q;
t[3] = r;
- return eta;
+ return delta;
}
private static int divsteps30Var(int eta, int f0, int g0, int[] t)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java
index 515ac47..ff53899 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java
@@ -236,6 +236,19 @@
return (int)c;
}
+ public static int caddTo(int len, int mask, int[] x, int[] z)
+ {
+ long MASK = -(mask & 1) & M;
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (z[i] & M) + (x[i] & MASK);
+ z[i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
public static void cmov(int len, int mask, int[] x, int xOff, int[] z, int zOff)
{
mask = -(mask & 1);
@@ -1129,41 +1142,6 @@
shiftUpBit(extLen, zz, zzOff, x[xOff] << 31);
}
- /**
- * @deprecated Use {@link #squareWordAddTo(int[], int, int[])} instead.
- */
- public static int squareWordAdd(int[] x, int xPos, int[] z)
- {
- long c = 0, xVal = x[xPos] & M;
- int i = 0;
- do
- {
- c += xVal * (x[i] & M) + (z[xPos + i] & M);
- z[xPos + i] = (int)c;
- c >>>= 32;
- }
- while (++i < xPos);
- return (int)c;
- }
-
- /**
- * @deprecated Use {@link #squareWordAddTo(int[], int, int, int[], int)} instead.
- */
- public static int squareWordAdd(int[] x, int xOff, int xPos, int[] z, int zOff)
- {
- long c = 0, xVal = x[xOff + xPos] & M;
- int i = 0;
- do
- {
- c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M);
- z[xPos + zOff] = (int)c;
- c >>>= 32;
- ++zOff;
- }
- while (++i < xPos);
- return (int)c;
- }
-
public static int squareWordAddTo(int[] x, int xPos, int[] z)
{
long c = 0, xVal = x[xPos] & M;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java
index 8f8423d..114971d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java
@@ -147,6 +147,33 @@
return (int)c;
}
+ public static int addTo(int[] x, int[] z, int cIn)
+ {
+ long c = cIn & M;
+ c += (x[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
{
long c = cIn & M;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java
index 0771409..70beb5c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java
@@ -162,6 +162,36 @@
return (int)c;
}
+ public static int addTo(int[] x, int[] z, int cIn)
+ {
+ long c = cIn & M;
+ c += (x[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ c += (x[7] & M) + (z[7] & M);
+ z[7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
{
long c = cIn & M;
@@ -606,6 +636,77 @@
}
}
+ public static void mul128(int[] x, int[] y128, int[] zz)
+ {
+ long x_0 = x[0] & M;
+ long x_1 = x[1] & M;
+ long x_2 = x[2] & M;
+ long x_3 = x[3] & M;
+ long x_4 = x[4] & M;
+ long x_5 = x[5] & M;
+ long x_6 = x[6] & M;
+ long x_7 = x[7] & M;
+
+ {
+ long c = 0, y_0 = y128[0] & M;
+ c += y_0 * x_0;
+ zz[0] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_1;
+ zz[1] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_2;
+ zz[2] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_3;
+ zz[3] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_4;
+ zz[4] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_5;
+ zz[5] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_6;
+ zz[6] = (int)c;
+ c >>>= 32;
+ c += y_0 * x_7;
+ zz[7] = (int)c;
+ c >>>= 32;
+ zz[8] = (int)c;
+ }
+
+ for (int i = 1; i < 4; ++i)
+ {
+ long c = 0, y_i = y128[i] & M;
+ c += y_i * x_0 + (zz[i + 0] & M);
+ zz[i + 0] = (int)c;
+ c >>>= 32;
+ c += y_i * x_1 + (zz[i + 1] & M);
+ zz[i + 1] = (int)c;
+ c >>>= 32;
+ c += y_i * x_2 + (zz[i + 2] & M);
+ zz[i + 2] = (int)c;
+ c >>>= 32;
+ c += y_i * x_3 + (zz[i + 3] & M);
+ zz[i + 3] = (int)c;
+ c >>>= 32;
+ c += y_i * x_4 + (zz[i + 4] & M);
+ zz[i + 4] = (int)c;
+ c >>>= 32;
+ c += y_i * x_5 + (zz[i + 5] & M);
+ zz[i + 5] = (int)c;
+ c >>>= 32;
+ c += y_i * x_6 + (zz[i + 6] & M);
+ zz[i + 6] = (int)c;
+ c >>>= 32;
+ c += y_i * x_7 + (zz[i + 7] & M);
+ zz[i + 7] = (int)c;
+ c >>>= 32;
+ zz[i + 8] = (int)c;
+ }
+ }
+
public static int mulAddTo(int[] x, int[] y, int[] zz)
{
long y_0 = y[0] & M;
@@ -1351,6 +1452,36 @@
return (int)c;
}
+ public static int subFrom(int[] x, int[] z, int cIn)
+ {
+ long c = cIn & M;
+ c += (z[0] & M) - (x[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - (x[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M) - (x[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (z[3] & M) - (x[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) - (x[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M) - (x[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ c += (z[6] & M) - (x[6] & M);
+ z[6] = (int)c;
+ c >>= 32;
+ c += (z[7] & M) - (x[7] & M);
+ z[7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
public static int subFrom(int[] x, int xOff, int[] z, int zOff)
{
long c = 0;
@@ -1381,6 +1512,36 @@
return (int)c;
}
+ public static int subFrom(int[] x, int xOff, int[] z, int zOff, int cIn)
+ {
+ long c = cIn & M;
+ c += (z[zOff + 0] & M) - (x[xOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 1] & M) - (x[xOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 2] & M) - (x[xOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 3] & M) - (x[xOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 4] & M) - (x[xOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 5] & M) - (x[xOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 6] & M) - (x[xOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 7] & M) - (x[xOff + 7] & M);
+ z[zOff + 7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
public static BigInteger toBigInteger(int[] x)
{
byte[] bs = new byte[32];
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java
index 3ce0b11..fdb5d27 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java
@@ -151,6 +151,47 @@
return 0 == d;
}
+ /**
+ * A constant time equals comparison - does not terminate early if
+ * comparison fails. For best results always pass the expected value
+ * as the first parameter.
+ *
+ * @param expected first array
+ * @param supplied second array
+ * @return true if arrays equal, false otherwise.
+ */
+ public static boolean constantTimeAreEqual(
+ char[] expected,
+ char[] supplied)
+ {
+ if (expected == null || supplied == null)
+ {
+ return false;
+ }
+
+ if (expected == supplied)
+ {
+ return true;
+ }
+
+ int len = Math.min(expected.length, supplied.length);
+
+ int nonEqual = expected.length ^ supplied.length;
+
+ // do the char-wise comparison
+ for (int i = 0; i != len; i++)
+ {
+ nonEqual |= (expected[i] ^ supplied[i]);
+ }
+ // If supplied is longer than expected, iterate over rest of supplied with NOPs
+ for (int i = len; i < supplied.length; i++)
+ {
+ nonEqual |= ((byte)supplied[i] ^ (byte)~supplied[i]);
+ }
+
+ return nonEqual == 0;
+ }
+
public static int compareUnsigned(byte[] a, byte[] b)
{
if (a == b)
@@ -276,14 +317,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(byte[], int, int, byte)} instead.
- */
- public static void fill(byte[] a, int fromIndex, byte val)
- {
- fill(a, fromIndex, a.length, val);
- }
-
public static void fill(byte[] a, int fromIndex, int toIndex, byte val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -304,14 +337,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(int[], int, int, int)} instead.
- */
- public static void fill(int[] a, int fromIndex, int val)
- {
- java.util.Arrays.fill(a, fromIndex, a.length, val);
- }
-
public static void fill(int[] a, int fromIndex, int toIndex, int val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -322,14 +347,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(long[], int, int, long)} instead.
- */
- public static void fill(long[] a, int fromIndex, long val)
- {
- java.util.Arrays.fill(a, fromIndex, a.length, val);
- }
-
public static void fill(long[] a, int fromIndex, int toIndex, long val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -350,14 +367,6 @@
java.util.Arrays.fill(a, val);
}
- /**
- * @deprecated Use {@link #fill(short[], int, int, short)} instead.
- */
- public static void fill(short[] a, int fromIndex, short val)
- {
- java.util.Arrays.fill(a, fromIndex, a.length, val);
- }
-
public static void fill(short[] a, int fromIndex, int toIndex, short val)
{
java.util.Arrays.fill(a, fromIndex, toIndex, val);
@@ -796,9 +805,7 @@
int newLength = to - from;
if (newLength < 0)
{
- StringBuffer sb = new StringBuffer(from);
- sb.append(" > ").append(to);
- throw new IllegalArgumentException(sb.toString());
+ throw new IllegalArgumentException(from + " > " + to);
}
return newLength;
}
@@ -1065,6 +1072,80 @@
return result;
}
+ public static void reverse(byte[] input, byte[] output)
+ {
+ int last = input.length - 1;
+ for (int i = 0; i <= last; ++i)
+ {
+ output[i] = input[last - i];
+ }
+ }
+
+ public static byte[] reverseInPlace(byte[] a)
+ {
+ if (null == a)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length - 1;
+ while (p1 < p2)
+ {
+ byte t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+
+ return a;
+ }
+
+ public static void reverseInPlace(byte[] a, int aOff, int aLen)
+ {
+ int p1 = aOff, p2 = aOff + aLen - 1;
+ while (p1 < p2)
+ {
+ byte t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+ }
+
+ public static short[] reverseInPlace(short[] a)
+ {
+ if (null == a)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length - 1;
+ while (p1 < p2)
+ {
+ short t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+
+ return a;
+ }
+
+ public static int[] reverseInPlace(int[] a)
+ {
+ if (null == a)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length - 1;
+ while (p1 < p2)
+ {
+ int t1 = a[p1], t2 = a[p2];
+ a[p1++] = t2;
+ a[p2--] = t1;
+ }
+
+ return a;
+ }
+
/**
* Iterator backed by a specific array.
* @hide This class is not part of the Android public SDK API
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java
index 62a5367..9d6749b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java
@@ -3,6 +3,11 @@
import java.math.BigInteger;
import java.security.SecureRandom;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import com.android.internal.org.bouncycastle.math.raw.Mod;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
import com.android.internal.org.bouncycastle.math.raw.Mod;
import com.android.internal.org.bouncycastle.math.raw.Nat;
@@ -23,7 +28,7 @@
/**
* Return the passed in value as an unsigned byte array.
- *
+ *
* @param value the value to be converted.
* @return a byte array without a leading zero byte if present in the signed encoding.
*/
@@ -31,16 +36,15 @@
BigInteger value)
{
byte[] bytes = value.toByteArray();
-
if (bytes[0] == 0 && bytes.length != 1)
{
byte[] tmp = new byte[bytes.length - 1];
-
+
System.arraycopy(bytes, 1, tmp, 0, tmp.length);
-
+
return tmp;
}
-
+
return bytes;
}
@@ -48,10 +52,8 @@
* Return the passed in value as an unsigned byte array of the specified length, padded with
* leading zeros as necessary..
*
- * @param length
- * the fixed length of the result
- * @param value
- * the value to be converted.
+ * @param length the fixed length of the result
+ * @param value the value to be converted.
* @return a byte array padded to a fixed length with leading zeros.
*/
public static byte[] asUnsignedByteArray(int length, BigInteger value)
@@ -79,14 +81,10 @@
* Write the passed in value as unsigned bytes to the specified buffer range, padded with
* leading zeros as necessary.
*
- * @param value
- * the value to be converted.
- * @param buf
- * the buffer to which the value is written.
- * @param off
- * the start offset in array <code>buf</code> at which the data is written.
- * @param len
- * the fixed length of data written (possibly padded with leading zeros).
+ * @param value the value to be converted.
+ * @param buf the buffer to which the value is written.
+ * @param off the start offset in array <code>buf</code> at which the data is written.
+ * @param len the fixed length of data written (possibly padded with leading zeros).
*/
public static void asUnsignedByteArray(BigInteger value, byte[] buf, int off, int len)
{
@@ -106,22 +104,23 @@
}
int padLen = len - count;
- Arrays.fill(buf, off, off + padLen, (byte)0x00);
+ Arrays.fill(buf, off, off + padLen, (byte)0x00);
System.arraycopy(bytes, start, buf, off + padLen, count);
}
+
/**
* Return a random BigInteger not less than 'min' and not greater than 'max'
- *
- * @param min the least value that may be generated
- * @param max the greatest value that may be generated
+ *
+ * @param min the least value that may be generated
+ * @param max the greatest value that may be generated
* @param random the source of randomness
* @return a random BigInteger value in the range [min,max]
*/
public static BigInteger createRandomInRange(
- BigInteger min,
- BigInteger max,
- SecureRandom random)
+ BigInteger min,
+ BigInteger max,
+ SecureRandom random)
{
int cmp = min.compareTo(max);
if (cmp >= 0)
@@ -152,6 +151,7 @@
return createRandomBigInteger(max.subtract(min).bitLength() - 1, random).add(min);
}
+
public static BigInteger fromUnsignedByteArray(byte[] buf)
{
return new BigInteger(1, buf);
@@ -168,6 +168,28 @@
return new BigInteger(1, mag);
}
+ public static byte byteValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.byteValueExact instead
+ if (x.bitLength() > 7)
+ {
+ throw new ArithmeticException("BigInteger out of int range");
+ }
+
+ return x.byteValue();
+ }
+
+ public static short shortValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.shortValueExact instead
+ if (x.bitLength() > 15)
+ {
+ throw new ArithmeticException("BigInteger out of int range");
+ }
+
+ return x.shortValue();
+ }
+
public static int intValueExact(BigInteger x)
{
// Since Java 1.8 could use BigInteger.intValueExact instead
@@ -176,7 +198,7 @@
throw new ArithmeticException("BigInteger out of int range");
}
- return x.intValue();
+ return x.intValue();
}
public static long longValueExact(BigInteger x)
@@ -187,7 +209,7 @@
throw new ArithmeticException("BigInteger out of long range");
}
- return x.longValue();
+ return x.longValue();
}
public static BigInteger modOddInverse(BigInteger M, BigInteger X)
@@ -266,7 +288,7 @@
* Return a positive BigInteger in the range of 0 to 2**bitLength - 1.
*
* @param bitLength maximum bit length for the generated BigInteger.
- * @param random a source of randomness.
+ * @param random a source of randomness.
* @return a positive BigInteger
*/
public static BigInteger createRandomBigInteger(int bitLength, SecureRandom random)
@@ -276,7 +298,7 @@
// Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
- "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
+ "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
+ "73d893fa424cd2edc8636a6c3285e022b0e3866a565ae8108eed8591cd4fe8d2"
+ "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8"
+ "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f",
@@ -287,7 +309,7 @@
* Return a prime number candidate of the specified bit length.
*
* @param bitLength bit length for the generated BigInteger.
- * @param random a source of randomness.
+ * @param random a source of randomness.
* @return a positive BigInteger of numBits length
*/
public static BigInteger createRandomPrime(int bitLength, int certainty, SecureRandom random)
@@ -349,4 +371,41 @@
return rv;
}
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Cache
+ {
+ private final Map<BigInteger, Boolean> values = new WeakHashMap<BigInteger, Boolean>();
+ private final BigInteger[] preserve = new BigInteger[8];
+
+ private int preserveCounter = 0;
+
+ public synchronized void add(BigInteger value)
+ {
+ values.put(value, Boolean.TRUE);
+ preserve[preserveCounter] = value;
+ preserveCounter = (preserveCounter + 1) % preserve.length;
+ }
+
+ public synchronized boolean contains(BigInteger value)
+ {
+ return values.containsKey(value);
+ }
+
+ public synchronized int size()
+ {
+ return values.size();
+ }
+
+ public synchronized void clear()
+ {
+ values.clear();
+ for (int i = 0; i != preserve.length; i++)
+ {
+ preserve[i] = null;
+ }
+ }
+ }
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Bytes.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Bytes.java
new file mode 100644
index 0000000..35860bb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Bytes.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * Utility methods and constants for bytes.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Bytes
+{
+ public static final int BYTES = 1;
+ public static final int SIZE = Byte.SIZE;
+
+ public static void xor(int len, byte[] x, byte[] y, byte[] z)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] = (byte)(x[i] ^ y[i]);
+ }
+ }
+
+ public static void xor(int len, byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]);
+ }
+ }
+
+ public static void xorTo(int len, byte[] x, byte[] z)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] ^= x[i];
+ }
+ }
+
+ public static void xorTo(int len, byte[] x, int xOff, byte[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[zOff + i] ^= x[xOff + i];
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Characters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Characters.java
new file mode 100644
index 0000000..c5e2df8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Characters.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Characters
+{
+ public static Character valueOf(char c)
+ {
+ return Character.valueOf(c);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Exceptions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Exceptions.java
new file mode 100644
index 0000000..3d2f233
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Exceptions.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+import java.io.IOException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Exceptions
+{
+ public static IllegalArgumentException illegalArgumentException(String message, Throwable cause)
+ {
+ return new IllegalArgumentException(message, cause);
+ }
+
+ public static IllegalStateException illegalStateException(String message, Throwable cause)
+ {
+ return new IllegalStateException(message, cause);
+ }
+
+ public static IOException ioException(String message, Throwable cause)
+ {
+ return new IOException(message, cause);
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/IPAddress.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/IPAddress.java
index 47c159a..29d9f75 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/IPAddress.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/IPAddress.java
@@ -14,8 +14,7 @@
*
* @return true if a valid address, false otherwise
*/
- public static boolean isValid(
- String address)
+ public static boolean isValid(String address)
{
return isValidIPv4(address) || isValidIPv6(address);
}
@@ -27,8 +26,7 @@
*
* @return true if a valid address with netmask, false otherwise
*/
- public static boolean isValidWithNetMask(
- String address)
+ public static boolean isValidWithNetMask(String address)
{
return isValidIPv4WithNetmask(address) || isValidIPv6WithNetmask(address);
}
@@ -40,79 +38,42 @@
*
* @return true if a valid IPv4 address, false otherwise
*/
- public static boolean isValidIPv4(
- String address)
+ public static boolean isValidIPv4(String address)
{
- if (address.length() == 0)
+ int length = address.length();
+ if (length < 7 || length > 15)
{
return false;
}
- int octet;
- int octets = 0;
-
- String temp = address+".";
-
- int pos;
- int start = 0;
- while (start < temp.length()
- && (pos = temp.indexOf('.', start)) > start)
+ int pos = 0;
+ for (int octetIndex = 0; octetIndex < 3; ++octetIndex)
{
- if (octets == 4)
+ int end = address.indexOf('.', pos);
+
+ if (!isParseableIPv4Octet(address, pos, end))
{
return false;
}
- try
- {
- octet = Integer.parseInt(temp.substring(start, pos));
- }
- catch (NumberFormatException ex)
- {
- return false;
- }
- if (octet < 0 || octet > 255)
- {
- return false;
- }
- start = pos + 1;
- octets++;
+
+ pos = end + 1;
}
- return octets == 4;
+ return isParseableIPv4Octet(address, pos, length);
}
- public static boolean isValidIPv4WithNetmask(
- String address)
+ public static boolean isValidIPv4WithNetmask(String address)
{
int index = address.indexOf("/");
- String mask = address.substring(index + 1);
-
- return (index > 0) && isValidIPv4(address.substring(0, index))
- && (isValidIPv4(mask) || isMaskValue(mask, 32));
- }
-
- public static boolean isValidIPv6WithNetmask(
- String address)
- {
- int index = address.indexOf("/");
- String mask = address.substring(index + 1);
-
- return (index > 0) && (isValidIPv6(address.substring(0, index))
- && (isValidIPv6(mask) || isMaskValue(mask, 128)));
- }
-
- private static boolean isMaskValue(String component, int size)
- {
- try
- {
- int value = Integer.parseInt(component);
-
- return value >= 0 && value <= size;
- }
- catch (NumberFormatException e)
+ if (index < 1)
{
return false;
}
+
+ String before = address.substring(0, index);
+ String after = address.substring(index + 1);
+
+ return isValidIPv4(before) && (isValidIPv4(after) || isParseableIPv4Mask(after));
}
/**
@@ -122,72 +83,131 @@
*
* @return true if a valid IPv6 address, false otherwise
*/
- public static boolean isValidIPv6(
- String address)
+ public static boolean isValidIPv6(String address)
{
if (address.length() == 0)
{
return false;
}
- int octet;
- int octets = 0;
+ char firstChar = address.charAt(0);
+ if (firstChar != ':' && Character.digit(firstChar, 16) < 0)
+ {
+ return false;
+ }
+ int segmentCount = 0;
String temp = address + ":";
boolean doubleColonFound = false;
- int pos;
- int start = 0;
- while (start < temp.length()
- && (pos = temp.indexOf(':', start)) >= start)
+
+ int pos = 0, end;
+ while (pos < temp.length() && (end = temp.indexOf(':', pos)) >= pos)
{
- if (octets == 8)
+ if (segmentCount == 8)
{
return false;
}
- if (start != pos)
+ if (pos != end)
{
- String value = temp.substring(start, pos);
+ String value = temp.substring(pos, end);
- if (pos == (temp.length() - 1) && value.indexOf('.') > 0)
+ if (end == temp.length() - 1 && value.indexOf('.') > 0)
{
+ // add an extra one as address covers 2 words.
+ if (++segmentCount == 8)
+ {
+ return false;
+ }
if (!isValidIPv4(value))
{
return false;
}
-
- octets++; // add an extra one as address covers 2 words.
}
- else
+ else if (!isParseableIPv6Segment(temp, pos, end))
{
- try
- {
- octet = Integer.parseInt(temp.substring(start, pos), 16);
- }
- catch (NumberFormatException ex)
- {
- return false;
- }
- if (octet < 0 || octet > 0xffff)
- {
- return false;
- }
+ return false;
}
}
else
{
- if (pos != 1 && pos != temp.length() - 1 && doubleColonFound)
+ if (end != 1 && end != temp.length() - 1 && doubleColonFound)
{
return false;
}
doubleColonFound = true;
}
- start = pos + 1;
- octets++;
+
+ pos = end + 1;
+ ++segmentCount;
}
- return octets == 8 || doubleColonFound;
+ return segmentCount == 8 || doubleColonFound;
+ }
+
+ public static boolean isValidIPv6WithNetmask(String address)
+ {
+ int index = address.indexOf("/");
+ if (index < 1)
+ {
+ return false;
+ }
+
+ String before = address.substring(0, index);
+ String after = address.substring(index + 1);
+
+ return isValidIPv6(before) && (isValidIPv6(after) || isParseableIPv6Mask(after));
+ }
+
+ private static boolean isParseableIPv4Mask(String s)
+ {
+ return isParseable(s, 0, s.length(), 10, 2, false, 0, 32);
+ }
+
+ private static boolean isParseableIPv4Octet(String s, int pos, int end)
+ {
+ return isParseable(s, pos, end, 10, 3, true, 0, 255);
+ }
+
+ private static boolean isParseableIPv6Mask(String s)
+ {
+ return isParseable(s, 0, s.length(), 10, 3, false, 1, 128);
+ }
+
+ private static boolean isParseableIPv6Segment(String s, int pos, int end)
+ {
+ return isParseable(s, pos, end, 16, 4, true, 0x0000, 0xFFFF);
+ }
+
+ private static boolean isParseable(String s, int pos, int end, int radix, int maxLength, boolean allowLeadingZero,
+ int minValue, int maxValue)
+ {
+ int length = end - pos;
+ if (length < 1 | length > maxLength)
+ {
+ return false;
+ }
+
+ boolean checkLeadingZero = length > 1 & !allowLeadingZero;
+ if (checkLeadingZero && Character.digit(s.charAt(pos), radix) <= 0)
+ {
+ return false;
+ }
+
+ int value = 0;
+ while (pos < end)
+ {
+ char c = s.charAt(pos++);
+ int d = Character.digit(c, radix);
+ if (d < 0)
+ {
+ return false;
+ }
+
+ value *= radix;
+ value += d;
+ }
+
+ return value >= minValue & value <= maxValue;
}
}
-
-
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Integers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Integers.java
index 09db121..0886aa3 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Integers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Integers.java
@@ -2,11 +2,29 @@
package com.android.internal.org.bouncycastle.util;
/**
- * Utility methods for ints.
+ * Utility methods and constants for ints.
* @hide This class is not part of the Android public SDK API
*/
public class Integers
{
+ public static final int BYTES = 4;
+ public static final int SIZE = Integer.SIZE;
+
+ public static int bitCount(int i)
+ {
+ return Integer.bitCount(i);
+ }
+
+ public static int highestOneBit(int i)
+ {
+ return Integer.highestOneBit(i);
+ }
+
+ public static int lowestOneBit(int i)
+ {
+ return Integer.lowestOneBit(i);
+ }
+
public static int numberOfLeadingZeros(int i)
{
return Integer.numberOfLeadingZeros(i);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Longs.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Longs.java
index f41ee5f..6260246 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Longs.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Longs.java
@@ -2,10 +2,34 @@
package com.android.internal.org.bouncycastle.util;
/**
+ * Utility methods and constants for longs.
* @hide This class is not part of the Android public SDK API
*/
public class Longs
{
+ public static final int BYTES = 8;
+ public static final int SIZE = Long.SIZE;
+
+ public static long highestOneBit(long i)
+ {
+ return Long.highestOneBit(i);
+ }
+
+ public static long lowestOneBit(long i)
+ {
+ return Long.lowestOneBit(i);
+ }
+
+ public static int numberOfLeadingZeros(long i)
+ {
+ return Long.numberOfLeadingZeros(i);
+ }
+
+ public static int numberOfTrailingZeros(long i)
+ {
+ return Long.numberOfTrailingZeros(i);
+ }
+
public static long reverse(long i)
{
return Long.reverse(i);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Memoable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Memoable.java
index 75ce09a..7f84a44 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Memoable.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Memoable.java
@@ -3,7 +3,7 @@
/**
* Interface for Memoable objects. Memoable objects allow the taking of a snapshot of their internal state
- * via the copy() method and then reseting the object back to that state later using the reset() method.
+ * via the copy() method and then resetting the object back to that state later using the reset() method.
* @hide This class is not part of the Android public SDK API
*/
public interface Memoable
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Pack.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Pack.java
index ef00137..5ce877a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Pack.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Pack.java
@@ -149,7 +149,6 @@
* @param bs The target.
* @param off Position in target to start.
* @param bytes number of bytes to write.
- *
* @deprecated Will be removed
*/
public static void longToBigEndian(long value, byte[] bs, int off, int bytes)
@@ -177,6 +176,25 @@
return n;
}
+ public static int littleEndianToInt_High(byte[] bs, int off, int len)
+ {
+ return littleEndianToInt_Low(bs, off, len) << ((4 - len) << 3);
+ }
+
+ public static int littleEndianToInt_Low(byte[] bs, int off, int len)
+ {
+// assert 1 <= len && len <= 4;
+
+ int result = bs[off] & 0xff;
+ int pos = 0;
+ for (int i = 1; i < len; ++i)
+ {
+ pos += 8;
+ result |= (bs[off + i] & 0xff) << pos;
+ }
+ return result;
+ }
+
public static void littleEndianToInt(byte[] bs, int off, int[] ns)
{
for (int i = 0; i < ns.length; ++i)
@@ -299,6 +317,40 @@
}
}
+ public static void longToLittleEndian_High(long n, byte[] bs, int off, int len)
+ {
+ //Debug.Assert(1 <= len && len <= 8);
+ int pos = 56;
+ bs[off] = (byte)(n >>> pos);
+ for (int i = 1; i < len; ++i)
+ {
+ pos -= 8;
+ bs[off + i] = (byte)(n >>> pos);
+ }
+ }
+
+// public static void longToLittleEndian_Low(long n, byte[] bs, int off, int len)
+// {
+// longToLittleEndian_High(n << ((8 - len) << 3), bs, off, len);
+// }
+
+ public static long littleEndianToLong_High(byte[] bs, int off, int len)
+ {
+ return littleEndianToLong_Low(bs, off, len) << ((8 - len) << 3);
+ }
+
+ public static long littleEndianToLong_Low(byte[] bs, int off, int len)
+ {
+ //Debug.Assert(1 <= len && len <= 8);
+ long result = bs[off] & 0xFF;
+ for (int i = 1; i < len; ++i)
+ {
+ result <<= 8;
+ result |= bs[off + i] & 0xFF;
+ }
+ return result;
+ }
+
public static byte[] longToLittleEndian(long n)
{
byte[] bs = new byte[8];
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java
index 4817548..2935389 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java
@@ -14,11 +14,18 @@
import java.util.StringTokenizer;
/**
- * Utility method for accessing system properties.
+ * Utility method for accessing properties values - properties can be set in java.security,
+ * thread local, and system properties. They are checked for in the same order with
+ * checking stopped as soon as a value is found.
* @hide This class is not part of the Android public SDK API
*/
public class Properties
{
+ /**
+ * If set the provider will attempt, where possible, to behave the same way as the oracle one.
+ */
+ public static final String EMULATE_ORACLE = "com.android.internal.org.bouncycastle.emulate.oracle";
+
private Properties()
{
}
@@ -117,6 +124,31 @@
return false;
}
+ /**
+ * Return propertyName as an integer, defaultValue used if not defined.
+ *
+ * @param propertyName name of property.
+ * @param defaultValue integer to return if property not defined.
+ * @return value of property, or default if not found, as an int.
+ */
+ public static int asInteger(String propertyName, int defaultValue)
+ {
+ String p = getPropertyValue(propertyName);
+
+ if (p != null)
+ {
+ return Integer.parseInt(p);
+ }
+
+ return defaultValue;
+ }
+
+ /**
+ * Return propertyName as a BigInteger.
+ *
+ * @param propertyName name of property.
+ * @return value of property as a BigInteger, null if not defined.
+ */
public static BigInteger asBigInteger(String propertyName)
{
String p = getPropertyValue(propertyName);
@@ -147,6 +179,13 @@
return Collections.unmodifiableSet(set);
}
+ /**
+ * Return the String value of the property propertyName. Property valuation
+ * starts with java.security, then thread local, then system properties.
+ *
+ * @param propertyName name of property.
+ * @return value of property as a String, null if not defined.
+ */
public static String getPropertyValue(final String propertyName)
{
String val = (String)AccessController.doPrivileged(new PrivilegedAction()
@@ -180,6 +219,18 @@
});
}
+ public static String getPropertyValue(final String propertyName, String defValue)
+ {
+ String rv = getPropertyValue(propertyName);
+
+ if (rv == null)
+ {
+ return defValue;
+ }
+
+ return rv;
+ }
+
private static boolean isSetFalse(String p)
{
if (p == null || p.length() != 5)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Strings.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Strings.java
index dfbc7f9..35a0f43 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Strings.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Strings.java
@@ -58,6 +58,17 @@
return new String(chars, 0, len);
}
+ public static String fromUTF8ByteArray(byte[] bytes, int off, int length)
+ {
+ char[] chars = new char[length];
+ int len = UTF8.transcodeToUTF16(bytes, off, length, chars);
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Invalid UTF-8 input");
+ }
+ return new String(chars, 0, len);
+ }
+
public static byte[] toUTF8ByteArray(String string)
{
return toUTF8ByteArray(string.toCharArray());
@@ -230,6 +241,37 @@
}
/**
+ * Constant time string comparison.
+ *
+ * @param a a string.
+ * @param b another string to compare to a.
+ *
+ * @return true if a and b represent the same string, false otherwise.
+ */
+ public static boolean constantTimeAreEqual(String a, String b)
+ {
+ boolean isEqual = a.length() == b.length();
+ int len = a.length();
+
+ if (isEqual)
+ {
+ for (int i = 0; i != len; i++)
+ {
+ isEqual &= (a.charAt(i) == b.charAt(i));
+ }
+ }
+ else
+ {
+ for (int i = 0; i != len; i++)
+ {
+ isEqual &= (a.charAt(i) == ' ');
+ }
+ }
+
+ return isEqual;
+ }
+
+ /**
* Convert an array of 8 bit characters into a string.
*
* @param bytes 8 bit characters.
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base32.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base32.java
new file mode 100644
index 0000000..61fa7f2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base32.java
@@ -0,0 +1,176 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.encoders;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * Utility class for converting Base32 data to bytes and back again.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Base32
+{
+ private static final Encoder encoder = new Base32Encoder();
+
+ public static String toBase32String(
+ byte[] data)
+ {
+ return toBase32String(data, 0, data.length);
+ }
+
+ public static String toBase32String(
+ byte[] data,
+ int off,
+ int length)
+ {
+ byte[] encoded = encode(data, off, length);
+ return Strings.fromByteArray(encoded);
+ }
+
+ /**
+ * encode the input data producing a base 32 encoded byte array.
+ *
+ * @return a byte array containing the base 32 encoded data.
+ */
+ public static byte[] encode(
+ byte[] data)
+ {
+ return encode(data, 0, data.length);
+ }
+
+ /**
+ * encode the input data producing a base 32 encoded byte array.
+ *
+ * @return a byte array containing the base 32 encoded data.
+ */
+ public static byte[] encode(
+ byte[] data,
+ int off,
+ int length)
+ {
+ int len = encoder.getEncodedLength(length);
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.encode(data, off, length, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new EncoderException("exception encoding base32 string: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * Encode the byte data to base 32 writing it to the given output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int encode(
+ byte[] data,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.encode(data, 0, data.length, out);
+ }
+
+ /**
+ * Encode the byte data to base 32 writing it to the given output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int encode(
+ byte[] data,
+ int off,
+ int length,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.encode(data, off, length, out);
+ }
+
+ /**
+ * decode the base 32 encoded input data. It is assumed the input data is valid.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ byte[] data)
+ {
+ int len = data.length / 8 * 5;
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.decode(data, 0, data.length, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base32 data: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * decode the base 32 encoded String data - whitespace will be ignored.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ String data)
+ {
+ int len = data.length() / 8 * 5;
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.decode(data, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base32 string: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * decode the base 32 encoded String data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int decode(
+ String data,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.decode(data, out);
+ }
+
+ /**
+ * Decode to an output stream;
+ *
+ * @param base32Data The source data.
+ * @param start Start position.
+ * @param length the length.
+ * @param out The output stream to write to.
+ */
+ public static int decode(byte[] base32Data, int start, int length, OutputStream out)
+ {
+ try
+ {
+ return encoder.decode(base32Data, start, length, out);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base32 data: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base32Encoder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base32Encoder.java
new file mode 100644
index 0000000..2711d7d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base32Encoder.java
@@ -0,0 +1,455 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.encoders;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * A streaming Base32 encoder.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Base32Encoder
+ implements Encoder
+{
+ private static final byte[] DEAULT_ENCODING_TABLE =
+ {
+ (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+ (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+ (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+ (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+ (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7'
+ };
+
+ private static final byte DEFAULT_PADDING = (byte)'=';
+
+ /*
+ * set up the decoding table.
+ */
+ private final byte[] encodingTable;
+ private final byte padding;
+ private final byte[] decodingTable = new byte[128];
+
+ 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;
+ }
+ }
+
+ /**
+ * Base constructor for RFC 4648, Section 6.
+ */
+ public Base32Encoder()
+ {
+ this.encodingTable = DEAULT_ENCODING_TABLE;
+ this.padding = DEFAULT_PADDING;
+
+ initialiseDecodingTable();
+ }
+
+ /**
+ * Constructor allowing the setting of an alternative alphabet.
+ *
+ * @param encodingTable a 32 entry encoding table to do the mapping.
+ * @param padding the padding value to use.
+ */
+ public Base32Encoder(byte[] encodingTable, byte padding)
+ {
+ if (encodingTable.length != 32)
+ {
+ throw new IllegalArgumentException("encoding table needs to be length 32");
+ }
+
+ this.encodingTable = Arrays.clone(encodingTable);
+ this.padding = padding;
+
+ initialiseDecodingTable();
+ }
+
+ public int encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) throws IOException
+ {
+ int inPos = inOff;
+ int inEnd = inOff + inLen - 4;
+ int outPos = outOff;
+
+ while (inPos < inEnd)
+ {
+ encodeBlock(inBuf, inPos, outBuf, outPos);
+ inPos += 5;
+ outPos += 8;
+ }
+
+ int extra = inLen - (inPos - inOff);
+ if (extra > 0)
+ {
+ byte[] in = new byte[5];
+ System.arraycopy(inBuf, inPos, in, 0, extra);
+ encodeBlock(in, 0, outBuf, outPos);
+ switch (extra)
+ {
+ case 1:
+ outBuf[outPos + 2] = padding;
+ outBuf[outPos + 3] = padding;
+ outBuf[outPos + 4] = padding;
+ outBuf[outPos + 5] = padding;
+ outBuf[outPos + 6] = padding;
+ outBuf[outPos + 7] = padding;
+ break;
+ case 2:
+ outBuf[outPos + 4] = padding;
+ outBuf[outPos + 5] = padding;
+ outBuf[outPos + 6] = padding;
+ outBuf[outPos + 7] = padding;
+ break;
+ case 3:
+ outBuf[outPos + 5] = padding;
+ outBuf[outPos + 6] = padding;
+ outBuf[outPos + 7] = padding;
+ break;
+ case 4:
+ outBuf[outPos + 7] = padding;
+ break;
+ }
+
+ outPos += 8;
+ }
+
+ return outPos - outOff;
+ }
+
+ private void encodeBlock(byte[] inBuf, int inPos, byte[] outBuf, int outPos)
+ {
+ int a1 = inBuf[inPos++];
+ int a2 = inBuf[inPos++] & 0xFF;
+ int a3 = inBuf[inPos++] & 0xFF;
+ int a4 = inBuf[inPos++] & 0xFF;
+ int a5 = inBuf[inPos] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[(a1 >>> 3) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a1 << 2) | (a2 >>> 6)) & 0x1F];
+ outBuf[outPos++] = encodingTable[(a2 >>> 1) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a2 << 4) | (a3 >>> 4)) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a3 << 1) | (a4 >>> 7)) & 0x1F];
+ outBuf[outPos++] = encodingTable[(a4 >>> 2) & 0x1F];
+ outBuf[outPos++] = encodingTable[((a4 << 3) | (a5 >>> 5)) & 0x1F];
+ outBuf[outPos] = encodingTable[a5 & 0x1F];
+ }
+
+ public int getEncodedLength(int inputLength)
+ {
+ return (inputLength + 4) / 5 * 8;
+ }
+
+ public int getMaxDecodedLength(int inputLength)
+ {
+ return inputLength / 8 * 5;
+ }
+
+ /**
+ * encode the input data producing a base 32 output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public int encode(byte[] buf, int off, int len, OutputStream out)
+ throws IOException
+ {
+ if (len < 0)
+ {
+ return 0;
+ }
+
+ byte[] tmp = new byte[72];
+ int remaining = len;
+ while (remaining > 0)
+ {
+ int inLen = Math.min(45, remaining);
+ int outLen = encode(buf, off, inLen, tmp, 0);
+ out.write(tmp, 0, outLen);
+ off += inLen;
+ remaining -= inLen;
+ }
+ return (len + 2) / 3 * 4;
+ }
+
+ private boolean ignore(
+ char c)
+ {
+ return (c == '\n' || c =='\r' || c == '\t' || c == ' ');
+ }
+
+ /**
+ * decode the base 32 encoded byte data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public int decode(
+ byte[] data,
+ int off,
+ int length,
+ OutputStream out)
+ throws IOException
+ {
+ byte b1, b2, b3, b4, b5, b6, b7, b8;
+ byte[] outBuffer = new byte[55];
+ int bufOff = 0;
+ int outLen = 0;
+
+ int end = off + length;
+
+ while (end > off)
+ {
+ if (!ignore((char)data[end - 1]))
+ {
+ break;
+ }
+
+ end--;
+ }
+
+ // empty data!
+ if (end == 0)
+ {
+ return 0;
+ }
+
+ int i = 0;
+ int finish = end;
+
+ while (finish > off && i != 8)
+ {
+ if (!ignore((char)data[finish - 1]))
+ {
+ i++;
+ }
+
+ finish--;
+ }
+
+ i = nextI(data, off, finish);
+
+ while (i < finish)
+ {
+ b1 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b2 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b3 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b4 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b5 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b6 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b7 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b8 = decodingTable[data[i++]];
+
+ if ((b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8) < 0)
+ {
+ throw new IOException("invalid characters encountered in base32 data");
+ }
+
+ outBuffer[bufOff++] = (byte)((b1 << 3) | (b2 >> 2));
+ outBuffer[bufOff++] = (byte)((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ outBuffer[bufOff++] = (byte)((b4 << 4) | (b5 >> 1));
+ outBuffer[bufOff++] = (byte)((b5 << 7) | (b6 << 2) | (b7 >> 3));
+ outBuffer[bufOff++] = (byte)((b7 << 5) | b8);
+
+ if (bufOff == outBuffer.length)
+ {
+ out.write(outBuffer);
+ bufOff = 0;
+ }
+
+ outLen += 5;
+
+ i = nextI(data, i, finish);
+ }
+
+ if (bufOff > 0)
+ {
+ out.write(outBuffer, 0, bufOff);
+ }
+
+ int e0 = nextI(data, i, end);
+ int e1 = nextI(data, e0 + 1, end);
+ int e2 = nextI(data, e1 + 1, end);
+ int e3 = nextI(data, e2 + 1, end);
+ int e4 = nextI(data, e3 + 1, end);
+ int e5 = nextI(data, e4 + 1, end);
+ int e6 = nextI(data, e5 + 1, end);
+ int e7 = nextI(data, e6 + 1, end);
+
+ outLen += decodeLastBlock(out,
+ (char)data[e0], (char)data[e1], (char)data[e2], (char)data[e3],
+ (char)data[e4], (char)data[e5], (char)data[e6], (char)data[e7]);
+
+ return outLen;
+ }
+
+ private int nextI(byte[] data, int i, int finish)
+ {
+ while ((i < finish) && ignore((char)data[i]))
+ {
+ i++;
+ }
+ return i;
+ }
+
+ /**
+ * decode the base 32 encoded String data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public int decode(
+ String data,
+ OutputStream out)
+ throws IOException
+ {
+ byte[] bytes = Strings.toByteArray(data);
+ return decode(bytes, 0, bytes.length, out);
+ }
+
+ private int decodeLastBlock(OutputStream out,
+ char c1, char c2, char c3, char c4,
+ char c5, char c6, char c7, char c8)
+ throws IOException
+ {
+ byte b1, b2, b3, b4, b5, b6, b7, b8;
+
+ if (c8 == padding)
+ {
+ if (c7 != padding)
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+ b5 = decodingTable[c5];
+ b6 = decodingTable[c6];
+ b7 = decodingTable[c7];
+
+ if ((b1 | b2 | b3 | b4 | b5 | b6 | b7) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ out.write((b4 << 4) | (b5 >> 1));
+ out.write((b5 << 7) | (b6 << 2) | (b7 >> 3));
+
+ return 4;
+ }
+ if (c6 != padding)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ if (c5 != padding)
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+ b5 = decodingTable[c5];
+
+ if ((b1 | b2 | b3 | b4 | b5) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ out.write((b4 << 4) | (b5 >> 1));
+
+ return 3;
+ }
+
+ if (c4 != padding)
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+
+ if ((b1 | b2 | b3 | b4) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+
+ return 2;
+ }
+
+ if (c3 != padding)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+
+ if ((b1 | b2) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+
+ return 1;
+ }
+ else
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+ b5 = decodingTable[c5];
+ b6 = decodingTable[c6];
+ b7 = decodingTable[c7];
+ b8 = decodingTable[c8];
+
+ if ((b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base32 data");
+ }
+
+ out.write((b1 << 3) | (b2 >> 2));
+ out.write((b2 << 6) | (b3 << 1) | (b4 >> 4));
+ out.write((b4 << 4) | (b5 >> 1));
+ out.write((b5 << 7) | (b6 << 2) | (b7 >> 3));
+ out.write((b7 << 5) | b8);
+
+ return 5;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64.java
index fa5bebf..7bc0560 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64.java
@@ -51,7 +51,7 @@
int off,
int length)
{
- int len = (length + 2) / 3 * 4;
+ int len = encoder.getEncodedLength(length);
ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
try
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java
index cda38c1..52c4b8c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java
@@ -98,24 +98,40 @@
return outPos - outOff;
}
+ public int getEncodedLength(int inputLength)
+ {
+ return (inputLength + 2) / 3 * 4;
+ }
+
+ public int getMaxDecodedLength(int inputLength)
+ {
+ return inputLength / 4 * 3;
+ }
+
/**
* encode the input data producing a base 64 output stream.
*
* @return the number of bytes produced.
*/
- public int encode(byte[] buf, int off, int len, OutputStream out)
+ public int encode(byte[] buf, int off, int len, OutputStream out)
throws IOException
{
- byte[] tmp = new byte[72];
- while (len > 0)
+ if (len < 0)
{
- int inLen = Math.min(54, len);
+ return 0;
+ }
+
+ byte[] tmp = new byte[72];
+ int remaining = len;
+ while (remaining > 0)
+ {
+ int inLen = Math.min(54, remaining);
int outLen = encode(buf, off, inLen, tmp, 0);
out.write(tmp, 0, outLen);
off += inLen;
- len -= inLen;
+ remaining -= inLen;
}
- return ((len + 2) / 3) * 4;
+ return (len + 2) / 3 * 4;
}
private boolean ignore(
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Encoder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Encoder.java
index 59a5114..5f425f4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Encoder.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Encoder.java
@@ -11,6 +11,23 @@
*/
public interface Encoder
{
+ /**
+ * Return the expected output length of the encoding.
+ *
+ * @param inputLength the input length of the data.
+ * @return the output length of an encoding.
+ */
+ int getEncodedLength(int inputLength);
+
+ /**
+ * Return the maximum expected output length of a decoding. If padding
+ * is present the value returned will be greater than the decoded data length.
+ *
+ * @param inputLength the input length of the encoded data.
+ * @return the upper bound of the output length of a decoding.
+ */
+ int getMaxDecodedLength(int inputLength);
+
int encode(byte[] data, int off, int length, OutputStream out) throws IOException;
int decode(byte[] data, int off, int length, OutputStream out) throws IOException;
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java
index 93ec068..14a0081 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java
@@ -64,6 +64,16 @@
return outPos - outOff;
}
+ public int getEncodedLength(int inputLength)
+ {
+ return inputLength * 2;
+ }
+
+ public int getMaxDecodedLength(int inputLength)
+ {
+ return inputLength / 2;
+ }
+
/**
* encode the input data producing a Hex output stream.
*
@@ -72,14 +82,20 @@
public int encode(byte[] buf, int off, int len, OutputStream out)
throws IOException
{
- byte[] tmp = new byte[72];
- while (len > 0)
+ if (len < 0)
{
- int inLen = Math.min(36, len);
+ return 0;
+ }
+
+ byte[] tmp = new byte[72];
+ int remaining = len;
+ while (remaining > 0)
+ {
+ int inLen = Math.min(36, remaining);
int outLen = encode(buf, off, inLen, tmp, 0);
out.write(tmp, 0, outLen);
off += inLen;
- len -= inLen;
+ remaining -= inLen;
}
return len * 2;
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/UTF8.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/UTF8.java
index c6f49f6..1a541a1 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/UTF8.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/UTF8.java
@@ -3,7 +3,7 @@
/**
* Utilities for working with UTF-8 encodings.
- *
+ * <p>
* Decoding of UTF-8 is based on a presentation by Bob Steagall at CppCon2018 (see
* https://github.com/BobSteagall/CppCon2018). It uses a Deterministic Finite Automaton (DFA) to
* recognize and decode multi-byte code points.
@@ -73,8 +73,8 @@
fill(transitionTable, S_P4A + 0x9, S_P4A + 0xB, S_CS2);
fill(transitionTable, S_P4B + 0x8, S_P4B + 0x8, S_CS2);
- byte[] firstUnitMasks = { 0x00, 0x00, 0x00, 0x00, 0x1F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07 };
- byte[] firstUnitTransitions = { S_ERR, S_ERR, S_ERR, S_ERR, S_CS1, S_P3A, S_CS2, S_P3B, S_P4A, S_CS3, S_P4B };
+ byte[] firstUnitMasks = {0x00, 0x00, 0x00, 0x00, 0x1F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07};
+ byte[] firstUnitTransitions = {S_ERR, S_ERR, S_ERR, S_ERR, S_CS1, S_P3A, S_CS2, S_P3B, S_P4A, S_CS3, S_P4B};
for (int i = 0x00; i < 0x80; ++i)
{
@@ -96,26 +96,52 @@
* "overlong" encodings, and unmappable code points. In particular, no unmatched surrogates will
* be produced. An error will also result if {@code utf16} is found to be too small to store the
* complete output.
- *
- * @param utf8
- * A non-null array containing a well-formed UTF-8 encoding.
- * @param utf16
- * A non-null array, at least as long as the {@code utf8} array in order to ensure
- * the output will fit.
+ *
+ * @param utf8 A non-null array containing a well-formed UTF-8 encoding.
+ * @param utf16 A non-null array, at least as long as the {@code utf8} array in order to ensure
+ * the output will fit.
* @return The number of UTF-16 code units written to {@code utf16} (beginning from index 0), or
- * else -1 if the input was either malformed or encoded any unmappable characters, or if
- * the {@code utf16} is too small.
+ * else -1 if the input was either malformed or encoded any unmappable characters, or if
+ * the {@code utf16} is too small.
*/
public static int transcodeToUTF16(byte[] utf8, char[] utf16)
{
- int i = 0, j = 0;
+ return transcodeToUTF16(utf8, 0, utf8.length, utf16);
+ }
- while (i < utf8.length)
+ /**
+ * Transcode a UTF-8 encoding into a UTF-16 representation. In the general case the output
+ * {@code utf16} array should be at least as long as the input length from {@code utf8} to handle
+ * arbitrary inputs. The number of output UTF-16 code units is returned, or -1 if any errors are
+ * encountered (in which case an arbitrary amount of data may have been written into the output
+ * array). Errors that will be detected are malformed UTF-8, including incomplete, truncated or
+ * "overlong" encodings, and unmappable code points. In particular, no unmatched surrogates will
+ * be produced. An error will also result if {@code utf16} is found to be too small to store the
+ * complete output.
+ *
+ * @param utf8 A non-null array containing a well-formed UTF-8 encoding.
+ * @param utf8Off start position in the array for the well-formed encoding.
+ * @param utf8Length length in bytes of the well-formed encoding.
+ * @param utf16 A non-null array, at least as long as the {@code utf8} array in order to ensure
+ * the output will fit.
+ * @return The number of UTF-16 code units written to {@code utf16} (beginning from index 0), or
+ * else -1 if the input was either malformed or encoded any unmappable characters, or if
+ * the {@code utf16} is too small.
+ */
+ public static int transcodeToUTF16(byte[] utf8, int utf8Off, int utf8Length, char[] utf16)
+ {
+ int i = utf8Off, j = 0;
+ int maxI = utf8Off + utf8Length;
+
+ while (i < maxI)
{
byte codeUnit = utf8[i++];
if (codeUnit >= 0)
{
- if (j >= utf16.length) { return -1; }
+ if (j >= utf16.length)
+ {
+ return -1;
+ }
utf16[j++] = (char)codeUnit;
continue;
@@ -127,25 +153,37 @@
while (state >= 0)
{
- if (i >= utf8.length) { return -1; }
+ if (i >= maxI)
+ {
+ return -1;
+ }
codeUnit = utf8[i++];
codePoint = (codePoint << 6) | (codeUnit & 0x3F);
state = transitionTable[state + ((codeUnit & 0xFF) >>> 4)];
}
- if (state == S_ERR) { return -1; }
+ if (state == S_ERR)
+ {
+ return -1;
+ }
if (codePoint <= 0xFFFF)
{
- if (j >= utf16.length) { return -1; }
+ if (j >= utf16.length)
+ {
+ return -1;
+ }
// Code points from U+D800 to U+DFFF are caught by the DFA
utf16[j++] = (char)codePoint;
}
else
{
- if (j >= utf16.length - 1) { return -1; }
+ if (j >= utf16.length - 1)
+ {
+ return -1;
+ }
// Code points above U+10FFFF are caught by the DFA
utf16[j++] = (char)(0xD7C0 + (codePoint >>> 10));
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/Streams.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/Streams.java
index 2c0a2ad..74a2cbf 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/Streams.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/Streams.java
@@ -30,6 +30,64 @@
}
/**
+ * Write the full contents of inStr to the destination stream outStr.
+ *
+ * @param inStr source input stream.
+ * @param outStr destination output stream.
+ * @throws IOException in case of underlying IOException.
+ */
+ public static void pipeAll(InputStream inStr, OutputStream outStr)
+ throws IOException
+ {
+ pipeAll(inStr, outStr, BUFFER_SIZE);
+ }
+
+ /**
+ * Write the full contents of inStr to the destination stream outStr.
+ *
+ * @param inStr source input stream.
+ * @param outStr destination output stream.
+ * @param bufferSize the size of temporary buffer to use.
+ * @throws IOException in case of underlying IOException.
+ */
+ public static void pipeAll(InputStream inStr, OutputStream outStr, int bufferSize)
+ throws IOException
+ {
+ byte[] bs = new byte[bufferSize];
+ int numRead;
+ while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ {
+ outStr.write(bs, 0, numRead);
+ }
+ }
+
+ /**
+ * Write up to limit bytes of data from inStr to the destination stream outStr.
+ *
+ * @param inStr source input stream.
+ * @param limit the maximum number of bytes allowed to be read.
+ * @param outStr destination output stream.
+ * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it.
+ */
+ public static long pipeAllLimited(InputStream inStr, long limit, OutputStream outStr)
+ throws IOException
+ {
+ long total = 0;
+ byte[] bs = new byte[BUFFER_SIZE];
+ int numRead;
+ while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ {
+ if ((limit - total) < numRead)
+ {
+ throw new StreamOverflowException("Data Overflow");
+ }
+ total += numRead;
+ outStr.write(bs, 0, numRead);
+ }
+ return total;
+ }
+
+ /**
* Read stream fully, returning contents in a byte array.
*
* @param inStr stream to be read.
@@ -98,51 +156,22 @@
}
totalRead += numRead;
}
+
return totalRead;
}
- /**
- * Write the full contents of inStr to the destination stream outStr.
- *
- * @param inStr source input stream.
- * @param outStr destination output stream.
- * @throws IOException in case of underlying IOException.
- */
- public static void pipeAll(InputStream inStr, OutputStream outStr)
- throws IOException
+ public static void validateBufferArguments(byte[] buf, int off, int len)
{
- byte[] bs = new byte[BUFFER_SIZE];
- int numRead;
- while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ if (buf == null)
{
- outStr.write(bs, 0, numRead);
+ throw new NullPointerException();
}
- }
-
- /**
- * Write up to limit bytes of data from inStr to the destination stream outStr.
- *
- * @param inStr source input stream.
- * @param limit the maximum number of bytes allowed to be read.
- * @param outStr destination output stream.
- * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it.
- */
- public static long pipeAllLimited(InputStream inStr, long limit, OutputStream outStr)
- throws IOException
- {
- long total = 0;
- byte[] bs = new byte[BUFFER_SIZE];
- int numRead;
- while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ int available = buf.length - off;
+ int remaining = available - len;
+ if ((off | len | available | remaining) < 0)
{
- if ((limit - total) < numRead)
- {
- throw new StreamOverflowException("Data Overflow");
- }
- total += numRead;
- outStr.write(bs, 0, numRead);
+ throw new IndexOutOfBoundsException();
}
- return total;
}
public static void writeBufTo(ByteArrayOutputStream buf, OutputStream output)
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java
index a192b36..9d3f1af 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java
@@ -66,9 +66,9 @@
while ((line = readLine()) != null)
{
- if (line.indexOf(":") >= 0)
+ int index = line.indexOf(':');
+ if (index >= 0)
{
- int index = line.indexOf(':');
String hdr = line.substring(0, index);
String value = line.substring(index + 1).trim();
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java
index 6ae4aee..7a93330 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java
@@ -22,12 +22,12 @@
import java.util.List;
import java.util.Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.x509.AttributeCertificate;
import com.android.internal.org.bouncycastle.asn1.x509.Extension;
import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
@@ -125,7 +125,7 @@
public boolean[] getIssuerUniqueID()
{
- DERBitString id = cert.getAcinfo().getIssuerUniqueID();
+ ASN1BitString id = cert.getAcinfo().getIssuerUniqueID();
if (id != null)
{