From 7577539bc1caf2ed8e0c3155129458bc4ed59e9a Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 29 Jun 2022 13:35:10 -0700 Subject: Downgrade SuspiciousIndentation lint to a warning Bug: 236431222 Test: Presubmits Change-Id: Ie8da1252fca58dadf076106cc5e2ee5f97079c3f --- Android.bp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Android.bp b/Android.bp index 5ac17917..241a75c7 100644 --- a/Android.bp +++ b/Android.bp @@ -72,6 +72,10 @@ java_defaults { }, }, }, + + lint: { + warning_checks: ["SuspiciousIndentation"], + }, } // The src files for bouncycastle, used to generate core platform / intra-core @@ -275,4 +279,7 @@ java_library { "bcprov/src/main/java/org/bouncycastle/iana/**/*.java", ], sdk_version: "core_current", + lint: { + warning_checks: ["SuspiciousIndentation"], + }, } -- cgit v1.2.3 From 578e14e95b4ed90b2bb27a9ccf5a4bdb99434a90 Mon Sep 17 00:00:00 2001 From: Rex Hoffman Date: Thu, 25 Aug 2022 22:15:35 +0000 Subject: Enable new_robolectric Test: mma in /external/robolectric Bug: 244627502 Change-Id: Ia7151517ef492b1747acbb7b14d055b3ccba3b34 --- Android.bp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Android.bp b/Android.bp index 241a75c7..f91813ed 100644 --- a/Android.bp +++ b/Android.bp @@ -151,6 +151,10 @@ unbundled_visibility = [ "//external/robolectric-shadows/robolectric", "//external/robolectric-shadows/shadows/supportv4", "//external/robolectric-shadows/shadows/httpclient", + "//external/robolectric", + "//external/robolectric/robolectric", + "//external/robolectric/shadows/supportv4", + "//external/robolectric/shadows/httpclient", "//external/wycheproof", "//frameworks/opt/net/wifi/service", "//frameworks/opt/net/wifi/tests/wifitests", -- cgit v1.2.3 From bfa7e4274d491ec5961a73b5bad5a70a62741955 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Sat, 15 Oct 2022 21:33:29 -0700 Subject: Fix errorprone warnings that should be errors This commit is part of a large scale change to fix errorprone errors that have been downgraded to warnings in the android source tree, so that they can be promoted to errors again. The full list of changes include the following, but not all will be present in any one individual commit: BadAnnotationImplementation BadShiftAmount BanJNDI BoxedPrimitiveEquality ComparableType ComplexBooleanConstant CollectionToArraySafeParameter ConditionalExpressionNumericPromotion DangerousLiteralNull DoubleBraceInitialization DurationFrom DurationTemporalUnit EmptyTopLevelDeclaration EqualsNull EqualsReference FormatString FromTemporalAccessor GetClassOnAnnotation GetClassOnClass HashtableContains IdentityBinaryExpression IdentityHashMapBoxing InstantTemporalUnit InvalidTimeZoneID InvalidZoneId IsInstanceIncompatibleType JUnitParameterMethodNotFound LockOnBoxedPrimitive MathRoundIntLong MislabeledAndroidString MisusedDayOfYear MissingSuperCall MisusedWeekYear ModifyingCollectionWithItself NoCanIgnoreReturnValueOnClasses NonRuntimeAnnotation NullableOnContainingClass NullTernary OverridesJavaxInjectableMethod ParcelableCreator PeriodFrom PreconditionsInvalidPlaceholder ProtoBuilderReturnValueIgnored ProtoFieldNullComparison RandomModInteger RectIntersectReturnValueIgnored ReturnValueIgnored SelfAssignment SelfComparison SelfEquals SizeGreaterThanOrEqualsZero StringBuilderInitWithChar TreeToString TryFailThrowable UnnecessaryCheckNotNull UnusedCollectionModifiedInPlace XorPower See https://errorprone.info/bugpatterns for more information on the checks. Bug: 253827323 Test: m RUN_ERROR_PRONE=true javac-check Change-Id: I5e8cfbbb015932c5ff0040d5effe70e0c88dc1b4 --- Android.bp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Android.bp b/Android.bp index 241a75c7..1cee7843 100644 --- a/Android.bp +++ b/Android.bp @@ -76,6 +76,13 @@ 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 -- cgit v1.2.3 From 9893a6d93de1971e69a2cc4ffd3e1848fdf99f0a Mon Sep 17 00:00:00 2001 From: Victor Hsieh Date: Mon, 17 Oct 2022 14:00:19 -0700 Subject: Add more files to bouncycastle-repackaged-unbundled This changes adds more snapshot from the bouncycastle/bcpkix to repackaged_platform. The motivation is to support PKCS#7/CMS signature verification in the system server, without introducing any new API across updatable interfaces. Bug: 253668864 Test: Use the code in system server to verify a PKCS#7 signature Change-Id: I7d2de128a2b6514b56ac9affc3c60b33b8f64e32 --- Android.bp | 5 +- .../cert/AttributeCertificateHolder.java | 374 ++++++++++ .../cert/AttributeCertificateIssuer.java | 149 ++++ .../org/bouncycastle/cert/CertException.java | 29 + .../org/bouncycastle/cert/CertIOException.java | 31 + .../internal/org/bouncycastle/cert/CertUtils.java | 330 +++++++++ .../cert/X509AttributeCertificateHolder.java | 394 +++++++++++ .../org/bouncycastle/cert/X509CRLEntryHolder.java | 146 ++++ .../org/bouncycastle/cert/X509CRLHolder.java | 370 ++++++++++ .../bouncycastle/cert/X509CertificateHolder.java | 355 ++++++++++ .../cert/X509v3CertificateBuilder.java | 423 ++++++++++++ .../org/bouncycastle/cert/jcajce/JcaCertStore.java | 66 ++ .../cert/jcajce/JcaX509CertificateHolder.java | 28 + .../cert/selector/MSOutlookKeyIdCalculator.java | 423 ++++++++++++ .../selector/X509CertificateHolderSelector.java | 154 +++++ .../org/bouncycastle/cms/CMSAbsentContent.java | 51 ++ .../cms/CMSAttributeTableGenerationException.java | 36 + .../cms/CMSAttributeTableGenerator.java | 23 + .../org/bouncycastle/cms/CMSException.java | 36 + .../org/bouncycastle/cms/CMSProcessable.java | 23 + .../bouncycastle/cms/CMSProcessableByteArray.java | 57 ++ .../internal/org/bouncycastle/cms/CMSReadable.java | 11 + .../org/bouncycastle/cms/CMSRuntimeException.java | 36 + .../cms/CMSSignatureAlgorithmNameGenerator.java | 19 + .../cms/CMSSignatureEncryptionAlgorithmFinder.java | 19 + .../org/bouncycastle/cms/CMSSignedData.java | 636 +++++++++++++++++ .../bouncycastle/cms/CMSSignedDataGenerator.java | 234 +++++++ .../org/bouncycastle/cms/CMSSignedGenerator.java | 256 +++++++ .../org/bouncycastle/cms/CMSSignedHelper.java | 272 ++++++++ .../cms/CMSSignerDigestMismatchException.java | 15 + .../org/bouncycastle/cms/CMSTypedData.java | 13 + .../internal/org/bouncycastle/cms/CMSUtils.java | 396 +++++++++++ .../CMSVerifierCertificateNotValidException.java | 15 + .../DefaultCMSSignatureAlgorithmNameGenerator.java | 249 +++++++ ...faultCMSSignatureEncryptionAlgorithmFinder.java | 75 ++ .../cms/DefaultSignedAttributeTableGenerator.java | 133 ++++ .../org/bouncycastle/cms/NullOutputStream.java | 29 + .../bouncycastle/cms/PKCS7ProcessableObject.java | 69 ++ .../org/bouncycastle/cms/PasswordRecipient.java | 54 ++ .../internal/org/bouncycastle/cms/Recipient.java | 9 + .../org/bouncycastle/cms/RecipientOperator.java | 64 ++ .../internal/org/bouncycastle/cms/SignerId.java | 106 +++ .../org/bouncycastle/cms/SignerInfoGenerator.java | 312 +++++++++ .../cms/SignerInfoGeneratorBuilder.java | 142 ++++ .../org/bouncycastle/cms/SignerInformation.java | 760 +++++++++++++++++++++ .../bouncycastle/cms/SignerInformationStore.java | 145 ++++ .../cms/SignerInformationVerifier.java | 55 ++ .../cms/SimpleAttributeTableGenerator.java | 27 + .../cms/jcajce/JcaSignerInfoGeneratorBuilder.java | 90 +++ .../cms/jcajce/JcaSignerInfoVerifierBuilder.java | 184 +++++ .../jcajce/JcaSimpleSignerInfoVerifierBuilder.java | 154 +++++ .../org/bouncycastle/operator/ContentSigner.java | 39 ++ .../org/bouncycastle/operator/ContentVerifier.java | 40 ++ .../operator/ContentVerifierProvider.java | 36 + .../DefaultDigestAlgorithmIdentifierFinder.java | 203 ++++++ .../DefaultSignatureAlgorithmIdentifierFinder.java | 451 ++++++++++++ .../operator/DigestAlgorithmIdentifierFinder.java | 28 + .../bouncycastle/operator/DigestCalculator.java | 38 ++ .../operator/DigestCalculatorProvider.java | 14 + .../org/bouncycastle/operator/GenericKey.java | 45 ++ .../org/bouncycastle/operator/InputDecryptor.java | 31 + .../org/bouncycastle/operator/MacCalculator.java | 40 ++ .../operator/OperatorCreationException.java | 19 + .../bouncycastle/operator/OperatorException.java | 28 + .../operator/OperatorStreamException.java | 25 + .../bouncycastle/operator/RawContentVerifier.java | 19 + .../operator/RuntimeOperatorException.java | 28 + .../SignatureAlgorithmIdentifierFinder.java | 19 + .../operator/bc/BcDefaultDigestProvider.java | 185 +++++ .../operator/bc/BcDigestCalculatorProvider.java | 84 +++ .../bouncycastle/operator/bc/BcDigestProvider.java | 15 + .../operator/jcajce/JcaContentSignerBuilder.java | 278 ++++++++ .../jcajce/JcaContentVerifierProviderBuilder.java | 454 ++++++++++++ .../jcajce/JcaDigestCalculatorProviderBuilder.java | 118 ++++ .../operator/jcajce/OperatorHelper.java | 624 +++++++++++++++++ srcgen_platform/generate_android_src.sh | 6 +- 76 files changed, 10947 insertions(+), 2 deletions(-) create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateHolder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/AttributeCertificateIssuer.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertException.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertIOException.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/CertUtils.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509AttributeCertificateHolder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLEntryHolder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CRLHolder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509CertificateHolder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/X509v3CertificateBuilder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/jcajce/JcaCertStore.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/jcajce/JcaX509CertificateHolder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/selector/MSOutlookKeyIdCalculator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAbsentContent.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerationException.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSException.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessable.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessableByteArray.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSReadable.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSRuntimeException.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedData.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedDataGenerator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedGenerator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedHelper.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignerDigestMismatchException.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSTypedData.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSUtils.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/NullOutputStream.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PKCS7ProcessableObject.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PasswordRecipient.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/Recipient.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/RecipientOperator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerId.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGenerator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformation.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationStore.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationVerifier.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SimpleAttributeTableGenerator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentSigner.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentVerifier.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/ContentVerifierProvider.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestCalculator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/DigestCalculatorProvider.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/GenericKey.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/InputDecryptor.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/MacCalculator.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorCreationException.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorException.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/OperatorStreamException.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/RawContentVerifier.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/RuntimeOperatorException.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/SignatureAlgorithmIdentifierFinder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/bc/BcDigestProvider.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java create mode 100644 repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/OperatorHelper.java diff --git a/Android.bp b/Android.bp index 241a75c7..97de7d51 100644 --- a/Android.bp +++ b/Android.bp @@ -134,7 +134,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 = [ 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. + * + *
+ *          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
+ *          }
+ * 
+ *

+ * Note: If objectDigestInfo comparisons are to be carried out the static + * method setDigestCalculatorProvider must be called once to configure the class + * to do the necessary calculations. + *

+ * @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. + *

+ * digestedObjectType can be one of the following: + *

    + *
  • 0 - publicKey - A hash of the public key of the holder must be + * passed. + *
  • 1 - publicKeyCert - A hash of the public key certificate of the + * holder must be passed. + *
  • 2 - otherObjectDigest - A hash of some other object type must be + * passed. otherObjectTypeID must not be empty. + *
+ *

+ * 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 + * digestedObjectType is + * otherObjectDigest. + * @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. + *

+ *

    + *
  • 0 - publicKey - A hash of the public key of the holder must be + * passed. + *
  • 1 - publicKeyCert - A hash of the public key certificate of the + * holder must be passed. + *
  • 2 - otherObjectDigest - A hash of some other object type must be + * passed. otherObjectTypeID must not be empty. + *
+ * + * @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 null 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 null 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 null 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. + *

+ * 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. + *

+ * + * @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. + *

+ * The class will convert X509Certificate objects into X509CertificateHolder objects. + *

+ * @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. + *

+ * 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... + * + *

+ *  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++;
+ *      }   
+ *  }
+ * 
+ * @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 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 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 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 getDigestAlgorithmIDs() + { + Set digests = new HashSet(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. + *

+ * A simple example of usage, generating a detached signature. + * + *

+ *      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);
+ * 
+ * @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 des = new HashSet(); + 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 +{ + 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 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 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 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 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 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 algorithmNames = compSpec.getAlgorithmNames(); + List 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 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 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/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/ -- cgit v1.2.3 From 5437c1f8ce377268472fa93adc65ed1b4ff69bb9 Mon Sep 17 00:00:00 2001 From: Orion Hodson Date: Tue, 25 Oct 2022 15:37:43 +0100 Subject: Extend the visibility of bouncycastle to all of libcore Required for some blueprint file re-structuring in libcore. Bug: 255273691 Test: m Change-Id: Id5fcff21cf6641adcbab8cafad6d4dc03e25e377 --- Android.bp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Android.bp b/Android.bp index ebbc6360..4eb2cee1 100644 --- a/Android.bp +++ b/Android.bp @@ -98,7 +98,7 @@ java_library { "//art/build/apex", "//art/build/sdk", "//external/wycheproof", - "//libcore", + "//libcore:__subpackages__", "//packages/modules/ArtPrebuilt", ], apex_available: [ -- cgit v1.2.3 From a8fb6b7b6c8cf8ad9d5a18020d52207ee1383e8b Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Tue, 22 Nov 2022 10:04:25 -0800 Subject: Allow rkpdapp tests to link bouncycastle-unbundled rkpdapp is a port of the RemoteProvisioner application from a system app into a mainline module. As such, we need to include rkpdapp's tests in the bouncycastle-unbundled visibilility as we did for RemoteProvisioner. Test: atest RkpdAppUnitTests Bug: 260101178 Change-Id: I2ddf4ebe3dff566255482805d8e401d8480a04a7 --- Android.bp | 1 + 1 file changed, 1 insertion(+) diff --git a/Android.bp b/Android.bp index 6e31737e..f9b91d8c 100644 --- a/Android.bp +++ b/Android.bp @@ -172,6 +172,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", -- cgit v1.2.3 From 4354b52d33effed936d027b3a94297abc49cc82d Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Wed, 14 Dec 2022 15:27:09 +0000 Subject: Add lib used for UWB. Bug: 200678121 Test: build and atest com.android.server.uwb Change-Id: I740f4501e6dadb0236ea71a0d2cb87c9c2e071cd --- Android.bp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Android.bp b/Android.bp index f9b91d8c..b6deb323 100644 --- a/Android.bp +++ b/Android.bp @@ -298,3 +298,28 @@ java_library { warning_checks: ["SuspiciousIndentation"], }, } + +// Bouncycastle for use by packages/modules/Uwb project. +// +//Excludes directories not needed. +java_library { + name: "bouncycastle-uwb", + visibility: [ + "//packages/modules/Uwb/service", + ], + apex_available: [ + "com.android.uwb", + ], + srcs: [ + "bcprov/src/main/java/org/bouncycastle/**/*.java", + "bcpkix/src/main/java/org/bouncycastle/cert/**/*.java", + "bcpkix/src/main/java/org/bouncycastle/cms/**/*.java", + "bcpkix/src/main/java/org/bouncycastle/operator/**/*.java", + ], + + exclude_srcs: [ + "bcprov/src/main/java/org/bouncycastle/iana/**/*.java", + "bcprov/src/main/java/org/bouncycastle/its/**/*.java", + ], + sdk_version: "core_current", +} -- cgit v1.2.3 From d5f5eeb432618575f92d6319b87691792dde6660 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Thu, 15 Dec 2022 23:41:51 +0000 Subject: Downgrade SuspiciousIndentation lint to a warning for uwb module. Bug: 200678121 Test: Build Change-Id: Icb953c649ae56e4ab62dbd98e01f6146ef9d2fc2 --- Android.bp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Android.bp b/Android.bp index b6deb323..00ee0935 100644 --- a/Android.bp +++ b/Android.bp @@ -322,4 +322,7 @@ java_library { "bcprov/src/main/java/org/bouncycastle/its/**/*.java", ], sdk_version: "core_current", + lint: { + warning_checks: ["SuspiciousIndentation"], + }, } -- cgit v1.2.3 From 4fae1c6cb82e4b3e7d51e38ce0e3d7a4f22a0939 Mon Sep 17 00:00:00 2001 From: Pete Bentley Date: Mon, 9 Jan 2023 15:21:28 +0000 Subject: Bouncy Castle: Add support for PBES2 encrypted KeyStores. Adds a private sub-Provider to BouncyCastleProvider which allows BC's PKCS12 implementation to conintue using its own implementations of some Macs and Ciphers which support PBES2. These implementions are not exposed to apps and are only used from BC internals. Bug: 230750823 Test: atest CtsLibcoreTestCases:tests.targets.security.KeyStorePkcs7FormatTest Change-Id: Ic505d0259d16cdc66f9776e818efa20ed97aa32b --- .../provider/config/ConfigurableProvider.java | 7 ++++ .../jcajce/provider/digest/SHA224.java | 2 + .../jcajce/provider/digest/SHA256.java | 2 + .../jcajce/provider/digest/SHA384.java | 2 + .../jcajce/provider/digest/SHA512.java | 2 + .../keystore/pkcs12/PKCS12KeyStoreSpi.java | 17 ++++++-- .../jcajce/provider/symmetric/AES.java | 5 +++ .../jcajce/provider/symmetric/PBEPBKDF2.java | 17 ++++---- .../bouncycastle/jcajce/util/BCJcaJceHelper.java | 46 ++++++++++++++++++++++ .../jce/provider/BouncyCastleProvider.java | 33 ++++++++++++++++ .../provider/config/ConfigurableProvider.java | 7 ++++ .../jcajce/provider/digest/SHA224.java | 2 + .../jcajce/provider/digest/SHA256.java | 2 + .../jcajce/provider/digest/SHA384.java | 2 + .../jcajce/provider/digest/SHA512.java | 2 + .../keystore/pkcs12/PKCS12KeyStoreSpi.java | 17 ++++++-- .../jcajce/provider/symmetric/AES.java | 5 +++ .../jcajce/provider/symmetric/PBEPBKDF2.java | 23 ++++++----- .../bouncycastle/jcajce/util/BCJcaJceHelper.java | 46 ++++++++++++++++++++++ .../jce/provider/BouncyCastleProvider.java | 33 ++++++++++++++++ .../provider/config/ConfigurableProvider.java | 7 ++++ .../jcajce/provider/digest/SHA224.java | 2 + .../jcajce/provider/digest/SHA256.java | 2 + .../jcajce/provider/digest/SHA384.java | 2 + .../jcajce/provider/digest/SHA512.java | 2 + .../keystore/pkcs12/PKCS12KeyStoreSpi.java | 17 ++++++-- .../jcajce/provider/symmetric/AES.java | 5 +++ .../jcajce/provider/symmetric/PBEPBKDF2.java | 23 ++++++----- .../bouncycastle/jcajce/util/BCJcaJceHelper.java | 46 ++++++++++++++++++++++ .../jce/provider/BouncyCastleProvider.java | 33 ++++++++++++++++ 30 files changed, 372 insertions(+), 39 deletions(-) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java index 9818f864..831b497e 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java @@ -54,4 +54,11 @@ public interface ConfigurableProvider AsymmetricKeyInfoConverter getKeyInfoConverter(ASN1ObjectIdentifier oid); void addAttributes(String key, Map attributeMap); + + // BEGIN Android-added: Allow algorithms to be added privately. + // See BouncyCastleProvider for details. + void addPrivateAlgorithm(String key, String value); + + void addPrivateAlgorithm(String type, ASN1ObjectIdentifier oid, String className); + // END Android-added: Allow algorithms to be added privately. } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA224.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA224.java index 5c6b699d..dd25b0c4 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA224.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA224.java @@ -76,6 +76,8 @@ public class SHA224 addHMACAlias(provider, "SHA224", PKCSObjectIdentifiers.id_hmacWithSHA224); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha224, PREFIX + "$HashMac"); } } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java index 48f99b4d..ae4c82fd 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java @@ -101,6 +101,8 @@ public class SHA256 addHMACAlias(provider, "SHA256", NISTObjectIdentifiers.id_sha256); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha256, PREFIX + "$HashMac"); } } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA384.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA384.java index 8f083748..b5f269ee 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA384.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA384.java @@ -95,6 +95,8 @@ public class SHA384 addHMACAlias(provider, "SHA384", PKCSObjectIdentifiers.id_hmacWithSHA384); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha384, PREFIX + "$HashMac"); } } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java index e227620e..335d0d60 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java @@ -193,6 +193,8 @@ public class SHA512 addHMACAlgorithm(provider, "SHA512/256", PREFIX + "$HashMacT256", PREFIX + "$KeyGeneratorT256"); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha512, PREFIX + "$HashMac"); } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java index 4c3e480d..263c63d2 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java @@ -116,9 +116,12 @@ public class PKCS12KeyStoreSpi { static final String PKCS12_MAX_IT_COUNT_PROPERTY = "org.bouncycastle.pkcs12.max_it_count"; - // Android-changed: Use default provider for JCA algorithms instead of BC + // Android-changed: Use default provider for most JCA algorithms instead of BC. + // For the case where we need BC implementations, the BCJcaJceHelper will also search + // the list of private implementations help by BouncyCastleProvider. // Was: private final JcaJceHelper helper = new BCJcaJceHelper(); private final JcaJceHelper helper = new DefaultJcaJceHelper(); + private final JcaJceHelper selfHelper = new BCJcaJceHelper(); private static final int SALT_SIZE = 20; private static final int MIN_ITERATIONS = 50 * 1024; @@ -727,7 +730,9 @@ public class PKCS12KeyStoreSpi PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters()); AlgorithmIdentifier encScheme = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme()); - SecretKeyFactory keyFact = helper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId()); + // Android-Changed: SecretKeyFactory must be from BC due to instanceof logic. + // SecretKeyFactory keyFact = helper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId()); + SecretKeyFactory keyFact = selfHelper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId()); SecretKey key; if (func.isDefaultPrf()) @@ -739,7 +744,9 @@ public class PKCS12KeyStoreSpi key = keyFact.generateSecret(new PBKDF2KeySpec(password, func.getSalt(), validateIterationCount(func.getIterationCount()), keySizeProvider.getKeySize(encScheme), func.getPrf())); } - Cipher cipher = Cipher.getInstance(alg.getEncryptionScheme().getAlgorithm().getId()); + // Android-Changed: Cipher must be from BC due to use of internal PKCS12Key tyoe. + // Cipher cipher = Cipher.getInstance(alg.getEncryptionScheme().getAlgorithm().getId()); + Cipher cipher = selfHelper.createCipher(alg.getEncryptionScheme().getAlgorithm().getId()); ASN1Encodable encParams = alg.getEncryptionScheme().getParameters(); if (encParams instanceof ASN1OctetString) @@ -1781,7 +1788,9 @@ public class PKCS12KeyStoreSpi { PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount); - Mac mac = helper.createMac(oid.getId()); + // Android-Changed: Mac must be from BC due to use of internal PKCS12Key tyoe. + // Mac mac = helper.createMac(oid.getId()); + Mac mac = selfHelper.createMac(oid.getId()); mac.init(new PKCS12Key(password, wrongPkcs12Zero), defParams); mac.update(data); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java index e7d3ec24..d25ed90c 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java @@ -1088,6 +1088,11 @@ public final class AES // addGMacAlgorithm(provider, "AES", PREFIX + "$AESGMAC", PREFIX + "$KeyGen128"); // addPoly1305Algorithm(provider, "AES", PREFIX + "$Poly1305", PREFIX + "$Poly1305KeyGen"); // END Android-removed: Unsupported algorithms + + // Android-added: Private implementations needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Cipher", NISTObjectIdentifiers.id_aes128_CBC, PREFIX + "$CBC"); + provider.addPrivateAlgorithm("Cipher", NISTObjectIdentifiers.id_aes192_CBC, PREFIX + "$CBC"); + provider.addPrivateAlgorithm("Cipher", NISTObjectIdentifiers.id_aes256_CBC, PREFIX + "$CBC"); } } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java index 1af79b80..e384134b 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java @@ -40,14 +40,14 @@ public class PBEPBKDF2 static { - // BEGIN Android-removed: Unsupported algorithm - /* - prfCodes.put(CryptoProObjectIdentifiers.gostR3411Hmac, Integers.valueOf(PBE.GOST3411)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA1, Integers.valueOf(PBE.SHA1)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA256, Integers.valueOf(PBE.SHA256)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA224, Integers.valueOf(PBE.SHA224)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA384, Integers.valueOf(PBE.SHA384)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA512, Integers.valueOf(PBE.SHA512)); + // BEGIN Android-removed: Unsupported algorithms + /* + prfCodes.put(CryptoProObjectIdentifiers.gostR3411Hmac, Integers.valueOf(PBE.GOST3411)); prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_256, Integers.valueOf(PBE.SHA3_256)); prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_224, Integers.valueOf(PBE.SHA3_224)); prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_384, Integers.valueOf(PBE.SHA3_384)); @@ -62,8 +62,6 @@ public class PBEPBKDF2 } - // BEGIN Android-removed: Unsupported algorithms - /* public static class AlgParams extends BaseAlgorithmParameters { @@ -146,8 +144,6 @@ public class PBEPBKDF2 return "PBKDF2 Parameters"; } } - */ - // END Android-removed: Unsupported algorithms public static class BasePBKDF2 extends BaseSecretKeyFactory @@ -273,8 +269,6 @@ public class PBEPBKDF2 } } - // BEGIN Android-removed: Unsupported algorithms - /* public static class PBKDF2withUTF8 extends BasePBKDF2 { @@ -284,6 +278,8 @@ public class PBEPBKDF2 } } + // BEGIN Android-removed: Unsupported algorithms + /* public static class PBKDF2withSHA224 extends BasePBKDF2 { @@ -614,6 +610,9 @@ public class PBEPBKDF2 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA512AndAES_256", PREFIX + "$PBEWithHmacSHA512AndAES_256"); provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1And8BIT", PREFIX + "$PBKDF2WithHmacSHA18BIT"); // END Android-added: Android versions of algorithms. + // Android-added: Private implementations needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("SecretKeyFactory.PBKDF2", PREFIX + "$PBKDF2withUTF8"); + provider.addPrivateAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.5.12", "PBKDF2"); } } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java index 6c384585..9a41d31c 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java @@ -1,8 +1,13 @@ package org.bouncycastle.jcajce.util; +import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.Security; +import javax.crypto.Cipher; +import javax.crypto.Mac; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKeyFactory; import org.bouncycastle.jce.provider.BouncyCastleProvider; /** @@ -38,4 +43,45 @@ public class BCJcaJceHelper { super(getBouncyCastleProvider()); } + + // BEGIN Android-added: Look up algorithms in private provider if not found in main Provider. + // + // If code is using a BCJcajceHelper to ensure it gets its implementation from BC, then + // also search in the privately provided algorithms if not found in the main set. + @Override + public Cipher createCipher(String algorithm) + throws NoSuchAlgorithmException, NoSuchPaddingException { + try { + return super.createCipher(algorithm); + } catch (NoSuchAlgorithmException e) { + return Cipher.getInstance(algorithm, getPrivateProvider()); + } + } + + @Override + public SecretKeyFactory createSecretKeyFactory(String algorithm) + throws NoSuchAlgorithmException { + try { + return super.createSecretKeyFactory(algorithm); + } catch (NoSuchAlgorithmException e) { + return SecretKeyFactory.getInstance(algorithm, getPrivateProvider()); + } + } + + @Override + public Mac createMac(String algorithm) throws NoSuchAlgorithmException { + try { + return super.createMac(algorithm); + } catch (NoSuchAlgorithmException e) { + return Mac.getInstance(algorithm, getPrivateProvider()); + } + } + + private Provider getPrivateProvider() { + if (provider instanceof BouncyCastleProvider) { + return ((BouncyCastleProvider) provider).getPrivateProvider(); + } + throw new IllegalStateException(); // XXX + } + // END Android-added: Look up algorithms in private provider if not found in main Provider. } diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java index bb12aecf..7f9285b1 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java @@ -426,4 +426,37 @@ public final class BouncyCastleProvider extends Provider return converter.generatePrivate(privateKeyInfo); */ } + + // BEGIN Android-added: Allow algorithms to be provided privately for BC internals. + // + // Algorithms added via these methods are stored in a private instance of PrivateProvider, + // which is never added to the system-wide list of installed Providers, and is only + // ever searched by BC internal classes which search for algorithms using an instance + // of BCJcajceHelper. + private static final class PrivateProvider extends Provider { + public PrivateProvider() { + super("BCPrivate", 1.0, "Android BC private use only"); + } + } + + private final Provider privateProvider = new PrivateProvider(); + + public void addPrivateAlgorithm(String key, String value) + { + if (privateProvider.containsKey(key)) + { + throw new IllegalStateException("duplicate provider key (" + key + ") found"); + } + privateProvider.put(key, value); + } + + public void addPrivateAlgorithm(String type, ASN1ObjectIdentifier oid, String className) + { + addPrivateAlgorithm(type + "." + oid, className); + } + + public Provider getPrivateProvider() { + return privateProvider; + } + // END Android-added: Allow algorithms to be provided privately for BC internals. } diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java index da69af72..d6dc21ea 100644 --- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java +++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java @@ -56,4 +56,11 @@ public interface ConfigurableProvider AsymmetricKeyInfoConverter getKeyInfoConverter(ASN1ObjectIdentifier oid); void addAttributes(String key, Map attributeMap); + + // BEGIN Android-added: Allow algorithms to be added privately. + // See BouncyCastleProvider for details. + void addPrivateAlgorithm(String key, String value); + + void addPrivateAlgorithm(String type, ASN1ObjectIdentifier oid, String className); + // END Android-added: Allow algorithms to be added privately. } diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA224.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA224.java index e9f436a8..ff4fde85 100644 --- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA224.java +++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA224.java @@ -92,6 +92,8 @@ public class SHA224 addHMACAlias(provider, "SHA224", PKCSObjectIdentifiers.id_hmacWithSHA224); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha224, PREFIX + "$HashMac"); } } } diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA256.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA256.java index 706d4ab3..a4e8a762 100644 --- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA256.java +++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA256.java @@ -115,6 +115,8 @@ public class SHA256 addHMACAlias(provider, "SHA256", NISTObjectIdentifiers.id_sha256); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha256, PREFIX + "$HashMac"); } } } diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA384.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA384.java index b7d97164..7ff261e0 100644 --- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA384.java +++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA384.java @@ -109,6 +109,8 @@ public class SHA384 addHMACAlias(provider, "SHA384", PKCSObjectIdentifiers.id_hmacWithSHA384); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha384, PREFIX + "$HashMac"); } } } diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA512.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA512.java index dbd513c7..cdc70186 100644 --- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA512.java +++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA512.java @@ -207,6 +207,8 @@ public class SHA512 addHMACAlgorithm(provider, "SHA512/256", PREFIX + "$HashMacT256", PREFIX + "$KeyGeneratorT256"); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha512, PREFIX + "$HashMac"); } } diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java index fb5f2fdd..06fbb963 100644 --- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java +++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java @@ -120,9 +120,12 @@ public class PKCS12KeyStoreSpi { static final String PKCS12_MAX_IT_COUNT_PROPERTY = "com.android.org.bouncycastle.pkcs12.max_it_count"; - // Android-changed: Use default provider for JCA algorithms instead of BC + // Android-changed: Use default provider for most JCA algorithms instead of BC. + // For the case where we need BC implementations, the BCJcaJceHelper will also search + // the list of private implementations help by BouncyCastleProvider. // Was: private final JcaJceHelper helper = new BCJcaJceHelper(); private final JcaJceHelper helper = new DefaultJcaJceHelper(); + private final JcaJceHelper selfHelper = new BCJcaJceHelper(); private static final int SALT_SIZE = 20; private static final int MIN_ITERATIONS = 50 * 1024; @@ -731,7 +734,9 @@ public class PKCS12KeyStoreSpi PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters()); AlgorithmIdentifier encScheme = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme()); - SecretKeyFactory keyFact = helper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId()); + // Android-Changed: SecretKeyFactory must be from BC due to instanceof logic. + // SecretKeyFactory keyFact = helper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId()); + SecretKeyFactory keyFact = selfHelper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId()); SecretKey key; if (func.isDefaultPrf()) @@ -743,7 +748,9 @@ public class PKCS12KeyStoreSpi key = keyFact.generateSecret(new PBKDF2KeySpec(password, func.getSalt(), validateIterationCount(func.getIterationCount()), keySizeProvider.getKeySize(encScheme), func.getPrf())); } - Cipher cipher = Cipher.getInstance(alg.getEncryptionScheme().getAlgorithm().getId()); + // Android-Changed: Cipher must be from BC due to use of internal PKCS12Key tyoe. + // Cipher cipher = Cipher.getInstance(alg.getEncryptionScheme().getAlgorithm().getId()); + Cipher cipher = selfHelper.createCipher(alg.getEncryptionScheme().getAlgorithm().getId()); ASN1Encodable encParams = alg.getEncryptionScheme().getParameters(); if (encParams instanceof ASN1OctetString) @@ -1785,7 +1792,9 @@ public class PKCS12KeyStoreSpi { PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount); - Mac mac = helper.createMac(oid.getId()); + // Android-Changed: Mac must be from BC due to use of internal PKCS12Key tyoe. + // Mac mac = helper.createMac(oid.getId()); + Mac mac = selfHelper.createMac(oid.getId()); mac.init(new PKCS12Key(password, wrongPkcs12Zero), defParams); mac.update(data); diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/AES.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/AES.java index 9e2a493d..9684f351 100644 --- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/AES.java +++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/AES.java @@ -1146,6 +1146,11 @@ public final class AES // addGMacAlgorithm(provider, "AES", PREFIX + "$AESGMAC", PREFIX + "$KeyGen128"); // addPoly1305Algorithm(provider, "AES", PREFIX + "$Poly1305", PREFIX + "$Poly1305KeyGen"); // END Android-removed: Unsupported algorithms + + // Android-added: Private implementations needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Cipher", NISTObjectIdentifiers.id_aes128_CBC, PREFIX + "$CBC"); + provider.addPrivateAlgorithm("Cipher", NISTObjectIdentifiers.id_aes192_CBC, PREFIX + "$CBC"); + provider.addPrivateAlgorithm("Cipher", NISTObjectIdentifiers.id_aes256_CBC, PREFIX + "$CBC"); } } } diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java index 2109104c..15880ad9 100644 --- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java +++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java @@ -44,14 +44,14 @@ public class PBEPBKDF2 static { - // BEGIN Android-removed: Unsupported algorithm - /* - prfCodes.put(CryptoProObjectIdentifiers.gostR3411Hmac, Integers.valueOf(PBE.GOST3411)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA1, Integers.valueOf(PBE.SHA1)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA256, Integers.valueOf(PBE.SHA256)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA224, Integers.valueOf(PBE.SHA224)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA384, Integers.valueOf(PBE.SHA384)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA512, Integers.valueOf(PBE.SHA512)); + // BEGIN Android-removed: Unsupported algorithms + /* + prfCodes.put(CryptoProObjectIdentifiers.gostR3411Hmac, Integers.valueOf(PBE.GOST3411)); prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_256, Integers.valueOf(PBE.SHA3_256)); prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_224, Integers.valueOf(PBE.SHA3_224)); prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_384, Integers.valueOf(PBE.SHA3_384)); @@ -66,8 +66,9 @@ public class PBEPBKDF2 } - // BEGIN Android-removed: Unsupported algorithms - /* + /** + * @hide This class is not part of the Android public SDK API + */ public static class AlgParams extends BaseAlgorithmParameters { @@ -150,8 +151,6 @@ public class PBEPBKDF2 return "PBKDF2 Parameters"; } } - */ - // END Android-removed: Unsupported algorithms /** * @hide This class is not part of the Android public SDK API @@ -280,8 +279,9 @@ public class PBEPBKDF2 } } - // BEGIN Android-removed: Unsupported algorithms - /* + /** + * @hide This class is not part of the Android public SDK API + */ public static class PBKDF2withUTF8 extends BasePBKDF2 { @@ -291,6 +291,8 @@ public class PBEPBKDF2 } } + // BEGIN Android-removed: Unsupported algorithms + /* public static class PBKDF2withSHA224 extends BasePBKDF2 { @@ -687,6 +689,9 @@ public class PBEPBKDF2 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA512AndAES_256", PREFIX + "$PBEWithHmacSHA512AndAES_256"); provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1And8BIT", PREFIX + "$PBKDF2WithHmacSHA18BIT"); // END Android-added: Android versions of algorithms. + // Android-added: Private implementations needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("SecretKeyFactory.PBKDF2", PREFIX + "$PBKDF2withUTF8"); + provider.addPrivateAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.5.12", "PBKDF2"); } } } diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/BCJcaJceHelper.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/BCJcaJceHelper.java index 65523d84..b444878f 100644 --- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/BCJcaJceHelper.java +++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/BCJcaJceHelper.java @@ -1,9 +1,14 @@ /* GENERATED SOURCE. DO NOT MODIFY. */ package com.android.org.bouncycastle.jcajce.util; +import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.Security; +import javax.crypto.Cipher; +import javax.crypto.Mac; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKeyFactory; import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider; /** @@ -40,4 +45,45 @@ public class BCJcaJceHelper { super(getBouncyCastleProvider()); } + + // BEGIN Android-added: Look up algorithms in private provider if not found in main Provider. + // + // If code is using a BCJcajceHelper to ensure it gets its implementation from BC, then + // also search in the privately provided algorithms if not found in the main set. + @Override + public Cipher createCipher(String algorithm) + throws NoSuchAlgorithmException, NoSuchPaddingException { + try { + return super.createCipher(algorithm); + } catch (NoSuchAlgorithmException e) { + return Cipher.getInstance(algorithm, getPrivateProvider()); + } + } + + @Override + public SecretKeyFactory createSecretKeyFactory(String algorithm) + throws NoSuchAlgorithmException { + try { + return super.createSecretKeyFactory(algorithm); + } catch (NoSuchAlgorithmException e) { + return SecretKeyFactory.getInstance(algorithm, getPrivateProvider()); + } + } + + @Override + public Mac createMac(String algorithm) throws NoSuchAlgorithmException { + try { + return super.createMac(algorithm); + } catch (NoSuchAlgorithmException e) { + return Mac.getInstance(algorithm, getPrivateProvider()); + } + } + + private Provider getPrivateProvider() { + if (provider instanceof BouncyCastleProvider) { + return ((BouncyCastleProvider) provider).getPrivateProvider(); + } + throw new IllegalStateException(); // XXX + } + // END Android-added: Look up algorithms in private provider if not found in main Provider. } diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProvider.java index 61383ce7..798bb8ed 100644 --- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProvider.java +++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProvider.java @@ -429,4 +429,37 @@ public final class BouncyCastleProvider extends Provider return converter.generatePrivate(privateKeyInfo); */ } + + // BEGIN Android-added: Allow algorithms to be provided privately for BC internals. + // + // Algorithms added via these methods are stored in a private instance of PrivateProvider, + // which is never added to the system-wide list of installed Providers, and is only + // ever searched by BC internal classes which search for algorithms using an instance + // of BCJcajceHelper. + private static final class PrivateProvider extends Provider { + public PrivateProvider() { + super("BCPrivate", 1.0, "Android BC private use only"); + } + } + + private final Provider privateProvider = new PrivateProvider(); + + public void addPrivateAlgorithm(String key, String value) + { + if (privateProvider.containsKey(key)) + { + throw new IllegalStateException("duplicate provider key (" + key + ") found"); + } + privateProvider.put(key, value); + } + + public void addPrivateAlgorithm(String type, ASN1ObjectIdentifier oid, String className) + { + addPrivateAlgorithm(type + "." + oid, className); + } + + public Provider getPrivateProvider() { + return privateProvider; + } + // END Android-added: Allow algorithms to be provided privately for BC internals. } diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java index 8f8787f7..cd76b860 100644 --- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java +++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java @@ -56,4 +56,11 @@ public interface ConfigurableProvider AsymmetricKeyInfoConverter getKeyInfoConverter(ASN1ObjectIdentifier oid); void addAttributes(String key, Map attributeMap); + + // BEGIN Android-added: Allow algorithms to be added privately. + // See BouncyCastleProvider for details. + void addPrivateAlgorithm(String key, String value); + + void addPrivateAlgorithm(String type, ASN1ObjectIdentifier oid, String className); + // END Android-added: Allow algorithms to be added privately. } diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA224.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA224.java index 5b5d9511..bac8e723 100644 --- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA224.java +++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA224.java @@ -92,6 +92,8 @@ public class SHA224 addHMACAlias(provider, "SHA224", PKCSObjectIdentifiers.id_hmacWithSHA224); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha224, PREFIX + "$HashMac"); } } } diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA256.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA256.java index 929364f5..a7ab4097 100644 --- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA256.java +++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA256.java @@ -115,6 +115,8 @@ public class SHA256 addHMACAlias(provider, "SHA256", NISTObjectIdentifiers.id_sha256); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha256, PREFIX + "$HashMac"); } } } diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA384.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA384.java index 89d14437..5d209512 100644 --- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA384.java +++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA384.java @@ -109,6 +109,8 @@ public class SHA384 addHMACAlias(provider, "SHA384", PKCSObjectIdentifiers.id_hmacWithSHA384); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha384, PREFIX + "$HashMac"); } } } diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA512.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA512.java index b726dbf8..243a3064 100644 --- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA512.java +++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA512.java @@ -207,6 +207,8 @@ public class SHA512 addHMACAlgorithm(provider, "SHA512/256", PREFIX + "$HashMacT256", PREFIX + "$KeyGeneratorT256"); */ // END Android-removed: Unsupported algorithms + // Android-added: Private implementation needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Mac", NISTObjectIdentifiers.id_sha512, PREFIX + "$HashMac"); } } diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java index d5897959..745534da 100644 --- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java +++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java @@ -120,9 +120,12 @@ public class PKCS12KeyStoreSpi { static final String PKCS12_MAX_IT_COUNT_PROPERTY = "com.android.internal.org.bouncycastle.pkcs12.max_it_count"; - // Android-changed: Use default provider for JCA algorithms instead of BC + // Android-changed: Use default provider for most JCA algorithms instead of BC. + // For the case where we need BC implementations, the BCJcaJceHelper will also search + // the list of private implementations help by BouncyCastleProvider. // Was: private final JcaJceHelper helper = new BCJcaJceHelper(); private final JcaJceHelper helper = new DefaultJcaJceHelper(); + private final JcaJceHelper selfHelper = new BCJcaJceHelper(); private static final int SALT_SIZE = 20; private static final int MIN_ITERATIONS = 50 * 1024; @@ -731,7 +734,9 @@ public class PKCS12KeyStoreSpi PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters()); AlgorithmIdentifier encScheme = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme()); - SecretKeyFactory keyFact = helper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId()); + // Android-Changed: SecretKeyFactory must be from BC due to instanceof logic. + // SecretKeyFactory keyFact = helper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId()); + SecretKeyFactory keyFact = selfHelper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId()); SecretKey key; if (func.isDefaultPrf()) @@ -743,7 +748,9 @@ public class PKCS12KeyStoreSpi key = keyFact.generateSecret(new PBKDF2KeySpec(password, func.getSalt(), validateIterationCount(func.getIterationCount()), keySizeProvider.getKeySize(encScheme), func.getPrf())); } - Cipher cipher = Cipher.getInstance(alg.getEncryptionScheme().getAlgorithm().getId()); + // Android-Changed: Cipher must be from BC due to use of internal PKCS12Key tyoe. + // Cipher cipher = Cipher.getInstance(alg.getEncryptionScheme().getAlgorithm().getId()); + Cipher cipher = selfHelper.createCipher(alg.getEncryptionScheme().getAlgorithm().getId()); ASN1Encodable encParams = alg.getEncryptionScheme().getParameters(); if (encParams instanceof ASN1OctetString) @@ -1785,7 +1792,9 @@ public class PKCS12KeyStoreSpi { PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount); - Mac mac = helper.createMac(oid.getId()); + // Android-Changed: Mac must be from BC due to use of internal PKCS12Key tyoe. + // Mac mac = helper.createMac(oid.getId()); + Mac mac = selfHelper.createMac(oid.getId()); mac.init(new PKCS12Key(password, wrongPkcs12Zero), defParams); mac.update(data); diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java index 55510fd2..056faae1 100644 --- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java +++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java @@ -1146,6 +1146,11 @@ public final class AES // addGMacAlgorithm(provider, "AES", PREFIX + "$AESGMAC", PREFIX + "$KeyGen128"); // addPoly1305Algorithm(provider, "AES", PREFIX + "$Poly1305", PREFIX + "$Poly1305KeyGen"); // END Android-removed: Unsupported algorithms + + // Android-added: Private implementations needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("Cipher", NISTObjectIdentifiers.id_aes128_CBC, PREFIX + "$CBC"); + provider.addPrivateAlgorithm("Cipher", NISTObjectIdentifiers.id_aes192_CBC, PREFIX + "$CBC"); + provider.addPrivateAlgorithm("Cipher", NISTObjectIdentifiers.id_aes256_CBC, PREFIX + "$CBC"); } } } diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java index ab218e1f..63824db6 100644 --- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java +++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java @@ -44,14 +44,14 @@ public class PBEPBKDF2 static { - // BEGIN Android-removed: Unsupported algorithm - /* - prfCodes.put(CryptoProObjectIdentifiers.gostR3411Hmac, Integers.valueOf(PBE.GOST3411)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA1, Integers.valueOf(PBE.SHA1)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA256, Integers.valueOf(PBE.SHA256)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA224, Integers.valueOf(PBE.SHA224)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA384, Integers.valueOf(PBE.SHA384)); prfCodes.put(PKCSObjectIdentifiers.id_hmacWithSHA512, Integers.valueOf(PBE.SHA512)); + // BEGIN Android-removed: Unsupported algorithms + /* + prfCodes.put(CryptoProObjectIdentifiers.gostR3411Hmac, Integers.valueOf(PBE.GOST3411)); prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_256, Integers.valueOf(PBE.SHA3_256)); prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_224, Integers.valueOf(PBE.SHA3_224)); prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_384, Integers.valueOf(PBE.SHA3_384)); @@ -66,8 +66,9 @@ public class PBEPBKDF2 } - // BEGIN Android-removed: Unsupported algorithms - /* + /** + * @hide This class is not part of the Android public SDK API + */ public static class AlgParams extends BaseAlgorithmParameters { @@ -150,8 +151,6 @@ public class PBEPBKDF2 return "PBKDF2 Parameters"; } } - */ - // END Android-removed: Unsupported algorithms /** * @hide This class is not part of the Android public SDK API @@ -280,8 +279,9 @@ public class PBEPBKDF2 } } - // BEGIN Android-removed: Unsupported algorithms - /* + /** + * @hide This class is not part of the Android public SDK API + */ public static class PBKDF2withUTF8 extends BasePBKDF2 { @@ -291,6 +291,8 @@ public class PBEPBKDF2 } } + // BEGIN Android-removed: Unsupported algorithms + /* public static class PBKDF2withSHA224 extends BasePBKDF2 { @@ -687,6 +689,9 @@ public class PBEPBKDF2 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA512AndAES_256", PREFIX + "$PBEWithHmacSHA512AndAES_256"); provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1And8BIT", PREFIX + "$PBKDF2WithHmacSHA18BIT"); // END Android-added: Android versions of algorithms. + // Android-added: Private implementations needed to support PBKDF2 with PKCS#12 + provider.addPrivateAlgorithm("SecretKeyFactory.PBKDF2", PREFIX + "$PBKDF2withUTF8"); + provider.addPrivateAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.5.12", "PBKDF2"); } } } diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java index 15130f26..7b7c6cb3 100644 --- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java +++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java @@ -1,9 +1,14 @@ /* GENERATED SOURCE. DO NOT MODIFY. */ package com.android.internal.org.bouncycastle.jcajce.util; +import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.Security; +import javax.crypto.Cipher; +import javax.crypto.Mac; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKeyFactory; import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider; /** @@ -40,4 +45,45 @@ public class BCJcaJceHelper { super(getBouncyCastleProvider()); } + + // BEGIN Android-added: Look up algorithms in private provider if not found in main Provider. + // + // If code is using a BCJcajceHelper to ensure it gets its implementation from BC, then + // also search in the privately provided algorithms if not found in the main set. + @Override + public Cipher createCipher(String algorithm) + throws NoSuchAlgorithmException, NoSuchPaddingException { + try { + return super.createCipher(algorithm); + } catch (NoSuchAlgorithmException e) { + return Cipher.getInstance(algorithm, getPrivateProvider()); + } + } + + @Override + public SecretKeyFactory createSecretKeyFactory(String algorithm) + throws NoSuchAlgorithmException { + try { + return super.createSecretKeyFactory(algorithm); + } catch (NoSuchAlgorithmException e) { + return SecretKeyFactory.getInstance(algorithm, getPrivateProvider()); + } + } + + @Override + public Mac createMac(String algorithm) throws NoSuchAlgorithmException { + try { + return super.createMac(algorithm); + } catch (NoSuchAlgorithmException e) { + return Mac.getInstance(algorithm, getPrivateProvider()); + } + } + + private Provider getPrivateProvider() { + if (provider instanceof BouncyCastleProvider) { + return ((BouncyCastleProvider) provider).getPrivateProvider(); + } + throw new IllegalStateException(); // XXX + } + // END Android-added: Look up algorithms in private provider if not found in main Provider. } diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java index 2f3f1ea2..2689da81 100644 --- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java +++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java @@ -428,4 +428,37 @@ public final class BouncyCastleProvider extends Provider return converter.generatePrivate(privateKeyInfo); */ } + + // BEGIN Android-added: Allow algorithms to be provided privately for BC internals. + // + // Algorithms added via these methods are stored in a private instance of PrivateProvider, + // which is never added to the system-wide list of installed Providers, and is only + // ever searched by BC internal classes which search for algorithms using an instance + // of BCJcajceHelper. + private static final class PrivateProvider extends Provider { + public PrivateProvider() { + super("BCPrivate", 1.0, "Android BC private use only"); + } + } + + private final Provider privateProvider = new PrivateProvider(); + + public void addPrivateAlgorithm(String key, String value) + { + if (privateProvider.containsKey(key)) + { + throw new IllegalStateException("duplicate provider key (" + key + ") found"); + } + privateProvider.put(key, value); + } + + public void addPrivateAlgorithm(String type, ASN1ObjectIdentifier oid, String className) + { + addPrivateAlgorithm(type + "." + oid, className); + } + + public Provider getPrivateProvider() { + return privateProvider; + } + // END Android-added: Allow algorithms to be provided privately for BC internals. } -- cgit v1.2.3 From 10942f23a051f9089baa013e2201f41b4d17a6ea Mon Sep 17 00:00:00 2001 From: Pete Bentley Date: Tue, 10 Jan 2023 12:43:08 +0000 Subject: Don't throw exceptions from BCPrivate provider. I originally thought this was fine, but it could cause confusion for developers encountering a PKCS#12 file using an unknown algorithm. Instead, throw the original NoSuchAlgorithmException from the BC Provider. Bug: 230750823 Test: atest CtsLibcoreTestCases:tests.targets.security.KeyStorePkcs7FormatTest Change-Id: I8a6d44d0e59bf0fb029ced4b8aa47908194bc161 --- .../bouncycastle/jcajce/util/BCJcaJceHelper.java | 30 +++++++++++++++++----- .../bouncycastle/jcajce/util/BCJcaJceHelper.java | 30 +++++++++++++++++----- .../bouncycastle/jcajce/util/BCJcaJceHelper.java | 30 +++++++++++++++++----- 3 files changed, 69 insertions(+), 21 deletions(-) diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java index 9a41d31c..13205ec2 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java @@ -48,13 +48,21 @@ public class BCJcaJceHelper // // If code is using a BCJcajceHelper to ensure it gets its implementation from BC, then // also search in the privately provided algorithms if not found in the main set. + // + // If any error occurs while searching the private Provider, typically a + // NoSuchAlgorithmException being thrown, then the original NoSuchAlgorithmException + // from the BC Provider is thrown for consistency. @Override public Cipher createCipher(String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException { try { return super.createCipher(algorithm); - } catch (NoSuchAlgorithmException e) { - return Cipher.getInstance(algorithm, getPrivateProvider()); + } catch (NoSuchAlgorithmException originalException) { + try { + return Cipher.getInstance(algorithm, getPrivateProvider()); + } catch (Throwable throwable) { + throw originalException; + } } } @@ -63,8 +71,12 @@ public class BCJcaJceHelper throws NoSuchAlgorithmException { try { return super.createSecretKeyFactory(algorithm); - } catch (NoSuchAlgorithmException e) { - return SecretKeyFactory.getInstance(algorithm, getPrivateProvider()); + } catch (NoSuchAlgorithmException originalException) { + try { + return SecretKeyFactory.getInstance(algorithm, getPrivateProvider()); + } catch (Throwable throwable) { + throw originalException; + } } } @@ -72,8 +84,12 @@ public class BCJcaJceHelper public Mac createMac(String algorithm) throws NoSuchAlgorithmException { try { return super.createMac(algorithm); - } catch (NoSuchAlgorithmException e) { - return Mac.getInstance(algorithm, getPrivateProvider()); + } catch (NoSuchAlgorithmException originalException) { + try { + return Mac.getInstance(algorithm, getPrivateProvider()); + } catch (Throwable throwable) { + throw originalException; + } } } @@ -81,7 +97,7 @@ public class BCJcaJceHelper if (provider instanceof BouncyCastleProvider) { return ((BouncyCastleProvider) provider).getPrivateProvider(); } - throw new IllegalStateException(); // XXX + throw new IllegalStateException("Internal error in BCJcaJceHelper"); } // END Android-added: Look up algorithms in private provider if not found in main Provider. } diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/BCJcaJceHelper.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/BCJcaJceHelper.java index b444878f..69ab946c 100644 --- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/BCJcaJceHelper.java +++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/BCJcaJceHelper.java @@ -50,13 +50,21 @@ public class BCJcaJceHelper // // If code is using a BCJcajceHelper to ensure it gets its implementation from BC, then // also search in the privately provided algorithms if not found in the main set. + // + // If any error occurs while searching the private Provider, typically a + // NoSuchAlgorithmException being thrown, then the original NoSuchAlgorithmException + // from the BC Provider is thrown for consistency. @Override public Cipher createCipher(String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException { try { return super.createCipher(algorithm); - } catch (NoSuchAlgorithmException e) { - return Cipher.getInstance(algorithm, getPrivateProvider()); + } catch (NoSuchAlgorithmException originalException) { + try { + return Cipher.getInstance(algorithm, getPrivateProvider()); + } catch (Throwable throwable) { + throw originalException; + } } } @@ -65,8 +73,12 @@ public class BCJcaJceHelper throws NoSuchAlgorithmException { try { return super.createSecretKeyFactory(algorithm); - } catch (NoSuchAlgorithmException e) { - return SecretKeyFactory.getInstance(algorithm, getPrivateProvider()); + } catch (NoSuchAlgorithmException originalException) { + try { + return SecretKeyFactory.getInstance(algorithm, getPrivateProvider()); + } catch (Throwable throwable) { + throw originalException; + } } } @@ -74,8 +86,12 @@ public class BCJcaJceHelper public Mac createMac(String algorithm) throws NoSuchAlgorithmException { try { return super.createMac(algorithm); - } catch (NoSuchAlgorithmException e) { - return Mac.getInstance(algorithm, getPrivateProvider()); + } catch (NoSuchAlgorithmException originalException) { + try { + return Mac.getInstance(algorithm, getPrivateProvider()); + } catch (Throwable throwable) { + throw originalException; + } } } @@ -83,7 +99,7 @@ public class BCJcaJceHelper if (provider instanceof BouncyCastleProvider) { return ((BouncyCastleProvider) provider).getPrivateProvider(); } - throw new IllegalStateException(); // XXX + throw new IllegalStateException("Internal error in BCJcaJceHelper"); } // END Android-added: Look up algorithms in private provider if not found in main Provider. } diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java index 7b7c6cb3..507d225c 100644 --- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java +++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java @@ -50,13 +50,21 @@ public class BCJcaJceHelper // // If code is using a BCJcajceHelper to ensure it gets its implementation from BC, then // also search in the privately provided algorithms if not found in the main set. + // + // If any error occurs while searching the private Provider, typically a + // NoSuchAlgorithmException being thrown, then the original NoSuchAlgorithmException + // from the BC Provider is thrown for consistency. @Override public Cipher createCipher(String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException { try { return super.createCipher(algorithm); - } catch (NoSuchAlgorithmException e) { - return Cipher.getInstance(algorithm, getPrivateProvider()); + } catch (NoSuchAlgorithmException originalException) { + try { + return Cipher.getInstance(algorithm, getPrivateProvider()); + } catch (Throwable throwable) { + throw originalException; + } } } @@ -65,8 +73,12 @@ public class BCJcaJceHelper throws NoSuchAlgorithmException { try { return super.createSecretKeyFactory(algorithm); - } catch (NoSuchAlgorithmException e) { - return SecretKeyFactory.getInstance(algorithm, getPrivateProvider()); + } catch (NoSuchAlgorithmException originalException) { + try { + return SecretKeyFactory.getInstance(algorithm, getPrivateProvider()); + } catch (Throwable throwable) { + throw originalException; + } } } @@ -74,8 +86,12 @@ public class BCJcaJceHelper public Mac createMac(String algorithm) throws NoSuchAlgorithmException { try { return super.createMac(algorithm); - } catch (NoSuchAlgorithmException e) { - return Mac.getInstance(algorithm, getPrivateProvider()); + } catch (NoSuchAlgorithmException originalException) { + try { + return Mac.getInstance(algorithm, getPrivateProvider()); + } catch (Throwable throwable) { + throw originalException; + } } } @@ -83,7 +99,7 @@ public class BCJcaJceHelper if (provider instanceof BouncyCastleProvider) { return ((BouncyCastleProvider) provider).getPrivateProvider(); } - throw new IllegalStateException(); // XXX + throw new IllegalStateException("Internal error in BCJcaJceHelper"); } // END Android-added: Look up algorithms in private provider if not found in main Provider. } -- cgit v1.2.3 From 6fe9ebd4c17b19d0777215c113167a3881bda0a7 Mon Sep 17 00:00:00 2001 From: Prashant Patil Date: Tue, 17 Jan 2023 12:00:55 +0000 Subject: Keystore:Add visibility to android-key-attestation Added a visibility of bouncycastle-unbundled library to //external/android-key-attestation library. Bug: 200011803 Test: atest CtsKeystoreTestCases:android.keystore.cts.DeviceOwnerKeyManagementTest Change-Id: I7574610636f95fc7d5b616f0516ad0edf8d7d8f6 --- Android.bp | 1 + 1 file changed, 1 insertion(+) diff --git a/Android.bp b/Android.bp index 00ee0935..9e038632 100644 --- a/Android.bp +++ b/Android.bp @@ -155,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", -- cgit v1.2.3 From fcb2b514ddb6d5ae69b8a17e364e2fb4c33c17dd Mon Sep 17 00:00:00 2001 From: Sorin Basca Date: Thu, 2 Feb 2023 20:11:53 +0000 Subject: Pin bouncycastle-bcpkix-unbundled to Java 11 for signapk Bug: 267608166 Test: TH Change-Id: I6d39dac37fc6439911a39d007e4e8349e570d7e3 --- Android.bp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Android.bp b/Android.bp index 9e038632..fadb1f70 100644 --- a/Android.bp +++ b/Android.bp @@ -214,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 -- cgit v1.2.3 From dd46e8b30d7938693a5f2327bf053918982950de Mon Sep 17 00:00:00 2001 From: Miguel Date: Tue, 23 Aug 2022 14:42:43 +0000 Subject: Reject BC keys without IV. Test: m Bug: 70275132 Change-Id: I07d40c9235ca9532cec7e8b608863441be8ee2d0 --- .../provider/symmetric/util/BaseBlockCipher.java | 48 ++++------------------ .../provider/symmetric/util/BaseBlockCipher.java | 48 ++++------------------ .../provider/symmetric/util/BaseBlockCipher.java | 48 ++++------------------ 3 files changed, 27 insertions(+), 117 deletions(-) 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/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 } } -- cgit v1.2.3