summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 00:58:37 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 00:58:37 +0000
commit1e201bf77448cc26721162305cc452e78a76b4f5 (patch)
tree39be991fa9e225803cfa7afe5e139ae3afa38a29
parentfb205187c81bc4c0126d870786ce4efd24483e12 (diff)
parent7133133ed9e493acc9bd3b7a656d90599e663851 (diff)
downloadbouncycastle-android14-mainline-tethering-release.tar.gz
Change-Id: Ifde4f0c586a0b8237dc29a800eb5e89b8acadd1a
-rw-r--r--Android.bp23
-rw-r--r--OWNERS7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java48
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java48
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateHolder.java374
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateIssuer.java149
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertException.java29
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertIOException.java31
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertUtils.java330
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509AttributeCertificateHolder.java394
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLEntryHolder.java146
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLHolder.java370
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CertificateHolder.java355
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java423
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/jcajce/JcaCertStore.java66
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/jcajce/JcaX509CertificateHolder.java28
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/selector/MSOutlookKeyIdCalculator.java423
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java154
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAbsentContent.java51
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerationException.java36
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerator.java23
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSException.java36
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessable.java23
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessableByteArray.java57
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSReadable.java11
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSRuntimeException.java36
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java19
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java19
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedData.java636
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedDataGenerator.java234
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedGenerator.java256
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedHelper.java272
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignerDigestMismatchException.java15
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSTypedData.java13
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSUtils.java396
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java15
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java249
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java75
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java133
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/NullOutputStream.java29
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PKCS7ProcessableObject.java69
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PasswordRecipient.java54
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/Recipient.java9
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/RecipientOperator.java64
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerId.java106
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGenerator.java312
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java142
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformation.java760
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationStore.java145
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationVerifier.java55
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SimpleAttributeTableGenerator.java27
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java90
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java184
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java154
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentSigner.java39
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentVerifier.java40
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentVerifierProvider.java36
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java203
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java451
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java28
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestCalculator.java38
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestCalculatorProvider.java14
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/GenericKey.java45
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/InputDecryptor.java31
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/MacCalculator.java40
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorCreationException.java19
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorException.java28
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorStreamException.java25
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/RawContentVerifier.java19
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/RuntimeOperatorException.java28
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/SignatureAlgorithmIdentifierFinder.java19
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java185
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java84
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestProvider.java15
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java278
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java454
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java118
-rw-r--r--repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/OperatorHelper.java624
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java48
-rwxr-xr-xsrcgen_platform/generate_android_src.sh6
80 files changed, 10993 insertions, 125 deletions
diff --git a/Android.bp b/Android.bp
index bdb67e02..fadb1f70 100644
--- a/Android.bp
+++ b/Android.bp
@@ -72,6 +72,17 @@ java_defaults {
},
},
},
+
+ 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
@@ -130,7 +141,10 @@ java_library {
defaults: ["bouncycastle-defaults"],
installable: true,
sdk_version: "core_current",
- srcs: ["repackaged_platform/bcprov/src/main/java/**/*.java"],
+ srcs: [
+ "repackaged_platform/bcpkix/src/main/java/**/*.java",
+ "repackaged_platform/bcprov/src/main/java/**/*.java",
+ ],
}
unbundled_visibility = [
@@ -141,6 +155,7 @@ unbundled_visibility = [
"//cts/tests/libcore/okhttp",
"//cts/tests/security",
"//cts/tests/tests/keystore",
+ "//external/android-key-attestation",
"//external/conscrypt",
"//external/okhttp",
"//external/robolectric-shadows",
@@ -158,6 +173,7 @@ unbundled_visibility = [
"//packages/apps/KeyChain",
"//packages/apps/RemoteProvisioner/tests/unittests",
"//packages/modules/Connectivity/tests/cts/net",
+ "//packages/modules/RemoteKeyProvisioning/app/tests/unit",
"//packages/modules/Wifi/service",
"//packages/modules/Wifi/service/tests/wifitests",
"//libcore",
@@ -198,6 +214,8 @@ java_library {
libs: ["bouncycastle-unbundled"],
sdk_version: "core_current",
+ // b/267608166: Allow to be used by components targeting Java 11.
+ java_version: "11",
}
// Bouncycastle OCSP classes in the original org.bouncycastle package for use
@@ -279,6 +297,9 @@ java_library {
"bcprov/src/main/java/org/bouncycastle/iana/**/*.java",
],
sdk_version: "core_current",
+ lint: {
+ warning_checks: ["SuspiciousIndentation"],
+ },
}
// Bouncycastle for use by packages/modules/Uwb project.
diff --git a/OWNERS b/OWNERS
index c3b459cc..73617ea1 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,7 +1,2 @@
# Bug component: 684135
-prb@google.com
-
-mast@google.com
-miguelaranda@google.com
-rpl@google.com
-sorinbasca@google.com
+include platform/libcore:/OWNERS
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 8c678059..7dadfa7f 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
@@ -957,56 +957,26 @@ public class BaseBlockCipher
{
byte[] iv = new byte[ivLength];
- // BEGIN Android-changed: For PBE keys with no IV, log and use IV of 0
+ // BEGIN Android-changed: Reject PBE keys with no IV
// These keys were accepted in BC 1.52 (and treated as having an IV of 0) but
- // rejected outright in BC 1.54 (even if an IV was passed in params). We
- // want the eventual state to be that an IV can be passed in params, but the key
- // is rejected otherwise. For now, log that these will be rejected in a future
- // release. See b/27995180 for historical details.
- // ivRandom.nextBytes(iv);
+ // rejected outright in BC 1.54 (even if an IV was passed in params).
+ // See b/27995180 for historical details.
if (!isBCPBEKeyWithoutIV(key)) {
ivRandom.nextBytes(iv);
} else {
- // TODO(b/70275132): Change to rejecting these keys
- System.err.println(" ******** DEPRECATED FUNCTIONALITY ********");
- System.err.println(" * You have initialized a cipher with a PBE key with no IV and");
- System.err.println(" * have not provided an IV in the AlgorithmParameterSpec. This");
- System.err.println(" * configuration is deprecated. The cipher will be initialized");
- System.err.println(" * with an all-zero IV, but in a future release this call will");
- System.err.println(" * throw an exception.");
- new InvalidAlgorithmParameterException("No IV set when using PBE key")
- .printStackTrace(System.err);
+ throw new InvalidAlgorithmParameterException("No IV set when using PBE key");
}
- // END Android-changed: For PBE keys with no IV, log and use IV of 0
+ // END Android-changed: Reject PBE keys with no IV
param = new ParametersWithIV(param, iv);
ivParam = (ParametersWithIV)param;
}
else if (cipher.getUnderlyingCipher().getAlgorithmName().indexOf("PGPCFB") < 0)
{
- // BEGIN Android-changed: For PBE keys with no IV, log and use IV of 0
+ // BEGIN Android-changed: Reject PBE keys with no IV
// These keys were accepted in BC 1.52 (and treated as having an IV of 0) but
- // rejected outright in BC 1.54 (even if an IV was passed in params). We
- // want the eventual state to be that an IV can be passed in params, but the key
- // is rejected otherwise. For now, log that these will be rejected in a future
- // release. See b/27995180 for historical details.
- // throw new InvalidAlgorithmParameterException("no IV set when one expected");
- if (!isBCPBEKeyWithoutIV(key)) {
- throw new InvalidAlgorithmParameterException("no IV set when one expected");
- } else {
- // TODO(b/70275132): Change to rejecting these keys
- System.err.println(" ******** DEPRECATED FUNCTIONALITY ********");
- System.err.println(" * You have initialized a cipher with a PBE key with no IV and");
- System.err.println(" * have not provided an IV in the AlgorithmParameterSpec. This");
- System.err.println(" * configuration is deprecated. The cipher will be initialized");
- System.err.println(" * with an all-zero IV, but in a future release this call will");
- System.err.println(" * throw an exception.");
- new InvalidAlgorithmParameterException("No IV set when using PBE key")
- .printStackTrace(System.err);
- // Mimic behaviour in 1.52 by using an IV of 0's
- param = new ParametersWithIV(param, new byte[ivLength]);
- ivParam = (ParametersWithIV)param;
- }
- // END Android-changed: For PBE keys with no IV, log and use IV of 0
+ // rejected outright in BC 1.54 (even if an IV was passed in params).
+ throw new InvalidAlgorithmParameterException("No IV set when using PBE key");
+ // END Android-changed: Reject PBE keys with no IV
}
}
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 1eeb6e96..51310cb5 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
@@ -961,56 +961,26 @@ public class BaseBlockCipher
{
byte[] iv = new byte[ivLength];
- // BEGIN Android-changed: For PBE keys with no IV, log and use IV of 0
+ // BEGIN Android-changed: Reject PBE keys with no IV
// These keys were accepted in BC 1.52 (and treated as having an IV of 0) but
- // rejected outright in BC 1.54 (even if an IV was passed in params). We
- // want the eventual state to be that an IV can be passed in params, but the key
- // is rejected otherwise. For now, log that these will be rejected in a future
- // release. See b/27995180 for historical details.
- // ivRandom.nextBytes(iv);
+ // rejected outright in BC 1.54 (even if an IV was passed in params).
+ // See b/27995180 for historical details.
if (!isBCPBEKeyWithoutIV(key)) {
ivRandom.nextBytes(iv);
} else {
- // TODO(b/70275132): Change to rejecting these keys
- System.err.println(" ******** DEPRECATED FUNCTIONALITY ********");
- System.err.println(" * You have initialized a cipher with a PBE key with no IV and");
- System.err.println(" * have not provided an IV in the AlgorithmParameterSpec. This");
- System.err.println(" * configuration is deprecated. The cipher will be initialized");
- System.err.println(" * with an all-zero IV, but in a future release this call will");
- System.err.println(" * throw an exception.");
- new InvalidAlgorithmParameterException("No IV set when using PBE key")
- .printStackTrace(System.err);
+ throw new InvalidAlgorithmParameterException("No IV set when using PBE key");
}
- // END Android-changed: For PBE keys with no IV, log and use IV of 0
+ // END Android-changed: Reject PBE keys with no IV
param = new ParametersWithIV(param, iv);
ivParam = (ParametersWithIV)param;
}
else if (cipher.getUnderlyingCipher().getAlgorithmName().indexOf("PGPCFB") < 0)
{
- // BEGIN Android-changed: For PBE keys with no IV, log and use IV of 0
+ // BEGIN Android-changed: Reject PBE keys with no IV
// These keys were accepted in BC 1.52 (and treated as having an IV of 0) but
- // rejected outright in BC 1.54 (even if an IV was passed in params). We
- // want the eventual state to be that an IV can be passed in params, but the key
- // is rejected otherwise. For now, log that these will be rejected in a future
- // release. See b/27995180 for historical details.
- // throw new InvalidAlgorithmParameterException("no IV set when one expected");
- if (!isBCPBEKeyWithoutIV(key)) {
- throw new InvalidAlgorithmParameterException("no IV set when one expected");
- } else {
- // TODO(b/70275132): Change to rejecting these keys
- System.err.println(" ******** DEPRECATED FUNCTIONALITY ********");
- System.err.println(" * You have initialized a cipher with a PBE key with no IV and");
- System.err.println(" * have not provided an IV in the AlgorithmParameterSpec. This");
- System.err.println(" * configuration is deprecated. The cipher will be initialized");
- System.err.println(" * with an all-zero IV, but in a future release this call will");
- System.err.println(" * throw an exception.");
- new InvalidAlgorithmParameterException("No IV set when using PBE key")
- .printStackTrace(System.err);
- // Mimic behaviour in 1.52 by using an IV of 0's
- param = new ParametersWithIV(param, new byte[ivLength]);
- ivParam = (ParametersWithIV)param;
- }
- // END Android-changed: For PBE keys with no IV, log and use IV of 0
+ // rejected outright in BC 1.54 (even if an IV was passed in params).
+ throw new InvalidAlgorithmParameterException("No IV set when using PBE key");
+ // END Android-changed: Reject PBE keys with no IV
}
}
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
new file mode 100644
index 00000000..58541a8b
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateHolder.java
@@ -0,0 +1,374 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert;
+
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+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.x500.X500Name;
+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.asn1.x509.Holder;
+import com.android.internal.org.bouncycastle.asn1.x509.IssuerSerial;
+import com.android.internal.org.bouncycastle.asn1.x509.ObjectDigestInfo;
+import com.android.internal.org.bouncycastle.operator.DigestCalculator;
+import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Selector;
+
+/**
+ * The Holder object.
+ *
+ * <pre>
+ * Holder ::= SEQUENCE {
+ * baseCertificateID [0] IssuerSerial OPTIONAL,
+ * -- the issuer and serial number of
+ * -- the holder's Public Key Certificate
+ * entityName [1] GeneralNames OPTIONAL,
+ * -- the name of the claimant or role
+ * objectDigestInfo [2] ObjectDigestInfo OPTIONAL
+ * -- used to directly authenticate the holder,
+ * -- for example, an executable
+ * }
+ * </pre>
+ * <p>
+ * <b>Note:</b> If objectDigestInfo comparisons are to be carried out the static
+ * method setDigestCalculatorProvider <b>must</b> be called once to configure the class
+ * to do the necessary calculations.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AttributeCertificateHolder
+ implements Selector
+{
+ private static DigestCalculatorProvider digestCalculatorProvider;
+
+ final Holder holder;
+
+ AttributeCertificateHolder(ASN1Sequence seq)
+ {
+ holder = Holder.getInstance(seq);
+ }
+
+ /**
+ * Create a holder using the baseCertificateID element.
+ *
+ * @param issuerName name of associated certificate's issuer.
+ * @param serialNumber serial number of associated certificate.
+ */
+ public AttributeCertificateHolder(X500Name issuerName,
+ BigInteger serialNumber)
+ {
+ holder = new Holder(new IssuerSerial(
+ generateGeneralNames(issuerName),
+ new ASN1Integer(serialNumber)));
+ }
+
+ /**
+ * Create a holder using the baseCertificateID option based on the passed in associated certificate,
+ *
+ * @param cert the certificate to be associated with this holder.
+ */
+ public AttributeCertificateHolder(X509CertificateHolder cert)
+ {
+ holder = new Holder(new IssuerSerial(generateGeneralNames(cert.getIssuer()),
+ new ASN1Integer(cert.getSerialNumber())));
+ }
+
+ /**
+ * Create a holder using the entityName option based on the passed in principal.
+ *
+ * @param principal the entityName to be associated with the attribute certificate.
+ */
+ public AttributeCertificateHolder(X500Name principal)
+ {
+ holder = new Holder(generateGeneralNames(principal));
+ }
+
+ /**
+ * Constructs a holder for v2 attribute certificates with a hash value for
+ * some type of object.
+ * <p>
+ * <code>digestedObjectType</code> can be one of the following:
+ * <ul>
+ * <li>0 - publicKey - A hash of the public key of the holder must be
+ * passed.
+ * <li>1 - publicKeyCert - A hash of the public key certificate of the
+ * holder must be passed.
+ * <li>2 - otherObjectDigest - A hash of some other object type must be
+ * passed. <code>otherObjectTypeID</code> must not be empty.
+ * </ul>
+ * <p>
+ * This cannot be used if a v1 attribute certificate is used.
+ *
+ * @param digestedObjectType The digest object type.
+ * @param digestAlgorithm The algorithm identifier for the hash.
+ * @param otherObjectTypeID The object type ID if
+ * <code>digestedObjectType</code> is
+ * <code>otherObjectDigest</code>.
+ * @param objectDigest The hash value.
+ */
+ public AttributeCertificateHolder(int digestedObjectType,
+ ASN1ObjectIdentifier digestAlgorithm, ASN1ObjectIdentifier otherObjectTypeID, byte[] objectDigest)
+ {
+ holder = new Holder(new ObjectDigestInfo(digestedObjectType,
+ otherObjectTypeID, new AlgorithmIdentifier(digestAlgorithm), Arrays
+ .clone(objectDigest)));
+ }
+
+ /**
+ * Returns the digest object type if an object digest info is used.
+ * <p>
+ * <ul>
+ * <li>0 - publicKey - A hash of the public key of the holder must be
+ * passed.
+ * <li>1 - publicKeyCert - A hash of the public key certificate of the
+ * holder must be passed.
+ * <li>2 - otherObjectDigest - A hash of some other object type must be
+ * passed. <code>otherObjectTypeID</code> must not be empty.
+ * </ul>
+ *
+ * @return The digest object type or -1 if no object digest info is set.
+ */
+ public int getDigestedObjectType()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ return holder.getObjectDigestInfo().getDigestedObjectType().intValueExact();
+ }
+ return -1;
+ }
+
+ /**
+ * Returns algorithm identifier for the digest used if ObjectDigestInfo is present.
+ *
+ * @return digest AlgorithmIdentifier or <code>null</code> if ObjectDigestInfo is absent.
+ */
+ public AlgorithmIdentifier getDigestAlgorithm()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ return holder.getObjectDigestInfo().getDigestAlgorithm();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the hash if an object digest info is used.
+ *
+ * @return The hash or <code>null</code> if ObjectDigestInfo is absent.
+ */
+ public byte[] getObjectDigest()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ return holder.getObjectDigestInfo().getObjectDigest().getBytes();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the digest algorithm ID if an object digest info is used.
+ *
+ * @return The digest algorithm ID or <code>null</code> if no object
+ * digest info is set.
+ */
+ public ASN1ObjectIdentifier getOtherObjectTypeID()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ new ASN1ObjectIdentifier(holder.getObjectDigestInfo().getOtherObjectTypeID().getId());
+ }
+ return null;
+ }
+
+ private GeneralNames generateGeneralNames(X500Name principal)
+ {
+ return new GeneralNames(new GeneralName(principal));
+ }
+
+ private boolean matchesDN(X500Name subject, GeneralNames targets)
+ {
+ GeneralName[] names = targets.getNames();
+
+ for (int i = 0; i != names.length; i++)
+ {
+ GeneralName gn = names[i];
+
+ if (gn.getTagNo() == GeneralName.directoryName)
+ {
+ if (X500Name.getInstance(gn.getName()).equals(subject))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private X500Name[] getPrincipals(GeneralName[] names)
+ {
+ List l = new ArrayList(names.length);
+
+ for (int i = 0; i != names.length; i++)
+ {
+ if (names[i].getTagNo() == GeneralName.directoryName)
+ {
+ l.add(X500Name.getInstance(names[i].getName()));
+ }
+ }
+
+ return (X500Name[])l.toArray(new X500Name[l.size()]);
+ }
+
+ /**
+ * Return any principal objects inside the attribute certificate holder
+ * entity names field.
+ *
+ * @return an array of Principal objects (usually X500Principal), null if no
+ * entity names field is set.
+ */
+ public X500Name[] getEntityNames()
+ {
+ if (holder.getEntityName() != null)
+ {
+ return getPrincipals(holder.getEntityName().getNames());
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the principals associated with the issuer attached to this holder
+ *
+ * @return an array of principals, null if no BaseCertificateID is set.
+ */
+ public X500Name[] getIssuer()
+ {
+ if (holder.getBaseCertificateID() != null)
+ {
+ return getPrincipals(holder.getBaseCertificateID().getIssuer().getNames());
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the serial number associated with the issuer attached to this
+ * holder.
+ *
+ * @return the certificate serial number, null if no BaseCertificateID is
+ * set.
+ */
+ public BigInteger getSerialNumber()
+ {
+ if (holder.getBaseCertificateID() != null)
+ {
+ return holder.getBaseCertificateID().getSerial().getValue();
+ }
+
+ return null;
+ }
+
+ public Object clone()
+ {
+ return new AttributeCertificateHolder((ASN1Sequence)holder.toASN1Primitive());
+ }
+
+ public boolean match(Object obj)
+ {
+ if (!(obj instanceof X509CertificateHolder))
+ {
+ return false;
+ }
+
+ X509CertificateHolder x509Cert = (X509CertificateHolder)obj;
+
+ if (holder.getBaseCertificateID() != null)
+ {
+ return holder.getBaseCertificateID().getSerial().hasValue(x509Cert.getSerialNumber())
+ && matchesDN(x509Cert.getIssuer(), holder.getBaseCertificateID().getIssuer());
+ }
+
+ if (holder.getEntityName() != null)
+ {
+ if (matchesDN(x509Cert.getSubject(),
+ holder.getEntityName()))
+ {
+ return true;
+ }
+ }
+
+ if (holder.getObjectDigestInfo() != null)
+ {
+ try
+ {
+ DigestCalculator digCalc = digestCalculatorProvider.get(holder.getObjectDigestInfo().getDigestAlgorithm());
+ OutputStream digOut = digCalc.getOutputStream();
+
+ switch (getDigestedObjectType())
+ {
+ case ObjectDigestInfo.publicKey:
+ // TODO: DSA Dss-parms
+ digOut.write(x509Cert.getSubjectPublicKeyInfo().getEncoded());
+ break;
+ case ObjectDigestInfo.publicKeyCert:
+ digOut.write(x509Cert.getEncoded());
+ break;
+ }
+
+ digOut.close();
+
+ if (!Arrays.areEqual(digCalc.getDigest(), getObjectDigest()))
+ {
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (!(obj instanceof AttributeCertificateHolder))
+ {
+ return false;
+ }
+
+ AttributeCertificateHolder other = (AttributeCertificateHolder)obj;
+
+ return this.holder.equals(other.holder);
+ }
+
+ public int hashCode()
+ {
+ return this.holder.hashCode();
+ }
+
+ /**
+ * Set a digest calculator provider to be used if matches are attempted using
+ * ObjectDigestInfo,
+ *
+ * @param digCalcProvider a provider of digest calculators.
+ */
+ public static void setDigestCalculatorProvider(DigestCalculatorProvider digCalcProvider)
+ {
+ digestCalculatorProvider = digCalcProvider;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateIssuer.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateIssuer.java
new file mode 100644
index 00000000..78350e3c
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateIssuer.java
@@ -0,0 +1,149 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.AttCertIssuer;
+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.V2Form;
+import com.android.internal.org.bouncycastle.util.Selector;
+
+/**
+ * Carrying class for an attribute certificate issuer.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AttributeCertificateIssuer
+ implements Selector
+{
+ final ASN1Encodable form;
+
+ /**
+ * Set the issuer directly with the ASN.1 structure.
+ *
+ * @param issuer The issuer
+ */
+ public AttributeCertificateIssuer(AttCertIssuer issuer)
+ {
+ form = issuer.getIssuer();
+ }
+
+ public AttributeCertificateIssuer(X500Name principal)
+ {
+ form = new V2Form(new GeneralNames(new GeneralName(principal)));
+ }
+
+ public X500Name[] getNames()
+ {
+ GeneralNames name;
+
+ if (form instanceof V2Form)
+ {
+ name = ((V2Form)form).getIssuerName();
+ }
+ else
+ {
+ name = (GeneralNames)form;
+ }
+
+ GeneralName[] names = name.getNames();
+
+ List l = new ArrayList(names.length);
+
+ for (int i = 0; i != names.length; i++)
+ {
+ if (names[i].getTagNo() == GeneralName.directoryName)
+ {
+ l.add(X500Name.getInstance(names[i].getName()));
+ }
+ }
+
+ return (X500Name[])l.toArray(new X500Name[l.size()]);
+ }
+
+ private boolean matchesDN(X500Name subject, GeneralNames targets)
+ {
+ GeneralName[] names = targets.getNames();
+
+ for (int i = 0; i != names.length; i++)
+ {
+ GeneralName gn = names[i];
+
+ if (gn.getTagNo() == GeneralName.directoryName)
+ {
+ if (X500Name.getInstance(gn.getName()).equals(subject))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public Object clone()
+ {
+ return new AttributeCertificateIssuer(AttCertIssuer.getInstance(form));
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (!(obj instanceof AttributeCertificateIssuer))
+ {
+ return false;
+ }
+
+ AttributeCertificateIssuer other = (AttributeCertificateIssuer)obj;
+
+ return this.form.equals(other.form);
+ }
+
+ public int hashCode()
+ {
+ return this.form.hashCode();
+ }
+
+ public boolean match(Object obj)
+ {
+ if (!(obj instanceof X509CertificateHolder))
+ {
+ return false;
+ }
+
+ X509CertificateHolder x509Cert = (X509CertificateHolder)obj;
+
+ if (form instanceof V2Form)
+ {
+ V2Form issuer = (V2Form)form;
+ if (issuer.getBaseCertificateID() != null)
+ {
+ return issuer.getBaseCertificateID().getSerial().hasValue(x509Cert.getSerialNumber())
+ && matchesDN(x509Cert.getIssuer(), issuer.getBaseCertificateID().getIssuer());
+ }
+
+ GeneralNames name = issuer.getIssuerName();
+ if (matchesDN(x509Cert.getSubject(), name))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ GeneralNames name = (GeneralNames)form;
+ if (matchesDN(x509Cert.getSubject(), name))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertException.java
new file mode 100644
index 00000000..b684053c
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertException.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert;
+
+/**
+ * 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 CertException
+ extends Exception
+{
+ private Throwable cause;
+
+ public CertException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public CertException(String msg)
+ {
+ super(msg);
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertIOException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertIOException.java
new file mode 100644
index 00000000..43280073
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertIOException.java
@@ -0,0 +1,31 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert;
+
+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 CertIOException
+ extends IOException
+{
+ private Throwable cause;
+
+ public CertIOException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public CertIOException(String msg)
+ {
+ super(msg);
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
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
new file mode 100644
index 00000000..ff8383ee
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertUtils.java
@@ -0,0 +1,330 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+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 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.ASN1GeneralizedTime;
+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.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+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.AttributeCertificate;
+import com.android.internal.org.bouncycastle.asn1.x509.AttributeCertificateInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
+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;
+import com.android.internal.org.bouncycastle.asn1.x509.ExtensionsGenerator;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertList;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertificate;
+import com.android.internal.org.bouncycastle.operator.ContentSigner;
+import com.android.internal.org.bouncycastle.util.Properties;
+
+class CertUtils
+{
+ private static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet());
+ private static List EMPTY_LIST = Collections.unmodifiableList(new ArrayList());
+
+ static ASN1Primitive parseNonEmptyASN1(byte[] encoding)
+ throws IOException
+ {
+ ASN1Primitive p = ASN1Primitive.fromByteArray(encoding);
+
+ if (p == null)
+ {
+ throw new IOException("no content found");
+ }
+ return p;
+ }
+
+
+ static X509CertificateHolder generateFullCert(ContentSigner signer, TBSCertificate tbsCert)
+ {
+ try
+ {
+ return new X509CertificateHolder(generateStructure(tbsCert, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCert)));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("cannot produce certificate signature");
+ }
+ }
+
+ static X509AttributeCertificateHolder generateFullAttrCert(ContentSigner signer, AttributeCertificateInfo attrInfo)
+ {
+ try
+ {
+ return new X509AttributeCertificateHolder(generateAttrStructure(attrInfo, signer.getAlgorithmIdentifier(), generateSig(signer, attrInfo)));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("cannot produce attribute certificate signature");
+ }
+ }
+
+ 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();
+
+ v.add(tbsCert);
+ v.add(sigAlgId);
+ v.add(new DERBitString(signature));
+
+ return Certificate.getInstance(new DERSequence(v));
+ }
+
+ private static AttributeCertificate generateAttrStructure(AttributeCertificateInfo attrInfo, AlgorithmIdentifier sigAlgId, byte[] signature)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(attrInfo);
+ v.add(sigAlgId);
+ v.add(new DERBitString(signature));
+
+ return AttributeCertificate.getInstance(new DERSequence(v));
+ }
+
+ private static CertificateList generateCRLStructure(TBSCertList tbsCertList, AlgorithmIdentifier sigAlgId, byte[] signature)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(tbsCertList);
+ v.add(sigAlgId);
+ v.add(new DERBitString(signature));
+
+ return CertificateList.getInstance(new DERSequence(v));
+ }
+
+ 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()));
+ }
+
+ static void addExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value)
+ throws CertIOException
+ {
+ try
+ {
+ extGenerator.addExtension(oid, isCritical, value);
+ }
+ catch (IOException e)
+ {
+ throw new CertIOException("cannot encode extension: " + e.getMessage(), e);
+ }
+ }
+
+ static DERBitString booleanToBitString(boolean[] id)
+ {
+ byte[] bytes = new byte[(id.length + 7) / 8];
+
+ for (int i = 0; i != id.length; i++)
+ {
+ bytes[i / 8] |= (id[i]) ? (1 << ((7 - (i % 8)))) : 0;
+ }
+
+ int pad = id.length % 8;
+
+ if (pad == 0)
+ {
+ return new DERBitString(bytes);
+ }
+ else
+ {
+ return new DERBitString(bytes, 8 - pad);
+ }
+ }
+
+ static boolean[] bitStringToBoolean(DERBitString bitString)
+ {
+ if (bitString != null)
+ {
+ byte[] bytes = bitString.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - bitString.getPadBits()];
+
+ for (int i = 0; i != boolId.length; i++)
+ {
+ boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+
+ return boolId;
+ }
+
+ return null;
+ }
+
+ static Date recoverDate(ASN1GeneralizedTime time)
+ {
+ try
+ {
+ return time.getDate();
+ }
+ catch (ParseException e)
+ {
+ throw new IllegalStateException("unable to recover date: " + e.getMessage());
+ }
+ }
+
+ static boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
+ {
+ if (!id1.getAlgorithm().equals(id2.getAlgorithm()))
+ {
+ return false;
+ }
+
+ if (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;
+ }
+
+ if (id2.getParameters() == null)
+ {
+ if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ if (id1.getParameters() != null)
+ {
+ return id1.getParameters().equals(id2.getParameters());
+ }
+
+ if (id2.getParameters() != null)
+ {
+ return id2.getParameters().equals(id1.getParameters());
+ }
+
+ return true;
+ }
+
+ static ExtensionsGenerator doReplaceExtension(ExtensionsGenerator extGenerator, Extension ext)
+ {
+ boolean isReplaced = false;
+ Extensions exts = extGenerator.generate();
+ extGenerator = new ExtensionsGenerator();
+
+ for (Enumeration en = exts.oids(); en.hasMoreElements();)
+ {
+ ASN1ObjectIdentifier extOid = (ASN1ObjectIdentifier)en.nextElement();
+
+ if (extOid.equals(ext.getExtnId()))
+ {
+ isReplaced = true;
+ extGenerator.addExtension(ext);
+ }
+ else
+ {
+ extGenerator.addExtension(exts.getExtension(extOid));
+ }
+ }
+
+ if (!isReplaced)
+ {
+ throw new IllegalArgumentException("replace - original extension (OID = " + ext.getExtnId() + ") not found");
+ }
+
+ return extGenerator;
+ }
+
+ static ExtensionsGenerator doRemoveExtension(ExtensionsGenerator extGenerator, ASN1ObjectIdentifier oid)
+ {
+ boolean isRemoved = false;
+ Extensions exts = extGenerator.generate();
+ extGenerator = new ExtensionsGenerator();
+
+ for (Enumeration en = exts.oids(); en.hasMoreElements();)
+ {
+ ASN1ObjectIdentifier extOid = (ASN1ObjectIdentifier)en.nextElement();
+
+ if (extOid.equals(oid))
+ {
+ isRemoved = true;
+ }
+ else
+ {
+ extGenerator.addExtension(exts.getExtension(extOid));
+ }
+ }
+
+ if (!isRemoved)
+ {
+ throw new IllegalArgumentException("remove - extension (OID = " + oid + ") not found");
+ }
+
+ return extGenerator;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509AttributeCertificateHolder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509AttributeCertificateHolder.java
new file mode 100644
index 00000000..b357af2d
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509AttributeCertificateHolder.java
@@ -0,0 +1,394 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.util.ArrayList;
+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.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.AttCertValidityPeriod;
+import com.android.internal.org.bouncycastle.asn1.x509.Attribute;
+import com.android.internal.org.bouncycastle.asn1.x509.AttributeCertificate;
+import com.android.internal.org.bouncycastle.asn1.x509.AttributeCertificateInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.operator.ContentVerifier;
+import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider;
+import com.android.internal.org.bouncycastle.util.Encodable;
+
+/**
+ * Holding class for an X.509 AttributeCertificate structure.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509AttributeCertificateHolder
+ implements Encodable, Serializable
+{
+ private static final long serialVersionUID = 20170722001L;
+
+ private static Attribute[] EMPTY_ARRAY = new Attribute[0];
+
+ private transient AttributeCertificate attrCert;
+ private transient Extensions extensions;
+
+ private static AttributeCertificate parseBytes(byte[] certEncoding)
+ throws IOException
+ {
+ try
+ {
+ return AttributeCertificate.getInstance(CertUtils.parseNonEmptyASN1(certEncoding));
+ }
+ catch (ClassCastException e)
+ {
+ throw new CertIOException("malformed data: " + e.getMessage(), e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new CertIOException("malformed data: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Create a X509AttributeCertificateHolder from the passed in bytes.
+ *
+ * @param certEncoding BER/DER encoding of the certificate.
+ * @throws IOException in the event of corrupted data, or an incorrect structure.
+ */
+ public X509AttributeCertificateHolder(byte[] certEncoding)
+ throws IOException
+ {
+ this(parseBytes(certEncoding));
+ }
+
+ /**
+ * Create a X509AttributeCertificateHolder from the passed in ASN.1 structure.
+ *
+ * @param attrCert an ASN.1 AttributeCertificate structure.
+ */
+ public X509AttributeCertificateHolder(AttributeCertificate attrCert)
+ {
+ init(attrCert);
+ }
+
+ private void init(AttributeCertificate attrCert)
+ {
+ this.attrCert = attrCert;
+ this.extensions = attrCert.getAcinfo().getExtensions();
+ }
+
+ /**
+ * Return the ASN.1 encoding of this holder's attribute certificate.
+ *
+ * @return a DER encoded byte array.
+ * @throws IOException if an encoding cannot be generated.
+ */
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return attrCert.getEncoded();
+ }
+
+ public int getVersion()
+ {
+ return attrCert.getAcinfo().getVersion().intValueExact() + 1;
+ }
+
+ /**
+ * Return the serial number of this attribute certificate.
+ *
+ * @return the serial number.
+ */
+ public BigInteger getSerialNumber()
+ {
+ return attrCert.getAcinfo().getSerialNumber().getValue();
+ }
+
+ /**
+ * Return the holder details for this attribute certificate.
+ *
+ * @return this attribute certificate's holder structure.
+ */
+ public AttributeCertificateHolder getHolder()
+ {
+ return new AttributeCertificateHolder((ASN1Sequence)attrCert.getAcinfo().getHolder().toASN1Primitive());
+ }
+
+ /**
+ * Return the issuer details for this attribute certificate.
+ *
+ * @return this attribute certificate's issuer structure,
+ */
+ public AttributeCertificateIssuer getIssuer()
+ {
+ return new AttributeCertificateIssuer(attrCert.getAcinfo().getIssuer());
+ }
+
+ /**
+ * Return the date before which this attribute certificate is not valid.
+ *
+ * @return the start date for the attribute certificate's validity period.
+ */
+ public Date getNotBefore()
+ {
+ return CertUtils.recoverDate(attrCert.getAcinfo().getAttrCertValidityPeriod().getNotBeforeTime());
+ }
+
+ /**
+ * Return the date after which this attribute certificate is not valid.
+ *
+ * @return the final date for the attribute certificate's validity period.
+ */
+ public Date getNotAfter()
+ {
+ return CertUtils.recoverDate(attrCert.getAcinfo().getAttrCertValidityPeriod().getNotAfterTime());
+ }
+
+ /**
+ * Return the attributes, if any associated with this request.
+ *
+ * @return an array of Attribute, zero length if none present.
+ */
+ public Attribute[] getAttributes()
+ {
+ ASN1Sequence seq = attrCert.getAcinfo().getAttributes();
+ Attribute[] attrs = new Attribute[seq.size()];
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ attrs[i] = Attribute.getInstance(seq.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)
+ {
+ ASN1Sequence seq = attrCert.getAcinfo().getAttributes();
+ List list = new ArrayList();
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ Attribute attr = Attribute.getInstance(seq.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()]);
+ }
+
+ /**
+ * Return whether or not the holder's attribute certificate contains extensions.
+ *
+ * @return true if extension are present, false otherwise.
+ */
+ public boolean hasExtensions()
+ {
+ return extensions != null;
+ }
+
+ /**
+ * 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)
+ {
+ if (extensions != null)
+ {
+ return extensions.getExtension(oid);
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the extensions block associated with this certificate if there is one.
+ *
+ * @return the extensions block, null otherwise.
+ */
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+
+ /**
+ * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the
+ * extensions contained in this holder's attribute certificate.
+ *
+ * @return a list of extension OIDs.
+ */
+ public List getExtensionOIDs()
+ {
+ return CertUtils.getExtensionOIDs(extensions);
+ }
+
+ /**
+ * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the
+ * critical extensions contained in this holder's attribute certificate.
+ *
+ * @return a set of critical extension OIDs.
+ */
+ public Set getCriticalExtensionOIDs()
+ {
+ return CertUtils.getCriticalExtensionOIDs(extensions);
+ }
+
+ /**
+ * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the
+ * non-critical extensions contained in this holder's attribute certificate.
+ *
+ * @return a set of non-critical extension OIDs.
+ */
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return CertUtils.getNonCriticalExtensionOIDs(extensions);
+ }
+
+ public boolean[] getIssuerUniqueID()
+ {
+ return CertUtils.bitStringToBoolean(attrCert.getAcinfo().getIssuerUniqueID());
+ }
+
+ /**
+ * Return the details of the signature algorithm used to create this attribute certificate.
+ *
+ * @return the AlgorithmIdentifier describing the signature algorithm used to create this attribute certificate.
+ */
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return attrCert.getSignatureAlgorithm();
+ }
+
+ /**
+ * Return the bytes making up the signature associated with this attribute certificate.
+ *
+ * @return the attribute certificate signature bytes.
+ */
+ public byte[] getSignature()
+ {
+ return attrCert.getSignatureValue().getOctets();
+ }
+
+ /**
+ * Return the underlying ASN.1 structure for the attribute certificate in this holder.
+ *
+ * @return a AttributeCertificate object.
+ */
+ public AttributeCertificate toASN1Structure()
+ {
+ return attrCert;
+ }
+
+ /**
+ * Return whether or not this attribute certificate is valid on a particular date.
+ *
+ * @param date the date of interest.
+ * @return true if the attribute certificate is valid, false otherwise.
+ */
+ public boolean isValidOn(Date date)
+ {
+ AttCertValidityPeriod certValidityPeriod = attrCert.getAcinfo().getAttrCertValidityPeriod();
+
+ return !date.before(CertUtils.recoverDate(certValidityPeriod.getNotBeforeTime())) && !date.after(CertUtils.recoverDate(certValidityPeriod.getNotAfterTime()));
+ }
+
+ /**
+ * Validate the signature on the attribute 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 isSignatureValid(ContentVerifierProvider verifierProvider)
+ throws CertException
+ {
+ AttributeCertificateInfo acinfo = attrCert.getAcinfo();
+
+ if (!CertUtils.isAlgIdEqual(acinfo.getSignature(), attrCert.getSignatureAlgorithm()))
+ {
+ throw new CertException("signature invalid - algorithm identifier mismatch");
+ }
+
+ ContentVerifier verifier;
+
+ try
+ {
+ verifier = verifierProvider.get((acinfo.getSignature()));
+
+ OutputStream sOut = verifier.getOutputStream();
+ acinfo.encodeTo(sOut, ASN1Encoding.DER);
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new CertException("unable to process signature: " + e.getMessage(), e);
+ }
+
+ return verifier.verify(this.getSignature());
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof X509AttributeCertificateHolder))
+ {
+ return false;
+ }
+
+ X509AttributeCertificateHolder other = (X509AttributeCertificateHolder)o;
+
+ return this.attrCert.equals(other.attrCert);
+ }
+
+ public int hashCode()
+ {
+ return this.attrCert.hashCode();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ init(AttributeCertificate.getInstance(in.readObject()));
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ out.writeObject(this.getEncoded());
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLEntryHolder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLEntryHolder.java
new file mode 100644
index 00000000..7b7a99ee
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLEntryHolder.java
@@ -0,0 +1,146 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert;
+
+import java.math.BigInteger;
+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.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralNames;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertList;
+
+/**
+ * Holding class for an X.509 CRL Entry structure.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509CRLEntryHolder
+{
+ private TBSCertList.CRLEntry entry;
+ private GeneralNames ca;
+
+ X509CRLEntryHolder(TBSCertList.CRLEntry entry, boolean isIndirect, GeneralNames previousCA)
+ {
+ this.entry = entry;
+ this.ca = previousCA;
+
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ ca = GeneralNames.getInstance(currentCaName.getParsedValue());
+ }
+ }
+ }
+
+ /**
+ * Return the serial number of the certificate associated with this CRLEntry.
+ *
+ * @return the revoked certificate's serial number.
+ */
+ public BigInteger getSerialNumber()
+ {
+ return entry.getUserCertificate().getValue();
+ }
+
+ /**
+ * Return the date on which the certificate associated with this CRLEntry was revoked.
+ *
+ * @return the revocation date for the revoked certificate.
+ */
+ public Date getRevocationDate()
+ {
+ return entry.getRevocationDate().getDate();
+ }
+
+ /**
+ * Return whether or not the holder's CRL entry contains extensions.
+ *
+ * @return true if extension are present, false otherwise.
+ */
+ public boolean hasExtensions()
+ {
+ return entry.hasExtensions();
+ }
+
+ /**
+ * Return the available names for the certificate issuer for the certificate referred to by this CRL entry.
+ * <p>
+ * Note: this will be the issuer of the CRL unless it has been specified that the CRL is indirect
+ * in the IssuingDistributionPoint extension and either a previous entry, or the current one,
+ * has specified a different CA via the certificateIssuer extension.
+ * </p>
+ *
+ * @return the revoked certificate's issuer.
+ */
+ public GeneralNames getCertificateIssuer()
+ {
+ return this.ca;
+ }
+
+ /**
+ * 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)
+ {
+ Extensions extensions = entry.getExtensions();
+
+ if (extensions != null)
+ {
+ return extensions.getExtension(oid);
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the extensions block associated with this CRL entry if there is one.
+ *
+ * @return the extensions block, null otherwise.
+ */
+ public Extensions getExtensions()
+ {
+ return entry.getExtensions();
+ }
+
+ /**
+ * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the
+ * extensions contained in this holder's CRL entry.
+ *
+ * @return a list of extension OIDs.
+ */
+ public List getExtensionOIDs()
+ {
+ return CertUtils.getExtensionOIDs(entry.getExtensions());
+ }
+
+ /**
+ * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the
+ * critical extensions contained in this holder's CRL entry.
+ *
+ * @return a set of critical extension OIDs.
+ */
+ public Set getCriticalExtensionOIDs()
+ {
+ return CertUtils.getCriticalExtensionOIDs(entry.getExtensions());
+ }
+
+ /**
+ * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the
+ * non-critical extensions contained in this holder's CRL entry.
+ *
+ * @return a set of non-critical extension OIDs.
+ */
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return CertUtils.getNonCriticalExtensionOIDs(entry.getExtensions());
+ }
+}
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
new file mode 100644
index 00000000..ef138991
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLHolder.java
@@ -0,0 +1,370 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+
+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.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+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;
+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.IssuingDistributionPoint;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertList;
+import com.android.internal.org.bouncycastle.asn1.x509.Time;
+import com.android.internal.org.bouncycastle.operator.ContentVerifier;
+import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider;
+import com.android.internal.org.bouncycastle.util.Encodable;
+
+/**
+ * Holding class for an X.509 CRL structure.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509CRLHolder
+ implements Encodable, Serializable
+{
+ private static final long serialVersionUID = 20170722001L;
+
+ private transient CertificateList x509CRL;
+ private transient boolean isIndirect;
+ private transient Extensions extensions;
+ private transient GeneralNames issuerName;
+
+ private static CertificateList parseStream(InputStream stream)
+ throws IOException
+ {
+ try
+ {
+ ASN1Primitive obj = new ASN1InputStream(stream, true).readObject();
+ if (obj == null)
+ {
+ throw new IOException("no content found");
+ }
+ return CertificateList.getInstance(obj);
+ }
+ catch (ClassCastException e)
+ {
+ throw new CertIOException("malformed data: " + e.getMessage(), e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new CertIOException("malformed data: " + e.getMessage(), e);
+ }
+ }
+
+ private static boolean isIndirectCRL(Extensions extensions)
+ {
+ if (extensions == null)
+ {
+ return false;
+ }
+
+ Extension ext = extensions.getExtension(Extension.issuingDistributionPoint);
+
+ return ext != null && IssuingDistributionPoint.getInstance(ext.getParsedValue()).isIndirectCRL();
+ }
+
+ /**
+ * Create a X509CRLHolder from the passed in bytes.
+ *
+ * @param crlEncoding BER/DER encoding of the CRL
+ * @throws IOException in the event of corrupted data, or an incorrect structure.
+ */
+ public X509CRLHolder(byte[] crlEncoding)
+ throws IOException
+ {
+ this(parseStream(new ByteArrayInputStream(crlEncoding)));
+ }
+
+ /**
+ * Create a X509CRLHolder from the passed in InputStream.
+ *
+ * @param crlStream BER/DER encoded InputStream of the CRL
+ * @throws IOException in the event of corrupted data, or an incorrect structure.
+ */
+ public X509CRLHolder(InputStream crlStream)
+ throws IOException
+ {
+ this(parseStream(crlStream));
+ }
+
+ /**
+ * Create a X509CRLHolder from the passed in ASN.1 structure.
+ *
+ * @param x509CRL an ASN.1 CertificateList structure.
+ */
+ public X509CRLHolder(CertificateList x509CRL)
+ {
+ init(x509CRL);
+ }
+
+ private void init(CertificateList x509CRL)
+ {
+ this.x509CRL = x509CRL;
+ this.extensions = x509CRL.getTBSCertList().getExtensions();
+ this.isIndirect = isIndirectCRL(extensions);
+ this.issuerName = new GeneralNames(new GeneralName(x509CRL.getIssuer()));
+ }
+
+ /**
+ * Return the ASN.1 encoding of this holder's CRL.
+ *
+ * @return a DER encoded byte array.
+ * @throws IOException if an encoding cannot be generated.
+ */
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return x509CRL.getEncoded();
+ }
+
+ /**
+ * Return the issuer of this holder's CRL.
+ *
+ * @return the CRL issuer.
+ */
+ public X500Name getIssuer()
+ {
+ return X500Name.getInstance(x509CRL.getIssuer());
+ }
+
+ public Date getThisUpdate()
+ {
+ return x509CRL.getThisUpdate().getDate();
+ }
+
+ public Date getNextUpdate()
+ {
+ Time update = x509CRL.getNextUpdate();
+
+ if (update != null)
+ {
+ return update.getDate();
+ }
+
+ return null;
+ }
+ public X509CRLEntryHolder getRevokedCertificate(BigInteger serialNumber)
+ {
+ GeneralNames currentCA = issuerName;
+ for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements();)
+ {
+ TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)en.nextElement();
+
+ if (entry.getUserCertificate().hasValue(serialNumber))
+ {
+ return new X509CRLEntryHolder(entry, isIndirect, currentCA);
+ }
+
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ currentCA = GeneralNames.getInstance(currentCaName.getParsedValue());
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Return a collection of X509CRLEntryHolder objects, giving the details of the
+ * revoked certificates that appear on this CRL.
+ *
+ * @return the revoked certificates as a collection of X509CRLEntryHolder objects.
+ */
+ public Collection getRevokedCertificates()
+ {
+ TBSCertList.CRLEntry[] entries = x509CRL.getRevokedCertificates();
+ List l = new ArrayList(entries.length);
+ GeneralNames currentCA = issuerName;
+
+ for (Enumeration en = x509CRL.getRevokedCertificateEnumeration(); en.hasMoreElements();)
+ {
+ TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)en.nextElement();
+ X509CRLEntryHolder crlEntry = new X509CRLEntryHolder(entry, isIndirect, currentCA);
+
+ l.add(crlEntry);
+
+ currentCA = crlEntry.getCertificateIssuer();
+ }
+
+ return l;
+ }
+
+ /**
+ * Return whether or not the holder's CRL contains extensions.
+ *
+ * @return true if extension are present, false otherwise.
+ */
+ public boolean hasExtensions()
+ {
+ return extensions != null;
+ }
+
+ /**
+ * 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)
+ {
+ if (extensions != null)
+ {
+ return extensions.getExtension(oid);
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the extensions block associated with this CRL if there is one.
+ *
+ * @return the extensions block, null otherwise.
+ */
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+
+ /**
+ * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the
+ * extensions contained in this holder's CRL.
+ *
+ * @return a list of extension OIDs.
+ */
+ public List getExtensionOIDs()
+ {
+ return CertUtils.getExtensionOIDs(extensions);
+ }
+
+ /**
+ * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the
+ * critical extensions contained in this holder's CRL.
+ *
+ * @return a set of critical extension OIDs.
+ */
+ public Set getCriticalExtensionOIDs()
+ {
+ return CertUtils.getCriticalExtensionOIDs(extensions);
+ }
+
+ /**
+ * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the
+ * non-critical extensions contained in this holder's CRL.
+ *
+ * @return a set of non-critical extension OIDs.
+ */
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return CertUtils.getNonCriticalExtensionOIDs(extensions);
+ }
+
+ /**
+ * Return the underlying ASN.1 structure for the CRL in this holder.
+ *
+ * @return a CertificateList object.
+ */
+ public CertificateList toASN1Structure()
+ {
+ return x509CRL;
+ }
+
+ /**
+ * Validate the signature on the CRL.
+ *
+ * @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 isSignatureValid(ContentVerifierProvider verifierProvider)
+ throws CertException
+ {
+ TBSCertList tbsCRL = x509CRL.getTBSCertList();
+
+ if (!CertUtils.isAlgIdEqual(tbsCRL.getSignature(), x509CRL.getSignatureAlgorithm()))
+ {
+ throw new CertException("signature invalid - algorithm identifier mismatch");
+ }
+
+ ContentVerifier verifier;
+
+ try
+ {
+ verifier = verifierProvider.get((tbsCRL.getSignature()));
+
+ OutputStream sOut = verifier.getOutputStream();
+ tbsCRL.encodeTo(sOut, ASN1Encoding.DER);
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new CertException("unable to process signature: " + e.getMessage(), e);
+ }
+
+ return verifier.verify(x509CRL.getSignature().getOctets());
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof X509CRLHolder))
+ {
+ return false;
+ }
+
+ X509CRLHolder other = (X509CRLHolder)o;
+
+ return this.x509CRL.equals(other.x509CRL);
+ }
+
+ public int hashCode()
+ {
+ return this.x509CRL.hashCode();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ init(CertificateList.getInstance(in.readObject()));
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ out.writeObject(this.getEncoded());
+ }
+}
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
new file mode 100644
index 00000000..9ca4a283
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CertificateHolder.java
@@ -0,0 +1,355 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.math.BigInteger;
+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.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.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertificate;
+import com.android.internal.org.bouncycastle.operator.ContentVerifier;
+import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider;
+import com.android.internal.org.bouncycastle.util.Encodable;
+
+/**
+ * Holding class for an X.509 Certificate structure.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509CertificateHolder
+ implements Encodable, Serializable
+{
+ private static final long serialVersionUID = 20170722001L;
+
+ private transient Certificate x509Certificate;
+ private transient Extensions extensions;
+
+ private static Certificate parseBytes(byte[] certEncoding)
+ throws IOException
+ {
+ try
+ {
+ return Certificate.getInstance(CertUtils.parseNonEmptyASN1(certEncoding));
+ }
+ catch (ClassCastException e)
+ {
+ throw new CertIOException("malformed data: " + e.getMessage(), e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new CertIOException("malformed data: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Create a X509CertificateHolder from the passed in bytes.
+ *
+ * @param certEncoding BER/DER encoding of the certificate.
+ * @throws IOException in the event of corrupted data, or an incorrect structure.
+ */
+ public X509CertificateHolder(byte[] certEncoding)
+ throws IOException
+ {
+ this(parseBytes(certEncoding));
+ }
+
+ /**
+ * Create a X509CertificateHolder from the passed in ASN.1 structure.
+ *
+ * @param x509Certificate an ASN.1 Certificate structure.
+ */
+ public X509CertificateHolder(Certificate x509Certificate)
+ {
+ init(x509Certificate);
+ }
+
+ private void init(Certificate x509Certificate)
+ {
+ this.x509Certificate = x509Certificate;
+ this.extensions = x509Certificate.getTBSCertificate().getExtensions();
+ }
+
+ public int getVersionNumber()
+ {
+ return x509Certificate.getVersionNumber();
+ }
+
+ /**
+ * @deprecated use getVersionNumber
+ */
+ public int getVersion()
+ {
+ return x509Certificate.getVersionNumber();
+ }
+
+ /**
+ * Return whether or not the holder's certificate contains extensions.
+ *
+ * @return true if extension are present, false otherwise.
+ */
+ public boolean hasExtensions()
+ {
+ return extensions != null;
+ }
+
+ /**
+ * 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)
+ {
+ if (extensions != null)
+ {
+ return extensions.getExtension(oid);
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the extensions block associated with this certificate if there is one.
+ *
+ * @return the extensions block, null otherwise.
+ */
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+
+ /**
+ * Returns a list of ASN1ObjectIdentifier objects representing the OIDs of the
+ * extensions contained in this holder's certificate.
+ *
+ * @return a list of extension OIDs.
+ */
+ public List getExtensionOIDs()
+ {
+ return CertUtils.getExtensionOIDs(extensions);
+ }
+
+ /**
+ * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the
+ * critical extensions contained in this holder's certificate.
+ *
+ * @return a set of critical extension OIDs.
+ */
+ public Set getCriticalExtensionOIDs()
+ {
+ return CertUtils.getCriticalExtensionOIDs(extensions);
+ }
+
+ /**
+ * Returns a set of ASN1ObjectIdentifier objects representing the OIDs of the
+ * non-critical extensions contained in this holder's certificate.
+ *
+ * @return a set of non-critical extension OIDs.
+ */
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return CertUtils.getNonCriticalExtensionOIDs(extensions);
+ }
+
+ /**
+ * Return the serial number of this attribute certificate.
+ *
+ * @return the serial number.
+ */
+ public BigInteger getSerialNumber()
+ {
+ return x509Certificate.getSerialNumber().getValue();
+ }
+
+ /**
+ * Return the issuer of this certificate.
+ *
+ * @return the certificate issuer.
+ */
+ public X500Name getIssuer()
+ {
+ return X500Name.getInstance(x509Certificate.getIssuer());
+ }
+
+ /**
+ * Return the subject this certificate is for.
+ *
+ * @return the subject for the certificate.
+ */
+ public X500Name getSubject()
+ {
+ return X500Name.getInstance(x509Certificate.getSubject());
+ }
+
+ /**
+ * Return the date before which this certificate is not valid.
+ *
+ * @return the start time for the certificate's validity period.
+ */
+ public Date getNotBefore()
+ {
+ return x509Certificate.getStartDate().getDate();
+ }
+
+ /**
+ * Return the date after which this certificate is not valid.
+ *
+ * @return the final time for the certificate's validity period.
+ */
+ public Date getNotAfter()
+ {
+ return x509Certificate.getEndDate().getDate();
+ }
+
+ /**
+ * Return the SubjectPublicKeyInfo describing the public key this certificate is carrying.
+ *
+ * @return the public key ASN.1 structure contained in the certificate.
+ */
+ public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
+ {
+ return x509Certificate.getSubjectPublicKeyInfo();
+ }
+
+ /**
+ * Return the underlying ASN.1 structure for the certificate in this holder.
+ *
+ * @return a Certificate object.
+ */
+ public Certificate toASN1Structure()
+ {
+ return x509Certificate;
+ }
+
+ /**
+ * Return the details of the signature algorithm used to create this attribute certificate.
+ *
+ * @return the AlgorithmIdentifier describing the signature algorithm used to create this attribute certificate.
+ */
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return x509Certificate.getSignatureAlgorithm();
+ }
+
+ /**
+ * Return the bytes making up the signature associated with this attribute certificate.
+ *
+ * @return the attribute certificate signature bytes.
+ */
+ public byte[] getSignature()
+ {
+ return x509Certificate.getSignature().getOctets();
+ }
+
+ /**
+ * Return whether or not this certificate is valid on a particular date.
+ *
+ * @param date the date of interest.
+ * @return true if the certificate is valid, false otherwise.
+ */
+ public boolean isValidOn(Date date)
+ {
+ return !date.before(x509Certificate.getStartDate().getDate()) && !date.after(x509Certificate.getEndDate().getDate());
+ }
+
+ /**
+ * 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 isSignatureValid(ContentVerifierProvider verifierProvider)
+ throws CertException
+ {
+ TBSCertificate tbsCert = x509Certificate.getTBSCertificate();
+
+ if (!CertUtils.isAlgIdEqual(tbsCert.getSignature(), x509Certificate.getSignatureAlgorithm()))
+ {
+ throw new CertException("signature invalid - algorithm identifier mismatch");
+ }
+
+ ContentVerifier verifier;
+
+ try
+ {
+ verifier = verifierProvider.get((tbsCert.getSignature()));
+
+ OutputStream sOut = verifier.getOutputStream();
+ tbsCert.encodeTo(sOut, ASN1Encoding.DER);
+ sOut.close();
+ }
+ catch (Exception e)
+ {
+ throw new CertException("unable to process signature: " + e.getMessage(), e);
+ }
+
+ return verifier.verify(this.getSignature());
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof X509CertificateHolder))
+ {
+ return false;
+ }
+
+ X509CertificateHolder other = (X509CertificateHolder)o;
+
+ return this.x509Certificate.equals(other.x509Certificate);
+ }
+
+ public int hashCode()
+ {
+ return this.x509Certificate.hashCode();
+ }
+
+ /**
+ * Return the ASN.1 encoding of this holder's certificate.
+ *
+ * @return a DER encoded byte array.
+ * @throws IOException if an encoding cannot be generated.
+ */
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return x509Certificate.getEncoded();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ init(Certificate.getInstance(in.readObject()));
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ out.writeObject(this.getEncoded());
+ }
+}
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
new file mode 100644
index 00000000..cd446d09
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java
@@ -0,0 +1,423 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+
+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.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+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;
+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.asn1.x509.ExtensionsGenerator;
+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.Time;
+import com.android.internal.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
+import com.android.internal.org.bouncycastle.operator.ContentSigner;
+
+
+/**
+ * class to produce an X.509 Version 3 certificate.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509v3CertificateBuilder
+{
+ private V3TBSCertificateGenerator tbsGen;
+ private ExtensionsGenerator extGenerator;
+
+ /**
+ * Create a builder for a version 3 certificate.
+ *
+ * @param issuer the certificate issuer
+ * @param serial the certificate serial number
+ * @param notBefore the date before which the certificate is not valid
+ * @param notAfter the date after which the certificate is not valid
+ * @param subject the certificate subject
+ * @param publicKeyInfo the info structure for the public key to be associated with this certificate.
+ */
+ public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
+ {
+ this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo);
+ }
+
+ /**
+ * Create a builder for a version 3 certificate. You may need to use this constructor if the default locale
+ * doesn't use a Gregorian calender so that the Time produced is compatible with other ASN.1 implementations.
+ *
+ * @param issuer the certificate issuer
+ * @param serial the certificate serial number
+ * @param notBefore the date before which the certificate is not valid
+ * @param notAfter the date after which the certificate is not valid
+ * @param dateLocale locale to be used for date interpretation.
+ * @param subject the certificate subject
+ * @param publicKeyInfo the info structure for the public key to be associated with this certificate.
+ */
+ public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, Locale dateLocale, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
+ {
+ this(issuer, serial, new Time(notBefore, dateLocale), new Time(notAfter, dateLocale), subject, publicKeyInfo);
+ }
+
+ /**
+ * Create a builder for a version 3 certificate.
+ *
+ * @param issuer the certificate issuer
+ * @param serial the certificate serial number
+ * @param notBefore the Time before which the certificate is not valid
+ * @param notAfter the Time after which the certificate is not valid
+ * @param subject the certificate subject
+ * @param publicKeyInfo the info structure for the public key to be associated with this certificate.
+ */
+ public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Time notBefore, Time notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
+ {
+ tbsGen = new V3TBSCertificateGenerator();
+ tbsGen.setSerialNumber(new ASN1Integer(serial));
+ tbsGen.setIssuer(issuer);
+ tbsGen.setStartDate(notBefore);
+ tbsGen.setEndDate(notAfter);
+ tbsGen.setSubject(subject);
+ tbsGen.setSubjectPublicKeyInfo(publicKeyInfo);
+
+ extGenerator = new ExtensionsGenerator();
+ }
+
+ /**
+ * Create a builder for a version 3 certificate, initialised with another certificate.
+ *
+ * @param template template certificate to base the new one on.
+ */
+ public X509v3CertificateBuilder(X509CertificateHolder template)
+ {
+ tbsGen = new V3TBSCertificateGenerator();
+ tbsGen.setSerialNumber(new ASN1Integer(template.getSerialNumber()));
+ tbsGen.setIssuer(template.getIssuer());
+ tbsGen.setStartDate(new Time(template.getNotBefore()));
+ tbsGen.setEndDate(new Time(template.getNotAfter()));
+ tbsGen.setSubject(template.getSubject());
+ tbsGen.setSubjectPublicKeyInfo(template.getSubjectPublicKeyInfo());
+
+ extGenerator = new ExtensionsGenerator();
+
+ Extensions exts = template.getExtensions();
+
+ for (Enumeration en = exts.oids(); en.hasMoreElements();)
+ {
+ extGenerator.addExtension(exts.getExtension((ASN1ObjectIdentifier)en.nextElement()));
+ }
+ }
+
+ /**
+ * Return if the extension indicated by OID is present.
+ *
+ * @param oid the OID for the extension of interest.
+ * @return the Extension, or null if it is not present.
+ */
+ public boolean hasExtension(ASN1ObjectIdentifier oid)
+ {
+ return doGetExtension(oid) != null;
+ }
+
+ /**
+ * Return the current value of the extension for OID.
+ *
+ * @param oid the OID for the extension we want to fetch.
+ * @return true if a matching extension is present, false otherwise.
+ */
+ public Extension getExtension(ASN1ObjectIdentifier oid)
+ {
+ return doGetExtension(oid);
+ }
+
+ private Extension doGetExtension(ASN1ObjectIdentifier oid)
+ {
+ Extensions exts = extGenerator.generate();
+
+ return exts.getExtension(oid);
+ }
+
+ /**
+ * Set the subjectUniqueID - note: it is very rare that it is correct to do this.
+ *
+ * @param uniqueID a boolean array representing the bits making up the subjectUniqueID.
+ * @return this builder object.
+ */
+ public X509v3CertificateBuilder setSubjectUniqueID(boolean[] uniqueID)
+ {
+ tbsGen.setSubjectUniqueID(booleanToBitString(uniqueID));
+
+ return this;
+ }
+
+ /**
+ * Set the issuerUniqueID - note: it is very rare that it is correct to do this.
+ *
+ * @param uniqueID a boolean array representing the bits making up the issuerUniqueID.
+ * @return this builder object.
+ */
+ public X509v3CertificateBuilder setIssuerUniqueID(boolean[] uniqueID)
+ {
+ tbsGen.setIssuerUniqueID(booleanToBitString(uniqueID));
+
+ return this;
+ }
+
+ /**
+ * Add a given extension field for the standard extensions tag (tag 3)
+ *
+ * @param oid the OID defining the extension type.
+ * @param isCritical true if the extension is critical, false otherwise.
+ * @param value the ASN.1 structure that forms the extension's value.
+ * @return this builder object.
+ * @throws CertIOException if there is an issue with the new extension value.
+ * @throws IllegalArgumentException if the OID oid has already been used.
+ */
+ public X509v3CertificateBuilder addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean isCritical,
+ ASN1Encodable value)
+ throws CertIOException
+ {
+ try
+ {
+ extGenerator.addExtension(oid, isCritical, value);
+ }
+ catch (IOException e)
+ {
+ throw new CertIOException("cannot encode extension: " + e.getMessage(), e);
+ }
+
+ return this;
+ }
+
+ /**
+ * Add a given extension field for the standard extensions tag (tag 3).
+ *
+ * @param extension the full extension value.
+ * @return this builder object.
+ * @throws CertIOException if there is an issue with the new extension value.
+ * @throws IllegalArgumentException if the OID oid has already been used.
+ */
+ public X509v3CertificateBuilder addExtension(
+ Extension extension)
+ throws CertIOException
+ {
+ extGenerator.addExtension(extension);
+
+ return this;
+ }
+
+ /**
+ * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the
+ * extension value.
+ *
+ * @param oid the OID defining the extension type.
+ * @param isCritical true if the extension is critical, false otherwise.
+ * @param encodedValue a byte array representing the encoding of the extension value.
+ * @return this builder object.
+ * @throws CertIOException if there is an issue with the new extension value.
+ * @throws IllegalArgumentException if the OID oid has already been allocated.
+ */
+ public X509v3CertificateBuilder addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean isCritical,
+ byte[] encodedValue)
+ throws CertIOException
+ {
+ extGenerator.addExtension(oid, isCritical, encodedValue);
+
+ return this;
+ }
+
+ /**
+ * Replace the extension field for the passed in extension's extension ID
+ * with a new version.
+ *
+ * @param oid the OID defining the extension type.
+ * @param isCritical true if the extension is critical, false otherwise.
+ * @param value the ASN.1 structure that forms the extension's value.
+ * @return this builder object.
+ * @throws CertIOException if there is an issue with the new extension value.
+ * @throws IllegalArgumentException if the extension to be replaced is not present.
+ */
+ public X509v3CertificateBuilder replaceExtension(
+ ASN1ObjectIdentifier oid,
+ boolean isCritical,
+ ASN1Encodable value)
+ throws CertIOException
+ {
+ try
+ {
+ extGenerator = CertUtils.doReplaceExtension(extGenerator, new Extension(oid, isCritical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER)));
+ }
+ catch (IOException e)
+ {
+ throw new CertIOException("cannot encode extension: " + e.getMessage(), e);
+ }
+
+ return this;
+ }
+
+ /**
+ * Replace the extension field for the passed in extension's extension ID
+ * with a new version.
+ *
+ * @param extension the full extension value.
+ * @return this builder object.
+ * @throws CertIOException if there is an issue with the new extension value.
+ * @throws IllegalArgumentException if the extension to be replaced is not present.
+ */
+ public X509v3CertificateBuilder replaceExtension(
+ Extension extension)
+ throws CertIOException
+ {
+ extGenerator = CertUtils.doReplaceExtension(extGenerator, extension);
+
+ return this;
+ }
+
+ /**
+ * Replace a given extension field for the standard extensions tag (tag 3) with the passed in
+ * byte encoded extension value.
+ *
+ * @param oid the OID defining the extension type.
+ * @param isCritical true if the extension is critical, false otherwise.
+ * @param encodedValue a byte array representing the encoding of the extension value.
+ * @return this builder object.
+ * @throws CertIOException if there is an issue with the new extension value.
+ * @throws IllegalArgumentException if the extension to be replaced is not present.
+ */
+ public X509v3CertificateBuilder replaceExtension(
+ ASN1ObjectIdentifier oid,
+ boolean isCritical,
+ byte[] encodedValue)
+ throws CertIOException
+ {
+ extGenerator = CertUtils.doReplaceExtension(extGenerator, new Extension(oid, isCritical, encodedValue));
+
+ return this;
+ }
+
+ /**
+ * Remove the extension indicated by OID.
+ *
+ * @param oid the OID of the extension to be removed.
+ * @return this builder object.
+ * @throws IllegalArgumentException if the extension to be removed is not present.
+ */
+ public X509v3CertificateBuilder removeExtension(ASN1ObjectIdentifier oid)
+ {
+ extGenerator = CertUtils.doRemoveExtension(extGenerator, oid);
+
+ return this;
+ }
+
+ /**
+ * Add a given extension field for the standard extensions tag (tag 3)
+ * copying the extension value from another certificate.
+ *
+ * @param oid the OID defining the extension type.
+ * @param isCritical true if the copied extension is to be marked as critical, false otherwise.
+ * @param certHolder the holder for the certificate that the extension is to be copied from.
+ * @return this builder object.
+ */
+ public X509v3CertificateBuilder copyAndAddExtension(
+ ASN1ObjectIdentifier oid,
+ boolean isCritical,
+ X509CertificateHolder certHolder)
+ {
+ Certificate cert = certHolder.toASN1Structure();
+
+ Extension extension = cert.getTBSCertificate().getExtensions().getExtension(oid);
+
+ if (extension == null)
+ {
+ throw new NullPointerException("extension " + oid + " not present");
+ }
+
+ extGenerator.addExtension(oid, isCritical, extension.getExtnValue().getOctets());
+
+ return this;
+ }
+
+ /**
+ * Generate an X.509 certificate, based on the current issuer and subject
+ * using the passed in signer.
+ *
+ * @param signer the content signer to be used to generate the signature validating the certificate.
+ * @return a holder containing the resulting signed certificate.
+ */
+ public X509CertificateHolder build(
+ ContentSigner signer)
+ {
+ tbsGen.setSignature(signer.getAlgorithmIdentifier());
+
+ if (!extGenerator.isEmpty())
+ {
+ tbsGen.setExtensions(extGenerator.generate());
+ }
+
+ try
+ {
+ TBSCertificate tbsCert = tbsGen.generateTBSCertificate();
+ return new X509CertificateHolder(generateStructure(tbsCert, signer.getAlgorithmIdentifier(), generateSig(signer, tbsCert)));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("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();
+
+ v.add(tbsCert);
+ v.add(sigAlgId);
+ v.add(new DERBitString(signature));
+
+ return Certificate.getInstance(new DERSequence(v));
+ }
+
+ static DERBitString booleanToBitString(boolean[] id)
+ {
+ byte[] bytes = new byte[(id.length + 7) / 8];
+
+ for (int i = 0; i != id.length; i++)
+ {
+ bytes[i / 8] |= (id[i]) ? (1 << ((7 - (i % 8)))) : 0;
+ }
+
+ int pad = id.length % 8;
+
+ if (pad == 0)
+ {
+ return new DERBitString(bytes);
+ }
+ else
+ {
+ return new DERBitString(bytes, 8 - pad);
+ }
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/jcajce/JcaCertStore.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/jcajce/JcaCertStore.java
new file mode 100644
index 00000000..5bac8547
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/jcajce/JcaCertStore.java
@@ -0,0 +1,66 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.jcajce;
+
+import java.io.IOException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.util.CollectionStore;
+
+/**
+ * Class for storing Certificates for later lookup.
+ * <p>
+ * The class will convert X509Certificate objects into X509CertificateHolder objects.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JcaCertStore
+ extends CollectionStore
+{
+ /**
+ * Basic constructor.
+ *
+ * @param collection - initial contents for the store, this is copied.
+ */
+ public JcaCertStore(Collection collection)
+ throws CertificateEncodingException
+ {
+ super(convertCerts(collection));
+ }
+
+ private static Collection convertCerts(Collection collection)
+ throws CertificateEncodingException
+ {
+ List list = new ArrayList(collection.size());
+
+ for (Iterator it = collection.iterator(); it.hasNext();)
+ {
+ Object o = it.next();
+
+ if (o instanceof X509Certificate)
+ {
+ X509Certificate cert = (X509Certificate)o;
+
+ try
+ {
+ list.add(new X509CertificateHolder(cert.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException("unable to read encoding: " + e.getMessage());
+ }
+ }
+ else
+ {
+ list.add((X509CertificateHolder)o);
+ }
+ }
+
+ return list;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/jcajce/JcaX509CertificateHolder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/jcajce/JcaX509CertificateHolder.java
new file mode 100644
index 00000000..ae965435
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/jcajce/JcaX509CertificateHolder.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.jcajce;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+
+/**
+ * JCA helper class for converting an X509Certificate into a X509CertificateHolder object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JcaX509CertificateHolder
+ extends X509CertificateHolder
+{
+ /**
+ * Base constructor.
+ *
+ * @param cert certificate to be used a the source for the holder creation.
+ * @throws CertificateEncodingException if there is a problem extracting the certificate information.
+ */
+ public JcaX509CertificateHolder(X509Certificate cert)
+ throws CertificateEncodingException
+ {
+ super(Certificate.getInstance(cert.getEncoded()));
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/selector/MSOutlookKeyIdCalculator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/selector/MSOutlookKeyIdCalculator.java
new file mode 100644
index 00000000..da8c8567
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/selector/MSOutlookKeyIdCalculator.java
@@ -0,0 +1,423 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.selector;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+class MSOutlookKeyIdCalculator
+{
+ // This is less than ideal, but it seems to be the best way of supporting this without exposing SHA-1
+ // as the class is only used to workout the MSOutlook Key ID, you can think of the fact it's SHA-1 as
+ // a coincidence...
+ static byte[] calculateKeyId(SubjectPublicKeyInfo info)
+ {
+ SHA1Digest dig = new SHA1Digest();
+ byte[] hash = new byte[dig.getDigestSize()];
+ byte[] spkiEnc = new byte[0];
+ try
+ {
+ spkiEnc = info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return new byte[0];
+ }
+
+ // try the outlook 2010 calculation
+ dig.update(spkiEnc, 0, spkiEnc.length);
+
+ dig.doFinal(hash, 0);
+
+ return hash;
+ }
+
+ private static abstract class GeneralDigest
+ {
+ private static final int BYTE_LENGTH = 64;
+ private byte[] xBuf;
+ private int xBufOff;
+
+ private long byteCount;
+
+ /**
+ * Standard constructor
+ */
+ protected GeneralDigest()
+ {
+ xBuf = new byte[4];
+ xBufOff = 0;
+ }
+
+ /**
+ * Copy constructor. We are using copy constructors in place
+ * of the Object.clone() interface as this interface is not
+ * supported by J2ME.
+ */
+ protected GeneralDigest(GeneralDigest t)
+ {
+ xBuf = new byte[t.xBuf.length];
+
+ copyIn(t);
+ }
+
+ protected void copyIn(GeneralDigest t)
+ {
+ System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
+
+ xBufOff = t.xBufOff;
+ byteCount = t.byteCount;
+ }
+
+ public void update(
+ byte in)
+ {
+ xBuf[xBufOff++] = in;
+
+ if (xBufOff == xBuf.length)
+ {
+ processWord(xBuf, 0);
+ xBufOff = 0;
+ }
+
+ byteCount++;
+ }
+
+ public void update(
+ byte[] in,
+ int inOff,
+ int len)
+ {
+ //
+ // fill the current word
+ //
+ while ((xBufOff != 0) && (len > 0))
+ {
+ update(in[inOff]);
+
+ inOff++;
+ len--;
+ }
+
+ //
+ // process whole words.
+ //
+ while (len > xBuf.length)
+ {
+ processWord(in, inOff);
+
+ inOff += xBuf.length;
+ len -= xBuf.length;
+ byteCount += xBuf.length;
+ }
+
+ //
+ // load in the remainder.
+ //
+ while (len > 0)
+ {
+ update(in[inOff]);
+
+ inOff++;
+ len--;
+ }
+ }
+
+ public void finish()
+ {
+ long bitLength = (byteCount << 3);
+
+ //
+ // add the pad bytes.
+ //
+ update((byte)128);
+
+ while (xBufOff != 0)
+ {
+ update((byte)0);
+ }
+
+ processLength(bitLength);
+
+ processBlock();
+ }
+
+ public void reset()
+ {
+ byteCount = 0;
+
+ xBufOff = 0;
+ for (int i = 0; i < xBuf.length; i++)
+ {
+ xBuf[i] = 0;
+ }
+ }
+
+ protected abstract void processWord(byte[] in, int inOff);
+
+ protected abstract void processLength(long bitLength);
+
+ protected abstract void processBlock();
+ }
+
+ private static class SHA1Digest
+ extends GeneralDigest
+ {
+ private static final int DIGEST_LENGTH = 20;
+
+ private int H1, H2, H3, H4, H5;
+
+ private int[] X = new int[80];
+ private int xOff;
+
+ /**
+ * Standard constructor
+ */
+ public SHA1Digest()
+ {
+ reset();
+ }
+
+ public String getAlgorithmName()
+ {
+ return "SHA-1";
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_LENGTH;
+ }
+
+ protected void processWord(
+ 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;
+
+ if (++xOff == 16)
+ {
+ processBlock();
+ }
+ }
+
+ protected void processLength(
+ long bitLength)
+ {
+ if (xOff > 14)
+ {
+ processBlock();
+ }
+
+ X[14] = (int)(bitLength >>> 32);
+ X[15] = (int)(bitLength & 0xffffffff);
+ }
+
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ {
+ finish();
+
+ Pack.intToBigEndian(H1, out, outOff);
+ Pack.intToBigEndian(H2, out, outOff + 4);
+ Pack.intToBigEndian(H3, out, outOff + 8);
+ Pack.intToBigEndian(H4, out, outOff + 12);
+ Pack.intToBigEndian(H5, out, outOff + 16);
+
+ reset();
+
+ return DIGEST_LENGTH;
+ }
+
+ /**
+ * reset the chaining variables
+ */
+ public void reset()
+ {
+ super.reset();
+
+ H1 = 0x67452301;
+ H2 = 0xefcdab89;
+ H3 = 0x98badcfe;
+ H4 = 0x10325476;
+ H5 = 0xc3d2e1f0;
+
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ //
+ // Additive constants
+ //
+ private static final int Y1 = 0x5a827999;
+ private static final int Y2 = 0x6ed9eba1;
+ private static final int Y3 = 0x8f1bbcdc;
+ private static final int Y4 = 0xca62c1d6;
+
+ private int f(
+ int u,
+ int v,
+ int w)
+ {
+ return ((u & v) | ((~u) & w));
+ }
+
+ private int h(
+ int u,
+ int v,
+ int w)
+ {
+ return (u ^ v ^ w);
+ }
+
+ private int g(
+ int u,
+ int v,
+ int w)
+ {
+ return ((u & v) | (u & w) | (v & w));
+ }
+
+ protected void processBlock()
+ {
+ //
+ // expand 16 word block into 80 word block.
+ //
+ for (int i = 16; i < 80; i++)
+ {
+ int t = X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16];
+ X[i] = t << 1 | t >>> 31;
+ }
+
+ //
+ // set up working variables.
+ //
+ int A = H1;
+ int B = H2;
+ int C = H3;
+ int D = H4;
+ int E = H5;
+
+ //
+ // round 1
+ //
+ int idx = 0;
+
+ for (int j = 0; j < 4; j++)
+ {
+ // E = rotateLeft(A, 5) + f(B, C, D) + E + X[idx++] + Y1
+ // B = rotateLeft(B, 30)
+ E += (A << 5 | A >>> 27) + f(B, C, D) + X[idx++] + Y1;
+ B = B << 30 | B >>> 2;
+
+ D += (E << 5 | E >>> 27) + f(A, B, C) + X[idx++] + Y1;
+ A = A << 30 | A >>> 2;
+
+ C += (D << 5 | D >>> 27) + f(E, A, B) + X[idx++] + Y1;
+ E = E << 30 | E >>> 2;
+
+ B += (C << 5 | C >>> 27) + f(D, E, A) + X[idx++] + Y1;
+ D = D << 30 | D >>> 2;
+
+ A += (B << 5 | B >>> 27) + f(C, D, E) + X[idx++] + Y1;
+ C = C << 30 | C >>> 2;
+ }
+
+ //
+ // round 2
+ //
+ for (int j = 0; j < 4; j++)
+ {
+ // E = rotateLeft(A, 5) + h(B, C, D) + E + X[idx++] + Y2
+ // B = rotateLeft(B, 30)
+ E += (A << 5 | A >>> 27) + h(B, C, D) + X[idx++] + Y2;
+ B = B << 30 | B >>> 2;
+
+ D += (E << 5 | E >>> 27) + h(A, B, C) + X[idx++] + Y2;
+ A = A << 30 | A >>> 2;
+
+ C += (D << 5 | D >>> 27) + h(E, A, B) + X[idx++] + Y2;
+ E = E << 30 | E >>> 2;
+
+ B += (C << 5 | C >>> 27) + h(D, E, A) + X[idx++] + Y2;
+ D = D << 30 | D >>> 2;
+
+ A += (B << 5 | B >>> 27) + h(C, D, E) + X[idx++] + Y2;
+ C = C << 30 | C >>> 2;
+ }
+
+ //
+ // round 3
+ //
+ for (int j = 0; j < 4; j++)
+ {
+ // E = rotateLeft(A, 5) + g(B, C, D) + E + X[idx++] + Y3
+ // B = rotateLeft(B, 30)
+ E += (A << 5 | A >>> 27) + g(B, C, D) + X[idx++] + Y3;
+ B = B << 30 | B >>> 2;
+
+ D += (E << 5 | E >>> 27) + g(A, B, C) + X[idx++] + Y3;
+ A = A << 30 | A >>> 2;
+
+ C += (D << 5 | D >>> 27) + g(E, A, B) + X[idx++] + Y3;
+ E = E << 30 | E >>> 2;
+
+ B += (C << 5 | C >>> 27) + g(D, E, A) + X[idx++] + Y3;
+ D = D << 30 | D >>> 2;
+
+ A += (B << 5 | B >>> 27) + g(C, D, E) + X[idx++] + Y3;
+ C = C << 30 | C >>> 2;
+ }
+
+ //
+ // round 4
+ //
+ for (int j = 0; j <= 3; j++)
+ {
+ // E = rotateLeft(A, 5) + h(B, C, D) + E + X[idx++] + Y4
+ // B = rotateLeft(B, 30)
+ E += (A << 5 | A >>> 27) + h(B, C, D) + X[idx++] + Y4;
+ B = B << 30 | B >>> 2;
+
+ D += (E << 5 | E >>> 27) + h(A, B, C) + X[idx++] + Y4;
+ A = A << 30 | A >>> 2;
+
+ C += (D << 5 | D >>> 27) + h(E, A, B) + X[idx++] + Y4;
+ E = E << 30 | E >>> 2;
+
+ B += (C << 5 | C >>> 27) + h(D, E, A) + X[idx++] + Y4;
+ D = D << 30 | D >>> 2;
+
+ A += (B << 5 | B >>> 27) + h(C, D, E) + X[idx++] + Y4;
+ C = C << 30 | C >>> 2;
+ }
+
+
+ H1 += A;
+ H2 += B;
+ H3 += C;
+ H4 += D;
+ H5 += E;
+
+ //
+ // reset start of the buffer.
+ //
+ xOff = 0;
+ for (int i = 0; i < 16; i++)
+ {
+ X[i] = 0;
+ }
+ }
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java
new file mode 100644
index 00000000..02b7c50b
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java
@@ -0,0 +1,154 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cert.selector;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Selector;
+
+/**
+ * a basic index for a X509CertificateHolder class
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509CertificateHolderSelector
+ implements Selector
+{
+ private byte[] subjectKeyId;
+
+ private X500Name issuer;
+ private BigInteger serialNumber;
+
+ /**
+ * Construct a selector with the value of a public key's subjectKeyId.
+ *
+ * @param subjectKeyId a subjectKeyId
+ */
+ public X509CertificateHolderSelector(byte[] subjectKeyId)
+ {
+ this(null, null, subjectKeyId);
+ }
+
+ /**
+ * Construct a signer ID based on the issuer and serial number of the signer's associated
+ * certificate.
+ *
+ * @param issuer the issuer of the signer's associated certificate.
+ * @param serialNumber the serial number of the signer's associated certificate.
+ */
+ public X509CertificateHolderSelector(X500Name issuer, BigInteger serialNumber)
+ {
+ this(issuer, serialNumber, null);
+ }
+
+ /**
+ * Construct a signer ID based on the issuer and serial number of the signer's associated
+ * certificate.
+ *
+ * @param issuer the issuer of the signer's associated certificate.
+ * @param serialNumber the serial number of the signer's associated certificate.
+ * @param subjectKeyId the subject key identifier to use to match the signers associated certificate.
+ */
+ public X509CertificateHolderSelector(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyId)
+ {
+ this.issuer = issuer;
+ this.serialNumber = serialNumber;
+ this.subjectKeyId = subjectKeyId;
+ }
+
+ public X500Name getIssuer()
+ {
+ return issuer;
+ }
+
+ public BigInteger getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ public byte[] getSubjectKeyIdentifier()
+ {
+ return Arrays.clone(subjectKeyId);
+ }
+
+ public int hashCode()
+ {
+ int code = Arrays.hashCode(subjectKeyId);
+
+ if (this.serialNumber != null)
+ {
+ code ^= this.serialNumber.hashCode();
+ }
+
+ if (this.issuer != null)
+ {
+ code ^= this.issuer.hashCode();
+ }
+
+ return code;
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof X509CertificateHolderSelector))
+ {
+ return false;
+ }
+
+ X509CertificateHolderSelector id = (X509CertificateHolderSelector)o;
+
+ return Arrays.areEqual(subjectKeyId, id.subjectKeyId)
+ && equalsObj(this.serialNumber, id.serialNumber)
+ && equalsObj(this.issuer, id.issuer);
+ }
+
+ private boolean equalsObj(Object a, Object b)
+ {
+ return (a != null) ? a.equals(b) : b == null;
+ }
+
+ public boolean match(Object obj)
+ {
+ if (obj instanceof X509CertificateHolder)
+ {
+ X509CertificateHolder certHldr = (X509CertificateHolder)obj;
+
+ if (this.getSerialNumber() != null)
+ {
+ IssuerAndSerialNumber iAndS = new IssuerAndSerialNumber(certHldr.toASN1Structure());
+
+ return iAndS.getName().equals(this.issuer)
+ && iAndS.getSerialNumber().hasValue(this.serialNumber);
+ }
+ else if (subjectKeyId != null)
+ {
+ Extension ext = certHldr.getExtension(Extension.subjectKeyIdentifier);
+
+ if (ext == null)
+ {
+ return Arrays.areEqual(subjectKeyId, MSOutlookKeyIdCalculator.calculateKeyId(certHldr.getSubjectPublicKeyInfo()));
+ }
+
+ byte[] subKeyID = ASN1OctetString.getInstance(ext.getParsedValue()).getOctets();
+
+ return Arrays.areEqual(subjectKeyId, subKeyID);
+ }
+ }
+ else if (obj instanceof byte[])
+ {
+ return Arrays.areEqual(subjectKeyId, (byte[])obj);
+ }
+
+ return false;
+ }
+
+ public Object clone()
+ {
+ return new X509CertificateHolderSelector(this.issuer, this.serialNumber, this.subjectKeyId);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAbsentContent.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAbsentContent.java
new file mode 100644
index 00000000..78252a1c
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAbsentContent.java
@@ -0,0 +1,51 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
+
+/**
+ * a class representing null or absent content.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMSAbsentContent
+ implements CMSTypedData, CMSReadable
+{
+ private final ASN1ObjectIdentifier type;
+
+ public CMSAbsentContent()
+ {
+ this(CMSObjectIdentifiers.data);
+ }
+
+ public CMSAbsentContent(
+ ASN1ObjectIdentifier type)
+ {
+ this.type = type;
+ }
+
+ public InputStream getInputStream()
+ {
+ return null;
+ }
+
+ public void write(OutputStream zOut)
+ throws IOException, CMSException
+ {
+ // do nothing
+ }
+
+ public Object getContent()
+ {
+ return null;
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return type;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerationException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerationException.java
new file mode 100644
index 00000000..7b82fc2f
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerationException.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMSAttributeTableGenerationException
+ extends CMSRuntimeException
+{
+ Exception e;
+
+ public CMSAttributeTableGenerationException(
+ String name)
+ {
+ super(name);
+ }
+
+ public CMSAttributeTableGenerationException(
+ String name,
+ Exception e)
+ {
+ super(name);
+
+ this.e = e;
+ }
+
+ public Exception getUnderlyingException()
+ {
+ return e;
+ }
+
+ public Throwable getCause()
+ {
+ return e;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerator.java
new file mode 100644
index 00000000..ea92ba12
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerator.java
@@ -0,0 +1,23 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.cms.AttributeTable;
+
+/**
+ * Note: The SIGNATURE parameter is only available when generating unsigned attributes.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CMSAttributeTableGenerator
+{
+ String CONTENT_TYPE = "contentType";
+ String DIGEST = "digest";
+ String SIGNATURE = "encryptedDigest";
+ String DIGEST_ALGORITHM_IDENTIFIER = "digestAlgID";
+ String MAC_ALGORITHM_IDENTIFIER = "macAlgID";
+ String SIGNATURE_ALGORITHM_IDENTIFIER = "signatureAlgID";
+
+ AttributeTable getAttributes(Map parameters)
+ throws CMSAttributeTableGenerationException;
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSException.java
new file mode 100644
index 00000000..03dcb2f9
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSException.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMSException
+ extends Exception
+{
+ Exception e;
+
+ public CMSException(
+ String msg)
+ {
+ super(msg);
+ }
+
+ public CMSException(
+ String msg,
+ Exception e)
+ {
+ super(msg);
+
+ this.e = e;
+ }
+
+ public Exception getUnderlyingException()
+ {
+ return e;
+ }
+
+ public Throwable getCause()
+ {
+ return e;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessable.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessable.java
new file mode 100644
index 00000000..be5ecfe6
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessable.java
@@ -0,0 +1,23 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Use CMSTypedData instead of this. See CMSProcessableFile/ByteArray for defaults.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CMSProcessable
+{
+ /**
+ * generic routine to copy out the data we want processed - the OutputStream
+ * passed in will do the handling on it's own.
+ * <p>
+ * Note: this routine may be called multiple times.
+ */
+ public void write(OutputStream out)
+ throws IOException, CMSException;
+
+ public Object getContent();
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessableByteArray.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessableByteArray.java
new file mode 100644
index 00000000..57837488
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessableByteArray.java
@@ -0,0 +1,57 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * a holding class for a byte array of data to be processed.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMSProcessableByteArray
+ implements CMSTypedData, CMSReadable
+{
+ private final ASN1ObjectIdentifier type;
+ private final byte[] bytes;
+
+ public CMSProcessableByteArray(
+ byte[] bytes)
+ {
+ this(CMSObjectIdentifiers.data, bytes);
+ }
+
+ public CMSProcessableByteArray(
+ ASN1ObjectIdentifier type,
+ byte[] bytes)
+ {
+ this.type = type;
+ this.bytes = bytes;
+ }
+
+ public InputStream getInputStream()
+ {
+ return new ByteArrayInputStream(bytes);
+ }
+
+ public void write(OutputStream zOut)
+ throws IOException, CMSException
+ {
+ zOut.write(bytes);
+ }
+
+ public Object getContent()
+ {
+ return Arrays.clone(bytes);
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return type;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSReadable.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSReadable.java
new file mode 100644
index 00000000..ceedceea
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSReadable.java
@@ -0,0 +1,11 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+interface CMSReadable
+{
+ public InputStream getInputStream()
+ throws IOException, CMSException;
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSRuntimeException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSRuntimeException.java
new file mode 100644
index 00000000..5fdd6502
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSRuntimeException.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMSRuntimeException
+ extends RuntimeException
+{
+ Exception e;
+
+ public CMSRuntimeException(
+ String name)
+ {
+ super(name);
+ }
+
+ public CMSRuntimeException(
+ String name,
+ Exception e)
+ {
+ super(name);
+
+ this.e = e;
+ }
+
+ public Exception getUnderlyingException()
+ {
+ return e;
+ }
+
+ public Throwable getCause()
+ {
+ return e;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java
new file mode 100644
index 00000000..d07820de
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java
@@ -0,0 +1,19 @@
+/* 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 CMSSignatureAlgorithmNameGenerator
+{
+ /**
+ * Return the digest algorithm using one of the standard string
+ * representations rather than the algorithm object identifier (if possible).
+ *
+ * @param digestAlg the digest algorithm id.
+ * @param encryptionAlg the encryption, or signing, algorithm id.
+ */
+ String getSignatureName(AlgorithmIdentifier digestAlg, AlgorithmIdentifier encryptionAlg);
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java
new file mode 100644
index 00000000..380a108c
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * Finder which is used to look up the algorithm identifiers representing the encryption algorithms that
+ * are associated with a particular signature algorithm.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CMSSignatureEncryptionAlgorithmFinder
+{
+ /**
+ * Return the encryption algorithm identifier associated with the passed in signatureAlgorithm
+ * @param signatureAlgorithm the algorithm identifier of the signature of interest
+ * @return the algorithm identifier to be associated with the encryption algorithm used in signature creation.
+ */
+ AlgorithmIdentifier findEncryptionAlgorithm(AlgorithmIdentifier signatureAlgorithm);
+}
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
new file mode 100644
index 00000000..f42ea21e
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedData.java
@@ -0,0 +1,636 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+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.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+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;
+import com.android.internal.org.bouncycastle.asn1.cms.SignerInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+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.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.
+ *
+ * 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
+ * matches the given signer...
+ *
+ * <pre>
+ * Store certStore = s.getCertificates();
+ * SignerInformationStore signers = s.getSignerInfos();
+ * Collection c = signers.getSigners();
+ * Iterator it = c.iterator();
+ *
+ * while (it.hasNext())
+ * {
+ * SignerInformation signer = (SignerInformation)it.next();
+ * Collection certCollection = certStore.getMatches(signer.getSID());
+ *
+ * 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
+ */
+public class CMSSignedData
+ implements Encodable
+{
+ private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE;
+
+ SignedData signedData;
+ ContentInfo contentInfo;
+ CMSTypedData signedContent;
+ SignerInformationStore signerInfoStore;
+
+ private Map hashes;
+
+ private CMSSignedData(
+ CMSSignedData c)
+ {
+ this.signedData = c.signedData;
+ this.contentInfo = c.contentInfo;
+ this.signedContent = c.signedContent;
+ this.signerInfoStore = c.signerInfoStore;
+ }
+
+ public CMSSignedData(
+ byte[] sigBlock)
+ throws CMSException
+ {
+ this(CMSUtils.readContentInfo(sigBlock));
+ }
+
+ public CMSSignedData(
+ CMSProcessable signedContent,
+ byte[] sigBlock)
+ throws CMSException
+ {
+ this(signedContent, CMSUtils.readContentInfo(sigBlock));
+ }
+
+ /**
+ * Content with detached signature, digests precomputed
+ *
+ * @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)
+ throws CMSException
+ {
+ this(hashes, CMSUtils.readContentInfo(sigBlock));
+ }
+
+ /**
+ * base constructor - content with detached signature.
+ *
+ * @param signedContent the content that was signed.
+ * @param sigData the signature object.
+ */
+ public CMSSignedData(
+ CMSProcessable signedContent,
+ InputStream sigData)
+ throws CMSException
+ {
+ this(signedContent, CMSUtils.readContentInfo(new ASN1InputStream(sigData)));
+ }
+
+ /**
+ * base constructor - with encapsulated content
+ */
+ public CMSSignedData(
+ InputStream sigData)
+ throws CMSException
+ {
+ this(CMSUtils.readContentInfo(sigData));
+ }
+
+ public CMSSignedData(
+ final CMSProcessable signedContent,
+ ContentInfo sigData)
+ throws CMSException
+ {
+ if (signedContent instanceof CMSTypedData)
+ {
+ this.signedContent = (CMSTypedData)signedContent;
+ }
+ else
+ {
+ this.signedContent = new CMSTypedData()
+ {
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return signedData.getEncapContentInfo().getContentType();
+ }
+
+ public void write(OutputStream out)
+ throws IOException, CMSException
+ {
+ signedContent.write(out);
+ }
+
+ public Object getContent()
+ {
+ return signedContent.getContent();
+ }
+ };
+ }
+
+ this.contentInfo = sigData;
+ this.signedData = getSignedData();
+ }
+
+ public CMSSignedData(
+ Map hashes,
+ ContentInfo sigData)
+ throws CMSException
+ {
+ this.hashes = hashes;
+ this.contentInfo = sigData;
+ this.signedData = getSignedData();
+ }
+
+ public CMSSignedData(
+ ContentInfo sigData)
+ throws CMSException
+ {
+ this.contentInfo = sigData;
+ this.signedData = getSignedData();
+
+ //
+ // this can happen if the signed message is sent simply to send a
+ // certificate chain.
+ //
+ ASN1Encodable content = signedData.getEncapContentInfo().getContent();
+ if (content != null)
+ {
+ if (content instanceof ASN1OctetString)
+ {
+ this.signedContent = new CMSProcessableByteArray(signedData.getEncapContentInfo().getContentType(),
+ ((ASN1OctetString)content).getOctets());
+ }
+ else
+ {
+ this.signedContent = new PKCS7ProcessableObject(signedData.getEncapContentInfo().getContentType(), content);
+ }
+ }
+ else
+ {
+ this.signedContent = null;
+ }
+ }
+
+ private SignedData getSignedData()
+ throws CMSException
+ {
+ try
+ {
+ return SignedData.getInstance(contentInfo.getContent());
+ }
+ catch (ClassCastException e)
+ {
+ throw new CMSException("Malformed content.", e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new CMSException("Malformed content.", e);
+ }
+ }
+
+ /**
+ * Return the version number for this object
+ */
+ public int getVersion()
+ {
+ return signedData.getVersion().intValueExact();
+ }
+
+ /**
+ * return the collection of signers that are associated with the
+ * signatures for the message.
+ */
+ public SignerInformationStore getSignerInfos()
+ {
+ if (signerInfoStore == null)
+ {
+ ASN1Set s = signedData.getSignerInfos();
+ List signerInfos = new ArrayList();
+
+ for (int i = 0; i != s.size(); i++)
+ {
+ SignerInfo info = SignerInfo.getInstance(s.getObjectAt(i));
+ ASN1ObjectIdentifier contentType = signedData.getEncapContentInfo().getContentType();
+
+ if (hashes == null)
+ {
+ signerInfos.add(new SignerInformation(info, contentType, signedContent, null));
+ }
+ else
+ {
+ Object obj = hashes.keySet().iterator().next();
+ byte[] hash = (obj instanceof String) ? (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm().getId()) : (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm());
+
+ signerInfos.add(new SignerInformation(info, contentType, null, hash));
+ }
+ }
+
+ signerInfoStore = new SignerInformationStore(signerInfos);
+ }
+
+ return signerInfoStore;
+ }
+
+ /**
+ * Return if this is object represents a detached signature.
+ *
+ * @return true if this message represents a detached signature, false otherwise.
+ */
+ public boolean isDetachedSignature()
+ {
+ return signedData.getEncapContentInfo().getContent() == null && signedData.getSignerInfos().size() > 0;
+ }
+
+ /**
+ * Return if this is object represents a certificate management message.
+ *
+ * @return true if the message has no signers or content, false otherwise.
+ */
+ public boolean isCertificateManagementMessage()
+ {
+ return signedData.getEncapContentInfo().getContent() == null && signedData.getSignerInfos().size() == 0;
+ }
+
+ /**
+ * Return any X.509 certificate objects in this SignedData structure as a Store of X509CertificateHolder objects.
+ *
+ * @return a Store of X509CertificateHolder objects.
+ */
+ public Store<X509CertificateHolder> getCertificates()
+ {
+ return HELPER.getCertificates(signedData.getCertificates());
+ }
+
+ /**
+ * Return any X.509 CRL objects in this SignedData structure as a Store of X509CRLHolder objects.
+ *
+ * @return a Store of X509CRLHolder objects.
+ */
+ public Store<X509CRLHolder> getCRLs()
+ {
+ return HELPER.getCRLs(signedData.getCRLs());
+ }
+
+ /**
+ * Return any X.509 attribute certificate objects in this SignedData structure as a Store of X509AttributeCertificateHolder objects.
+ *
+ * @return a Store of X509AttributeCertificateHolder objects.
+ */
+ public Store<X509AttributeCertificateHolder> getAttributeCertificates()
+ {
+ return HELPER.getAttributeCertificates(signedData.getCertificates());
+ }
+
+ // BEGIN Android-removed: OtherRevocationInfoFormat isn't supported
+ /*
+ /**
+ * Return any OtherRevocationInfo OtherRevInfo objects of the type indicated by otherRevocationInfoFormat in
+ * 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)
+ {
+ return HELPER.getOtherRevocationInfo(otherRevocationInfoFormat, signedData.getCRLs());
+ }
+ */
+ // END Android-removed: OtherRevocationInfoFormat isn't supported
+
+ /**
+ * Return the digest algorithm identifiers for the SignedData object
+ *
+ * @return the set of digest algorithm identifiers
+ */
+ public Set<AlgorithmIdentifier> getDigestAlgorithmIDs()
+ {
+ Set<AlgorithmIdentifier> digests = new HashSet<AlgorithmIdentifier>(signedData.getDigestAlgorithms().size());
+
+ for (Enumeration en = signedData.getDigestAlgorithms().getObjects(); en.hasMoreElements();)
+ {
+ digests.add(AlgorithmIdentifier.getInstance(en.nextElement()));
+ }
+
+ return Collections.unmodifiableSet(digests);
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * return the ContentInfo
+ */
+ public ContentInfo toASN1Structure()
+ {
+ return contentInfo;
+ }
+
+ /**
+ * return the ASN.1 encoded representation of this object.
+ */
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return contentInfo.getEncoded();
+ }
+
+ // BEGIN Android-removed: Unknown reason
+ /*
+ /**
+ * 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);
+ }
+
+ /**
+ * Verify all the SignerInformation objects and their associated counter signatures attached
+ * to this CMS SignedData object.
+ *
+ * @param verifierProvider a provider of SignerInformationVerifier objects.
+ * @return true if all verify, false otherwise.
+ * @throws CMSException if an exception occurs during the verification process.
+ *
+ public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider)
+ throws CMSException
+ {
+ return verifySignatures(verifierProvider, false);
+ }
+
+ /**
+ * 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 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.
+ *
+ public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider, boolean ignoreCounterSignatures)
+ throws CMSException
+ {
+ Collection signers = this.getSignerInfos().getSigners();
+
+ for (Iterator it = signers.iterator(); it.hasNext();)
+ {
+ SignerInformation signer = (SignerInformation)it.next();
+
+ try
+ {
+ SignerInformationVerifier verifier = verifierProvider.get(signer.getSID());
+
+ if (!signer.verify(verifier))
+ {
+ return false;
+ }
+
+ if (!ignoreCounterSignatures)
+ {
+ Collection counterSigners = signer.getCounterSignatures().getSigners();
+
+ for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();)
+ {
+ if (!verifyCounterSignature((SignerInformation)cIt.next(), verifierProvider))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ catch (OperatorCreationException e)
+ {
+ throw new CMSException("failure in verifier provider: " + e.getMessage(), e);
+ }
+ }
+
+ return true;
+ }
+
+ private boolean verifyCounterSignature(SignerInformation counterSigner, SignerInformationVerifierProvider verifierProvider)
+ throws OperatorCreationException, CMSException
+ {
+ SignerInformationVerifier counterVerifier = verifierProvider.get(counterSigner.getSID());
+
+ if (!counterSigner.verify(counterVerifier))
+ {
+ return false;
+ }
+
+ Collection counterSigners = counterSigner.getCounterSignatures().getSigners();
+ for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();)
+ {
+ if (!verifyCounterSignature((SignerInformation)cIt.next(), verifierProvider))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ */
+ // END Android-removed: Unknown reason
+
+ /**
+ * 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
+ * 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.
+ * @return a new signed data object.
+ */
+ public static CMSSignedData replaceSigners(
+ CMSSignedData signedData,
+ SignerInformationStore signerInformationStore)
+ {
+ //
+ // copy
+ //
+ CMSSignedData cms = new CMSSignedData(signedData);
+
+ //
+ // replace the store
+ //
+ cms.signerInfoStore = signerInformationStore;
+
+ //
+ // replace the signers in the SignedData object
+ //
+ ASN1EncodableVector digestAlgs = new ASN1EncodableVector();
+ ASN1EncodableVector vec = new ASN1EncodableVector();
+
+ Iterator it = signerInformationStore.getSigners().iterator();
+ while (it.hasNext())
+ {
+ SignerInformation signer = (SignerInformation)it.next();
+ digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID()));
+ vec.add(signer.toASN1Structure());
+ }
+
+ ASN1Set digests = new DERSet(digestAlgs);
+ ASN1Set signers = new DLSet(vec);
+ ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive();
+
+ vec = new ASN1EncodableVector();
+
+ //
+ // signers are the last item in the sequence.
+ //
+ vec.add(sD.getObjectAt(0)); // version
+ vec.add(digests);
+
+ for (int i = 2; i != sD.size() - 1; i++)
+ {
+ vec.add(sD.getObjectAt(i));
+ }
+
+ vec.add(signers);
+
+ 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 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 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.
+ * @return a new signed data object.
+ * @exception CMSException if there is an error processing the CertStore
+ */
+ public static CMSSignedData replaceCertificatesAndCRLs(
+ CMSSignedData signedData,
+ Store certificates,
+ Store attrCerts,
+ Store revocations)
+ throws CMSException
+ {
+ //
+ // copy
+ //
+ CMSSignedData cms = new CMSSignedData(signedData);
+
+ //
+ // replace the certs and revocations in the SignedData object
+ //
+ ASN1Set certSet = null;
+ ASN1Set crlSet = null;
+
+ if (certificates != null || attrCerts != null)
+ {
+ List certs = new ArrayList();
+
+ if (certificates != null)
+ {
+ certs.addAll(CMSUtils.getCertificatesFromStore(certificates));
+ }
+ if (attrCerts != null)
+ {
+ certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts));
+ }
+
+ ASN1Set set = CMSUtils.createBerSetFromList(certs);
+
+ if (set.size() != 0)
+ {
+ certSet = set;
+ }
+ }
+
+ if (revocations != null)
+ {
+ ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(revocations));
+
+ if (set.size() != 0)
+ {
+ crlSet = set;
+ }
+ }
+
+ //
+ // replace the CMS structure.
+ //
+ cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(),
+ signedData.signedData.getEncapContentInfo(),
+ certSet,
+ crlSet,
+ signedData.signedData.getSignerInfos());
+
+ //
+ // replace the contentInfo with the new one
+ //
+ cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData);
+
+ return cms;
+ }
+}
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
new file mode 100644
index 00000000..1fdaaa9d
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedDataGenerator.java
@@ -0,0 +1,234 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+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.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.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;
+
+/**
+ * general class for generating a pkcs7-signature message.
+ * <p>
+ * A simple example of usage, generating a detached signature.
+ *
+ * <pre>
+ * List certList = new ArrayList();
+ * CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes());
+ *
+ * certList.add(signCert);
+ *
+ * Store certs = new JcaCertStore(certList);
+ *
+ * CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
+ * ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(signKP.getPrivate());
+ *
+ * gen.addSignerInfoGenerator(
+ * new JcaSignerInfoGeneratorBuilder(
+ * new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
+ * .build(sha1Signer, signCert));
+ *
+ * gen.addCertificates(certs);
+ *
+ * CMSSignedData sigData = gen.generate(msg, false);
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMSSignedDataGenerator
+ extends CMSSignedGenerator
+{
+ private List signerInfs = new ArrayList();
+
+ /**
+ * base constructor
+ */
+ public CMSSignedDataGenerator()
+ {
+ }
+
+ /**
+ * Generate a CMS Signed Data object carrying a detached CMS signature.
+ *
+ * @param content the content to be signed.
+ */
+ public CMSSignedData generate(
+ CMSTypedData content)
+ throws CMSException
+ {
+ return generate(content, false);
+ }
+
+ /**
+ * Generate a CMS Signed Data object which can be carrying a detached CMS signature, or have encapsulated data, depending on the value
+ * of the encapsulated parameter.
+ *
+ * @param content the content to be signed.
+ * @param encapsulate true if the content should be encapsulated in the signature, false otherwise.
+ */
+ public CMSSignedData generate(
+ // FIXME Avoid accessing more than once to support CMSProcessableInputStream
+ CMSTypedData content,
+ boolean encapsulate)
+ throws CMSException
+ {
+ if (!signerInfs.isEmpty())
+ {
+ throw new IllegalStateException("this method can only be used with SignerInfoGenerator");
+ }
+
+ // TODO
+// if (signerInfs.isEmpty())
+// {
+// /* RFC 3852 5.2
+// * "In the degenerate case where there are no signers, the
+// * EncapsulatedContentInfo value being "signed" is irrelevant. In this
+// * case, the content type within the EncapsulatedContentInfo value being
+// * "signed" MUST be id-data (as defined in section 4), and the content
+// * field of the EncapsulatedContentInfo value MUST be omitted."
+// */
+// if (encapsulate)
+// {
+// throw new IllegalArgumentException("no signers, encapsulate must be false");
+// }
+// if (!DATA.equals(eContentType))
+// {
+// throw new IllegalArgumentException("no signers, eContentType must be id-data");
+// }
+// }
+//
+// if (!DATA.equals(eContentType))
+// {
+// /* RFC 3852 5.3
+// * [The 'signedAttrs']...
+// * field is optional, but it MUST be present if the content type of
+// * the EncapsulatedContentInfo value being signed is not id-data.
+// */
+// // TODO signedAttrs must be present for all signers
+// }
+
+ ASN1EncodableVector digestAlgs = new ASN1EncodableVector();
+ ASN1EncodableVector signerInfos = new ASN1EncodableVector();
+
+ digests.clear(); // clear the current preserved digest state
+
+ //
+ // add the precalculated SignerInfo objects.
+ //
+ for (Iterator it = _signers.iterator(); it.hasNext();)
+ {
+ SignerInformation signer = (SignerInformation)it.next();
+ digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID()));
+
+ // TODO Verify the content type and calculated digest match the precalculated SignerInfo
+ signerInfos.add(signer.toASN1Structure());
+ }
+
+ //
+ // add the SignerInfo objects
+ //
+ ASN1ObjectIdentifier contentTypeOID = content.getContentType();
+
+ ASN1OctetString octs = null;
+
+ if (content.getContent() != null)
+ {
+ ByteArrayOutputStream bOut = null;
+
+ if (encapsulate)
+ {
+ bOut = new ByteArrayOutputStream();
+ }
+
+ OutputStream cOut = CMSUtils.attachSignersToOutputStream(signerGens, bOut);
+
+ // Just in case it's unencapsulated and there are no signers!
+ cOut = CMSUtils.getSafeOutputStream(cOut);
+
+ try
+ {
+ content.write(cOut);
+
+ cOut.close();
+ }
+ catch (IOException e)
+ {
+ throw new CMSException("data processing exception: " + e.getMessage(), e);
+ }
+
+ if (encapsulate)
+ {
+ octs = new BEROctetString(bOut.toByteArray());
+ }
+ }
+
+ for (Iterator it = signerGens.iterator(); it.hasNext();)
+ {
+ SignerInfoGenerator sGen = (SignerInfoGenerator)it.next();
+ SignerInfo inf = sGen.generate(contentTypeOID);
+
+ digestAlgs.add(inf.getDigestAlgorithm());
+ signerInfos.add(inf);
+
+ byte[] calcDigest = sGen.getCalculatedDigest();
+
+ if (calcDigest != null)
+ {
+ digests.put(inf.getDigestAlgorithm().getAlgorithm().getId(), calcDigest);
+ }
+ }
+
+ ASN1Set certificates = null;
+
+ if (certs.size() != 0)
+ {
+ certificates = CMSUtils.createBerSetFromList(certs);
+ }
+
+ ASN1Set certrevlist = null;
+
+ if (crls.size() != 0)
+ {
+ certrevlist = CMSUtils.createBerSetFromList(crls);
+ }
+
+ ContentInfo encInfo = new ContentInfo(contentTypeOID, octs);
+
+ SignedData sd = new SignedData(
+ new DERSet(digestAlgs),
+ encInfo,
+ certificates,
+ certrevlist,
+ new DERSet(signerInfos));
+
+ ContentInfo contentInfo = new ContentInfo(
+ CMSObjectIdentifiers.signedData, sd);
+
+ return new CMSSignedData(content, contentInfo);
+ }
+
+ /**
+ * generate a set of one or more SignerInformation objects representing counter signatures on
+ * the passed in SignerInformation object.
+ *
+ * @param signer the signer to be countersigned
+ * @return a store containing the signers.
+ */
+ public SignerInformationStore generateCounterSigners(SignerInformation signer)
+ throws CMSException
+ {
+ return this.generate(new CMSProcessableByteArray(null, signer.getSignature()), false).getSignerInfos();
+ }
+}
+
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
new file mode 100644
index 00000000..eae4ff4b
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedGenerator.java
@@ -0,0 +1,256 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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.OtherRevocationInfoFormat;
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+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;
+// Android-removed: Unsupported algorithms
+// 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;
+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.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Store;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMSSignedGenerator
+{
+ /**
+ * 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();
+ public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId();
+ public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId();
+ 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 DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId();
+ // public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId();
+ // public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId();
+ // public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId();
+ // END Android-removed: Unsupported algorithms
+
+ public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId();
+ public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId();
+ public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId();
+ public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId();
+ // BEGIN Android-removed: Unsupported algorithms
+ // public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId();
+ // public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId();
+ // public static final String ENCRYPTION_ECGOST3410_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256.getId();
+ // public static final String ENCRYPTION_ECGOST3410_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512.getId();
+ // END Android-removed: Unsupported algorithms
+
+ private static final String ENCRYPTION_ECDSA_WITH_SHA1 = X9ObjectIdentifiers.ecdsa_with_SHA1.getId();
+ private static final String ENCRYPTION_ECDSA_WITH_SHA224 = X9ObjectIdentifiers.ecdsa_with_SHA224.getId();
+ private static final String ENCRYPTION_ECDSA_WITH_SHA256 = X9ObjectIdentifiers.ecdsa_with_SHA256.getId();
+ private static final String ENCRYPTION_ECDSA_WITH_SHA384 = X9ObjectIdentifiers.ecdsa_with_SHA384.getId();
+ private static final String ENCRYPTION_ECDSA_WITH_SHA512 = X9ObjectIdentifiers.ecdsa_with_SHA512.getId();
+
+ private static final Set NO_PARAMS = new HashSet();
+ private static final Map EC_ALGORITHMS = new HashMap();
+
+ static
+ {
+ NO_PARAMS.add(ENCRYPTION_DSA);
+ NO_PARAMS.add(ENCRYPTION_ECDSA);
+ NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1);
+ NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA224);
+ NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA256);
+ NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA384);
+ NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA512);
+
+ EC_ALGORITHMS.put(DIGEST_SHA1, ENCRYPTION_ECDSA_WITH_SHA1);
+ EC_ALGORITHMS.put(DIGEST_SHA224, ENCRYPTION_ECDSA_WITH_SHA224);
+ EC_ALGORITHMS.put(DIGEST_SHA256, ENCRYPTION_ECDSA_WITH_SHA256);
+ EC_ALGORITHMS.put(DIGEST_SHA384, ENCRYPTION_ECDSA_WITH_SHA384);
+ EC_ALGORITHMS.put(DIGEST_SHA512, ENCRYPTION_ECDSA_WITH_SHA512);
+ }
+
+ protected List certs = new ArrayList();
+ protected List crls = new ArrayList();
+ protected List _signers = new ArrayList();
+ protected List signerGens = new ArrayList();
+ protected Map digests = new HashMap();
+
+ /**
+ * base constructor
+ */
+ protected CMSSignedGenerator()
+ {
+ }
+
+ protected Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
+ {
+ Map param = new HashMap();
+ param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType);
+ param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId);
+ param.put(CMSAttributeTableGenerator.DIGEST, Arrays.clone(hash));
+ return param;
+ }
+
+ /**
+ * Add a certificate to the certificate set to be included with the generated SignedData message.
+ *
+ * @param certificate the certificate to be included.
+ * @throws CMSException if the certificate cannot be encoded for adding.
+ */
+ public void addCertificate(
+ X509CertificateHolder certificate)
+ throws CMSException
+ {
+ certs.add(certificate.toASN1Structure());
+ }
+
+ /**
+ * Add the certificates in certStore to the certificate set to be included with the generated SignedData message.
+ *
+ * @param certStore the store containing the certificates to be included.
+ * @throws CMSException if the certificates cannot be encoded for adding.
+ */
+ public void addCertificates(
+ Store certStore)
+ throws CMSException
+ {
+ certs.addAll(CMSUtils.getCertificatesFromStore(certStore));
+ }
+
+ /**
+ * Add a CRL to the CRL set to be included with the generated SignedData message.
+ *
+ * @param crl the CRL to be included.
+ */
+ public void addCRL(X509CRLHolder crl)
+ {
+ crls.add(crl.toASN1Structure());
+ }
+
+ /**
+ * Add the CRLs in crlStore to the CRL set to be included with the generated SignedData message.
+ *
+ * @param crlStore the store containing the CRLs to be included.
+ * @throws CMSException if the CRLs cannot be encoded for adding.
+ */
+ public void addCRLs(
+ Store crlStore)
+ throws CMSException
+ {
+ crls.addAll(CMSUtils.getCRLsFromStore(crlStore));
+ }
+
+ /**
+ * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message.
+ *
+ * @param attrCert the store containing the certificates to be included.
+ * @throws CMSException if the attribute certificate cannot be encoded for adding.
+ */
+ public void addAttributeCertificate(
+ X509AttributeCertificateHolder attrCert)
+ throws CMSException
+ {
+ certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure()));
+ }
+
+ /**
+ * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message.
+ *
+ * @param attrStore the store containing the certificates to be included.
+ * @throws CMSException if the attribute certificate cannot be encoded for adding.
+ */
+ public void addAttributeCertificates(
+ Store attrStore)
+ throws CMSException
+ {
+ certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrStore));
+ }
+
+ // BEGIN Android-removed: OtherRevocationInfoFormat isn't supported
+ /*
+ /**
+ * Add a single instance of otherRevocationData to the CRL set to be included with the generated SignedData message.
+ *
+ * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data.
+ * @param otherRevocationInfo the otherRevocationInfo ASN.1 structure.
+ *
+ public void addOtherRevocationInfo(
+ ASN1ObjectIdentifier otherRevocationInfoFormat,
+ ASN1Encodable otherRevocationInfo)
+ {
+ crls.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, otherRevocationInfo)));
+ }
+
+ /**
+ * Add a Store of otherRevocationData to the CRL set to be included with the generated SignedData message.
+ *
+ * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data.
+ * @param otherRevocationInfos a Store of otherRevocationInfo data to add.
+ *
+ public void addOtherRevocationInfo(
+ ASN1ObjectIdentifier otherRevocationInfoFormat,
+ Store otherRevocationInfos)
+ {
+ crls.addAll(CMSUtils.getOthersFromStore(otherRevocationInfoFormat, otherRevocationInfos));
+ }
+ */
+ // END Android-removed: OtherRevocationInfoFormat isn't supported
+
+ /**
+ * Add a store of pre-calculated signers to the generator.
+ *
+ * @param signerStore store of signers
+ */
+ public void addSigners(
+ SignerInformationStore signerStore)
+ {
+ Iterator it = signerStore.getSigners().iterator();
+
+ while (it.hasNext())
+ {
+ _signers.add(it.next());
+ }
+ }
+
+ /**
+ * Add a generator for a particular signer to this CMS SignedData generator.
+ *
+ * @param infoGen the generator representing the particular signer.
+ */
+ public void addSignerInfoGenerator(SignerInfoGenerator infoGen)
+ {
+ signerGens.add(infoGen);
+ }
+
+ /**
+ * Return a map of oids and byte arrays representing the digests calculated on the content during
+ * the last generate.
+ *
+ * @return a map of oids (as String objects) and byte[] representing digests.
+ */
+ public Map getGeneratedDigests()
+ {
+ return new HashMap(digests);
+ }
+}
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
new file mode 100644
index 00000000..bd528bdb
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedHelper.java
@@ -0,0 +1,272 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+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.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+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 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 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.x509.AttributeCertificate;
+import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
+import com.android.internal.org.bouncycastle.asn1.x509.CertificateList;
+import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+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.util.CollectionStore;
+import com.android.internal.org.bouncycastle.util.Store;
+
+class CMSSignedHelper
+{
+ static final CMSSignedHelper INSTANCE = new CMSSignedHelper();
+
+ private static final Map encryptionAlgs = new HashMap();
+
+ private static void addEntries(ASN1ObjectIdentifier alias, String encryption)
+ {
+ encryptionAlgs.put(alias.getId(), encryption);
+ }
+
+ static
+ {
+ addEntries(NISTObjectIdentifiers.dsa_with_sha224, "DSA");
+ addEntries(NISTObjectIdentifiers.dsa_with_sha256, "DSA");
+ addEntries(NISTObjectIdentifiers.dsa_with_sha384, "DSA");
+ addEntries(NISTObjectIdentifiers.dsa_with_sha512, "DSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_224, "DSA");
+ addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_256, "DSA");
+ addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_384, "DSA");
+ addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_512, "DSA");
+ */
+ // END Android-removed: Unsupported algorithms
+ addEntries(OIWObjectIdentifiers.dsaWithSHA1, "DSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ addEntries(OIWObjectIdentifiers.md4WithRSA, "RSA");
+ addEntries(OIWObjectIdentifiers.md4WithRSAEncryption, "RSA");
+ */
+ // END Android-removed: Unsupported algorithms
+ addEntries(OIWObjectIdentifiers.md5WithRSA, "RSA");
+ addEntries(OIWObjectIdentifiers.sha1WithRSA, "RSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ addEntries(PKCSObjectIdentifiers.md2WithRSAEncryption, "RSA");
+ addEntries(PKCSObjectIdentifiers.md4WithRSAEncryption, "RSA");
+ */
+ // END Android-removed: Unsupported algorithms
+ addEntries(PKCSObjectIdentifiers.md5WithRSAEncryption, "RSA");
+ addEntries(PKCSObjectIdentifiers.sha1WithRSAEncryption, "RSA");
+ addEntries(PKCSObjectIdentifiers.sha224WithRSAEncryption, "RSA");
+ addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "RSA");
+ addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "RSA");
+ addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "RSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224, "RSA");
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256, "RSA");
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384, "RSA");
+ addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512, "RSA");
+ */
+ // END Android-removed: Unsupported algorithms
+ addEntries(X9ObjectIdentifiers.ecdsa_with_SHA1, "ECDSA");
+ addEntries(X9ObjectIdentifiers.ecdsa_with_SHA224, "ECDSA");
+ addEntries(X9ObjectIdentifiers.ecdsa_with_SHA256, "ECDSA");
+ addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "ECDSA");
+ addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "ECDSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_224, "ECDSA");
+ 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");
+ addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "ECDSA");
+ addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "ECDSA");
+ addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "RSA");
+ 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");
+
+ addEntries(X9ObjectIdentifiers.id_dsa, "DSA");
+ addEntries(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ addEntries(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA");
+ addEntries(X509ObjectIdentifiers.id_ea_rsa, "RSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ addEntries(PKCSObjectIdentifiers.id_RSASSA_PSS, "RSAandMGF1");
+ addEntries(CryptoProObjectIdentifiers.gostR3410_94, "GOST3410");
+ addEntries(CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410");
+ addEntries(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.6.2"), "ECGOST3410");
+ addEntries(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.1.5"), "GOST3410");
+ addEntries(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, "ECGOST3410-2012-256");
+ addEntries(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512, "ECGOST3410-2012-512");
+ addEntries(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "ECGOST3410");
+ addEntries(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3410");
+ addEntries(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "ECGOST3410-2012-256");
+ addEntries(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "ECGOST3410-2012-512");
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+
+
+ /**
+ * Return the digest encryption algorithm using one of the standard
+ * JCA string representations rather the the algorithm identifier (if
+ * possible).
+ */
+ String getEncryptionAlgName(
+ String encryptionAlgOID)
+ {
+ String algName = (String)encryptionAlgs.get(encryptionAlgOID);
+
+ if (algName != null)
+ {
+ return algName;
+ }
+
+ return encryptionAlgOID;
+ }
+
+ AlgorithmIdentifier fixAlgID(AlgorithmIdentifier algId)
+ {
+ if (algId.getParameters() == null)
+ {
+ return new AlgorithmIdentifier(algId.getAlgorithm(), DERNull.INSTANCE);
+ }
+
+ return algId;
+ }
+
+ void setSigningEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName)
+ {
+ addEntries(oid, algorithmName);
+ }
+
+ Store getCertificates(ASN1Set certSet)
+ {
+ if (certSet != null)
+ {
+ List certList = new ArrayList(certSet.size());
+
+ for (Enumeration en = certSet.getObjects(); en.hasMoreElements();)
+ {
+ ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive();
+
+ if (obj instanceof ASN1Sequence)
+ {
+ certList.add(new X509CertificateHolder(Certificate.getInstance(obj)));
+ }
+ }
+
+ return new CollectionStore(certList);
+ }
+
+ return new CollectionStore(new ArrayList());
+ }
+
+ Store getAttributeCertificates(ASN1Set certSet)
+ {
+ if (certSet != null)
+ {
+ List certList = new ArrayList(certSet.size());
+
+ for (Enumeration en = certSet.getObjects(); en.hasMoreElements();)
+ {
+ ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive();
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(((ASN1TaggedObject)obj).getObject())));
+ }
+ }
+
+ return new CollectionStore(certList);
+ }
+
+ return new CollectionStore(new ArrayList());
+ }
+
+ Store getCRLs(ASN1Set crlSet)
+ {
+ if (crlSet != null)
+ {
+ List crlList = new ArrayList(crlSet.size());
+
+ for (Enumeration en = crlSet.getObjects(); en.hasMoreElements();)
+ {
+ ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive();
+
+ if (obj instanceof ASN1Sequence)
+ {
+ crlList.add(new X509CRLHolder(CertificateList.getInstance(obj)));
+ }
+ }
+
+ return new CollectionStore(crlList);
+ }
+
+ return new CollectionStore(new ArrayList());
+ }
+
+ // BEGIN Android-removed: OtherRevocationInfoFormat isn't supported
+ /*
+ Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat, ASN1Set crlSet)
+ {
+ if (crlSet != null)
+ {
+ List crlList = new ArrayList(crlSet.size());
+
+ for (Enumeration en = crlSet.getObjects(); en.hasMoreElements();)
+ {
+ ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive();
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(obj);
+
+ if (tObj.getTagNo() == 1)
+ {
+ OtherRevocationInfoFormat other = OtherRevocationInfoFormat.getInstance(tObj, false);
+
+ if (otherRevocationInfoFormat.equals(other.getInfoFormat()))
+ {
+ crlList.add(other.getInfo());
+ }
+ }
+ }
+ }
+
+ return new CollectionStore(crlList);
+ }
+
+ return new CollectionStore(new ArrayList());
+ }
+ */
+ // END Android-removed: OtherRevocationInfoFormat isn't supported
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignerDigestMismatchException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignerDigestMismatchException.java
new file mode 100644
index 00000000..53ae42e9
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignerDigestMismatchException.java
@@ -0,0 +1,15 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMSSignerDigestMismatchException
+ extends CMSException
+{
+ public CMSSignerDigestMismatchException(
+ String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSTypedData.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSTypedData.java
new file mode 100644
index 00000000..c589dc7b
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSTypedData.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CMSTypedData
+ extends CMSProcessable
+{
+ ASN1ObjectIdentifier getContentType();
+}
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
new file mode 100644
index 00000000..a8032604
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSUtils.java
@@ -0,0 +1,396 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+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.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.BEROctetStringGenerator;
+import com.android.internal.org.bouncycastle.asn1.BERSet;
+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.cms.CMSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.cms.ContentInfo;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat;
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.ocsp.OCSPResponse;
+// import org.bouncycastle.asn1.ocsp.OCSPResponseStatus;
+// import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers;
+// import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+// import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+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.DigestCalculator;
+import com.android.internal.org.bouncycastle.util.Store;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.io.Streams;
+import com.android.internal.org.bouncycastle.util.io.TeeInputStream;
+import com.android.internal.org.bouncycastle.util.io.TeeOutputStream;
+
+class CMSUtils
+{
+ private static final Set<String> des = new HashSet<String>();
+ private static final Set mqvAlgs = new HashSet();
+ private static final Set ecAlgs = new HashSet();
+ private static final Set gostAlgs = new HashSet();
+
+ static
+ {
+ des.add("DES");
+ des.add("DESEDE");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ 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);
+ mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme);
+ mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme);
+ mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme);
+ mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme);
+
+ ecAlgs.add(X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme);
+ ecAlgs.add(X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme);
+ ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme);
+ ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme);
+ ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme);
+ ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme);
+ ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme);
+ ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme);
+ ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme);
+ ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme);
+
+ gostAlgs.add(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_ESDH);
+ gostAlgs.add(RosstandartObjectIdentifiers.id_tc26_agreement_gost_3410_12_256);
+ gostAlgs.add(RosstandartObjectIdentifiers.id_tc26_agreement_gost_3410_12_512);
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+
+ static boolean isMQV(ASN1ObjectIdentifier algorithm)
+ {
+ return mqvAlgs.contains(algorithm);
+ }
+
+ static boolean isEC(ASN1ObjectIdentifier algorithm)
+ {
+ return ecAlgs.contains(algorithm);
+ }
+
+ static boolean isGOST(ASN1ObjectIdentifier algorithm)
+ {
+ return gostAlgs.contains(algorithm);
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ static boolean isRFC2631(ASN1ObjectIdentifier algorithm)
+ {
+ return algorithm.equals(PKCSObjectIdentifiers.id_alg_ESDH) || algorithm.equals(PKCSObjectIdentifiers.id_alg_SSDH);
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ static boolean isDES(String algorithmID)
+ {
+ String name = Strings.toUpperCase(algorithmID);
+
+ return des.contains(name);
+ }
+
+ static boolean isEquivalent(AlgorithmIdentifier algId1, AlgorithmIdentifier algId2)
+ {
+ if (algId1 == null || algId2 == null)
+ {
+ return false;
+ }
+
+ if (!algId1.getAlgorithm().equals(algId2.getAlgorithm()))
+ {
+ return false;
+ }
+
+ ASN1Encodable params1 = algId1.getParameters();
+ ASN1Encodable params2 = algId2.getParameters();
+ if (params1 != null)
+ {
+ return params1.equals(params2) || (params1.equals(DERNull.INSTANCE) && params2 == null);
+ }
+
+ return params2 == null || params2.equals(DERNull.INSTANCE);
+ }
+
+ static ContentInfo readContentInfo(
+ byte[] input)
+ throws CMSException
+ {
+ // enforce limit checking as from a byte array
+ return readContentInfo(new ASN1InputStream(input));
+ }
+
+ static ContentInfo readContentInfo(
+ InputStream input)
+ throws CMSException
+ {
+ // enforce some limit checking
+ return readContentInfo(new ASN1InputStream(input));
+ }
+
+ static List getCertificatesFromStore(Store certStore)
+ throws CMSException
+ {
+ List certs = new ArrayList();
+
+ try
+ {
+ for (Iterator it = certStore.getMatches(null).iterator(); it.hasNext(); )
+ {
+ X509CertificateHolder c = (X509CertificateHolder)it.next();
+
+ certs.add(c.toASN1Structure());
+ }
+
+ return certs;
+ }
+ catch (ClassCastException e)
+ {
+ throw new CMSException("error processing certs", e);
+ }
+ }
+
+ static List getAttributeCertificatesFromStore(Store attrStore)
+ throws CMSException
+ {
+ List certs = new ArrayList();
+
+ try
+ {
+ for (Iterator it = attrStore.getMatches(null).iterator(); it.hasNext(); )
+ {
+ X509AttributeCertificateHolder attrCert = (X509AttributeCertificateHolder)it.next();
+
+ certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure()));
+ }
+
+ return certs;
+ }
+ catch (ClassCastException e)
+ {
+ throw new CMSException("error processing certs", e);
+ }
+ }
+
+
+ static List getCRLsFromStore(Store crlStore)
+ throws CMSException
+ {
+ List crls = new ArrayList();
+
+ try
+ {
+ for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext(); )
+ {
+ Object rev = it.next();
+
+ if (rev instanceof X509CRLHolder)
+ {
+ X509CRLHolder c = (X509CRLHolder)rev;
+
+ crls.add(c.toASN1Structure());
+ }
+ // BEGIN Android-removed: OtherRevocationInfoFormat isn't supported
+ // else if (rev instanceof OtherRevocationInfoFormat)
+ // {
+ // OtherRevocationInfoFormat infoFormat = OtherRevocationInfoFormat.getInstance(rev);
+ //
+ // validateInfoFormat(infoFormat);
+ //
+ // crls.add(new DERTaggedObject(false, 1, infoFormat));
+ // }
+ // END Android-removed: OtherRevocationInfoFormat isn't supported
+ else if (rev instanceof ASN1TaggedObject)
+ {
+ crls.add(rev);
+ }
+ }
+
+ return crls;
+ }
+ catch (ClassCastException e)
+ {
+ throw new CMSException("error processing certs", e);
+ }
+ }
+
+ // BEGIN Android-removed: OtherRevocationInfoFormat isn't supported
+ /*
+ private static void validateInfoFormat(OtherRevocationInfoFormat infoFormat)
+ {
+ if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(infoFormat.getInfoFormat()))
+ {
+ OCSPResponse resp = OCSPResponse.getInstance(infoFormat.getInfo());
+
+ if (OCSPResponseStatus.SUCCESSFUL != resp.getResponseStatus().getIntValue())
+ {
+ throw new IllegalArgumentException("cannot add unsuccessful OCSP response to CMS SignedData");
+ }
+ }
+ }
+
+ static Collection getOthersFromStore(ASN1ObjectIdentifier otherRevocationInfoFormat, Store otherRevocationInfos)
+ {
+ List others = new ArrayList();
+
+ for (Iterator it = otherRevocationInfos.getMatches(null).iterator(); it.hasNext(); )
+ {
+ ASN1Encodable info = (ASN1Encodable)it.next();
+ OtherRevocationInfoFormat infoFormat = new OtherRevocationInfoFormat(otherRevocationInfoFormat, info);
+
+ validateInfoFormat(infoFormat);
+
+ others.add(new DERTaggedObject(false, 1, infoFormat));
+ }
+
+ return others;
+ }
+ */
+ // END Android-removed: OtherRevocationInfoFormat isn't supported
+
+ static ASN1Set createBerSetFromList(List derObjects)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (Iterator it = derObjects.iterator(); it.hasNext(); )
+ {
+ v.add((ASN1Encodable)it.next());
+ }
+
+ return new BERSet(v);
+ }
+
+ static ASN1Set createDerSetFromList(List derObjects)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (Iterator it = derObjects.iterator(); it.hasNext(); )
+ {
+ v.add((ASN1Encodable)it.next());
+ }
+
+ return new DERSet(v);
+ }
+
+ static OutputStream createBEROctetOutputStream(OutputStream s,
+ int tagNo, boolean isExplicit, int bufferSize)
+ throws IOException
+ {
+ BEROctetStringGenerator octGen = new BEROctetStringGenerator(s, tagNo, isExplicit);
+
+ if (bufferSize != 0)
+ {
+ return octGen.getOctetOutputStream(new byte[bufferSize]);
+ }
+
+ return octGen.getOctetOutputStream();
+ }
+
+ private static ContentInfo readContentInfo(
+ ASN1InputStream in)
+ throws CMSException
+ {
+ try
+ {
+ ContentInfo info = ContentInfo.getInstance(in.readObject());
+ if (info == null)
+ {
+ throw new CMSException("No content found.");
+ }
+
+ return info;
+ }
+ catch (IOException e)
+ {
+ throw new CMSException("IOException reading content.", e);
+ }
+ catch (ClassCastException e)
+ {
+ throw new CMSException("Malformed content.", e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new CMSException("Malformed content.", e);
+ }
+ }
+
+ public static byte[] streamToByteArray(
+ InputStream in)
+ throws IOException
+ {
+ return Streams.readAll(in);
+ }
+
+ public static byte[] streamToByteArray(
+ InputStream in,
+ int limit)
+ throws IOException
+ {
+ return Streams.readAllLimited(in, limit);
+ }
+
+ static InputStream attachDigestsToInputStream(Collection digests, InputStream s)
+ {
+ InputStream result = s;
+ Iterator it = digests.iterator();
+ while (it.hasNext())
+ {
+ DigestCalculator digest = (DigestCalculator)it.next();
+ result = new TeeInputStream(result, digest.getOutputStream());
+ }
+ return result;
+ }
+
+ static OutputStream attachSignersToOutputStream(Collection signers, OutputStream s)
+ {
+ OutputStream result = s;
+ Iterator it = signers.iterator();
+ while (it.hasNext())
+ {
+ SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next();
+ result = getSafeTeeOutputStream(result, signerGen.getCalculatingOutputStream());
+ }
+ return result;
+ }
+
+ static OutputStream getSafeOutputStream(OutputStream s)
+ {
+ return s == null ? new NullOutputStream() : s;
+ }
+
+ static OutputStream getSafeTeeOutputStream(OutputStream s1,
+ OutputStream s2)
+ {
+ return s1 == null ? getSafeOutputStream(s2)
+ : s2 == null ? getSafeOutputStream(s1) : new TeeOutputStream(
+ s1, s2);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java
new file mode 100644
index 00000000..3ad28616
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java
@@ -0,0 +1,15 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMSVerifierCertificateNotValidException
+ extends CMSException
+{
+ public CMSVerifierCertificateNotValidException(
+ String msg)
+ {
+ super(msg);
+ }
+}
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
new file mode 100644
index 00000000..45a401c4
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
@@ -0,0 +1,249 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.eac.EACObjectIdentifiers;
+// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
+// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+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 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.x509.X509ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultCMSSignatureAlgorithmNameGenerator
+ implements CMSSignatureAlgorithmNameGenerator
+{
+ private final Map encryptionAlgs = new HashMap();
+ private final Map digestAlgs = new HashMap();
+
+ private void addEntries(ASN1ObjectIdentifier alias, String digest, String encryption)
+ {
+ digestAlgs.put(alias, digest);
+ encryptionAlgs.put(alias, encryption);
+ }
+
+ public DefaultCMSSignatureAlgorithmNameGenerator()
+ {
+ addEntries(NISTObjectIdentifiers.dsa_with_sha224, "SHA224", "DSA");
+ addEntries(NISTObjectIdentifiers.dsa_with_sha256, "SHA256", "DSA");
+ addEntries(NISTObjectIdentifiers.dsa_with_sha384, "SHA384", "DSA");
+ addEntries(NISTObjectIdentifiers.dsa_with_sha512, "SHA512", "DSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_224, "SHA3-224", "DSA");
+ addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_256, "SHA3-256", "DSA");
+ addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_384, "SHA3-384", "DSA");
+ addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_512, "SHA3-512", "DSA");
+ 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");
+ addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_224, "SHA3-224", "ECDSA");
+ addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_256, "SHA3-256", "ECDSA");
+ addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_384, "SHA3-384", "ECDSA");
+ addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_512, "SHA3-512", "ECDSA");
+ */
+ // END Android-removed: Unsupported algorithms
+ addEntries(OIWObjectIdentifiers.dsaWithSHA1, "SHA1", "DSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ // addEntries(OIWObjectIdentifiers.md4WithRSA, "MD4", "RSA");
+ // addEntries(OIWObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA");
+ // END Android-removed: Unsupported algorithms
+ addEntries(OIWObjectIdentifiers.md5WithRSA, "MD5", "RSA");
+ addEntries(OIWObjectIdentifiers.sha1WithRSA, "SHA1", "RSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ // addEntries(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2", "RSA");
+ // addEntries(PKCSObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA");
+ // END Android-removed: Unsupported algorithms
+ addEntries(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5", "RSA");
+ addEntries(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1", "RSA");
+ addEntries(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224", "RSA");
+ addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256", "RSA");
+ addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384", "RSA");
+ addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512", "RSA");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, "RIPEMD128", "RSA");
+ addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, "RIPEMD160", "RSA");
+ addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, "RIPEMD256", "RSA");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ addEntries(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1", "ECDSA");
+ addEntries(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224", "ECDSA");
+ addEntries(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256", "ECDSA");
+ addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384", "ECDSA");
+ addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512", "ECDSA");
+ addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1", "DSA");
+ 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");
+ addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384", "ECDSA");
+ addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512", "ECDSA");
+ addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "SHA1", "RSA");
+ 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(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");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ encryptionAlgs.put(X9ObjectIdentifiers.id_dsa, "DSA");
+ encryptionAlgs.put(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ encryptionAlgs.put(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA");
+ encryptionAlgs.put(X509ObjectIdentifiers.id_ea_rsa, "RSA");
+ encryptionAlgs.put(PKCSObjectIdentifiers.id_RSASSA_PSS, "RSAandMGF1");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_94, "GOST3410");
+ encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410");
+ encryptionAlgs.put(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.6.2"), "ECGOST3410");
+ encryptionAlgs.put(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.1.5"), "GOST3410");
+ encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, "ECGOST3410-2012-256");
+ encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512, "ECGOST3410-2012-512");
+ encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "ECGOST3410");
+ 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");
+
+ digestAlgs.put(PKCSObjectIdentifiers.md2, "MD2");
+ digestAlgs.put(PKCSObjectIdentifiers.md4, "MD4");
+ */
+ // END Android-removed: Unsupported algorithms
+ digestAlgs.put(PKCSObjectIdentifiers.md5, "MD5");
+ digestAlgs.put(OIWObjectIdentifiers.idSHA1, "SHA1");
+ digestAlgs.put(NISTObjectIdentifiers.id_sha224, "SHA224");
+ digestAlgs.put(NISTObjectIdentifiers.id_sha256, "SHA256");
+ digestAlgs.put(NISTObjectIdentifiers.id_sha384, "SHA384");
+ digestAlgs.put(NISTObjectIdentifiers.id_sha512, "SHA512");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ digestAlgs.put(NISTObjectIdentifiers.id_sha3_224, "SHA3-224");
+ digestAlgs.put(NISTObjectIdentifiers.id_sha3_256, "SHA3-256");
+ digestAlgs.put(NISTObjectIdentifiers.id_sha3_384, "SHA3-384");
+ digestAlgs.put(NISTObjectIdentifiers.id_sha3_512, "SHA3-512");
+ digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD128");
+ digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160");
+ digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256");
+ digestAlgs.put(CryptoProObjectIdentifiers.gostR3411, "GOST3411");
+ digestAlgs.put(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.2.1"), "GOST3411");
+ 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");
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+
+ /**
+ * Return the digest algorithm using one of the standard JCA string
+ * representations rather than the algorithm identifier (if possible).
+ */
+ private String getDigestAlgName(
+ ASN1ObjectIdentifier digestAlgOID)
+ {
+ String algName = (String)digestAlgs.get(digestAlgOID);
+
+ if (algName != null)
+ {
+ return algName;
+ }
+
+ return digestAlgOID.getId();
+ }
+
+ /**
+ * Return the digest encryption algorithm using one of the standard
+ * JCA string representations rather the the algorithm identifier (if
+ * possible).
+ */
+ private String getEncryptionAlgName(
+ ASN1ObjectIdentifier encryptionAlgOID)
+ {
+ String algName = (String)encryptionAlgs.get(encryptionAlgOID);
+
+ if (algName != null)
+ {
+ return algName;
+ }
+
+ return encryptionAlgOID.getId();
+ }
+
+ /**
+ * Set the mapping for the encryption algorithm used in association with a SignedData generation
+ * or interpretation.
+ *
+ * @param oid object identifier to map.
+ * @param algorithmName algorithm name to use.
+ */
+ protected void setSigningEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName)
+ {
+ encryptionAlgs.put(oid, algorithmName);
+ }
+
+ /**
+ * Set the mapping for the digest algorithm to use in conjunction with a SignedData generation
+ * or interpretation.
+ *
+ * @param oid object identifier to map.
+ * @param algorithmName algorithm name to use.
+ */
+ protected void setSigningDigestAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName)
+ {
+ digestAlgs.put(oid, algorithmName);
+ }
+
+ public String getSignatureName(AlgorithmIdentifier digestAlg, AlgorithmIdentifier encryptionAlg)
+ {
+ // BEGIN Android-removed: unsupported algorithms
+ /*
+ if (EdECObjectIdentifiers.id_Ed25519.equals(encryptionAlg.getAlgorithm()))
+ {
+ return "Ed25519";
+ }
+ if (EdECObjectIdentifiers.id_Ed448.equals(encryptionAlg.getAlgorithm()))
+ {
+ return "Ed448";
+ }
+ */
+ // END Android-removed: unsupported algorithms
+
+ String digestName = getDigestAlgName(encryptionAlg.getAlgorithm());
+
+ if (!digestName.equals(encryptionAlg.getAlgorithm().getId()))
+ {
+ return digestName + "with" + getEncryptionAlgName(encryptionAlg.getAlgorithm());
+ }
+
+ return getDigestAlgName(digestAlg.getAlgorithm()) + "with" + getEncryptionAlgName(encryptionAlg.getAlgorithm());
+ }
+}
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
new file mode 100644
index 00000000..f82906b2
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
@@ -0,0 +1,75 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultCMSSignatureEncryptionAlgorithmFinder
+ implements CMSSignatureEncryptionAlgorithmFinder
+{
+ private static final Set RSA_PKCS1d5 = new HashSet();
+ private static final Map GOST_ENC = new HashMap();
+
+ static
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ // RSA_PKCS1d5.add(PKCSObjectIdentifiers.md2WithRSAEncryption);
+ // RSA_PKCS1d5.add(PKCSObjectIdentifiers.md4WithRSAEncryption);
+ // END Android-removed: Unsupported algorithms
+ RSA_PKCS1d5.add(PKCSObjectIdentifiers.md5WithRSAEncryption);
+ RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha1WithRSAEncryption);
+ // BEGIN Android-added: Add support for SHA-2 family signatures
+ RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha224WithRSAEncryption);
+ RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha256WithRSAEncryption);
+ RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha384WithRSAEncryption);
+ RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha512WithRSAEncryption);
+ // END Android-added: Add support for SHA-2 family signatures
+ // BEGIN Android-removed: Unsupported algorithms
+ // RSA_PKCS1d5.add(OIWObjectIdentifiers.md4WithRSAEncryption);
+ // RSA_PKCS1d5.add(OIWObjectIdentifiers.md4WithRSA);
+ // END Android-removed: Unsupported algorithms
+ RSA_PKCS1d5.add(OIWObjectIdentifiers.md5WithRSA);
+ RSA_PKCS1d5.add(OIWObjectIdentifiers.sha1WithRSA);
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ RSA_PKCS1d5.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ RSA_PKCS1d5.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ RSA_PKCS1d5.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
+ GOST_ENC.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001,
+ new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, DERNull.INSTANCE));
+ GOST_ENC.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256,
+ new AlgorithmIdentifier(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, DERNull.INSTANCE));
+ GOST_ENC.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512,
+ new AlgorithmIdentifier(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512, DERNull.INSTANCE));
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+
+ public AlgorithmIdentifier findEncryptionAlgorithm(AlgorithmIdentifier signatureAlgorithm)
+ {
+ // RFC3370 section 3.2 with RFC 5754 update
+ if (RSA_PKCS1d5.contains(signatureAlgorithm.getAlgorithm()))
+ {
+ return new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
+ }
+ // GOST signature encryption algorithms
+ if (GOST_ENC.containsKey(signatureAlgorithm.getAlgorithm()))
+ {
+ return (AlgorithmIdentifier)GOST_ENC.get(signatureAlgorithm.getAlgorithm());
+ }
+ return signatureAlgorithm;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
new file mode 100644
index 00000000..ca171288
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
@@ -0,0 +1,133 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+import com.android.internal.org.bouncycastle.asn1.cms.Attribute;
+import com.android.internal.org.bouncycastle.asn1.cms.AttributeTable;
+import com.android.internal.org.bouncycastle.asn1.cms.CMSAlgorithmProtection;
+import com.android.internal.org.bouncycastle.asn1.cms.CMSAttributes;
+import com.android.internal.org.bouncycastle.asn1.cms.Time;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * Default signed attributes generator.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultSignedAttributeTableGenerator
+ implements CMSAttributeTableGenerator
+{
+ private final Hashtable table;
+
+ /**
+ * Initialise to use all defaults
+ */
+ public DefaultSignedAttributeTableGenerator()
+ {
+ table = new Hashtable();
+ }
+
+ /**
+ * Initialise with some extra attributes or overrides.
+ *
+ * @param attributeTable initial attribute table to use.
+ */
+ public DefaultSignedAttributeTableGenerator(
+ AttributeTable attributeTable)
+ {
+ if (attributeTable != null)
+ {
+ table = attributeTable.toHashtable();
+ }
+ else
+ {
+ table = new Hashtable();
+ }
+ }
+
+ /**
+ * Create a standard attribute table from the passed in parameters - this will
+ * normally include contentType, signingTime, messageDigest, and CMS algorithm protection.
+ * If the constructor using an AttributeTable was used, entries in it for contentType, signingTime, and
+ * messageDigest will override the generated ones.
+ *
+ * @param parameters source parameters for table generation.
+ *
+ * @return a filled in Hashtable of attributes.
+ */
+ protected Hashtable createStandardAttributeTable(
+ Map parameters)
+ {
+ Hashtable std = copyHashTable(table);
+
+ if (!std.containsKey(CMSAttributes.contentType))
+ {
+ ASN1ObjectIdentifier contentType = ASN1ObjectIdentifier.getInstance(
+ parameters.get(CMSAttributeTableGenerator.CONTENT_TYPE));
+
+ // contentType will be null if we're trying to generate a counter signature.
+ if (contentType != null)
+ {
+ Attribute attr = new Attribute(CMSAttributes.contentType,
+ new DERSet(contentType));
+ std.put(attr.getAttrType(), attr);
+ }
+ }
+
+ if (!std.containsKey(CMSAttributes.signingTime))
+ {
+ Date signingTime = new Date();
+ Attribute attr = new Attribute(CMSAttributes.signingTime,
+ new DERSet(new Time(signingTime)));
+ std.put(attr.getAttrType(), attr);
+ }
+
+ if (!std.containsKey(CMSAttributes.messageDigest))
+ {
+ byte[] messageDigest = (byte[])parameters.get(
+ CMSAttributeTableGenerator.DIGEST);
+ Attribute attr = new Attribute(CMSAttributes.messageDigest,
+ new DERSet(new DEROctetString(messageDigest)));
+ std.put(attr.getAttrType(), attr);
+ }
+
+ if (!std.contains(CMSAttributes.cmsAlgorithmProtect))
+ {
+ Attribute attr = new Attribute(CMSAttributes.cmsAlgorithmProtect, new DERSet(new CMSAlgorithmProtection(
+ (AlgorithmIdentifier)parameters.get(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER),
+ CMSAlgorithmProtection.SIGNATURE, (AlgorithmIdentifier)parameters.get(CMSAttributeTableGenerator.SIGNATURE_ALGORITHM_IDENTIFIER))));
+ std.put(attr.getAttrType(), attr);
+ }
+
+ return std;
+ }
+
+ /**
+ * @param parameters source parameters
+ * @return the populated attribute table
+ */
+ public AttributeTable getAttributes(Map parameters)
+ {
+ return new AttributeTable(createStandardAttributeTable(parameters));
+ }
+
+ private static Hashtable copyHashTable(Hashtable paramsMap)
+ {
+ Hashtable newTable = new Hashtable();
+
+ Enumeration keys = paramsMap.keys();
+ while (keys.hasMoreElements())
+ {
+ Object key = keys.nextElement();
+ newTable.put(key, paramsMap.get(key));
+ }
+
+ return newTable;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/NullOutputStream.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/NullOutputStream.java
new file mode 100644
index 00000000..f434fd7c
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/NullOutputStream.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/**
+ *
+ */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+class NullOutputStream
+ extends OutputStream
+{
+ public void write(byte[] buf)
+ throws IOException
+ {
+ // do nothing
+ }
+
+ public void write(byte[] buf, int off, int len)
+ throws IOException
+ {
+ // do nothing
+ }
+
+ public void write(int b) throws IOException
+ {
+ // do nothing
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PKCS7ProcessableObject.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PKCS7ProcessableObject.java
new file mode 100644
index 00000000..d836a68e
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PKCS7ProcessableObject.java
@@ -0,0 +1,69 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS7ProcessableObject
+ implements CMSTypedData
+{
+ private final ASN1ObjectIdentifier type;
+ private final ASN1Encodable structure;
+
+ public PKCS7ProcessableObject(
+ ASN1ObjectIdentifier type,
+ ASN1Encodable structure)
+ {
+ this.type = type;
+ this.structure = structure;
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return type;
+ }
+
+ public void write(OutputStream cOut)
+ throws IOException, CMSException
+ {
+ if (structure instanceof ASN1Sequence)
+ {
+ ASN1Sequence s = ASN1Sequence.getInstance(structure);
+
+ for (Iterator it = s.iterator(); it.hasNext();)
+ {
+ ASN1Encodable enc = (ASN1Encodable)it.next();
+
+ cOut.write(enc.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+ }
+ }
+ else
+ {
+ byte[] encoded = structure.toASN1Primitive().getEncoded(ASN1Encoding.DER);
+ int index = 1;
+
+ while ((encoded[index] & 0xff) > 127)
+ {
+ index++;
+ }
+
+ index++;
+
+ cOut.write(encoded, index, encoded.length - index);
+ }
+ }
+
+ public Object getContent()
+ {
+ return structure;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PasswordRecipient.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PasswordRecipient.java
new file mode 100644
index 00000000..106dc9fe
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PasswordRecipient.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PasswordRecipient
+ extends Recipient
+{
+ public static final int PKCS5_SCHEME2 = 0;
+ public static final int PKCS5_SCHEME2_UTF8 = 1;
+
+ static final class PRF
+ {
+ public static final PRF HMacSHA1 = new PRF("HMacSHA1", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA1, DERNull.INSTANCE));
+ public static final PRF HMacSHA224 = new PRF("HMacSHA224", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA224, DERNull.INSTANCE));
+ public static final PRF HMacSHA256 = new PRF("HMacSHA256", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA256, DERNull.INSTANCE));
+ public static final PRF HMacSHA384 = new PRF("HMacSHA384", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA384, DERNull.INSTANCE));
+ public static final PRF HMacSHA512 = new PRF("HMacSHA512", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA512, DERNull.INSTANCE));
+
+ private final String hmac;
+ final AlgorithmIdentifier prfAlgID;
+
+ private PRF(String hmac, AlgorithmIdentifier prfAlgID)
+ {
+ this.hmac = hmac;
+ this.prfAlgID = prfAlgID;
+ }
+
+ public String getName()
+ {
+ return hmac;
+ }
+
+ public AlgorithmIdentifier getAlgorithmID()
+ {
+ return prfAlgID;
+ }
+ }
+
+ byte[] calculateDerivedKey(int schemeID, AlgorithmIdentifier derivationAlgorithm, int keySize)
+ throws CMSException;
+
+ RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] derivedKey, byte[] encryptedEncryptedContentKey)
+ throws CMSException;
+
+ int getPasswordConversionScheme();
+
+ char[] getPassword();
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/Recipient.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/Recipient.java
new file mode 100644
index 00000000..2b5ab03b
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/Recipient.java
@@ -0,0 +1,9 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Recipient
+{
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/RecipientOperator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/RecipientOperator.java
new file mode 100644
index 00000000..6b3dff40
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/RecipientOperator.java
@@ -0,0 +1,64 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+// import org.bouncycastle.operator.InputAEADDecryptor;
+import com.android.internal.org.bouncycastle.operator.InputDecryptor;
+import com.android.internal.org.bouncycastle.operator.MacCalculator;
+import com.android.internal.org.bouncycastle.util.io.TeeInputStream;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RecipientOperator
+{
+ private final Object operator;
+
+ public RecipientOperator(InputDecryptor decryptor)
+ {
+ this.operator = decryptor;
+ }
+
+ public RecipientOperator(MacCalculator macCalculator)
+ {
+ this.operator = macCalculator;
+ }
+
+ public InputStream getInputStream(InputStream dataIn)
+ {
+ if (operator instanceof InputDecryptor)
+ {
+ return ((InputDecryptor)operator).getInputStream(dataIn);
+ }
+ else
+ {
+ return new TeeInputStream(dataIn, ((MacCalculator)operator).getOutputStream());
+ }
+ }
+
+ // BEGIN Android-removed
+ /*
+ public boolean isAEADBased()
+ {
+ return operator instanceof InputAEADDecryptor;
+ }
+
+ public OutputStream getAADStream()
+ {
+ return ((InputAEADDecryptor)operator).getAADStream();
+ }
+ */
+ // END Android-removed
+
+ public boolean isMacBased()
+ {
+ return operator instanceof MacCalculator;
+ }
+
+ public byte[] getMac()
+ {
+ return ((MacCalculator)operator).getMac();
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerId.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerId.java
new file mode 100644
index 00000000..f68e12c7
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerId.java
@@ -0,0 +1,106 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.cert.selector.X509CertificateHolderSelector;
+import com.android.internal.org.bouncycastle.util.Selector;
+
+/**
+ * a basic index for a signer.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignerId
+ implements Selector
+{
+ private X509CertificateHolderSelector baseSelector;
+
+ private SignerId(X509CertificateHolderSelector baseSelector)
+ {
+ this.baseSelector = baseSelector;
+ }
+
+ /**
+ * Construct a signer ID with the value of a public key's subjectKeyId.
+ *
+ * @param subjectKeyId a subjectKeyId
+ */
+ public SignerId(byte[] subjectKeyId)
+ {
+ this(null, null, subjectKeyId);
+ }
+
+ /**
+ * Construct a signer ID based on the issuer and serial number of the signer's associated
+ * certificate.
+ *
+ * @param issuer the issuer of the signer's associated certificate.
+ * @param serialNumber the serial number of the signer's associated certificate.
+ */
+ public SignerId(X500Name issuer, BigInteger serialNumber)
+ {
+ this(issuer, serialNumber, null);
+ }
+
+ /**
+ * Construct a signer ID based on the issuer and serial number of the signer's associated
+ * certificate.
+ *
+ * @param issuer the issuer of the signer's associated certificate.
+ * @param serialNumber the serial number of the signer's associated certificate.
+ * @param subjectKeyId the subject key identifier to use to match the signers associated certificate.
+ */
+ public SignerId(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyId)
+ {
+ this(new X509CertificateHolderSelector(issuer, serialNumber, subjectKeyId));
+ }
+
+ public X500Name getIssuer()
+ {
+ return baseSelector.getIssuer();
+ }
+
+ public BigInteger getSerialNumber()
+ {
+ return baseSelector.getSerialNumber();
+ }
+
+ public byte[] getSubjectKeyIdentifier()
+ {
+ return baseSelector.getSubjectKeyIdentifier();
+ }
+
+ public int hashCode()
+ {
+ return baseSelector.hashCode();
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof SignerId))
+ {
+ return false;
+ }
+
+ SignerId id = (SignerId)o;
+
+ return this.baseSelector.equals(id.baseSelector);
+ }
+
+ public boolean match(Object obj)
+ {
+ if (obj instanceof SignerInformation)
+ {
+ return ((SignerInformation)obj).getSID().equals(this);
+ }
+
+ return baseSelector.match(obj);
+ }
+
+ public Object clone()
+ {
+ return new SignerId(this.baseSelector);
+ }
+}
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
new file mode 100644
index 00000000..b6d006a5
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGenerator.java
@@ -0,0 +1,312 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+import com.android.internal.org.bouncycastle.asn1.cms.AttributeTable;
+import com.android.internal.org.bouncycastle.asn1.cms.SignerIdentifier;
+import com.android.internal.org.bouncycastle.asn1.cms.SignerInfo;
+// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+// import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+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;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignerInfoGenerator
+{
+ private final SignerIdentifier signerIdentifier;
+ private final CMSAttributeTableGenerator sAttrGen;
+ private final CMSAttributeTableGenerator unsAttrGen;
+ private final ContentSigner signer;
+ private final DigestCalculator digester;
+ private final DigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+ private final CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder;
+
+ private byte[] calculatedDigest = null;
+ private X509CertificateHolder certHolder;
+
+ SignerInfoGenerator(
+ SignerIdentifier signerIdentifier,
+ ContentSigner signer,
+ DigestCalculatorProvider digesterProvider,
+ CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder)
+ throws OperatorCreationException
+ {
+ this(signerIdentifier, signer, digesterProvider, sigEncAlgFinder, false);
+ }
+
+ SignerInfoGenerator(
+ SignerIdentifier signerIdentifier,
+ ContentSigner signer,
+ DigestCalculatorProvider digesterProvider,
+ CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder,
+ boolean isDirectSignature)
+ throws OperatorCreationException
+ {
+ 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.sigEncAlgFinder = sigEncAlgFinder;
+ }
+
+ public SignerInfoGenerator(
+ SignerInfoGenerator original,
+ CMSAttributeTableGenerator sAttrGen,
+ CMSAttributeTableGenerator unsAttrGen)
+ {
+ this.signerIdentifier = original.signerIdentifier;
+ this.signer = original.signer;
+ 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;
+ }
+
+ public int getGeneratedVersion()
+ {
+ return signerIdentifier.isTagged() ? 3 : 1;
+ }
+
+ public boolean hasAssociatedCertificate()
+ {
+ return certHolder != null;
+ }
+
+ public X509CertificateHolder getAssociatedCertificate()
+ {
+ return certHolder;
+ }
+
+ public AlgorithmIdentifier getDigestAlgorithm()
+ {
+ if (digester != null)
+ {
+ return digester.getAlgorithmIdentifier();
+ }
+
+ return digAlgFinder.find(signer.getAlgorithmIdentifier());
+ }
+
+ public OutputStream getCalculatingOutputStream()
+ {
+ if (digester != null)
+ {
+ if (sAttrGen == null)
+ {
+ return new TeeOutputStream(digester.getOutputStream(), signer.getOutputStream());
+ }
+ return digester.getOutputStream();
+ }
+ else
+ {
+ return signer.getOutputStream();
+ }
+ }
+
+ public SignerInfo generate(ASN1ObjectIdentifier contentType)
+ throws CMSException
+ {
+ try
+ {
+ /* RFC 3852 5.4
+ * The result of the message digest calculation process depends on
+ * whether the signedAttrs field is present. When the field is absent,
+ * the result is just the message digest of the content as described
+ *
+ * above. When the field is present, however, the result is the message
+ * digest of the complete DER encoding of the SignedAttrs value
+ * contained in the signedAttrs field.
+ */
+ ASN1Set signedAttr = null;
+
+ AlgorithmIdentifier digestEncryptionAlgorithm = sigEncAlgFinder.findEncryptionAlgorithm(signer.getAlgorithmIdentifier());
+
+ AlgorithmIdentifier digestAlg = null;
+
+ if (sAttrGen != null)
+ {
+ digestAlg = digester.getAlgorithmIdentifier();
+ calculatedDigest = digester.getDigest();
+ Map parameters = getBaseParameters(contentType, digester.getAlgorithmIdentifier(), digestEncryptionAlgorithm, calculatedDigest);
+ AttributeTable signed = sAttrGen.getAttributes(Collections.unmodifiableMap(parameters));
+
+ signedAttr = getAttributeSet(signed);
+
+ // sig must be composed from the DER encoding.
+ OutputStream sOut = signer.getOutputStream();
+
+ sOut.write(signedAttr.getEncoded(ASN1Encoding.DER));
+
+ sOut.close();
+ }
+ else
+ {
+ if (digester != null)
+ {
+ digestAlg = digester.getAlgorithmIdentifier();
+ calculatedDigest = digester.getDigest();
+ }
+ else
+ {
+ digestAlg = digAlgFinder.find(signer.getAlgorithmIdentifier());
+ calculatedDigest = null;
+ }
+ }
+
+ byte[] sigBytes = signer.getSignature();
+
+ ASN1Set unsignedAttr = null;
+ if (unsAttrGen != null)
+ {
+ Map parameters = getBaseParameters(contentType, digestAlg, digestEncryptionAlgorithm, calculatedDigest);
+ parameters.put(CMSAttributeTableGenerator.SIGNATURE, Arrays.clone(sigBytes));
+
+ AttributeTable unsigned = unsAttrGen.getAttributes(Collections.unmodifiableMap(parameters));
+
+ unsignedAttr = getAttributeSet(unsigned);
+ }
+
+ if (sAttrGen == null)
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ // RFC 8419, Section 3.2 - needs to be shake-256, not shake-256-len
+ if (EdECObjectIdentifiers.id_Ed448.equals(digestEncryptionAlgorithm.getAlgorithm()))
+ {
+ digestAlg = new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256);
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+
+ return new SignerInfo(signerIdentifier, digestAlg,
+ signedAttr, digestEncryptionAlgorithm, new DEROctetString(sigBytes), unsignedAttr);
+ }
+ catch (IOException e)
+ {
+ throw new CMSException("encoding error.", e);
+ }
+ }
+
+ void setAssociatedCertificate(X509CertificateHolder certHolder)
+ {
+ this.certHolder = certHolder;
+ }
+
+ private ASN1Set getAttributeSet(
+ AttributeTable attr)
+ {
+ if (attr != null)
+ {
+ return new DERSet(attr.toASN1EncodableVector());
+ }
+
+ return null;
+ }
+
+ private Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, AlgorithmIdentifier sigAlgId, byte[] hash)
+ {
+ Map param = new HashMap();
+
+ if (contentType != null)
+ {
+ param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType);
+ }
+
+ param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId);
+ param.put(CMSAttributeTableGenerator.SIGNATURE_ALGORITHM_IDENTIFIER, sigAlgId);
+ param.put(CMSAttributeTableGenerator.DIGEST, Arrays.clone(hash));
+
+ return param;
+ }
+
+ public byte[] getCalculatedDigest()
+ {
+ if (calculatedDigest != null)
+ {
+ return Arrays.clone(calculatedDigest);
+ }
+
+ return null;
+ }
+
+ public CMSAttributeTableGenerator getSignedAttributeTableGenerator()
+ {
+ return sAttrGen;
+ }
+
+ public CMSAttributeTableGenerator getUnsignedAttributeTableGenerator()
+ {
+ return unsAttrGen;
+ }
+}
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
new file mode 100644
index 00000000..e6aea68b
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
@@ -0,0 +1,142 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+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.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.operator.ContentSigner;
+import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider;
+import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
+
+/**
+ * Builder for SignerInfo generator objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignerInfoGeneratorBuilder
+{
+ private DigestCalculatorProvider digestProvider;
+ private boolean directSignature;
+ private CMSAttributeTableGenerator signedGen;
+ private CMSAttributeTableGenerator unsignedGen;
+ private CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder;
+
+ /**
+ * Base constructor.
+ *
+ * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations.
+ */
+ public SignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider)
+ {
+ this(digestProvider, new DefaultCMSSignatureEncryptionAlgorithmFinder());
+ }
+
+ /**
+ * Base constructor with a particular finder for signature algorithms.
+ *
+ * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations.
+ * @param sigEncAlgFinder finder for algorithm IDs to store for the signature encryption/signature algorithm field.
+ */
+ public SignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder)
+ {
+ this.digestProvider = digestProvider;
+ this.sigEncAlgFinder = sigEncAlgFinder;
+ }
+
+ /**
+ * If the passed in flag is true, the signer signature will be based on the data, not
+ * a collection of signed attributes, and no signed attributes will be included.
+ *
+ * @return the builder object
+ */
+ public SignerInfoGeneratorBuilder setDirectSignature(boolean hasNoSignedAttributes)
+ {
+ this.directSignature = hasNoSignedAttributes;
+
+ return this;
+ }
+
+ /**
+ * Provide a custom signed attribute generator.
+ *
+ * @param signedGen a generator of signed attributes.
+ * @return the builder object
+ */
+ public SignerInfoGeneratorBuilder setSignedAttributeGenerator(CMSAttributeTableGenerator signedGen)
+ {
+ this.signedGen = signedGen;
+
+ return this;
+ }
+
+ /**
+ * Provide a generator of unsigned attributes.
+ *
+ * @param unsignedGen a generator for signed attributes.
+ * @return the builder object
+ */
+ public SignerInfoGeneratorBuilder setUnsignedAttributeGenerator(CMSAttributeTableGenerator unsignedGen)
+ {
+ this.unsignedGen = unsignedGen;
+
+ return this;
+ }
+
+ /**
+ * Build a generator with the passed in certHolder issuer and serial number as the signerIdentifier.
+ *
+ * @param contentSigner operator for generating the final signature in the SignerInfo with.
+ * @param certHolder carrier for the X.509 certificate related to the contentSigner.
+ * @return a SignerInfoGenerator
+ * @throws OperatorCreationException if the generator cannot be built.
+ */
+ public SignerInfoGenerator build(ContentSigner contentSigner, X509CertificateHolder certHolder)
+ throws OperatorCreationException
+ {
+ SignerIdentifier sigId = new SignerIdentifier(new IssuerAndSerialNumber(certHolder.toASN1Structure()));
+
+ SignerInfoGenerator sigInfoGen = createGenerator(contentSigner, sigId);
+
+ sigInfoGen.setAssociatedCertificate(certHolder);
+
+ return sigInfoGen;
+ }
+
+ /**
+ * Build a generator with the passed in subjectKeyIdentifier as the signerIdentifier. If used you should
+ * try to follow the calculation described in RFC 5280 section 4.2.1.2.
+ *
+ * @param contentSigner operator for generating the final signature in the SignerInfo with.
+ * @param subjectKeyIdentifier key identifier to identify the public key for verifying the signature.
+ * @return a SignerInfoGenerator
+ * @throws OperatorCreationException if the generator cannot be built.
+ */
+ public SignerInfoGenerator build(ContentSigner contentSigner, byte[] subjectKeyIdentifier)
+ throws OperatorCreationException
+ {
+ SignerIdentifier sigId = new SignerIdentifier(new DEROctetString(subjectKeyIdentifier));
+
+ return createGenerator(contentSigner, sigId);
+ }
+
+ private SignerInfoGenerator createGenerator(ContentSigner contentSigner, SignerIdentifier sigId)
+ throws OperatorCreationException
+ {
+ if (directSignature)
+ {
+ return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, true);
+ }
+
+ if (signedGen != null || unsignedGen != null)
+ {
+ if (signedGen == null)
+ {
+ signedGen = new DefaultSignedAttributeTableGenerator();
+ }
+
+ return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, signedGen, unsignedGen);
+ }
+
+ return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder);
+ }
+}
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
new file mode 100644
index 00000000..1f70626b
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformation.java
@@ -0,0 +1,760 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+
+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.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+import com.android.internal.org.bouncycastle.asn1.cms.Attribute;
+import com.android.internal.org.bouncycastle.asn1.cms.AttributeTable;
+import com.android.internal.org.bouncycastle.asn1.cms.CMSAlgorithmProtection;
+import com.android.internal.org.bouncycastle.asn1.cms.CMSAttributes;
+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.cms.SignerInfo;
+import com.android.internal.org.bouncycastle.asn1.cms.Time;
+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;
+import com.android.internal.org.bouncycastle.operator.ContentVerifier;
+import com.android.internal.org.bouncycastle.operator.DigestCalculator;
+import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
+import com.android.internal.org.bouncycastle.operator.RawContentVerifier;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.io.TeeOutputStream;
+
+/**
+ * an expanded SignerInfo block from a CMS Signed message
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignerInformation
+{
+ 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;
+
+ protected final SignerInfo info;
+ protected final AlgorithmIdentifier digestAlgorithm;
+ protected final AlgorithmIdentifier encryptionAlgorithm;
+ protected final ASN1Set signedAttributeSet;
+ protected final ASN1Set unsignedAttributeSet;
+
+ SignerInformation(
+ SignerInfo info,
+ ASN1ObjectIdentifier contentType,
+ CMSProcessable content,
+ byte[] resultDigest)
+ {
+ this.info = info;
+ this.contentType = contentType;
+ this.isCounterSignature = contentType == null;
+
+ SignerIdentifier s = info.getSID();
+
+ if (s.isTagged())
+ {
+ ASN1OctetString octs = ASN1OctetString.getInstance(s.getId());
+
+ sid = new SignerId(octs.getOctets());
+ }
+ else
+ {
+ IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.getInstance(s.getId());
+
+ sid = new SignerId(iAnds.getName(), iAnds.getSerialNumber().getValue());
+ }
+
+ this.digestAlgorithm = info.getDigestAlgorithm();
+ this.signedAttributeSet = info.getAuthenticatedAttributes();
+ this.unsignedAttributeSet = info.getUnauthenticatedAttributes();
+ this.encryptionAlgorithm = info.getDigestEncryptionAlgorithm();
+ this.signature = info.getEncryptedDigest().getOctets();
+
+ this.content = content;
+ this.resultDigest = resultDigest;
+ }
+
+ /**
+ * Protected constructor. In some cases clients have their own idea about how to encode
+ * the signed attributes and calculate the signature. This constructor is to allow developers
+ * to deal with that by extending off the class and overriding methods like getSignedAttributes().
+ *
+ * @param baseInfo the SignerInformation to base this one on.
+ */
+ protected SignerInformation(SignerInformation baseInfo)
+ {
+ this(baseInfo, baseInfo.info);
+ }
+
+ /**
+ * Protected constructor. In some cases clients also have their own ideas about what
+ * goes in various SignerInfo fields. This constructor is to allow developers to deal with
+ * 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.
+ */
+ protected SignerInformation(SignerInformation baseInfo, SignerInfo info)
+ {
+ this.info = info;
+ this.contentType = baseInfo.contentType;
+ this.isCounterSignature = baseInfo.isCounterSignature();
+ this.sid = baseInfo.getSID();
+ this.digestAlgorithm = info.getDigestAlgorithm();
+ this.signedAttributeSet = info.getAuthenticatedAttributes();
+ this.unsignedAttributeSet = info.getUnauthenticatedAttributes();
+ this.encryptionAlgorithm = info.getDigestEncryptionAlgorithm();
+ this.signature = info.getEncryptedDigest().getOctets();
+ this.content = baseInfo.content;
+ this.resultDigest = baseInfo.resultDigest;
+ this.signedAttributeValues = baseInfo.signedAttributeValues;
+ this.unsignedAttributeValues = baseInfo.unsignedAttributeValues;
+ }
+
+ public boolean isCounterSignature()
+ {
+ return isCounterSignature;
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return this.contentType;
+ }
+
+ private byte[] encodeObj(
+ ASN1Encodable obj)
+ throws IOException
+ {
+ if (obj != null)
+ {
+ return obj.toASN1Primitive().getEncoded();
+ }
+
+ return null;
+ }
+
+ public SignerId getSID()
+ {
+ return sid;
+ }
+
+ /**
+ * return the version number for this objects underlying SignerInfo structure.
+ */
+ public int getVersion()
+ {
+ return info.getVersion().intValueExact();
+ }
+
+ public AlgorithmIdentifier getDigestAlgorithmID()
+ {
+ return digestAlgorithm;
+ }
+
+ /**
+ * return the object identifier for the signature.
+ */
+ public String getDigestAlgOID()
+ {
+ return digestAlgorithm.getAlgorithm().getId();
+ }
+
+ /**
+ * return the signature parameters, or null if there aren't any.
+ */
+ public byte[] getDigestAlgParams()
+ {
+ try
+ {
+ return encodeObj(digestAlgorithm.getParameters());
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("exception getting digest parameters " + e);
+ }
+ }
+
+ /**
+ * return the content digest that was calculated during verification.
+ */
+ public byte[] getContentDigest()
+ {
+ if (resultDigest == null)
+ {
+ throw new IllegalStateException("method can only be called after verify.");
+ }
+
+ return Arrays.clone(resultDigest);
+ }
+
+ /**
+ * return the object identifier for the signature.
+ */
+ public String getEncryptionAlgOID()
+ {
+ return encryptionAlgorithm.getAlgorithm().getId();
+ }
+
+ /**
+ * return the signature/encryption algorithm parameters, or null if
+ * there aren't any.
+ */
+ public byte[] getEncryptionAlgParams()
+ {
+ try
+ {
+ return encodeObj(encryptionAlgorithm.getParameters());
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("exception getting encryption parameters " + e);
+ }
+ }
+
+ /**
+ * return a table of the signed attributes - indexed by
+ * the OID of the attribute.
+ */
+ public AttributeTable getSignedAttributes()
+ {
+ if (signedAttributeSet != null && signedAttributeValues == null)
+ {
+ signedAttributeValues = new AttributeTable(signedAttributeSet);
+ }
+
+ return signedAttributeValues;
+ }
+
+ /**
+ * return a table of the unsigned attributes indexed by
+ * the OID of the attribute.
+ */
+ public AttributeTable getUnsignedAttributes()
+ {
+ if (unsignedAttributeSet != null && unsignedAttributeValues == null)
+ {
+ unsignedAttributeValues = new AttributeTable(unsignedAttributeSet);
+ }
+
+ return unsignedAttributeValues;
+ }
+
+ /**
+ * return the encoded signature
+ */
+ public byte[] getSignature()
+ {
+ return Arrays.clone(signature);
+ }
+
+ /**
+ * Return a SignerInformationStore containing the counter signatures attached to this
+ * signer. If no counter signatures are present an empty store is returned.
+ */
+ public SignerInformationStore getCounterSignatures()
+ {
+ // TODO There are several checks implied by the RFC3852 comments that are missing
+
+ /*
+ 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)
+ {
+ return new SignerInformationStore(new ArrayList(0));
+ }
+
+ List counterSignatures = new ArrayList();
+
+ /*
+ The UnsignedAttributes syntax is defined as a SET OF Attributes. The
+ UnsignedAttributes in a signerInfo may include multiple instances of
+ the countersignature attribute.
+ */
+ ASN1EncodableVector allCSAttrs = unsignedAttributeTable.getAll(CMSAttributes.counterSignature);
+
+ for (int i = 0; i < allCSAttrs.size(); ++i)
+ {
+ Attribute counterSignatureAttribute = (Attribute)allCSAttrs.get(i);
+
+ /*
+ A countersignature attribute can have multiple attribute values. The
+ syntax is defined as a SET OF AttributeValue, and there MUST be one
+ or more instances of AttributeValue present.
+ */
+ ASN1Set values = counterSignatureAttribute.getAttrValues();
+ if (values.size() < 1)
+ {
+ // TODO Throw an appropriate exception?
+ }
+
+ for (Enumeration en = values.getObjects(); en.hasMoreElements();)
+ {
+ /*
+ Countersignature values have the same meaning as SignerInfo values
+ for ordinary signatures, except that:
+
+ 1. The signedAttributes field MUST NOT contain a content-type
+ attribute; there is no content type for countersignatures.
+
+ 2. The signedAttributes field MUST contain a message-digest
+ attribute if it contains any other attributes.
+
+ 3. The input to the message-digesting process is the contents
+ octets of the DER encoding of the signatureValue field of the
+ SignerInfo value with which the attribute is associated.
+ */
+ SignerInfo si = SignerInfo.getInstance(en.nextElement());
+
+ counterSignatures.add(new SignerInformation(si, null, new CMSProcessableByteArray(getSignature()), null));
+ }
+ }
+
+ return new SignerInformationStore(counterSignatures);
+ }
+
+ /**
+ * return the DER encoding of the signed attributes.
+ * @throws IOException if an encoding error occurs.
+ */
+ public byte[] getEncodedSignedAttributes()
+ throws IOException
+ {
+ if (signedAttributeSet != null)
+ {
+ return signedAttributeSet.getEncoded(ASN1Encoding.DER);
+ }
+
+ return null;
+ }
+
+ private boolean doVerify(
+ SignerInformationVerifier verifier)
+ throws CMSException
+ {
+ String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID());
+ ContentVerifier contentVerifier;
+
+ try
+ {
+ contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, info.getDigestAlgorithm());
+ }
+ catch (OperatorCreationException e)
+ {
+ throw new CMSException("can't create content verifier: " + e.getMessage(), e);
+ }
+
+ try
+ {
+ OutputStream sigOut = contentVerifier.getOutputStream();
+
+ if (resultDigest == null)
+ {
+ DigestCalculator calc = verifier.getDigestCalculator(this.getDigestAlgorithmID());
+ if (content != null)
+ {
+ OutputStream digOut = calc.getOutputStream();
+
+ if (signedAttributeSet == null)
+ {
+ if (contentVerifier instanceof RawContentVerifier)
+ {
+ content.write(digOut);
+ }
+ else
+ {
+ OutputStream cOut = new TeeOutputStream(digOut, sigOut);
+
+ content.write(cOut);
+
+ cOut.close();
+ }
+ }
+ else
+ {
+ content.write(digOut);
+ sigOut.write(this.getEncodedSignedAttributes());
+ }
+
+ digOut.close();
+ }
+ else if (signedAttributeSet != null)
+ {
+ sigOut.write(this.getEncodedSignedAttributes());
+ }
+ else
+ {
+ // TODO Get rid of this exception and just treat content==null as empty not missing?
+ throw new CMSException("data not encapsulated in signature - use detached constructor.");
+ }
+
+ resultDigest = calc.getDigest();
+ }
+ else
+ {
+ if (signedAttributeSet == null)
+ {
+ if (content != null)
+ {
+ content.write(sigOut);
+ }
+ }
+ else
+ {
+ sigOut.write(this.getEncodedSignedAttributes());
+ }
+ }
+
+ sigOut.close();
+ }
+ catch (IOException e)
+ {
+ throw new CMSException("can't process mime object to create signature.", e);
+ }
+ catch (OperatorCreationException e)
+ {
+ throw new CMSException("can't create digest calculator: " + e.getMessage(), e);
+ }
+
+ // 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");
+ }
+ }
+ }
+
+ 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");
+ }
+ }
+ }
+ }
+
+ // 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");
+ }
+ }
+ }
+
+ // 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
+ }
+ }
+ }
+
+ try
+ {
+ if (signedAttributeSet == null && resultDigest != null)
+ {
+ if (contentVerifier instanceof RawContentVerifier)
+ {
+ RawContentVerifier rawVerifier = (RawContentVerifier)contentVerifier;
+
+ if (encName.equals("RSA"))
+ {
+ DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest);
+
+ return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature());
+ }
+
+ return rawVerifier.verify(resultDigest, this.getSignature());
+ }
+ }
+
+ return contentVerifier.verify(this.getSignature());
+ }
+ catch (IOException e)
+ {
+ throw new CMSException("can't process mime object to create signature.", e);
+ }
+ }
+
+ /**
+ * Verify that the given verifier can successfully verify the signature on
+ * this SignerInformation object.
+ *
+ * @param verifier a suitably configured SignerInformationVerifier.
+ * @return true if the signer information is verified, false otherwise.
+ * @throws com.android.internal.org.bouncycastle.cms.CMSVerifierCertificateNotValidException if the provider has an associated certificate and the certificate is not valid at the time given as the SignerInfo's signing time.
+ * @throws com.android.internal.org.bouncycastle.cms.CMSException if the verifier is unable to create a ContentVerifiers or DigestCalculators.
+ */
+ public boolean verify(SignerInformationVerifier verifier)
+ throws CMSException
+ {
+ Time signingTime = getSigningTime(); // has to be validated if present.
+
+ if (verifier.hasAssociatedCertificate())
+ {
+ if (signingTime != null)
+ {
+ X509CertificateHolder dcv = verifier.getAssociatedCertificate();
+
+ if (!dcv.isValidOn(signingTime.getDate()))
+ {
+ throw new CMSVerifierCertificateNotValidException("verifier not valid at signingTime");
+ }
+ }
+ }
+
+ return doVerify(verifier);
+ }
+
+ /**
+ * Return the underlying ASN.1 object defining this SignerInformation object.
+ *
+ * @return a SignerInfo.
+ */
+ public SignerInfo toASN1Structure()
+ {
+ return info;
+ }
+
+ private ASN1Primitive getSingleValuedSignedAttribute(
+ ASN1ObjectIdentifier attrOID, String printableName)
+ throws CMSException
+ {
+ AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
+ if (unsignedAttrTable != null
+ && unsignedAttrTable.getAll(attrOID).size() > 0)
+ {
+ throw new CMSException("The " + printableName
+ + " attribute MUST NOT be an unsigned attribute");
+ }
+
+ AttributeTable signedAttrTable = this.getSignedAttributes();
+ if (signedAttrTable == null)
+ {
+ return null;
+ }
+
+ ASN1EncodableVector v = signedAttrTable.getAll(attrOID);
+ switch (v.size())
+ {
+ case 0:
+ return null;
+ case 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();
+ }
+ default:
+ throw new CMSException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the "
+ + printableName + " attribute");
+ }
+ }
+
+ private Time getSigningTime() throws CMSException
+ {
+ ASN1Primitive validSigningTime = getSingleValuedSignedAttribute(
+ CMSAttributes.signingTime, "signing-time");
+
+ if (validSigningTime == null)
+ {
+ return null;
+ }
+
+ try
+ {
+ return Time.getInstance(validSigningTime);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new CMSException("signing-time attribute value not a valid 'Time' structure");
+ }
+ }
+
+ /**
+ * 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 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)
+ {
+ 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);
+ }
+
+ /**
+ * Return a signer information object with passed in SignerInformationStore representing counter
+ * signatures attached as an unsigned attribute.
+ *
+ * @param signerInformation the signerInfo to be used as the basis.
+ * @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)
+ {
+ // TODO Perform checks from RFC 3852 11.4
+
+ SignerInfo sInfo = signerInformation.info;
+ AttributeTable unsignedAttr = signerInformation.getUnsignedAttributes();
+ ASN1EncodableVector v;
+
+ if (unsignedAttr != null)
+ {
+ v = unsignedAttr.toASN1EncodableVector();
+ }
+ else
+ {
+ v = new ASN1EncodableVector();
+ }
+
+ ASN1EncodableVector sigs = new ASN1EncodableVector();
+
+ for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext();)
+ {
+ sigs.add(((SignerInformation)it.next()).toASN1Structure());
+ }
+
+ 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);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationStore.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationStore.java
new file mode 100644
index 00000000..0f08e37e
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationStore.java
@@ -0,0 +1,145 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.util.Iterable;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignerInformationStore
+ implements Iterable<SignerInformation>
+{
+ private List all = new ArrayList();
+ private Map table = new HashMap();
+
+ /**
+ * Create a store containing a single SignerInformation object.
+ *
+ * @param signerInfo the signer information to contain.
+ */
+ public SignerInformationStore(
+ SignerInformation signerInfo)
+ {
+ this.all = new ArrayList(1);
+ this.all.add(signerInfo);
+
+ SignerId sid = signerInfo.getSID();
+
+ table.put(sid, all);
+ }
+
+ /**
+ * Create a store containing a collection of SignerInformation objects.
+ *
+ * @param signerInfos a collection signer information objects to contain.
+ */
+ public SignerInformationStore(
+ Collection<SignerInformation> signerInfos)
+ {
+ Iterator it = signerInfos.iterator();
+
+ while (it.hasNext())
+ {
+ SignerInformation signer = (SignerInformation)it.next();
+ SignerId sid = signer.getSID();
+
+ List list = (ArrayList)table.get(sid);
+ if (list == null)
+ {
+ list = new ArrayList(1);
+ table.put(sid, list);
+ }
+
+ list.add(signer);
+ }
+
+ this.all = new ArrayList(signerInfos);
+ }
+
+ /**
+ * Return the first SignerInformation object that matches the
+ * passed in selector. Null if there are no matches.
+ *
+ * @param selector to identify a signer
+ * @return a single SignerInformation object. Null if none matches.
+ */
+ public SignerInformation get(
+ SignerId selector)
+ {
+ Collection list = getSigners(selector);
+
+ return list.size() == 0 ? null : (SignerInformation) list.iterator().next();
+ }
+
+ /**
+ * Return the number of signers in the collection.
+ *
+ * @return number of signers identified.
+ */
+ public int size()
+ {
+ return all.size();
+ }
+
+ /**
+ * Return all signers in the collection
+ *
+ * @return a collection of signers.
+ */
+ public Collection<SignerInformation> getSigners()
+ {
+ return new ArrayList(all);
+ }
+
+ /**
+ * Return possible empty collection with signers matching the passed in SignerId
+ *
+ * @param selector a signer id to select against.
+ * @return a collection of SignerInformation objects.
+ */
+ public Collection<SignerInformation> getSigners(
+ SignerId selector)
+ {
+ if (selector.getIssuer() != null && selector.getSubjectKeyIdentifier() != null)
+ {
+ List results = new ArrayList();
+
+ Collection match1 = getSigners(new SignerId(selector.getIssuer(), selector.getSerialNumber()));
+
+ if (match1 != null)
+ {
+ results.addAll(match1);
+ }
+
+ Collection match2 = getSigners(new SignerId(selector.getSubjectKeyIdentifier()));
+
+ if (match2 != null)
+ {
+ results.addAll(match2);
+ }
+
+ return results;
+ }
+ else
+ {
+ List list = (ArrayList)table.get(selector);
+
+ return list == null ? new ArrayList() : new ArrayList(list);
+ }
+ }
+
+ /**
+ * Support method for Iterable where available.
+ */
+ public Iterator<SignerInformation> iterator()
+ {
+ return getSigners().iterator();
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationVerifier.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationVerifier.java
new file mode 100644
index 00000000..d73b2bbc
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationVerifier.java
@@ -0,0 +1,55 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+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.operator.DigestCalculator;
+import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider;
+import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
+import com.android.internal.org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignerInformationVerifier
+{
+ private ContentVerifierProvider verifierProvider;
+ private DigestCalculatorProvider digestProvider;
+ private SignatureAlgorithmIdentifierFinder sigAlgorithmFinder;
+ private CMSSignatureAlgorithmNameGenerator sigNameGenerator;
+
+ public SignerInformationVerifier(CMSSignatureAlgorithmNameGenerator sigNameGenerator, SignatureAlgorithmIdentifierFinder sigAlgorithmFinder, ContentVerifierProvider verifierProvider, DigestCalculatorProvider digestProvider)
+ {
+ this.sigNameGenerator = sigNameGenerator;
+ this.sigAlgorithmFinder = sigAlgorithmFinder;
+ this.verifierProvider = verifierProvider;
+ this.digestProvider = digestProvider;
+ }
+
+ public boolean hasAssociatedCertificate()
+ {
+ return verifierProvider.hasAssociatedCertificate();
+ }
+
+ public X509CertificateHolder getAssociatedCertificate()
+ {
+ return verifierProvider.getAssociatedCertificate();
+ }
+
+ public ContentVerifier getContentVerifier(AlgorithmIdentifier signingAlgorithm, AlgorithmIdentifier digestAlgorithm)
+ throws OperatorCreationException
+ {
+ String signatureName = sigNameGenerator.getSignatureName(digestAlgorithm, signingAlgorithm);
+ AlgorithmIdentifier baseAlgID = sigAlgorithmFinder.find(signatureName);
+
+ return verifierProvider.get(new AlgorithmIdentifier(baseAlgID.getAlgorithm(), signingAlgorithm.getParameters()));
+ }
+
+ public DigestCalculator getDigestCalculator(AlgorithmIdentifier algorithmIdentifier)
+ throws OperatorCreationException
+ {
+ return digestProvider.get(algorithmIdentifier);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SimpleAttributeTableGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SimpleAttributeTableGenerator.java
new file mode 100644
index 00000000..7b11d617
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SimpleAttributeTableGenerator.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms;
+
+import com.android.internal.org.bouncycastle.asn1.cms.AttributeTable;
+
+import java.util.Map;
+
+/**
+ * Basic generator that just returns a preconstructed attribute table
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SimpleAttributeTableGenerator
+ implements CMSAttributeTableGenerator
+{
+ private final AttributeTable attributes;
+
+ public SimpleAttributeTableGenerator(
+ AttributeTable attributes)
+ {
+ this.attributes = attributes;
+ }
+
+ public AttributeTable getAttributes(Map parameters)
+ {
+ return attributes;
+ }
+}
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
new file mode 100644
index 00000000..e1b4fa58
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
@@ -0,0 +1,90 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms.jcajce;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+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;
+import com.android.internal.org.bouncycastle.cms.CMSSignatureEncryptionAlgorithmFinder;
+import com.android.internal.org.bouncycastle.cms.DefaultCMSSignatureEncryptionAlgorithmFinder;
+import com.android.internal.org.bouncycastle.cms.SignerInfoGenerator;
+import com.android.internal.org.bouncycastle.cms.SignerInfoGeneratorBuilder;
+import com.android.internal.org.bouncycastle.operator.ContentSigner;
+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 JcaSignerInfoGeneratorBuilder
+{
+ private SignerInfoGeneratorBuilder builder;
+
+ /**
+ * Base constructor.
+ *
+ * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations.
+ */
+ public JcaSignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider)
+ {
+ this(digestProvider, new DefaultCMSSignatureEncryptionAlgorithmFinder());
+ }
+
+ /**
+ * Base constructor with a particular finder for signature algorithms.
+ *
+ * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations.
+ * @param sigEncAlgFinder finder for algorithm IDs to store for the signature encryption/signature algorithm field.
+ */
+ public JcaSignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder)
+ {
+ builder = new SignerInfoGeneratorBuilder(digestProvider, sigEncAlgFinder);
+ }
+
+ /**
+ * If the passed in flag is true, the signer signature will be based on the data, not
+ * a collection of signed attributes, and no signed attributes will be included.
+ *
+ * @return the builder object
+ */
+ public JcaSignerInfoGeneratorBuilder setDirectSignature(boolean hasNoSignedAttributes)
+ {
+ builder.setDirectSignature(hasNoSignedAttributes);
+
+ return this;
+ }
+
+ public JcaSignerInfoGeneratorBuilder setSignedAttributeGenerator(CMSAttributeTableGenerator signedGen)
+ {
+ builder.setSignedAttributeGenerator(signedGen);
+
+ return this;
+ }
+
+ public JcaSignerInfoGeneratorBuilder setUnsignedAttributeGenerator(CMSAttributeTableGenerator unsignedGen)
+ {
+ builder.setUnsignedAttributeGenerator(unsignedGen);
+
+ return this;
+ }
+
+ public SignerInfoGenerator build(ContentSigner contentSigner, X509CertificateHolder certHolder)
+ throws OperatorCreationException
+ {
+ return builder.build(contentSigner, certHolder);
+ }
+
+ public SignerInfoGenerator build(ContentSigner contentSigner, byte[] keyIdentifier)
+ throws OperatorCreationException
+ {
+ return builder.build(contentSigner, keyIdentifier);
+ }
+
+ public SignerInfoGenerator build(ContentSigner contentSigner, X509Certificate certificate)
+ throws OperatorCreationException, CertificateEncodingException
+ {
+ return this.build(contentSigner, new JcaX509CertificateHolder(certificate));
+ }
+}
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
new file mode 100644
index 00000000..13512d32
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java
@@ -0,0 +1,184 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms.jcajce;
+
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.cms.CMSSignatureAlgorithmNameGenerator;
+import com.android.internal.org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator;
+import com.android.internal.org.bouncycastle.cms.SignerInformationVerifier;
+import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider;
+import com.android.internal.org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider;
+import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
+import com.android.internal.org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder;
+import com.android.internal.org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+import com.android.internal.org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JcaSignerInfoVerifierBuilder
+{
+ private Helper helper = new Helper();
+ private DigestCalculatorProvider digestProvider;
+ private CMSSignatureAlgorithmNameGenerator sigAlgNameGen = new DefaultCMSSignatureAlgorithmNameGenerator();
+ private SignatureAlgorithmIdentifierFinder sigAlgIDFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+
+ public JcaSignerInfoVerifierBuilder(DigestCalculatorProvider digestProvider)
+ {
+ this.digestProvider = digestProvider;
+ }
+
+ public JcaSignerInfoVerifierBuilder setProvider(Provider provider)
+ {
+ this.helper = new ProviderHelper(provider);
+
+ return this;
+ }
+
+ public JcaSignerInfoVerifierBuilder setProvider(String providerName)
+ {
+ this.helper = new NamedHelper(providerName);
+
+ return this;
+ }
+
+ /**
+ * Override the default signature algorithm name generator.
+ *
+ * @param sigAlgNameGen the algorithm name generator to use.
+ * @return the current builder.
+ */
+ public JcaSignerInfoVerifierBuilder setSignatureAlgorithmNameGenerator(CMSSignatureAlgorithmNameGenerator sigAlgNameGen)
+ {
+ this.sigAlgNameGen = sigAlgNameGen;
+
+ return this;
+ }
+
+ public JcaSignerInfoVerifierBuilder setSignatureAlgorithmFinder(SignatureAlgorithmIdentifierFinder sigAlgIDFinder)
+ {
+ this.sigAlgIDFinder = sigAlgIDFinder;
+
+ return this;
+ }
+
+ public SignerInformationVerifier build(X509CertificateHolder certHolder)
+ throws OperatorCreationException, CertificateException
+ {
+ return new SignerInformationVerifier(sigAlgNameGen, sigAlgIDFinder, helper.createContentVerifierProvider(certHolder), digestProvider);
+ }
+
+ public SignerInformationVerifier build(X509Certificate certificate)
+ throws OperatorCreationException
+ {
+ return new SignerInformationVerifier(sigAlgNameGen, sigAlgIDFinder, helper.createContentVerifierProvider(certificate), digestProvider);
+ }
+
+ public SignerInformationVerifier build(PublicKey pubKey)
+ throws OperatorCreationException
+ {
+ return new SignerInformationVerifier(sigAlgNameGen, sigAlgIDFinder, helper.createContentVerifierProvider(pubKey), digestProvider);
+ }
+
+ private class Helper
+ {
+ ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().build(publicKey);
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().build(certificate);
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder)
+ throws OperatorCreationException, CertificateException
+ {
+ return new JcaContentVerifierProviderBuilder().build(certHolder);
+ }
+
+ DigestCalculatorProvider createDigestCalculatorProvider()
+ throws OperatorCreationException
+ {
+ return new JcaDigestCalculatorProviderBuilder().build();
+ }
+ }
+
+ private class NamedHelper
+ extends Helper
+ {
+ private final String providerName;
+
+ public NamedHelper(String providerName)
+ {
+ this.providerName = providerName;
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(publicKey);
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certificate);
+ }
+
+ DigestCalculatorProvider createDigestCalculatorProvider()
+ throws OperatorCreationException
+ {
+ return new JcaDigestCalculatorProviderBuilder().setProvider(providerName).build();
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder)
+ throws OperatorCreationException, CertificateException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certHolder);
+ }
+ }
+
+ private class ProviderHelper
+ extends Helper
+ {
+ private final Provider provider;
+
+ public ProviderHelper(Provider provider)
+ {
+ this.provider = provider;
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(provider).build(publicKey);
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certificate);
+ }
+
+ DigestCalculatorProvider createDigestCalculatorProvider()
+ throws OperatorCreationException
+ {
+ return new JcaDigestCalculatorProviderBuilder().setProvider(provider).build();
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder)
+ throws OperatorCreationException, CertificateException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certHolder);
+ }
+ }
+}
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
new file mode 100644
index 00000000..b1e22fb1
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java
@@ -0,0 +1,154 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.cms.jcajce;
+
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator;
+import com.android.internal.org.bouncycastle.cms.SignerInformationVerifier;
+import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider;
+import com.android.internal.org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider;
+import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
+import com.android.internal.org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+import com.android.internal.org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JcaSimpleSignerInfoVerifierBuilder
+{
+ private Helper helper = new Helper();
+
+ public JcaSimpleSignerInfoVerifierBuilder setProvider(Provider provider)
+ {
+ this.helper = new ProviderHelper(provider);
+
+ return this;
+ }
+
+ public JcaSimpleSignerInfoVerifierBuilder setProvider(String providerName)
+ {
+ this.helper = new NamedHelper(providerName);
+
+ return this;
+ }
+
+ public SignerInformationVerifier build(X509CertificateHolder certHolder)
+ throws OperatorCreationException, CertificateException
+ {
+ return new SignerInformationVerifier(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), helper.createContentVerifierProvider(certHolder), helper.createDigestCalculatorProvider());
+ }
+
+ public SignerInformationVerifier build(X509Certificate certificate)
+ throws OperatorCreationException
+ {
+ return new SignerInformationVerifier(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), helper.createContentVerifierProvider(certificate), helper.createDigestCalculatorProvider());
+ }
+
+ public SignerInformationVerifier build(PublicKey pubKey)
+ throws OperatorCreationException
+ {
+ return new SignerInformationVerifier(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), helper.createContentVerifierProvider(pubKey), helper.createDigestCalculatorProvider());
+ }
+
+ private class Helper
+ {
+ ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().build(publicKey);
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().build(certificate);
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder)
+ throws OperatorCreationException, CertificateException
+ {
+ return new JcaContentVerifierProviderBuilder().build(certHolder);
+ }
+
+ DigestCalculatorProvider createDigestCalculatorProvider()
+ throws OperatorCreationException
+ {
+ return new JcaDigestCalculatorProviderBuilder().build();
+ }
+ }
+
+ private class NamedHelper
+ extends Helper
+ {
+ private final String providerName;
+
+ public NamedHelper(String providerName)
+ {
+ this.providerName = providerName;
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(publicKey);
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certificate);
+ }
+
+ DigestCalculatorProvider createDigestCalculatorProvider()
+ throws OperatorCreationException
+ {
+ return new JcaDigestCalculatorProviderBuilder().setProvider(providerName).build();
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder)
+ throws OperatorCreationException, CertificateException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certHolder);
+ }
+ }
+
+ private class ProviderHelper
+ extends Helper
+ {
+ private final Provider provider;
+
+ public ProviderHelper(Provider provider)
+ {
+ this.provider = provider;
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(provider).build(publicKey);
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate)
+ throws OperatorCreationException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certificate);
+ }
+
+ DigestCalculatorProvider createDigestCalculatorProvider()
+ throws OperatorCreationException
+ {
+ return new JcaDigestCalculatorProviderBuilder().setProvider(provider).build();
+ }
+
+ ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder)
+ throws OperatorCreationException, CertificateException
+ {
+ return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certHolder);
+ }
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentSigner.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentSigner.java
new file mode 100644
index 00000000..aecd8ba1
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentSigner.java
@@ -0,0 +1,39 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * General interface for an operator that is able to create a signature from
+ * a stream of output.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ContentSigner
+{
+ /**
+ * Return the algorithm identifier describing the signature
+ * algorithm and parameters this signer generates.
+ *
+ * @return algorithm oid and parameters.
+ */
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ /**
+ * Returns a stream that will accept data for the purpose of calculating
+ * a signature. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate
+ * the data on the fly as well.
+ *
+ * @return an OutputStream
+ */
+ OutputStream getOutputStream();
+
+ /**
+ * Returns a signature based on the current data written to the stream, since the
+ * start or the last call to getSignature().
+ *
+ * @return bytes representing the signature.
+ */
+ byte[] getSignature();
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentVerifier.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentVerifier.java
new file mode 100644
index 00000000..e04e6e3a
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentVerifier.java
@@ -0,0 +1,40 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * General interface for an operator that is able to verify a signature based
+ * on data in a stream of output.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ContentVerifier
+{
+ /**
+ * Return the algorithm identifier describing the signature
+ * algorithm and parameters this verifier supports.
+ *
+ * @return algorithm oid and parameters.
+ */
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ /**
+ * Returns a stream that will accept data for the purpose of calculating
+ * a signature for later verification. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate
+ * the data on the fly as well.
+ *
+ * @return an OutputStream
+ */
+ OutputStream getOutputStream();
+
+ /**
+ * Return true if the expected value of the signature matches the data passed
+ * into the stream.
+ *
+ * @param expected expected value of the signature on the data.
+ * @return true if the signature verifies, false otherwise
+ */
+ boolean verify(byte[] expected);
+} \ No newline at end of file
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentVerifierProvider.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentVerifierProvider.java
new file mode 100644
index 00000000..af0fefab
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentVerifierProvider.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+
+/**
+ * General interface for providers of ContentVerifier objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ContentVerifierProvider
+{
+ /**
+ * Return whether or not this verifier has a certificate associated with it.
+ *
+ * @return true if there is an associated certificate, false otherwise.
+ */
+ boolean hasAssociatedCertificate();
+
+ /**
+ * Return the associated certificate if there is one.
+ *
+ * @return a holder containing the associated certificate if there is one, null if there is not.
+ */
+ X509CertificateHolder getAssociatedCertificate();
+
+ /**
+ * Return a ContentVerifier that matches the passed in algorithm identifier,
+ *
+ * @param verifierAlgorithmIdentifier the algorithm and parameters required.
+ * @return a matching ContentVerifier
+ * @throws OperatorCreationException if the required ContentVerifier cannot be created.
+ */
+ ContentVerifier get(AlgorithmIdentifier verifierAlgorithmIdentifier)
+ throws OperatorCreationException;
+}
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
new file mode 100644
index 00000000..0e3edd30
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
@@ -0,0 +1,203 @@
+/* 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.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
+// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// 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 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 org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultDigestAlgorithmIdentifierFinder
+ implements DigestAlgorithmIdentifierFinder
+{
+ private static Map digestOids = new HashMap();
+ private static Map digestNameToOids = new HashMap();
+
+ static
+ {
+ //
+ // digests
+ //
+ // BEGIN Android-removed: Unsupported algorithms
+ // digestOids.put(OIWObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
+ // digestOids.put(OIWObjectIdentifiers.md4WithRSA, PKCSObjectIdentifiers.md4);
+ // digestOids.put(OIWObjectIdentifiers.dsaWithSHA1, OIWObjectIdentifiers.idSHA1);
+ // END Android-removed: Unsupported algorithms
+ digestOids.put(OIWObjectIdentifiers.sha1WithRSA, OIWObjectIdentifiers.idSHA1);
+
+ 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.md2WithRSAEncryption, PKCSObjectIdentifiers.md2);
+ // digestOids.put(PKCSObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
+ // END Android-removed: Unsupported algorithms
+ digestOids.put(PKCSObjectIdentifiers.md5WithRSAEncryption, PKCSObjectIdentifiers.md5);
+ digestOids.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, OIWObjectIdentifiers.idSHA1);
+
+ digestOids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, OIWObjectIdentifiers.idSHA1);
+ digestOids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, NISTObjectIdentifiers.id_sha224);
+ digestOids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, NISTObjectIdentifiers.id_sha384);
+ digestOids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, NISTObjectIdentifiers.id_sha512);
+ digestOids.put(X9ObjectIdentifiers.id_dsa_with_sha1, OIWObjectIdentifiers.idSHA1);
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, OIWObjectIdentifiers.idSHA1);
+ digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, NISTObjectIdentifiers.id_sha224);
+ 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_RIPEMD160, TeleTrusTObjectIdentifiers.ripemd160);
+
+ digestOids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, OIWObjectIdentifiers.idSHA1);
+ digestOids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, NISTObjectIdentifiers.id_sha224);
+ digestOids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, NISTObjectIdentifiers.id_sha384);
+ digestOids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, NISTObjectIdentifiers.id_sha512);
+ */
+ // END Android-removed: Unsupported algorithms
+
+ digestOids.put(NISTObjectIdentifiers.dsa_with_sha224, NISTObjectIdentifiers.id_sha224);
+ digestOids.put(NISTObjectIdentifiers.dsa_with_sha256, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(NISTObjectIdentifiers.dsa_with_sha384, NISTObjectIdentifiers.id_sha384);
+ digestOids.put(NISTObjectIdentifiers.dsa_with_sha512, NISTObjectIdentifiers.id_sha512);
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224, NISTObjectIdentifiers.id_sha3_224);
+ digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256, NISTObjectIdentifiers.id_sha3_256);
+ digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384, NISTObjectIdentifiers.id_sha3_384);
+ digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512, NISTObjectIdentifiers.id_sha3_512);
+ digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_224, NISTObjectIdentifiers.id_sha3_224);
+ digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_256, NISTObjectIdentifiers.id_sha3_256);
+ digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_384, NISTObjectIdentifiers.id_sha3_384);
+ digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_512, NISTObjectIdentifiers.id_sha3_512);
+ digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_224, NISTObjectIdentifiers.id_sha3_224);
+ digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_256, NISTObjectIdentifiers.id_sha3_256);
+ digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_384, NISTObjectIdentifiers.id_sha3_384);
+ digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_512, NISTObjectIdentifiers.id_sha3_512);
+
+ digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, TeleTrusTObjectIdentifiers.ripemd128);
+ digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, TeleTrusTObjectIdentifiers.ripemd160);
+ 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(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256);
+ digestOids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512);
+
+ digestOids.put(BCObjectIdentifiers.sphincs256_with_SHA3_512, NISTObjectIdentifiers.id_sha3_512);
+ digestOids.put(BCObjectIdentifiers.sphincs256_with_SHA512, NISTObjectIdentifiers.id_sha512);
+
+ 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);
+ */
+ // END Android-removed: Unsupported algorithms
+
+ digestNameToOids.put("SHA-1", OIWObjectIdentifiers.idSHA1);
+ digestNameToOids.put("SHA-224", NISTObjectIdentifiers.id_sha224);
+ digestNameToOids.put("SHA-256", NISTObjectIdentifiers.id_sha256);
+ digestNameToOids.put("SHA-384", NISTObjectIdentifiers.id_sha384);
+ digestNameToOids.put("SHA-512", NISTObjectIdentifiers.id_sha512);
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ digestNameToOids.put("SHA-512-224", NISTObjectIdentifiers.id_sha512_224);
+ digestNameToOids.put("SHA-512-256", NISTObjectIdentifiers.id_sha512_256);
+
+ digestNameToOids.put("SHA1", OIWObjectIdentifiers.idSHA1);
+ digestNameToOids.put("SHA224", NISTObjectIdentifiers.id_sha224);
+ digestNameToOids.put("SHA256", NISTObjectIdentifiers.id_sha256);
+ digestNameToOids.put("SHA384", NISTObjectIdentifiers.id_sha384);
+ digestNameToOids.put("SHA512", NISTObjectIdentifiers.id_sha512);
+ digestNameToOids.put("SHA512-224", NISTObjectIdentifiers.id_sha512_224);
+ digestNameToOids.put("SHA512-256", NISTObjectIdentifiers.id_sha512_256);
+
+ digestNameToOids.put("SHA3-224", NISTObjectIdentifiers.id_sha3_224);
+ digestNameToOids.put("SHA3-256", NISTObjectIdentifiers.id_sha3_256);
+ digestNameToOids.put("SHA3-384", NISTObjectIdentifiers.id_sha3_384);
+ digestNameToOids.put("SHA3-512", NISTObjectIdentifiers.id_sha3_512);
+
+ digestNameToOids.put("SHAKE-128", NISTObjectIdentifiers.id_shake128);
+ digestNameToOids.put("SHAKE-256", NISTObjectIdentifiers.id_shake256);
+
+ digestNameToOids.put("GOST3411", CryptoProObjectIdentifiers.gostR3411);
+ digestNameToOids.put("GOST3411-2012-256", RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256);
+ digestNameToOids.put("GOST3411-2012-512", RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512);
+
+ digestNameToOids.put("MD2", PKCSObjectIdentifiers.md2);
+ digestNameToOids.put("MD4", PKCSObjectIdentifiers.md4);
+ */
+ // END Android-removed: Unsupported algorithms
+ digestNameToOids.put("MD5", PKCSObjectIdentifiers.md5);
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ digestNameToOids.put("RIPEMD128", TeleTrusTObjectIdentifiers.ripemd128);
+ digestNameToOids.put("RIPEMD160", TeleTrusTObjectIdentifiers.ripemd160);
+ digestNameToOids.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256);
+
+ digestNameToOids.put("SM3", GMObjectIdentifiers.sm3);
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+
+ public AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId)
+ {
+ AlgorithmIdentifier digAlgId;
+
+ if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ digAlgId = RSASSAPSSparams.getInstance(sigAlgId.getParameters()).getHashAlgorithm();
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (sigAlgId.getAlgorithm().equals(EdECObjectIdentifiers.id_Ed25519))
+ {
+ digAlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512);
+ }
+ else if (sigAlgId.getAlgorithm().equals(EdECObjectIdentifiers.id_Ed448))
+ {
+ digAlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256_len, new ASN1Integer(512));
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else
+ {
+ digAlgId = new AlgorithmIdentifier((ASN1ObjectIdentifier)digestOids.get(sigAlgId.getAlgorithm()), DERNull.INSTANCE);
+ }
+
+ return digAlgId;
+ }
+
+ public AlgorithmIdentifier find(String digAlgName)
+ {
+ return new AlgorithmIdentifier((ASN1ObjectIdentifier)digestNameToOids.get(digAlgName), DERNull.INSTANCE);
+ }
+} \ 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
new file mode 100644
index 00000000..0ed65077
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
@@ -0,0 +1,451 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+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.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
+// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// 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 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 org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultSignatureAlgorithmIdentifierFinder
+ implements SignatureAlgorithmIdentifierFinder
+{
+ private static Map algorithms = new HashMap();
+ private static Set noParams = new HashSet();
+ private static Map params = new HashMap();
+ private static Set pkcs15RsaEncryption = new HashSet();
+ private static Map digestOids = new HashMap();
+
+ private static final ASN1ObjectIdentifier ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption;
+ private static final ASN1ObjectIdentifier ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1;
+ private static final ASN1ObjectIdentifier ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1;
+ private static final ASN1ObjectIdentifier ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS;
+ // BEGIN Android-removed: Unsupported algorithms
+ // private static final ASN1ObjectIdentifier ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94;
+ // private static final ASN1ObjectIdentifier ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001;
+ // private static final ASN1ObjectIdentifier ENCRYPTION_ECGOST3410_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256;
+ // private static final ASN1ObjectIdentifier ENCRYPTION_ECGOST3410_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512;
+ // END Android-removed: Unsupported algorithms
+
+ static
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ // algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption);
+ // algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption);
+ // END Android-removed: Unsupported algorithms
+ algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption);
+ algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption);
+ algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption);
+ algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption);
+ algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption);
+ algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption);
+ algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption);
+ algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption);
+ algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption);
+ algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption);
+ algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption);
+ algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption);
+ algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ algorithms.put("SHA3-224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("SHA3-256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("SHA3-384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("SHA3-512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
+ algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
+ */
+ // END Android-removed: Unsupported algorithms
+ algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1);
+ algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1);
+ algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224);
+ algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256);
+ algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384);
+ algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512);
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ algorithms.put("SHA3-224WITHDSA", NISTObjectIdentifiers.id_dsa_with_sha3_224);
+ algorithms.put("SHA3-256WITHDSA", NISTObjectIdentifiers.id_dsa_with_sha3_256);
+ algorithms.put("SHA3-384WITHDSA", NISTObjectIdentifiers.id_dsa_with_sha3_384);
+ algorithms.put("SHA3-512WITHDSA", NISTObjectIdentifiers.id_dsa_with_sha3_512);
+ algorithms.put("SHA3-224WITHECDSA", NISTObjectIdentifiers.id_ecdsa_with_sha3_224);
+ algorithms.put("SHA3-256WITHECDSA", NISTObjectIdentifiers.id_ecdsa_with_sha3_256);
+ algorithms.put("SHA3-384WITHECDSA", NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
+ algorithms.put("SHA3-512WITHECDSA", NISTObjectIdentifiers.id_ecdsa_with_sha3_512);
+ algorithms.put("SHA3-224WITHRSA", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224);
+ algorithms.put("SHA3-256WITHRSA", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256);
+ algorithms.put("SHA3-384WITHRSA", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384);
+ algorithms.put("SHA3-512WITHRSA", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512);
+ algorithms.put("SHA3-224WITHRSAENCRYPTION", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224);
+ algorithms.put("SHA3-256WITHRSAENCRYPTION", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256);
+ algorithms.put("SHA3-384WITHRSAENCRYPTION", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384);
+ algorithms.put("SHA3-512WITHRSAENCRYPTION", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512);
+ */
+ // END Android-removed: Unsupported algorithms
+ algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1);
+ algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1);
+ algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224);
+ algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256);
+ algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384);
+ algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512);
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+ algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+ algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+ algorithms.put("GOST3411WITHECGOST3410-2012-256", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256);
+ algorithms.put("GOST3411WITHECGOST3410-2012-512", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512);
+ algorithms.put("GOST3411WITHGOST3410-2012-256", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256);
+ algorithms.put("GOST3411WITHGOST3410-2012-512", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512);
+ algorithms.put("GOST3411-2012-256WITHECGOST3410-2012-256", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256);
+ 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);
+ algorithms.put("SHA384WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_384);
+ algorithms.put("SHA512WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_512);
+ algorithms.put("SHA3-512WITHSPHINCS256", BCObjectIdentifiers.sphincs256_with_SHA3_512);
+ algorithms.put("SHA512WITHSPHINCS256", BCObjectIdentifiers.sphincs256_with_SHA512);
+
+ algorithms.put("ED25519", EdECObjectIdentifiers.id_Ed25519);
+ algorithms.put("ED448", EdECObjectIdentifiers.id_Ed448);
+
+ algorithms.put("RIPEMD160WITHSM2", GMObjectIdentifiers.sm2sign_with_rmd160);
+ algorithms.put("SHA1WITHSM2", GMObjectIdentifiers.sm2sign_with_sha1);
+ algorithms.put("SHA224WITHSM2", GMObjectIdentifiers.sm2sign_with_sha224);
+ algorithms.put("SHA256WITHSM2", GMObjectIdentifiers.sm2sign_with_sha256);
+ algorithms.put("SHA384WITHSM2", GMObjectIdentifiers.sm2sign_with_sha384);
+ algorithms.put("SHA512WITHSM2", GMObjectIdentifiers.sm2sign_with_sha512);
+ 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("SHA256WITHXMSSMT", BCObjectIdentifiers.xmss_mt_SHA256ph);
+ algorithms.put("SHA512WITHXMSSMT", BCObjectIdentifiers.xmss_mt_SHA512ph);
+ algorithms.put("SHAKE128WITHXMSSMT", BCObjectIdentifiers.xmss_mt_SHAKE128ph);
+ algorithms.put("SHAKE256WITHXMSSMT", BCObjectIdentifiers.xmss_mt_SHAKE256ph);
+
+ algorithms.put("SHA256WITHXMSS-SHA256", BCObjectIdentifiers.xmss_SHA256ph);
+ algorithms.put("SHA512WITHXMSS-SHA512", BCObjectIdentifiers.xmss_SHA512ph);
+ algorithms.put("SHAKE128WITHXMSS-SHAKE128", BCObjectIdentifiers.xmss_SHAKE128ph);
+ algorithms.put("SHAKE256WITHXMSS-SHAKE256", BCObjectIdentifiers.xmss_SHAKE256ph);
+
+ algorithms.put("SHA256WITHXMSSMT-SHA256", BCObjectIdentifiers.xmss_mt_SHA256ph);
+ 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("LMS", PKCSObjectIdentifiers.id_alg_hss_lms_hashsig);
+
+ algorithms.put("XMSS", IsaraObjectIdentifiers.id_alg_xmss);
+ algorithms.put("XMSS-SHA256", BCObjectIdentifiers.xmss_SHA256);
+ algorithms.put("XMSS-SHA512", BCObjectIdentifiers.xmss_SHA512);
+ algorithms.put("XMSS-SHAKE128", BCObjectIdentifiers.xmss_SHAKE128);
+ algorithms.put("XMSS-SHAKE256", BCObjectIdentifiers.xmss_SHAKE256);
+
+ algorithms.put("XMSSMT", IsaraObjectIdentifiers.id_alg_xmssmt);
+ algorithms.put("XMSSMT-SHA256", BCObjectIdentifiers.xmss_mt_SHA256);
+ algorithms.put("XMSSMT-SHA512", BCObjectIdentifiers.xmss_mt_SHA512);
+ algorithms.put("XMSSMT-SHAKE128", BCObjectIdentifiers.xmss_mt_SHAKE128);
+ algorithms.put("XMSSMT-SHAKE256", BCObjectIdentifiers.xmss_mt_SHAKE256);
+
+ algorithms.put("QTESLA-P-I", BCObjectIdentifiers.qTESLA_p_I);
+ algorithms.put("QTESLA-P-III", BCObjectIdentifiers.qTESLA_p_III);
+ */
+ // END Android-removed: Unsupported algorithms
+
+ //
+ // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field.
+ // The parameters field SHALL be NULL for RSA based signature algorithms.
+ //
+ noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1);
+ noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224);
+ noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256);
+ noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384);
+ noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512);
+ noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1);
+ // BEGIN Android-removed: unsupported algorithms
+ // noParams.add(OIWObjectIdentifiers.dsaWithSHA1);
+ // END Android-removed: unsupported algorithms
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha224);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha384);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha512);
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ noParams.add(NISTObjectIdentifiers.id_dsa_with_sha3_224);
+ noParams.add(NISTObjectIdentifiers.id_dsa_with_sha3_256);
+ noParams.add(NISTObjectIdentifiers.id_dsa_with_sha3_384);
+ noParams.add(NISTObjectIdentifiers.id_dsa_with_sha3_512);
+ noParams.add(NISTObjectIdentifiers.id_ecdsa_with_sha3_224);
+ noParams.add(NISTObjectIdentifiers.id_ecdsa_with_sha3_256);
+ noParams.add(NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
+ noParams.add(NISTObjectIdentifiers.id_ecdsa_with_sha3_512);
+
+ //
+ // RFC 4491
+ //
+ noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+ noParams.add(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256);
+ noParams.add(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512);
+
+ //
+ // SPHINCS-256
+ //
+ noParams.add(BCObjectIdentifiers.sphincs256_with_SHA512);
+ noParams.add(BCObjectIdentifiers.sphincs256_with_SHA3_512);
+
+ //
+ // XMSS
+ //
+ noParams.add(BCObjectIdentifiers.xmss_SHA256ph);
+ noParams.add(BCObjectIdentifiers.xmss_SHA512ph);
+ noParams.add(BCObjectIdentifiers.xmss_SHAKE128ph);
+ noParams.add(BCObjectIdentifiers.xmss_SHAKE256ph);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHA256ph);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHA512ph);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE128ph);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE256ph);
+
+ noParams.add(BCObjectIdentifiers.xmss_SHA256);
+ noParams.add(BCObjectIdentifiers.xmss_SHA512);
+ noParams.add(BCObjectIdentifiers.xmss_SHAKE128);
+ noParams.add(BCObjectIdentifiers.xmss_SHAKE256);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHA256);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHA512);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE128);
+ noParams.add(BCObjectIdentifiers.xmss_mt_SHAKE256);
+
+ noParams.add(IsaraObjectIdentifiers.id_alg_xmss);
+ noParams.add(IsaraObjectIdentifiers.id_alg_xmssmt);
+
+ //
+ // qTESLA
+ //
+ noParams.add(BCObjectIdentifiers.qTESLA_p_I);
+ noParams.add(BCObjectIdentifiers.qTESLA_p_III);
+
+ //
+ // SM2
+ //
+// noParams.add(GMObjectIdentifiers.sm2sign_with_rmd160);
+// noParams.add(GMObjectIdentifiers.sm2sign_with_sha1);
+// noParams.add(GMObjectIdentifiers.sm2sign_with_sha224);
+ noParams.add(GMObjectIdentifiers.sm2sign_with_sha256);
+// noParams.add(GMObjectIdentifiers.sm2sign_with_sha384);
+// noParams.add(GMObjectIdentifiers.sm2sign_with_sha512);
+ noParams.add(GMObjectIdentifiers.sm2sign_with_sm3);
+ // EdDSA
+ noParams.add(EdECObjectIdentifiers.id_Ed25519);
+ noParams.add(EdECObjectIdentifiers.id_Ed448);
+ */
+ // END Android-removed: Unsupported algorithms
+
+ //
+ // PKCS 1.5 encrypted algorithms
+ //
+ pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha1WithRSAEncryption);
+ pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha224WithRSAEncryption);
+ pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha256WithRSAEncryption);
+ pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha384WithRSAEncryption);
+ pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512WithRSAEncryption);
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
+ pkcs15RsaEncryption.add(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224);
+ pkcs15RsaEncryption.add(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256);
+ pkcs15RsaEncryption.add(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384);
+ pkcs15RsaEncryption.add(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512);
+ */
+ // END Android-removed: Unsupported algorithms
+
+ //
+ // explicit params
+ //
+ AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
+ params.put("SHA1WITHRSAANDMGF1", createPSSParams(sha1AlgId, 20));
+
+ AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE);
+ params.put("SHA224WITHRSAANDMGF1", createPSSParams(sha224AlgId, 28));
+
+ AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);
+ params.put("SHA256WITHRSAANDMGF1", createPSSParams(sha256AlgId, 32));
+
+ AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE);
+ params.put("SHA384WITHRSAANDMGF1", createPSSParams(sha384AlgId, 48));
+
+ AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE);
+ params.put("SHA512WITHRSAANDMGF1", createPSSParams(sha512AlgId, 64));
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ AlgorithmIdentifier sha3_224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_224, DERNull.INSTANCE);
+ params.put("SHA3-224WITHRSAANDMGF1", createPSSParams(sha3_224AlgId, 28));
+
+ AlgorithmIdentifier sha3_256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256, DERNull.INSTANCE);
+ params.put("SHA3-256WITHRSAANDMGF1", createPSSParams(sha3_256AlgId, 32));
+
+ AlgorithmIdentifier sha3_384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_384, DERNull.INSTANCE);
+ params.put("SHA3-384WITHRSAANDMGF1", createPSSParams(sha3_384AlgId, 48));
+
+ AlgorithmIdentifier sha3_512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_512, DERNull.INSTANCE);
+ params.put("SHA3-512WITHRSAANDMGF1", createPSSParams(sha3_512AlgId, 64));
+ */
+ // END Android-removed: Unsupported algorithms
+
+ //
+ // digests
+ //
+ 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.md2WithRSAEncryption, PKCSObjectIdentifiers.md2);
+ // digestOids.put(PKCSObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
+ // END Android-removed: Unsupported algorithms
+ digestOids.put(PKCSObjectIdentifiers.md5WithRSAEncryption, PKCSObjectIdentifiers.md5);
+ digestOids.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, OIWObjectIdentifiers.idSHA1);
+ // BEGIN Android-removed: Unsupported algorithms
+ // digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, TeleTrusTObjectIdentifiers.ripemd128);
+ // digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, TeleTrusTObjectIdentifiers.ripemd160);
+ // 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);
+ // END Android-removed: Unsupported algorithms
+ digestOids.put(NISTObjectIdentifiers.dsa_with_sha224, NISTObjectIdentifiers.id_sha224);
+ digestOids.put(NISTObjectIdentifiers.dsa_with_sha256, NISTObjectIdentifiers.id_sha256);
+ digestOids.put(NISTObjectIdentifiers.dsa_with_sha384, NISTObjectIdentifiers.id_sha384);
+ digestOids.put(NISTObjectIdentifiers.dsa_with_sha512, NISTObjectIdentifiers.id_sha512);
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_224, NISTObjectIdentifiers.id_sha3_224);
+ digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_256, NISTObjectIdentifiers.id_sha3_256);
+ digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_384, NISTObjectIdentifiers.id_sha3_384);
+ digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_512, NISTObjectIdentifiers.id_sha3_512);
+ digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_224, NISTObjectIdentifiers.id_sha3_224);
+ digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_256, NISTObjectIdentifiers.id_sha3_256);
+ digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_384, NISTObjectIdentifiers.id_sha3_384);
+ digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_512, NISTObjectIdentifiers.id_sha3_512);
+ digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224, NISTObjectIdentifiers.id_sha3_224);
+ digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256, NISTObjectIdentifiers.id_sha3_256);
+ digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384, NISTObjectIdentifiers.id_sha3_384);
+ digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512, NISTObjectIdentifiers.id_sha3_512);
+
+ digestOids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, PKCSObjectIdentifiers.md2);
+ digestOids.put(PKCSObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
+ */
+ // END Android-removed: Unsupported algorithms
+ digestOids.put(PKCSObjectIdentifiers.md5WithRSAEncryption, PKCSObjectIdentifiers.md5);
+ digestOids.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, OIWObjectIdentifiers.idSHA1);
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, TeleTrusTObjectIdentifiers.ripemd128);
+ digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, TeleTrusTObjectIdentifiers.ripemd160);
+ 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(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256);
+ digestOids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512);
+
+ 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);
+ */
+ // 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(
+ hashAlgId,
+ new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId),
+ new ASN1Integer(saltSize),
+ new ASN1Integer(1));
+ }
+
+ public AlgorithmIdentifier find(String sigAlgName)
+ {
+ return generate(sigAlgName);
+ }
+} \ No newline at end of file
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
new file mode 100644
index 00000000..168c48d2
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java
@@ -0,0 +1,28 @@
+/* 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 DigestAlgorithmIdentifierFinder
+{
+ /**
+ * Find the digest algorithm identifier that matches with
+ * the passed in signature algorithm identifier.
+ *
+ * @param sigAlgId the signature algorithm of interest.
+ * @return an algorithm identifier for the corresponding digest.
+ */
+ AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId);
+
+ /**
+ * Find the algorithm identifier that matches with
+ * the passed in digest name.
+ *
+ * @param digAlgName the name of the digest algorithm of interest.
+ * @return an algorithm identifier for the digest signature.
+ */
+ AlgorithmIdentifier find(String digAlgName);
+} \ No newline at end of file
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestCalculator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestCalculator.java
new file mode 100644
index 00000000..a02c3e05
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestCalculator.java
@@ -0,0 +1,38 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * General interface for an operator that is able to calculate a digest from
+ * a stream of output.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface DigestCalculator
+{
+ /**
+ * Return the algorithm identifier representing the digest implemented by
+ * this calculator.
+ *
+ * @return algorithm id and parameters.
+ */
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ /**
+ * Returns a stream that will accept data for the purpose of calculating
+ * a digest. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate
+ * the data on the fly as well.
+ *
+ * @return an OutputStream
+ */
+ OutputStream getOutputStream();
+
+ /**
+ * Return the digest calculated on what has been written to the calculator's output stream.
+ *
+ * @return a digest.
+ */
+ byte[] getDigest();
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestCalculatorProvider.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestCalculatorProvider.java
new file mode 100644
index 00000000..99d3be93
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestCalculatorProvider.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * The base interface for a provider of DigestCalculator implementations.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface DigestCalculatorProvider
+{
+ DigestCalculator get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ throws OperatorCreationException;
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/GenericKey.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/GenericKey.java
new file mode 100644
index 00000000..4205a5fd
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/GenericKey.java
@@ -0,0 +1,45 @@
+/* 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 class GenericKey
+{
+ private AlgorithmIdentifier algorithmIdentifier;
+ private Object representation;
+
+ /**
+ * @deprecated provide an AlgorithmIdentifier.
+ * @param representation key data
+ */
+ public GenericKey(Object representation)
+ {
+ this.algorithmIdentifier = null;
+ this.representation = representation;
+ }
+
+ public GenericKey(AlgorithmIdentifier algorithmIdentifier, byte[] representation)
+ {
+ this.algorithmIdentifier = algorithmIdentifier;
+ this.representation = representation;
+ }
+
+ protected GenericKey(AlgorithmIdentifier algorithmIdentifier, Object representation)
+ {
+ this.algorithmIdentifier = algorithmIdentifier;
+ this.representation = representation;
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithmIdentifier;
+ }
+
+ public Object getRepresentation()
+ {
+ return representation;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/InputDecryptor.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/InputDecryptor.java
new file mode 100644
index 00000000..848b94c6
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/InputDecryptor.java
@@ -0,0 +1,31 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * General interface for an operator that is able to produce
+ * an InputStream that will decrypt a stream of encrypted data.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface InputDecryptor
+{
+ /**
+ * Return the algorithm identifier describing the encryption
+ * algorithm and parameters this decryptor can process.
+ *
+ * @return algorithm oid and parameters.
+ */
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ /**
+ * Wrap the passed in input stream encIn, returning an input stream
+ * that decrypts what it reads from encIn before returning it.
+ *
+ * @param encIn InputStream containing encrypted input.
+ * @return an decrypting InputStream
+ */
+ InputStream getInputStream(InputStream encIn);
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/MacCalculator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/MacCalculator.java
new file mode 100644
index 00000000..7154f79c
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/MacCalculator.java
@@ -0,0 +1,40 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * General interface for a key initialized operator that is able to calculate a MAC from
+ * a stream of output.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface MacCalculator
+{
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ /**
+ * Returns a stream that will accept data for the purpose of calculating
+ * the MAC for later verification. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate
+ * the data on the fly as well.
+ *
+ * @return an OutputStream
+ */
+ OutputStream getOutputStream();
+
+ /**
+ * Return the calculated MAC based on what has been written to the stream.
+ *
+ * @return calculated MAC.
+ */
+ byte[] getMac();
+
+
+ /**
+ * Return the key used for calculating the MAC.
+ *
+ * @return the MAC key.
+ */
+ GenericKey getKey();
+} \ No newline at end of file
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorCreationException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorCreationException.java
new file mode 100644
index 00000000..72063e08
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorCreationException.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OperatorCreationException
+ extends OperatorException
+{
+ public OperatorCreationException(String msg, Throwable cause)
+ {
+ super(msg, cause);
+ }
+
+ public OperatorCreationException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorException.java
new file mode 100644
index 00000000..4835fa90
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorException.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OperatorException
+ extends Exception
+{
+ private Throwable cause;
+
+ public OperatorException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public OperatorException(String msg)
+ {
+ super(msg);
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorStreamException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorStreamException.java
new file mode 100644
index 00000000..043128b2
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorStreamException.java
@@ -0,0 +1,25 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+import java.io.IOException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OperatorStreamException
+ extends IOException
+{
+ private Throwable cause;
+
+ public OperatorStreamException(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/operator/RawContentVerifier.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/RawContentVerifier.java
new file mode 100644
index 00000000..e7e12cef
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/RawContentVerifier.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+/**
+ * Interface for ContentVerifiers that also support raw signatures that can be
+ * verified using the digest of the calculated data.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface RawContentVerifier
+{
+ /**
+ * Verify that the expected signature value was derived from the passed in digest.
+ *
+ * @param digest digest calculated from the content.
+ * @param expected expected value of the signature
+ * @return true if the expected signature is derived from the digest, false otherwise.
+ */
+ boolean verify(byte[] digest, byte[] expected);
+}
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/RuntimeOperatorException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/RuntimeOperatorException.java
new file mode 100644
index 00000000..b51738fa
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/RuntimeOperatorException.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RuntimeOperatorException
+ extends RuntimeException
+{
+ private Throwable cause;
+
+ public RuntimeOperatorException(String msg)
+ {
+ super(msg);
+ }
+
+ public RuntimeOperatorException(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/operator/SignatureAlgorithmIdentifierFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/SignatureAlgorithmIdentifierFinder.java
new file mode 100644
index 00000000..07299e77
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/SignatureAlgorithmIdentifierFinder.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 SignatureAlgorithmIdentifierFinder
+{
+ /**
+ * Find the signature algorithm identifier that matches with
+ * the passed in signature algorithm name.
+ *
+ * @param sigAlgName the name of the signature algorithm of interest.
+ * @return an algorithm identifier for the corresponding signature.
+ */
+ AlgorithmIdentifier find(String sigAlgName);
+} \ No newline at end of file
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
new file mode 100644
index 00000000..0f5b47e1
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
@@ -0,0 +1,185 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator.bc;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers;
+// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+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 com.android.internal.org.bouncycastle.operator.OperatorCreationException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BcDefaultDigestProvider
+ implements BcDigestProvider
+{
+ private static final Map lookup = createTable();
+
+ private static Map createTable()
+ {
+ Map table = new HashMap();
+
+ table.put(OIWObjectIdentifiers.idSHA1, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHA1Digest();
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_sha224, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHA224Digest();
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_sha256, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHA256Digest();
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_sha384, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHA384Digest();
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_sha512, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHA512Digest();
+ }
+ });
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ table.put(NISTObjectIdentifiers.id_sha3_224, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHA3Digest(224);
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_sha3_256, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHA3Digest(256);
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_sha3_384, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHA3Digest(384);
+ }
+ });
+ table.put(NISTObjectIdentifiers.id_sha3_512, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new SHA3Digest(512);
+ }
+ });
+ table.put(PKCSObjectIdentifiers.md5, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new MD5Digest();
+ }
+ });
+ table.put(PKCSObjectIdentifiers.md4, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new MD4Digest();
+ }
+ });
+ table.put(PKCSObjectIdentifiers.md2, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new MD2Digest();
+ }
+ });
+ table.put(CryptoProObjectIdentifiers.gostR3411, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new GOST3411Digest();
+ }
+ });
+ table.put(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new GOST3411_2012_256Digest();
+ }
+ });
+ table.put(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new GOST3411_2012_512Digest();
+ }
+ });
+ table.put(TeleTrusTObjectIdentifiers.ripemd128, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new RIPEMD128Digest();
+ }
+ });
+ table.put(TeleTrusTObjectIdentifiers.ripemd160, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new RIPEMD160Digest();
+ }
+ });
+ table.put(TeleTrusTObjectIdentifiers.ripemd256, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new RIPEMD256Digest();
+ }
+ });
+ */
+ // END Android-removed: Unsupported algorithms
+
+ return Collections.unmodifiableMap(table);
+ }
+
+ public static final BcDigestProvider INSTANCE = new BcDefaultDigestProvider();
+
+ private BcDefaultDigestProvider()
+ {
+
+ }
+
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ throws OperatorCreationException
+ {
+ BcDigestProvider extProv = (BcDigestProvider)lookup.get(digestAlgorithmIdentifier.getAlgorithm());
+
+ if (extProv == null)
+ {
+ throw new OperatorCreationException("cannot recognise digest");
+ }
+
+ return extProv.get(digestAlgorithmIdentifier);
+ }
+}
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
new file mode 100644
index 00000000..176c681a
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
@@ -0,0 +1,84 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator.bc;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+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 BcDigestCalculatorProvider
+ implements DigestCalculatorProvider
+{
+ private BcDigestProvider digestProvider = BcDefaultDigestProvider.INSTANCE;
+
+ public DigestCalculator get(final AlgorithmIdentifier algorithm)
+ throws OperatorCreationException
+ {
+ Digest dig = digestProvider.get(algorithm);
+
+ final DigestOutputStream stream = new DigestOutputStream(dig);
+
+ return new DigestCalculator()
+ {
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithm;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return stream;
+ }
+
+ public byte[] getDigest()
+ {
+ return stream.getDigest();
+ }
+ };
+ }
+
+ private class DigestOutputStream
+ extends OutputStream
+ {
+ private Digest dig;
+
+ DigestOutputStream(Digest dig)
+ {
+ this.dig = dig;
+ }
+
+ public void write(byte[] bytes, int off, int len)
+ throws IOException
+ {
+ dig.update(bytes, off, len);
+ }
+
+ public void write(byte[] bytes)
+ throws IOException
+ {
+ dig.update(bytes, 0, bytes.length);
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ dig.update((byte)b);
+ }
+
+ byte[] getDigest()
+ {
+ byte[] d = new byte[dig.getDigestSize()];
+
+ dig.doFinal(d, 0);
+
+ return d;
+ }
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestProvider.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestProvider.java
new file mode 100644
index 00000000..5df15eb4
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestProvider.java
@@ -0,0 +1,15 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator.bc;
+
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.crypto.ExtendedDigest;
+import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BcDigestProvider
+{
+ ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ throws OperatorCreationException;
+}
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
new file mode 100644
index 00000000..6e669d38
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
@@ -0,0 +1,278 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator.jcajce;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.GeneralSecurityException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+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.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+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.RSASSAPSSparams;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.jcajce.CompositePrivateKey;
+import com.android.internal.org.bouncycastle.jcajce.io.OutputStreamFactory;
+import com.android.internal.org.bouncycastle.jcajce.spec.CompositeAlgorithmSpec;
+import com.android.internal.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+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.ContentSigner;
+import com.android.internal.org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import com.android.internal.org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import com.android.internal.org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
+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.io.TeeOutputStream;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JcaContentSignerBuilder
+{
+ 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)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+
+ if (sigParamSpec instanceof PSSParameterSpec)
+ {
+ PSSParameterSpec pssSpec = (PSSParameterSpec)sigParamSpec;
+
+ this.sigAlgSpec = pssSpec;
+ this.sigAlgId = new AlgorithmIdentifier(
+ PKCSObjectIdentifiers.id_RSASSA_PSS, createPSSParams(pssSpec));
+ }
+ else if (sigParamSpec instanceof CompositeAlgorithmSpec)
+ {
+ CompositeAlgorithmSpec compSpec = (CompositeAlgorithmSpec)sigParamSpec;
+
+ this.sigAlgSpec = compSpec;
+ this.sigAlgId = new AlgorithmIdentifier(
+ MiscObjectIdentifiers.id_alg_composite, createCompParams(compSpec));
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown sigParamSpec: "
+ + ((sigParamSpec == null) ? "null" : sigParamSpec.getClass().getName()));
+ }
+ }
+
+ public JcaContentSignerBuilder setProvider(Provider provider)
+ {
+ this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
+
+ return this;
+ }
+
+ public JcaContentSignerBuilder setProvider(String providerName)
+ {
+ this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
+
+ return this;
+ }
+
+ public JcaContentSignerBuilder setSecureRandom(SecureRandom random)
+ {
+ this.random = random;
+
+ return this;
+ }
+
+ public ContentSigner build(PrivateKey privateKey)
+ throws OperatorCreationException
+ {
+ if (privateKey instanceof CompositePrivateKey)
+ {
+ return buildComposite((CompositePrivateKey)privateKey);
+ }
+
+ try
+ {
+ final Signature sig = helper.createSignature(sigAlgId);
+ final AlgorithmIdentifier signatureAlgId = sigAlgId;
+
+ if (random != null)
+ {
+ sig.initSign(privateKey, random);
+ }
+ else
+ {
+ sig.initSign(privateKey);
+ }
+
+ return new ContentSigner()
+ {
+ private OutputStream stream = OutputStreamFactory.createStream(sig);
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return signatureAlgId;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return stream;
+ }
+
+ public byte[] getSignature()
+ {
+ try
+ {
+ return sig.sign();
+ }
+ catch (SignatureException e)
+ {
+ throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e);
+ }
+ }
+ };
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("cannot create signer: " + e.getMessage(), e);
+ }
+ }
+
+ private ContentSigner buildComposite(CompositePrivateKey privateKey)
+ throws OperatorCreationException
+ {
+ try
+ {
+ List<PrivateKey> privateKeys = privateKey.getPrivateKeys();
+ final ASN1Sequence sigAlgIds = ASN1Sequence.getInstance(sigAlgId.getParameters());
+ final Signature[] sigs = new Signature[sigAlgIds.size()];
+
+ for (int i = 0; i != sigAlgIds.size(); i++)
+ {
+ sigs[i] = helper.createSignature(AlgorithmIdentifier.getInstance(sigAlgIds.getObjectAt(i)));
+
+ if (random != null)
+ {
+ sigs[i].initSign(privateKeys.get(i), random);
+ }
+ else
+ {
+ sigs[i].initSign(privateKeys.get(i));
+ }
+ }
+
+ OutputStream sStream = OutputStreamFactory.createStream(sigs[0]);
+ for (int i = 1; i != sigs.length; i++)
+ {
+ sStream = new TeeOutputStream(sStream, OutputStreamFactory.createStream(sigs[i]));
+ }
+
+ final OutputStream sigStream = sStream;
+
+ return new ContentSigner()
+ {
+ OutputStream stream = sigStream;
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return sigAlgId;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return stream;
+ }
+
+ public byte[] getSignature()
+ {
+ try
+ {
+ ASN1EncodableVector sigV = new ASN1EncodableVector();
+
+ for (int i = 0; i != sigs.length; i++)
+ {
+ sigV.add(new DERBitString(sigs[i].sign()));
+ }
+
+ return new DERSequence(sigV).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeOperatorException("exception encoding signature: " + e.getMessage(), e);
+ }
+ catch (SignatureException e)
+ {
+ throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e);
+ }
+ }
+ };
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("cannot create signer: " + e.getMessage(), e);
+ }
+ }
+
+ private static RSASSAPSSparams createPSSParams(PSSParameterSpec pssSpec)
+ {
+ DigestAlgorithmIdentifierFinder digFinder = new DefaultDigestAlgorithmIdentifierFinder();
+ AlgorithmIdentifier digId = digFinder.find(pssSpec.getDigestAlgorithm());
+ AlgorithmIdentifier mgfDig = digFinder.find(((MGF1ParameterSpec)pssSpec.getMGFParameters()).getDigestAlgorithm());
+
+ return new RSASSAPSSparams(
+ digId,
+ new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, mgfDig),
+ new ASN1Integer(pssSpec.getSaltLength()),
+ new ASN1Integer(pssSpec.getTrailerField()));
+ }
+
+ private static ASN1Sequence createCompParams(CompositeAlgorithmSpec compSpec)
+ {
+ SignatureAlgorithmIdentifierFinder algFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ List<String> algorithmNames = compSpec.getAlgorithmNames();
+ List<AlgorithmParameterSpec> algorithmSpecs = compSpec.getParameterSpecs();
+
+ for (int i = 0; i != algorithmNames.size(); i++)
+ {
+ AlgorithmParameterSpec sigSpec = algorithmSpecs.get(i);
+ if (sigSpec == null)
+ {
+ v.add(algFinder.find(algorithmNames.get(i)));
+ }
+ else if (sigSpec instanceof PSSParameterSpec)
+ {
+ v.add(createPSSParams((PSSParameterSpec)sigSpec));
+ }
+ else
+ {
+ throw new IllegalArgumentException("unrecognized parameterSpec");
+ }
+ }
+
+ return new DERSequence(v);
+ }
+}
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
new file mode 100644
index 00000000..825f8294
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
@@ -0,0 +1,454 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator.jcajce;
+
+import java.io.OutputStream;
+import java.security.GeneralSecurityException;
+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.X509Certificate;
+import java.util.List;
+
+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;
+import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
+import com.android.internal.org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
+import com.android.internal.org.bouncycastle.jcajce.CompositePublicKey;
+import com.android.internal.org.bouncycastle.jcajce.io.OutputStreamFactory;
+import com.android.internal.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+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.ContentVerifier;
+import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider;
+import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
+import com.android.internal.org.bouncycastle.operator.RawContentVerifier;
+import com.android.internal.org.bouncycastle.operator.RuntimeOperatorException;
+import com.android.internal.org.bouncycastle.util.io.TeeOutputStream;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JcaContentVerifierProviderBuilder
+{
+ private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
+
+ public JcaContentVerifierProviderBuilder()
+ {
+ }
+
+ public JcaContentVerifierProviderBuilder setProvider(Provider provider)
+ {
+ this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
+
+ return this;
+ }
+
+ public JcaContentVerifierProviderBuilder setProvider(String providerName)
+ {
+ this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
+
+ return this;
+ }
+
+ public ContentVerifierProvider build(X509CertificateHolder certHolder)
+ throws OperatorCreationException, CertificateException
+ {
+ return build(helper.convertCertificate(certHolder));
+ }
+
+ public ContentVerifierProvider build(final X509Certificate certificate)
+ throws OperatorCreationException
+ {
+ final X509CertificateHolder certHolder;
+
+ try
+ {
+ certHolder = new JcaX509CertificateHolder(certificate);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new OperatorCreationException("cannot process certificate: " + e.getMessage(), e);
+ }
+
+ return new ContentVerifierProvider()
+ {
+ public boolean hasAssociatedCertificate()
+ {
+ return true;
+ }
+
+ public X509CertificateHolder getAssociatedCertificate()
+ {
+ return certHolder;
+ }
+
+ public ContentVerifier get(AlgorithmIdentifier algorithm)
+ throws OperatorCreationException
+ {
+ if (algorithm.getAlgorithm().equals(MiscObjectIdentifiers.id_alg_composite))
+ {
+ return createCompositeVerifier(algorithm, certificate.getPublicKey());
+ }
+ else
+ {
+ Signature sig;
+ try
+ {
+ sig = helper.createSignature(algorithm);
+
+ sig.initVerify(certificate.getPublicKey());
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("exception on setup: " + e, e);
+ }
+
+ Signature rawSig = createRawSig(algorithm, certificate.getPublicKey());
+
+ if (rawSig != null)
+ {
+ return new RawSigVerifier(algorithm, sig, rawSig);
+ }
+ else
+ {
+ return new SigVerifier(algorithm, sig);
+ }
+ }
+ }
+ };
+ }
+
+ public ContentVerifierProvider build(final PublicKey publicKey)
+ throws OperatorCreationException
+ {
+ return new ContentVerifierProvider()
+ {
+ public boolean hasAssociatedCertificate()
+ {
+ return false;
+ }
+
+ public X509CertificateHolder getAssociatedCertificate()
+ {
+ return null;
+ }
+
+ public ContentVerifier get(AlgorithmIdentifier algorithm)
+ throws OperatorCreationException
+ {
+ if (algorithm.getAlgorithm().equals(MiscObjectIdentifiers.id_alg_composite))
+ {
+ return createCompositeVerifier(algorithm, publicKey);
+ }
+
+ if (publicKey instanceof CompositePublicKey)
+ {
+ List<PublicKey> keys = ((CompositePublicKey)publicKey).getPublicKeys();
+
+ for (int i = 0; i != keys.size(); i++)
+ {
+ try
+ {
+ Signature sig = createSignature(algorithm, (PublicKey)keys.get(i));
+
+ Signature rawSig = createRawSig(algorithm, (PublicKey)keys.get(i));
+
+ if (rawSig != null)
+ {
+ return new RawSigVerifier(algorithm, sig, rawSig);
+ }
+ else
+ {
+ return new SigVerifier(algorithm, sig);
+ }
+ }
+ catch (OperatorCreationException e)
+ {
+ // skip incorrect keys
+ }
+ }
+
+ throw new OperatorCreationException("no matching algorithm found for key");
+ }
+ else
+ {
+ Signature sig = createSignature(algorithm, publicKey);
+
+ Signature rawSig = createRawSig(algorithm, publicKey);
+
+ if (rawSig != null)
+ {
+ return new RawSigVerifier(algorithm, sig, rawSig);
+ }
+ else
+ {
+ return new SigVerifier(algorithm, sig);
+ }
+ }
+ }
+ };
+ }
+
+ public ContentVerifierProvider build(SubjectPublicKeyInfo publicKey)
+ throws OperatorCreationException
+ {
+ return this.build(helper.convertPublicKey(publicKey));
+ }
+
+ private ContentVerifier createCompositeVerifier(AlgorithmIdentifier compAlgId, PublicKey publicKey)
+ throws OperatorCreationException
+ {
+ if (publicKey instanceof CompositePublicKey)
+ {
+ List<PublicKey> pubKeys = ((CompositePublicKey)publicKey).getPublicKeys();
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(compAlgId.getParameters());
+ Signature[] sigs = new Signature[keySeq.size()];
+ for (int i = 0; i != keySeq.size(); i++)
+ {
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ if (pubKeys.get(i) != null)
+ {
+ sigs[i] = createSignature(sigAlg, (PublicKey)pubKeys.get(i));
+ }
+ else
+ {
+ sigs[i] = null;
+ }
+ }
+
+ return new CompositeVerifier(sigs);
+ }
+ else
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(compAlgId.getParameters());
+ Signature[] sigs = new Signature[keySeq.size()];
+ for (int i = 0; i != keySeq.size(); i++)
+ {
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ try
+ {
+ sigs[i] = createSignature(sigAlg, publicKey);
+ }
+ catch (Exception e)
+ {
+ sigs[i] = null;
+ // continue
+ }
+ }
+
+ return new CompositeVerifier(sigs);
+ }
+ }
+
+ private Signature createSignature(AlgorithmIdentifier algorithm, PublicKey publicKey)
+ throws OperatorCreationException
+ {
+ try
+ {
+ Signature sig = helper.createSignature(algorithm);
+
+ sig.initVerify(publicKey);
+
+ return sig;
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("exception on setup: " + e, e);
+ }
+ }
+
+ private Signature createRawSig(AlgorithmIdentifier algorithm, PublicKey publicKey)
+ {
+ Signature rawSig;
+ try
+ {
+ rawSig = helper.createRawSignature(algorithm);
+
+ if (rawSig != null)
+ {
+ rawSig.initVerify(publicKey);
+ }
+ }
+ catch (Exception e)
+ {
+ rawSig = null;
+ }
+ return rawSig;
+ }
+
+ private class SigVerifier
+ implements ContentVerifier
+ {
+ private final AlgorithmIdentifier algorithm;
+ private final Signature signature;
+
+ protected final OutputStream stream;
+
+ SigVerifier(AlgorithmIdentifier algorithm, Signature signature)
+ {
+ this.algorithm = algorithm;
+ this.signature = signature;
+ this.stream = OutputStreamFactory.createStream(signature);
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithm;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ if (stream == null)
+ {
+ throw new IllegalStateException("verifier not initialised");
+ }
+
+ return stream;
+ }
+
+ public boolean verify(byte[] expected)
+ {
+ try
+ {
+ return signature.verify(expected);
+ }
+ catch (SignatureException e)
+ {
+ throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ private class RawSigVerifier
+ extends SigVerifier
+ implements RawContentVerifier
+ {
+ private Signature rawSignature;
+
+ RawSigVerifier(AlgorithmIdentifier algorithm, Signature standardSig, Signature rawSignature)
+ {
+ super(algorithm, standardSig);
+ this.rawSignature = rawSignature;
+ }
+
+ public boolean verify(byte[] expected)
+ {
+ try
+ {
+ return super.verify(expected);
+ }
+ finally
+ {
+ // we need to do this as in some PKCS11 implementations the session associated with the init of the
+ // raw signature will not be freed if verify is not called on it.
+ try
+ {
+ rawSignature.verify(expected);
+ }
+ catch (Exception e)
+ {
+ // ignore
+ }
+ }
+ }
+
+ public boolean verify(byte[] digest, byte[] expected)
+ {
+ try
+ {
+ rawSignature.update(digest);
+
+ return rawSignature.verify(expected);
+ }
+ catch (SignatureException e)
+ {
+ throw new RuntimeOperatorException("exception obtaining raw signature: " + e.getMessage(), e);
+ }
+ finally
+ {
+ // we need to do this as in some PKCS11 implementations the session associated with the init of the
+ // standard signature will not be freed if verify is not called on it.
+ try
+ {
+ rawSignature.verify(expected);
+ }
+ catch (Exception e)
+ {
+ // ignore
+ }
+ }
+ }
+ }
+
+ private class CompositeVerifier
+ implements ContentVerifier
+ {
+ private Signature[] sigs;
+ private OutputStream stream;
+
+ public CompositeVerifier(Signature[] sigs)
+ throws OperatorCreationException
+ {
+ this.sigs = sigs;
+
+ int start = 0;
+ while (start < sigs.length && sigs[start] == null)
+ {
+ start++;
+ }
+
+ if (start == sigs.length)
+ {
+ throw new OperatorCreationException("no matching signature found in composite");
+ }
+ this.stream = OutputStreamFactory.createStream(sigs[start]);
+ for (int i = start + 1; i != sigs.length; i++)
+ {
+ if (sigs[i] != null)
+ {
+ this.stream = new TeeOutputStream(this.stream, OutputStreamFactory.createStream(sigs[i]));
+ }
+ }
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite);
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return stream;
+ }
+
+ public boolean verify(byte[] expected)
+ {
+ try
+ {
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(expected);
+ boolean failed = false;
+ for (int i = 0; i != sigSeq.size(); i++)
+ {
+ if (sigs[i] != null)
+ {
+ if (!sigs[i].verify(DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes()))
+ {
+ failed = true;
+ }
+ }
+ }
+ return !failed;
+ }
+ catch (SignatureException e)
+ {
+ throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e);
+ }
+ }
+ }
+} \ No newline at end of file
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
new file mode 100644
index 00000000..862cbdc8
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java
@@ -0,0 +1,118 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator.jcajce;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.Provider;
+
+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.NamedJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
+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 JcaDigestCalculatorProviderBuilder
+{
+ private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
+
+ public JcaDigestCalculatorProviderBuilder()
+ {
+ }
+
+ public JcaDigestCalculatorProviderBuilder setProvider(Provider provider)
+ {
+ this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
+
+ return this;
+ }
+
+ public JcaDigestCalculatorProviderBuilder setProvider(String providerName)
+ {
+ this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
+
+ return this;
+ }
+
+ public DigestCalculatorProvider build()
+ throws OperatorCreationException
+ {
+ return new DigestCalculatorProvider()
+ {
+ public DigestCalculator get(final AlgorithmIdentifier algorithm)
+ throws OperatorCreationException
+ {
+ final DigestOutputStream stream;
+
+ try
+ {
+ MessageDigest dig = helper.createDigest(algorithm);
+
+ stream = new DigestOutputStream(dig);
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("exception on setup: " + e, e);
+ }
+
+ return new DigestCalculator()
+ {
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithm;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return stream;
+ }
+
+ public byte[] getDigest()
+ {
+ return stream.getDigest();
+ }
+ };
+ }
+ };
+ }
+
+ private class DigestOutputStream
+ extends OutputStream
+ {
+ private MessageDigest dig;
+
+ DigestOutputStream(MessageDigest dig)
+ {
+ this.dig = dig;
+ }
+
+ public void write(byte[] bytes, int off, int len)
+ throws IOException
+ {
+ dig.update(bytes, off, len);
+ }
+
+ public void write(byte[] bytes)
+ throws IOException
+ {
+ dig.update(bytes);
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ dig.update((byte)b);
+ }
+
+ byte[] getDigest()
+ {
+ return dig.digest();
+ }
+ }
+} \ No newline at end of file
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
new file mode 100644
index 00000000..63efaff6
--- /dev/null
+++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/OperatorHelper.java
@@ -0,0 +1,624 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.operator.jcajce;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PSSParameterSpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyAgreement;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+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.DERNull;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// 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 com.android.internal.org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
+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 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.OperatorCreationException;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+class OperatorHelper
+{
+ private static final Map oids = new HashMap();
+ private static final Map asymmetricWrapperAlgNames = new HashMap();
+ private static final Map symmetricWrapperAlgNames = new HashMap();
+ private static final Map symmetricKeyAlgNames = new HashMap();
+ private static final Map symmetricWrapperKeySizes = new HashMap();
+
+ 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");
+ oids.put(NISTObjectIdentifiers.id_sha256, "SHA256");
+ oids.put(NISTObjectIdentifiers.id_sha384, "SHA384");
+ oids.put(NISTObjectIdentifiers.id_sha512, "SHA512");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ oids.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD128");
+ oids.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160");
+ oids.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding");
+
+ // Android-removed: Unsupported algorithms
+ // asymmetricWrapperAlgNames.put(CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410");
+
+ symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWrap");
+ symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2Wrap");
+ symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes128_wrap, "AESWrap");
+ symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes192_wrap, "AESWrap");
+ symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes256_wrap, "AESWrap");
+ symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia128_wrap, "CamelliaWrap");
+ symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia192_wrap, "CamelliaWrap");
+ symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia256_wrap, "CamelliaWrap");
+ symmetricWrapperAlgNames.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, "SEEDWrap");
+ symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede");
+
+ symmetricWrapperKeySizes.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, Integers.valueOf(192));
+ symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes128_wrap, Integers.valueOf(128));
+ symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes192_wrap, Integers.valueOf(192));
+ symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes256_wrap, Integers.valueOf(256));
+ symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia128_wrap, Integers.valueOf(128));
+ symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia192_wrap, Integers.valueOf(192));
+ symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia256_wrap, Integers.valueOf(256));
+ symmetricWrapperKeySizes.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, Integers.valueOf(128));
+ symmetricWrapperKeySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC, Integers.valueOf(192));
+
+ symmetricKeyAlgNames.put(NISTObjectIdentifiers.aes, "AES");
+ symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes128_CBC, "AES");
+ symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes192_CBC, "AES");
+ symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes256_CBC, "AES");
+ symmetricKeyAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede");
+ symmetricKeyAlgNames.put(PKCSObjectIdentifiers.RC2_CBC, "RC2");
+ }
+
+ private JcaJceHelper helper;
+
+ OperatorHelper(JcaJceHelper helper)
+ {
+ this.helper = helper;
+ }
+
+ String getWrappingAlgorithmName(ASN1ObjectIdentifier algOid)
+ {
+ return (String)symmetricWrapperAlgNames.get(algOid);
+ }
+
+ int getKeySizeInBits(ASN1ObjectIdentifier algOid)
+ {
+ return ((Integer)symmetricWrapperKeySizes.get(algOid)).intValue();
+ }
+
+ KeyPairGenerator createKeyPairGenerator(ASN1ObjectIdentifier algorithm)
+ throws CMSException
+ {
+ try
+ {
+ String agreementName = null; //(String)BASE_CIPHER_NAMES.get(algorithm);
+
+ if (agreementName != null)
+ {
+ try
+ {
+ // this is reversed as the Sun policy files now allow unlimited strength RSA
+ return helper.createKeyPairGenerator(agreementName);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // Ignore
+ }
+ }
+ return helper.createKeyPairGenerator(algorithm.getId());
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new CMSException("cannot create key agreement: " + e.getMessage(), e);
+ }
+ }
+
+ Cipher createCipher(ASN1ObjectIdentifier algorithm)
+ throws OperatorCreationException
+ {
+ try
+ {
+ return helper.createCipher(algorithm.getId());
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e);
+ }
+ }
+
+ KeyAgreement createKeyAgreement(ASN1ObjectIdentifier algorithm)
+ throws OperatorCreationException
+ {
+ try
+ {
+ String agreementName = null; //(String)BASE_CIPHER_NAMES.get(algorithm);
+
+ if (agreementName != null)
+ {
+ try
+ {
+ // this is reversed as the Sun policy files now allow unlimited strength RSA
+ return helper.createKeyAgreement(agreementName);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // Ignore
+ }
+ }
+ return helper.createKeyAgreement(algorithm.getId());
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("cannot create key agreement: " + e.getMessage(), e);
+ }
+ }
+
+ Cipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm, Map extraAlgNames)
+ throws OperatorCreationException
+ {
+ try
+ {
+ String cipherName = null;
+
+ if (!extraAlgNames.isEmpty())
+ {
+ cipherName = (String)extraAlgNames.get(algorithm);
+ }
+
+ if (cipherName == null)
+ {
+ cipherName = (String)asymmetricWrapperAlgNames.get(algorithm);
+ }
+
+ if (cipherName != null)
+ {
+ try
+ {
+ // this is reversed as the Sun policy files now allow unlimited strength RSA
+ return helper.createCipher(cipherName);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // try alternate for RSA
+ if (cipherName.equals("RSA/ECB/PKCS1Padding"))
+ {
+ try
+ {
+ return helper.createCipher("RSA/NONE/PKCS1Padding");
+ }
+ catch (NoSuchAlgorithmException ex)
+ {
+ // Ignore
+ }
+ }
+ // Ignore
+ }
+ }
+
+ return helper.createCipher(algorithm.getId());
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e);
+ }
+ }
+
+ Cipher createSymmetricWrapper(ASN1ObjectIdentifier algorithm)
+ throws OperatorCreationException
+ {
+ try
+ {
+ String cipherName = (String)symmetricWrapperAlgNames.get(algorithm);
+
+ if (cipherName != null)
+ {
+ try
+ {
+ // this is reversed as the Sun policy files now allow unlimited strength RSA
+ return helper.createCipher(cipherName);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // Ignore
+ }
+ }
+ return helper.createCipher(algorithm.getId());
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e);
+ }
+ }
+
+ AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
+ throws OperatorCreationException
+ {
+ AlgorithmParameters parameters;
+
+ if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
+ {
+ return null;
+ }
+
+ 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
+ {
+ parameters.init(cipherAlgId.getParameters().toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot initialise algorithm parameters: " + e.getMessage(), e);
+ }
+
+ return parameters;
+ }
+
+ MessageDigest createDigest(AlgorithmIdentifier digAlgId)
+ throws GeneralSecurityException
+ {
+ MessageDigest dig;
+
+ try
+ {
+ if (digAlgId.getAlgorithm().equals(NISTObjectIdentifiers.id_shake256_len))
+ {
+ dig = helper.createMessageDigest("SHAKE256-" + ASN1Integer.getInstance(digAlgId.getParameters()).getValue());
+ }
+ else
+ {
+ dig = helper.createMessageDigest(MessageDigestUtils.getDigestName(digAlgId.getAlgorithm()));
+ }
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ //
+ // try an alternate
+ //
+ if (oids.get(digAlgId.getAlgorithm()) != null)
+ {
+ String digestAlgorithm = (String)oids.get(digAlgId.getAlgorithm());
+
+ dig = helper.createMessageDigest(digestAlgorithm);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+
+ return dig;
+ }
+
+ Signature createSignature(AlgorithmIdentifier sigAlgId)
+ throws GeneralSecurityException
+ {
+ String sigName = getSignatureName(sigAlgId);
+ Signature sig;
+
+ try
+ {
+ sig = helper.createSignature(sigName);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ //
+ // try an alternate
+ //
+ if (sigName.endsWith("WITHRSAANDMGF1"))
+ {
+ String signatureAlgorithm =
+ sigName.substring(0, sigName.indexOf('W')) + "WITHRSASSA-PSS";
+
+ 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;
+ }
+ }
+
+ if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(sigAlgId.getParameters());
+
+ if (notDefaultPSSParams(seq))
+ {
+ try
+ {
+ AlgorithmParameters algParams = helper.createAlgorithmParameters("PSS");
+
+ algParams.init(seq.getEncoded());
+
+ sig.setParameter(algParams.getParameterSpec(PSSParameterSpec.class));
+ }
+ catch (IOException e)
+ {
+ throw new GeneralSecurityException("unable to process PSS parameters: " + e.getMessage());
+ }
+ }
+ }
+
+ return sig;
+ }
+
+ public Signature createRawSignature(AlgorithmIdentifier algorithm)
+ {
+ Signature sig;
+
+ try
+ {
+ String algName = getSignatureName(algorithm);
+
+ algName = "NONE" + algName.substring(algName.indexOf("WITH"));
+
+ sig = helper.createSignature(algName);
+
+ // RFC 4056
+ // When the id-RSASSA-PSS algorithm identifier is used for a signature,
+ // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params.
+ if (algorithm.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ AlgorithmParameters params = helper.createAlgorithmParameters(algName);
+
+ AlgorithmParametersUtils.loadParameters(params, algorithm.getParameters());
+
+ PSSParameterSpec spec = (PSSParameterSpec)params.getParameterSpec(PSSParameterSpec.class);
+ sig.setParameter(spec);
+ }
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+
+ return sig;
+ }
+
+ 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();
+ }
+
+ // we need to remove the - to create a correct signature name
+ private static String getDigestName(ASN1ObjectIdentifier oid)
+ {
+ String name = MessageDigestUtils.getDigestName(oid);
+
+ int dIndex = name.indexOf('-');
+ if (dIndex > 0 && !name.startsWith("SHA3"))
+ {
+ return name.substring(0, dIndex) + name.substring(dIndex + 1);
+ }
+
+ return name;
+ }
+
+ public X509Certificate convertCertificate(X509CertificateHolder certHolder)
+ throws CertificateException
+ {
+ try
+ {
+ CertificateFactory certFact = helper.createCertificateFactory("X.509");
+
+ return (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(certHolder.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new OpCertificateException("cannot get encoded form of certificate: " + e.getMessage(), e);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OpCertificateException("cannot find factory provider: " + e.getMessage(), e);
+ }
+ }
+
+ public PublicKey convertPublicKey(SubjectPublicKeyInfo publicKeyInfo)
+ throws OperatorCreationException
+ {
+ try
+ {
+ KeyFactory keyFact = helper.createKeyFactory(publicKeyInfo.getAlgorithm().getAlgorithm().getId());
+
+ return keyFact.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot get encoded form of key: " + e.getMessage(), e);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot find factory provider: " + e.getMessage(), e);
+ }
+ catch (InvalidKeySpecException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
+ }
+ }
+
+ // TODO: put somewhere public so cause easily accessed
+ private static class OpCertificateException
+ extends CertificateException
+ {
+ private Throwable cause;
+
+ public OpCertificateException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
+
+ String getKeyAlgorithmName(ASN1ObjectIdentifier oid)
+ {
+
+ String name = (String)symmetricKeyAlgNames.get(oid);
+
+ if (name != null)
+ {
+ return name;
+ }
+
+ return oid.getId();
+ }
+
+ // for our purposes default includes varient digest with salt the same size as digest
+ private boolean notDefaultPSSParams(ASN1Sequence seq)
+ throws GeneralSecurityException
+ {
+ if (seq == null || seq.size() == 0)
+ {
+ return false;
+ }
+
+ RSASSAPSSparams pssParams = RSASSAPSSparams.getInstance(seq);
+
+ if (!pssParams.getMaskGenAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1))
+ {
+ return true;
+ }
+
+ // same digest for sig and MGF1
+ if (!pssParams.getHashAlgorithm().equals(AlgorithmIdentifier.getInstance(pssParams.getMaskGenAlgorithm().getParameters())))
+ {
+ return true;
+ }
+
+ MessageDigest digest = createDigest(pssParams.getHashAlgorithm());
+
+ return pssParams.getSaltLength().intValue() != digest.getDigestLength();
+ }
+}
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 7eaf8ac8..50417c7a 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
@@ -961,56 +961,26 @@ public class BaseBlockCipher
{
byte[] iv = new byte[ivLength];
- // BEGIN Android-changed: For PBE keys with no IV, log and use IV of 0
+ // BEGIN Android-changed: Reject PBE keys with no IV
// These keys were accepted in BC 1.52 (and treated as having an IV of 0) but
- // rejected outright in BC 1.54 (even if an IV was passed in params). We
- // want the eventual state to be that an IV can be passed in params, but the key
- // is rejected otherwise. For now, log that these will be rejected in a future
- // release. See b/27995180 for historical details.
- // ivRandom.nextBytes(iv);
+ // rejected outright in BC 1.54 (even if an IV was passed in params).
+ // See b/27995180 for historical details.
if (!isBCPBEKeyWithoutIV(key)) {
ivRandom.nextBytes(iv);
} else {
- // TODO(b/70275132): Change to rejecting these keys
- System.err.println(" ******** DEPRECATED FUNCTIONALITY ********");
- System.err.println(" * You have initialized a cipher with a PBE key with no IV and");
- System.err.println(" * have not provided an IV in the AlgorithmParameterSpec. This");
- System.err.println(" * configuration is deprecated. The cipher will be initialized");
- System.err.println(" * with an all-zero IV, but in a future release this call will");
- System.err.println(" * throw an exception.");
- new InvalidAlgorithmParameterException("No IV set when using PBE key")
- .printStackTrace(System.err);
+ throw new InvalidAlgorithmParameterException("No IV set when using PBE key");
}
- // END Android-changed: For PBE keys with no IV, log and use IV of 0
+ // END Android-changed: Reject PBE keys with no IV
param = new ParametersWithIV(param, iv);
ivParam = (ParametersWithIV)param;
}
else if (cipher.getUnderlyingCipher().getAlgorithmName().indexOf("PGPCFB") < 0)
{
- // BEGIN Android-changed: For PBE keys with no IV, log and use IV of 0
+ // BEGIN Android-changed: Reject PBE keys with no IV
// These keys were accepted in BC 1.52 (and treated as having an IV of 0) but
- // rejected outright in BC 1.54 (even if an IV was passed in params). We
- // want the eventual state to be that an IV can be passed in params, but the key
- // is rejected otherwise. For now, log that these will be rejected in a future
- // release. See b/27995180 for historical details.
- // throw new InvalidAlgorithmParameterException("no IV set when one expected");
- if (!isBCPBEKeyWithoutIV(key)) {
- throw new InvalidAlgorithmParameterException("no IV set when one expected");
- } else {
- // TODO(b/70275132): Change to rejecting these keys
- System.err.println(" ******** DEPRECATED FUNCTIONALITY ********");
- System.err.println(" * You have initialized a cipher with a PBE key with no IV and");
- System.err.println(" * have not provided an IV in the AlgorithmParameterSpec. This");
- System.err.println(" * configuration is deprecated. The cipher will be initialized");
- System.err.println(" * with an all-zero IV, but in a future release this call will");
- System.err.println(" * throw an exception.");
- new InvalidAlgorithmParameterException("No IV set when using PBE key")
- .printStackTrace(System.err);
- // Mimic behaviour in 1.52 by using an IV of 0's
- param = new ParametersWithIV(param, new byte[ivLength]);
- ivParam = (ParametersWithIV)param;
- }
- // END Android-changed: For PBE keys with no IV, log and use IV of 0
+ // rejected outright in BC 1.54 (even if an IV was passed in params).
+ throw new InvalidAlgorithmParameterException("No IV set when using PBE key");
+ // END Android-changed: Reject PBE keys with no IV
}
}
diff --git a/srcgen_platform/generate_android_src.sh b/srcgen_platform/generate_android_src.sh
index 6e5b4447..616ab716 100755
--- a/srcgen_platform/generate_android_src.sh
+++ b/srcgen_platform/generate_android_src.sh
@@ -26,6 +26,7 @@ PACKAGE_TRANSFORMATIONS="\
MODULE_DIRS="\
bcprov \
+ bcpkix \
"
DEFAULT_CONSTRUCTORS_FILE=${BOUNCY_CASTLE_DIR}/srcgen/default-constructors.txt
@@ -42,4 +43,7 @@ source ${ANDROID_BUILD_TOP}/tools/currysrc/scripts/repackage-common.sh
# Remove some unused source files:
rm -fr ${REPACKAGED_DIR}/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ocsp/
-
+rm -fr ${REPACKAGED_DIR}/bcpkix/src/main/java/com/android/org/bouncycastle/cert/ocsp/
+rm -fr ${REPACKAGED_DIR}/bcpkix/src/main/java/com/android/org/bouncycastle/cmc/
+rm -fr ${REPACKAGED_DIR}/bcpkix/src/main/java/com/android/org/bouncycastle/openssl/
+rm -fr ${REPACKAGED_DIR}/bcpkix/src/main/java/com/android/org/bouncycastle/pkix/